8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 19:23:02 +01:00
firebird-mirror/src/gpre/msc.cpp
2014-12-21 13:45:26 +00:00

523 lines
11 KiB
C++

//____________________________________________________________
//
// 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
//
//
//____________________________________________________________
//
//
//
//
// ***************************************************
// 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:
//
// qli/all.cpp
// gpre/msc.cpp
//
// - THANK YOU
// **************************************************
#include "firebird.h"
#include <stdio.h>
#include <string.h>
#include "../gpre/gpre.h"
#include "../gpre/gpre_proto.h"
#include "../gpre/msc_proto.h"
#include "../yvalve/gds_proto.h"
struct gpre_space
{
gpre_space* spc_next;
SLONG spc_remaining;
};
static gpre_space* space;
static gpre_space* permanent_space;
static gpre_lls* free_lls;
//____________________________________________________________
//
// Make an action and link it to a request.
//
act* MSC_action( gpre_req* request, 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, FB_ALIGNMENT);
if (!space || size > space->spc_remaining)
{
const int n = MAX(size, 4096);
gpre_space* next = (gpre_space*) gds__alloc((SLONG) (n + sizeof(gpre_space)));
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* blk = ((UCHAR*) space + sizeof(gpre_space) + space->spc_remaining);
memset(blk, 0, size);
return blk;
}
//____________________________________________________________
//
// Allocate a block in permanent memory.
//
UCHAR* MSC_alloc_permanent(int size)
{
size = FB_ALIGN(size, FB_ALIGNMENT);
if (!permanent_space || size > permanent_space->spc_remaining)
{
const int n = MAX(size, 4096);
gpre_space* next = (gpre_space*) gds__alloc((SLONG) (n + sizeof(gpre_space)));
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* blk = (UCHAR*) permanent_space + sizeof(gpre_space) + permanent_space->spc_remaining;
memset(blk, 0, size);
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)
memcpy(to, from, length);
to[length] = 0;
}
//____________________________________________________________
//
// Copy two strings into another.
//
void MSC_copy_cat(const char* from1, int length1, const char* from2, int length2, char* to)
{
if (length1)
memcpy(to, from1, length1);
if (length2)
memcpy(to + length1, from2, length2);
to[length1 + length2] = 0;
}
//____________________________________________________________
//
// Find a symbol of a particular type.
//
gpre_sym* MSC_find_symbol(gpre_sym* symbol, sym_t type)
{
for (; symbol; symbol = symbol->sym_homonym)
if (symbol->sym_type == type)
return symbol;
return NULL;
}
//____________________________________________________________
//
// Free a block.
//
void MSC_free(void*)
{
}
//____________________________________________________________
//
// 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(request);
}
//____________________________________________________________
//
// Initialize (or more properly, re-initialize) the memory
// allocator.
//
void MSC_init()
{
free_lls = NULL;
gpre_space* 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(const kwwords_t 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_t>(symbol->sym_keyword);
}
}
}
if (gpreGlob.token_global.tok_keyword != 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(const gpre_nod* object, const gpre_lls* stack)
{
for (; stack; stack = stack->lls_next)
if (stack->lls_object == object)
return true;
return false;
}
#endif
//____________________________________________________________
//
// Allocate and initialize a syntax node.
//
gpre_nod* MSC_node(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()
{
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(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(static_cast<int>(strlen(input) + 1));
strcpy(string, input);
return string;
}
//____________________________________________________________
//
// Allocate and initialize a symbol block.
//
gpre_sym* MSC_symbol(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)
memcpy(p, string, length);
return symbol;
}
//____________________________________________________________
//
// Make a ternary node.
//
gpre_nod* MSC_ternary(nod_t type, gpre_nod* arg1, gpre_nod* arg2, gpre_nod* arg3)
{
gpre_nod* node = MSC_node(type, 3);
node->nod_arg[0] = arg1;
node->nod_arg[1] = arg2;
node->nod_arg[2] = arg3;
return node;
}
//____________________________________________________________
//
// 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(const SCHAR* name, USHORT name_dyn)
{
gpre_usn* username = (gpre_usn*) MSC_alloc(USN_LEN);
char* newname = (char*) MSC_alloc(static_cast<int>(strlen(name) + 1));
username->usn_name = newname;
strcpy(newname, name);
username->usn_dyn = name_dyn;
username->usn_next = 0;
return username;
}