mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 12:03:02 +01:00
1010 lines
30 KiB
Plaintext
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;
|
|
}
|
|
}
|
|
|