8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-27 06:03:02 +01:00
firebird-mirror/src/jrd/codes.epp

845 lines
25 KiB
Plaintext
Raw Normal View History

2001-05-23 15:26:42 +02:00
/*
* PROGRAM: JRD Access Method
* MODULE: codes.e
* DESCRIPTION: Code and message include file 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): ______________________________________.
* Mark O'Donohue skywalker@users.sourceforge.net
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 <stdlib.h>
#include <unistd.h>
2001-05-23 15:26:42 +02:00
#include "../jrd/common.h"
#include "../jrd/gds.h"
2001-05-23 15:26:42 +02:00
#include "../jrd/msg_encode.h"
/* The MSG.GDB database is found under the /msgs component subdirectory.
Use links or logicals to point it there, thanks! AMG */
DATABASE DB = FILENAME "msg.gdb";
#define CODES_PAS "gds_codes.pas"
#define CODES_FTN "gds_codes.ftn"
#define CODES_H "codes.h"
#define IBERROR_H "iberror.h"
#define CODETEXT_H "codetext.h"
#define MSGS_H "msgs.h"
#define RDBCODES_H "rdb_codes.h"
#define SQL_CODES_H "sql_code.h"
#define MSGFAC_H "msg_facs.h"
static void build_codes_h(void);
static void build_iberror_h(void);
static void build_other_headers(void);
static void build_msgfac_h(void);
static void move_if_not_identical(char *, char *);
2001-05-23 15:26:42 +02:00
static void add_text(IB_FILE *, int, const char **);
static char* genDirectory = NULL;
2001-05-23 15:26:42 +02:00
#define CHECK_OPEN(f, name, tmp, mode) \
if (((f) = ib_fopen ((tmp), (mode))) == NULL) \
{ \
ib_fprintf (ib_stderr, "CODES: Unable to open %s in filemode %s for %s\n", \
(tmp), (mode), (name)); \
exit (FINI_ERROR); \
}
#define CHECK_CLOSE(f, name, tmp, mode) \
ib_fclose (f);\
move_if_not_identical ((name), (tmp))
#define CSTYLE 1
#define PASSTYLE 2
#define FTNSTYLE 3
#define FAC_SQL_POSITIVE 14 /* facility for positive SQL codes */
#define FAC_SQL_NEGATIVE 13 /* ditto for negative codes */
#define gds_facility 20
#define gds_base (gds_facility << 24)
#define gds_factor 1
static const char *license[] = {
"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 content of this file was generated by the Firebird project",
"using the program jrd/codes.epp",
2001-05-23 15:26:42 +02:00
0
};
static const char *warn[] = {
"",
"*** WARNING *** - This file is automatically generated by codes.e - do not edit!",
2001-05-23 15:26:42 +02:00
"",
0
};
2003-02-13 11:11:35 +01:00
static const SCHAR *c_boiler_plate[] = {
2001-05-23 15:26:42 +02:00
"#define gds_arg_end 0 /* end of argument list */",
"#define gds_arg_gds 1 /* generic DSRI status value */",
"#define gds_arg_string 2 /* string argument */",
"#define gds_arg_cstring 3 /* count & string argument */",
"#define gds_arg_number 4 /* numeric argument (long) */",
"#define gds_arg_interpreted 5 /* interpreted status code (string) */",
"#define gds_arg_vms 6 /* VAX/VMS status code (long) */",
"#define gds_arg_unix 7 /* UNIX error code */",
"#define gds_arg_domain 8 /* Apollo/Domain error code */",
"#define gds_arg_dos 9 /* MSDOS/OS2 error code */",
"#define gds_arg_mpexl 10 /* HP MPE/XL error code */",
"#define gds_arg_mpexl_ipc 11 /* HP MPE/XL IPC error code */",
/* #'s 12-14 WERE USED BY TWIN SUN AND THUS MUST BE SKIPPED BY US! */
2003-02-09 12:39:07 +01:00
"#define gds_arg_next_mach 15 /* NeXT/Mach error code */",
2001-05-23 15:26:42 +02:00
"#define gds_arg_netware 16 /* NetWare error code */",
"#define gds_arg_win32 17 /* Win32 error code */",
"#define gds_arg_warning 18 /* warning argument */",
"",
};
2003-02-13 11:11:35 +01:00
static const SCHAR *cpp_boiler_plate[] = {
"const SLONG gds_arg_end = 0; /* end of argument list */",
"const SLONG gds_arg_gds = 1; /* generic DSRI status value */",
"const SLONG gds_arg_string = 2; /* string argument */",
"const SLONG gds_arg_cstring = 3; /* count & string argument */",
"const SLONG gds_arg_number = 4; /* numeric argument (long) */",
"const SLONG gds_arg_interpreted = 5; /* interpreted status code (string) */",
"const SLONG gds_arg_vms = 6; /* VAX/VMS status code (long) */",
"const SLONG gds_arg_unix = 7; /* UNIX error code */",
"const SLONG gds_arg_domain = 8; /* Apollo/Domain error code */",
"const SLONG gds_arg_dos = 9; /* MSDOS/OS2 error code */",
"const SLONG gds_arg_mpexl = 10; /* HP MPE/XL error code */",
"const SLONG gds_arg_mpexl_ipc = 11; /* HP MPE/XL IPC error code */",
/* #'s 12-14 WERE USED BY TWIN SUN AND THUS MUST BE SKIPPED BY US! */
"const SLONG gds_arg_next_mach = 15; /* NeXT/Mach error code */",
"const SLONG gds_arg_netware = 16; /* NetWare error code */",
"const SLONG gds_arg_win32 = 17; /* Win32 error code */",
"const SLONG gds_arg_warning = 18; /* warning argument */",
"",
};
2001-05-23 15:26:42 +02:00
#define isc_facility 20
#define isc_base (isc_facility << 24)
#define isc_factor 1
2003-02-13 11:11:35 +01:00
static const SCHAR *isc_c_boiler_plate[] = {
2001-05-23 15:26:42 +02:00
"#define isc_arg_end 0 /* end of argument list */",
"#define isc_arg_gds 1 /* generic DSRI status value */",
"#define isc_arg_string 2 /* string argument */",
"#define isc_arg_cstring 3 /* count & string argument */",
"#define isc_arg_number 4 /* numeric argument (long) */",
"#define isc_arg_interpreted 5 /* interpreted status code (string) */",
"#define isc_arg_vms 6 /* VAX/VMS status code (long) */",
"#define isc_arg_unix 7 /* UNIX error code */",
"#define isc_arg_domain 8 /* Apollo/Domain error code */",
"#define isc_arg_dos 9 /* MSDOS/OS2 error code */",
"#define isc_arg_mpexl 10 /* HP MPE/XL error code */",
"#define isc_arg_mpexl_ipc 11 /* HP MPE/XL IPC error code */",
/* #'s 12-14 WERE USED BY TWIN SUN AND THUS MUST BE SKIPPED BY US! */
2003-02-09 12:39:07 +01:00
"#define isc_arg_next_mach 15 /* NeXT/Mach error code */",
2001-05-23 15:26:42 +02:00
"#define isc_arg_netware 16 /* NetWare error code */",
"#define isc_arg_win32 17 /* Win32 error code */",
"#define isc_arg_warning 18 /* warning argument */",
"",
};
2003-02-13 11:11:35 +01:00
static const SCHAR *pas_boiler_plate[] = {
2001-05-23 15:26:42 +02:00
"\tgds_arg_end\t\t= 0;\t(* end of argument list *)",
"\tgds_arg_gds\t\t= 1;\t(* generic DSRI status value *)",
"\tgds_arg_string\t\t= 2;\t(* string argument *)",
"\tgds_arg_cstring\t\t= 3;\t(* count & string argument *)",
"\tgds_arg_number\t\t= 4;\t(* numeric argument (long) *)",
"\tgds_arg_interpreted\t= 5;\t(* interpreted status code (string) *)",
"\tgds_arg_vms\t\t= 6;\t(* VAX/VMS status code (long) *)",
"\tgds_arg_unix\t\t= 7;\t(* UNIX error code *)",
"\tgds_arg_domain\t\t= 8;\t(* Apollo/Domain error code *)",
"\tgds_arg_dos\t\t= 9;\t(* MSDOS/OS2 error code *)",
"",
};
2003-02-13 11:11:35 +01:00
static const SCHAR *ftn_boiler_plate_data[] = {
2001-05-23 15:26:42 +02:00
"",
" PARAMETER (",
" + GDS_ARG_END = 0, { end of argument list }",
" + GDS_ARG_GDS = 1, { generic DSRI status value }",
" + GDS_ARG_STRING = 2, { string argument }",
" + GDS_ARG_CSTRING = 3, { count & string argument }",
" + GDS_ARG_NUMBER = 4, { numeric argument (long) }",
" + GDS_ARG_INTERPRETED = 5, { interpreted status code (string) }",
" + GDS_ARG_VMS = 6, { VAX/VMS status code (long) }",
" + GDS_ARG_UNIX = 7, { UNIX error code }",
" + GDS_ARG_DOMAIN = 8, { Apollo/Domain error code }",
" + GDS_ARG_DOS = 9) { Apollo/Domain error code }",
"",
};
2003-02-13 11:11:35 +01:00
static const SCHAR *ftn_boiler_plate_decls[] = {
2001-05-23 15:26:42 +02:00
" INTEGER*4",
" + GDS_ARG_END, { end of argument list }",
" + GDS_ARG_GDS, { generic DSRI status value }",
" + GDS_ARG_STRING, { string argument }",
" + GDS_ARG_CSTRING, { count & string argument }",
" + GDS_ARG_NUMBER, { numeric argument (long) }",
" + GDS_ARG_INTERPRETED, { interpreted status code (string) }",
" + GDS_ARG_VMS, { VAX/VMS status code (long) }",
" + GDS_ARG_UNIX, { UNIX error code }",
" + GDS_ARG_DOMAIN, { Apollo/Domain error code }",
" + GDS_ARG_DOS { MSDOS/OS2 error code }",
"",
};
2003-02-13 11:11:35 +01:00
static const SCHAR sql_code_boiler_plate[] =
2003-02-28 13:57:13 +01:00
"static const SSHORT gds__sql_code [] = {";
2001-05-23 15:26:42 +02:00
int CLIB_ROUTINE main( int argc, char *argv[])
2001-05-23 15:26:42 +02:00
{
/*************************************
*
* m a i n
*
**************************************
*
* Functional description
* Generate both code definition
* include file and message text
* include file.
*
**************************************/
READY
ON_ERROR
ib_printf("Attach failed.\n");
gds__print_status(gds_status);
2001-05-23 15:26:42 +02:00
exit(FINI_ERROR);
END_ERROR;
// See if the user has specified an optional output directory
if (argc >=1 ) {
genDirectory = argv[1];
}
2001-05-23 15:26:42 +02:00
START_TRANSACTION;
build_iberror_h();
build_codes_h();
build_msgfac_h();
build_other_headers();
COMMIT;
FINISH;
// exit(0);
return 0;
2001-05-23 15:26:42 +02:00
}
static void build_msgfac_h(void)
{
/*******************************************
*
* b u i l d _ m s g f a c _ h
*
*******************************************
*
* Functional desciption
* Function creates the msgfac.h
* file which contains a listing of valid
* facilities for the error codes.
*
*******************************************/
IB_FILE *msgfac;
/* Open msgfac.h in the current directory */
CHECK_OPEN(msgfac, MSGFAC_H, "tmpcode1", "w");
add_text(msgfac, CSTYLE, license);
add_text(msgfac, CSTYLE, warn);
ib_fprintf(msgfac, "/*\n");
ib_fprintf(msgfac, " * MODULE: msg_facs.h\n");
ib_fprintf(msgfac, " * DESCRIPTION: ISC message facilities\n");
ib_fprintf(msgfac, " *\n");
ib_fprintf(msgfac, " */\n");
ib_fprintf(msgfac, "\n\n\n");
ib_fprintf(msgfac, "/******************************/\n");
ib_fprintf(msgfac, "/* ISC message facilities */\n");
ib_fprintf(msgfac, "/******************************/\n");
ib_fprintf(msgfac, "\n");
ib_fprintf(msgfac, "#ifndef __cplusplus\n");
ib_fprintf(msgfac, "typedef\n");
ib_fprintf(msgfac, "#endif\n");
ib_fprintf(msgfac, "struct _facilities {\n");
2001-05-23 15:26:42 +02:00
ib_fprintf(msgfac, "\tint fac_code;\n");
ib_fprintf(msgfac, "\tchar *facility;\n");
ib_fprintf(msgfac, "\t};\n\n");
2003-02-13 11:11:35 +01:00
ib_fprintf(msgfac, "static const struct _facilities facilities[] = {\n");
2001-05-23 15:26:42 +02:00
FOR F IN FACILITIES WITH ANY FAC_CODE IN SYSTEM_ERRORS OVER FAC_CODE
ib_fprintf(msgfac, "\t{%d, \"%-10.10s\"},\n", F.FAC_CODE, F.FACILITY);
2001-05-23 15:26:42 +02:00
END_FOR;
ib_fprintf(msgfac, "\t{0, NULL}\n};\n\n");
2001-05-23 15:26:42 +02:00
ib_fprintf(msgfac, "\n");
CHECK_CLOSE(msgfac, MSGFAC_H, "tmpcode1", "w");
}
static void build_iberror_h(void)
{
/*******************************************
*
* b u i l d _ i b e r r o r _ h
*
*******************************************
*
* Functional desciption
* Function creates the iberror.h
* file which contains c and isc_
* style error codes.
*
*******************************************/
IB_FILE *iberror;
int code = 1, last_code = code - 1;
unsigned long new_code = 0L;
/* Open iberror.h in the current directory. */
CHECK_OPEN(iberror, IBERROR_H, "tmpcode2", "w");
ib_fprintf(iberror, "\n#ifndef _JRD_GEN_IBERROR_H\n");
ib_fprintf(iberror, "#define _JRD_GEN_IBERROR_H\n");
2001-05-23 15:26:42 +02:00
add_text(iberror, CSTYLE, license);
add_text(iberror, CSTYLE, warn);
ib_fprintf(iberror, "/*\n");
ib_fprintf(iberror, " * MODULE: iberror.h\n");
ib_fprintf(iberror, " * DESCRIPTION: ISC error codes\n");
ib_fprintf(iberror, " *\n");
ib_fprintf(iberror, " */\n");
ib_fprintf(iberror, "\n\n\n");
ib_fprintf(iberror, "/***********************/\n");
ib_fprintf(iberror, "/* ISC Error Codes */\n");
ib_fprintf(iberror, "/***********************/\n");
ib_fprintf(iberror, "\n");
ib_fprintf(iberror, "#define isc_facility %d\n", isc_facility);
ib_fprintf(iberror, "#define isc_base %dL\n", isc_base);
ib_fprintf(iberror, "#define isc_factor %d\n", isc_factor);
ib_fprintf(iberror, "\n");
/* Append the ISC boiler plate */
int numLines = FB_NELEM(isc_c_boiler_plate);
for (int i=0; i < numLines; i++) {
ib_fprintf(iberror, "%s\n", isc_c_boiler_plate[i]);
}
2001-05-23 15:26:42 +02:00
/* Fetch error codes from SYSTEM_ERRORS relation.
Write them out using the ISC prefix. */
FOR S IN SYSTEM_ERRORS CROSS N IN MESSAGES OVER NUMBER WITH
N.FAC_CODE = S.FAC_CODE SORTED BY N.FAC_CODE, S.NUMBER
/* The only facility that is guaranteed to have all codes in system errors
* is JRD */
if (last_code + 1 != N.CODE && N.FAC_CODE == 0)
ib_fprintf(ib_stderr,
"Warning: missing codes between %d and %d (exclusive)\n",
last_code, (int) N.CODE);
last_code = N.CODE;
new_code = ENCODE_ISC_MSG(S.NUMBER, N.FAC_CODE);
ib_fprintf(iberror, "#define isc_%-32.32s %dL\n", S.GDS_SYMBOL,
new_code);
++code;
END_FOR;
--code;
ib_fprintf(iberror, "#define isc_%-32.32s %d\n", "err_max", code);
ib_fprintf(iberror, "\n");
ib_fprintf(iberror, "#endif /* JRD_GEN_IBERROR_H */\n");
2001-05-23 15:26:42 +02:00
CHECK_CLOSE(iberror, IBERROR_H, "tmpcode2", "w");
}
static void build_codes_h(void)
{
/*******************************************
*
* b u i l d _ c o d e s _ h
*
*******************************************
*
* Functional desciption
* Function creates the codes.h
* file which contains c and isc_
* style error codes.
*
*******************************************/
IB_FILE *c_codes;
2002-12-10 12:53:53 +01:00
int code = 1, last_code = code - 1;
2001-05-23 15:26:42 +02:00
unsigned long new_code = 0L;
/* Open codes.h in the current directory. */
CHECK_OPEN(c_codes, CODES_H, "tmpcode3", "w");
add_text(c_codes, CSTYLE, license);
add_text(c_codes, CSTYLE, warn);
ib_fprintf(c_codes, "\n#ifndef _JRD_GEN_CODES_H\n");
ib_fprintf(c_codes, "#define _JRD_GEN_CODES_H\n");
ib_fprintf(c_codes, "\n#ifdef __cplusplus /* c++ definitions */\n\n");
2001-05-23 15:26:42 +02:00
ib_fprintf(c_codes,
"const SLONG gds_facility = %d;\nconst SLONG gds_err_base = %ldL;\nconst SLONG gds_err_factor = %ld;\n",
2001-05-23 15:26:42 +02:00
gds_facility, (SLONG) gds_base, (SLONG) gds_factor);
/* Append the C++ boiler plate */
2001-05-23 15:26:42 +02:00
int numLines = FB_NELEM(cpp_boiler_plate);
for (int i=0; i < numLines; i++) {
ib_fprintf(c_codes, "%s\n", cpp_boiler_plate[i]);
}
2001-05-23 15:26:42 +02:00
FOR S IN SYSTEM_ERRORS CROSS N IN MESSAGES OVER NUMBER WITH
N.FAC_CODE = S.FAC_CODE SORTED BY N.FAC_CODE, S.NUMBER
/* The only facility that is guaranteed to have all codes in system errors
* is JRD */
if (last_code + 1 != N.CODE && N.FAC_CODE == 0)
ib_fprintf(ib_stderr,
"Warning: missing codes between %d and %d (exclusive)\n",
last_code, (int) N.CODE);
last_code = N.CODE;
new_code = ENCODE_ISC_MSG(S.NUMBER, N.FAC_CODE);
ib_fprintf(c_codes, "const SLONG gds_%-32.32s = %dL;\n", S.GDS_SYMBOL,
2001-05-23 15:26:42 +02:00
new_code);
++code;
/* make sure that the SQL code is also present in the SQLERR facility */
/**** this part really should be done via a trigger on the database--
commented out for now - deej
got_it = 0;
if (S.SQL_CODE < 0)
{
srchnum = 1000 + S.SQL_CODE;
**FOR M IN MESSAGES WITH M.FAC_CODE = FAC_SQL_NEGATIVE
AND M.NUMBER = srchnum
got_it = 1;
**END_FOR;
}
else
{
srchnum = S.SQL_CODE;
**FOR M IN MESSAGES WITH M.FAC_CODE = FAC_SQL_POSITIVE
AND M.NUMBER = srchnum
got_it = 1;
**END_FOR;
}
if (!got_it)
{
ib_printf ("codes: msg %d: sql-code %d, is not in the SQLERR facility\n",
N.NUMBER, S.SQL_CODE);
ROLLBACK;
FINISH;
exit (FINI_ERROR);
} ****/
END_FOR;
--code;
ib_fprintf(c_codes, "const SLONG gds_%-32.32s = %dL;\n", "err_max", code);
2001-05-23 15:26:42 +02:00
ib_fprintf(c_codes, "\n");
ib_fprintf(c_codes, "#else /* c definitions */\n\n");
2001-05-23 15:26:42 +02:00
ib_fprintf(c_codes,
"#define gds_facility %d\n#define gds_err_base %ldL\n#define gds_err_factor %ld\n",
gds_facility, (SLONG) gds_base, (SLONG) gds_factor);
2001-05-23 15:26:42 +02:00
/* Append the C boiler plate */
2001-05-23 15:26:42 +02:00
// Reset the variables for another trip round the loop.
2001-05-23 15:26:42 +02:00
code = 1;
last_code = code - 1;
new_code = 0L;
numLines = FB_NELEM(c_boiler_plate);
for (int i=0; i < numLines; i++) {
ib_fprintf(c_codes, "%s\n", c_boiler_plate[i]);
}
2001-05-23 15:26:42 +02:00
FOR S IN SYSTEM_ERRORS CROSS N IN MESSAGES OVER NUMBER WITH
N.FAC_CODE = S.FAC_CODE SORTED BY N.FAC_CODE, S.NUMBER
/* The only facility that is guaranteed to have all codes in system errors
* is JRD */
if (last_code + 1 != N.CODE && N.FAC_CODE == 0)
ib_fprintf(ib_stderr,
"Warning: missing codes between %d and %d (exclusive)\n",
last_code, (int) N.CODE);
last_code = N.CODE;
new_code = ENCODE_ISC_MSG(S.NUMBER, N.FAC_CODE);
ib_fprintf(c_codes, "#define gds__%-32.32s %dL\n", S.GDS_SYMBOL,
2001-05-23 15:26:42 +02:00
new_code);
++code;
/* make sure that the SQL code is also present in the SQLERR facility */
/**** this part really should be done via a trigger on the database--
commented out for now - deej
got_it = 0;
if (S.SQL_CODE < 0)
{
srchnum = 1000 + S.SQL_CODE;
**FOR M IN MESSAGES WITH M.FAC_CODE = FAC_SQL_NEGATIVE
AND M.NUMBER = srchnum
got_it = 1;
**END_FOR;
}
else
{
srchnum = S.SQL_CODE;
**FOR M IN MESSAGES WITH M.FAC_CODE = FAC_SQL_POSITIVE
AND M.NUMBER = srchnum
got_it = 1;
**END_FOR;
}
if (!got_it)
{
ib_printf ("codes: msg %d: sql-code %d, is not in the SQLERR facility\n",
N.NUMBER, S.SQL_CODE);
ROLLBACK;
FINISH;
exit (FINI_ERROR);
} ****/
2001-05-23 15:26:42 +02:00
END_FOR;
--code;
ib_fprintf(c_codes, "#define gds_%-32.32s %d\n", "err_max", code);
2001-05-23 15:26:42 +02:00
ib_fprintf(c_codes, "\n");
ib_fprintf(c_codes, "#endif\n\n");
/* Append the ISC error codes */
/* I have removed the isc errors from codes.h since they are all now placed
into iberror.h - If it needs to be replaced then it can be copied back
from gen iberror routine. I now do the include of that file.
MOD 17-07-2001
*/
ib_fprintf(c_codes, "#include \"gen/iberror.h\"\n\n");
ib_fprintf(c_codes, "#endif /* JRD_GEN_CODES_H */\n");
2001-05-23 15:26:42 +02:00
CHECK_CLOSE(c_codes, CODES_H, "tmpcode3", "w");
}
static void build_other_headers(void)
{
/********************************************
*
* b u i l d _ o t h e r _ h e a d e r s
*
*********************************************
*
* Functional desciption
* Function creates the other header
* files.
*
*********************************************/
IB_FILE *msgs, *rdbcodes, *code_text, *pas_codes, *ftn_codes, *sql_codes;
2002-12-10 12:53:53 +01:00
SCHAR *p, *q, *end, text[128];
2001-05-23 15:26:42 +02:00
int last_code, code, i;
unsigned long new_code = 0L;
/* Use the CHECK_OPEN macro to open header files in current directory. */
CHECK_OPEN(pas_codes, CODES_PAS, "tmpcode4", "w");
CHECK_OPEN(ftn_codes, CODES_FTN, "tmpcode5", "w");
CHECK_OPEN(code_text, CODETEXT_H, "tmpcode6", "w");
CHECK_OPEN(msgs, MSGS_H, "tmpcode7", "w");
CHECK_OPEN(rdbcodes, RDBCODES_H, "tmpcode8", "w");
/* Add license */
add_text(pas_codes, PASSTYLE, license);
add_text(pas_codes, PASSTYLE, warn);
add_text(ftn_codes, FTNSTYLE, license);
add_text(ftn_codes, FTNSTYLE, warn);
add_text(code_text, CSTYLE, license);
add_text(code_text, CSTYLE, warn);
add_text(msgs, CSTYLE, license);
add_text(msgs, CSTYLE, warn);
add_text(rdbcodes, CSTYLE, license);
add_text(rdbcodes, CSTYLE, warn);
/* Start the PASCAL codes file */
ib_fprintf(pas_codes, "\
2003-02-13 11:11:35 +01:00
const\n\
2001-05-23 15:26:42 +02:00
\tgds_facility\t\t= %d;\n\
\tgds_err_base\t\t= %ld;\n\
\tgds_err_factor\t\t= %ld;\n", gds_facility, (SLONG) gds_base, (SLONG) gds_factor);
int numLines = FB_NELEM(pas_boiler_plate);
for (int i=0; i < numLines; i++) {
ib_fprintf(pas_codes, "%s\n", pas_boiler_plate[i]);
}
2001-05-23 15:26:42 +02:00
/* Start the FORTRAN codes file */
ib_fprintf(ftn_codes, "\n\
INTEGER*4\n\
+ GDS_FACILITY,\n\
+ GDS_ERR_BASE,\n\
+ GDS_ERR_FACTOR\n");
numLines = FB_NELEM(ftn_boiler_plate_decls);
for (int i=0; i < numLines; i++) {
ib_fprintf(ftn_codes, "%s\n", ftn_boiler_plate_decls[i]);
}
2001-05-23 15:26:42 +02:00
ib_fprintf(ftn_codes, "\n\
PARAMETER (\n\
+ GDS_FACILITY = %d,\n\
+ GDS_ERR_BASE = %ld,\n\
+ GDS_ERR_FACTOR = %ld)\n", gds_facility, (SLONG) gds_base, (SLONG) gds_factor);
numLines = FB_NELEM(ftn_boiler_plate_data);
for (int i=0; i < numLines; i++) {
ib_fprintf(ftn_codes, "%s\n", ftn_boiler_plate_data[i]);
}
2001-05-23 15:26:42 +02:00
/* Start the MSGS file */
ib_fprintf(msgs, "\"unassigned code\",\n");
/* Fetch error codes from SYSTEM_ERRORS relation. Write them
out to the pascal, fortran, and rdb header files */
code = 1;
last_code = code - 1;
FOR S IN SYSTEM_ERRORS CROSS N IN MESSAGES OVER NUMBER WITH
N.FAC_CODE = S.FAC_CODE SORTED BY N.FAC_CODE, S.NUMBER
/* The only facility that is guaranteed to have all codes in system errors
* is JRD */
if (last_code + 1 != N.CODE && N.FAC_CODE == 0)
ib_fprintf(ib_stderr,
"Warning: missing codes between %d and %d (exclusive)\n",
last_code, (int) N.CODE);
last_code = N.CODE;
new_code = ENCODE_ISC_MSG(N.NUMBER, N.FAC_CODE);
ib_fprintf(pas_codes, "\tgds_%-32.32s = %d;\n", S.GDS_SYMBOL,
2001-05-23 15:26:42 +02:00
new_code);
ib_fprintf(ftn_codes,
" INTEGER*4 GDS__%-32.32s\n PARAMETER (GDS__%-32.32s = %d)\n",
S.GDS_SYMBOL, S.GDS_SYMBOL, new_code);
ib_fprintf(rdbcodes, "%d,\n", S.VMS_CODE);
q = text;
end = q;
for (p = N.TEXT; *p && p < N.TEXT + sizeof(N.TEXT); p++) {
if (*p == '"')
*q++ = '\\';
*q++ = *p;
if (*p != ' ')
end = q;
}
*end = 0;
ib_fprintf(msgs, "\"%s\",\t\t/*%d, %-32.32s*/\n",
text, code, S.GDS_SYMBOL);
for (p = S.GDS_SYMBOL;
*p && *p != ' ' && p < S.GDS_SYMBOL + sizeof(S.GDS_SYMBOL) - 1;
p++);
*p = 0;
ib_fprintf(code_text, "{\"%s\", %d},\n", S.GDS_SYMBOL, new_code);
2001-05-23 15:26:42 +02:00
++code;
END_FOR;
CHECK_CLOSE(pas_codes, CODES_PAS, "tmpcode4", "w");
CHECK_CLOSE(ftn_codes, CODES_FTN, "tmpcode5", "w");
CHECK_CLOSE(code_text, CODETEXT_H, "tmpcode6", "w");
CHECK_CLOSE(msgs, MSGS_H, "tmpcode7", "w");
CHECK_CLOSE(rdbcodes, RDBCODES_H, "tmpcode8", "w");
/* build sql_code.h */
CHECK_OPEN(sql_codes, SQL_CODES_H, "tmpcode9", "w");
add_text(sql_codes, CSTYLE, license);
add_text(sql_codes, CSTYLE, warn);
ib_fprintf(sql_codes, "%s\n", sql_code_boiler_plate);
#define DEFAULT_SQL_CODE -999 /* InterBase error */
i = 0;
ib_fprintf(sql_codes, "%4d /* No Error */", 0);
FOR E IN SYSTEM_ERRORS SORTED BY E.FAC_CODE, E.NUMBER
{
/* The only facility that is guaranteed to have all codes in system errors
* is JRD */
if (E.NUMBER != (SSHORT) i + 1 && E.FAC_CODE == 0)
ib_fprintf(ib_stderr,
"Warning: Sequence of error numbers is bad %d!\n",
E.NUMBER);
i = E.NUMBER;
ib_fprintf(sql_codes, ",\n");
if (E.SQL_CODE.NULL)
2002-06-29 15:03:13 +02:00
ib_fprintf(sql_codes, "%4d /* %3d %-32.32s (default) */",
2001-05-23 15:26:42 +02:00
DEFAULT_SQL_CODE, E.NUMBER, E.GDS_SYMBOL);
else
2002-06-29 15:03:13 +02:00
ib_fprintf(sql_codes, "%4d /* %3d %-32.32s */",
E.SQL_CODE, E.NUMBER, E.GDS_SYMBOL);
2001-05-23 15:26:42 +02:00
}
END_FOR;
--code;
ib_fprintf(sql_codes, "\n};\n");
CHECK_CLOSE(sql_codes, SQL_CODES_H, "tmpcode9", "w");
}
static void move_if_not_identical( char* original, char* new_file)
2001-05-23 15:26:42 +02:00
{
char origName[1000];
if ( genDirectory != NULL) {
sprintf(origName,"%s/%s", genDirectory, original);
}
else {
sprintf(origName,"./%s", original);
}
char buffer[1000];
sprintf(buffer, "cmp -s %s %s", new_file, origName);
2001-05-23 15:26:42 +02:00
/* If the new file is identical to the original, then don't update
the original */
if (system(buffer) == 0) {
ib_fprintf(ib_stderr, "No need to update %s\n", origName);
2001-05-23 15:26:42 +02:00
unlink(new_file);
}
else {
/* Original file is missing or different */
sprintf(buffer, "mv -f %s %s", new_file, origName);
2001-05-23 15:26:42 +02:00
if (system(buffer) != 0) {
ib_fprintf(ib_stderr, "Error moving %s to %s!\n",
new_file, origName);
2001-05-23 15:26:42 +02:00
exit(FINI_ERROR);
}
else
ib_fprintf(ib_stderr, "Updated %s\n", origName);
2001-05-23 15:26:42 +02:00
}
}
static void add_text(IB_FILE * fd, int style, const char **text)
{
/*******************************************
*
* a d d _ t e x t
*
*******************************************
*
* Functional desciption
* Function adds text as comment
* in 'style' language
*
*******************************************/
const char **ptr;
switch (style) {
case CSTYLE:
ib_fprintf(fd, "/*\n");
break;
case PASSTYLE:
ib_fprintf(fd, "(*\n");
break;
case FTNSTYLE:
ib_fprintf(fd, "C --\n");
break;
default:
ib_fprintf(ib_stderr, "Error writing license\n");
exit(FINI_ERROR);
break;
}
for (ptr = text; *ptr; ++ptr) {
switch (style) {
case CSTYLE:
case PASSTYLE:
ib_fprintf(fd, " * ");
break;
case FTNSTYLE:
ib_fprintf(fd, "C -- ");
break;
}
ib_fprintf(fd, "%s\n", *ptr);
}
switch (style) {
case CSTYLE:
ib_fprintf(fd, " */\n");
break;
case PASSTYLE:
ib_fprintf(fd, " *)\n");
break;
case FTNSTYLE:
ib_fprintf(fd, "C --\n");
break;
}
}