2001-05-23 15:26:42 +02:00
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// PROGRAM: General preprocessor
|
|
|
|
// MODULE: ftn.cpp
|
|
|
|
// DESCRIPTION: Fortran text 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): ______________________________________.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
2004-06-05 11:37:18 +02:00
|
|
|
// $Id: ftn.cpp,v 1.49 2004-06-05 09:36:56 robocop Exp $
|
2002-10-29 03:45:09 +01:00
|
|
|
//
|
|
|
|
// 2002.10.28 Sean Leyne - Completed removal of obsolete "DGUX" port
|
2002-10-29 04:31:20 +01:00
|
|
|
// 2002.10.28 Sean Leyne - Completed removal of obsolete "SGI" port
|
2002-10-29 03:45:09 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
//
|
|
|
|
|
2001-07-30 01:43:24 +02:00
|
|
|
#include "firebird.h"
|
2004-04-29 00:36:29 +02:00
|
|
|
#include <stdio.h>
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../jrd/common.h"
|
|
|
|
#include <stdarg.h>
|
2003-11-08 17:40:17 +01:00
|
|
|
#include "../jrd/ibase.h"
|
2003-09-28 23:36:05 +02:00
|
|
|
#include "../jrd/gds_proto.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../gpre/gpre.h"
|
|
|
|
#include "../gpre/pat.h"
|
|
|
|
#include "../gpre/cmp_proto.h"
|
|
|
|
#include "../gpre/gpre_proto.h"
|
|
|
|
#include "../gpre/lang_proto.h"
|
|
|
|
#include "../gpre/pat_proto.h"
|
|
|
|
#include "../gpre/prett_proto.h"
|
|
|
|
#include "../jrd/isc_proto.h"
|
2003-10-15 00:22:32 +02:00
|
|
|
#include "../gpre/msc_proto.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-07-12 07:46:06 +02:00
|
|
|
#ifdef HAVE_STRING_H
|
|
|
|
#include <string.h>
|
|
|
|
#endif
|
|
|
|
|
2003-02-12 13:51:07 +01:00
|
|
|
#ifdef NOT_USED_OR_REPLACED
|
2002-07-06 07:32:02 +02:00
|
|
|
static void align (int column);
|
|
|
|
#endif
|
2003-10-06 11:48:44 +02:00
|
|
|
static void asgn_from (const act*, const ref*);
|
|
|
|
static void asgn_to (const act*, const ref*);
|
|
|
|
static void asgn_to_proc (const ref*);
|
|
|
|
static void gen_any (const act*);
|
|
|
|
static void gen_at_end (const act*);
|
|
|
|
static void gen_based (const act*);
|
|
|
|
static void gen_blob_close (const act*);
|
|
|
|
static void gen_blob_end (const act*);
|
|
|
|
static void gen_blob_for (const act*);
|
|
|
|
static void gen_blob_open (const act*);
|
2003-09-29 14:43:14 +02:00
|
|
|
static void gen_blr (void*, SSHORT, const char*);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_clear_handles(const act*);
|
2003-08-09 20:00:14 +02:00
|
|
|
#ifdef NOT_USED_OR_REPLACED
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_compatibility_symbol(const TEXT*, const TEXT*, const TEXT*);
|
2003-08-09 20:00:14 +02:00
|
|
|
#endif
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_compile (const act*);
|
|
|
|
static void gen_create_database (const act*);
|
|
|
|
static void gen_cursor_close (const act*, const gpre_req*);
|
|
|
|
static void gen_cursor_init (const act*);
|
|
|
|
static void gen_cursor_open (const act*, const gpre_req*);
|
|
|
|
static void gen_database (const act*);
|
|
|
|
static void gen_database_data (const act*);
|
|
|
|
static void gen_database_decls (const act*);
|
|
|
|
static void gen_ddl (const act*);
|
|
|
|
static void gen_drop_database (const act*);
|
|
|
|
static void gen_dyn_close (const act*);
|
|
|
|
static void gen_dyn_declare (const act*);
|
|
|
|
static void gen_dyn_describe(const act*, bool);
|
|
|
|
static void gen_dyn_execute (const act*);
|
|
|
|
static void gen_dyn_fetch (const act*);
|
|
|
|
static void gen_dyn_immediate (const act*);
|
|
|
|
static void gen_dyn_insert (const act*);
|
|
|
|
static void gen_dyn_open (const act*);
|
|
|
|
static void gen_dyn_prepare (const act*);
|
|
|
|
static void gen_emodify (const act*);
|
|
|
|
static void gen_estore (const act*);
|
2002-07-06 07:32:02 +02:00
|
|
|
static void gen_end_fetch (void);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_endfor (const act*);
|
|
|
|
static void gen_erase (const act*);
|
|
|
|
static SSHORT gen_event_block (const act*);
|
|
|
|
static void gen_event_init (const act*);
|
|
|
|
static void gen_event_wait (const act*);
|
|
|
|
static void gen_fetch (const act*);
|
|
|
|
static void gen_finish (const act*);
|
|
|
|
static void gen_for (const act*);
|
|
|
|
static void gen_function(const act*);
|
|
|
|
static void gen_get_or_put_slice(const act*, const ref*, bool);
|
|
|
|
static void gen_get_segment (const act*);
|
|
|
|
static void gen_loop (const act*);
|
|
|
|
static TEXT* gen_name (SCHAR*, const ref*, bool);
|
|
|
|
static void gen_on_error (const act*);
|
|
|
|
static void gen_procedure (const act*);
|
|
|
|
static void gen_put_segment (const act*);
|
2002-07-06 07:32:02 +02:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* RRK_?: the following prototype is differnet from C stuff */
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_raw(const UCHAR*, enum req_t, int, int, int);
|
2002-07-06 07:32:02 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_ready (const act*);
|
2004-01-28 08:50:41 +01:00
|
|
|
static void gen_receive (const act*, const gpre_port*);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_release (const act*);
|
2003-08-09 20:00:14 +02:00
|
|
|
#ifdef NOT_USED_OR_REPLACED
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_request (const gpre_req*);
|
2003-08-09 20:00:14 +02:00
|
|
|
#endif
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_request_data (const gpre_req*);
|
|
|
|
static void gen_request_decls (const gpre_req*);
|
|
|
|
static void gen_return_value (const act*);
|
|
|
|
static void gen_routine (const act*);
|
|
|
|
static void gen_s_end (const act*);
|
|
|
|
static void gen_s_fetch (const act*);
|
|
|
|
static void gen_s_start (const act*);
|
|
|
|
static void gen_segment (const act*);
|
|
|
|
static void gen_select (const act*);
|
2004-01-28 08:50:41 +01:00
|
|
|
static void gen_send (const act*, const gpre_port*);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_slice (const act*);
|
2004-01-28 08:50:41 +01:00
|
|
|
static void gen_start (const act*, const gpre_port*);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_store (const act*);
|
|
|
|
static void gen_t_start (const act*);
|
|
|
|
static void gen_tpb_data(const tpb*);
|
|
|
|
static void gen_tpb_decls(const tpb*);
|
|
|
|
static void gen_trans (const act*);
|
|
|
|
static void gen_type (const act*);
|
|
|
|
static void gen_update (const act*);
|
|
|
|
static void gen_variable (const act*);
|
|
|
|
static void gen_whenever (const swe*);
|
|
|
|
static void make_array_declaration (const ref*);
|
2004-01-28 08:50:41 +01:00
|
|
|
static TEXT* make_name (TEXT*, const gpre_sym*);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void make_ok_test (const act*, const gpre_req*);
|
2004-01-28 08:50:41 +01:00
|
|
|
static void make_port (const gpre_port*);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void make_ready (DBB, const TEXT*, const TEXT*, const gpre_req*);
|
2002-07-06 07:32:02 +02:00
|
|
|
static USHORT next_label (void);
|
2003-10-05 08:56:48 +02:00
|
|
|
static void printa(const TEXT*, const TEXT*, ...);
|
2003-08-09 20:00:14 +02:00
|
|
|
#ifdef NOT_USED_OR_REPLACED
|
2003-10-06 11:48:44 +02:00
|
|
|
static void printb(const TEXT*, ...);
|
2003-08-09 20:00:14 +02:00
|
|
|
#endif
|
2003-10-06 11:48:44 +02:00
|
|
|
static const TEXT* request_trans (const act*, const gpre_req*);
|
|
|
|
static void status_and_stop (const act*);
|
|
|
|
static const TEXT* status_vector (const act*);
|
|
|
|
static void t_start_auto (const gpre_req*, const TEXT*, const act*, bool);
|
2002-07-06 07:32:02 +02:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
static TEXT output_buffer[512];
|
2003-10-29 11:53:47 +01:00
|
|
|
static bool global_first_flag = false;
|
2004-01-28 08:50:41 +01:00
|
|
|
static adl* array_decl_list;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
#ifdef VMS
|
2003-10-16 10:51:06 +02:00
|
|
|
const char* const INCLUDE_ISC_FTN = " include 'interbase:[syslib]gds.for\' \n\n";
|
|
|
|
const char* const DOUBLE_DCL = "DOUBLE PRECISION";
|
|
|
|
const char* const I2CONST_1 = "%VAL(";
|
|
|
|
const char* const I2CONST_2 = ")";
|
|
|
|
const char* const I2_1 = "";
|
|
|
|
const char* const I2_2 = "";
|
|
|
|
const char* const VAL_1 = "%VAL(";
|
|
|
|
const char* const VAL_2 = ")";
|
|
|
|
const char* const REF_1 = "%REF(";
|
|
|
|
const char* const REF_2 = ")";
|
|
|
|
const char* const I4CONST_1 = "%VAL(";
|
|
|
|
const char* const I4CONST_2 = ")";
|
|
|
|
const char* const COMMENT = "C ";
|
|
|
|
const char* const INLINE_COMMENT = "!";
|
|
|
|
const char* const COMMA = ",";
|
2003-10-15 00:22:32 +02:00
|
|
|
#elif (defined AIX || defined AIX_PPC)
|
2003-10-16 10:51:06 +02:00
|
|
|
const char* const INCLUDE_ISC_FTN = " INCLUDE '%s\' \n\n";
|
|
|
|
const char* const INCLUDE_FTN_FILE = "include/gds.f";
|
|
|
|
const char* const DOUBLE_DCL = "DOUBLE PRECISION";
|
|
|
|
const char* const I2CONST_1 = "%VAL(";
|
|
|
|
const char* const I2CONST_2 = ")";
|
|
|
|
const char* const I2_1 = "";
|
|
|
|
const char* const I2_2 = "";
|
|
|
|
const char* const VAL_1 = "%VAL(";
|
|
|
|
const char* const VAL_2 = ")";
|
|
|
|
const char* const REF_1 = "%REF(";
|
|
|
|
const char* const REF_2 = ")";
|
|
|
|
const char* const I4CONST_1 = "%VAL(";
|
|
|
|
const char* const I4CONST_2 = ")";
|
|
|
|
const char* const COMMENT = "C ";
|
|
|
|
const char* const INLINE_COMMENT = "!";
|
|
|
|
const char* const COMMA = ",";
|
2003-10-15 00:22:32 +02:00
|
|
|
#elif defined(sun)
|
2003-10-16 10:51:06 +02:00
|
|
|
const char* const INCLUDE_ISC_FTN = " INCLUDE '%s\' \n\n";
|
|
|
|
const char* const INCLUDE_FTN_FILE = "include/gds.f";
|
|
|
|
const char* const DOUBLE_DCL = "DOUBLE PRECISION";
|
|
|
|
const char* const I2CONST_1 = "";
|
|
|
|
const char* const I2CONST_2 = "";
|
|
|
|
const char* const I2_1 = "";
|
|
|
|
const char* const I2_2 = "";
|
|
|
|
const char* const VAL_1 = "";
|
|
|
|
const char* const VAL_2 = "";
|
|
|
|
const char* const REF_1 = "";
|
|
|
|
const char* const REF_2 = "";
|
|
|
|
const char* const I4CONST_1 = "";
|
|
|
|
const char* const I4CONST_2 = "";
|
|
|
|
const char* const COMMENT = "* ";
|
|
|
|
const char* const INLINE_COMMENT = "\n* ";
|
|
|
|
const char* const COMMA = ",";
|
2003-10-15 00:22:32 +02:00
|
|
|
#elif defined(SINIXZ)
|
2003-10-31 09:30:04 +01:00
|
|
|
const char* const INCLUDE_ISC_FTN = " INCLUDE '/usr/interbase/include/gds.f\' \n\n";
|
2003-10-16 10:51:06 +02:00
|
|
|
const char* const INCLUDE_FTN_FILE = "include/gds.f";
|
|
|
|
const char* const DOUBLE_DCL = "DOUBLE PRECISION";
|
|
|
|
const char* const I2CONST_1 = "";
|
|
|
|
const char* const I2CONST_2 = "";
|
|
|
|
const char* const I2_1 = "";
|
|
|
|
const char* const I2_2 = "";
|
|
|
|
const char* const VAL_1 = "";
|
|
|
|
const char* const VAL_2 = "";
|
|
|
|
const char* const REF_1 = "";
|
|
|
|
const char* const REF_2 = "";
|
|
|
|
const char* const I4CONST_1 = "";
|
|
|
|
const char* const I4CONST_2 = "";
|
|
|
|
const char* const COMMENT = "* ";
|
|
|
|
const char* const INLINE_COMMENT = "\n* ";
|
|
|
|
const char* const COMMA = ",";
|
2003-10-15 00:22:32 +02:00
|
|
|
#elif defined(LINUX)
|
2003-10-16 10:51:06 +02:00
|
|
|
const char* const INCLUDE_ISC_FTN = " INCLUDE '/usr/interbase/include/gds.f\' \n\n";
|
|
|
|
const char* const INCLUDE_FTN_FILE = "include/gds.f";
|
|
|
|
const char* const DOUBLE_DCL = "DOUBLE PRECISION";
|
|
|
|
const char* const I2CONST_1 = "";
|
|
|
|
const char* const I2CONST_2 = "";
|
|
|
|
const char* const I2_1 = "";
|
|
|
|
const char* const I2_2 = "";
|
|
|
|
const char* const VAL_1 = "";
|
|
|
|
const char* const VAL_2 = "";
|
|
|
|
const char* const REF_1 = "";
|
|
|
|
const char* const REF_2 = "";
|
|
|
|
const char* const I4CONST_1 = "";
|
|
|
|
const char* const I4CONST_2 = "";
|
|
|
|
const char* const COMMENT = "* ";
|
|
|
|
const char* const INLINE_COMMENT = "\n* ";
|
|
|
|
const char* const COMMA = ",";
|
2003-10-15 00:22:32 +02:00
|
|
|
#elif defined(WIN_NT)
|
2003-10-16 10:51:06 +02:00
|
|
|
const char* const INCLUDE_ISC_FTN = " INCLUDE \'%s\' \n\n";
|
|
|
|
const char* const INCLUDE_FTN_FILE = "include/gds.f";
|
|
|
|
const char* const DOUBLE_DCL = "DOUBLE PRECISION";
|
|
|
|
const char* const I2CONST_1 = "";
|
|
|
|
const char* const I2CONST_2 = "";
|
|
|
|
const char* const I2_1 = "";
|
|
|
|
const char* const I2_2 = "";
|
|
|
|
const char* const VAL_1 = "";
|
|
|
|
const char* const VAL_2 = "";
|
|
|
|
const char* const REF_1 = "";
|
|
|
|
const char* const REF_2 = "";
|
|
|
|
const char* const I4CONST_1 = "";
|
|
|
|
const char* const I4CONST_2 = "";
|
|
|
|
const char* const COMMENT = "* ";
|
|
|
|
const char* const INLINE_COMMENT = "\n* ";
|
|
|
|
const char* const COMMA = ",";
|
2003-10-15 00:22:32 +02:00
|
|
|
#elif (defined FREEBSD || defined NETBSD)
|
2003-10-16 10:51:06 +02:00
|
|
|
const char* const INCLUDE_ISC_FTN = " INCLUDE '/usr/interbase/include/gds.f\' \n\n";
|
|
|
|
const char* const INCLUDE_FTN_FILE = "include/gds.f";
|
|
|
|
const char* const DOUBLE_DCL = "DOUBLE PRECISION";
|
|
|
|
const char* const I2CONST_1 = "";
|
|
|
|
const char* const I2CONST_2 = "";
|
|
|
|
const char* const I2_1 = "";
|
|
|
|
const char* const I2_2 = "";
|
|
|
|
const char* const VAL_1 = "";
|
|
|
|
const char* const VAL_2 = "";
|
|
|
|
const char* const REF_1 = "";
|
|
|
|
const char* const REF_2 = "";
|
|
|
|
const char* const I4CONST_1 = "";
|
|
|
|
const char* const I4CONST_2 = "";
|
|
|
|
const char* const COMMENT = "* ";
|
|
|
|
const char* const INLINE_COMMENT = "\n* ";
|
|
|
|
const char* const COMMA = ",";
|
2003-10-15 00:22:32 +02:00
|
|
|
#elif defined(DARWIN)
|
2003-10-16 10:51:06 +02:00
|
|
|
const char* const INCLUDE_ISC_FTN = " INCLUDE '/Library/Frameworks/Firebird.framework/Headers/gds.f\' \n\n";
|
|
|
|
const char* const INCLUDE_FTN_FILE = "Firebird/gds.f";
|
|
|
|
const char* const DOUBLE_DCL = "DOUBLE PRECISION";
|
|
|
|
const char* const I2CONST_1 = "";
|
|
|
|
const char* const I2CONST_2 = "";
|
|
|
|
const char* const I2_1 = "";
|
|
|
|
const char* const I2_2 = "";
|
|
|
|
const char* const VAL_1 = "";
|
|
|
|
const char* const VAL_2 = "";
|
|
|
|
const char* const REF_1 = "";
|
|
|
|
const char* const REF_2 = "";
|
|
|
|
const char* const I4CONST_1 = "";
|
|
|
|
const char* const I4CONST_2 = "";
|
|
|
|
const char* const COMMENT = "* ";
|
|
|
|
const char* const INLINE_COMMENT = "\n* ";
|
|
|
|
const char* const COMMA = ",";
|
2003-10-15 00:22:32 +02:00
|
|
|
#elif defined(hpux)
|
2003-10-16 10:51:06 +02:00
|
|
|
const char* const INCLUDE_ISC_FTN = " INCLUDE '%s\' \n\n";
|
|
|
|
const char* const INCLUDE_FTN_FILE = "include/gds.f";
|
|
|
|
const char* const DOUBLE_DCL = "DOUBLE PRECISION";
|
|
|
|
const char* const I2CONST_1 = "ISC_INT2(";
|
|
|
|
const char* const I2CONST_2 = ")";
|
|
|
|
const char* const I2_1 = "ISC_INT2(";
|
|
|
|
const char* const I2_2 = ")";
|
|
|
|
const char* const VAL_1 = "";
|
|
|
|
const char* const VAL_2 = "";
|
|
|
|
const char* const REF_1 = "";
|
|
|
|
const char* const REF_2 = "";
|
|
|
|
const char* const I4CONST_1 = "";
|
|
|
|
const char* const I4CONST_2 = "";
|
|
|
|
const char* const COMMENT = "* ";
|
|
|
|
const char* const INLINE_COMMENT = "!";
|
|
|
|
const char* const COMMA = ",";
|
2001-05-23 15:26:42 +02:00
|
|
|
#endif
|
|
|
|
|
2003-10-16 10:51:06 +02:00
|
|
|
const char* const COLUMN = " ";
|
|
|
|
const char* const INDENT = " ";
|
|
|
|
const char* const CONTINUE = " + ";
|
|
|
|
const char* const COLUMN_INDENT = " ";
|
|
|
|
|
|
|
|
const char* const ISC_EMBED_DSQL_CLOSE = "isc_embed_dsql_close";
|
|
|
|
const char* const ISC_EMBED_DSQL_DECLARE = "isc_embed_dsql_declare";
|
|
|
|
const char* const ISC_EMBED_DSQL_DESCRIBE = "isc_embed_dsql_describe";
|
|
|
|
const char* const ISC_EMBED_DSQL_DESCRIBE_BIND = "isc_embed_dsql_describe_bind";
|
|
|
|
const char* const ISC_EMBED_DSQL_EXECUTE = "isc_embed_dsql_execute";
|
|
|
|
const char* const ISC_EMBED_DSQL_EXECUTE2 = "isc_embed_dsql_execute2";
|
|
|
|
const char* const ISC_EMBED_DSQL_EXECUTE_IMMEDIATE = "isc_embed_dsql_execute_immed";
|
|
|
|
const char* const ISC_EMBED_DSQL_EXECUTE_IMMEDIATE2 = "isc_embed_dsql_execute_immed2";
|
|
|
|
const char* const ISC_EMBED_DSQL_FETCH = "isc_embed_dsql_fetch";
|
|
|
|
const char* const ISC_EMBED_DSQL_INSERT = "isc_embed_dsql_insert";
|
|
|
|
const char* const ISC_EMBED_DSQL_OPEN = "isc_embed_dsql_open";
|
|
|
|
const char* const ISC_EMBED_DSQL_OPEN2 = "isc_embed_dsql_open2";
|
|
|
|
const char* const ISC_EMBED_DSQL_PREPARE = "isc_embed_dsql_prepare";
|
|
|
|
const char* const ISC_DSQL_ALLOCATE = "isc_dsql_alloc_statement2";
|
|
|
|
const char* const ISC_DSQL_EXECUTE = "isc_dsql_execute_m";
|
|
|
|
const char* const ISC_DSQL_FREE = "isc_dsql_free_statement";
|
|
|
|
const char* const ISC_DSQL_SET_CURSOR = "isc_dsql_set_cursor_name";
|
|
|
|
|
|
|
|
const char* const ISC_EVENT_WAIT = "ISC_EVENT_WAIT";
|
|
|
|
const char* const ISC_EVENT_COUNTS = "ISC_EVENT_COUNTS";
|
|
|
|
|
|
|
|
const char* const DSQL_I2CONST_1 = I2CONST_1;
|
|
|
|
const char* const DSQL_I2CONST_2 = I2CONST_2;
|
2002-11-30 16:08:09 +01:00
|
|
|
|
2003-10-15 00:22:32 +02:00
|
|
|
#ifdef VMS
|
2003-10-16 10:51:06 +02:00
|
|
|
const char* const NULL_SQLDA = "%VAL(0)";
|
2003-10-15 00:22:32 +02:00
|
|
|
#else
|
2003-10-16 10:51:06 +02:00
|
|
|
const char* const NULL_SQLDA = "0";
|
2001-05-23 15:26:42 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
void FTN_action(const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
if (action->act_flags & ACT_break)
|
2003-10-29 11:53:47 +01:00
|
|
|
global_first_flag = false;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
switch (action->act_type) {
|
|
|
|
case ACT_alter_database:
|
|
|
|
case ACT_alter_domain:
|
|
|
|
case ACT_alter_table:
|
|
|
|
case ACT_alter_index:
|
|
|
|
case ACT_create_domain:
|
|
|
|
case ACT_create_generator:
|
|
|
|
case ACT_create_index:
|
|
|
|
case ACT_create_shadow:
|
|
|
|
case ACT_create_table:
|
|
|
|
case ACT_create_view:
|
|
|
|
case ACT_declare_filter:
|
|
|
|
case ACT_declare_udf:
|
|
|
|
case ACT_drop_domain:
|
|
|
|
case ACT_drop_filter:
|
|
|
|
case ACT_drop_index:
|
|
|
|
case ACT_drop_shadow:
|
|
|
|
case ACT_drop_table:
|
|
|
|
case ACT_drop_udf:
|
|
|
|
case ACT_statistics:
|
|
|
|
case ACT_drop_view:
|
|
|
|
gen_ddl(action);
|
|
|
|
break;
|
|
|
|
case ACT_any:
|
|
|
|
gen_any(action);
|
|
|
|
return;
|
|
|
|
case ACT_at_end:
|
|
|
|
gen_at_end(action);
|
|
|
|
return;
|
|
|
|
case ACT_commit:
|
|
|
|
gen_trans(action);
|
|
|
|
break;
|
|
|
|
case ACT_commit_retain_context:
|
|
|
|
gen_trans(action);
|
|
|
|
break;
|
|
|
|
case ACT_basedon:
|
|
|
|
gen_based(action);
|
|
|
|
return;
|
|
|
|
case ACT_b_declare:
|
|
|
|
gen_database(action);
|
|
|
|
return;
|
|
|
|
case ACT_blob_cancel:
|
|
|
|
gen_blob_close(action);
|
|
|
|
return;
|
|
|
|
case ACT_blob_close:
|
|
|
|
gen_blob_close(action);
|
|
|
|
break;
|
|
|
|
case ACT_blob_create:
|
|
|
|
gen_blob_open(action);
|
|
|
|
break;
|
|
|
|
case ACT_blob_for:
|
|
|
|
gen_blob_for(action);
|
|
|
|
return;
|
|
|
|
case ACT_blob_handle:
|
|
|
|
gen_segment(action);
|
|
|
|
return;
|
|
|
|
case ACT_blob_open:
|
|
|
|
gen_blob_open(action);
|
|
|
|
break;
|
|
|
|
case ACT_clear_handles:
|
|
|
|
gen_clear_handles(action);
|
|
|
|
break;
|
|
|
|
case ACT_create_database:
|
|
|
|
gen_create_database(action);
|
|
|
|
break;
|
|
|
|
case ACT_cursor:
|
|
|
|
gen_cursor_init(action);
|
|
|
|
return;
|
|
|
|
case ACT_database:
|
|
|
|
gen_database(action);
|
|
|
|
return;
|
|
|
|
case ACT_disconnect:
|
|
|
|
gen_finish(action);
|
|
|
|
break;
|
|
|
|
case ACT_drop_database:
|
|
|
|
gen_drop_database(action);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_close:
|
|
|
|
gen_dyn_close(action);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_cursor:
|
|
|
|
gen_dyn_declare(action);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_describe:
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_dyn_describe(action, false);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
case ACT_dyn_describe_input:
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_dyn_describe(action, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
case ACT_dyn_execute:
|
|
|
|
gen_dyn_execute(action);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_fetch:
|
|
|
|
gen_dyn_fetch(action);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_grant:
|
|
|
|
gen_ddl(action);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_immediate:
|
|
|
|
gen_dyn_immediate(action);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_insert:
|
|
|
|
gen_dyn_insert(action);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_open:
|
|
|
|
gen_dyn_open(action);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_prepare:
|
|
|
|
gen_dyn_prepare(action);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_revoke:
|
|
|
|
gen_ddl(action);
|
|
|
|
break;
|
|
|
|
case ACT_close:
|
|
|
|
gen_s_end(action);
|
|
|
|
break;
|
|
|
|
case ACT_endblob:
|
|
|
|
gen_blob_end(action);
|
|
|
|
return;
|
|
|
|
case ACT_enderror:
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
return;
|
|
|
|
case ACT_endfor:
|
|
|
|
gen_endfor(action);
|
|
|
|
break;
|
|
|
|
case ACT_endmodify:
|
|
|
|
gen_emodify(action);
|
|
|
|
break;
|
|
|
|
case ACT_endstore:
|
|
|
|
gen_estore(action);
|
|
|
|
break;
|
|
|
|
case ACT_erase:
|
|
|
|
gen_erase(action);
|
|
|
|
return;
|
|
|
|
case ACT_event_init:
|
|
|
|
gen_event_init(action);
|
|
|
|
break;
|
|
|
|
case ACT_event_wait:
|
|
|
|
gen_event_wait(action);
|
|
|
|
break;
|
|
|
|
case ACT_fetch:
|
|
|
|
gen_fetch(action);
|
|
|
|
break;
|
|
|
|
case ACT_finish:
|
|
|
|
gen_finish(action);
|
|
|
|
break;
|
|
|
|
case ACT_for:
|
|
|
|
gen_for(action);
|
|
|
|
return;
|
|
|
|
case ACT_function:
|
|
|
|
gen_function(action);
|
|
|
|
return;
|
|
|
|
case ACT_get_segment:
|
|
|
|
gen_get_segment(action);
|
|
|
|
break;
|
|
|
|
case ACT_get_slice:
|
|
|
|
gen_slice(action);
|
|
|
|
break;
|
|
|
|
case ACT_hctef:
|
|
|
|
gen_end_fetch();
|
|
|
|
return;
|
|
|
|
case ACT_insert:
|
|
|
|
gen_s_start(action);
|
|
|
|
break;
|
|
|
|
case ACT_loop:
|
|
|
|
gen_loop(action);
|
|
|
|
break;
|
|
|
|
case ACT_open:
|
|
|
|
gen_s_start(action);
|
|
|
|
break;
|
|
|
|
case ACT_on_error:
|
|
|
|
gen_on_error(action);
|
|
|
|
return;
|
|
|
|
case ACT_procedure:
|
|
|
|
gen_procedure(action);
|
|
|
|
return;
|
|
|
|
case ACT_put_segment:
|
|
|
|
gen_put_segment(action);
|
|
|
|
break;
|
|
|
|
case ACT_put_slice:
|
|
|
|
gen_slice(action);
|
|
|
|
break;
|
|
|
|
case ACT_ready:
|
|
|
|
gen_ready(action);
|
|
|
|
return;
|
|
|
|
case ACT_release:
|
|
|
|
gen_release(action);
|
|
|
|
break;
|
|
|
|
case ACT_rfinish:
|
|
|
|
gen_finish(action);
|
|
|
|
return;
|
|
|
|
case ACT_prepare:
|
|
|
|
gen_trans(action);
|
|
|
|
break;
|
|
|
|
case ACT_rollback:
|
|
|
|
gen_trans(action);
|
|
|
|
break;
|
|
|
|
case ACT_routine:
|
|
|
|
gen_routine(action);
|
|
|
|
return;
|
|
|
|
case ACT_s_end:
|
|
|
|
gen_s_end(action);
|
|
|
|
return;
|
|
|
|
case ACT_s_fetch:
|
|
|
|
gen_s_fetch(action);
|
|
|
|
break;
|
|
|
|
case ACT_s_start:
|
|
|
|
gen_s_start(action);
|
|
|
|
break;
|
|
|
|
case ACT_select:
|
|
|
|
gen_select(action);
|
|
|
|
break;
|
|
|
|
case ACT_segment_length:
|
|
|
|
gen_segment(action);
|
|
|
|
return;
|
|
|
|
case ACT_segment:
|
|
|
|
gen_segment(action);
|
|
|
|
return;
|
|
|
|
case ACT_sql_dialect:
|
2004-05-24 19:13:38 +02:00
|
|
|
gpreGlob.sw_sql_dialect = ((SDT) action->act_object)->sdt_dialect;
|
2001-05-23 15:26:42 +02:00
|
|
|
return;
|
|
|
|
case ACT_start:
|
|
|
|
gen_t_start(action);
|
|
|
|
break;
|
|
|
|
case ACT_store:
|
|
|
|
gen_store(action);
|
|
|
|
break;
|
|
|
|
case ACT_store2:
|
|
|
|
gen_return_value(action);
|
|
|
|
break;
|
2003-10-06 11:48:44 +02:00
|
|
|
case ACT_type_number:
|
2001-05-23 15:26:42 +02:00
|
|
|
gen_type(action);
|
|
|
|
return;
|
|
|
|
case ACT_update:
|
|
|
|
gen_update(action);
|
|
|
|
break;
|
|
|
|
case ACT_variable:
|
|
|
|
gen_variable(action);
|
|
|
|
return;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (action->act_flags & ACT_sql)
|
|
|
|
gen_whenever(action->act_whenever);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Create a block data module at the
|
|
|
|
// head of a preprocessed fortran file
|
|
|
|
// containing the initializations for
|
|
|
|
// all databases not declared as extern
|
|
|
|
//
|
|
|
|
|
|
|
|
void FTN_fini(void)
|
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
if (!gpreGlob.global_db_count)
|
2001-05-23 15:26:42 +02:00
|
|
|
return;
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "\n");
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "BLOCK DATA");
|
2003-10-06 11:48:44 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
const dbd* db_list = gpreGlob.global_db_list;
|
|
|
|
for (const dbd* const end = gpreGlob.global_db_list + gpreGlob.global_db_count;
|
2003-10-06 11:48:44 +02:00
|
|
|
db_list < end; ++db_list)
|
|
|
|
{
|
|
|
|
const TEXT* name = db_list->dbb_name;
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 %s %s{ database handle }\n",
|
|
|
|
COLUMN, name, INLINE_COMMENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%sCOMMON /%s/ %s\n", COLUMN, name, name);
|
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sDATA %s /0/ %s{ init database handle }\n",
|
|
|
|
COLUMN, name, INLINE_COMMENT);
|
|
|
|
}
|
|
|
|
printa(COLUMN, "END");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Print a statment, breaking it into
|
|
|
|
// reasonable 72 character hunks.
|
|
|
|
//
|
|
|
|
|
2004-05-13 11:46:01 +02:00
|
|
|
void FTN_print_buffer( TEXT* output_bufferL)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
TEXT s[73];
|
|
|
|
TEXT* p = s;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-13 11:46:01 +02:00
|
|
|
for (const TEXT* q = output_bufferL; *q; q++) {
|
2001-05-23 15:26:42 +02:00
|
|
|
*p++ = *q;
|
|
|
|
#ifdef sun
|
|
|
|
if (q[0] == '\n' && q[1] == '\0') {
|
|
|
|
*p = 0;
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s", s);
|
2001-05-23 15:26:42 +02:00
|
|
|
p = s;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if ((p - s) > 71) {
|
|
|
|
for (p--; (*p != ',') && (*p != ' '); p--) {
|
|
|
|
if ((p - s) < 10) {
|
|
|
|
p += 51;
|
|
|
|
q += 50;
|
|
|
|
*p-- = 0;
|
2003-10-06 11:48:44 +02:00
|
|
|
TEXT err[128];
|
2001-05-23 15:26:42 +02:00
|
|
|
sprintf(err, "Output line overflow: %s", s);
|
|
|
|
CPR_error(err);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
q--;
|
|
|
|
}
|
|
|
|
|
|
|
|
*++p = 0;
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s\n", s);
|
2001-05-23 15:26:42 +02:00
|
|
|
strcpy(s, CONTINUE);
|
|
|
|
for (p = s; *p; p++);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*p = 0;
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s", s);
|
2004-05-13 11:46:01 +02:00
|
|
|
output_bufferL[0] = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// RRK_?: copy align from c_cxx
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Build an assignment from a host language variable to
|
|
|
|
// a port variable.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void asgn_from(const act* action, const ref* reference)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
SCHAR name[64], variable[20], temp[20];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
for (; reference; reference = reference->ref_next) {
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_fld* field = reference->ref_field;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (field->fld_array_info)
|
|
|
|
if (!(reference->ref_flags & REF_array_elem)) {
|
|
|
|
printa(COLUMN, "CALL isc_qtoq (isc_blob_null, %s)",
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(name, reference, true));
|
|
|
|
gen_get_or_put_slice(action, reference, false);
|
2001-05-23 15:26:42 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!reference->ref_source && !reference->ref_value)
|
|
|
|
continue;
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(variable, reference, true);
|
2003-10-06 11:48:44 +02:00
|
|
|
|
2004-06-05 11:37:18 +02:00
|
|
|
const TEXT* value;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (reference->ref_source)
|
2003-09-10 21:48:53 +02:00
|
|
|
value = gen_name(temp, reference->ref_source, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
|
|
|
value = reference->ref_value;
|
|
|
|
if (reference->ref_value && (reference->ref_flags & REF_array_elem))
|
|
|
|
field = field->fld_array;
|
|
|
|
if (field->fld_dtype == dtype_blob ||
|
|
|
|
field->fld_dtype == dtype_quad || field->fld_dtype == dtype_date)
|
2003-10-06 11:48:44 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
sprintf(output_buffer, "%sCALL isc_qtoq (%s, %s)\n",
|
|
|
|
COLUMN, value, variable);
|
2003-10-06 11:48:44 +02:00
|
|
|
}
|
2003-10-05 08:56:48 +02:00
|
|
|
else if (!reference->ref_master || (reference->ref_flags & REF_literal))
|
|
|
|
{
|
|
|
|
sprintf(output_buffer, "%s%s = %s\n", COLUMN, variable, value);
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
else {
|
|
|
|
sprintf(output_buffer, "%sIF (%s .LT. 0) THEN\n", COLUMN, value);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
sprintf(output_buffer, "%s%s = -1\n", COLUMN_INDENT, variable);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
sprintf(output_buffer, "%sELSE\n", COLUMN);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
sprintf(output_buffer, "%s%s = 0\n", COLUMN_INDENT, variable);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
sprintf(output_buffer, "%sEND IF\n", COLUMN);
|
|
|
|
}
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Build an assignment to a host language variable from
|
|
|
|
// a port variable.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void asgn_to(const act* action, const ref* reference)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
ref* source = reference->ref_friend;
|
|
|
|
const gpre_fld* field = source->ref_field;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (field->fld_array_info) {
|
|
|
|
source->ref_value = reference->ref_value;
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_get_or_put_slice(action, source, true);
|
2002-07-06 07:32:02 +02:00
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
SCHAR s[128];
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, source, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (field->fld_dtype == dtype_blob ||
|
|
|
|
field->fld_dtype == dtype_quad || field->fld_dtype == dtype_date)
|
2003-10-06 11:48:44 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
sprintf(output_buffer, "%sCALL isc_qtoq (%s, %s)\n",
|
|
|
|
COLUMN, s, reference->ref_value);
|
2003-10-06 11:48:44 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
|
|
|
sprintf(output_buffer, "%s%s = %s\n",
|
|
|
|
COLUMN, reference->ref_value, s);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
|
|
|
|
// Pick up NULL value if one is there
|
|
|
|
|
|
|
|
if (reference = reference->ref_null) {
|
|
|
|
sprintf(output_buffer, "%s%s = %s\n",
|
2003-09-10 21:48:53 +02:00
|
|
|
COLUMN, reference->ref_value, gen_name(s, reference, true));
|
2001-05-23 15:26:42 +02:00
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Build an assignment to a host language variable from
|
|
|
|
// a port variable.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void asgn_to_proc( const ref* reference)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
SCHAR s[64];
|
|
|
|
|
|
|
|
for (; reference; reference = reference->ref_next) {
|
|
|
|
if (!reference->ref_value)
|
|
|
|
continue;
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_fld* field = reference->ref_field;
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, reference, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
if (field->fld_dtype == dtype_blob ||
|
|
|
|
field->fld_dtype == dtype_quad || field->fld_dtype == dtype_date)
|
2003-09-10 21:48:53 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
sprintf(output_buffer, "%sCALL isc_qtoq (%s, %s)\n",
|
|
|
|
COLUMN, s, reference->ref_value);
|
2003-09-10 21:48:53 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
|
|
|
sprintf(output_buffer, "%s%s = %s\n",
|
|
|
|
COLUMN, reference->ref_value, s);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate code for AT END clause of FETCH.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_at_end(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
SCHAR s[20];
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "IF (%s .EQ. 0) THEN",
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, request->req_eof, true));
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, COLUMN);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Substitute for a BASED ON <field name> clause.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_based(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
USHORT datatype;
|
2003-10-06 11:48:44 +02:00
|
|
|
SLONG length = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
bas* based_on = (bas*) action->act_object;
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_fld* field = based_on->bas_field;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (based_on->bas_flags & BAS_segment) {
|
|
|
|
datatype = dtype_text;
|
|
|
|
if (!(length = field->fld_seg_length))
|
|
|
|
length = 256;
|
|
|
|
}
|
|
|
|
else if (field->fld_array_info)
|
|
|
|
datatype = field->fld_array_info->ary_dtype;
|
|
|
|
else
|
|
|
|
datatype = field->fld_dtype;
|
|
|
|
|
|
|
|
switch (datatype) {
|
|
|
|
case dtype_short:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%sINTEGER*2%s", COLUMN, COLUMN);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_long:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%sINTEGER*4%s", COLUMN, COLUMN);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_date:
|
|
|
|
case dtype_blob:
|
|
|
|
case dtype_quad:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%sINTEGER*4%s", COLUMN, COLUMN);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_text:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%sCHARACTER*%ld%s", COLUMN,
|
2001-05-23 15:26:42 +02:00
|
|
|
(based_on->bas_flags & BAS_segment) ? length :
|
|
|
|
((field->fld_array_info) ? field->fld_array->
|
|
|
|
fld_length : field->fld_length), COLUMN);
|
|
|
|
break;
|
|
|
|
|
2003-10-15 00:22:32 +02:00
|
|
|
case dtype_real:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%sREAL%s", COLUMN, COLUMN);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_double:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s%s%s", COLUMN, DOUBLE_DCL, COLUMN);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2003-10-06 11:48:44 +02:00
|
|
|
{
|
|
|
|
TEXT s[64];
|
|
|
|
sprintf(s, "datatype %d unknown\n", field->fld_dtype);
|
|
|
|
CPR_error(s);
|
|
|
|
return;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// print the first variable, then precede the rest with commas
|
|
|
|
|
2003-09-25 13:49:12 +02:00
|
|
|
bool first = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
while (based_on->bas_variables) {
|
2003-10-15 03:18:01 +02:00
|
|
|
const TEXT* variable = (const TEXT*) MSC_pop(&based_on->bas_variables);
|
2003-09-25 13:49:12 +02:00
|
|
|
if (!first)
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ",\n%s", CONTINUE);
|
|
|
|
fprintf(gpreGlob.out_file, "%s", variable);
|
2003-09-25 13:49:12 +02:00
|
|
|
first = false;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (field->fld_array_info && !(based_on->bas_flags & BAS_segment)) {
|
2003-11-28 07:48:34 +01:00
|
|
|
// Print out the dimension part of the declaration
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "(");
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
for (dim* dimension = field->fld_array_info->ary_dimension; dimension;
|
2003-10-06 11:48:44 +02:00
|
|
|
dimension = dimension->dim_next)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
if (dimension->dim_lower != 1)
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%"SLONGFORMAT":", dimension->dim_lower);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%"SLONGFORMAT, dimension->dim_upper);
|
2001-05-23 15:26:42 +02:00
|
|
|
if (dimension->dim_next)
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ", ");
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (field->fld_dtype == dtype_quad ||
|
2003-10-06 11:48:44 +02:00
|
|
|
field->fld_dtype == dtype_date)
|
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ",2");
|
2003-10-06 11:48:44 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ")");
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
else if (field->fld_dtype == dtype_blob ||
|
|
|
|
field->fld_dtype == dtype_quad ||
|
2003-10-06 11:48:44 +02:00
|
|
|
field->fld_dtype == dtype_date)
|
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "(2)");
|
2003-10-06 11:48:44 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "\n");
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Make a blob FOR loop.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_blob_close(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-01-28 08:50:41 +01:00
|
|
|
blb* blob;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (action->act_flags & ACT_sql) {
|
|
|
|
gen_cursor_close(action, action->act_request);
|
2004-01-28 08:50:41 +01:00
|
|
|
blob = (blb*) action->act_request->req_blobs;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
else
|
2004-01-28 08:50:41 +01:00
|
|
|
blob = (blb*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-05 08:56:48 +02:00
|
|
|
const TEXT* command = (action->act_type == ACT_blob_cancel) ?
|
|
|
|
"CANCEL" : "CLOSE";
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "CALL ISC_%s_BLOB (%s, isc_%d)",
|
|
|
|
command, status_vector(action), blob->blb_ident);
|
|
|
|
|
|
|
|
if (action->act_flags & ACT_sql) {
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
}
|
|
|
|
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// End a blob FOR loop.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_blob_end(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-01-28 08:50:41 +01:00
|
|
|
blb* blob = (blb*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "%sGOTO %d", INDENT, blob->blb_top_label);
|
|
|
|
printa("", "%-6dCONTINUE", blob->blb_btm_label);
|
|
|
|
if (action->act_error)
|
|
|
|
printa(COLUMN, "CALL ISC_CANCEL_BLOB (ISC_STATUS2, isc_%d)",
|
|
|
|
blob->blb_ident);
|
|
|
|
else
|
|
|
|
printa(COLUMN, "CALL ISC_CANCEL_BLOB (%s, isc_%d)",
|
|
|
|
status_vector(0), blob->blb_ident);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Make a blob FOR loop.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_blob_for(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-01-28 08:50:41 +01:00
|
|
|
blb* blob = (blb*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
blob->blb_top_label = next_label();
|
|
|
|
blob->blb_btm_label = next_label();
|
|
|
|
gen_blob_open(action);
|
|
|
|
if (action->act_error)
|
|
|
|
printa(COLUMN, "IF (ISC_STATUS(2) .NE. 0) GOTO %d\n",
|
|
|
|
blob->blb_btm_label);
|
|
|
|
printa("", "%-6dCONTINUE", blob->blb_top_label);
|
|
|
|
gen_get_segment(action);
|
|
|
|
printa(COLUMN,
|
|
|
|
"IF (ISC_STATUS(2) .NE. 0 .AND. ISC_STATUS(2) .NE. ISC_SEGMENT) THEN");
|
|
|
|
printa(COLUMN, "%s GOTO %d", INDENT, blob->blb_btm_label);
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate the call to open (or create) a blob.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_blob_open(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
TEXT s[20];
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* pattern1 =
|
|
|
|
"CALL ISC_%IFCREATE%ELOPEN%EN_BLOB2 (%V1, %RF%DH%RE, %RF%RT%RE, %RF%BH%RE, %RF%FR%RE, %N1, %I1)\n";
|
|
|
|
const TEXT* pattern2 =
|
2001-05-23 15:26:42 +02:00
|
|
|
"CALL ISC_%IFCREATE%ELOPEN%EN_BLOB2 (%V1, %RF%DH%RE, %RF%RT%RE, %RF%BH%RE, %RF%FR%RE, 0, 0)\n";
|
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
blb* blob;
|
2003-10-06 11:48:44 +02:00
|
|
|
const ref* reference;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (action->act_flags & ACT_sql) {
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto) {
|
2001-05-23 15:26:42 +02:00
|
|
|
t_start_auto(action->act_request, status_vector(action), action,
|
2003-09-10 21:48:53 +02:00
|
|
|
true);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "if (%s .ne. 0) then",
|
|
|
|
request_trans(action, action->act_request));
|
|
|
|
}
|
|
|
|
|
|
|
|
gen_cursor_open(action, action->act_request);
|
2004-01-28 08:50:41 +01:00
|
|
|
blob = (blb*) action->act_request->req_blobs;
|
|
|
|
reference = ((open_cursor*) action->act_object)->opn_using;
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, reference, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
else {
|
2004-01-28 08:50:41 +01:00
|
|
|
blob = (blb*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
reference = blob->blb_reference;
|
|
|
|
}
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
PAT args;
|
2003-09-11 04:13:46 +02:00
|
|
|
args.pat_condition = (action->act_type == ACT_blob_create); // open or create blob
|
|
|
|
args.pat_vector1 = status_vector(action); // status vector
|
|
|
|
args.pat_database = blob->blb_request->req_database; // database handle
|
|
|
|
args.pat_request = blob->blb_request; // transaction handle
|
|
|
|
args.pat_blob = blob; // blob handle
|
|
|
|
args.pat_reference = reference; // blob identifier
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_ident1 = blob->blb_bpb_ident;
|
|
|
|
|
|
|
|
if ((action->act_flags & ACT_sql) && action->act_type == ACT_blob_open) {
|
|
|
|
printa(COLUMN, "CALL isc_qtoq (%s, %s)", reference->ref_value, s);
|
|
|
|
}
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const USHORT column = 6;
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
if (args.pat_value1 = blob->blb_bpb_length)
|
|
|
|
PATTERN_expand(column, pattern1, &args);
|
|
|
|
else
|
|
|
|
PATTERN_expand(column, pattern2, &args);
|
|
|
|
|
|
|
|
if (action->act_flags & ACT_sql) {
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
printa(COLUMN, "END IF");
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
status_and_stop(action);
|
|
|
|
if (action->act_type == ACT_blob_create) {
|
|
|
|
printa(COLUMN, "IF (SQLCODE .EQ. 0) THEN");
|
|
|
|
printa(COLUMN_INDENT, "CALL isc_qtoq (%s, %s)",
|
|
|
|
s, reference->ref_value);
|
|
|
|
printa(COLUMN, "ENDIF");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Callback routine for BLR pretty printer.
|
|
|
|
//
|
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
static void gen_blr(void* user_arg, SSHORT offset, const char* string)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const int c_len = strlen(COMMENT);
|
|
|
|
const int len = strlen(string);
|
|
|
|
int from = 0;
|
|
|
|
int to = 80 - c_len;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
while (from < len) {
|
|
|
|
if (to < len) {
|
2003-09-28 23:36:05 +02:00
|
|
|
char buffer[81];
|
2003-09-29 14:43:14 +02:00
|
|
|
strncpy(buffer, string + from, 80 - c_len);
|
|
|
|
buffer[80 - c_len] = 0;
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s%s\n", COMMENT, buffer);
|
2004-01-28 08:50:41 +01:00
|
|
|
}
|
|
|
|
else
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s%s\n", COMMENT, string + from);
|
2001-05-23 15:26:42 +02:00
|
|
|
from = to;
|
|
|
|
to = to + 80 - c_len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate text to compile a request.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_compile(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
|
|
|
DBB db = request->req_database;
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_sym* symbol = db->dbb_name;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
// generate automatic ready if appropriate
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
2003-09-10 21:48:53 +02:00
|
|
|
t_start_auto(request, status_vector(action), action, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
//
|
|
|
|
// always generate a compile, a test for the success of the compile,
|
|
|
|
// and an end to the 'if not compiled test
|
|
|
|
//
|
|
|
|
|
|
|
|
// generate an 'if not compiled'
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto && (action->act_error || (action->act_flags & ACT_sql)))
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "IF (%s .EQ. 0 .AND. %s .NE. 0) THEN",
|
|
|
|
request->req_handle, request_trans(action, request));
|
|
|
|
else
|
|
|
|
printa(COLUMN, "IF (%s .EQ. 0) THEN", request->req_handle);
|
|
|
|
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL ISC_COMPILE_REQUEST%s (%s, %s, %s, %s%d%s, %sisc_%d%s)\n",
|
|
|
|
COLUMN, (request->req_flags & REQ_exp_hand) ? "" : "2",
|
|
|
|
status_vector(action), symbol->sym_string, request->req_handle,
|
|
|
|
I2CONST_1, request->req_length, I2CONST_2, REF_1,
|
|
|
|
request->req_ident, REF_2);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
status_and_stop(action);
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
|
|
|
|
// If blobs are present, zero out all of the blob handles. After this
|
|
|
|
// point, the handles are the user's responsibility
|
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
blb* blob = request->req_blobs;
|
2003-10-06 11:48:44 +02:00
|
|
|
if (blob) {
|
2001-05-23 15:26:42 +02:00
|
|
|
for (; blob; blob = blob->blb_next) {
|
|
|
|
sprintf(output_buffer, "%sisc_%d = 0\n", COLUMN, blob->blb_ident);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a call to create a database.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_create_database(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
TEXT s1[32], s2[32];
|
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_req* request = ((mdbb*) action->act_object)->mdbb_dpb_request;
|
2003-10-06 11:48:44 +02:00
|
|
|
DBB db = (DBB) request->req_database;
|
2001-05-23 15:26:42 +02:00
|
|
|
sprintf(s1, "isc_%dl", request->req_ident);
|
|
|
|
|
|
|
|
if (request->req_flags & REQ_extend_dpb) {
|
|
|
|
sprintf(s2, "isc_%dp", request->req_ident);
|
|
|
|
if (request->req_length) {
|
|
|
|
sprintf(output_buffer, "%s%s = isc_%d\n",
|
|
|
|
COLUMN, s2, request->req_ident);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
if (db->dbb_r_user) {
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL ISC_MODIFY_DPB (%s, %s, isc_dpb_user_name, %s, %sLEN(%s)%s)\n",
|
|
|
|
COLUMN,
|
|
|
|
s2, s1, db->dbb_r_user,
|
|
|
|
I2CONST_1, db->dbb_r_user, I2CONST_2);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
if (db->dbb_r_password) {
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL ISC_MODIFY_DPB (%s, %s, isc_dpb_password, %s, %sLEN(%s)%s)\n",
|
|
|
|
COLUMN,
|
|
|
|
s2, s1, db->dbb_r_password,
|
|
|
|
I2CONST_1, db->dbb_r_password, I2CONST_2);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** =========================================================
|
|
|
|
** == SQL Role supports GPRE/Fortran
|
|
|
|
** =========================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (db->dbb_r_sql_role) {
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL ISC_MODIFY_DPB (%s, %s, isc_dpb_sql_role_name, %s, %sLEN(%s)%s)\n",
|
|
|
|
COLUMN,
|
|
|
|
s2, s1, db->dbb_r_sql_role,
|
|
|
|
I2CONST_1, db->dbb_r_sql_role, I2CONST_2);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (db->dbb_r_lc_messages) {
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL ISC_MODIFY_DPB (%s, %s, isc_dpb_lc_messages, %s, %sLEN(%s)%s)\n",
|
|
|
|
COLUMN,
|
|
|
|
s2, s1, db->dbb_r_lc_messages,
|
|
|
|
I2CONST_1, db->dbb_r_lc_messages, I2CONST_2);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
if (db->dbb_r_lc_ctype) {
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL ISC_MODIFY_DPB (%s, %s, isc_dpb_lc_type, %s, %sLEN(%s)%s)\n",
|
|
|
|
COLUMN,
|
|
|
|
s2, s1, db->dbb_r_lc_ctype,
|
|
|
|
I2CONST_1, db->dbb_r_lc_ctype, I2CONST_2);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
sprintf(s2, "isc_%d", request->req_ident);
|
|
|
|
|
|
|
|
if (request->req_length || request->req_flags & REQ_extend_dpb)
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL ISC_CREATE_DATABASE (%s, %s%d%s, %s'%s'%s, %s, %s%s%s, %s, 0)\n",
|
|
|
|
COLUMN,
|
|
|
|
status_vector(action),
|
|
|
|
I2CONST_1, strlen(db->dbb_filename), I2CONST_2,
|
|
|
|
REF_1, db->dbb_filename, REF_2,
|
|
|
|
db->dbb_name->sym_string, I2CONST_1, s1, I2CONST_2, s2);
|
|
|
|
else
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL ISC_CREATE_DATABASE (%s, %s%d%s, %s'%s'%s, %s, %s0%s, 0, 0)\n",
|
|
|
|
COLUMN,
|
|
|
|
status_vector(action),
|
|
|
|
I2CONST_1, strlen(db->dbb_filename), I2CONST_2,
|
|
|
|
REF_1, db->dbb_filename, REF_2,
|
|
|
|
db->dbb_name->sym_string, I2CONST_1, I2CONST_2);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
if (request && request->req_flags & REQ_extend_dpb) {
|
|
|
|
if (request->req_length) {
|
|
|
|
sprintf(output_buffer, "%sif (%s != isc_%d)\n", COLUMN, s2,
|
|
|
|
request->req_ident);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
sprintf(output_buffer, "%sCALL ISC_FREE (%s)\n", COLUMN, s2);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// reset the length of the dpb
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
sprintf(output_buffer, "%s%s = %d\n", COLUMN, s1,
|
|
|
|
request->req_length);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
2003-10-06 11:48:44 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
const bool save_sw_auto = gpreGlob.sw_auto;
|
|
|
|
gpreGlob.sw_auto = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "IF (isc_status(2) .eq. 0) THEN");
|
|
|
|
gen_ddl(action);
|
|
|
|
printa(COLUMN, "END IF");
|
2004-05-24 19:13:38 +02:00
|
|
|
gpreGlob.sw_auto = save_sw_auto;
|
2001-05-23 15:26:42 +02:00
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate substitution text for END_STREAM.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_cursor_close(const act* action, const gpre_req* request)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
printa(COLUMN, "IF (isc_%ds .NE. 0) THEN", request->req_ident);
|
|
|
|
printa(COLUMN, "CALL %s (%s, isc_%ds, %s1%s)",
|
|
|
|
ISC_DSQL_FREE,
|
|
|
|
status_vector(action),
|
|
|
|
request->req_ident, DSQL_I2CONST_1, DSQL_I2CONST_2);
|
|
|
|
printa(COLUMN, "IF (isc_status(2) .EQ. 0) THEN");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate text to initialize a cursor.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_cursor_init(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
// If blobs are present, zero out all of the blob handles. After this
|
|
|
|
// point, the handles are the user's responsibility
|
|
|
|
|
|
|
|
if (action->act_request->
|
2003-10-05 08:56:48 +02:00
|
|
|
req_flags & (REQ_sql_blob_open | REQ_sql_blob_create))
|
|
|
|
{
|
|
|
|
printa(COLUMN, "isc_%d = 0", action->act_request->req_blobs->blb_ident);
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate text to open an embedded SQL cursor.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_cursor_open(const act* action, const gpre_req* request)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
TEXT s[64];
|
|
|
|
|
|
|
|
if (action->act_type != ACT_open) {
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "IF (isc_%ds .EQ. 0 .AND. %s .NE. 0) THEN",
|
|
|
|
request->req_ident,
|
|
|
|
request->req_database->dbb_name->sym_string);
|
|
|
|
else
|
|
|
|
printa(COLUMN, "IF (isc_%ds .EQ. 0) THEN", request->req_ident);
|
|
|
|
}
|
|
|
|
else {
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN,
|
|
|
|
"IF (isc_%ds .EQ. 0 .AND. %s .NE. 0 .AND. %s .NE. 0) THEN",
|
|
|
|
request->req_ident, request->req_handle,
|
|
|
|
request->req_database->dbb_name->sym_string);
|
|
|
|
else
|
|
|
|
printa(COLUMN, "IF (isc_%ds .EQ. 0 .AND. %s .NE. 0) THEN",
|
|
|
|
request->req_ident, request->req_handle);
|
|
|
|
}
|
|
|
|
|
|
|
|
printa(COLUMN, "CALL %s (%s, %s, isc_%ds)",
|
|
|
|
ISC_DSQL_ALLOCATE,
|
|
|
|
status_vector(action),
|
|
|
|
request->req_database->dbb_name->sym_string, request->req_ident);
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "IF (isc_%ds .NE. 0 .AND. %s .NE. 0) THEN",
|
|
|
|
request->req_ident, request_trans(action, request));
|
|
|
|
else
|
|
|
|
printa(COLUMN, "IF (isc_%ds .NE. 0) THEN", request->req_ident);
|
|
|
|
printa(COLUMN, "CALL %s (%s, isc_%ds, %s, %s0%s)",
|
|
|
|
ISC_DSQL_SET_CURSOR,
|
|
|
|
status_vector(action),
|
|
|
|
request->req_ident,
|
2004-01-28 08:50:41 +01:00
|
|
|
make_name(s, ((open_cursor*) action->act_object)->opn_cursor),
|
2001-05-23 15:26:42 +02:00
|
|
|
DSQL_I2CONST_1, DSQL_I2CONST_2);
|
|
|
|
printa(COLUMN, "IF (isc_status(2) .EQ. 0) THEN");
|
|
|
|
printa(COLUMN, "CALL %s (%s, %s, isc_%ds, %s0%s, 0, %s-1%s, %s0%s, 0)",
|
|
|
|
ISC_DSQL_EXECUTE,
|
|
|
|
status_vector(action),
|
|
|
|
request_trans(action, request),
|
|
|
|
request->req_ident,
|
|
|
|
DSQL_I2CONST_1, DSQL_I2CONST_2,
|
|
|
|
DSQL_I2CONST_1, DSQL_I2CONST_2, DSQL_I2CONST_1, DSQL_I2CONST_2);
|
|
|
|
printa(COLUMN, "IF (isc_status(2) .EQ. 0) THEN");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate insertion text for the database statement.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_database(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-29 11:53:47 +01:00
|
|
|
if (global_first_flag)
|
2002-07-06 07:32:02 +02:00
|
|
|
return;
|
2003-10-29 11:53:47 +01:00
|
|
|
global_first_flag = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"\n%s **** GDS Preprocessor Definitions ****\n\n", COMMENT);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
|
|
|
|
gen_database_decls(action);
|
|
|
|
gen_database_data(action);
|
|
|
|
|
|
|
|
printa(COMMENT, "**** end of GPRE definitions ****\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate insertion text for global DATA statements.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_database_data(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-04-06 13:40:29 +02:00
|
|
|
TEXT include_buffer[MAXPATHLEN];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
ISC_prefix(include_buffer, INCLUDE_FTN_FILE);
|
|
|
|
sprintf(output_buffer, INCLUDE_ISC_FTN, include_buffer);
|
|
|
|
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
|
2003-09-10 21:48:53 +02:00
|
|
|
bool any_extern = false;
|
2004-05-24 19:13:38 +02:00
|
|
|
for (DBB db = gpreGlob.isc_databases; db; db = db->dbb_next) {
|
2001-05-23 15:26:42 +02:00
|
|
|
#ifndef FTN_BLK_DATA
|
|
|
|
if (db->dbb_scope != DBB_EXTERN)
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sDATA %s /0/ %s{ init database handle }\n",
|
|
|
|
COLUMN, db->dbb_name->sym_string, INLINE_COMMENT);
|
|
|
|
else
|
2003-09-10 21:48:53 +02:00
|
|
|
any_extern = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
#endif
|
2003-10-06 11:48:44 +02:00
|
|
|
for (const tpb* tpb_iterator = db->dbb_tpbs;
|
2003-09-05 12:14:08 +02:00
|
|
|
tpb_iterator;
|
|
|
|
tpb_iterator = tpb_iterator->tpb_dbb_next)
|
|
|
|
{
|
|
|
|
gen_tpb_data(tpb_iterator);
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sDATA ISC_NULL /0/ %s{ init null vector }\n",
|
|
|
|
COLUMN, INLINE_COMMENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sDATA ISC_BLOB_NULL /0,0/ %s{ init null blob }\n",
|
|
|
|
COLUMN, INLINE_COMMENT);
|
|
|
|
#ifndef FTN_BLK_DATA
|
|
|
|
if (!any_extern)
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sDATA GDS__TRANS /0/ %s{ init trans handle }\n",
|
|
|
|
COLUMN, INLINE_COMMENT);
|
|
|
|
#endif
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
for (const gpre_req* request = gpreGlob.requests; request; request = request->req_next)
|
2001-05-23 15:26:42 +02:00
|
|
|
gen_request_data(request);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate insertion text for global
|
|
|
|
// data declarations.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_database_decls(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 ISC_BLOB_NULL(2) %s{ null blob handle }\n",
|
|
|
|
COLUMN, INLINE_COMMENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 GDS__TRANS %s{ default transaction handle }\n",
|
|
|
|
COLUMN, INLINE_COMMENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 ISC_STATUS(20) %s{ status vector }\n", COLUMN,
|
|
|
|
INLINE_COMMENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 ISC_STATUS2(20) %s{ status vector }\n", COLUMN,
|
|
|
|
INLINE_COMMENT);
|
|
|
|
|
|
|
|
// added for 3.3 compatibility
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 GDS__STATUS(20) %s{ status vector }\n",
|
|
|
|
COLUMN, INLINE_COMMENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 GDS__STATUS2(20) %s{ status vector }\n",
|
|
|
|
COLUMN, INLINE_COMMENT);
|
|
|
|
|
|
|
|
printa(COLUMN, "EQUIVALENCE (ISC_STATUS(20), GDS__STATUS(20)) ");
|
|
|
|
printa(COLUMN, "EQUIVALENCE (ISC_STATUS2(20), GDS__STATUS2(20)) ");
|
|
|
|
// end of code added for 3.3 compatibility
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 ISC_NULL %s{ dummy status vector }\n",
|
|
|
|
COLUMN, INLINE_COMMENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 SQLCODE %s{ SQL status code }\n",
|
|
|
|
COLUMN, INLINE_COMMENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 ISC_SQLCODE %s{ SQL status code translator }\n",
|
|
|
|
COLUMN, INLINE_COMMENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 ISC_ARRAY_LENGTH %s{ array return size }\n",
|
|
|
|
COLUMN, INLINE_COMMENT);
|
|
|
|
|
2003-09-10 21:48:53 +02:00
|
|
|
bool all_static = true;
|
|
|
|
bool dcl_ndx_var = false;
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
SSHORT count = 0;
|
2004-05-24 19:13:38 +02:00
|
|
|
for (DBB db = gpreGlob.isc_databases; db; db = db->dbb_next) {
|
2001-05-23 15:26:42 +02:00
|
|
|
all_static = all_static && (db->dbb_scope == DBB_STATIC);
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* name = db->dbb_name->sym_string;
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 %s %s{ database handle }\n",
|
|
|
|
COLUMN, name, INLINE_COMMENT);
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sCHARACTER*256 ISC_%s %s{ database file name }\n",
|
|
|
|
COLUMN, name, INLINE_COMMENT);
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
for (const tpb* tpb_iterator = db->dbb_tpbs;
|
2003-09-05 12:14:08 +02:00
|
|
|
tpb_iterator;
|
|
|
|
tpb_iterator = tpb_iterator->tpb_dbb_next)
|
|
|
|
{
|
|
|
|
gen_tpb_decls(tpb_iterator);
|
2003-09-10 21:48:53 +02:00
|
|
|
dcl_ndx_var = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef hpux
|
2003-11-28 07:48:34 +01:00
|
|
|
// build fields to handle start_multiple
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
count++;
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 ISC_TEB%d_DBB %s( vector db handle )\n",
|
|
|
|
COLUMN, count, INLINE_COMMENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 ISC_TEB%d_LEN %s( vector tpb length )\n",
|
|
|
|
COLUMN, count, INLINE_COMMENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 ISC_TEB%d_TPB %s( vector tpb handle )\n",
|
|
|
|
COLUMN, count, INLINE_COMMENT);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
printa(COLUMN, "COMMON /%s/ %s", name, name);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef hpux
|
|
|
|
// declare array and set up equivalence for start_multiple vector
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const SSHORT length = 12;
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sCHARACTER ISC_TEB(%d) %s( transaction vector )\n",
|
|
|
|
COLUMN, length * count, INLINE_COMMENT);
|
2003-10-06 11:48:44 +02:00
|
|
|
for (SSHORT i = 0; i < count;) {
|
|
|
|
const SSHORT index = i++ * length + 1;
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "EQUIVALENCE (ISC_TEB(%d), ISC_TEB%d_DBB )",
|
|
|
|
index, i);
|
|
|
|
printa(COLUMN, "EQUIVALENCE (ISC_TEB(%d), ISC_TEB%d_LEN )",
|
|
|
|
index + 4, i);
|
|
|
|
printa(COLUMN, "EQUIVALENCE (ISC_TEB(%d) ,ISC_TEB%d_TPB )",
|
|
|
|
index + 8, i);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!all_static) {
|
|
|
|
printa(COLUMN, "COMMON /GDS__TRANS/GDS__TRANS");
|
|
|
|
printa(COLUMN, "COMMON /ISC_STATUS/ISC_STATUS");
|
|
|
|
printa(COLUMN, "COMMON /ISC_STATUS2/ISC_STATUS2");
|
|
|
|
printa(COLUMN, "COMMON /SQLCODE/SQLCODE");
|
|
|
|
}
|
|
|
|
array_decl_list = NULL;
|
2004-05-24 19:13:38 +02:00
|
|
|
for (const gpre_req* request = gpreGlob.requests; request; request = request->req_next) {
|
2001-05-23 15:26:42 +02:00
|
|
|
gen_request_decls(request);
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_port* port;
|
2001-05-23 15:26:42 +02:00
|
|
|
for (port = request->req_ports; port; port = port->por_next)
|
|
|
|
make_port(port);
|
2004-01-28 08:50:41 +01:00
|
|
|
for (blb* blob = request->req_blobs; blob; blob = blob->blb_next) {
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 isc_%d %s{ blob handle }\n",
|
|
|
|
COLUMN, blob->blb_ident, INLINE_COMMENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sCHARACTER*%d isc_%d %s{ blob segment }\n",
|
|
|
|
COLUMN, blob->blb_seg_length, blob->blb_buff_ident,
|
|
|
|
INLINE_COMMENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*2 isc_%d %s{ segment length }\n",
|
|
|
|
COLUMN, blob->blb_len_ident, INLINE_COMMENT);
|
|
|
|
}
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Array declarations
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (port = request->req_primary)
|
2003-10-06 11:48:44 +02:00
|
|
|
for (const ref* reference = port->por_references; reference;
|
2001-05-23 15:26:42 +02:00
|
|
|
reference = reference->ref_next)
|
2003-10-06 11:48:44 +02:00
|
|
|
{
|
|
|
|
if (reference->ref_field->fld_array_info)
|
|
|
|
make_array_declaration(reference);
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Declare DATA statement index variable
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (dcl_ndx_var || gpreGlob.requests)
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "INTEGER ISC_I");
|
|
|
|
|
|
|
|
// generate event parameter block for each event in module
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
SSHORT max_count = 0;
|
2004-05-24 19:13:38 +02:00
|
|
|
for (gpre_lls* stack_ptr = gpreGlob.events; stack_ptr; stack_ptr = stack_ptr->lls_next) {
|
2003-10-06 11:48:44 +02:00
|
|
|
count = gen_event_block((const act*) stack_ptr->lls_object);
|
2001-05-23 15:26:42 +02:00
|
|
|
max_count = MAX(count, max_count);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (max_count) {
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 ISC_EVENTS(%d) %s{ event vector }\n",
|
|
|
|
COLUMN, max_count, INLINE_COMMENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 ISC_EVENT_NAMES(%d) %s{ event buffer }\n",
|
|
|
|
COLUMN, max_count, INLINE_COMMENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sCHARACTER*31 ISC_EVENT_NAMES2(%d) %s{ event string buffer }\n",
|
|
|
|
COLUMN, max_count, INLINE_COMMENT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a call to update metadata.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_ddl(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto) {
|
2003-09-10 21:48:53 +02:00
|
|
|
t_start_auto(0, status_vector(action), action, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "if (gds__trans .ne. 0) then");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set up command type for call to RDB_DDL
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL isc_ddl (%s, %s, gds__trans, %s%d%s, isc_%d)\n", COLUMN,
|
|
|
|
status_vector(action),
|
|
|
|
request->req_database->dbb_name->sym_string, I2CONST_1,
|
|
|
|
request->req_length, I2CONST_2, request->req_ident);
|
|
|
|
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto) {
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
printa(COLUMN, "if (isc_status(2) .eq. 0)");
|
|
|
|
printa(CONTINUE, "CALL isc_commit_transaction (%s, gds__trans)",
|
|
|
|
status_vector(action));
|
|
|
|
printa(COLUMN, "if (isc_status(2) .ne. 0)");
|
|
|
|
printa(CONTINUE,
|
|
|
|
"CALL isc_rollback_transaction (isc_status2, gds__trans)");
|
|
|
|
}
|
|
|
|
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a call to create a database.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_drop_database(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
DBB db = (DBB) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%s CALL ISC_DROP_DATABASE (%s, %s%d%s, %s\'%s\'%s, RDB_K_DB_TYPE_GDS)\n",
|
|
|
|
COLUMN,
|
|
|
|
status_vector(action),
|
|
|
|
I2_1, strlen(db->dbb_filename), I2_2,
|
|
|
|
REF_1, db->dbb_filename, REF_2);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a dynamic SQL statement.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_dyn_close(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
TEXT s[64];
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const dyn* statement = (const dyn*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN,
|
|
|
|
"CALL %s (isc_status, %s)",
|
|
|
|
ISC_EMBED_DSQL_CLOSE, make_name(s, statement->dyn_cursor_name));
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a dynamic SQL statement.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_dyn_declare(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
TEXT s1[64], s2[64];
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const dyn* statement = (const dyn*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN,
|
|
|
|
"CALL %s (isc_status, %s, %s)",
|
|
|
|
ISC_EMBED_DSQL_DECLARE,
|
|
|
|
make_name(s1, statement->dyn_statement_name),
|
|
|
|
make_name(s2, statement->dyn_cursor_name));
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a dynamic SQL statement.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_dyn_describe(const act* action,
|
2003-09-10 21:48:53 +02:00
|
|
|
bool bind_flag)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
TEXT s[64];
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const dyn* statement = (const dyn*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN,
|
|
|
|
"CALL %s (isc_status, %s, %s%d%s, %s)",
|
|
|
|
bind_flag ? ISC_EMBED_DSQL_DESCRIBE_BIND : ISC_EMBED_DSQL_DESCRIBE,
|
|
|
|
make_name(s, statement->dyn_statement_name),
|
2004-05-24 19:13:38 +02:00
|
|
|
DSQL_I2CONST_1, gpreGlob.sw_sql_dialect, DSQL_I2CONST_2,
|
2001-05-23 15:26:42 +02:00
|
|
|
statement->dyn_sqlda);
|
|
|
|
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a dynamic SQL statement.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_dyn_execute(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* transaction;
|
2003-09-05 12:14:08 +02:00
|
|
|
gpre_req* request;
|
|
|
|
gpre_req req_const;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const dyn* statement = (const dyn*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (statement->dyn_trans) {
|
|
|
|
transaction = statement->dyn_trans;
|
|
|
|
request = &req_const;
|
|
|
|
request->req_trans = transaction;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
transaction = "gds__trans";
|
|
|
|
request = NULL;
|
|
|
|
}
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto) {
|
2003-09-10 21:48:53 +02:00
|
|
|
t_start_auto(request, status_vector(action), action, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "if (%s .ne. 0) then", transaction);
|
|
|
|
}
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* sqlda = statement->dyn_sqlda;
|
|
|
|
const TEXT* sqlda2 = statement->dyn_sqlda2;
|
2001-05-23 15:26:42 +02:00
|
|
|
#ifdef hpux
|
2003-10-06 11:48:44 +02:00
|
|
|
TEXT s2[64], s3[64];
|
2001-05-23 15:26:42 +02:00
|
|
|
if (sqlda) {
|
|
|
|
sprintf(s2, "isc_baddress (%s)", sqlda);
|
|
|
|
sqlda = s2;
|
|
|
|
}
|
|
|
|
if (sqlda2) {
|
|
|
|
sprintf(s3, "isc_baddress (%s)", sqlda2);
|
|
|
|
sqlda2 = s3;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
TEXT s1[64];
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN,
|
|
|
|
(sqlda2) ?
|
2003-10-05 08:56:48 +02:00
|
|
|
"CALL %s (isc_status, %s, %s, %s%d%s, %s, %s)" :
|
|
|
|
"CALL %s (isc_status, %s, %s, %s%d%s, %s)",
|
2001-05-23 15:26:42 +02:00
|
|
|
(sqlda2) ? ISC_EMBED_DSQL_EXECUTE2 : ISC_EMBED_DSQL_EXECUTE,
|
|
|
|
transaction,
|
|
|
|
make_name(s1, statement->dyn_statement_name),
|
2004-05-24 19:13:38 +02:00
|
|
|
DSQL_I2CONST_1, gpreGlob.sw_sql_dialect, DSQL_I2CONST_2,
|
2001-05-23 15:26:42 +02:00
|
|
|
(sqlda) ? sqlda : NULL_SQLDA, (sqlda2) ? sqlda2 : NULL_SQLDA);
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a dynamic SQL statement.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_dyn_fetch(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const dyn* statement = (const dyn*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* sqlda = statement->dyn_sqlda;
|
2001-05-23 15:26:42 +02:00
|
|
|
#ifdef hpux
|
2003-10-06 11:48:44 +02:00
|
|
|
TEXT s2[64];
|
2001-05-23 15:26:42 +02:00
|
|
|
if (sqlda) {
|
|
|
|
sprintf(s2, "isc_baddress (%s)", sqlda);
|
|
|
|
sqlda = s2;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
TEXT s1[64];
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN,
|
|
|
|
"SQLCODE = %s (isc_status, %s, %s%d%s, %s)",
|
|
|
|
ISC_EMBED_DSQL_FETCH,
|
|
|
|
make_name(s1, statement->dyn_cursor_name),
|
2004-05-24 19:13:38 +02:00
|
|
|
DSQL_I2CONST_1, gpreGlob.sw_sql_dialect, DSQL_I2CONST_2,
|
2001-05-23 15:26:42 +02:00
|
|
|
(sqlda) ? sqlda : NULL_SQLDA);
|
|
|
|
|
|
|
|
printa(COLUMN,
|
|
|
|
"IF (SQLCODE .NE. 100) SQLCODE = ISC_SQLCODE (isc_status)");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate code for an EXECUTE IMMEDIATE dynamic SQL statement.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_dyn_immediate(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* transaction;
|
2003-09-05 12:14:08 +02:00
|
|
|
gpre_req* request;
|
|
|
|
gpre_req req_const;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const dyn* statement = (const dyn*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (statement->dyn_trans) {
|
|
|
|
transaction = statement->dyn_trans;
|
|
|
|
request = &req_const;
|
|
|
|
request->req_trans = transaction;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
transaction = "gds__trans";
|
|
|
|
request = NULL;
|
|
|
|
}
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
DBB database = statement->dyn_database;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto) {
|
2003-09-10 21:48:53 +02:00
|
|
|
t_start_auto(request, status_vector(action), action, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "if (%s .ne. 0) then", transaction);
|
|
|
|
}
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* sqlda = statement->dyn_sqlda;
|
|
|
|
const TEXT* sqlda2 = statement->dyn_sqlda2;
|
2001-05-23 15:26:42 +02:00
|
|
|
#ifdef hpux
|
2003-10-06 11:48:44 +02:00
|
|
|
TEXT s2[64], s3[64];
|
2001-05-23 15:26:42 +02:00
|
|
|
if (sqlda) {
|
|
|
|
sprintf(s2, "isc_baddress (%s)", sqlda);
|
|
|
|
sqlda = s2;
|
|
|
|
}
|
|
|
|
if (sqlda2) {
|
|
|
|
sprintf(s3, "isc_baddress (%s)", sqlda2);
|
|
|
|
sqlda2 = s3;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
printa(COLUMN,
|
|
|
|
(sqlda2) ?
|
2003-10-05 08:56:48 +02:00
|
|
|
"CALL %s (isc_status, %s, %s, %sLEN(%s)%s, %s%s%s, %s%d%s, %s, %s)" :
|
|
|
|
"CALL %s (isc_status, %s, %s, %sLEN(%s)%s, %s%s%s, %s%d%s, %s)",
|
2001-05-23 15:26:42 +02:00
|
|
|
(sqlda2) ? ISC_EMBED_DSQL_EXECUTE_IMMEDIATE2 :
|
2003-10-05 08:56:48 +02:00
|
|
|
ISC_EMBED_DSQL_EXECUTE_IMMEDIATE,
|
|
|
|
transaction,
|
2001-05-23 15:26:42 +02:00
|
|
|
database->dbb_name->sym_string, DSQL_I2CONST_1,
|
|
|
|
statement->dyn_string, DSQL_I2CONST_2, REF_1,
|
2004-05-24 19:13:38 +02:00
|
|
|
statement->dyn_string, REF_2, DSQL_I2CONST_1, gpreGlob.sw_sql_dialect,
|
2001-05-23 15:26:42 +02:00
|
|
|
DSQL_I2CONST_2, (sqlda) ? sqlda : NULL_SQLDA,
|
|
|
|
(sqlda2) ? sqlda2 : NULL_SQLDA);
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a dynamic SQL statement.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_dyn_insert(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const dyn* statement = (const dyn*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* sqlda = statement->dyn_sqlda;
|
2001-05-23 15:26:42 +02:00
|
|
|
#ifdef hpux
|
2003-10-06 11:48:44 +02:00
|
|
|
TEXT s2[64];
|
2001-05-23 15:26:42 +02:00
|
|
|
if (sqlda) {
|
|
|
|
sprintf(s2, "isc_baddress (%s)", sqlda);
|
|
|
|
sqlda = s2;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
TEXT s1[64];
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN,
|
|
|
|
"%s (isc_status, %s, %s%d%s, %s)",
|
|
|
|
ISC_EMBED_DSQL_INSERT,
|
|
|
|
make_name(s1, statement->dyn_cursor_name),
|
2004-05-24 19:13:38 +02:00
|
|
|
DSQL_I2CONST_1, gpreGlob.sw_sql_dialect, DSQL_I2CONST_2,
|
2001-05-23 15:26:42 +02:00
|
|
|
(sqlda) ? sqlda : NULL_SQLDA);
|
|
|
|
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a dynamic SQL statement.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_dyn_open(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* transaction;
|
2003-09-05 12:14:08 +02:00
|
|
|
gpre_req* request;
|
|
|
|
gpre_req req_const;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const dyn* statement = (const dyn*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (statement->dyn_trans) {
|
|
|
|
transaction = statement->dyn_trans;
|
|
|
|
request = &req_const;
|
|
|
|
request->req_trans = transaction;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
transaction = "gds__trans";
|
|
|
|
request = NULL;
|
|
|
|
}
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto) {
|
2003-09-10 21:48:53 +02:00
|
|
|
t_start_auto(request, status_vector(action), action, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "if (%s .ne. 0) then", transaction);
|
|
|
|
}
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* sqlda = statement->dyn_sqlda;
|
|
|
|
const TEXT* sqlda2 = statement->dyn_sqlda2;
|
2001-05-23 15:26:42 +02:00
|
|
|
#ifdef hpux
|
2003-10-06 11:48:44 +02:00
|
|
|
TEXT s2[64], s3[64];
|
2001-05-23 15:26:42 +02:00
|
|
|
if (sqlda) {
|
|
|
|
sprintf(s2, "isc_baddress (%s)", sqlda);
|
|
|
|
sqlda = s2;
|
|
|
|
}
|
|
|
|
if (sqlda2) {
|
|
|
|
sprintf(s3, "isc_baddress (%s)", sqlda2);
|
|
|
|
sqlda2 = s3;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
TEXT s1[64];
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN,
|
|
|
|
(sqlda2) ?
|
2003-10-05 08:56:48 +02:00
|
|
|
"CALL %s (isc_status, %s, %s, %s%d%s, %s, %s)" :
|
|
|
|
"CALL %s (isc_status, %s, %s, %s%d%s, %s)",
|
2001-05-23 15:26:42 +02:00
|
|
|
(sqlda2) ? ISC_EMBED_DSQL_OPEN2 : ISC_EMBED_DSQL_OPEN,
|
|
|
|
transaction,
|
|
|
|
make_name(s1, statement->dyn_cursor_name),
|
2004-05-24 19:13:38 +02:00
|
|
|
DSQL_I2CONST_1, gpreGlob.sw_sql_dialect, DSQL_I2CONST_2,
|
2001-05-23 15:26:42 +02:00
|
|
|
(sqlda) ? sqlda : NULL_SQLDA, (sqlda2) ? sqlda2 : NULL_SQLDA);
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a dynamic SQL statement.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_dyn_prepare(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* transaction;
|
2003-09-05 12:14:08 +02:00
|
|
|
gpre_req* request;
|
|
|
|
gpre_req req_const;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const dyn* statement = (const dyn*) action->act_object;
|
|
|
|
DBB database = statement->dyn_database;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (statement->dyn_trans) {
|
|
|
|
transaction = statement->dyn_trans;
|
|
|
|
request = &req_const;
|
|
|
|
request->req_trans = transaction;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
transaction = "gds__trans";
|
|
|
|
request = NULL;
|
|
|
|
}
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto) {
|
2003-09-10 21:48:53 +02:00
|
|
|
t_start_auto(request, status_vector(action), action, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "if (%s .ne. 0) then", transaction);
|
|
|
|
}
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* sqlda = statement->dyn_sqlda;
|
2001-05-23 15:26:42 +02:00
|
|
|
#ifdef hpux
|
2003-10-06 11:48:44 +02:00
|
|
|
TEXT s2[64];
|
2001-05-23 15:26:42 +02:00
|
|
|
if (sqlda) {
|
|
|
|
sprintf(s2, "isc_baddress (%s)", sqlda);
|
|
|
|
sqlda = s2;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
TEXT s1[64];
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN,
|
|
|
|
"CALL %s (isc_status, %s, %s, %s, %sLEN(%s)%s, %s%s%s, %s%d%s, %s)",
|
|
|
|
ISC_EMBED_DSQL_PREPARE, database->dbb_name->sym_string,
|
|
|
|
transaction, make_name(s1, statement->dyn_statement_name),
|
|
|
|
DSQL_I2CONST_1, statement->dyn_string, DSQL_I2CONST_2, REF_1,
|
2004-05-24 19:13:38 +02:00
|
|
|
statement->dyn_string, REF_2, DSQL_I2CONST_1, gpreGlob.sw_sql_dialect,
|
2001-05-23 15:26:42 +02:00
|
|
|
DSQL_I2CONST_2, (sqlda) ? sqlda : NULL_SQLDA);
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate substitution text for END_MODIFY.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_emodify(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
SCHAR s1[20], s2[20];
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const upd* modify = (const upd*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
for (const ref* reference = modify->upd_port->por_references; reference;
|
|
|
|
reference = reference->ref_next)
|
|
|
|
{
|
|
|
|
const ref* source = reference->ref_source;
|
|
|
|
if (!source)
|
2001-05-23 15:26:42 +02:00
|
|
|
continue;
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_fld* field = reference->ref_field;
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s1, source, true);
|
|
|
|
gen_name(s2, reference, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
if (field->fld_dtype == dtype_blob ||
|
|
|
|
field->fld_dtype == dtype_quad || field->fld_dtype == dtype_date)
|
2003-09-10 21:48:53 +02:00
|
|
|
{
|
|
|
|
sprintf(output_buffer, "%sCALL isc_qtoq (%s, %s)\n", COLUMN, s1, s2);
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
|
|
|
sprintf(output_buffer, "%s%s = %s\n", COLUMN, s2, s1);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
if (field->fld_array_info)
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_get_or_put_slice(action, reference, false);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
gen_send(action, modify->upd_port);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate substitution text for END_STORE.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_estore(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
// if this is a store...returning_values (aka store2)
|
|
|
|
// we already executed the store, so go home quietly
|
|
|
|
|
|
|
|
if (request->req_type == REQ_store2)
|
2002-07-06 07:32:02 +02:00
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
gen_start(action, request->req_primary);
|
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate an END IF for the IF generated for
|
|
|
|
// the AT_END clause.
|
|
|
|
//
|
|
|
|
|
2002-07-06 07:32:02 +02:00
|
|
|
static void gen_end_fetch(void)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate definitions associated with a single request.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_endfor(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (request->req_sync)
|
|
|
|
gen_send(action, request->req_sync);
|
|
|
|
|
|
|
|
printa(COLUMN, "GOTO %d", request->req_top_label);
|
|
|
|
printa("", "%-6dCONTINUE", request->req_btm_label);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate substitution text for ERASE.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_erase(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const upd* erase = (const upd*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
gen_send(action, erase->upd_port);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate event parameter blocks for use
|
|
|
|
// with a particular call to isc_event_wait.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static SSHORT gen_event_block(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
GPRE_NOD init = (GPRE_NOD) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
int ident = CMP_next_ident();
|
2002-11-13 13:07:13 +01:00
|
|
|
init->nod_arg[2] = (GPRE_NOD) ident;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
printa(COLUMN, "INTEGER*4 isc_%dA", ident);
|
|
|
|
printa(COLUMN, "INTEGER*4 isc_%dB", ident);
|
|
|
|
printa(COLUMN, "INTEGER*2 isc_%dL", ident);
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
GPRE_NOD list = init->nod_arg[1];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
return list->nod_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate substitution text for EVENT_INIT.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_event_init(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
#if (!defined AIX && !defined AIX_PPC)
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* pattern1 =
|
2001-05-23 15:26:42 +02:00
|
|
|
"ISC_%N1L = ISC_EVENT_BLOCK_A (%RFISC_%N1A%RE, %RFISC_%N1B%RE, %VF%S3%N2%S4%VE, %RFISC_EVENT_NAMES%RE)";
|
|
|
|
#else
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* pattern1 =
|
2001-05-23 15:26:42 +02:00
|
|
|
"CALL ISC_EVENT_BLOCK_S (%RFISC_%N1A%RE, %RFISC_%N1B%RE, %VF%S3%N2%S4%VE, %RFISC_EVENT_NAMES%RE, %RFISC_%N1L%RE)";
|
|
|
|
#endif
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* pattern2 =
|
2001-05-23 15:26:42 +02:00
|
|
|
"CALL %S1 (%V1, %RF%DH%RE, %VFISC_%N1L%VE, %VFISC_%N1A%VE, %VFISC_%N1B%VE)";
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* pattern3 =
|
2001-05-23 15:26:42 +02:00
|
|
|
"CALL %S2 (ISC_EVENTS, %VFISC_%N1L%VE, %VFISC_%N1A%VE, %VFISC_%N1B%VE)";
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
GPRE_NOD init = (GPRE_NOD) action->act_object;
|
|
|
|
GPRE_NOD event_list = init->nod_arg[1];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
PAT args;
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_database = (DBB) init->nod_arg[3];
|
|
|
|
args.pat_vector1 = status_vector(action);
|
|
|
|
args.pat_value1 = (int) init->nod_arg[2];
|
|
|
|
args.pat_value2 = (int) event_list->nod_count;
|
2003-10-16 10:51:06 +02:00
|
|
|
args.pat_string1 = ISC_EVENT_WAIT;
|
|
|
|
args.pat_string2 = ISC_EVENT_COUNTS;
|
|
|
|
args.pat_string3 = I2_1;
|
|
|
|
args.pat_string4 = I2_2;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
// generate call to dynamically generate event blocks
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
TEXT variable[20];
|
|
|
|
SSHORT count = 0;
|
|
|
|
GPRE_NOD* ptr = event_list->nod_arg;
|
|
|
|
for (GPRE_NOD* end = ptr + event_list->nod_count; ptr < end; ptr++)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
count++;
|
2003-10-06 11:48:44 +02:00
|
|
|
GPRE_NOD node = *ptr;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (node->nod_type == nod_field) {
|
2003-10-06 11:48:44 +02:00
|
|
|
const ref* reference = (const ref*) node->nod_arg[0];
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(variable, reference, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "ISC_EVENT_NAMES2(%d) = %s", count, variable);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
printa(COLUMN, "ISC_EVENT_NAMES2(%d) = %s", count,
|
|
|
|
node->nod_arg[0]);
|
|
|
|
|
|
|
|
#if (!defined AIX && !defined AIX_PPC)
|
|
|
|
printa(COLUMN,
|
|
|
|
"ISC_EVENT_NAMES(%d) = ISC_BADDRESS (%sISC_EVENT_NAMES2(%d)%s)",
|
|
|
|
count, REF_1, count, REF_2);
|
|
|
|
#else
|
|
|
|
printa(COLUMN,
|
|
|
|
"CALL ISC_BADDRESS (%sISC_EVENT_NAMES2(%d)%s, ISC_EVENT_NAMES(%d))",
|
|
|
|
REF_1, count, REF_2, count);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const SSHORT column = 6;
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
PATTERN_expand(column, pattern1, &args);
|
|
|
|
|
|
|
|
// generate actual call to event_wait
|
|
|
|
|
|
|
|
PATTERN_expand(column, pattern2, &args);
|
|
|
|
|
|
|
|
// get change in event counts, copying event parameter block for reuse
|
|
|
|
|
|
|
|
PATTERN_expand(column, pattern3, &args);
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate substitution text for EVENT_WAIT.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_event_wait(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* pattern1 =
|
2001-05-23 15:26:42 +02:00
|
|
|
"CALL %S1 (%V1, %RF%DH%RE, %VFISC_%N1L%VE, %VFISC_%N1A%VE, %VFISC_%N1B%VE)";
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* pattern2 =
|
2001-05-23 15:26:42 +02:00
|
|
|
"CALL %S2 (ISC_EVENTS, %VFISC_%N1L%VE, %VFISC_%N1A%VE, %VFISC_%N1B%VE)";
|
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_sym* event_name = (const gpre_sym*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
// go through the stack of gpreGlob.events, checking to see if the
|
2001-05-23 15:26:42 +02:00
|
|
|
// event has been initialized and getting the event identifier
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
int ident = -1;
|
|
|
|
DBB database = NULL;
|
2004-05-24 19:13:38 +02:00
|
|
|
for (gpre_lls* stack_ptr = gpreGlob.events; stack_ptr; stack_ptr = stack_ptr->lls_next) {
|
2003-10-06 11:48:44 +02:00
|
|
|
const act* event_action = (const act*) stack_ptr->lls_object;
|
|
|
|
GPRE_NOD event_init = (GPRE_NOD) event_action->act_object;
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_sym* stack_name = (const gpre_sym*) event_init->nod_arg[0];
|
2001-05-23 15:26:42 +02:00
|
|
|
if (!strcmp(event_name->sym_string, stack_name->sym_string)) {
|
|
|
|
ident = (int) event_init->nod_arg[2];
|
|
|
|
database = (DBB) event_init->nod_arg[3];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ident < 0) {
|
2003-10-06 11:48:44 +02:00
|
|
|
TEXT s[64];
|
2001-05-23 15:26:42 +02:00
|
|
|
sprintf(s, "event handle \"%s\" not found", event_name->sym_string);
|
2003-10-15 00:22:32 +02:00
|
|
|
CPR_error(s);
|
2002-07-06 07:32:02 +02:00
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
PAT args;
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_database = database;
|
|
|
|
args.pat_vector1 = status_vector(action);
|
|
|
|
args.pat_value1 = (int) ident;
|
2003-10-16 10:51:06 +02:00
|
|
|
args.pat_string1 = ISC_EVENT_WAIT;
|
|
|
|
args.pat_string2 = ISC_EVENT_COUNTS;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
// generate calls to wait on the event and to fill out the gpreGlob.events array
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const SSHORT column = 6;
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
PATTERN_expand(column, pattern1, &args);
|
|
|
|
PATTERN_expand(column, pattern2, &args);
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate replacement text for the SQL FETCH statement. The
|
|
|
|
// epilog FETCH statement is handled by GEN_S_FETCH (generate
|
|
|
|
// stream fetch).
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_fetch(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
SCHAR s[20];
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (request->req_sync) {
|
|
|
|
gen_send(action, request->req_sync);
|
|
|
|
printa(COLUMN, "IF (SQLCODE .EQ. 0) THEN");
|
|
|
|
}
|
|
|
|
|
|
|
|
gen_receive(action, request->req_primary);
|
|
|
|
printa(COLUMN, "IF (%s .NE. 0) THEN",
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, request->req_eof, true));
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "SQLCODE = 0");
|
2003-10-06 11:48:44 +02:00
|
|
|
|
|
|
|
GPRE_NOD var_list = (GPRE_NOD) action->act_object;
|
|
|
|
if (var_list) {
|
|
|
|
for (int i = 0; i < var_list->nod_count; i++) {
|
|
|
|
asgn_to(action, (const ref*) var_list->nod_arg[i]);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2003-10-06 11:48:44 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "ELSE");
|
|
|
|
printa(COLUMN, "SQLCODE = 100");
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
|
|
|
|
if (request->req_sync)
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate substitution text for FINISH
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_finish(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
DBB db = NULL;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto || ((action->act_flags & ACT_sql) &&
|
2004-05-29 06:55:23 +02:00
|
|
|
(action->act_type != ACT_disconnect)))
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "IF (GDS__TRANS .NE. 0) THEN");
|
|
|
|
printa(COLUMN, " CALL ISC_%s_TRANSACTION (%s, GDS__TRANS)",
|
|
|
|
(action->act_type != ACT_rfinish) ? "COMMIT" : "ROLLBACK",
|
|
|
|
status_vector(action));
|
|
|
|
status_and_stop(action);
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
}
|
|
|
|
|
|
|
|
// the user supplied one or more db_handles
|
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
for (rdy* ready = (rdy*) action->act_object; ready; ready = ready->rdy_next) {
|
2001-05-23 15:26:42 +02:00
|
|
|
db = ready->rdy_database;
|
|
|
|
printa(COLUMN, "IF (%s .NE. 0) THEN", db->dbb_name->sym_string);
|
|
|
|
printa(COLUMN, "CALL ISC_DETACH_DATABASE (%s, %s)",
|
|
|
|
status_vector(action), db->dbb_name->sym_string);
|
|
|
|
status_and_stop(action);
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!db)
|
2004-05-24 19:13:38 +02:00
|
|
|
for (db = gpreGlob.isc_databases; db; db = db->dbb_next) {
|
2001-05-23 15:26:42 +02:00
|
|
|
if ((action->act_error || (action->act_flags & ACT_sql))
|
2004-05-24 19:13:38 +02:00
|
|
|
&& (db != gpreGlob.isc_databases))
|
2003-10-05 08:56:48 +02:00
|
|
|
{
|
|
|
|
printa(COLUMN, "IF (%s .NE. 0 .AND. ISC_STATUS(2) .EQ. 0) THEN",
|
|
|
|
db->dbb_name->sym_string);
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
|
|
|
printa(COLUMN, "IF (%s .NE. 0) THEN",
|
|
|
|
db->dbb_name->sym_string);
|
|
|
|
printa(COLUMN, "CALL ISC_DETACH_DATABASE (%s, %s)",
|
|
|
|
status_vector(action), db->dbb_name->sym_string);
|
|
|
|
status_and_stop(action);
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate substitution text for FOR statement.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_for(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
SCHAR s[20];
|
|
|
|
|
|
|
|
gen_s_start(action);
|
2003-10-06 11:48:44 +02:00
|
|
|
gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
request->req_top_label = next_label();
|
|
|
|
request->req_btm_label = next_label();
|
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
|
|
|
printa(COLUMN, "IF (ISC_STATUS(2) .NE. 0) GOTO %d\n",
|
|
|
|
request->req_btm_label);
|
|
|
|
|
|
|
|
printa("", "%-6dCONTINUE", request->req_top_label);
|
|
|
|
gen_receive(action, request->req_primary);
|
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
|
|
|
printa(COLUMN, "IF (%s .EQ. 0 .OR. ISC_STATUS(2) .NE. 0) GOTO %d\n",
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, request->req_eof, true), request->req_btm_label);
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
|
|
|
printa(COLUMN, "IF (%s .EQ. 0) GOTO %d\n",
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, request->req_eof, true), request->req_btm_label);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_port* port = action->act_request->req_primary;
|
2003-10-06 11:48:44 +02:00
|
|
|
if (port) {
|
|
|
|
for (const ref* reference = port->por_references; reference;
|
2003-09-10 21:48:53 +02:00
|
|
|
reference = reference->ref_next)
|
|
|
|
{
|
|
|
|
if (reference-> ref_flags & REF_fetch_array)
|
|
|
|
gen_get_or_put_slice(action, reference, true);
|
|
|
|
}
|
2003-10-06 11:48:44 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a call to isc_get_slice
|
|
|
|
// or isc_put_slice for an array.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_get_or_put_slice(const act* action,
|
|
|
|
const ref* reference,
|
2003-09-10 21:48:53 +02:00
|
|
|
bool get)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
TEXT s[25];
|
|
|
|
|
|
|
|
if (!(reference->ref_flags & REF_fetch_array))
|
2002-07-06 07:32:02 +02:00
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (get) {
|
|
|
|
if (action->act_flags & ACT_sql) {
|
|
|
|
sprintf(output_buffer,
|
2003-08-09 20:00:14 +02:00
|
|
|
"%sCALL ISC_GET_SLICE (%s, %s, %s, %s, %s%d%s, isc_%d, %s0%s, %s0%s, %s%"
|
|
|
|
SLONGFORMAT"%s, %s, ISC_ARRAY_LENGTH)\n",
|
2001-05-23 15:26:42 +02:00
|
|
|
COLUMN,
|
|
|
|
status_vector(action),
|
|
|
|
action->act_request->req_database->dbb_name->sym_string,
|
|
|
|
action->act_request->req_trans,
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, reference, true),
|
2001-05-23 15:26:42 +02:00
|
|
|
I2CONST_1, reference->ref_sdl_length, I2CONST_2,
|
|
|
|
reference->ref_sdl_ident,
|
|
|
|
I2CONST_1, I2CONST_2,
|
|
|
|
I2CONST_1, I2CONST_2,
|
|
|
|
I4CONST_1, reference->ref_field->fld_array_info->ary_size,
|
|
|
|
I4CONST_2, reference->ref_value);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sprintf(output_buffer,
|
2003-08-09 20:00:14 +02:00
|
|
|
"%sCALL ISC_GET_SLICE (%s, %s, %s, %s, %s%d%s, isc_%d, %s0%s, %s0%s, %s%"
|
|
|
|
SLONGFORMAT"%s, isc_%d, ISC_ARRAY_LENGTH)\n",
|
2001-05-23 15:26:42 +02:00
|
|
|
COLUMN,
|
|
|
|
status_vector(action),
|
|
|
|
action->act_request->req_database->dbb_name->sym_string,
|
|
|
|
action->act_request->req_trans,
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, reference, true),
|
2001-05-23 15:26:42 +02:00
|
|
|
I2CONST_1, reference->ref_sdl_length, I2CONST_2,
|
|
|
|
reference->ref_sdl_ident,
|
|
|
|
I2CONST_1, I2CONST_2,
|
|
|
|
I2CONST_1, I2CONST_2,
|
|
|
|
I4CONST_1, reference->ref_field->fld_array_info->ary_size,
|
|
|
|
I4CONST_2,
|
|
|
|
reference->ref_field->fld_array_info->ary_ident);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (action->act_flags & ACT_sql) {
|
|
|
|
sprintf(output_buffer,
|
2003-08-09 20:00:14 +02:00
|
|
|
"%sCALL ISC_PUT_SLICE (%s, %s, %s, %s, %s%d%s, isc_%d, %s0%s, %s0%s, %s%"
|
|
|
|
SLONGFORMAT"%s, %s)\n",
|
2001-05-23 15:26:42 +02:00
|
|
|
COLUMN,
|
|
|
|
status_vector(action),
|
|
|
|
action->act_request->req_database->dbb_name->sym_string,
|
|
|
|
action->act_request->req_trans,
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, reference, true),
|
2001-05-23 15:26:42 +02:00
|
|
|
I2CONST_1, reference->ref_sdl_length, I2CONST_2,
|
|
|
|
reference->ref_sdl_ident,
|
|
|
|
I2CONST_1, I2CONST_2,
|
|
|
|
I2CONST_1, I2CONST_2,
|
|
|
|
I4CONST_1, reference->ref_field->fld_array_info->ary_size,
|
|
|
|
I4CONST_2, reference->ref_value);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sprintf(output_buffer,
|
2003-08-09 20:00:14 +02:00
|
|
|
"%sCALL ISC_PUT_SLICE (%s, %s, %s, %s, %s%d%s, isc_%d, %s0%s, %s0%s, %s%"
|
|
|
|
SLONGFORMAT"%s, isc_%d)\n",
|
2001-05-23 15:26:42 +02:00
|
|
|
COLUMN,
|
|
|
|
status_vector(action),
|
|
|
|
action->act_request->req_database->dbb_name->sym_string,
|
|
|
|
action->act_request->req_trans,
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, reference, true),
|
2001-05-23 15:26:42 +02:00
|
|
|
I2CONST_1, reference->ref_sdl_length, I2CONST_2,
|
|
|
|
reference->ref_sdl_ident,
|
|
|
|
I2CONST_1, I2CONST_2,
|
|
|
|
I2CONST_1, I2CONST_2,
|
|
|
|
I4CONST_1, reference->ref_field->fld_array_info->ary_size,
|
|
|
|
I4CONST_2,
|
|
|
|
reference->ref_field->fld_array_info->ary_ident);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate the code to do a get segment.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_get_segment(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-01-28 08:50:41 +01:00
|
|
|
blb* blob;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (action->act_flags & ACT_sql)
|
2004-01-28 08:50:41 +01:00
|
|
|
blob = (blb*) action->act_request->req_blobs;
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
2004-01-28 08:50:41 +01:00
|
|
|
blob = (blb*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sISC_STATUS(2) = ISC_GET_SEGMENT (%s, isc_%d, isc_%d, %sLEN(isc_%d)%s, %sisc_%d%s)\n",
|
|
|
|
COLUMN,
|
|
|
|
status_vector(action),
|
|
|
|
blob->blb_ident,
|
|
|
|
blob->blb_len_ident,
|
|
|
|
I2CONST_1, blob->blb_buff_ident, I2CONST_2,
|
|
|
|
REF_1, blob->blb_buff_ident, REF_2);
|
|
|
|
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
|
|
|
|
if (action->act_flags & ACT_sql) {
|
|
|
|
status_and_stop(action);
|
|
|
|
printa(COLUMN, "IF (SQLCODE .EQ. 0 .OR. SQLCODE .EQ. 101) THEN");
|
2003-10-06 11:48:44 +02:00
|
|
|
const ref* into = action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN_INDENT, "%s = isc_%d", into->ref_value,
|
|
|
|
blob->blb_buff_ident);
|
|
|
|
if (into->ref_null_value)
|
|
|
|
printa(COLUMN_INDENT, "%s = isc_%d", into->ref_null_value,
|
|
|
|
blob->blb_len_ident);
|
|
|
|
printa(COLUMN, "ENDIF");
|
|
|
|
}
|
|
|
|
else if (!action->act_error) {
|
|
|
|
printa(COLUMN,
|
|
|
|
"IF (ISC_STATUS(2) .NE. 0 .AND. ISC_STATUS(2) .NE. ISC_SEGMENT");
|
|
|
|
printa(CONTINUE, ".AND. ISC_STATUS(2) .NE. ISC_SEGSTR_EOF) THEN");
|
|
|
|
printa(COLUMN, " CALL ISC_PRINT_STATUS (ISC_STATUS)");
|
|
|
|
printa(COLUMN, " STOP");
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate text to compile and start a stream. This is
|
|
|
|
// used both by START_STREAM and FOR
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_loop(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
TEXT name[20];
|
|
|
|
|
|
|
|
gen_s_start(action);
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_port* port = request->req_primary;
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "IF (SQLCODE .EQ. 0) THEN");
|
|
|
|
gen_receive(action, port);
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(name, port->por_references, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "IF (SQLCODE .EQ. 0 .AND. %s .EQ. 0) ", name);
|
|
|
|
printa(CONTINUE, "SQLCODE = 100");
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a name for a reference. Name is constructed from
|
|
|
|
// port and parameter idents.
|
|
|
|
//
|
|
|
|
|
2003-10-05 08:56:48 +02:00
|
|
|
static TEXT* gen_name(SCHAR* string,
|
2003-10-06 11:48:44 +02:00
|
|
|
const ref* reference,
|
2003-09-10 21:48:53 +02:00
|
|
|
bool as_blob)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
if (reference->ref_field->fld_array_info && !as_blob)
|
|
|
|
sprintf(string, "isc_%d",
|
|
|
|
reference->ref_field->fld_array_info->ary_ident);
|
|
|
|
else
|
|
|
|
sprintf(string, "isc_%d", reference->ref_ident);
|
|
|
|
|
|
|
|
return string;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a block to handle errors.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_on_error(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const act* err_action = (const act*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
if ((err_action->act_type == ACT_get_segment) ||
|
|
|
|
(err_action->act_type == ACT_put_segment) ||
|
|
|
|
(err_action->act_type == ACT_endblob))
|
2003-10-05 08:56:48 +02:00
|
|
|
{
|
|
|
|
printa(COLUMN,
|
|
|
|
"IF (ISC_STATUS(2) .NE. 0 .AND. ISC_STATUS(2) .NE. ISC_SEGMENT .AND. ISC_STATUS(2) .NE. ISC_SEGSTR_EOF) THEN");
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
|
|
|
printa(COLUMN, "IF (ISC_STATUS(2) .NE. 0) THEN");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate code for an EXECUTE PROCEDURE.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_procedure(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_port* in_port = request->req_vport;
|
|
|
|
const gpre_port* out_port = request->req_primary;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
dbb* database = request->req_database;
|
|
|
|
PAT args;
|
2003-09-05 12:14:08 +02:00
|
|
|
args.pat_database = database;
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_request = action->act_request;
|
|
|
|
args.pat_vector1 = status_vector(action);
|
|
|
|
args.pat_request = request;
|
|
|
|
args.pat_port = in_port;
|
|
|
|
args.pat_port2 = out_port;
|
2003-10-06 11:48:44 +02:00
|
|
|
|
|
|
|
const TEXT* pattern;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (in_port && in_port->por_length)
|
|
|
|
pattern =
|
|
|
|
"CALL ISC_TRANSACT_REQUEST (%V1, %RF%DH%RE, %RF%RT%RE, %VF%RS%VE, %RF%RI%RE, %VF%PL%VE, %RF%PI%RE, %VF%QL%VE, %RF%QI%RE)\n";
|
|
|
|
else
|
|
|
|
pattern =
|
|
|
|
"CALL ISC_TRANSACT_REQUEST (%V1, %RF%DH%RE, %RF%RT%RE, %VF%RS%VE, %RI, %VF0%VE, 0, %VF%QL%VE, %RF%QI%RE)\n";
|
|
|
|
|
|
|
|
// Get database attach and transaction started
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
2003-09-10 21:48:53 +02:00
|
|
|
t_start_auto(0, status_vector(action), action, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
// Move in input values
|
|
|
|
|
|
|
|
asgn_from(action, request->req_values);
|
|
|
|
|
|
|
|
// Execute the procedure
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const USHORT column = 6;
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
PATTERN_expand(column, pattern, &args);
|
|
|
|
|
|
|
|
status_and_stop(action);
|
|
|
|
|
|
|
|
printa(COLUMN, "IF (SQLCODE .EQ. 0) THEN");
|
|
|
|
|
|
|
|
// Move out output values
|
|
|
|
|
|
|
|
asgn_to_proc(request->req_references);
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate the code to do a put segment.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_put_segment(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-01-28 08:50:41 +01:00
|
|
|
blb* blob;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (action->act_flags & ACT_sql) {
|
2004-01-28 08:50:41 +01:00
|
|
|
blob = (blb*) action->act_request->req_blobs;
|
2003-10-06 11:48:44 +02:00
|
|
|
const ref* from = action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "isc_%d = %s", blob->blb_len_ident,
|
|
|
|
from->ref_null_value);
|
|
|
|
printa(COLUMN, "isc_%d = %s", blob->blb_buff_ident, from->ref_value);
|
|
|
|
}
|
|
|
|
else
|
2004-01-28 08:50:41 +01:00
|
|
|
blob = (blb*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sISC_STATUS(2) = ISC_PUT_SEGMENT (%s, isc_%d, %sisc_%d%s, %sisc_%d%s)\n",
|
|
|
|
COLUMN,
|
|
|
|
status_vector(action),
|
|
|
|
blob->blb_ident,
|
|
|
|
VAL_1, blob->blb_len_ident, VAL_2,
|
|
|
|
REF_1, blob->blb_buff_ident, REF_2);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate BLR in raw, numeric form. Ughly but dense.
|
|
|
|
//
|
|
|
|
|
2002-07-06 07:32:02 +02:00
|
|
|
static void gen_raw(
|
2003-10-06 11:48:44 +02:00
|
|
|
const UCHAR* blr,
|
2001-05-23 15:26:42 +02:00
|
|
|
enum req_t request_type,
|
|
|
|
int request_length, int begin_c, int end_c)
|
|
|
|
{
|
|
|
|
union {
|
|
|
|
UCHAR bytewise_blr[4];
|
|
|
|
SLONG longword_blr;
|
|
|
|
} blr_hunk;
|
|
|
|
|
|
|
|
blr = blr + begin_c;
|
2003-10-06 11:48:44 +02:00
|
|
|
int blr_length = end_c - begin_c + 1;
|
|
|
|
|
|
|
|
TEXT buffer[80];
|
|
|
|
TEXT* p = buffer;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
while (blr_length) {
|
2003-10-06 11:48:44 +02:00
|
|
|
blr_hunk.longword_blr = 0;
|
|
|
|
for (UCHAR* c = blr_hunk.bytewise_blr;
|
|
|
|
c < blr_hunk.bytewise_blr + sizeof(SLONG); c++)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
if (--blr_length)
|
|
|
|
*c = *blr++;
|
|
|
|
else {
|
|
|
|
if (request_type == REQ_slice)
|
|
|
|
*c = isc_sdl_eoc;
|
|
|
|
else if ((request_type == REQ_ddl) ||
|
|
|
|
(request_type == REQ_create_database) ||
|
|
|
|
(request_length != end_c + 1))
|
2003-09-11 04:13:46 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
*c = *blr++;
|
2003-09-11 04:13:46 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
|
|
|
*c = blr_eoc;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (blr_length)
|
2003-08-09 20:00:14 +02:00
|
|
|
sprintf(p, "%"SLONGFORMAT",", blr_hunk.longword_blr);
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
2003-08-09 20:00:14 +02:00
|
|
|
sprintf(p, "%"SLONGFORMAT, blr_hunk.longword_blr);
|
2001-05-23 15:26:42 +02:00
|
|
|
while (*p)
|
|
|
|
p++;
|
|
|
|
if (p - buffer > 50) {
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s%s\n", CONTINUE, buffer);
|
2001-05-23 15:26:42 +02:00
|
|
|
p = buffer;
|
|
|
|
*p = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s%s/\n", CONTINUE, buffer);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate substitution text for READY
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_ready(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-05 08:56:48 +02:00
|
|
|
const TEXT* vector = status_vector(action);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
for (rdy* ready = (rdy*) action->act_object; ready; ready = ready->rdy_next) {
|
2003-10-05 08:56:48 +02:00
|
|
|
DBB db = ready->rdy_database;
|
|
|
|
const TEXT* filename = ready->rdy_filename;
|
|
|
|
if (!filename)
|
2001-05-23 15:26:42 +02:00
|
|
|
filename = db->dbb_runtime;
|
2004-01-28 08:50:41 +01:00
|
|
|
if (action->act_error && (ready != (rdy*) action->act_object))
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "IF (ISC_STATUS(2) .EQ. 0) THEN");
|
|
|
|
make_ready(db, filename, vector, ready->rdy_request);
|
|
|
|
status_and_stop(action);
|
2004-01-28 08:50:41 +01:00
|
|
|
if (action->act_error && (ready != (rdy*) action->act_object))
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a send or receive call for a port.
|
|
|
|
//
|
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
static void gen_receive(const act* action, const gpre_port* port)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL ISC_RECEIVE (%s, %s, %s%d%s, %s%d%s, %sisc_%d%s, %s%s%s)\n",
|
|
|
|
COLUMN, status_vector(action), request->req_handle, I2CONST_1,
|
|
|
|
port->por_msg_number, I2CONST_2, I2CONST_1, port->por_length,
|
|
|
|
I2CONST_2, REF_1, port->por_ident, REF_2, VAL_1,
|
|
|
|
request->req_request_level, VAL_2);
|
|
|
|
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate substitution text for RELEASE_REQUESTS
|
|
|
|
// For active databases, call isc_release_request.
|
|
|
|
// for all others, just zero the handle. For the
|
|
|
|
// release request calls, ignore error returns, which
|
|
|
|
// are likely if the request was compiled on a database
|
|
|
|
// which has been released and re-readied. If there is
|
|
|
|
// a serious error, it will be caught on the next statement.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_release(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
DBB exp_db = (DBB) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
for (const gpre_req* request = gpreGlob.requests; request; request = request->req_next) {
|
2003-10-06 11:48:44 +02:00
|
|
|
DBB db = request->req_database;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (exp_db && db != exp_db)
|
|
|
|
continue;
|
|
|
|
if (!(request->req_flags & REQ_exp_hand)) {
|
|
|
|
printa(COLUMN, "IF %s", db->dbb_name->sym_string);
|
|
|
|
printa(CONTINUE, "CALL ISC_RELEASE_REQUEST (ISC_STATUS, %S)",
|
|
|
|
request->req_handle);
|
|
|
|
printa(COLUMN, "%s = 0", request->req_handle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate definitions associated with a single request.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_request_data( const gpre_req* request)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
int begin_i, end_i;
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
// gpreGlob.requests are generated as raw BLR in longword chunks
|
2001-05-23 15:26:42 +02:00
|
|
|
// because FORTRAN is a miserable excuse for a language
|
|
|
|
// and doesn't allow byte value assignments to character
|
|
|
|
// fields.
|
|
|
|
|
2003-09-11 04:13:46 +02:00
|
|
|
if (!(request->req_flags & (REQ_exp_hand | REQ_sql_blob_open
|
|
|
|
| REQ_sql_blob_create)) &&
|
2001-05-23 15:26:42 +02:00
|
|
|
request->req_type != REQ_slice && request->req_type != REQ_procedure)
|
2003-09-10 21:48:53 +02:00
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sDATA %s /0/ %s{ init request handle }\n\n",
|
|
|
|
COLUMN, request->req_handle, INLINE_COMMENT);
|
2003-09-10 21:48:53 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (request->req_flags & (REQ_sql_blob_open | REQ_sql_blob_create))
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sDATA isc_%dS /0/ %s{ init SQL statement handle }\n\n",
|
|
|
|
COLUMN, request->req_ident, INLINE_COMMENT);
|
|
|
|
|
|
|
|
if (request->req_flags & REQ_sql_cursor)
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sDATA isc_%dS /0/ %s{ init SQL statement handle }\n\n",
|
|
|
|
COLUMN, request->req_ident, INLINE_COMMENT);
|
|
|
|
|
|
|
|
// Changed termination test in for-loop from <= to < to fix bug#840.
|
|
|
|
// We were generating data statements with bad bounds on the last data
|
|
|
|
// statement if the data size was divisible by 75. mao 4/3/89
|
|
|
|
//
|
|
|
|
if ((request->req_type == REQ_ready) ||
|
|
|
|
(request->req_type == REQ_create_database))
|
2003-09-10 21:48:53 +02:00
|
|
|
{
|
|
|
|
if (request->req_length || request->req_flags & REQ_extend_dpb)
|
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sDATA isc_%dl /%d/ %s{ request length }\n\n",
|
|
|
|
COLUMN, request->req_ident, request->req_length,
|
|
|
|
INLINE_COMMENT);
|
|
|
|
}
|
2003-09-10 21:48:53 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (request->req_length) {
|
2003-09-10 21:48:53 +02:00
|
|
|
for (begin_i = 0; begin_i < request->req_length;
|
|
|
|
begin_i = begin_i + (75 * sizeof(SLONG)))
|
|
|
|
{
|
|
|
|
end_i = MIN(request->req_length - 1,
|
2003-08-09 20:00:14 +02:00
|
|
|
begin_i + (SLONG)(75 * sizeof(SLONG)) - 1);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "DATA (isc_%d(ISC_I)%s ISC_I=%d,%d) /",
|
|
|
|
request->req_ident, COMMA, (begin_i / sizeof(SLONG)) + 1,
|
|
|
|
(end_i / sizeof(SLONG)) + 1);
|
|
|
|
gen_raw(request->req_blr, request->req_type, request->req_length,
|
|
|
|
begin_i, end_i);
|
|
|
|
}
|
2003-10-06 11:48:44 +02:00
|
|
|
|
|
|
|
const TEXT* string_type;
|
2004-05-24 19:13:38 +02:00
|
|
|
if (!gpreGlob.sw_raw) {
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COMMENT, " ");
|
|
|
|
printa(COMMENT, "FORMATTED REQUEST BLR FOR isc_%d = ",
|
|
|
|
request->req_ident);
|
|
|
|
switch (request->req_type) {
|
|
|
|
case REQ_create_database:
|
|
|
|
case REQ_ready:
|
|
|
|
string_type = "DPB";
|
2003-09-28 23:36:05 +02:00
|
|
|
if (PRETTY_print_cdb(request->req_blr, gen_blr, 0, 0))
|
2003-10-15 00:22:32 +02:00
|
|
|
CPR_error("internal error during parameter generation");
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case REQ_ddl:
|
|
|
|
string_type = "DYN";
|
2003-09-28 23:36:05 +02:00
|
|
|
if (PRETTY_print_dyn(request->req_blr, gen_blr, 0, 0))
|
2003-10-15 00:22:32 +02:00
|
|
|
CPR_error("internal error during dynamic DDL generation");
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
case REQ_slice:
|
|
|
|
string_type = "SDL";
|
2003-09-28 23:36:05 +02:00
|
|
|
if (PRETTY_print_sdl(request->req_blr, gen_blr, 0, 0))
|
2003-10-15 00:22:32 +02:00
|
|
|
CPR_error("internal error during SDL generation");
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
string_type = "BLR";
|
2003-09-28 23:36:05 +02:00
|
|
|
if (gds__print_blr(request->req_blr, gen_blr, 0, 0))
|
2003-10-15 00:22:32 +02:00
|
|
|
CPR_error("internal error during BLR generation");
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
switch (request->req_type) {
|
|
|
|
case REQ_create_database:
|
|
|
|
case REQ_ready:
|
|
|
|
string_type = "DPB";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case REQ_ddl:
|
|
|
|
string_type = "DYN";
|
|
|
|
break;
|
|
|
|
case REQ_slice:
|
|
|
|
string_type = "SDL";
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
string_type = "BLR";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
printa(COMMENT, " ");
|
|
|
|
printa(COMMENT, "END OF %s STRING FOR REQUEST isc_%d\n",
|
|
|
|
string_type, request->req_ident);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Print out slice description language if there are arrays associated with request
|
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
for (const gpre_port* port = request->req_ports; port; port = port->por_next)
|
2003-10-06 11:48:44 +02:00
|
|
|
for (const ref* reference = port->por_references; reference;
|
2003-09-10 21:48:53 +02:00
|
|
|
reference = reference->ref_next)
|
|
|
|
{
|
|
|
|
if (reference->ref_sdl) {
|
2001-05-23 15:26:42 +02:00
|
|
|
for (begin_i = 0; begin_i < reference->ref_sdl_length;
|
2003-09-10 21:48:53 +02:00
|
|
|
begin_i = begin_i + (75 * sizeof(SLONG)))
|
|
|
|
{
|
|
|
|
end_i = MIN(reference->ref_sdl_length - 1,
|
2003-08-09 20:00:14 +02:00
|
|
|
begin_i + (SLONG)(75 * sizeof(SLONG)) - 1);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "DATA (isc_%d(ISC_I)%s ISC_I=%d,%d) /",
|
|
|
|
reference->ref_sdl_ident, COMMA,
|
|
|
|
(begin_i / sizeof(SLONG)) + 1,
|
|
|
|
(end_i / sizeof(SLONG)) + 1);
|
2004-06-03 09:31:10 +02:00
|
|
|
gen_raw(reference->ref_sdl, REQ_slice,
|
2001-05-23 15:26:42 +02:00
|
|
|
reference->ref_sdl_length, begin_i, end_i);
|
|
|
|
}
|
2004-05-24 19:13:38 +02:00
|
|
|
if (!(gpreGlob.sw_raw)) {
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COMMENT, " ");
|
2003-09-28 23:36:05 +02:00
|
|
|
if (PRETTY_print_sdl(reference->ref_sdl, gen_blr, 0, 0))
|
2003-10-15 00:22:32 +02:00
|
|
|
CPR_error("internal error during SDL generation");
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COMMENT, " ");
|
|
|
|
printa(COMMENT, "END OF SDL STRING FOR REQUEST isc_%d\n",
|
|
|
|
reference->ref_sdl_ident);
|
|
|
|
}
|
|
|
|
}
|
2003-09-10 21:48:53 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
// Print out any blob parameter blocks required
|
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
for (blb* blob = request->req_blobs; blob; blob = blob->blb_next)
|
2001-05-23 15:26:42 +02:00
|
|
|
if (blob->blb_bpb_length) {
|
2003-09-10 21:48:53 +02:00
|
|
|
for (begin_i = 0; begin_i < blob->blb_bpb_length;
|
|
|
|
begin_i = begin_i + (75 * sizeof(SLONG)))
|
|
|
|
{
|
|
|
|
end_i = MIN(blob->blb_bpb_length - 1,
|
|
|
|
begin_i + (SLONG)(75 * sizeof(SLONG)) - 1);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "DATA (isc_%d(ISC_I)%s ISC_I=%d,%d) /",
|
|
|
|
blob->blb_bpb_ident, COMMA,
|
|
|
|
(begin_i / sizeof(SLONG)) + 1,
|
|
|
|
(end_i / sizeof(SLONG)) + 1);
|
|
|
|
gen_raw(blob->blb_bpb, REQ_for, blob->blb_bpb_length, begin_i,
|
|
|
|
end_i);
|
|
|
|
printa(COMMENT, " ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate definitions associated with a single request.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_request_decls( const gpre_req* request)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
if (!(request->req_flags & (REQ_exp_hand | REQ_sql_blob_open
|
2003-09-11 04:13:46 +02:00
|
|
|
| REQ_sql_blob_create)) &&
|
2001-05-23 15:26:42 +02:00
|
|
|
request->req_type != REQ_slice && request->req_type != REQ_procedure)
|
2003-09-10 21:48:53 +02:00
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 %s %s{ request handle }\n\n",
|
|
|
|
COLUMN, request->req_handle, INLINE_COMMENT);
|
2003-09-10 21:48:53 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
// generate the request as BLR long words
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const int rlength = (request->req_length + (sizeof(SLONG) - 1)) / sizeof(SLONG);
|
|
|
|
if (rlength)
|
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 isc_%d(%d) %s{ request BLR }\n",
|
2003-10-06 11:48:44 +02:00
|
|
|
COLUMN, request->req_ident, rlength, INLINE_COMMENT);
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
// Generate declarations for the slice description language
|
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
for (const gpre_port* port = request->req_ports; port; port = port->por_next)
|
2003-10-06 11:48:44 +02:00
|
|
|
for (const ref* reference = port->por_references; reference;
|
2003-09-13 14:23:31 +02:00
|
|
|
reference = reference->ref_next)
|
2003-09-10 21:48:53 +02:00
|
|
|
{
|
2003-09-13 14:23:31 +02:00
|
|
|
if (reference->ref_sdl)
|
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const int slength = (reference->ref_sdl_length +
|
2003-09-13 14:23:31 +02:00
|
|
|
(sizeof(SLONG) - 1)) / sizeof(SLONG);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2003-09-13 14:23:31 +02:00
|
|
|
"%sINTEGER*4 isc_%d(%d) %s{ request SDL }\n",
|
2003-10-06 11:48:44 +02:00
|
|
|
COLUMN, reference->ref_sdl_ident, slength,
|
2003-09-13 14:23:31 +02:00
|
|
|
INLINE_COMMENT);
|
|
|
|
}
|
2003-09-10 21:48:53 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
// Print out any blob parameter block variable declarations required
|
2004-01-28 08:50:41 +01:00
|
|
|
for (blb* blob = request->req_blobs; blob; blob = blob->blb_next)
|
2001-05-23 15:26:42 +02:00
|
|
|
if (blob->blb_const_from_type) {
|
2003-10-06 11:48:44 +02:00
|
|
|
const int blength =
|
2001-05-23 15:26:42 +02:00
|
|
|
(blob->blb_bpb_length + (sizeof(SLONG) - 1)) / sizeof(SLONG);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 isc_%d(%d) %s{ blob parameter block }\n",
|
2003-10-06 11:48:44 +02:00
|
|
|
COLUMN, blob->blb_bpb_ident, blength, INLINE_COMMENT);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (request->req_flags & REQ_sql_cursor)
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 isc_%dS %s{ SQL statement handle }\n\n",
|
|
|
|
COLUMN, request->req_ident, INLINE_COMMENT);
|
|
|
|
|
|
|
|
if ((request->req_type == REQ_ready) ||
|
2003-09-10 21:48:53 +02:00
|
|
|
(request->req_type == REQ_create_database))
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "INTEGER*2 isc_%dl", request->req_ident);
|
|
|
|
if (request->req_flags & REQ_extend_dpb)
|
|
|
|
printa(COLUMN, "INTEGER*4 isc_%dp", request->req_ident);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If this is a GET_SLICE/PUT_slice, allocate some variables
|
|
|
|
|
|
|
|
if (request->req_type == REQ_slice) {
|
|
|
|
printa(COLUMN, "INTEGER*4 isc_%dv (%d)", request->req_ident,
|
|
|
|
MAX(request->req_slice->slc_parameters, 1));
|
|
|
|
printa(COLUMN, "INTEGER*4 isc_%ds", request->req_ident);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate receive call for a port
|
|
|
|
// in a store2 statement.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_return_value(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
gen_start(action, request->req_primary);
|
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const upd* update = (const upd*) action->act_object;
|
|
|
|
const ref* reference = update->upd_references;
|
2001-05-23 15:26:42 +02:00
|
|
|
gen_receive(action, reference->ref_port);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
2004-05-24 19:13:38 +02:00
|
|
|
// Process routine head. If there are gpreGlob.requests in the
|
2001-05-23 15:26:42 +02:00
|
|
|
// routine, insert local definitions.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_routine(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
for (const gpre_req* request = (const gpre_req*) action->act_object; request;
|
2003-09-10 21:48:53 +02:00
|
|
|
request = request->req_routine)
|
|
|
|
{
|
2004-01-28 08:50:41 +01:00
|
|
|
for (const gpre_port* port = request->req_ports; port; port = port->por_next)
|
2001-05-23 15:26:42 +02:00
|
|
|
make_port(port);
|
2004-01-28 08:50:41 +01:00
|
|
|
for (blb* blob = request->req_blobs; blob; blob = blob->blb_next) {
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 isc_%d %s{ blob handle }\n",
|
|
|
|
COLUMN, blob->blb_ident, INLINE_COMMENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sCHARACTER*%d isc_%d %s{ blob segment }\n",
|
|
|
|
COLUMN, blob->blb_seg_length, blob->blb_buff_ident,
|
|
|
|
INLINE_COMMENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*2 isc_%d %s{ segment length }\n",
|
|
|
|
COLUMN, blob->blb_len_ident, INLINE_COMMENT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate substitution text for END_STREAM.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_s_end(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (action->act_type == ACT_close)
|
|
|
|
gen_cursor_close(action, request);
|
|
|
|
|
|
|
|
printa(COLUMN, "CALL ISC_UNWIND_REQUEST (%s, %s, %s%s%s)",
|
|
|
|
status_vector(action),
|
|
|
|
request->req_handle, VAL_1, request->req_request_level, VAL_2);
|
|
|
|
|
|
|
|
if (action->act_type == ACT_close) {
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
}
|
|
|
|
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate substitution text for FETCH.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_s_fetch(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (request->req_sync)
|
|
|
|
gen_send(action, request->req_sync);
|
|
|
|
|
|
|
|
gen_receive(action, request->req_primary);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate text to compile and start a stream. This is
|
|
|
|
// used both by START_STREAM and FOR
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_s_start(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
gen_compile(action);
|
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_port* port = request->req_vport;
|
2003-10-06 11:48:44 +02:00
|
|
|
if (port)
|
2001-05-23 15:26:42 +02:00
|
|
|
asgn_from(action, port->por_references);
|
|
|
|
|
|
|
|
if (action->act_type == ACT_open)
|
|
|
|
gen_cursor_open(action, request);
|
|
|
|
|
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
|
|
|
make_ok_test(action, request);
|
|
|
|
|
|
|
|
gen_start(action, port);
|
|
|
|
|
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
|
|
|
|
if (action->act_type == ACT_open) {
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Substitute for a segment, segment length, or blob handle.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_segment(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-01-28 08:50:41 +01:00
|
|
|
blb* blob = (blb*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
printa("", "%sisc_%d",
|
|
|
|
(action->act_flags & ACT_first) ? COLUMN : CONTINUE,
|
|
|
|
(action->act_type == ACT_segment) ? blob->blb_buff_ident :
|
|
|
|
(action->act_type == ACT_segment_length) ? blob->blb_len_ident :
|
|
|
|
blob->blb_ident);
|
2004-05-24 19:13:38 +02:00
|
|
|
fputs(CONTINUE, gpreGlob.out_file);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_select(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
SCHAR name[20];
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_port* port = request->req_primary;
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(name, request->req_eof, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
gen_s_start(action);
|
|
|
|
printa(COLUMN, "IF (SQLCODE .EQ. 0) THEN");
|
|
|
|
gen_receive(action, port);
|
|
|
|
printa(COLUMN, "IF (%s .NE. 0) THEN", name);
|
2003-10-06 11:48:44 +02:00
|
|
|
GPRE_NOD var_list = (GPRE_NOD) action->act_object;
|
|
|
|
if (var_list)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < var_list->nod_count; ++i)
|
|
|
|
asgn_to(action, (const ref*) var_list->nod_arg[i]);
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (request->req_database->dbb_flags & DBB_v3) {
|
|
|
|
gen_receive(action, port);
|
|
|
|
printa(COLUMN, "IF (%s .NE. 0) THEN", name);
|
|
|
|
printa(COLUMN, "SQLCODE = -1");
|
|
|
|
printa(COLUMN, "ELSE");
|
|
|
|
printa(COLUMN, "SQLCODE = 0");
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
}
|
|
|
|
|
|
|
|
printa(COLUMN, "ELSE");
|
|
|
|
printa(COLUMN, "SQLCODE = 100");
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a send call for a port.
|
|
|
|
//
|
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
static void gen_send(const act* action, const gpre_port* port)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
sprintf(output_buffer,
|
|
|
|
"%s CALL ISC_SEND (%s, %s, %s%d%s, %s%d%s, %sisc_%d%s, %s%s%s)\n",
|
|
|
|
COLUMN, status_vector(action), request->req_handle, I2CONST_1,
|
|
|
|
port->por_msg_number, I2CONST_2, I2CONST_1, port->por_length,
|
|
|
|
I2CONST_2, REF_1, port->por_ident, REF_2, VAL_1,
|
|
|
|
request->req_request_level, VAL_2);
|
|
|
|
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate support for get/put slice statement.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_slice(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
TEXT buffer[256], temp[64];
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* pattern1 =
|
2001-05-23 15:26:42 +02:00
|
|
|
"CALL ISC_GET_SLICE (%V1, %RF%DH%RE, %RF%RT%RE, %RF%FR%RE, %N1, \
|
|
|
|
%I1, %N2, %I1v, %I1s, %RF%S5%RE, %RF%S6%RE)";
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* pattern2 =
|
2001-05-23 15:26:42 +02:00
|
|
|
"CALL ISC_PUT_SLICE (%V1, %RF%DH%RE, %RF%RT%RE, %RF%FR%RE, %N1, \
|
|
|
|
%I1, %N2, %I1v, %I1s, %RF%S5%RE)";
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2004-01-28 08:50:41 +01:00
|
|
|
slc* slice = (slc*) action->act_object;
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* parent_request = slice->slc_parent_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
// Compute array size
|
|
|
|
|
|
|
|
sprintf(buffer, "isc_%ds = %d", request->req_ident,
|
|
|
|
slice->slc_field->fld_array->fld_length);
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
slc::slc_repeat* tail = slice->slc_rpt;
|
|
|
|
for (slc::slc_repeat* const end = tail + slice->slc_dimensions;
|
2001-05-23 15:26:42 +02:00
|
|
|
tail < end; ++tail)
|
2003-09-10 21:48:53 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
if (tail->slc_upper != tail->slc_lower) {
|
2003-10-06 11:48:44 +02:00
|
|
|
const ref* lower = (const ref*) tail->slc_lower->nod_arg[0];
|
|
|
|
const ref* upper = (const ref*) tail->slc_upper->nod_arg[0];
|
2001-05-23 15:26:42 +02:00
|
|
|
if (lower->ref_value)
|
|
|
|
sprintf(temp, " * ( %s - %s + 1)", upper->ref_value,
|
|
|
|
lower->ref_value);
|
|
|
|
else
|
|
|
|
sprintf(temp, " * ( %s + 1)", upper->ref_value);
|
|
|
|
strcat(buffer, temp);
|
|
|
|
}
|
2003-09-10 21:48:53 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, buffer);
|
|
|
|
|
|
|
|
// Make assignments to variable vector
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const ref* reference;
|
2001-05-23 15:26:42 +02:00
|
|
|
for (reference = request->req_values; reference;
|
|
|
|
reference =
|
2003-10-05 08:56:48 +02:00
|
|
|
reference->ref_next)
|
|
|
|
{
|
|
|
|
printa(COLUMN, "isc_%dv [%d] = %s;",
|
|
|
|
request->req_ident, reference->ref_id,
|
|
|
|
reference->ref_value);
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
PAT args;
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_reference = slice->slc_field_ref;
|
2003-11-28 07:48:34 +01:00
|
|
|
args.pat_request = parent_request; // blob id request
|
|
|
|
args.pat_vector1 = status_vector(action); // status vector
|
|
|
|
args.pat_database = parent_request->req_database; // database handle
|
|
|
|
args.pat_string1 = action->act_request->req_trans; // transaction handle
|
|
|
|
args.pat_value1 = request->req_length; // slice descr. length
|
|
|
|
args.pat_ident1 = request->req_ident; // request name
|
|
|
|
args.pat_value2 = slice->slc_parameters * sizeof(SLONG); // parameter length
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
reference = (const ref*) slice->slc_array->nod_arg[0];
|
2003-11-28 07:48:34 +01:00
|
|
|
args.pat_string5 = reference->ref_value; // array name
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_string6 = "isc_array_length";
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const SSHORT column = 6;
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
PATTERN_expand(column,
|
|
|
|
(action->act_type == ACT_get_slice) ? pattern1 : pattern2,
|
|
|
|
&args);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate either a START or START_AND_SEND depending
|
|
|
|
// on whether or a not a port is present.
|
|
|
|
//
|
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
static void gen_start(const act* action, const gpre_port* port)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2003-10-05 08:56:48 +02:00
|
|
|
const TEXT* vector = status_vector(action);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (port) {
|
2003-10-06 11:48:44 +02:00
|
|
|
for (const ref* reference = port->por_references; reference;
|
2003-09-10 21:48:53 +02:00
|
|
|
reference = reference->ref_next)
|
|
|
|
{
|
|
|
|
if (reference->ref_field-> fld_array_info)
|
|
|
|
gen_get_or_put_slice(action, reference, false);
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL ISC_START_AND_SEND (%s, %s, %s, %s%d%s, %s%d%s, %sisc_%d%s, %s%s%s)\n",
|
2003-09-10 21:48:53 +02:00
|
|
|
COLUMN, vector, request->req_handle,
|
2001-05-23 15:26:42 +02:00
|
|
|
request_trans(action, request),
|
|
|
|
I2CONST_1, port->por_msg_number, I2CONST_2,
|
|
|
|
I2CONST_1, port->por_length, I2CONST_2,
|
|
|
|
REF_1, port->por_ident, REF_2,
|
|
|
|
I2CONST_1, request->req_request_level, I2CONST_2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL ISC_START_REQUEST (%s, %s, %s, %s%s%s)\n", COLUMN,
|
|
|
|
vector, request->req_handle, request_trans(action, request),
|
|
|
|
I2CONST_1, request->req_request_level, I2CONST_2);
|
|
|
|
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate text for STORE statement. This includes the compile
|
|
|
|
// call and any variable initialization required.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_store(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
TEXT name[64];
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
gen_compile(action);
|
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
|
|
|
make_ok_test(action, request);
|
|
|
|
|
|
|
|
// Initialize any blob fields
|
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_port* port = request->req_primary;
|
2003-10-06 11:48:44 +02:00
|
|
|
for (const ref* reference = port->por_references; reference;
|
2003-09-10 21:48:53 +02:00
|
|
|
reference = reference->ref_next)
|
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_fld* field = reference->ref_field;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (field->fld_flags & FLD_blob)
|
|
|
|
printa(COLUMN, "CALL isc_qtoq (isc_blob_null, %s)",
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(name, reference, true));
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate substitution text for START_TRANSACTION.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_t_start(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
// if this is a purely default transaction, just let it through
|
2004-01-28 08:50:41 +01:00
|
|
|
gpre_tra* trans;
|
|
|
|
if (!action || !(trans = (gpre_tra*) action->act_object)) {
|
2003-09-10 21:48:53 +02:00
|
|
|
t_start_auto(0, status_vector(action), action, false);
|
2002-07-06 07:32:02 +02:00
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// build a complete statement, including tpb's. Ready db's as req.
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const tpb* tpb_iterator;
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
2003-09-10 21:48:53 +02:00
|
|
|
for (tpb_iterator = trans->tra_tpb; tpb_iterator;
|
2003-09-05 12:14:08 +02:00
|
|
|
tpb_iterator = tpb_iterator->tpb_tra_next)
|
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
DBB db = tpb_iterator->tpb_database;
|
|
|
|
const TEXT* filename = db->dbb_runtime;
|
|
|
|
if (filename || !(db->dbb_flags & DBB_sqlca)) {
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "IF (%s .EQ. 0) THEN",
|
|
|
|
db->dbb_name->sym_string);
|
|
|
|
make_ready(db, filename, status_vector(action), 0);
|
|
|
|
status_and_stop(action);
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef hpux
|
|
|
|
// If this is hpux we should be building a teb vector here
|
|
|
|
// with the tpb address and length specified
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
int count = 0;
|
|
|
|
for (tpb_iterator = trans->tra_tpb;
|
2003-09-10 21:48:53 +02:00
|
|
|
tpb_iterator; tpb_iterator = tpb_iterator->tpb_tra_next)
|
2003-09-05 12:14:08 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
count++;
|
2003-10-06 11:48:44 +02:00
|
|
|
DBB db = tpb_iterator->tpb_database;
|
2003-09-05 12:14:08 +02:00
|
|
|
printa(COLUMN, "ISC_TEB%d_LEN = %d", count, tpb_iterator->tpb_length);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "ISC_TEB%d_TPB = ISC_BADDRESS (ISC_TPB_%d)",
|
2003-09-05 12:14:08 +02:00
|
|
|
count, tpb_iterator->tpb_ident);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "ISC_TEB%d_DBB = ISC_BADDRESS (%s)",
|
|
|
|
count, db->dbb_name->sym_string);
|
|
|
|
}
|
|
|
|
|
|
|
|
printa(COLUMN, "CALL ISC_START_MULTIPLE (%s, %s, %d, ISC_TEB)",
|
|
|
|
status_vector(action),
|
|
|
|
(trans->tra_handle) ? trans->tra_handle : "gds__trans",
|
|
|
|
trans->tra_db_count);
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
printa(COLUMN, "CALL ISC_START_TRANSACTION (%s, %s, %s%d%s",
|
|
|
|
status_vector(action),
|
|
|
|
(trans->tra_handle) ? trans->tra_handle : "GDS__TRANS",
|
|
|
|
I2CONST_1, trans->tra_db_count, I2CONST_2);
|
|
|
|
|
2003-09-05 12:14:08 +02:00
|
|
|
for (tpb_iterator = trans->tra_tpb;
|
2003-09-10 21:48:53 +02:00
|
|
|
tpb_iterator; tpb_iterator = tpb_iterator->tpb_tra_next)
|
2003-09-05 12:14:08 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(CONTINUE, ", %s, %s%d%s, isc_tpb_%d",
|
2003-09-05 12:14:08 +02:00
|
|
|
tpb_iterator->tpb_database->dbb_name->sym_string,
|
|
|
|
I2CONST_1, tpb_iterator->tpb_length, I2CONST_2,
|
|
|
|
tpb_iterator->tpb_ident);
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
printa(CONTINUE, ")");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Initialize a TPB in the output file
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_tpb_data(const tpb* tpb_buffer)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
union {
|
|
|
|
UCHAR bytewise_tpb[4];
|
|
|
|
SLONG longword_tpb;
|
|
|
|
} tpb_hunk;
|
|
|
|
|
|
|
|
//
|
|
|
|
// TPBs are generated as raw BLR in longword chunks
|
|
|
|
// because FORTRAN is a miserable excuse for a language
|
|
|
|
// and doesn't allow byte value assignments to character
|
|
|
|
// fields.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
int length = (tpb_buffer->tpb_length + (sizeof(SLONG) - 1)) / sizeof(SLONG);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-05 12:14:08 +02:00
|
|
|
printa(COLUMN, "DATA ISC_TPB_%d /", tpb_buffer->tpb_ident, COMMA, length);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const UCHAR* text = tpb_buffer->tpb_string;
|
2003-09-05 12:14:08 +02:00
|
|
|
length = tpb_buffer->tpb_length;
|
2001-05-23 15:26:42 +02:00
|
|
|
strcpy(output_buffer, CONTINUE);
|
2003-10-06 11:48:44 +02:00
|
|
|
|
|
|
|
TEXT* p;
|
2001-05-23 15:26:42 +02:00
|
|
|
for (p = output_buffer; *p; p++);
|
|
|
|
|
|
|
|
while (length) {
|
2003-10-06 11:48:44 +02:00
|
|
|
for (UCHAR* c = tpb_hunk.bytewise_tpb;
|
2003-09-10 21:48:53 +02:00
|
|
|
c < tpb_hunk.bytewise_tpb + sizeof(SLONG); c++)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
*c = *text++;
|
|
|
|
if (!(--length))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (length)
|
2003-08-09 20:00:14 +02:00
|
|
|
sprintf(p, "%"SLONGFORMAT",", tpb_hunk.longword_tpb);
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
2003-08-09 20:00:14 +02:00
|
|
|
sprintf(p, "%"SLONGFORMAT"/\n", tpb_hunk.longword_tpb);
|
2001-05-23 15:26:42 +02:00
|
|
|
p += 12;
|
|
|
|
}
|
|
|
|
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
sprintf(output_buffer, "%sEnd of data for ISC_TPB_%d\n",
|
2003-09-05 12:14:08 +02:00
|
|
|
COMMENT, tpb_buffer->tpb_ident);
|
2001-05-23 15:26:42 +02:00
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate the declaration for a
|
|
|
|
// TPB in the output file
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_tpb_decls(const tpb* tpb_buffer)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const int length = (tpb_buffer->tpb_length + (sizeof(SLONG) - 1)) / sizeof(SLONG);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2001-05-23 15:26:42 +02:00
|
|
|
"%sINTEGER*4 ISC_TPB_%d(%d) %s{ transaction parameters }\n",
|
2003-09-05 12:14:08 +02:00
|
|
|
COLUMN, tpb_buffer->tpb_ident, length, INLINE_COMMENT);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate substitution text for COMMIT, ROLLBACK, PREPARE, and SAVE
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_trans(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
if (action->act_type == ACT_commit_retain_context)
|
|
|
|
printa(COLUMN, "CALL ISC_COMMIT_RETAINING (%s, %s)",
|
|
|
|
status_vector(action),
|
2003-10-05 08:56:48 +02:00
|
|
|
(action->act_object) ? (TEXT*) (action->
|
2001-05-23 15:26:42 +02:00
|
|
|
act_object) : "GDS__TRANS");
|
|
|
|
else
|
|
|
|
printa(COLUMN, "CALL ISC_%s_TRANSACTION (%s, %s)",
|
|
|
|
(action->act_type ==
|
|
|
|
ACT_commit) ? "COMMIT" : (action->act_type ==
|
|
|
|
ACT_rollback) ? "ROLLBACK" :
|
|
|
|
"PREPARE", status_vector(action),
|
2003-10-05 08:56:48 +02:00
|
|
|
(action->act_object) ? (TEXT*) (action->
|
2001-05-23 15:26:42 +02:00
|
|
|
act_object) : "GDS__TRANS");
|
|
|
|
status_and_stop(action);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate substitution text for UPDATE ... WHERE CURRENT OF ...
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_update(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const upd* modify = (const upd*) action->act_object;
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_port* port = modify->upd_port;
|
2001-05-23 15:26:42 +02:00
|
|
|
asgn_from(action, port->por_references);
|
|
|
|
gen_send(action, port);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Substitute for a variable reference.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_variable(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
SCHAR s[20];
|
2003-10-06 11:48:44 +02:00
|
|
|
const ref* reference = (const ref*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
printa("", "%s%s",
|
|
|
|
(action->act_flags & ACT_first) ? COLUMN : CONTINUE,
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, reference, false));
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fputs(CONTINUE, gpreGlob.out_file);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate tests for any WHENEVER clauses that may have been declared.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_whenever(const swe* label)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* condition;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
while (label) {
|
|
|
|
switch (label->swe_condition) {
|
|
|
|
case SWE_error:
|
|
|
|
condition = "SQLCODE .LT. 0";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SWE_warning:
|
|
|
|
condition = "SQLCODE .EQ. 0 .AND. SQLCODE .NE. 100";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SWE_not_found:
|
|
|
|
condition = "SQLCODE .EQ. 100";
|
|
|
|
break;
|
2003-10-06 11:48:44 +02:00
|
|
|
//CVC: default: => error???
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
printa(COLUMN, "if (%s) goto %s", condition, label->swe_label);
|
|
|
|
label = label->swe_next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a declaration of an array in the
|
|
|
|
// output file.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void make_array_declaration( const ref* reference)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_fld* field = reference->ref_field;
|
|
|
|
const SCHAR* const name = field->fld_symbol->sym_string;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
// Check to see if the array already has been
|
|
|
|
// declared in this routine or subroutine
|
2002-07-06 07:32:02 +02:00
|
|
|
if (array_decl_list) {
|
2004-01-28 08:50:41 +01:00
|
|
|
for (adl* loop_array = array_decl_list; loop_array;
|
2003-10-06 11:48:44 +02:00
|
|
|
loop_array = loop_array->adl_next)
|
2003-09-10 21:48:53 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
if (field->fld_array_info->ary_ident == loop_array->adl_gds_ident)
|
2003-09-10 21:48:53 +02:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2002-07-06 07:32:02 +02:00
|
|
|
}
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
// If not, add it to the "declared" list and declare it
|
2004-01-28 08:50:41 +01:00
|
|
|
adl* this_array = (adl*) MSC_alloc(ADL_LEN);
|
2001-05-23 15:26:42 +02:00
|
|
|
this_array->adl_gds_ident = field->fld_array_info->ary_ident;
|
|
|
|
if (array_decl_list)
|
|
|
|
this_array->adl_next = array_decl_list;
|
|
|
|
else
|
|
|
|
this_array->adl_next = NULL;
|
|
|
|
array_decl_list = this_array;
|
|
|
|
|
|
|
|
switch (field->fld_array_info->ary_dtype) {
|
|
|
|
case dtype_short:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%sINTEGER*2%s", COLUMN, COLUMN);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_long:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%sINTEGER*4%s", COLUMN, COLUMN);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_date:
|
|
|
|
case dtype_blob:
|
|
|
|
case dtype_quad:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%sINTEGER*4%s", COLUMN, COLUMN);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_text:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%sCHARACTER*%d%s",
|
2001-05-23 15:26:42 +02:00
|
|
|
COLUMN, field->fld_array->fld_length, COLUMN);
|
|
|
|
break;
|
|
|
|
|
2003-10-15 00:22:32 +02:00
|
|
|
case dtype_real:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%sREAL%s", COLUMN, COLUMN);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_double:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s%s%s", COLUMN, DOUBLE_DCL, COLUMN);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2003-10-06 11:48:44 +02:00
|
|
|
{
|
|
|
|
TEXT s[64];
|
|
|
|
sprintf(s, "datatype %d unknown\n", field->fld_dtype);
|
|
|
|
CPR_error(s);
|
|
|
|
return;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Print out the dimension part of the declaration
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "isc_%d", field->fld_array_info->ary_ident);
|
|
|
|
fprintf(gpreGlob.out_file, "(");
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
for (dim* dimension = field->fld_array_info->ary_dimension; dimension;
|
2003-09-10 21:48:53 +02:00
|
|
|
dimension = dimension->dim_next)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
if (dimension->dim_lower != 1)
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%"SLONGFORMAT":", dimension->dim_lower);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%"SLONGFORMAT, dimension->dim_upper);
|
2001-05-23 15:26:42 +02:00
|
|
|
if (dimension->dim_next)
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ", ");
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (field->fld_dtype == dtype_quad || field->fld_dtype == dtype_date)
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ",2");
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
// Print out the database field
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ") %s{ %s }\n", INLINE_COMMENT, name);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Turn a symbol into a varying string.
|
|
|
|
//
|
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
static TEXT* make_name( TEXT* string, const gpre_sym* symbol)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
sprintf(string, "%s'%s '%s", REF_1, symbol->sym_string, REF_2);
|
|
|
|
|
|
|
|
return string;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate code to test existence of compiled request with
|
|
|
|
// active transaction
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void make_ok_test(const act* action, const gpre_req* request)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "IF (%s .NE. 0 .AND. %s .NE. 0) THEN",
|
|
|
|
request_trans(action, request), request->req_handle);
|
|
|
|
else
|
|
|
|
printa(COLUMN, "IF (%s .NE. 0) THEN", request->req_handle);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Insert a port record description in output.
|
|
|
|
//
|
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
static void make_port( const gpre_port* port)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const USHORT length = (port->por_length + 3) & ~3;
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "CHARACTER isc_%d(%d)", port->por_ident, length);
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const ref* reference;
|
2001-05-23 15:26:42 +02:00
|
|
|
for (reference = port->por_references; reference;
|
2003-09-10 21:48:53 +02:00
|
|
|
reference = reference->ref_next)
|
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_fld* field = reference->ref_field;
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_sym* symbol = field->fld_symbol;
|
2003-10-06 11:48:44 +02:00
|
|
|
const SCHAR* name;
|
|
|
|
if (symbol)
|
2001-05-23 15:26:42 +02:00
|
|
|
name = symbol->sym_string;
|
|
|
|
else
|
|
|
|
name = "<expression>";
|
|
|
|
if (reference->ref_value && (reference->ref_flags & REF_array_elem))
|
|
|
|
field = field->fld_array;
|
2003-10-06 11:48:44 +02:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
switch (field->fld_dtype) {
|
|
|
|
case dtype_short:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%sINTEGER*2 isc_%d %s{ %s }\n",
|
2001-05-23 15:26:42 +02:00
|
|
|
COLUMN, reference->ref_ident, INLINE_COMMENT, name);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_long:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%sINTEGER*4 isc_%d %s{ %s }\n",
|
2001-05-23 15:26:42 +02:00
|
|
|
COLUMN, reference->ref_ident, INLINE_COMMENT, name);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_cstring:
|
|
|
|
case dtype_text:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%sCHARACTER*%d isc_%d %s{ %s }\n",
|
2001-05-23 15:26:42 +02:00
|
|
|
COLUMN, field->fld_length, reference->ref_ident,
|
|
|
|
INLINE_COMMENT, name);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_date:
|
|
|
|
case dtype_quad:
|
|
|
|
case dtype_blob:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%sINTEGER*4 isc_%d(2) %s{ %s }\n",
|
2001-05-23 15:26:42 +02:00
|
|
|
COLUMN, reference->ref_ident, INLINE_COMMENT, name);
|
|
|
|
break;
|
|
|
|
|
2003-10-15 00:22:32 +02:00
|
|
|
case dtype_real:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%sREAL isc_%d %s{ %s }\n",
|
2001-05-23 15:26:42 +02:00
|
|
|
COLUMN, reference->ref_ident, INLINE_COMMENT, name);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_double:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s%s isc_%d %s{ %s }\n",
|
2001-05-23 15:26:42 +02:00
|
|
|
COLUMN, DOUBLE_DCL, reference->ref_ident,
|
|
|
|
INLINE_COMMENT, name);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2003-10-06 11:48:44 +02:00
|
|
|
{
|
|
|
|
SCHAR s[80];
|
|
|
|
sprintf(s, "datatype %d unknown for field %s, msg %d",
|
|
|
|
field->fld_dtype, name, port->por_msg_number);
|
|
|
|
CPR_error(s);
|
|
|
|
return;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (reference = port->por_references; reference;
|
|
|
|
reference = reference->ref_next)
|
2003-09-10 21:48:53 +02:00
|
|
|
{
|
|
|
|
printa(COLUMN, "EQUIVALENCE (isc_%d(%d), isc_%d)",
|
|
|
|
port->por_ident, reference->ref_offset + 1,
|
|
|
|
reference->ref_ident);
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
printa(COLUMN, " ");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate the actual ready call.
|
|
|
|
//
|
|
|
|
|
2003-10-05 08:56:48 +02:00
|
|
|
static void make_ready( DBB db, const TEXT* filename, const TEXT* vector,
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
TEXT s1[32], s2[32];
|
|
|
|
|
|
|
|
if (request) {
|
|
|
|
sprintf(s1, "isc_%dl", request->req_ident);
|
|
|
|
|
|
|
|
if (request->req_flags & REQ_extend_dpb)
|
|
|
|
sprintf(s2, "isc_%dp", request->req_ident);
|
|
|
|
else
|
|
|
|
sprintf(s2, "isc_%d", request->req_ident);
|
|
|
|
/* if the dpb needs to be extended at runtime to include items
|
|
|
|
in host variables, do so here; this assumes that there is
|
|
|
|
always a request generated for runtime variables */
|
|
|
|
|
|
|
|
if (request->req_flags & REQ_extend_dpb) {
|
|
|
|
if (request->req_length) {
|
|
|
|
sprintf(output_buffer, "%s%s = isc_%d\n",
|
|
|
|
COLUMN, s2, request->req_ident);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
// MMM
|
|
|
|
else {
|
|
|
|
sprintf(output_buffer, "%s%s = 0\n", COLUMN, s2);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (db->dbb_r_user) {
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL ISC_MODIFY_DPB (%s, %s, isc_dpb_user_name, %s, %sLEN(%s)%s)\n",
|
2003-09-10 21:48:53 +02:00
|
|
|
COLUMN, s2, s1, db->dbb_r_user,
|
2001-05-23 15:26:42 +02:00
|
|
|
I2CONST_1, db->dbb_r_user, I2CONST_2);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
if (db->dbb_r_password) {
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL ISC_MODIFY_DPB (%s, %s, isc_dpb_password, %s, %sLEN(%s)%s)\n",
|
2003-09-10 21:48:53 +02:00
|
|
|
COLUMN, s2, s1, db->dbb_r_password,
|
2001-05-23 15:26:42 +02:00
|
|
|
I2CONST_1, db->dbb_r_password, I2CONST_2);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** =========================================================
|
|
|
|
** == SQL Role supports GPRE/Fortran
|
|
|
|
** =========================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (db->dbb_r_sql_role) {
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL ISC_MODIFY_DPB (%s, %s, isc_dpb_sql_role_name, %s, %sLEN(%s)%s)\n",
|
2003-09-10 21:48:53 +02:00
|
|
|
COLUMN, s2, s1, db->dbb_r_sql_role,
|
2001-05-23 15:26:42 +02:00
|
|
|
I2CONST_1, db->dbb_r_sql_role, I2CONST_2);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (db->dbb_r_lc_messages) {
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL ISC_MODIFY_DPB(%s, %s, isc_dpb_lc_messages, %s, %sLEN(%s)%s)\n",
|
2003-09-10 21:48:53 +02:00
|
|
|
COLUMN, s2, s1, db->dbb_r_lc_messages,
|
2001-05-23 15:26:42 +02:00
|
|
|
I2CONST_1, db->dbb_r_lc_messages, I2CONST_2);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
if (db->dbb_r_lc_ctype) {
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL ISC_MODIFY_DPB (%s, %s, isc_dpb_lc_type, %s, %sLEN(%s)%s)\n",
|
2003-09-10 21:48:53 +02:00
|
|
|
COLUMN, s2, s1, db->dbb_r_lc_ctype,
|
2001-05-23 15:26:42 +02:00
|
|
|
I2CONST_1, db->dbb_r_lc_ctype, I2CONST_2);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (filename) {
|
2003-09-10 21:48:53 +02:00
|
|
|
sprintf(output_buffer, "%sISC_%s = %s\n", COLUMN,
|
|
|
|
db->dbb_name->sym_string, filename);
|
2001-05-23 15:26:42 +02:00
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL ISC_ATTACH_DATABASE (%s, %sLEN(%s)%s, %sISC_%s%s, %s, %s%s%s, %s)\n",
|
2003-09-10 21:48:53 +02:00
|
|
|
COLUMN, vector, I2CONST_1, filename, I2CONST_2,
|
2001-05-23 15:26:42 +02:00
|
|
|
REF_1, db->dbb_name->sym_string, REF_2,
|
2003-09-10 21:48:53 +02:00
|
|
|
db->dbb_name->sym_string, I2CONST_1,
|
2001-05-23 15:26:42 +02:00
|
|
|
(request ? s1 : "0"), I2CONST_2, (request ? s2 : "0"));
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sprintf(output_buffer, "%sISC_%s = '%s'\n",
|
|
|
|
COLUMN, db->dbb_name->sym_string, db->dbb_filename);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
|
|
|
|
sprintf(output_buffer,
|
|
|
|
"%sCALL ISC_ATTACH_DATABASE (%s, %sLEN('%s')%s, %sISC_%s%s, %s, %s%s%s, %s)\n",
|
2003-09-10 21:48:53 +02:00
|
|
|
COLUMN, vector, I2CONST_1, db->dbb_filename, I2CONST_2,
|
2001-05-23 15:26:42 +02:00
|
|
|
REF_1, db->dbb_name->sym_string, REF_2,
|
2003-09-10 21:48:53 +02:00
|
|
|
db->dbb_name->sym_string, I2CONST_1,
|
2001-05-23 15:26:42 +02:00
|
|
|
(request ? s1 : "0"), I2CONST_2, (request ? s2 : "0"));
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
if (request && request->req_flags & REQ_extend_dpb) {
|
|
|
|
if (request->req_length) {
|
|
|
|
sprintf(output_buffer, "%sif (%s != isc_%d)\n", COLUMN, s2,
|
|
|
|
request->req_ident);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
sprintf(output_buffer, "%sCALL ISC_FREE (%s)\n", COLUMN, s2);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// reset the length of the dpb
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
sprintf(output_buffer, "%s%s = %d\n", COLUMN, s1,
|
|
|
|
request->req_length);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Looks at the label bitmap and allocates
|
|
|
|
// an unused label. Marks the current
|
|
|
|
// label as used.
|
|
|
|
//
|
|
|
|
|
2002-07-06 07:32:02 +02:00
|
|
|
static USHORT next_label(void)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
UCHAR* byte;
|
2004-05-24 19:13:38 +02:00
|
|
|
for (byte = gpreGlob.fortran_labels; *byte == 255; byte++);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
USHORT label = ((byte - gpreGlob.fortran_labels) << 3);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
for (UCHAR target_byte = *byte; target_byte & 1; target_byte >>= 1)
|
2001-05-23 15:26:42 +02:00
|
|
|
label++;
|
|
|
|
|
|
|
|
*byte |= 1 << (label & 7);
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
return label;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Print a fixed string at a particular COLUMN.
|
|
|
|
//
|
|
|
|
|
2003-10-05 08:56:48 +02:00
|
|
|
static void printa(const TEXT* column, const TEXT* string, ...)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
va_list ptr;
|
|
|
|
SCHAR s[256];
|
|
|
|
|
2004-05-24 01:28:06 +02:00
|
|
|
va_start(ptr, string);
|
2001-05-23 15:26:42 +02:00
|
|
|
strcpy(s, column);
|
|
|
|
strcat(s, string);
|
|
|
|
strcat(s, "\n");
|
|
|
|
vsprintf(output_buffer, s, ptr);
|
|
|
|
FTN_print_buffer(output_buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate the appropriate transaction handle.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static const TEXT* request_trans(const act* action, const gpre_req* request)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
if (action->act_type == ACT_open) {
|
2004-01-28 08:50:41 +01:00
|
|
|
const TEXT* trname = ((open_cursor*) action->act_object)->opn_trans;
|
2003-10-05 08:56:48 +02:00
|
|
|
if (!trname)
|
2001-05-23 15:26:42 +02:00
|
|
|
trname = "GDS__TRANS";
|
|
|
|
return trname;
|
|
|
|
}
|
|
|
|
else
|
2003-10-05 08:56:48 +02:00
|
|
|
return (request) ? request->req_trans : "GDS__TRANS";
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Do the error handling ourselves
|
|
|
|
// until we figure out how to use the
|
|
|
|
// ISC_NULL from FORTRAN
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void status_and_stop(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
if (action && (action->act_flags & ACT_sql))
|
|
|
|
printa(COLUMN, "SQLCODE = ISC_SQLCODE (ISC_STATUS)");
|
|
|
|
else if (!action || !action->act_error) {
|
|
|
|
printa(COLUMN, "IF (ISC_STATUS(2) .NE. 0) THEN");
|
|
|
|
printa(COLUMN, " CALL ISC_PRINT_STATUS (ISC_STATUS)");
|
|
|
|
printa(COLUMN, " STOP");
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate the appropriate status vector parameter for a gds
|
|
|
|
// call depending on where or not the action has an error clause.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static const TEXT* status_vector(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
return "ISC_STATUS";
|
|
|
|
// return (!action || !action->act_error) ? "ISC_NULL" : "ISC_STATUS";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate substitution text for START_TRANSACTION,
|
|
|
|
// when it's being generated automatically by a compile
|
|
|
|
// call or one of the DDL commands. Be careful not to
|
|
|
|
// continue after errors as that destroys evidence.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void t_start_auto(const gpre_req* request,
|
2003-10-05 08:56:48 +02:00
|
|
|
const TEXT* vector,
|
2003-10-06 11:48:44 +02:00
|
|
|
const act* action,
|
2003-09-10 21:48:53 +02:00
|
|
|
bool test)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
TEXT buffer[256], temp[40];
|
2001-05-23 15:26:42 +02:00
|
|
|
buffer[0] = 0;
|
2003-10-05 08:56:48 +02:00
|
|
|
const TEXT* trname = request_trans(action, request);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
// this is a default transaction, make sure all databases are ready
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
int count = 0;
|
2004-05-24 19:13:38 +02:00
|
|
|
for (DBB db = gpreGlob.isc_databases; db; db = db->dbb_next) {
|
|
|
|
if (gpreGlob.sw_auto)
|
2003-10-06 11:48:44 +02:00
|
|
|
{
|
|
|
|
const TEXT* filename = db->dbb_runtime;
|
|
|
|
if (filename || !(db->dbb_flags & DBB_sqlca)) {
|
2001-05-23 15:26:42 +02:00
|
|
|
if (buffer[0])
|
|
|
|
printa(COLUMN, "IF (%s .EQ. 0 .AND. %s(2) .EQ. 0) THEN",
|
|
|
|
db->dbb_name->sym_string, vector);
|
|
|
|
else
|
|
|
|
printa(COLUMN, "IF (%s .EQ. 0) THEN",
|
|
|
|
db->dbb_name->sym_string);
|
|
|
|
make_ready(db, filename, vector, 0);
|
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
if (buffer[0])
|
|
|
|
strcat(buffer, " .AND. ");
|
|
|
|
sprintf(temp, "%s .NE. 0", db->dbb_name->sym_string);
|
|
|
|
strcat(buffer, temp);
|
|
|
|
}
|
2003-10-06 11:48:44 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
count++;
|
|
|
|
#ifdef hpux
|
|
|
|
printa(COLUMN, "ISC_TEB%d_LEN = 0", count);
|
|
|
|
printa(COLUMN, "ISC_TEB%d_TPB = ISC_NULL", count);
|
|
|
|
printa(COLUMN, "ISC_TEB%d_DBB = ISC_BADDRESS (%s)", count,
|
|
|
|
db->dbb_name->sym_string);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto) {
|
2001-05-23 15:26:42 +02:00
|
|
|
if (!buffer[0])
|
|
|
|
strcpy(buffer, ".TRUE.");
|
|
|
|
if (test)
|
|
|
|
printa(COLUMN, "IF ((%s) .AND. (%s .EQ. 0)) THEN", buffer,
|
|
|
|
trname);
|
|
|
|
else
|
|
|
|
printa(COLUMN, "IF (%s) THEN", buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef hpux
|
|
|
|
printa(COLUMN_INDENT, "CALL ISC_START_MULTIPLE (%s, %s, %s%d%s, ISC_TEB)",
|
|
|
|
vector, trname, I2CONST_1, count, I2CONST_2);
|
|
|
|
#else
|
|
|
|
printa(COLUMN_INDENT, "CALL ISC_START_TRANSACTION (%s, %s, %s%d%s",
|
|
|
|
vector, trname, I2CONST_1, count, I2CONST_2);
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
for (DBB db2 = gpreGlob.isc_databases; db2; db2 = db2->dbb_next)
|
2003-10-06 11:48:44 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(CONTINUE, ", %s, %s0%s, 0",
|
2003-10-06 11:48:44 +02:00
|
|
|
db2->dbb_name->sym_string, I2CONST_1, I2CONST_2);
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(CONTINUE, ")");
|
|
|
|
#endif
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(COLUMN, "END IF");
|
|
|
|
|
|
|
|
status_and_stop(action);
|
|
|
|
}
|
|
|
|
|
2003-02-12 13:51:07 +01:00
|
|
|
#ifdef NOT_USED_OR_REPLACED /* RRK_?: this column stuff was not used in 3.3
|
2001-05-23 15:26:42 +02:00
|
|
|
may be should not bother with it now */
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Align output to a specific column for output. If the
|
|
|
|
// column is negative, don't do anything.
|
|
|
|
//
|
|
|
|
|
|
|
|
static void align( int column)
|
|
|
|
{
|
|
|
|
if (column < 0)
|
|
|
|
return;
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
putc('\n', gpreGlob.out_file);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
int i;
|
2001-05-23 15:26:42 +02:00
|
|
|
for (i = column / 8; i; --i)
|
2004-05-24 19:13:38 +02:00
|
|
|
putc('\t', gpreGlob.out_file);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
for (i = column % 8; i; --i)
|
2004-05-24 19:13:38 +02:00
|
|
|
putc(' ', gpreGlob.out_file);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
#endif /* RRK_?: end of comment out */
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a function call for free standing ANY. Somebody else
|
|
|
|
// will need to generate the actual function.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_any(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s%s_r (&%s, &%s", COLUMN,
|
2001-05-23 15:26:42 +02:00
|
|
|
request->req_handle, request->req_handle, request->req_trans);
|
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_port* port = request->req_vport;
|
2003-10-06 11:48:44 +02:00
|
|
|
if (port) {
|
|
|
|
for (const ref* reference = port->por_references; reference;
|
2001-05-23 15:26:42 +02:00
|
|
|
reference = reference->ref_next)
|
2003-09-10 21:48:53 +02:00
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ", %s", reference->ref_value);
|
2003-09-10 21:48:53 +02:00
|
|
|
}
|
2003-10-06 11:48:44 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ")");
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Zap all know handles.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_clear_handles(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
for (const gpre_req* request = gpreGlob.requests; request; request = request->req_next) {
|
2001-05-23 15:26:42 +02:00
|
|
|
if (!(request->req_flags & REQ_exp_hand))
|
2003-10-16 10:51:06 +02:00
|
|
|
printa("%s%s = 0;", COLUMN, request->req_handle);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-08-09 20:00:14 +02:00
|
|
|
#ifdef NOT_USED_OR_REPLACED
|
2001-05-23 15:26:42 +02:00
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a symbol to ease compatibility with V3.
|
|
|
|
//
|
|
|
|
|
2002-07-06 07:32:02 +02:00
|
|
|
static void gen_compatibility_symbol(
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* symbol,
|
|
|
|
const TEXT* v4_prefix, const TEXT* trailer)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
// CVC: always the same prefix? Function not used, so no problem. :-)
|
2004-05-24 19:13:38 +02:00
|
|
|
const char* v3_prefix = (isLangCpp(gpreGlob.sw_language)) ? "isc_" : "isc_";
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "#define %s%s\t%s%s%s\n", v3_prefix, symbol,
|
2001-05-23 15:26:42 +02:00
|
|
|
v4_prefix, symbol, trailer);
|
|
|
|
}
|
2003-08-09 20:00:14 +02:00
|
|
|
#endif
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Generate a function for free standing ANY or statistical.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_function(const act* function)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
TEXT s[64];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const act* action = (const act*) function->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (action->act_type != ACT_any) {
|
2003-10-15 00:22:32 +02:00
|
|
|
CPR_error("can't generate function");
|
2002-07-06 07:32:02 +02:00
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "static %s_r (request, transaction", request->req_handle);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_port* port = request->req_vport;
|
2003-10-06 11:48:44 +02:00
|
|
|
if (port) {
|
|
|
|
for (const ref* reference = port->por_references; reference;
|
2001-05-23 15:26:42 +02:00
|
|
|
reference = reference->ref_next)
|
2003-09-10 21:48:53 +02:00
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ", %s",
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, reference->ref_source, true));
|
|
|
|
}
|
2003-10-06 11:48:44 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file,
|
2003-03-27 18:15:48 +01:00
|
|
|
")\n isc_req_handle\trequest;\n isc_tr_handle\ttransaction;\n");
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (port)
|
2003-10-06 11:48:44 +02:00
|
|
|
{
|
|
|
|
for (const ref* reference = port->por_references; reference;
|
2003-09-10 21:48:53 +02:00
|
|
|
reference = reference->ref_next)
|
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const gpre_fld* field = reference->ref_field;
|
|
|
|
const TEXT* dtype;
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
switch (field->fld_dtype) {
|
|
|
|
case dtype_short:
|
|
|
|
dtype = "short";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_long:
|
|
|
|
// RRK_?: dtype = DCL_LONG;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_cstring:
|
|
|
|
case dtype_text:
|
|
|
|
dtype = "char*";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_quad:
|
|
|
|
// dtype = DCL_QUAD;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_date:
|
|
|
|
case dtype_blob:
|
|
|
|
dtype = "ISC_QUAD";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_real:
|
|
|
|
dtype = "float";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_double:
|
|
|
|
dtype = "double";
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2003-10-15 00:22:32 +02:00
|
|
|
CPR_error("gen_function: unsupported datatype");
|
2002-07-06 07:32:02 +02:00
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, " %s\t%s;\n", dtype,
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, reference->ref_source, true));
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2003-10-06 11:48:44 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "{\n");
|
2001-05-23 15:26:42 +02:00
|
|
|
for (port = request->req_ports; port; port = port->por_next)
|
|
|
|
make_port(port);
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "\n\n");
|
2001-05-23 15:26:42 +02:00
|
|
|
gen_s_start(action);
|
|
|
|
gen_receive(action, request->req_primary);
|
|
|
|
|
|
|
|
for (port = request->req_ports; port; port = port->por_next)
|
2003-10-06 11:48:44 +02:00
|
|
|
{
|
|
|
|
for (const ref* reference = port->por_references; reference;
|
2003-09-10 21:48:53 +02:00
|
|
|
reference = reference->ref_next)
|
|
|
|
{
|
|
|
|
if (reference->ref_field-> fld_array_info)
|
|
|
|
gen_get_or_put_slice(action, reference, true);
|
|
|
|
}
|
2003-10-06 11:48:44 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
port = request->req_primary;
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "\nreturn %s;\n}\n",
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, port->por_references, true));
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Substitute for a variable reference.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_type(const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
// CVC: If I'm not mistaken, assumes sizeof(long) == sizeof(ref*)
|
2003-10-16 10:51:06 +02:00
|
|
|
printa("%s%ld", COLUMN, action->act_object);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-08-09 20:00:14 +02:00
|
|
|
#ifdef NOT_USED_OR_REPLACED
|
2001-05-23 15:26:42 +02:00
|
|
|
//____________________________________________________________
|
|
|
|
//
|
|
|
|
// Print a fixed string at a particular column.
|
|
|
|
//
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void printb(const TEXT* string, ...)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
va_list ptr;
|
|
|
|
|
2004-05-24 01:28:06 +02:00
|
|
|
va_start(ptr, string);
|
2004-05-24 19:13:38 +02:00
|
|
|
vfprintf(gpreGlob.out_file, string, ptr);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2003-08-09 20:00:14 +02:00
|
|
|
#endif
|
2003-10-05 08:56:48 +02:00
|
|
|
|