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

525 lines
11 KiB
C++
Raw Normal View History

2001-05-23 15:26:42 +02:00
//____________________________________________________________
//
// 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
//
//
//____________________________________________________________
//
2004-05-12 21:39:17 +02:00
// $Id: msc.cpp,v 1.21 2004-05-12 19:34:43 brodsom Exp $
2001-05-23 15:26:42 +02:00
//
//
//
// ***************************************************
// 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:
//
2003-10-16 10:51:06 +02:00
// dsql/all.cpp
// jrd/all.cpp
// pipe/allp.cpp
// qli/all.cpp
// remote/allr.cpp
// gpre/msc.cpp
2001-05-23 15:26:42 +02:00
//
// - THANK YOU
//**************************************************
#include "firebird.h"
2004-04-29 00:36:29 +02:00
#include <stdio.h>
2001-05-23 15:26:42 +02:00
#include <string.h>
#include "../gpre/gpre.h"
#include "../gpre/parse.h"
#include "../gpre/gpre_proto.h"
#include "../gpre/msc_proto.h"
#include "../jrd/gds_proto.h"
extern act* cur_routine;
2001-05-23 15:26:42 +02:00
typedef struct spc {
2003-09-05 12:14:08 +02:00
spc* spc_next;
2001-05-23 15:26:42 +02:00
SLONG spc_remaining;
} *SPC;
static SPC space, permanent_space;
2004-02-02 12:02:12 +01:00
static gpre_lls* free_lls;
2001-05-23 15:26:42 +02:00
//____________________________________________________________
//
// Make an action and link it to a request.
//
act* MSC_action( gpre_req* request, enum act_t type)
2001-05-23 15:26:42 +02:00
{
act* action = (act*) MSC_alloc(ACT_LEN);
2001-05-23 15:26:42 +02:00
action->act_type = type;
if (request) {
action->act_next = request->req_actions;
request->req_actions = action;
action->act_request = request;
}
return action;
}
//____________________________________________________________
//
//
2003-10-16 10:51:06 +02:00
UCHAR* MSC_alloc(int size)
2001-05-23 15:26:42 +02:00
{
size = FB_ALIGN(size, ALIGNMENT);
if (!space || size > space->spc_remaining) {
2003-10-16 10:51:06 +02:00
const int n = MAX(size, 4096);
SPC next = (SPC) gds__alloc((SLONG) (n + sizeof(spc)));
if (!next)
2001-05-23 15:26:42 +02:00
CPR_error("virtual memory exhausted");
#ifdef DEBUG_GDS_ALLOC
// For V4.0 we don't care about gpre specific memory leaks
2001-05-23 15:26:42 +02:00
gds_alloc_flag_unfreed(next);
#endif
next->spc_next = space;
next->spc_remaining = n;
space = next;
}
space->spc_remaining -= size;
2003-10-16 10:51:06 +02:00
UCHAR* const blk = ((UCHAR*) space + sizeof(spc) + space->spc_remaining);
UCHAR* p = blk;
const UCHAR* const end = p + size;
2001-05-23 15:26:42 +02:00
while (p < end)
*p++ = 0;
return blk;
}
//____________________________________________________________
//
// Allocate a block in permanent memory.
//
2003-10-16 10:51:06 +02:00
UCHAR* MSC_alloc_permanent(int size)
2001-05-23 15:26:42 +02:00
{
size = FB_ALIGN(size, ALIGNMENT);
if (!permanent_space || size > permanent_space->spc_remaining) {
2003-10-16 10:51:06 +02:00
const int n = MAX(size, 4096);
SPC next = (SPC) gds__alloc((SLONG) (n + sizeof(spc)));
if (!next)
2001-05-23 15:26:42 +02:00
CPR_error("virtual memory exhausted");
#ifdef DEBUG_GDS_ALLOC
// For V4.0 we don't care about gpre specific memory leaks
2001-05-23 15:26:42 +02:00
gds_alloc_flag_unfreed(next);
#endif
next->spc_next = permanent_space;
next->spc_remaining = n;
permanent_space = next;
}
permanent_space->spc_remaining -= size;
2003-10-16 10:51:06 +02:00
UCHAR* const blk = ((UCHAR*) permanent_space + sizeof(spc) +
2001-05-23 15:26:42 +02:00
permanent_space->spc_remaining);
2003-10-16 10:51:06 +02:00
UCHAR* p = blk;
const UCHAR* const end = p + size;
2001-05-23 15:26:42 +02:00
while (p < end)
*p++ = 0;
return blk;
}
//____________________________________________________________
//
// Make a binary node.
//
2002-11-11 20:19:43 +01:00
GPRE_NOD MSC_binary(NOD_T type, GPRE_NOD arg1, GPRE_NOD arg2)
2001-05-23 15:26:42 +02:00
{
2003-10-16 10:51:06 +02:00
GPRE_NOD node = MSC_node(type, 2);
2001-05-23 15:26:42 +02:00
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)
2001-05-23 15:26:42 +02:00
{
2003-10-16 10:51:06 +02:00
// allocate and initialize
2001-05-23 15:26:42 +02:00
gpre_ctx* context = (gpre_ctx*) MSC_alloc(CTX_LEN);
2001-05-23 15:26:42 +02:00
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)
2001-05-23 15:26:42 +02:00
{
if (length)
2003-10-16 10:51:06 +02:00
do {
2001-05-23 15:26:42 +02:00
*to++ = *from++;
2003-10-16 10:51:06 +02:00
} while (--length);
2001-05-23 15:26:42 +02:00
*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)
2003-10-16 10:51:06 +02:00
do {
*to++ = *from1++;
2003-10-16 10:51:06 +02:00
} while (--length1);
if (length2)
2003-10-16 10:51:06 +02:00
do {
*to++ = *from2++;
2003-10-16 10:51:06 +02:00
} while (--length2);
*to = 0;
}
2001-05-23 15:26:42 +02:00
//____________________________________________________________
//
// Find a symbol of a particular type.
//
gpre_sym* MSC_find_symbol(gpre_sym* symbol, enum sym_t type)
2001-05-23 15:26:42 +02:00
{
for (; symbol; symbol = symbol->sym_homonym)
if (symbol->sym_type == type)
return symbol;
return NULL;
}
//____________________________________________________________
//
// Free a block.
//
2003-10-16 10:51:06 +02:00
void MSC_free( UCHAR* block)
2001-05-23 15:26:42 +02:00
{
}
//____________________________________________________________
//
// Get rid of an erroroneously allocated request block.
//
void MSC_free_request( gpre_req* request)
2001-05-23 15:26:42 +02:00
{
requests = request->req_next;
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;
2003-10-16 10:51:06 +02:00
SPC stuff;
2001-05-23 15:26:42 +02:00
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.
//
2003-09-11 04:13:46 +02:00
bool MSC_match(KWWORDS keyword)
2001-05-23 15:26:42 +02:00
{
2004-05-12 21:39:17 +02:00
if (token_global.tok_keyword == KW_none && token_global.tok_symbol) {
gpre_sym* symbol;
2004-05-12 21:39:17 +02:00
for (symbol = token_global.tok_symbol->sym_collision; symbol;
2003-09-05 16:55:59 +02:00
symbol = symbol->sym_collision)
{
2004-05-12 21:39:17 +02:00
if ((strcmp(symbol->sym_string, token_global.tok_string) ==
2003-09-05 16:55:59 +02:00
0) && symbol->sym_keyword != KW_none)
{
2004-05-12 21:39:17 +02:00
token_global.tok_symbol = symbol;
token_global.tok_keyword = static_cast < kwwords > (symbol->sym_keyword);
2001-05-23 15:26:42 +02:00
}
2003-09-05 16:55:59 +02:00
}
2001-05-23 15:26:42 +02:00
}
2004-05-12 21:39:17 +02:00
if ((int) token_global.tok_keyword != (int) keyword)
2003-09-11 04:13:46 +02:00
return false;
2001-05-23 15:26:42 +02:00
CPR_token();
2003-09-11 04:13:46 +02:00
return true;
2001-05-23 15:26:42 +02:00
}
2003-09-11 04:13:46 +02:00
#ifdef NOT_USED_OR_REPLACED
2001-05-23 15:26:42 +02:00
//____________________________________________________________
//
// Determinate where a specific object is
// represented on a linked list stack.
//
2004-02-02 12:02:12 +01:00
bool MSC_member(GPRE_NOD object, gpre_lls* stack)
2001-05-23 15:26:42 +02:00
{
for (; stack; stack = stack->lls_next)
if (stack->lls_object == object)
return true;
2001-05-23 15:26:42 +02:00
return false;
2001-05-23 15:26:42 +02:00
}
2003-09-11 04:13:46 +02:00
#endif
2001-05-23 15:26:42 +02:00
//____________________________________________________________
//
// Allocate an initialize a syntax node.
//
2002-11-11 20:19:43 +01:00
GPRE_NOD MSC_node(enum nod_t type, SSHORT count)
2001-05-23 15:26:42 +02:00
{
2003-10-16 10:51:06 +02:00
GPRE_NOD node = (GPRE_NOD) MSC_alloc(NOD_LEN(count));
2001-05-23 15:26:42 +02:00
node->nod_count = count;
node->nod_type = type;
return node;
}
//____________________________________________________________
//
// Pop an item off a linked list stack. Free the stack node.
//
2004-02-02 12:02:12 +01:00
GPRE_NOD MSC_pop(gpre_lls** pointer)
2001-05-23 15:26:42 +02:00
{
2004-02-02 12:02:12 +01:00
gpre_lls* stack = *pointer;
2003-10-16 10:51:06 +02:00
GPRE_NOD node = stack->lls_object;
2001-05-23 15:26:42 +02:00
*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)
{
2003-10-16 10:51:06 +02:00
PRV privilege_block = (PRV) MSC_alloc(PRV_LEN);
2001-05-23 15:26:42 +02:00
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.
//
2004-02-02 12:02:12 +01:00
void MSC_push( GPRE_NOD object, gpre_lls** pointer)
2001-05-23 15:26:42 +02:00
{
2004-02-02 12:02:12 +01:00
gpre_lls* stack = free_lls;
2003-10-16 10:51:06 +02:00
if (stack)
2001-05-23 15:26:42 +02:00
free_lls = stack->lls_next;
else
2004-02-02 12:02:12 +01:00
stack = (gpre_lls*) MSC_alloc(LLS_LEN);
2001-05-23 15:26:42 +02:00
stack->lls_object = object;
stack->lls_next = *pointer;
*pointer = stack;
}
//____________________________________________________________
//
// Generate a reference and possibly link the reference into
// a linked list.
//
2003-10-16 10:51:06 +02:00
REF MSC_reference(REF* link)
2001-05-23 15:26:42 +02:00
{
2003-10-16 10:51:06 +02:00
REF reference = (REF) MSC_alloc(REF_LEN);
2001-05-23 15:26:42 +02:00
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)
2001-05-23 15:26:42 +02:00
{
gpre_req* request = (gpre_req*) MSC_alloc(REQ_LEN);
2001-05-23 15:26:42 +02:00
request->req_type = type;
request->req_next = requests;
requests = request;
request->req_routine = (gpre_req*) cur_routine->act_object;
2001-05-23 15:26:42 +02:00
cur_routine->act_object = (REF) request;
if (!(cur_routine->act_flags & ACT_main))
request->req_flags |= REQ_local;
if (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)
2001-05-23 15:26:42 +02:00
{
2003-10-15 03:18:01 +02:00
TEXT* string = (TEXT*) MSC_alloc(strlen(input) + 1);
2001-05-23 15:26:42 +02:00
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)
2001-05-23 15:26:42 +02:00
{
gpre_sym* symbol = (gpre_sym*) MSC_alloc(SYM_LEN + length);
2001-05-23 15:26:42 +02:00
symbol->sym_type = type;
symbol->sym_object = object;
TEXT* p = symbol->sym_name;
symbol->sym_string = p;
2001-05-23 15:26:42 +02:00
if (length)
do {
2001-05-23 15:26:42 +02:00
*p++ = *string++;
} while (--length);
2001-05-23 15:26:42 +02:00
return symbol;
}
//____________________________________________________________
//
// Make a unary node.
//
2002-11-11 20:19:43 +01:00
GPRE_NOD MSC_unary(NOD_T type, GPRE_NOD arg)
2001-05-23 15:26:42 +02:00
{
2003-10-16 10:51:06 +02:00
GPRE_NOD node = MSC_node(type, 1);
2001-05-23 15:26:42 +02:00
node->nod_arg[0] = arg;
return node;
}
//____________________________________________________________
//
// Set up for a new username.
//
gpre_usn* MSC_username(SCHAR* name, USHORT name_dyn)
2001-05-23 15:26:42 +02:00
{
gpre_usn* username = (gpre_usn*) MSC_alloc(USN_LEN);
2003-10-16 10:51:06 +02:00
username->usn_name = (SCHAR*) MSC_alloc(strlen(name) + 1);
2001-05-23 15:26:42 +02:00
strcpy(username->usn_name, name);
username->usn_dyn = name_dyn;
username->usn_next = 0;
return username;
}