//____________________________________________________________ // // PROGRAM: C preprocessor // MODULE: msc.cpp // DESCRIPTION: Miscellaneous little stuff // // The contents of this file are subject to the Interbase Public // License Version 1.0 (the "License"); you may not use this file // except in compliance with the License. You may obtain a copy // of the License at http://www.Inprise.com/IPL.html // // Software distributed under the License is distributed on an // "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express // or implied. See the License for the specific language governing // rights and limitations under the License. // // The Original Code was created by Inprise Corporation // and its predecessors. Portions created by Inprise Corporation are // Copyright (C) Inprise Corporation. // // All Rights Reserved. // Contributor(s): ______________________________________. // TMN (Mike Nordell) 11.APR.2001 - Reduce compiler warnings // // //____________________________________________________________ // // $Id: msc.cpp,v 1.22 2004-05-24 17:13:37 brodsom Exp $ // // // // *************************************************** // THIS MODULE HAS SEVERAL KISSING COUSINS; IF YOU // SHOULD CHANGE ONE OF THE MODULES IN THE FOLLOWING // LIST, PLEASE BE SURE TO CHECK THE OTHERS FOR // SIMILAR CHANGES: // // dsql/all.cpp // jrd/all.cpp // pipe/allp.cpp // qli/all.cpp // remote/allr.cpp // gpre/msc.cpp // // - THANK YOU //************************************************** #include "firebird.h" #include #include #include "../gpre/gpre.h" #include "../gpre/gpre_proto.h" #include "../gpre/msc_proto.h" #include "../jrd/gds_proto.h" typedef struct spc { spc* spc_next; SLONG spc_remaining; } *SPC; static SPC space, permanent_space; static gpre_lls* free_lls; //____________________________________________________________ // // Make an action and link it to a request. // act* MSC_action( gpre_req* request, enum act_t type) { act* action = (act*) MSC_alloc(ACT_LEN); action->act_type = type; if (request) { action->act_next = request->req_actions; request->req_actions = action; action->act_request = request; } return action; } //____________________________________________________________ // // UCHAR* MSC_alloc(int size) { size = FB_ALIGN(size, ALIGNMENT); if (!space || size > space->spc_remaining) { const int n = MAX(size, 4096); SPC next = (SPC) gds__alloc((SLONG) (n + sizeof(spc))); if (!next) CPR_error("virtual memory exhausted"); #ifdef DEBUG_GDS_ALLOC // For V4.0 we don't care about gpre specific memory leaks gds_alloc_flag_unfreed(next); #endif next->spc_next = space; next->spc_remaining = n; space = next; } space->spc_remaining -= size; UCHAR* const blk = ((UCHAR*) space + sizeof(spc) + space->spc_remaining); UCHAR* p = blk; const UCHAR* const end = p + size; while (p < end) *p++ = 0; return blk; } //____________________________________________________________ // // Allocate a block in permanent memory. // UCHAR* MSC_alloc_permanent(int size) { size = FB_ALIGN(size, ALIGNMENT); if (!permanent_space || size > permanent_space->spc_remaining) { const int n = MAX(size, 4096); SPC next = (SPC) gds__alloc((SLONG) (n + sizeof(spc))); if (!next) CPR_error("virtual memory exhausted"); #ifdef DEBUG_GDS_ALLOC // For V4.0 we don't care about gpre specific memory leaks gds_alloc_flag_unfreed(next); #endif next->spc_next = permanent_space; next->spc_remaining = n; permanent_space = next; } permanent_space->spc_remaining -= size; UCHAR* const blk = ((UCHAR*) permanent_space + sizeof(spc) + permanent_space->spc_remaining); UCHAR* p = blk; const UCHAR* const end = p + size; while (p < end) *p++ = 0; return blk; } //____________________________________________________________ // // Make a binary node. // GPRE_NOD MSC_binary(NOD_T type, GPRE_NOD arg1, GPRE_NOD arg2) { GPRE_NOD node = MSC_node(type, 2); node->nod_arg[0] = arg1; node->nod_arg[1] = arg2; return node; } //____________________________________________________________ // // Make a new context for a request and link it up to the request. // gpre_ctx* MSC_context(gpre_req* request) { // allocate and initialize gpre_ctx* context = (gpre_ctx*) MSC_alloc(CTX_LEN); context->ctx_request = request; context->ctx_internal = request->req_internal++; context->ctx_scope_level = request->req_scope_level; // link in with the request block context->ctx_next = request->req_contexts; request->req_contexts = context; return context; } //____________________________________________________________ // // Copy one string into another. // void MSC_copy(const char* from, int length, char* to) { if (length) do { *to++ = *from++; } while (--length); *to = 0; } //____________________________________________________________ // // Copy two strings into another. // void MSC_copy_cat(const char* from1, int length1, const char* from2, int length2, char* to) { if (length1) do { *to++ = *from1++; } while (--length1); if (length2) do { *to++ = *from2++; } while (--length2); *to = 0; } //____________________________________________________________ // // Find a symbol of a particular type. // gpre_sym* MSC_find_symbol(gpre_sym* symbol, enum sym_t type) { for (; symbol; symbol = symbol->sym_homonym) if (symbol->sym_type == type) return symbol; return NULL; } //____________________________________________________________ // // Free a block. // void MSC_free( UCHAR* block) { } //____________________________________________________________ // // Get rid of an erroroneously allocated request block. // void MSC_free_request( gpre_req* request) { gpreGlob.requests = request->req_next; gpreGlob.cur_routine->act_object = (REF) request->req_routine; MSC_free((UCHAR *) request); } //____________________________________________________________ // // Initialize (or more properly, re-initialize) the memory // allocator. // void MSC_init(void) { free_lls = NULL; SPC stuff; while (stuff = space) { space = space->spc_next; gds__free(stuff); } } //____________________________________________________________ // // Match the current token against a keyword. If successful, // advance the token stream and return true. Otherwise return // false. // bool MSC_match(KWWORDS keyword) { if (gpreGlob.token_global.tok_keyword == KW_none && gpreGlob.token_global.tok_symbol) { gpre_sym* symbol; for (symbol = gpreGlob.token_global.tok_symbol->sym_collision; symbol; symbol = symbol->sym_collision) { if ((strcmp(symbol->sym_string, gpreGlob.token_global.tok_string) == 0) && symbol->sym_keyword != KW_none) { gpreGlob.token_global.tok_symbol = symbol; gpreGlob.token_global.tok_keyword = static_cast < kwwords > (symbol->sym_keyword); } } } if ((int) gpreGlob.token_global.tok_keyword != (int) keyword) return false; CPR_token(); return true; } #ifdef NOT_USED_OR_REPLACED //____________________________________________________________ // // Determinate where a specific object is // represented on a linked list stack. // bool MSC_member(GPRE_NOD object, gpre_lls* stack) { for (; stack; stack = stack->lls_next) if (stack->lls_object == object) return true; return false; } #endif //____________________________________________________________ // // Allocate an initialize a syntax node. // GPRE_NOD MSC_node(enum nod_t type, SSHORT count) { GPRE_NOD node = (GPRE_NOD) MSC_alloc(NOD_LEN(count)); node->nod_count = count; node->nod_type = type; return node; } //____________________________________________________________ // // Pop an item off a linked list stack. Free the stack node. // GPRE_NOD MSC_pop(gpre_lls** pointer) { gpre_lls* stack = *pointer; GPRE_NOD node = stack->lls_object; *pointer = stack->lls_next; stack->lls_next = free_lls; free_lls = stack; return node; } //____________________________________________________________ // // Allocate a new privilege (grant/revoke) block. // PRV MSC_privilege_block(void) { PRV privilege_block = (PRV) MSC_alloc(PRV_LEN); privilege_block->prv_privileges = PRV_no_privs; privilege_block->prv_username = 0; privilege_block->prv_relation = 0; privilege_block->prv_fields = 0; privilege_block->prv_next = 0; return privilege_block; } //____________________________________________________________ // // Push an arbitrary object onto a linked list stack. // void MSC_push( GPRE_NOD object, gpre_lls** pointer) { gpre_lls* stack = free_lls; if (stack) free_lls = stack->lls_next; else stack = (gpre_lls*) MSC_alloc(LLS_LEN); stack->lls_object = object; stack->lls_next = *pointer; *pointer = stack; } //____________________________________________________________ // // Generate a reference and possibly link the reference into // a linked list. // REF MSC_reference(REF* link) { REF reference = (REF) MSC_alloc(REF_LEN); if (link) { reference->ref_next = *link; *link = reference; } return reference; } //____________________________________________________________ // // Set up for a new request. Make request and action // blocks, all linked up and ready to go. // gpre_req* MSC_request(enum req_t type) { gpre_req* request = (gpre_req*) MSC_alloc(REQ_LEN); request->req_type = type; request->req_next = gpreGlob.requests; gpreGlob.requests = request; request->req_routine = (gpre_req*) gpreGlob.cur_routine->act_object; gpreGlob.cur_routine->act_object = (REF) request; if (!(gpreGlob.cur_routine->act_flags & ACT_main)) request->req_flags |= REQ_local; if (gpreGlob.sw_sql_dialect <= SQL_DIALECT_V5) request->req_flags |= REQ_blr_version4; return request; } //____________________________________________________________ // // Copy a string into a permanent block. // SCHAR* MSC_string(const TEXT* input) { TEXT* string = (TEXT*) MSC_alloc(strlen(input) + 1); strcpy(string, input); return string; } //____________________________________________________________ // // Allocate and initialize a symbol block. // gpre_sym* MSC_symbol(enum sym_t type, const TEXT* string, USHORT length, gpre_ctx* object) { gpre_sym* symbol = (gpre_sym*) MSC_alloc(SYM_LEN + length); symbol->sym_type = type; symbol->sym_object = object; TEXT* p = symbol->sym_name; symbol->sym_string = p; if (length) do { *p++ = *string++; } while (--length); return symbol; } //____________________________________________________________ // // Make a unary node. // GPRE_NOD MSC_unary(NOD_T type, GPRE_NOD arg) { GPRE_NOD node = MSC_node(type, 1); node->nod_arg[0] = arg; return node; } //____________________________________________________________ // // Set up for a new username. // gpre_usn* MSC_username(SCHAR* name, USHORT name_dyn) { gpre_usn* username = (gpre_usn*) MSC_alloc(USN_LEN); username->usn_name = (SCHAR*) MSC_alloc(strlen(name) + 1); strcpy(username->usn_name, name); username->usn_dyn = name_dyn; username->usn_next = 0; return username; }