2001-05-23 15:26:42 +02:00
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// PROGRAM: Language Preprocessor
|
|
|
|
// MODULE: pat.cpp
|
|
|
|
// DESCRIPTION: Code generator pattern generator
|
|
|
|
//
|
|
|
|
// 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): ______________________________________.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
2001-07-30 01:43:24 +02:00
|
|
|
// $Id: pat.cpp,v 1.2 2001-07-29 23:43:22 skywalker Exp $
|
2001-05-23 15:26:42 +02:00
|
|
|
//
|
|
|
|
|
2001-07-30 01:43:24 +02:00
|
|
|
#include "firebird.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../jrd/ib_stdio.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include "../gpre/gpre.h"
|
|
|
|
#include "../gpre/form.h"
|
|
|
|
#include "../gpre/pat.h"
|
|
|
|
#include "../gpre/gpre_proto.h"
|
|
|
|
#include "../gpre/pat_proto.h"
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
|
|
|
|
|
|
|
extern TEXT *ident_pattern;
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
NL,
|
|
|
|
RH, RL, RT, RI, RS, /* Request handle, level, transaction, ident, length */
|
|
|
|
DH, DF, /* Database handle, filename */
|
|
|
|
TH, /* Transaction handle */
|
|
|
|
BH, BI, /* Blob handle, blob_ident */
|
|
|
|
FH, /* Form handle */
|
|
|
|
V1, V2, /* Status vectors */
|
|
|
|
I1, I2, /* Identifier numbers */
|
|
|
|
RF, RE, /* OS- and language-dependent REF and REF-end character */
|
|
|
|
VF, VE, /* OS- and language-dependent VAL and VAL-end character */
|
|
|
|
S1, S2, S3, S4, S5, S6, S7,
|
|
|
|
/* Arbitrary strings */
|
|
|
|
N1, N2, N3, N4, /* Arbitrary number (SSHORT) */
|
|
|
|
L1, L2, /* Arbitrary number (SLONG) */
|
|
|
|
PN, PL, PI, /* Port number, port length, port ident */
|
|
|
|
QN, QL, QI, /* Second port number, port length, port ident */
|
|
|
|
IF, EL, EN, /* If, else, end */
|
|
|
|
FR /* Field reference */
|
|
|
|
} PAT_T;
|
|
|
|
|
|
|
|
static struct ops {
|
|
|
|
PAT_T ops_type;
|
|
|
|
TEXT ops_string[3];
|
|
|
|
} operators[] = {
|
|
|
|
RH, "RH",
|
|
|
|
RL, "RL",
|
|
|
|
RT, "RT",
|
|
|
|
RI, "RI",
|
|
|
|
RS, "RS",
|
|
|
|
DH, "DH",
|
|
|
|
DF, "DF",
|
|
|
|
TH, "TH",
|
|
|
|
BH, "BH",
|
|
|
|
BI, "BI",
|
|
|
|
FH, "FH",
|
|
|
|
V1, "V1",
|
|
|
|
V2, "V2",
|
|
|
|
I1, "I1",
|
|
|
|
I2, "I2",
|
|
|
|
S1, "S1",
|
|
|
|
S2, "S2",
|
|
|
|
S3, "S3",
|
|
|
|
S4, "S4",
|
|
|
|
S5, "S5",
|
|
|
|
S6, "S6",
|
|
|
|
S7, "S7",
|
|
|
|
N1, "N1",
|
|
|
|
N2, "N2",
|
|
|
|
N3, "N3",
|
|
|
|
N4, "N4",
|
|
|
|
L1, "L1",
|
|
|
|
L2, "L2",
|
|
|
|
PN, "PN",
|
|
|
|
PL, "PL",
|
|
|
|
PI, "PI",
|
|
|
|
QN, "QN",
|
|
|
|
QL, "QL",
|
|
|
|
QI, "QI",
|
|
|
|
IF, "IF",
|
|
|
|
EL, "EL",
|
|
|
|
EN, "EN", RF, "RF", RE, "RE", VF, "VF", VE, "VE", FR, "FR", NL, ""};
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Expand a pattern.
|
|
|
|
//
|
|
|
|
|
|
|
|
void PATTERN_expand( USHORT column, TEXT * pattern, PAT * args)
|
|
|
|
{
|
|
|
|
struct ops *operator_;
|
|
|
|
TEXT buffer[512], c, *p, temp1[16], temp2[16];
|
|
|
|
USHORT sw_ident, sw_gen, n;
|
|
|
|
SSHORT value; /* value needs to be signed since some of the
|
|
|
|
values printed out are signed. */
|
|
|
|
SLONG long_value;
|
|
|
|
BOOLEAN long_flag, handle_flag;
|
|
|
|
REF reference;
|
|
|
|
TEXT *string, *ref, *refend, *val, *valend, *q;
|
|
|
|
|
|
|
|
ref = "";
|
|
|
|
refend = "";
|
|
|
|
val = "";
|
|
|
|
valend = "";
|
|
|
|
|
|
|
|
if ((sw_language == lang_c) || (sw_language == lang_cxx)) {
|
|
|
|
ref = "&";
|
|
|
|
refend = "";
|
|
|
|
}
|
|
|
|
else if (sw_language == lang_pli) {
|
|
|
|
ref = "ADDR(";
|
|
|
|
refend = ")";
|
|
|
|
}
|
|
|
|
else if (sw_language == lang_pascal) {
|
|
|
|
ref = "%%REF ";
|
|
|
|
refend = "";
|
|
|
|
}
|
|
|
|
else if (sw_language == lang_cobol) {
|
|
|
|
ref = "BY REFERENCE ";
|
|
|
|
refend = "";
|
|
|
|
val = "BY VALUE ";
|
|
|
|
valend = "";
|
|
|
|
}
|
|
|
|
else if (sw_language == lang_fortran) {
|
|
|
|
#ifdef VMS
|
|
|
|
ref = "%REF(";
|
|
|
|
refend = ")";
|
|
|
|
val = "%VAL(";
|
|
|
|
valend = ")";
|
|
|
|
#endif
|
|
|
|
#if (defined AIX || defined AIX_PPC)
|
|
|
|
ref = "%REF(";
|
|
|
|
refend = ")";
|
|
|
|
val = "%VAL(";
|
|
|
|
valend = ")";
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
p = buffer;
|
|
|
|
*p++ = '\n';
|
|
|
|
sw_gen = TRUE;
|
|
|
|
for (n = column; n; --n)
|
|
|
|
*p++ = ' ';
|
|
|
|
|
|
|
|
while (c = *pattern++) {
|
|
|
|
if (c != '%') {
|
|
|
|
if (sw_gen) {
|
|
|
|
*p++ = c;
|
|
|
|
if ((c == '\n') && (*pattern))
|
|
|
|
for (n = column; n; --n)
|
|
|
|
*p++ = ' ';
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
sw_ident = FALSE;
|
|
|
|
string = NULL;
|
|
|
|
reference = NULL;
|
|
|
|
handle_flag = long_flag = FALSE;
|
|
|
|
for (operator_ = operators; operator_->ops_type != NL; operator_++)
|
|
|
|
if (operator_->ops_string[0] == pattern[0] &&
|
|
|
|
operator_->ops_string[1] == pattern[1])
|
|
|
|
break;
|
|
|
|
pattern += 2;
|
|
|
|
switch (operator_->ops_type) {
|
|
|
|
case IF:
|
|
|
|
sw_gen = args->pat_condition;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case EL:
|
|
|
|
sw_gen = !sw_gen;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case EN:
|
|
|
|
sw_gen = TRUE;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case RH:
|
|
|
|
handle_flag = TRUE;
|
|
|
|
string = args->pat_request->req_handle;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RL:
|
|
|
|
string = args->pat_request->req_request_level;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RS:
|
|
|
|
value = args->pat_request->req_length;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RT:
|
|
|
|
handle_flag = TRUE;
|
|
|
|
string = args->pat_request->req_trans;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RI:
|
|
|
|
value = args->pat_request->req_ident;
|
|
|
|
sw_ident = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DH:
|
|
|
|
handle_flag = TRUE;
|
|
|
|
string = args->pat_database->dbb_name->sym_string;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DF:
|
|
|
|
string = args->pat_database->dbb_filename;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PN:
|
|
|
|
value = args->pat_port->por_msg_number;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PL:
|
|
|
|
value = args->pat_port->por_length;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PI:
|
|
|
|
value = args->pat_port->por_ident;
|
|
|
|
sw_ident = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QN:
|
|
|
|
value = args->pat_port2->por_msg_number;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QL:
|
|
|
|
value = args->pat_port2->por_length;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QI:
|
|
|
|
value = args->pat_port2->por_ident;
|
|
|
|
sw_ident = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BH:
|
|
|
|
value = args->pat_blob->blb_ident;
|
|
|
|
sw_ident = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case I1:
|
|
|
|
value = args->pat_ident1;
|
|
|
|
sw_ident = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case I2:
|
|
|
|
value = args->pat_ident2;
|
|
|
|
sw_ident = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case S1:
|
|
|
|
string = args->pat_string1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case S2:
|
|
|
|
string = args->pat_string2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case S3:
|
|
|
|
string = args->pat_string3;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case S4:
|
|
|
|
string = args->pat_string4;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case S5:
|
|
|
|
string = args->pat_string5;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case S6:
|
|
|
|
string = args->pat_string6;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case S7:
|
|
|
|
string = args->pat_string7;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case V1:
|
|
|
|
string = args->pat_vector1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case V2:
|
|
|
|
string = args->pat_vector2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case N1:
|
|
|
|
value = args->pat_value1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case N2:
|
|
|
|
value = args->pat_value2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case N3:
|
|
|
|
value = args->pat_value3;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case N4:
|
|
|
|
value = args->pat_value4;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case L1:
|
|
|
|
long_value = args->pat_long1;
|
|
|
|
long_flag = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case L2:
|
|
|
|
long_value = args->pat_long2;
|
|
|
|
long_flag = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RF:
|
|
|
|
string = ref;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RE:
|
|
|
|
string = refend;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VF:
|
|
|
|
string = val;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VE:
|
|
|
|
string = valend;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FR:
|
|
|
|
reference = args->pat_reference;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
sprintf(buffer, "Unknown substitution \"%c%c\"", pattern[-2],
|
|
|
|
pattern[-1]);
|
|
|
|
IBERROR(buffer);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!sw_gen)
|
|
|
|
continue;
|
|
|
|
if (string) {
|
|
|
|
if (handle_flag && (sw_language == lang_ada))
|
|
|
|
for (q = ada_package; *q;)
|
|
|
|
*p++ = *q++;
|
|
|
|
while (*string)
|
|
|
|
*p++ = *string++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (sw_ident)
|
|
|
|
sprintf(p, ident_pattern, value);
|
|
|
|
else if (reference) {
|
|
|
|
if (!reference->ref_port)
|
|
|
|
sprintf(p, ident_pattern, reference->ref_ident);
|
|
|
|
else {
|
|
|
|
sprintf(temp1, ident_pattern, reference->ref_port->por_ident);
|
|
|
|
sprintf(temp2, ident_pattern, reference->ref_ident);
|
|
|
|
switch (sw_language) {
|
|
|
|
case lang_basic:
|
|
|
|
sprintf(p, "%s::%s", temp1, temp2);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case lang_fortran:
|
|
|
|
case lang_cobol:
|
|
|
|
strcpy(p, temp2);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
sprintf(p, "%s.%s", temp1, temp2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (long_flag) {
|
|
|
|
if (sw_language == lang_basic)
|
|
|
|
sprintf(p, "%d%%", long_value);
|
|
|
|
else
|
|
|
|
sprintf(p, "%d", long_value);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (sw_language == lang_basic)
|
|
|
|
sprintf(p, "%d%%", value);
|
|
|
|
else
|
|
|
|
sprintf(p, "%d", value);
|
|
|
|
}
|
|
|
|
|
|
|
|
while (*p)
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*p = 0;
|
|
|
|
switch (sw_language) {
|
|
|
|
#ifdef ADA
|
|
|
|
/* Ada lines can be up to 120 characters long. ADA_print_buffer
|
|
|
|
handles this problem and ensures that GPRE output is <=120 characters.
|
|
|
|
*/
|
|
|
|
case lang_ada:
|
|
|
|
ADA_print_buffer(buffer, 0);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef BASIC
|
|
|
|
case lang_basic:
|
|
|
|
/* Basic lines can be up to 72 characters long. BAS_print_buffer
|
|
|
|
handles this problem and ensures that GPRE output is <= 72 characters.
|
|
|
|
*/
|
|
|
|
BAS_print_buffer(buffer);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef COBOL
|
|
|
|
/* COBOL lines can be up to 72 characters long. COB_print_buffer
|
|
|
|
handles this problem and ensures that GPRE output is <= 72 characters.
|
|
|
|
*/
|
|
|
|
case lang_cobol:
|
|
|
|
COB_print_buffer(buffer, TRUE);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef FORTRAN
|
|
|
|
/* In FORTRAN, characters beyond column 72 are ignored. FTN_print_buffer
|
|
|
|
handles this problem and ensures that GPRE output does not exceed this
|
|
|
|
limit.
|
|
|
|
*/
|
|
|
|
case lang_fortran:
|
|
|
|
FTN_print_buffer(buffer);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
default:
|
|
|
|
ib_fprintf(out_file, buffer);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // extern "C"
|