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

911 lines
19 KiB
C++
Raw Normal View History

2001-05-23 15:26:42 +02:00
//____________________________________________________________
//
// PROGRAM: BLR Pretty Printer
// MODULE: pretty.cpp
// DESCRIPTION: BLR Pretty Printer
//
// 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: pretty.cpp,v 1.26 2004-05-23 23:24:42 brodsom Exp $
2001-05-23 15:26:42 +02:00
//
#include "firebird.h"
2004-04-29 00:36:29 +02:00
#include <stdio.h>
2001-05-23 15:26:42 +02:00
#include "../jrd/common.h"
#include <stdarg.h>
2003-11-08 17:40:17 +01:00
#include "../jrd/ibase.h"
#include "../jrd/constants.h"
2001-05-23 15:26:42 +02:00
#include "../gpre/prett_proto.h"
#include "../jrd/gds_proto.h"
#define ADVANCE_PTR(ptr) while (*ptr) ptr++;
2004-05-18 23:54:56 +02:00
//#define PRINT_VERB if (print_verb (control, level)) return -1
2001-05-23 15:26:42 +02:00
#define PRINT_DYN_VERB if (print_dyn_verb (control, level)) return -1
#define PRINT_SDL_VERB if (print_sdl_verb (control, level)) return -1
#define BLR_BYTE *(control->ctl_blr)++
#define PUT_BYTE(byte) *(control->ctl_ptr)++ = byte
#define NEXT_BYTE *(control->ctl_blr)
2004-05-18 23:54:56 +02:00
#define CHECK_BUFFER if (control->ctl_ptr > control->ctl_buffer + sizeof (control->ctl_buffer) - 20) print_line(control, (SSHORT)offset)
2001-05-23 15:26:42 +02:00
typedef struct ctl {
UCHAR *ctl_blr; // Running blr string
UCHAR *ctl_blr_start; // Original start of blr string
FPTR_PRINT_CALLBACK ctl_routine; // Call back
void *ctl_user_arg; // User argument
2001-05-23 15:26:42 +02:00
TEXT *ctl_ptr;
SSHORT ctl_language;
SSHORT ctl_level;
TEXT ctl_buffer[PRETTY_BUFFER_SIZE];
2001-05-23 15:26:42 +02:00
} *CTL;
static int blr_format(CTL, const char *, ...);
2004-05-18 23:54:56 +02:00
static int error(CTL, SSHORT, TEXT *, int);
2001-05-23 15:26:42 +02:00
static int indent(CTL, SSHORT);
static int print_blr_dtype(CTL, bool);
static void print_blr_line(void*, SSHORT, const char*);
2001-05-23 15:26:42 +02:00
static int print_byte(CTL, SSHORT);
static int print_char(CTL, SSHORT);
static int print_dyn_verb(CTL, SSHORT);
static int print_line(CTL, SSHORT);
static SLONG print_long(CTL, SSHORT);
static int print_sdl_verb(CTL, SSHORT);
static int print_string(CTL, SSHORT);
static int print_word(CTL, SSHORT);
const char *dyn_table[] = {
#include "../gpre/dyntable.h"
NULL
};
const char *cdb_table[] = {
#include "../gpre/cdbtable.h"
NULL
};
const char *sdl_table[] = {
#include "../gpre/sdltable.h"
NULL
};
const char *map_strings[] = {
"FIELD2",
"FIELD1",
"MESSAGE",
"TERMINATOR",
"TERMINATING_FIELD",
"OPAQUE",
"TRANSPARENT",
"TAG",
"SUB_FORM",
"ITEM_INDEX",
"SUB_FIELD"
};
//____________________________________________________________
//
// Pretty print create database parameter buffer thru callback routine.
//
int PRETTY_print_cdb( UCHAR* blr,
FPTR_PRINT_CALLBACK routine,
void* user_arg, SSHORT language)
2001-05-23 15:26:42 +02:00
{
2003-09-05 12:14:08 +02:00
ctl ctl_buffer;
ctl* control = &ctl_buffer;
2001-05-23 15:26:42 +02:00
SCHAR temp[32];
SSHORT parameter;
SSHORT level = 0;
SSHORT length;
SSHORT i;
2004-05-18 23:54:56 +02:00
SSHORT offset = 0;
2001-05-23 15:26:42 +02:00
if (!routine) {
routine = gds__default_printer;
user_arg = NULL;
2001-05-23 15:26:42 +02:00
}
control->ctl_routine = routine;
2001-05-23 15:26:42 +02:00
control->ctl_user_arg = user_arg;
control->ctl_blr = control->ctl_blr_start = blr;
control->ctl_ptr = control->ctl_buffer;
control->ctl_language = language;
indent(control, level);
i = BLR_BYTE;
if (*control->ctl_blr)
sprintf(temp, "gds__dpb_version%d, ", i);
2001-05-23 15:26:42 +02:00
else
sprintf(temp, "gds__dpb_version%d", i);
2001-05-23 15:26:42 +02:00
blr_format(control, temp);
2004-05-18 23:54:56 +02:00
print_line(control, offset);
2001-05-23 15:26:42 +02:00
while (parameter = BLR_BYTE) {
const char *p;
if (parameter > FB_NELEM(cdb_table) ||
2001-05-23 15:26:42 +02:00
!(p = cdb_table[parameter])) {
return error(control, 0,
"*** cdb parameter %d is undefined ***\n",
2003-04-02 13:49:35 +02:00
parameter);
2001-05-23 15:26:42 +02:00
}
indent(control, level);
blr_format(control, p);
PUT_BYTE(',');
2004-05-18 23:54:56 +02:00
if (length = print_byte(control, offset)) {
2001-05-23 15:26:42 +02:00
do {
2004-05-18 23:54:56 +02:00
print_char(control, offset);
2001-05-23 15:26:42 +02:00
} while (--length);
}
2004-05-18 23:54:56 +02:00
print_line(control, offset);
2001-05-23 15:26:42 +02:00
}
return 0;
}
int PRETTY_print_dyn(
UCHAR* blr,
2001-05-23 15:26:42 +02:00
//____________________________________________________________
//
// Pretty print dynamic DDL thru callback routine.
//
FPTR_PRINT_CALLBACK routine,
void* user_arg, SSHORT language)
2001-05-23 15:26:42 +02:00
{
2003-09-05 12:14:08 +02:00
ctl ctl_buffer;
ctl* control = &ctl_buffer;
2004-05-18 23:54:56 +02:00
SSHORT offset = 0;
SSHORT version = 0;
SSHORT level = 0;
2001-05-23 15:26:42 +02:00
if (!routine) {
routine = gds__default_printer;
user_arg = NULL;
2001-05-23 15:26:42 +02:00
}
control->ctl_routine = routine;
2001-05-23 15:26:42 +02:00
control->ctl_user_arg = user_arg;
control->ctl_blr = control->ctl_blr_start = blr;
control->ctl_ptr = control->ctl_buffer;
control->ctl_language = language;
version = BLR_BYTE;
2003-11-08 17:40:17 +01:00
if (version != isc_dyn_version_1)
2001-05-23 15:26:42 +02:00
return error(control, offset,
"*** dyn version %d is not supported ***\n",
2003-04-02 13:49:35 +02:00
version);
2001-05-23 15:26:42 +02:00
blr_format(control, "gds__dyn_version_1, ");
2004-05-18 23:54:56 +02:00
print_line(control, offset);
2001-05-23 15:26:42 +02:00
level++;
PRINT_DYN_VERB;
2003-11-08 17:40:17 +01:00
if (BLR_BYTE != isc_dyn_eoc)
2001-05-23 15:26:42 +02:00
return error(control, offset,
"*** expected dyn end-of-command ***\n", 0);
blr_format(control, "gds__dyn_eoc");
2004-05-18 23:54:56 +02:00
print_line(control, offset);
2001-05-23 15:26:42 +02:00
return 0;
}
2001-07-12 07:46:06 +02:00
int
PRETTY_print_sdl(UCHAR* blr,
2001-05-23 15:26:42 +02:00
//____________________________________________________________
//
// Pretty print slice description language.
//
FPTR_PRINT_CALLBACK routine,
void *user_arg, SSHORT language)
2001-05-23 15:26:42 +02:00
{
2003-09-05 12:14:08 +02:00
ctl ctl_buffer;
ctl* control = &ctl_buffer;
2004-05-18 23:54:56 +02:00
SSHORT offset = 0;
SSHORT version;
SSHORT level = 0;
2001-05-23 15:26:42 +02:00
if (!routine) {
routine = gds__default_printer;
user_arg = NULL;
2001-05-23 15:26:42 +02:00
}
control->ctl_routine = routine;
2001-05-23 15:26:42 +02:00
control->ctl_user_arg = user_arg;
control->ctl_blr = control->ctl_blr_start = blr;
control->ctl_ptr = control->ctl_buffer;
control->ctl_language = language;
version = BLR_BYTE;
2003-11-08 17:40:17 +01:00
if (version != isc_sdl_version1)
2001-05-23 15:26:42 +02:00
return error(control, offset,
"*** sdl version %d is not supported ***\n",
2003-04-02 13:49:35 +02:00
version);
2001-05-23 15:26:42 +02:00
blr_format(control, "gds__sdl_version1, ");
2004-05-18 23:54:56 +02:00
print_line(control, offset);
2001-05-23 15:26:42 +02:00
level++;
2003-11-08 17:40:17 +01:00
while (NEXT_BYTE != isc_sdl_eoc)
2001-05-23 15:26:42 +02:00
PRINT_SDL_VERB;
offset = control->ctl_blr - control->ctl_blr_start;
blr_format(control, "gds__sdl_eoc");
2004-05-18 23:54:56 +02:00
print_line(control, offset);
2001-05-23 15:26:42 +02:00
return 0;
}
//____________________________________________________________
//
// Format an utterance.
//
static int blr_format(CTL control, const char *string, ...)
{
va_list ptr;
va_start(ptr, string);
2001-05-23 15:26:42 +02:00
vsprintf(control->ctl_ptr, string, ptr);
while (*control->ctl_ptr)
control->ctl_ptr++;
return 0;
}
//____________________________________________________________
//
// Put out an error msg and punt.
//
2004-05-18 23:54:56 +02:00
static int error( CTL control, SSHORT offset, TEXT * string, int arg)
2001-05-23 15:26:42 +02:00
{
2004-05-18 23:54:56 +02:00
print_line(control, offset);
2001-05-23 15:26:42 +02:00
sprintf(control->ctl_ptr, string, arg);
2004-04-29 00:36:29 +02:00
fprintf(stderr, control->ctl_ptr);
2001-05-23 15:26:42 +02:00
ADVANCE_PTR(control->ctl_ptr);
2004-05-18 23:54:56 +02:00
print_line(control, offset);
2001-05-23 15:26:42 +02:00
return -1;
}
//____________________________________________________________
//
// Indent for pretty printing.
//
static int indent( CTL control, SSHORT level)
{
level *= 3;
while (--level >= 0)
PUT_BYTE(' ');
return 0;
}
//____________________________________________________________
//
// Print a datatype sequence and return the length of the
// data described.
//
static int print_blr_dtype(CTL control,
bool print_object)
2001-05-23 15:26:42 +02:00
{
unsigned short dtype;
SCHAR *string;
SSHORT length;
// TMN: FIX FIX Note that offset is not initialized to anything useful
2004-05-18 23:54:56 +02:00
// for e.g. print_word(control, (SSHORT)offset). I assume it's better to initialize it to zero
2001-05-23 15:26:42 +02:00
// than letting it be random.
//
SSHORT offset = 0;
dtype = BLR_BYTE;
// Special case blob (261) to keep down the size of the
// jump table
switch (dtype) {
case blr_short:
string = "short";
length = 2;
break;
case blr_long:
string = "long";
length = 4;
break;
case blr_quad:
string = "quad";
length = 8;
break;
// ** Begin date/time/timestamp *
case blr_sql_date:
string = "sql_date";
length = sizeof(ISC_DATE);
break;
case blr_sql_time:
string = "sql_time";
length = sizeof(ISC_TIME);
break;
case blr_timestamp:
string = "timestamp";
length = sizeof(ISC_TIMESTAMP);
break;
// ** End date/time/timestamp *
case blr_int64:
string = "int64";
length = sizeof(ISC_INT64);
break;
case blr_float:
string = "float";
length = 4;
break;
case blr_double:
string = "double";
length = 8;
break;
case blr_d_float:
string = "d_float";
length = 8;
break;
case blr_text:
string = "text";
break;
case blr_cstring:
string = "cstring";
break;
case blr_varying:
string = "varying";
break;
case blr_text2:
string = "text2";
break;
case blr_cstring2:
string = "cstring2";
break;
case blr_varying2:
string = "varying2";
break;
case blr_blob_id:
string = "blob_id";
length = 8;
break;
default:
error(control, 0, "*** invalid data type ***", 0);
}
blr_format(control, "blr_%s, ", string);
if (!print_object)
return length;
switch (dtype) {
case blr_text:
2004-05-18 23:54:56 +02:00
length = print_word(control, offset);
2001-05-23 15:26:42 +02:00
break;
case blr_varying:
2004-05-18 23:54:56 +02:00
length = print_word(control, offset) + 2;
2001-05-23 15:26:42 +02:00
break;
case blr_text2:
2004-05-18 23:54:56 +02:00
print_word(control, offset);
length = print_word(control, offset);
2001-05-23 15:26:42 +02:00
break;
case blr_varying2:
2004-05-18 23:54:56 +02:00
print_word(control, offset);
length = print_word(control, offset) + 2;
2001-05-23 15:26:42 +02:00
break;
case blr_short:
case blr_long:
2002-12-13 15:50:23 +01:00
case blr_int64:
2001-05-23 15:26:42 +02:00
case blr_quad:
2004-05-18 23:54:56 +02:00
print_byte(control, offset);
2001-05-23 15:26:42 +02:00
break;
case blr_blob_id:
2004-05-18 23:54:56 +02:00
print_word(control, offset);
2001-05-23 15:26:42 +02:00
break;
default:
if (dtype == blr_cstring)
2004-05-18 23:54:56 +02:00
length = print_word(control, offset);
2001-05-23 15:26:42 +02:00
if (dtype == blr_cstring2) {
2004-05-18 23:54:56 +02:00
print_word(control, offset);
length = print_word(control, offset);
2001-05-23 15:26:42 +02:00
}
break;
}
return length;
}
//____________________________________________________________
//
// Print a line of pretty-printed BLR.
//
static void print_blr_line(void* arg, SSHORT offset, const char* line)
2001-05-23 15:26:42 +02:00
{
CTL control = reinterpret_cast<CTL>(arg);
bool comma = false;
char c;
2001-05-23 15:26:42 +02:00
indent(control, control->ctl_level);
while (c = *line++) {
PUT_BYTE(c);
if (c == ',')
comma = true;
2001-05-23 15:26:42 +02:00
else if (c != ' ')
comma = false;
2001-05-23 15:26:42 +02:00
}
if (!comma)
PUT_BYTE(',');
2004-05-18 23:54:56 +02:00
print_line(control, offset);
2001-05-23 15:26:42 +02:00
}
//____________________________________________________________
//
// Print a byte as a numeric value and return same.
//
static int print_byte( CTL control, SSHORT offset)
{
UCHAR v;
v = BLR_BYTE;
sprintf(control->ctl_ptr, (control->ctl_language) ? "chr(%d), " : "%d, ",
v);
ADVANCE_PTR(control->ctl_ptr);
return v;
}
//____________________________________________________________
//
// Print a byte as a numeric value and return same.
//
static int print_char( CTL control, SSHORT offset)
{
UCHAR c;
SSHORT printable;
c = BLR_BYTE;
printable = (c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9' || c == '$' || c == '_');
sprintf(control->ctl_ptr, (printable) ?
"'%c'," : (control->ctl_language) ? "chr(%d)," : "%d,", c);
ADVANCE_PTR(control->ctl_ptr);
CHECK_BUFFER;
return c;
}
//____________________________________________________________
//
// Primary recursive routine to print dynamic DDL.
//
static int print_dyn_verb( CTL control, SSHORT level)
{
2004-05-18 23:54:56 +02:00
SSHORT offset = control->ctl_blr - control->ctl_blr_start;
2004-02-02 12:02:12 +01:00
const UCHAR dyn_operator = BLR_BYTE;
2001-05-23 15:26:42 +02:00
2003-12-22 11:00:59 +01:00
const char* p;
const int size = FB_NELEM(dyn_table);
2004-02-02 12:02:12 +01:00
if (dyn_operator > size || dyn_operator <= 0 || !(p = dyn_table[dyn_operator])) {
2001-05-23 15:26:42 +02:00
return error(control, offset,
"*** dyn operator %d is undefined ***\n",
2004-02-02 12:02:12 +01:00
(int) dyn_operator);
2003-12-22 11:00:59 +01:00
}
2001-05-23 15:26:42 +02:00
indent(control, level);
blr_format(control, p);
PUT_BYTE(',');
PUT_BYTE(' ');
++level;
2003-12-22 11:00:59 +01:00
int length;
2004-02-02 12:02:12 +01:00
switch (dyn_operator) {
case isc_dyn_drop_difference:
case isc_dyn_begin_backup:
case isc_dyn_end_backup:
return 0;
2003-11-08 17:40:17 +01:00
case isc_dyn_begin:
case isc_dyn_mod_database:
2004-05-18 23:54:56 +02:00
print_line(control, offset);
2003-11-08 17:40:17 +01:00
while (NEXT_BYTE != isc_dyn_end)
2001-05-23 15:26:42 +02:00
PRINT_DYN_VERB;
PRINT_DYN_VERB;
return 0;
2003-11-08 17:40:17 +01:00
case isc_dyn_view_blr:
case isc_dyn_fld_validation_blr:
case isc_dyn_fld_computed_blr:
case isc_dyn_trg_blr:
case isc_dyn_fld_missing_value:
case isc_dyn_prc_blr:
case isc_dyn_fld_default_value:
2004-05-18 23:54:56 +02:00
length = print_word(control, offset);
print_line(control, offset);
2001-05-23 15:26:42 +02:00
if (length) {
control->ctl_level = level;
2003-12-22 11:00:59 +01:00
gds__print_blr((const UCHAR*) control->ctl_blr,
print_blr_line, control,
2001-05-23 15:26:42 +02:00
control->ctl_language);
control->ctl_blr += length;
}
return 0;
2003-11-08 17:40:17 +01:00
case isc_dyn_scl_acl:
case isc_dyn_log_check_point_length:
case isc_dyn_log_num_of_buffers:
case isc_dyn_log_buffer_size:
case isc_dyn_log_group_commit_wait:
case isc_dyn_idx_inactive:
2004-05-18 23:54:56 +02:00
length = print_word(control, offset);
2001-05-23 15:26:42 +02:00
while (length--)
2004-05-18 23:54:56 +02:00
print_byte(control, offset);
print_line(control, offset);
2001-05-23 15:26:42 +02:00
return 0;
2003-11-08 17:40:17 +01:00
case isc_dyn_view_source:
case isc_dyn_fld_validation_source:
case isc_dyn_fld_computed_source:
case isc_dyn_description:
case isc_dyn_prc_source:
case isc_dyn_fld_default_source:
2004-05-18 23:54:56 +02:00
length = print_word(control, offset);
2001-05-23 15:26:42 +02:00
while (length--)
2004-05-18 23:54:56 +02:00
print_char(control, offset);
print_line(control, offset);
2001-05-23 15:26:42 +02:00
return 0;
2003-11-08 17:40:17 +01:00
case isc_dyn_del_exception:
2004-05-18 23:54:56 +02:00
if (length = print_word(control, offset))
2003-12-22 11:00:59 +01:00
do {
2004-05-18 23:54:56 +02:00
print_char(control, offset);
2003-12-22 11:00:59 +01:00
} while (--length);
2001-05-23 15:26:42 +02:00
return 0;
2003-11-08 17:40:17 +01:00
case isc_dyn_fld_not_null:
case isc_dyn_sql_object:
case isc_dyn_drop_log:
case isc_dyn_drop_cache:
case isc_dyn_def_default_log:
case isc_dyn_log_file_serial:
case isc_dyn_log_file_raw:
case isc_dyn_log_file_overflow:
case isc_dyn_single_validation:
case isc_dyn_del_default:
case isc_dyn_del_validation:
case isc_dyn_idx_statistic:
case isc_dyn_foreign_key_delete:
case isc_dyn_foreign_key_update:
case isc_dyn_foreign_key_cascade:
case isc_dyn_foreign_key_default:
case isc_dyn_foreign_key_null:
case isc_dyn_foreign_key_none:
2001-05-23 15:26:42 +02:00
2004-05-18 23:54:56 +02:00
print_line(control, offset);
2001-05-23 15:26:42 +02:00
return 0;
2003-11-08 17:40:17 +01:00
case isc_dyn_end:
2004-05-18 23:54:56 +02:00
print_line(control, offset);
2001-05-23 15:26:42 +02:00
return 0;
}
2004-05-18 23:54:56 +02:00
if (length = print_word(control, offset))
2003-12-22 11:00:59 +01:00
do {
2004-05-18 23:54:56 +02:00
print_char(control, offset);
2003-12-22 11:00:59 +01:00
} while (--length);
2001-05-23 15:26:42 +02:00
2004-05-18 23:54:56 +02:00
print_line(control, offset);
2001-05-23 15:26:42 +02:00
2004-02-02 12:02:12 +01:00
switch (dyn_operator) {
2003-11-08 17:40:17 +01:00
case isc_dyn_def_database:
case isc_dyn_def_dimension:
case isc_dyn_def_exception:
case isc_dyn_def_file:
case isc_dyn_def_log_file:
case isc_dyn_def_cache_file:
case isc_dyn_def_filter:
case isc_dyn_def_function:
case isc_dyn_def_function_arg:
case isc_dyn_def_generator:
case isc_dyn_def_global_fld:
case isc_dyn_def_idx:
case isc_dyn_def_local_fld:
case isc_dyn_def_rel:
case isc_dyn_def_procedure:
case isc_dyn_def_parameter:
case isc_dyn_def_security_class:
case isc_dyn_def_shadow:
case isc_dyn_def_sql_fld:
case isc_dyn_def_trigger:
case isc_dyn_def_trigger_msg:
case isc_dyn_def_view:
case isc_dyn_delete_database:
case isc_dyn_delete_dimensions:
case isc_dyn_delete_filter:
case isc_dyn_delete_function:
case isc_dyn_delete_global_fld:
case isc_dyn_delete_idx:
case isc_dyn_delete_local_fld:
case isc_dyn_delete_rel:
case isc_dyn_delete_procedure:
case isc_dyn_delete_parameter:
case isc_dyn_delete_security_class:
case isc_dyn_delete_trigger:
case isc_dyn_delete_trigger_msg:
case isc_dyn_delete_shadow:
case isc_dyn_mod_exception:
case isc_dyn_mod_global_fld:
case isc_dyn_mod_idx:
case isc_dyn_mod_local_fld:
case isc_dyn_mod_procedure:
case isc_dyn_mod_rel:
case isc_dyn_mod_security_class:
case isc_dyn_mod_trigger:
case isc_dyn_mod_trigger_msg:
case isc_dyn_rel_constraint:
case isc_dyn_mod_view:
case isc_dyn_grant:
case isc_dyn_revoke:
case isc_dyn_view_relation:
case isc_dyn_def_sql_role:
2003-11-08 17:40:17 +01:00
while (NEXT_BYTE != isc_dyn_end)
2001-05-23 15:26:42 +02:00
PRINT_DYN_VERB;
PRINT_DYN_VERB;
return 0;
}
return 0;
}
//____________________________________________________________
//
// Invoke callback routine to print (or do something with) a line.
//
static int print_line( CTL control, SSHORT offset)
{
*control->ctl_ptr = 0;
(*control->ctl_routine) (control->ctl_user_arg, offset, control->ctl_buffer);
control->ctl_ptr = control->ctl_buffer;
return 0;
}
//____________________________________________________________
//
// Print a VAX word as a numeric value an return same.
//
static SLONG print_long( CTL control, SSHORT offset)
{
2003-12-22 11:00:59 +01:00
const UCHAR v1 = BLR_BYTE;
const UCHAR v2 = BLR_BYTE;
const UCHAR v3 = BLR_BYTE;
const UCHAR v4 = BLR_BYTE;
2001-05-23 15:26:42 +02:00
sprintf(control->ctl_ptr,
(control->
ctl_language) ? "chr(%d),chr(%d),chr(%d),chr(%d) " :
"%d,%d,%d,%d, ", v1, v2, v3, v4);
ADVANCE_PTR(control->ctl_ptr);
return v1 | (v2 << 8) | (v3 << 16) | (v4 << 24);
}
//____________________________________________________________
//
// Primary recursive routine to print slice description language.
//
2001-07-12 07:46:06 +02:00
static int print_sdl_verb( CTL control, SSHORT level)
2001-05-23 15:26:42 +02:00
{
2004-02-02 12:02:12 +01:00
const char* p;
2001-05-23 15:26:42 +02:00
2004-05-18 23:54:56 +02:00
SSHORT offset = control->ctl_blr - control->ctl_blr_start;
2004-02-02 12:02:12 +01:00
const UCHAR sdl_operator = BLR_BYTE;
2001-05-23 15:26:42 +02:00
2004-02-02 12:02:12 +01:00
if (sdl_operator > FB_NELEM(sdl_table) ||
sdl_operator <= 0 || !(p = sdl_table[sdl_operator]))
{
2001-05-23 15:26:42 +02:00
return error(control, offset,
"*** SDL operator %d is undefined ***\n",
2004-02-02 12:02:12 +01:00
(int) sdl_operator);
}
2001-05-23 15:26:42 +02:00
indent(control, level);
blr_format(control, p);
PUT_BYTE(',');
PUT_BYTE(' ');
++level;
2004-02-02 12:02:12 +01:00
int n = 0;
2001-05-23 15:26:42 +02:00
2004-02-02 12:02:12 +01:00
switch (sdl_operator) {
2003-11-08 17:40:17 +01:00
case isc_sdl_begin:
2004-05-18 23:54:56 +02:00
print_line(control, offset);
2003-11-08 17:40:17 +01:00
while (NEXT_BYTE != isc_sdl_end)
2001-05-23 15:26:42 +02:00
PRINT_SDL_VERB;
PRINT_SDL_VERB;
return 0;
2003-11-08 17:40:17 +01:00
case isc_sdl_struct:
2004-05-18 23:54:56 +02:00
n = print_byte(control, offset);
2001-05-23 15:26:42 +02:00
while (n--) {
2004-05-18 23:54:56 +02:00
print_line(control, offset);
indent(control, level + 1);
2001-05-23 15:26:42 +02:00
offset = control->ctl_blr - control->ctl_blr_start;
print_blr_dtype(control, true);
2001-05-23 15:26:42 +02:00
}
break;
2003-11-08 17:40:17 +01:00
case isc_sdl_scalar:
2004-05-18 23:54:56 +02:00
print_byte(control, offset);
2001-05-23 15:26:42 +02:00
2003-11-08 17:40:17 +01:00
case isc_sdl_element:
2004-05-18 23:54:56 +02:00
n = print_byte(control, offset);
print_line(control, offset);
2001-05-23 15:26:42 +02:00
while (n--)
PRINT_SDL_VERB;
return 0;
2003-11-08 17:40:17 +01:00
case isc_sdl_field:
case isc_sdl_relation:
2004-05-18 23:54:56 +02:00
print_string(control, offset);
2001-05-23 15:26:42 +02:00
break;
2003-11-08 17:40:17 +01:00
case isc_sdl_fid:
case isc_sdl_rid:
case isc_sdl_short_integer:
2004-05-18 23:54:56 +02:00
print_word(control, offset);
2001-05-23 15:26:42 +02:00
break;
2003-11-08 17:40:17 +01:00
case isc_sdl_variable:
case isc_sdl_tiny_integer:
2004-05-18 23:54:56 +02:00
print_byte(control, offset);
2001-05-23 15:26:42 +02:00
break;
2003-11-08 17:40:17 +01:00
case isc_sdl_long_integer:
2004-05-18 23:54:56 +02:00
print_long(control, offset);
2001-05-23 15:26:42 +02:00
break;
2003-11-08 17:40:17 +01:00
case isc_sdl_add:
case isc_sdl_subtract:
case isc_sdl_multiply:
case isc_sdl_divide:
2004-05-18 23:54:56 +02:00
print_line(control, offset);
2001-05-23 15:26:42 +02:00
PRINT_SDL_VERB;
PRINT_SDL_VERB;
return 0;
2003-11-08 17:40:17 +01:00
case isc_sdl_negate:
2004-05-18 23:54:56 +02:00
print_line(control, offset);
2001-05-23 15:26:42 +02:00
PRINT_SDL_VERB;
return 0;
2003-11-08 17:40:17 +01:00
case isc_sdl_do3:
2001-05-23 15:26:42 +02:00
n++;
2003-11-08 17:40:17 +01:00
case isc_sdl_do2:
2001-05-23 15:26:42 +02:00
n++;
2003-11-08 17:40:17 +01:00
case isc_sdl_do1:
2001-05-23 15:26:42 +02:00
n += 2;
2004-05-18 23:54:56 +02:00
print_byte(control, offset);
print_line(control, offset);
2001-05-23 15:26:42 +02:00
while (n--)
PRINT_SDL_VERB;
return 0;
}
2004-05-18 23:54:56 +02:00
print_line(control, offset);
2001-05-23 15:26:42 +02:00
return 0;
}
//____________________________________________________________
//
// Print a byte-counted string.
//
static int print_string( CTL control, SSHORT offset)
{
SSHORT n;
2004-05-18 23:54:56 +02:00
n = print_byte(control, offset);
2001-05-23 15:26:42 +02:00
while (--n >= 0)
2004-05-18 23:54:56 +02:00
print_char(control, offset);
2001-05-23 15:26:42 +02:00
PUT_BYTE(' ');
return 0;
}
//____________________________________________________________
//
// Print a VAX word as a numeric value an return same.
//
2001-07-12 07:46:06 +02:00
static int print_word( CTL control, SSHORT offset)
2001-05-23 15:26:42 +02:00
{
UCHAR v1, v2;
v1 = BLR_BYTE;
v2 = BLR_BYTE;
sprintf(control->ctl_ptr,
(control->ctl_language) ? "chr(%d),chr(%d), " : "%d,%d, ", v1,
v2);
ADVANCE_PTR(control->ctl_ptr);
return (v2 << 8) | v1;
}