2001-05-23 15:26:42 +02:00
|
|
|
/*
|
|
|
|
* PROGRAM: Data Definition Utility
|
|
|
|
* MODULE: ddl.c
|
|
|
|
* DESCRIPTION: Main line routine
|
|
|
|
*
|
|
|
|
* 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): ______________________________________.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define DDL_MAIN
|
|
|
|
#include "../jrd/ib_stdio.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "../dudley/ddl.h"
|
|
|
|
#include "../include/jrd/gds.h"
|
|
|
|
#include "../jrd/license.h"
|
|
|
|
#include "../dudley/ddl_proto.h"
|
|
|
|
#include "../dudley/exe_proto.h"
|
|
|
|
#include "../dudley/expan_proto.h"
|
|
|
|
#include "../dudley/extra_proto.h"
|
|
|
|
#include "../dudley/hsh_proto.h"
|
|
|
|
#include "../dudley/lex_proto.h"
|
|
|
|
#include "../dudley/parse_proto.h"
|
|
|
|
#include "../dudley/trn_proto.h"
|
|
|
|
#include "../jrd/gds_proto.h"
|
|
|
|
#include "../jrd/why_proto.h"
|
|
|
|
|
2001-07-12 07:46:06 +02:00
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
#if defined(WIN_NT)
|
|
|
|
#include <io.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
TEXT *DDL_prompt;
|
|
|
|
|
|
|
|
static LLS free_stack;
|
|
|
|
static TEXT DDL_message[256];
|
|
|
|
|
|
|
|
#ifndef FOPEN_INPUT_TYPE
|
|
|
|
#define FOPEN_INPUT_TYPE "r"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define DDL_EXT ".gdl" /* normal extension for a ddl file */
|
|
|
|
#define MAX_ERRORS 50
|
|
|
|
|
|
|
|
#define IN_SW_GDEF_0 0 /* null switch value */
|
|
|
|
#define IN_SW_GDEF_G 1 /* generate DDL from a database file */
|
|
|
|
#define IN_SW_GDEF_R 2 /* replace existing database */
|
|
|
|
#define IN_SW_GDEF_D 3 /* generate dynamic DDL */
|
|
|
|
#define IN_SW_GDEF_Z 4 /* print version number */
|
|
|
|
#define IN_SW_GDEF_T 5 /* print tokens as they are read */
|
|
|
|
#define IN_SW_GDEF_C 7 /* source is C */
|
|
|
|
#define IN_SW_GDEF_F 8 /* source is FORTRAN */
|
|
|
|
#define IN_SW_GDEF_P 9 /* source is PASCAL */
|
|
|
|
#define IN_SW_GDEF_COB 10 /* source is (shudder) cobol */
|
|
|
|
#define IN_SW_GDEF_ANSI 11 /* source is (worse and worse!) ansi format */
|
|
|
|
#define IN_SW_GDEF_BAS 12 /* source is basic */
|
|
|
|
#define IN_SW_GDEF_PLI 13 /* source is pli */
|
|
|
|
#define IN_SW_GDEF_ADA 14 /* source is ada */
|
|
|
|
#define IN_SW_GDEF_CXX 15 /* source is C++ */
|
|
|
|
#define IN_SW_GDEF_7 16 /* force creation of an ODS 7 database */
|
|
|
|
#define IN_SW_GDEF_USER 17 /* user name for PC security */
|
|
|
|
#define IN_SW_GDEF_PASSWORD 18 /* password for PC security */
|
|
|
|
|
|
|
|
static struct in_sw_tab_t gdef_in_sw_table[] = {
|
|
|
|
IN_SW_GDEF_G, 0, "EXTRACT", 0, 0, 0, FALSE, 0, 0,
|
|
|
|
"\t\textract definition from database", /* extract DDL from database */
|
|
|
|
IN_SW_GDEF_R, 0, "REPLACE", 0, 0, 0, FALSE, 0, 0,
|
|
|
|
"\t\treplace existing database", /* replace database */
|
|
|
|
IN_SW_GDEF_D, 0, "DYNAMIC", 0, 0, 0, FALSE, 0, 0,
|
|
|
|
"\t\tgenerate dynamic DDL",
|
|
|
|
IN_SW_GDEF_T, 0, "T", 0, 0, 0, FALSE, 0, 0, NULL,
|
|
|
|
IN_SW_GDEF_C, 0, "C", 0, 0, 0, FALSE, 0, 0, "\t\tDYN for C",
|
|
|
|
IN_SW_GDEF_F, 0, "FORTRAN", 0, 0, 0, FALSE, 0, 0, "\t\tDYN for FORTRAN",
|
|
|
|
IN_SW_GDEF_P, 0, "PASCAL", 0, 0, 0, FALSE, 0, 0, "\t\tDYN for PASCAL",
|
|
|
|
IN_SW_GDEF_COB, 0, "COB", 0, 0, 0, FALSE, 0, 0, "\t\tDYN for COBOL",
|
|
|
|
IN_SW_GDEF_ANSI, 0, "ANSI", 0, 0, 0, FALSE, 0, 0,
|
|
|
|
"\t\tDYN for ANSI COBOL",
|
|
|
|
IN_SW_GDEF_BAS, 0, "BASIC", 0, 0, 0, FALSE, 0, 0, "\t\tDYN for BASIC",
|
|
|
|
IN_SW_GDEF_PLI, 0, "PLI", 0, 0, 0, FALSE, 0, 0, "\t\tDYN for PLI",
|
|
|
|
IN_SW_GDEF_ADA, 0, "ADA", 0, 0, 0, FALSE, 0, 0, "\t\tDYN for ADA",
|
|
|
|
IN_SW_GDEF_CXX, 0, "CXX", 0, 0, 0, FALSE, 0, 0, "\t\tDYN for C++",
|
|
|
|
#ifdef DEV_BUILD
|
|
|
|
IN_SW_GDEF_7, 0, "7", 0, 0, 0, FALSE, 0, 0, NULL,
|
|
|
|
#endif
|
|
|
|
IN_SW_GDEF_USER, 0, "USER", 0, 0, 0, FALSE, 0, 0,
|
|
|
|
"\t\tuser name to use in attaching database",
|
|
|
|
IN_SW_GDEF_PASSWORD, 0, "PASSWORD", 0, 0, 0, FALSE, 0, 0,
|
|
|
|
"\t\tpassword to use with user name",
|
|
|
|
IN_SW_GDEF_Z, 0, "Z", 0, 0, 0, FALSE, 0, 0, "\t\tprint version number",
|
|
|
|
IN_SW_GDEF_0, 0, NULL, 0, 0, 0, FALSE, 0, 0, NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
int CLIB_ROUTINE main( int argc, char *argv[])
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* m a i n
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Main line routine for C preprocessor. Initializes
|
|
|
|
* system, performs pass 1 and pass 2. Interpretes
|
|
|
|
* command line.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
IB_FILE *input_file;
|
|
|
|
TEXT c, c1, *p, *q, *string, file_name_1[256], file_name_2[256],
|
|
|
|
buffer[256], dyn_file_name[256];
|
|
|
|
USHORT in_sw;
|
|
|
|
IN_SW_TAB in_sw_tab;
|
|
|
|
ACT temp, stack;
|
|
|
|
FIL file;
|
|
|
|
SLONG redir_in, redir_out, redir_err;
|
|
|
|
#ifdef DEV_BUILD
|
|
|
|
USHORT sw_ods7;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef VMS
|
|
|
|
argc = VMS_parse(&argv, argc);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Perform some special handling when run as an Interbase service. The
|
|
|
|
first switch can be "-svc" (lower case!) or it can be "-svc_re" followed
|
|
|
|
by 3 file descriptors to use in re-directing ib_stdin, ib_stdout, and ib_stderr. */
|
|
|
|
|
|
|
|
DDL_service = FALSE;
|
|
|
|
|
|
|
|
if (argc > 1 && !strcmp(argv[1], "-svc")) {
|
|
|
|
DDL_service = TRUE;
|
|
|
|
argv++;
|
|
|
|
argc--;
|
|
|
|
}
|
|
|
|
else if (argc > 4 && !strcmp(argv[1], "-svc_re")) {
|
|
|
|
DDL_service = TRUE;
|
|
|
|
redir_in = atol(argv[2]);
|
|
|
|
redir_out = atol(argv[3]);
|
|
|
|
redir_err = atol(argv[4]);
|
|
|
|
#ifdef WIN_NT
|
|
|
|
redir_in = _open_osfhandle(redir_in, 0);
|
|
|
|
redir_out = _open_osfhandle(redir_out, 0);
|
|
|
|
redir_err = _open_osfhandle(redir_err, 0);
|
|
|
|
#endif
|
|
|
|
if (redir_in != 0)
|
|
|
|
if (dup2((int) redir_in, 0))
|
|
|
|
close((int) redir_in);
|
|
|
|
if (redir_out != 1)
|
|
|
|
if (dup2((int) redir_out, 1))
|
|
|
|
close((int) redir_out);
|
|
|
|
if (redir_err != 2)
|
|
|
|
if (dup2((int) redir_err, 2))
|
|
|
|
close((int) redir_err);
|
|
|
|
argv += 4;
|
|
|
|
argc -= 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
DDL_file_name = NULL;
|
|
|
|
DB_file_name = NULL;
|
|
|
|
DDL_drop_database = DDL_quit = DDL_extract = DDL_dynamic = DDL_trace =
|
|
|
|
DDL_version = FALSE;
|
|
|
|
DDL_default_user = DDL_default_password = NULL;
|
|
|
|
#ifdef DEV_BUILD
|
|
|
|
sw_ods7 = FALSE;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if (defined JPN_EUC || defined JPN_SJIS)
|
|
|
|
DDL_interp = HOST_INTERP;
|
|
|
|
|
|
|
|
/* Initialize the array which is used to map untagged versions of
|
|
|
|
ddl verbs into tagged versions. */
|
|
|
|
|
|
|
|
DDL_tagged_verbs[gds__dyn_description] = gds__dyn_description2;
|
|
|
|
DDL_tagged_verbs[gds__dyn_fld_computed_source] =
|
|
|
|
gds__dyn_fld_computed_source2;
|
|
|
|
DDL_tagged_verbs[gds__dyn_fld_edit_string] = gds__dyn_fld_edit_string2;
|
|
|
|
DDL_tagged_verbs[gds__dyn_fld_query_header] = gds__dyn_fld_query_header2;
|
|
|
|
DDL_tagged_verbs[gds__dyn_fld_validation_source] =
|
|
|
|
gds__dyn_fld_validation_source2;
|
|
|
|
DDL_tagged_verbs[gds__dyn_trg_msg] = gds__dyn_trg_msg2;
|
|
|
|
DDL_tagged_verbs[gds__dyn_trg_source] = gds__dyn_trg_source2;
|
|
|
|
DDL_tagged_verbs[gds__dyn_view_source] = gds__dyn_view_source2;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
file_name_1[0] = file_name_2[0] = 0;
|
|
|
|
|
|
|
|
for (--argc; argc; argc--) {
|
|
|
|
string = *++argv;
|
|
|
|
if ((*string != '-') && (*string != '?')) {
|
|
|
|
if (!*file_name_1)
|
|
|
|
strcpy(file_name_1, string);
|
|
|
|
else
|
|
|
|
strcpy(file_name_2, string);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else if (*string == '-') {
|
|
|
|
/* iterate through the switch table, looking for matches */
|
|
|
|
|
|
|
|
in_sw = IN_SW_GDEF_0;
|
|
|
|
for (in_sw_tab = gdef_in_sw_table; q = in_sw_tab->in_sw_name;
|
|
|
|
in_sw_tab++) {
|
|
|
|
p = string + 1;
|
|
|
|
|
|
|
|
/* handle orphaned hyphen case */
|
|
|
|
|
|
|
|
if (!*p--)
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* compare switch to switch name in table */
|
|
|
|
|
|
|
|
while (*p) {
|
|
|
|
if (!*++p)
|
|
|
|
in_sw = in_sw_tab->in_sw;
|
|
|
|
if (UPPER(*p) != *q++)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* end of input means we got a match. stop looking */
|
|
|
|
|
|
|
|
if (!*p)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch (in_sw) {
|
|
|
|
case IN_SW_GDEF_D:
|
|
|
|
DDL_dynamic = TRUE;
|
|
|
|
DYN_file_name[0] = 0;
|
|
|
|
if (argc == 1)
|
|
|
|
break;
|
|
|
|
string = *++argv;
|
|
|
|
if (*string != '-') {
|
|
|
|
argc--;
|
|
|
|
strcpy(DYN_file_name, string);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
argv--;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IN_SW_GDEF_C:
|
|
|
|
language = lan_c;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IN_SW_GDEF_P:
|
|
|
|
language = lan_pascal;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IN_SW_GDEF_COB:
|
|
|
|
language = lan_cobol;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IN_SW_GDEF_ANSI:
|
|
|
|
language = lan_ansi_cobol;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IN_SW_GDEF_BAS:
|
|
|
|
language = lan_basic;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IN_SW_GDEF_PLI:
|
|
|
|
language = lan_pli;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IN_SW_GDEF_F:
|
|
|
|
language = lan_fortran;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IN_SW_GDEF_ADA:
|
|
|
|
language = lan_ada;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IN_SW_GDEF_CXX:
|
|
|
|
language = lan_cxx;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IN_SW_GDEF_G:
|
|
|
|
DDL_extract = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IN_SW_GDEF_R:
|
|
|
|
DDL_replace = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IN_SW_GDEF_T:
|
|
|
|
DDL_trace = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IN_SW_GDEF_Z:
|
|
|
|
DDL_msg_put(0, GDS_VERSION, 0, 0, 0, 0); /* msg 0: gdef version %s\n */
|
|
|
|
DDL_version = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IN_SW_GDEF_PASSWORD:
|
|
|
|
if (argc > 1) {
|
|
|
|
DDL_default_password = *++argv;
|
|
|
|
argc--;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IN_SW_GDEF_USER:
|
|
|
|
if (argc > 1) {
|
|
|
|
DDL_default_user = *++argv;
|
|
|
|
argc--;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
#ifdef DEV_BUILD
|
|
|
|
case IN_SW_GDEF_7:
|
|
|
|
sw_ods7 = TRUE;
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
case IN_SW_GDEF_0:
|
|
|
|
if (*string != '?')
|
|
|
|
DDL_msg_put(1, string, 0, 0, 0, 0); /* msg 1: gdef: unknown switch %s */
|
|
|
|
DDL_msg_put(2, 0, 0, 0, 0, 0); /* msg 2: \tlegal switches are: */
|
|
|
|
for (in_sw_tab = gdef_in_sw_table; in_sw_tab->in_sw; in_sw_tab++)
|
|
|
|
if (in_sw_tab->in_sw_text)
|
|
|
|
DDL_msg_put(3, in_sw_tab->in_sw_name,
|
|
|
|
in_sw_tab->in_sw_text, 0, 0, 0); /* msg 3: %s%s */
|
|
|
|
DDL_exit(FINI_ERROR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DDL_extract) {
|
|
|
|
strcpy(DB_file_string, file_name_1);
|
|
|
|
strcpy(DDL_file_string, file_name_2);
|
|
|
|
if (!*DB_file_string) {
|
|
|
|
DDL_msg_put(4, 0, 0, 0, 0, 0); /* msg 4: gdef: Database name is required for extract */
|
|
|
|
DDL_exit(FINI_ERROR);
|
|
|
|
}
|
|
|
|
DB_file_name = DB_file_string;
|
|
|
|
DDL_file_name = DDL_file_string;
|
|
|
|
DDL_ext();
|
|
|
|
DDL_exit(FINI_OK);
|
|
|
|
}
|
|
|
|
else if (*file_name_1) {
|
|
|
|
strcpy(DDL_file_string, file_name_1);
|
|
|
|
DDL_file_name = DDL_file_string;
|
|
|
|
}
|
|
|
|
if (DDL_file_name == NULL) {
|
|
|
|
DDL_file_name = "standard input";
|
|
|
|
input_file = ib_stdin;
|
|
|
|
DDL_interactive = DDL_service || isatty(0);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/*
|
|
|
|
* try to open the input DDL file.
|
|
|
|
* If it already has a .GDL extension, just try to open it.
|
|
|
|
* Otherwise, add the extension, try, remove the extension,
|
|
|
|
* and try again.
|
|
|
|
*/
|
|
|
|
|
|
|
|
input_file = NULL;
|
|
|
|
|
|
|
|
/* first find the extension by going to the end and backing up */
|
|
|
|
|
|
|
|
for (p = DDL_file_name; *p; p++);
|
|
|
|
while ((p != DDL_file_name) && (*p != '.') && (*p != '/'))
|
|
|
|
p--;
|
|
|
|
|
|
|
|
/* then handle the case where the input already ends in .GDL */
|
|
|
|
|
|
|
|
if (*p == '.') {
|
|
|
|
for (q = DDL_EXT; UPPER(*p) == UPPER(*q); p++, q++)
|
|
|
|
if (!*p) {
|
|
|
|
input_file = ib_fopen(DDL_file_name, FOPEN_INPUT_TYPE);
|
|
|
|
if (!input_file) {
|
|
|
|
DDL_msg_put(5, DDL_file_name, 0, 0, 0, 0); /* msg 5: gdef: can't open %s */
|
|
|
|
DDL_exit(FINI_ERROR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if we got this far without opening it, it's time to add the new extension */
|
|
|
|
|
|
|
|
if (!input_file) {
|
|
|
|
sprintf(file_name_1, "%s%s", DDL_file_name, DDL_EXT);
|
|
|
|
input_file = ib_fopen(file_name_1, FOPEN_INPUT_TYPE);
|
|
|
|
if (input_file)
|
|
|
|
DDL_file_name = file_name_1;
|
|
|
|
else {
|
|
|
|
input_file = ib_fopen(DDL_file_name, FOPEN_INPUT_TYPE);
|
|
|
|
if (!input_file)
|
|
|
|
DDL_msg_put(6, DDL_file_name, file_name_1, 0, 0, 0);
|
|
|
|
/* msg 6: gdef: can't open %s or %s */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!input_file)
|
|
|
|
DDL_exit(FINI_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEV_BUILD
|
|
|
|
if (sw_ods7) {
|
|
|
|
gds__enable_subsystem("GDSSHR5");
|
|
|
|
gds__enable_subsystem("PIPE5");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
LEX_init(input_file);
|
|
|
|
HSH_init();
|
|
|
|
PARSE_actions();
|
|
|
|
|
|
|
|
if (input_file != ib_stdin)
|
|
|
|
ib_fclose(input_file);
|
|
|
|
|
|
|
|
if (DDL_actions && ((DDL_errors && DDL_interactive) || DDL_quit)) {
|
|
|
|
ib_rewind(ib_stdin);
|
|
|
|
*buffer = 0;
|
|
|
|
if (DDL_errors > 1)
|
|
|
|
DDL_msg_partial(7, (TEXT *) DDL_errors, 0, 0, 0, 0); /* msg 7: \n%d errors during input. */
|
|
|
|
else if (DDL_errors)
|
|
|
|
DDL_msg_partial(9, 0, 0, 0, 0, 0); /* msg 9: \n1 error during input. */
|
|
|
|
else
|
|
|
|
DDL_msg_partial(8, 0, 0, 0, 0, 0); /* msg 8: \nNo errors. */
|
|
|
|
if (DDL_yes_no(10)) /* msg 10 : save changes before exiting? */
|
|
|
|
DDL_quit = DDL_errors = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Reverse the set of actions */
|
|
|
|
|
|
|
|
stack = NULL;
|
|
|
|
while (DDL_actions) {
|
|
|
|
temp = DDL_actions;
|
|
|
|
DDL_actions = temp->act_next;
|
|
|
|
temp->act_next = stack;
|
|
|
|
stack = temp;
|
|
|
|
}
|
|
|
|
DDL_actions = stack;
|
|
|
|
|
|
|
|
if (!DDL_errors && !DDL_quit) {
|
|
|
|
EXP_actions();
|
|
|
|
if (!DDL_errors && !DDL_quit) {
|
|
|
|
EXE_execute();
|
|
|
|
if (DDL_dynamic)
|
|
|
|
TRN_translate();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DDL_actions && (DDL_errors || DDL_quit))
|
|
|
|
if (DDL_errors)
|
|
|
|
DDL_msg_put(307, 0, 0, 0, 0, 0); /* msg 307: Ceasing processing because of errors. */
|
|
|
|
else
|
|
|
|
DDL_msg_put(308, 0, 0, 0, 0, 0); /* msg 308: Ceasing processing. */
|
|
|
|
|
|
|
|
EXE_fini(database);
|
|
|
|
|
|
|
|
if (DDL_errors) {
|
|
|
|
if (database && (database->dbb_flags & DBB_create_database)) {
|
|
|
|
for (file = database->dbb_files; file; file = file->fil_next)
|
|
|
|
unlink(file->fil_name->sym_name);
|
|
|
|
unlink(database->dbb_name->sym_string);
|
|
|
|
}
|
|
|
|
DDL_exit(FINI_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
DDL_exit(FINI_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UCHAR *DDL_alloc(register int size)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D D L _ a l l o c
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
register UCHAR *block, *p;
|
|
|
|
|
2001-07-12 07:46:06 +02:00
|
|
|
p = block = (UCHAR*) gds__alloc((SLONG) size);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
#ifdef DEBUG_GDS_ALLOC
|
|
|
|
/* For V4.0 we don't care about gdef specific memory leaks */
|
|
|
|
gds_alloc_flag_unfreed(block);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!p)
|
|
|
|
DDL_err(14, 0, 0, 0, 0, 0); /* msg 14: memory exhausted */
|
|
|
|
else
|
|
|
|
do
|
|
|
|
*p++ = 0;
|
|
|
|
while (--size);
|
|
|
|
|
|
|
|
return block;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int DDL_db_error(
|
|
|
|
STATUS * status_vector,
|
|
|
|
USHORT number,
|
|
|
|
TEXT * arg1,
|
|
|
|
TEXT * arg2, TEXT * arg3, TEXT * arg4, TEXT * arg5)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D D L _ d b _ e r r o r
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Issue an error message.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
|
|
|
gds__print_status(status_vector);
|
|
|
|
|
|
|
|
return DDL_err(number, arg1, arg2, arg3, arg4, arg5);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int DDL_err(
|
|
|
|
USHORT number,
|
|
|
|
TEXT * arg1, TEXT * arg2, TEXT * arg3, TEXT * arg4, TEXT * arg5)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D D L _ e r r
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Issue an error message. Quit if >MAX_ERRORS
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
|
|
|
DDL_msg_partial(15, DDL_file_name, (TEXT *) DDL_line, 0, 0, 0); /*msg 15: %s:%d: */
|
|
|
|
DDL_msg_put(number, arg1, arg2, arg3, arg4, arg5);
|
|
|
|
if (DDL_errors++ > MAX_ERRORS) {
|
|
|
|
DDL_msg_put(16, (TEXT *) MAX_ERRORS, 0, 0, 0, 0); /* msg 16: error count exceeds limit (%d) */
|
|
|
|
DDL_msg_put(17, 0, 0, 0, 0, 0); /* msg 17: what we have here is a failure to communicate! */
|
|
|
|
if (database && (database->dbb_flags & DBB_create_database))
|
|
|
|
unlink(DB_file_name);
|
|
|
|
DDL_exit(FINI_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DDL_error_abort(
|
|
|
|
STATUS * status_vector,
|
|
|
|
USHORT number,
|
|
|
|
TEXT * arg1,
|
|
|
|
TEXT * arg2, TEXT * arg3, TEXT * arg4, TEXT * arg5)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D D L _ e r r o r _ a b o r t
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Things are going very poorly, so put out an error message
|
|
|
|
* and give up.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
|
|
|
if (status_vector)
|
|
|
|
gds__print_status(status_vector);
|
|
|
|
|
|
|
|
DDL_err(number, arg1, arg2, arg3, arg4, arg5);
|
|
|
|
DDL_exit(FINI_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DDL_exit( int stat)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D D L _ e x i t
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Exit with status.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
|
|
|
LEX_fini();
|
|
|
|
exit(stat);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DDL_msg_partial(
|
|
|
|
USHORT number,
|
|
|
|
TEXT * arg1,
|
|
|
|
TEXT * arg2, TEXT * arg3, TEXT * arg4, TEXT * arg5)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D D L _ m s g _ p a r t i a l
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Retrieve a message from the error file, format it, and print it
|
|
|
|
* without a newline.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
|
|
|
gds__msg_format(0, DDL_MSG_FAC, number, sizeof(DDL_message), DDL_message,
|
|
|
|
arg1, arg2, arg3, arg4, arg5);
|
|
|
|
ib_printf("%s", DDL_message);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DDL_msg_put(
|
|
|
|
USHORT number,
|
|
|
|
TEXT * arg1,
|
|
|
|
TEXT * arg2, TEXT * arg3, TEXT * arg4, TEXT * arg5)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D D L _ m s g _ p u t
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Retrieve a message from the error file, format it, and print it.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
|
|
|
gds__msg_format(0, DDL_MSG_FAC, number, sizeof(DDL_message), DDL_message,
|
|
|
|
arg1, arg2, arg3, arg4, arg5);
|
|
|
|
ib_printf("%s\n", DDL_message);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NOD DDL_pop(LLS * pointer)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D D L _ p o p
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Pop an item off a linked list stack. Free the stack node.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
LLS stack;
|
|
|
|
NOD node;
|
|
|
|
|
|
|
|
stack = *pointer;
|
|
|
|
node = stack->lls_object;
|
|
|
|
*pointer = stack->lls_next;
|
|
|
|
stack->lls_next = free_stack;
|
|
|
|
free_stack = stack;
|
|
|
|
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DDL_push( NOD object, LLS * pointer)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D D L _ p u s h
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Push an arbitrary object onto a linked list stack.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
LLS stack;
|
|
|
|
|
|
|
|
if (free_stack) {
|
|
|
|
stack = free_stack;
|
|
|
|
free_stack = stack->lls_next;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
stack = (LLS) DDL_alloc(LLS_LEN);
|
|
|
|
|
|
|
|
stack->lls_object = object;
|
|
|
|
stack->lls_next = *pointer;
|
|
|
|
*pointer = stack;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int DDL_yes_no( USHORT number)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D D L _ y e s _ n o
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Ask a yes/no question.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
int c, d;
|
|
|
|
USHORT count, yes_num, no_num, re_num;
|
|
|
|
TEXT prompt[128], reprompt[128], yes_ans[128], no_ans[128];
|
|
|
|
|
|
|
|
gds__msg_format(0, DDL_MSG_FAC, number, sizeof(prompt), prompt, NULL,
|
|
|
|
NULL, NULL, NULL, NULL);
|
|
|
|
|
|
|
|
yes_num = 342; /* Msg342 YES */
|
|
|
|
no_num = 343; /* Msg343 NO */
|
|
|
|
re_num = 344; /* Msg344 Please respond with YES or NO. */
|
|
|
|
reprompt[0] = '\0';
|
|
|
|
|
|
|
|
if (gds__msg_format
|
|
|
|
(0, DDL_MSG_FAC, no_num, sizeof(no_ans), no_ans, NULL, NULL, NULL,
|
|
|
|
NULL, NULL) <= 0)
|
|
|
|
strcpy(no_ans, "NO"); /* default if msg_format fails */
|
|
|
|
if (gds__msg_format
|
|
|
|
(0, DDL_MSG_FAC, yes_num, sizeof(yes_ans), yes_ans, NULL, NULL, NULL,
|
|
|
|
NULL, NULL) <= 0)
|
|
|
|
strcpy(yes_ans, "YES");
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
ib_printf(prompt);
|
|
|
|
if (DDL_service)
|
|
|
|
ib_putc('\001', ib_stdout);
|
|
|
|
ib_fflush(ib_stdout);
|
|
|
|
count = 0;
|
|
|
|
while ((c = ib_getc(ib_stdin)) == ' ')
|
|
|
|
count++;
|
|
|
|
if (c != '\n' && c != EOF)
|
|
|
|
while ((d = ib_getc(ib_stdin)) != '\n' && d != EOF);
|
|
|
|
if (!count && c == EOF)
|
|
|
|
return FALSE;
|
|
|
|
if (UPPER(c) == UPPER(yes_ans[0]))
|
|
|
|
return TRUE;
|
|
|
|
if (UPPER(c) == UPPER(no_ans[0]))
|
|
|
|
return FALSE;
|
|
|
|
if (!reprompt
|
|
|
|
&& gds__msg_format(0, DDL_MSG_FAC, re_num, sizeof(reprompt),
|
|
|
|
reprompt, NULL, NULL, NULL, NULL, NULL) <= 0)
|
|
|
|
sprintf(reprompt, "Please respond with YES or NO."); /* default if msg_format fails */
|
|
|
|
ib_printf("%s\n", reprompt);
|
|
|
|
}
|
|
|
|
}
|