8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-25 05:23:02 +01:00
firebird-mirror/src/gpre/msc.cpp

522 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
//
//
//____________________________________________________________
//
// $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 <stdio.h>
#include <string.h>
#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;
}