8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 12:03:02 +01:00
firebird-mirror/src/misc/codes.epp
2005-12-27 08:10:00 +00:00

1010 lines
30 KiB
Plaintext

/*
* PROGRAM: JRD Access Method
* MODULE: codes.epp
* 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
*/
#include "firebird.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "../jrd/common.h"
#include "../jrd/ibase.h"
#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.fdb";
const char* CODES_PAS = "gds_codes.pas";
const char* CODES_FTN = "gds_codes.ftn";
//const char* CODES_H = "codes.h"
const char* IBERROR_H = "iberror.h";
const char* CODETEXT_H = "codetext.h";
const char* MSGS_H = "msgs.h";
const char* RDBCODES_H = "rdb_codes.h";
const char* SQL_CODES_H = "sql_code.h";
const char* MSGFAC_H = "msg_facs.h";
enum formatStyle
{
CSTYLE = 1,
PASSTYLE = 2,
FTNSTYLE = 3,
CPPSTYLE = 4
};
//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(const char *, const char *, const char*);
static void add_text(FILE*, formatStyle, const char **);
static const char* genDirectory = NULL;
static const char* genFtnPasDirectory = NULL;
static void check_open(FILE*& f, const char* name, const char* tmp, const char* mode)
{
f = fopen(tmp, mode);
if (!f)
{
fprintf(stderr, "CODES: Unable to open %s in filemode %s for %s\n",
tmp, mode, name);
exit(FINI_ERROR);
}
}
static void check_close(FILE* f, const char* name, const char* tmp, const char* mode,
const char* directory)
{
fclose(f);
move_if_not_identical(name, tmp, directory);
}
const int FAC_SQL_POSITIVE = 14; // facility for positive SQL codes
const int FAC_SQL_NEGATIVE = 13; // ditto for negative codes
const int gds_facility_local = 20;
const SLONG gds_base_local = (SLONG) gds_facility_local << 24;
const SLONG gds_factor_local = 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",
0
};
static const char *warn[] = {
"",
"*** WARNING *** - This file is automatically generated by codes.epp - do not edit!",
"",
0
};
static const SCHAR *gds_c_boiler_plate[] = {
"#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!
"#define gds_arg_next_mach 15 /* NeXT/Mach error code */",
"#define gds_arg_netware 16 /* NetWare error code */",
"#define gds_arg_win32 17 /* Win32 error code */",
"#define gds_arg_warning 18 /* warning argument */",
"",
};
/* It's used only in code that's commented now: build_codes_h().
static const SCHAR *gds_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",
"",
};
*/
// At first glance, it wasn't evident why isc_facility had to be undefined,
// but it turns that this file includes ibase.h,
// but ibase.h includes iberror.h that's generated by this program!
// The solution is that iberror.h adopts a C++ section like codes.h does.
// Appending "_local" here saves us from any clash.
const int isc_facility_local = 20;
const SLONG isc_base_local = (SLONG) isc_facility_local << 24;
const SLONG isc_factor_local = 1;
static const SCHAR *isc_c_boiler_plate[] = {
"#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!
"#define isc_arg_next_mach 15 /* NeXT/Mach error code */",
"#define isc_arg_netware 16 /* NetWare error code */",
"#define isc_arg_win32 17 /* Win32 error code */",
"#define isc_arg_warning 18 /* warning argument */",
"",
};
static const SCHAR *isc_cpp_boiler_plate[] = {
"const ISC_LONG isc_arg_end = 0; // end of argument list ",
"const ISC_LONG isc_arg_gds = 1; // generic DSRI status value ",
"const ISC_LONG isc_arg_string = 2; // string argument ",
"const ISC_LONG isc_arg_cstring = 3; // count & string argument ",
"const ISC_LONG isc_arg_number = 4; // numeric argument (long) ",
"const ISC_LONG isc_arg_interpreted = 5; // interpreted status code (string) ",
"const ISC_LONG isc_arg_vms = 6; // VAX/VMS status code (long) ",
"const ISC_LONG isc_arg_unix = 7; // UNIX error code ",
"const ISC_LONG isc_arg_domain = 8; // Apollo/Domain error code ",
"const ISC_LONG isc_arg_dos = 9; // MSDOS/OS2 error code ",
"const ISC_LONG isc_arg_mpexl = 10; // HP MPE/XL error code ",
"const ISC_LONG 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!
"const ISC_LONG isc_arg_next_mach = 15; // NeXT/Mach error code ",
"const ISC_LONG isc_arg_netware = 16; // NetWare error code ",
"const ISC_LONG isc_arg_win32 = 17; // Win32 error code ",
"const ISC_LONG isc_arg_warning = 18; // warning argument ",
"",
};
static const SCHAR *pas_boiler_plate[] = {
"\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 *)",
"",
};
static const SCHAR *ftn_boiler_plate_data[] = {
"",
" 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 }",
"",
};
static const SCHAR *ftn_boiler_plate_decls[] = {
" 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 }",
"",
};
int CLIB_ROUTINE main( int argc, char *argv[])
{
/*************************************
*
* m a i n
*
**************************************
*
* Functional description
* Generate both code definition
* include file and message text
* include file.
*
**************************************/
READY
ON_ERROR
printf("Attach failed.\n");
isc_print_status(gds_status);
exit(FINI_ERROR);
END_ERROR;
// See if the user has specified an optional output directory
if (argc >= 1 ) {
genDirectory = argv[1];
}
if (argc >= 2 ) {
genFtnPasDirectory = argv[2];
}
START_TRANSACTION;
build_iberror_h();
// build_codes_h();
build_msgfac_h();
build_other_headers();
COMMIT;
FINISH;
// exit(0);
return 0;
}
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.
*
*******************************************/
FILE *msgfac = NULL;
/* Open msgfac.h in the current directory */
check_open(msgfac, MSGFAC_H, "tmpcode1", "w");
add_text(msgfac, CSTYLE, license);
add_text(msgfac, CSTYLE, warn);
fprintf(msgfac, "/*\n");
fprintf(msgfac, " * MODULE: msg_facs.h\n");
fprintf(msgfac, " * DESCRIPTION: ISC message facilities\n");
fprintf(msgfac, " *\n");
fprintf(msgfac, " */\n");
fprintf(msgfac, "\n\n\n");
fprintf(msgfac, "/******************************/\n");
fprintf(msgfac, "/* ISC message facilities */\n");
fprintf(msgfac, "/******************************/\n");
fprintf(msgfac, "\n");
fprintf(msgfac, "struct _facilities {\n");
fprintf(msgfac, "\tint fac_code;\n");
fprintf(msgfac, "\tchar *facility;\n");
fprintf(msgfac, "\t};\n\n");
fprintf(msgfac, "static const struct _facilities facilities[] = {\n");
FOR F IN FACILITIES WITH ANY FAC_CODE IN SYSTEM_ERRORS OVER FAC_CODE
fprintf(msgfac, "\t{%d, \"%-10.10s\"},\n", F.FAC_CODE, F.FACILITY);
END_FOR;
fprintf(msgfac, "\t{0, NULL}\n};\n\n");
fprintf(msgfac, "\n");
check_close(msgfac, MSGFAC_H, "tmpcode1", "w", genDirectory);
}
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.
*
*******************************************/
FILE *iberror = NULL;
int i, 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");
fprintf(iberror, "\n#ifndef JRD_GEN_IBERROR_H\n");
fprintf(iberror, "#define JRD_GEN_IBERROR_H\n");
add_text(iberror, CSTYLE, license);
add_text(iberror, CSTYLE, warn);
fprintf(iberror, "/*\n");
fprintf(iberror, " * MODULE: iberror.h\n");
fprintf(iberror, " * DESCRIPTION: ISC error codes\n");
fprintf(iberror, " *\n");
fprintf(iberror, " */\n");
fprintf(iberror, "\n\n\n");
fprintf(iberror, "/***********************/\n");
fprintf(iberror, "/* ISC Error Codes */\n");
fprintf(iberror, "/***********************/\n");
fprintf(iberror, "\n");
fprintf(iberror, "\n#ifdef __cplusplus /* c++ definitions */\n\n");
fprintf(iberror,
"const ISC_LONG isc_facility = %d;\n", isc_facility_local);
fprintf(iberror,
"const ISC_LONG isc_base = %"SLONGFORMAT"L;\n", isc_base_local);
fprintf(iberror,
"const ISC_LONG isc_factor = %"SLONGFORMAT";\n", isc_factor_local);
// Append the ISC C++ boiler plate
int numLines = FB_NELEM(isc_cpp_boiler_plate);
for (i = 0; i < numLines; i++) {
fprintf(iberror, "%s\n", isc_cpp_boiler_plate[i]);
}
// 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)
{
fprintf(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);
fprintf(iberror, "const ISC_LONG isc_%-32.32s = %luL;\n", S.GDS_SYMBOL,
new_code);
++code;
END_FOR;
--code;
fprintf(iberror, "const ISC_LONG isc_%-32.32s = %d;\n", "err_max", code);
fprintf(iberror, "\n");
fprintf(iberror, "#else /* c definitions */\n\n");
// Reset counters for a new iteration.
code = 1;
last_code = code - 1;
new_code = 0L;
fprintf(iberror, "#define isc_facility %d\n", isc_facility_local);
fprintf(iberror, "#define isc_base %"SLONGFORMAT"L\n", isc_base_local);
fprintf(iberror, "#define isc_factor %"SLONGFORMAT"\n", isc_factor_local);
fprintf(iberror, "\n");
// Append the ISC C boiler plate
numLines = FB_NELEM(isc_c_boiler_plate);
for (i = 0; i < numLines; i++) {
fprintf(iberror, "%s\n", isc_c_boiler_plate[i]);
}
// 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)
{
fprintf(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);
fprintf(iberror, "#define isc_%-32.32s %luL\n", S.GDS_SYMBOL,
new_code);
++code;
END_FOR;
--code;
fprintf(iberror, "#define isc_%-32.32s %d\n", "err_max", code);
fprintf(iberror, "\n");
fprintf(iberror, "#endif\n\n");
fprintf(iberror, "#endif /* JRD_GEN_IBERROR_H */\n");
check_close(iberror, IBERROR_H, "tmpcode2", "w", genDirectory);
}
//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.
//*
//*******************************************/
// FILE *c_codes = NULL;
// int i, code = 1, last_code = code - 1;
// 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);
//
// fprintf(c_codes, "\n#ifndef JRD_GEN_CODES_H\n");
// fprintf(c_codes, "#define JRD_GEN_CODES_H\n");
//
// fprintf(c_codes, "\n#ifdef __cplusplus /* c++ definitions */\n\n");
//
// fprintf(c_codes, "const SLONG gds_facility = %d;\n", gds_facility_local);
// fprintf(c_codes, "const SLONG gds_err_base = %ldL;\n", gds_base_local);
// fprintf(c_codes, "const SLONG gds_err_factor = %ld;\n", gds_factor_local);
//
// // Append the C++ boiler plate
// int numLines = FB_NELEM(gds_cpp_boiler_plate);
// for (i = 0; i < numLines; i++) {
// fprintf(c_codes, "%s\n", gds_cpp_boiler_plate[i]);
// }
//
//
// 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)
// {
// fprintf(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);
// fprintf(c_codes, "const SLONG gds_%-32.32s = %luL;\n", S.GDS_SYMBOL,
// 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)
// {
// 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;
// fprintf(c_codes, "const SLONG gds_%-32.32s = %dL;\n", "err_max", code);
// fprintf(c_codes, "\n");
//
//
// fprintf(c_codes, "#else /* c definitions */\n\n");
//
//
// fprintf(c_codes, "#define gds_facility %d\n", gds_facility_local);
// fprintf(c_codes, "#define gds_err_base %ldL\n", gds_base_local);
// fprintf(c_codes, "#define gds_err_factor %ld\n", gds_factor_local);
//
// // Reset the variables for another trip round the loop.
// code = 1;
// last_code = code - 1;
// new_code = 0L;
//
// // Append the C boiler plate
// numLines = FB_NELEM(gds_c_boiler_plate);
// for (i = 0; i < numLines; i++) {
// fprintf(c_codes, "%s\n", gds_c_boiler_plate[i]);
// }
//
//
// 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)
// {
// fprintf(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);
// fprintf(c_codes, "#define gds__%-32.32s %luL\n", S.GDS_SYMBOL,
// 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)
// {
// 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;
// fprintf(c_codes, "#define gds_%-32.32s %d\n", "err_max", code);
// fprintf(c_codes, "\n");
//
//
// 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
//*/
// fprintf(c_codes, "#include \"iberror.h\"\n\n");
//
//
// fprintf(c_codes, "#endif /* JRD_GEN_CODES_H */\n");
//
// check_close(c_codes, CODES_H, "tmpcode3", "w", genDirectory);
//}
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.
*
*********************************************/
SCHAR text[128];
int last_code, code, i;
unsigned long new_code = 0L;
/* Use the check_open function to open header files in current directory. */
FILE* pas_codes = NULL;
check_open(pas_codes, CODES_PAS, "tmpcode4", "w");
FILE* ftn_codes = NULL;
check_open(ftn_codes, CODES_FTN, "tmpcode5", "w");
FILE* code_text = NULL;
check_open(code_text, CODETEXT_H, "tmpcode6", "w");
FILE* msgs = NULL;
check_open(msgs, MSGS_H, "tmpcode7", "w");
FILE* rdbcodes = NULL;
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 */
fprintf(pas_codes, "\n"
"const\n"
"\tgds_facility\t\t= %d;\n"
"\tgds_err_base\t\t= %ld;\n"
"\tgds_err_factor\t\t= %ld;\n",
gds_facility_local, gds_base_local, gds_factor_local);
int numLines = FB_NELEM(pas_boiler_plate);
for (i = 0; i < numLines; i++) {
fprintf(pas_codes, "%s\n", pas_boiler_plate[i]);
}
/* Start the FORTRAN codes file */
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 (i = 0; i < numLines; i++) {
fprintf(ftn_codes, "%s\n", ftn_boiler_plate_decls[i]);
}
fprintf(ftn_codes, "\n"
" PARAMETER (\n"
" + GDS_FACILITY = %d,\n"
" + GDS_ERR_BASE = %ld,\n"
" + GDS_ERR_FACTOR = %ld)\n",
gds_facility_local, gds_base_local, gds_factor_local);
numLines = FB_NELEM(ftn_boiler_plate_data);
for (i = 0; i < numLines; i++) {
fprintf(ftn_codes, "%s\n", ftn_boiler_plate_data[i]);
}
/* Start the rdb_codes.h */
fprintf(rdbcodes, "static SLONG user_codes[] = {\n");
fprintf(rdbcodes, "1,\n");
/* Start the codetext.h */
fprintf(code_text, "static const struct {\n");
fprintf(code_text, "\tconst SCHAR *code_string;\n");
fprintf(code_text, "\tSLONG code_number;\n");
fprintf(code_text, "} codes[] =\n{\n");
/* Start the MSGS file */
fprintf(msgs, "static const struct {\n");
fprintf(msgs, "\tSLONG code_number;\n");
fprintf(msgs, "\tconst SCHAR *code_text;\n");
fprintf(msgs, "} messages[] = {\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)
{
fprintf(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);
fprintf(pas_codes, "\tgds_%-32.32s = %lu;\n", S.GDS_SYMBOL,
new_code);
fprintf(ftn_codes,
" INTEGER*4 GDS__%-32.32s\n PARAMETER (GDS__%-32.32s = %lu)\n",
S.GDS_SYMBOL, S.GDS_SYMBOL, new_code);
fprintf(rdbcodes, "%ld,\n", S.VMS_CODE);
SCHAR* q = text;
SCHAR* end = q;
for (const SCHAR* p = N.TEXT; *p && p < N.TEXT + sizeof(N.TEXT); p++)
{
if (*p == '"')
*q++ = '\\';
*q++ = *p;
if (*p != ' ')
end = q;
}
*end = 0;
q = S.GDS_SYMBOL;
while (*q && *q != ' ' && q < S.GDS_SYMBOL + sizeof(S.GDS_SYMBOL) - 1)
q++;
*q = 0;
fprintf(code_text, "\t{\"%s\", %lu},\n",
S.GDS_SYMBOL, new_code);
fprintf(msgs, "\t{%lu, \"%s\"},\t\t/* %d, %s */\n",
new_code, text, code, S.GDS_SYMBOL);
++code;
END_FOR;
/* end the rdb_codes.h */
fprintf(rdbcodes, "};\n");
/* end the codetext.h */
fprintf(code_text, "\t{NULL, 0}\n");
fprintf(code_text, "};\n");
/* end the msgs.h */
fprintf(msgs, "\t{0, NULL}\n");
fprintf(msgs, "};\n");
check_close(pas_codes, CODES_PAS, "tmpcode4", "w", genFtnPasDirectory);
check_close(ftn_codes, CODES_FTN, "tmpcode5", "w", genFtnPasDirectory);
check_close(code_text, CODETEXT_H, "tmpcode6", "w", genDirectory);
check_close(msgs, MSGS_H, "tmpcode7", "w", genDirectory);
check_close(rdbcodes, RDBCODES_H, "tmpcode8", "w", genDirectory);
// build sql_code.h
FILE* sql_codes = NULL;
check_open(sql_codes, SQL_CODES_H, "tmpcode9", "w");
add_text(sql_codes, CSTYLE, license);
add_text(sql_codes, CSTYLE, warn);
fprintf(sql_codes, "static const struct {\n");
fprintf(sql_codes, "\tSLONG gds_code;\n");
fprintf(sql_codes, "\tSSHORT sql_code;\n");
fprintf(sql_codes, "} gds__sql_code[] = {\n");
const int DEFAULT_SQL_CODE = -999; // InterBase error
i = 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)
{
fprintf(stderr,
"Warning: Sequence of error numbers is bad %d!\n",
E.NUMBER);
}
i = E.NUMBER;
new_code = ENCODE_ISC_MSG(E.NUMBER, E.FAC_CODE);
if (E.SQL_CODE.NULL)
{
fprintf(sql_codes, "\t{%lu, %4d}, /* %3d %-32.32s (default) */\n",
new_code, DEFAULT_SQL_CODE, E.NUMBER, E.GDS_SYMBOL);
}
else {
fprintf(sql_codes, "\t{%lu, %4d}, /* %3d %-32.32s */\n",
new_code, (int) E.SQL_CODE, E.NUMBER, E.GDS_SYMBOL);
}
END_FOR;
--code;
fprintf(sql_codes, "\t{0, 0}\n");
fprintf(sql_codes, "};\n");
check_close(sql_codes, SQL_CODES_H, "tmpcode9", "w", genDirectory);
}
static void move_if_not_identical( const char* original, const char* new_file,
const char *directory)
{
char origName[1000];
char buffer[1000];
#if defined(WIN_NT) && !defined(__GNUC__)
if ( directory != NULL) {
sprintf(origName, "%s\\%s", directory, original);
}
else {
sprintf(origName, ".\\%s", original);
}
/*
* This is a trick to make on systems previous to W2K were apparently
* fc does not return a errorlevel, but find return it (1 found 0 not found)
* FC: appear only where there are no differences (and the switch /B is not used)
*/
sprintf(buffer, "fc %s %s | find \"FC:\" > nul", new_file, origName);
#else
if ( directory != NULL) {
sprintf(origName, "%s/%s", directory, original);
}
else {
sprintf(origName, "./%s", original);
}
sprintf(buffer, "cmp -s %s %s", new_file, origName);
#endif
/* If the new file is identical to the original, then don't update
the original */
if (system(buffer) == 0) {
fprintf(stdout, "No need to update %s\n", origName);
unlink(new_file);
}
else {
/* Original file is missing or different */
#if defined(WIN_NT) && !defined(__GNUC__)
sprintf(buffer, "move %s %s > nul", new_file, origName);
#else
sprintf(buffer, "mv -f %s %s", new_file, origName);
#endif
if (system(buffer) != 0) {
fprintf(stderr, "Error moving %s to %s!\n",
new_file, origName);
exit(FINI_ERROR);
}
else
fprintf(stdout, "Updated %s\n", origName);
}
}
static void add_text(FILE * fd, formatStyle style, const char **text)
{
/*******************************************
*
* a d d _ t e x t
*
*******************************************
*
* Functional desciption
* Function adds text as comment
* in 'style' language
*
*******************************************/
switch (style) {
case CSTYLE:
fprintf(fd, "/*\n");
break;
case PASSTYLE:
fprintf(fd, "(*\n");
break;
case FTNSTYLE:
fprintf(fd, "C --\n");
break;
case CPPSTYLE:
fprintf(fd, "//\n");
break;
default:
fprintf(stderr, "Error writing license\n");
exit(FINI_ERROR);
break;
}
for (const char** ptr = text; *ptr; ++ptr)
{
switch (style) {
case CSTYLE:
case PASSTYLE:
fprintf(fd, " * ");
break;
case FTNSTYLE:
fprintf(fd, "C -- ");
break;
case CPPSTYLE:
fprintf(fd, "// ");
break;
}
fprintf(fd, "%s\n", *ptr);
}
switch (style) {
case CSTYLE:
fprintf(fd, " */\n");
break;
case PASSTYLE:
fprintf(fd, " *)\n");
break;
case FTNSTYLE:
fprintf(fd, "C --\n");
break;
case CPPSTYLE:
fprintf(fd, "//\n");
break;
}
}