8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-27 07:23:04 +01:00
firebird-mirror/src/gpre/pat.cpp

441 lines
8.5 KiB
C++
Raw Normal View History

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): ______________________________________.
//
//
//____________________________________________________________
//
// $Id: pat.cpp,v 1.11 2003-09-08 11:27:51 robocop Exp $
2001-05-23 15:26:42 +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"
2002-07-04 11:34:20 +02:00
#include "../gpre/lang_proto.h"
2001-05-23 15:26:42 +02:00
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" },
2001-12-24 03:51:06 +01:00
{ 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, "" }
};
2001-05-23 15:26:42 +02:00
//____________________________________________________________
//
// Expand a pattern.
//
void PATTERN_expand( USHORT column, TEXT * pattern, PAT * args)
{
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) || (isLangCpp(sw_language))) {
2001-05-23 15:26:42 +02:00
ref = "&";
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;
ops* oper_iter;
for (oper_iter = operators; oper_iter->ops_type != NL; oper_iter++)
if (oper_iter->ops_string[0] == pattern[0] &&
oper_iter->ops_string[1] == pattern[1])
2001-05-23 15:26:42 +02:00
break;
pattern += 2;
switch (oper_iter->ops_type) {
2001-05-23 15:26:42 +02:00
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_fortran:
case lang_cobol:
strcpy(p, temp2);
break;
default:
sprintf(p, "%s.%s", temp1, temp2);
}
}
}
else if (long_flag) {
2003-04-01 13:49:33 +02:00
sprintf(p, "%"SLONGFORMAT, long_value);
2001-05-23 15:26:42 +02:00
}
else {
sprintf(p, "%d", value);
2001-05-23 15:26:42 +02:00
}
while (*p)
p++;
}
*p = 0;
switch (sw_language) {
#ifdef GPRE_ADA
2001-05-23 15:26:42 +02:00
/* 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 GPRE_COBOL
2001-05-23 15:26:42 +02:00
/* 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 GPRE_FORTRAN
2001-05-23 15:26:42 +02:00
/* 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;
}
}