--- firebird-1.0.0.796/porting/pyxis/save.c.orig Thu Jan 1 01:00:00 1970 +++ firebird-1.0.0.796/porting/pyxis/save.c Wed Dec 4 23:34:54 2002 @@ -0,0 +1,1388 @@ +/*********** Preprocessed module -- do not edit ***************/ +/*********** Preprocessed module -- do not edit ***************/ +/*********** Preprocessed module -- do not edit ***************/ +/*********** Preprocessed module -- do not edit ***************/ +/*********** Preprocessed module -- do not edit ***************/ +/***************** gpre version LI-T6.2.796 Firebird 1.0 **********************/ +/* + * PROGRAM: PYXIS Form Package + * MODULE: save.e + * DESCRIPTION: Form dump/load code. + * + * 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): ______________________________________. + */ + +#include "../jrd/gds.h" +#include "../pyxis/pyxis.h" + +#define HANDLES 10 +#define PYXIS_RELATION "PYXIS$FORMS" +#define BUF_LEN 256 + +extern PIC PICSTR_analyze(); +extern OBJ PYXIS_create_object(), PYXIS_clone(), PYXIS_get_attribute_value(); +extern ATT PYXIS_get_attribute(), PYXIS_put_attribute(), + PYXIS_find_object(); + +/*DATABASE + DB = STATIC "yachts.lnk";*/ +/**** GDS Preprocessor Definitions ****/ +#ifndef _JRD_IBASE_H_ +#include +#endif + +static ISC_QUAD + isc_blob_null = {0,0}; /* initializer for blobs */ +static long *gds__null = 0; /* dummy status vector */ +static isc_db_handle + DB = 0; /* database handle */ + +static isc_tr_handle + gds__trans = 0; /* default transaction handle */ +static long + isc_status [20], /* status vector */ + isc_status2 [20]; /* status vector */ +static long + isc_array_length, /* array return size */ + SQLCODE; /* SQL status code */ +static char + isc_tpb_0 [4] = {1,9,2,6}; + +static short + isc_1l = 73; +static char + isc_1 [] = { + 4,2,4,0,2,0,9,0,40,32,0,12,0,15,'J',11,'P','Y','X','I','S','$', + 'F','O','R','M','S',0,2,1,25,0,0,0,23,0,10,'P','Y','X','I','S', + '$','F','O','R','M',1,25,0,1,0,23,0,15,'P','Y','X','I','S','$', + 'F','O','R','M','_','N','A','M','E',-1,-1,'L' + }; /* end of blr string for request isc_1 */ + +static short + isc_8l = 161; +static char + isc_8 [] = { + 4,2,4,3,1,0,7,0,4,2,1,0,9,0,4,1,2,0,9,0,7,0,4,0,1,0,40,32,0, + 12,0,2,7,'C',1,'J',11,'P','Y','X','I','S','$','F','O','R','M', + 'S',0,'G',47,23,0,15,'P','Y','X','I','S','$','F','O','R','M', + '_','N','A','M','E',25,0,0,0,-1,2,14,1,2,1,23,0,10,'P','Y','X', + 'I','S','$','F','O','R','M',25,1,0,0,1,21,8,0,1,0,0,0,25,1,1, + 0,-1,17,0,9,13,12,3,18,0,12,2,10,0,1,2,1,25,2,0,0,23,1,10,'P', + 'Y','X','I','S','$','F','O','R','M',-1,-1,-1,14,1,1,21,8,0,0, + 0,0,0,25,1,1,0,-1,-1,'L' + }; /* end of blr string for request isc_8 */ + +static short + isc_21l = 140; +static char + isc_21 [] = { + 4,2,4,0,2,0,40,32,0,7,0,2,7,'C',1,'J',13,'R','D','B','$','R', + 'E','L','A','T','I','O','N','S',0,'G',47,23,0,15,'R','D','B', + '$','S','Y','S','T','E','M','_','F','L','A','G',21,8,0,0,0,0, + 0,'F',1,'H',23,0,17,'R','D','B','$','R','E','L','A','T','I', + 'O','N','_','N','A','M','E',-1,14,0,2,1,23,0,17,'R','D','B', + '$','R','E','L','A','T','I','O','N','_','N','A','M','E',25,0, + 0,0,1,21,8,0,1,0,0,0,25,0,1,0,-1,14,0,1,21,8,0,0,0,0,0,25,0, + 1,0,-1,-1,'L' + }; /* end of blr string for request isc_21 */ + +static short + isc_25l = 358; +static char + isc_25 [] = { + 4,2,4,1,8,0,40,32,0,7,0,40,126,0,40,126,0,7,0,7,0,7,0,7,0,4, + 0,1,0,40,32,0,12,0,2,7,'C',2,'J',19,'R','D','B','$','R','E', + 'L','A','T','I','O','N','_','F','I','E','L','D','S',0,'J',10, + 'R','D','B','$','F','I','E','L','D','S',1,'G',58,47,23,0,17, + 'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A', + 'M','E',25,0,0,0,47,23,0,16,'R','D','B','$','F','I','E','L', + 'D','_','S','O','U','R','C','E',23,1,14,'R','D','B','$','F', + 'I','E','L','D','_','N','A','M','E','F',1,'H',23,0,18,'R','D', + 'B','$','F','I','E','L','D','_','P','O','S','I','T','I','O', + 'N',-1,14,1,2,1,23,0,14,'R','D','B','$','F','I','E','L','D', + '_','N','A','M','E',25,1,0,0,1,21,8,0,1,0,0,0,25,1,1,0,1,23, + 1,15,'R','D','B','$','E','D','I','T','_','S','T','R','I','N', + 'G',25,1,2,0,1,23,0,15,'R','D','B','$','E','D','I','T','_','S', + 'T','R','I','N','G',25,1,3,0,1,23,1,18,'R','D','B','$','S','E', + 'G','M','E','N','T','_','L','E','N','G','T','H',25,1,4,0,1,23, + 1,14,'R','D','B','$','F','I','E','L','D','_','T','Y','P','E', + 25,1,5,0,1,23,1,16,'R','D','B','$','F','I','E','L','D','_','L', + 'E','N','G','T','H',25,1,6,0,1,23,1,15,'R','D','B','$','F','I', + 'E','L','D','_','S','C','A','L','E',25,1,7,0,-1,14,1,1,21,8, + 0,0,0,0,0,25,1,1,0,-1,-1,'L' + }; /* end of blr string for request isc_25 */ + +static short + isc_37l = 113; +static char + isc_37 [] = { + 4,2,4,1,2,0,9,0,7,0,4,0,1,0,40,32,0,12,0,2,7,'C',1,'J',11,'P', + 'Y','X','I','S','$','F','O','R','M','S',0,'G',47,23,0,15,'P', + 'Y','X','I','S','$','F','O','R','M','_','N','A','M','E',25,0, + 0,0,-1,14,1,2,1,23,0,10,'P','Y','X','I','S','$','F','O','R', + 'M',25,1,0,0,1,21,8,0,1,0,0,0,25,1,1,0,-1,14,1,1,21,8,0,0,0, + 0,0,25,1,1,0,-1,-1,'L' + }; /* end of blr string for request isc_37 */ + +static short + isc_46l = 107; +static char + isc_46 [] = { + 4,2,4,0,2,0,40,32,0,7,0,2,7,'C',1,'J',11,'P','Y','X','I','S', + '$','F','O','R','M','S',0,'F',1,'H',23,0,15,'P','Y','X','I', + 'S','$','F','O','R','M','_','N','A','M','E',-1,14,0,2,1,23,0, + 15,'P','Y','X','I','S','$','F','O','R','M','_','N','A','M','E', + 25,0,0,0,1,21,8,0,1,0,0,0,25,0,1,0,-1,14,0,1,21,8,0,0,0,0,0, + 25,0,1,0,-1,-1,'L' + }; /* end of blr string for request isc_46 */ + +static short + isc_50l = 120; +static char + isc_50 [] = { + 4,2,4,3,1,0,7,0,4,2,1,0,7,0,4,1,1,0,7,0,4,0,1,0,40,32,0,12,0, + 2,7,'C',1,'J',11,'P','Y','X','I','S','$','F','O','R','M','S', + 0,'G',47,23,0,15,'P','Y','X','I','S','$','F','O','R','M','_', + 'N','A','M','E',25,0,0,0,-1,2,14,1,2,1,21,8,0,1,0,0,0,25,1,0, + 0,-1,17,0,9,13,12,3,18,0,12,2,5,0,-1,-1,14,1,1,21,8,0,0,0,0, + 0,25,1,0,0,-1,-1,'L' + }; /* end of blr string for request isc_50 */ + +static short + isc_59l = 99; +static char + isc_59 [] = { + 4,2,4,0,1,0,7,0,2,7,'C',1,'J',13,'R','D','B','$','R','E','L', + 'A','T','I','O','N','S',0,'G',47,23,0,17,'R','D','B','$','R', + 'E','L','A','T','I','O','N','_','N','A','M','E',21,14,11,0,'P', + 'Y','X','I','S','$','F','O','R','M','S',-1,14,0,2,1,21,8,0,1, + 0,0,0,25,0,0,0,-1,14,0,1,21,8,0,0,0,0,0,25,0,0,0,-1,-1,'L' + }; /* end of blr string for request isc_59 */ + + +#define gds__blob_null isc_blob_null /* compatibility symbols */ +#define gds__status isc_status +#define gds__status2 isc_status2 +#define gds__array_length isc_array_length +#define gds__count isc_count +#define gds__slack isc_slack +#define gds__utility isc_utility /* end of compatibility symbols */ + +#ifndef isc_version4 + Generate a compile-time error. + Picking up a V3 include file after preprocessing with V4 GPRE. +#endif + +/**** end of GPRE definitions ****/ + + +static SCHAR ddl [] = + { +#include "../pyxis/form_ddl.h" + , 0 }; + +static ATT_N special_attributes [] = + { + att_display_x, + att_display_y, + /* + att_scroll_x, + att_scroll_y, + */ + att_width, + att_height, + att_border, + att_index, + att_inactive, + att_reverse_video, + att_bold, + att_underline, + att_box, + att_blank, + att_insert_right, + att_updatable_flag, + att_wakeup_flag, + att_reverse_for_update, + att_any + }; + + +PYXIS_define_forms_relation (dbb) + SLONG **dbb; +{ + struct { + short isc_61; /* isc_utility */ + } isc_60; +/************************************** + * + * P Y X I S _ d e f i n e _ f o r m s _ r e l a t i o n + * + ************************************** + * + * Functional description + * Check for existence of PYXIS$FORMS relation. If it doesn't + * exist, create it. + * + **************************************/ +SLONG *transaction, *handle, success; +STATUS status_vector [20]; + +DB = *dbb; +transaction = handle = NULL; +success = FALSE; + +/*START_TRANSACTION transaction READ_WRITE;*/ +{ +isc_start_transaction ((long*) 0L, &transaction, (short) 1, &DB, (short) 4, isc_tpb_0); +} + +/*FOR (REQUEST_HANDLE handle TRANSACTION_HANDLE transaction) + X IN RDB$RELATIONS WITH X.RDB$RELATION_NAME EQ "PYXIS$FORMS"*/ +{ +if (!handle) + isc_compile_request ((long*) 0L, &DB, &handle, (short) sizeof (isc_59), (char ISC_FAR *) isc_59); +isc_start_request ((long*) 0L, &handle, &transaction, (short) 0); +while (1) + { + isc_receive ((long*) 0L, &handle, (short) 0, (short) 2, &isc_60, (short) 0); + if (!isc_60.isc_61) break; + success = TRUE; +/*END_FOR;*/ + } +} + +gds__release_request (status_vector, GDS_REF (handle)); + +if (!success && gds__ddl (status_vector, + GDS_REF (DB), + GDS_REF (transaction), + sizeof (ddl), + ddl)) + { + gds__print_status (status_vector); + success = FALSE; + /*ROLLBACK transaction;*/ + { + isc_rollback_transaction ((long*) 0L, &transaction); + } + return FALSE; + } + +/*COMMIT transaction;*/ +{ +isc_commit_transaction ((long*) 0L, &transaction); +} + +return success; +} + +OBJ PYXIS_delete_form (dbb, transaction, form_name) + SLONG **dbb, **transaction; + TEXT *form_name; +{ + struct { + short isc_58; /* isc_utility */ + } isc_57; + struct { + short isc_56; /* isc_utility */ + } isc_55; + struct { + short isc_54; /* isc_utility */ + } isc_53; + struct { + char isc_52 [32]; /* PYXIS$FORM_NAME */ + } isc_51; +/************************************** + * + * P Y X I S _ d e l e t e _ f o r m + * + ************************************** + * + * Functional description + * Delete a form from a database. + * + **************************************/ +int *handle; + +DB = *dbb; +gds__trans = *transaction; +handle = NULL; + +/*FOR (REQUEST_HANDLE handle) + X IN PYXIS$FORMS WITH X.PYXIS$FORM_NAME EQ form_name*/ +{ +if (!handle) + isc_compile_request ((long*) 0L, &DB, &handle, (short) sizeof (isc_50), (char ISC_FAR *) isc_50); +isc_vtov (form_name, isc_51.isc_52, 32); +isc_start_and_send ((long*) 0L, &handle, &gds__trans, (short) 0, (short) 32, &isc_51, (short) 0); +while (1) + { + isc_receive ((long*) 0L, &handle, (short) 1, (short) 2, &isc_53, (short) 0); + if (!isc_53.isc_54) break; + /*ERASE X;*/ + isc_send ((long*) 0L, &handle, (short) 2, (short) 2, &isc_55, (short) 0); +/*END_FOR;*/ + isc_send ((long*) 0L, &handle, (short) 3, (short) 2, &isc_57, (short) 0); + } +} + +gds__release_request (gds__status, GDS_REF (handle)); + +return NULL; +} + +PYXIS_dump (object, ptr) + OBJ object; + TEXT **ptr; +{ +/************************************** + * + * P Y X I S _ d u m p + * + ************************************** + * + * Functional description + * Dump an object into linear form. Assume space is large + * enough. + * + **************************************/ +ATT attribute; +ATT_N *attr_ptr, name; +SLONG value; +TEXT *p, c; + +p = *ptr; + +/* Start by handling ordinary attributes */ + +for (attribute = object->obj_attributes; attribute; + attribute = attribute->att_next) + { + if (attribute->att_type == attype_other) + continue; + sprintf (p, "%d", attribute->att_name); + while (*p) p++; + switch (attribute->att_type) + { + case attype_string: + c = (attribute == object->obj_display_attribute) ? 'D' : 'S'; + sprintf (p, "%c`%s`", c, attribute->att_value); + while (*p) p++; + break; + + case attype_numeric: + sprintf (p, "N%d.", attribute->att_value); + while (*p) p++; + break; + + case attype_object: + *p++ = 'O'; + PYXIS_dump (attribute->att_value, &p); + break; + + default: + BUGCHECK ("DUMP:Unknown attribute type"); + } + } + +/* Next, handle special attributes */ + +for (attr_ptr = special_attributes; *attr_ptr != att_any; attr_ptr++) + if (value = GET_VALUE (object, *attr_ptr)) + { + sprintf (p, "%dN%d.", *attr_ptr, value); + while (*p) p++; + } + +/* Finish up */ + +*p++ = 'E'; +*ptr = p; +} + +PYXIS_dump_length (object) + OBJ object; +{ +/************************************** + * + * P Y X I S _ d u m p _ l e n g t h + * + ************************************** + * + * Functional description + * Compute length of object when dumped. + * + **************************************/ +ATT attribute; +ATT_N *attr_ptr; +TEXT buffer [32]; +USHORT n; +SLONG length; +SLONG value; + +length = 1; + +for (attribute = object->obj_attributes; attribute; + attribute = attribute->att_next) + { + if (attribute->att_type == attype_other) + continue; + sprintf (buffer, "%d", attribute->att_name); + length += strlen (buffer); + switch (attribute->att_type) + { + case attype_string: + length += strlen (attribute->att_value) + 3; + break; + + case attype_numeric: + sprintf (buffer, "N%d.", attribute->att_value); + length += strlen (buffer); + break; + + case attype_object: + length += 1 + PYXIS_dump_length (attribute->att_value); + break; + + default: + BUGCHECK ("Unknown attribute type"); + } + } + +/* Next, handle special attributes */ + +for (attr_ptr = special_attributes; *attr_ptr != att_any; attr_ptr++) + if (value = GET_VALUE (object, *attr_ptr)) + { + sprintf (buffer, "%dN%d.", *attr_ptr, value); + length += strlen (buffer); + } + +return length; +} + +PYXIS_field_defaults (field) + OBJ field; +{ +/************************************** + * + * P Y X I S _ f i e l d _ d e f a u l t s + * + ************************************** + * + * Functional description + * Supply defaults for missing field characteristics. + * + **************************************/ +ATT attribute; +OBJ prototype; +USHORT length, display_length; +TEXT *p, buffer [256], c, *edit_string; +PIC picture; +DSC desc; +STR string; + +PYXIS_delete_named_attribute (field, att_inactive); +picture = NULL; +desc.dsc_length = desc.dsc_dtype = desc.dsc_scale = 0; + +/* If we have a picture string, analyze it */ + +if (edit_string = GET_STRING (field, att_edit_string)) + { + picture = PICSTR_analyze (edit_string, NULL); + switch (picture->pic_type) + { + case pic_alpha: + case pic_text: + desc.dsc_dtype = dtype_text; + desc.dsc_length = picture->pic_length; + break; + + case pic_numeric: + desc.dsc_dtype = dtype_long; + desc.dsc_scale = -picture->pic_fractions; + break; + + case pic_date: + desc.dsc_dtype = dtype_text; + break; + + case pic_float : + c = 'F'; + desc.dsc_dtype = dtype_double; /* No path to this stmt. */ + break; + } + } + +/* Pick up data type info, if supplied directly */ + +if (GET_ATTRIBUTE (field, att_dtype)) + desc.dsc_dtype = GET_VALUE (field, att_dtype); + +if (GET_ATTRIBUTE (field, att_length)) + desc.dsc_length = GET_VALUE (field, att_length); + +if (GET_ATTRIBUTE (field, att_scale)) + desc.dsc_scale = GET_VALUE (field, att_scale); + +/* Cleanup datatype info, as appropriate */ + +switch (desc.dsc_dtype) + { + case dtype_varying: +/* + desc.dsc_length += 2; +*/ + break; + + case dtype_short: + desc.dsc_length = 2; + break; + + case dtype_long: + desc.dsc_length = 4; + break; + + case dtype_real: + desc.dsc_length = 4; + break; + + case dtype_double: +#ifdef VMS + case dtype_d_float: +#endif + desc.dsc_length = 8; + break; + + case dtype_timestamp: + desc.dsc_length = 8; + break; + + case dtype_sql_date: + desc.dsc_length = 4; + break; + + case dtype_sql_time: + desc.dsc_length = 4; + break; + + case dtype_blob: + if (!(display_length = GET_VALUE (field, att_segment_length))) + display_length = 40; + REPLACE_ATTRIBUTE (field, att_width, attype_numeric, display_length + 2); + REPLACE_ATTRIBUTE (field, att_height, attype_numeric, 6); + if (!GET_VALUE (field, att_prototype)) + { + PYXIS_box (field); + prototype = PYXIS_create_object (NULL_PTR, 0); + REPLACE_ATTRIBUTE (prototype, att_width, attype_numeric, display_length); + REPLACE_ATTRIBUTE (prototype, att_reverse_for_update, attype_numeric, TRUE); + REPLACE_ATTRIBUTE (field, att_prototype, attype_object, prototype); + } + return TRUE; + + case dtype_text: + default: + desc.dsc_dtype = dtype_text; + desc.dsc_scale = 0; + if (!desc.dsc_length && + !(desc.dsc_length = GET_VALUE (field, att_width))) + desc.dsc_length = 10; + break; + } + +REPLACE_ATTRIBUTE (field, att_dtype, attype_numeric, desc.dsc_dtype); +REPLACE_ATTRIBUTE (field, att_length, attype_numeric, desc.dsc_length); +if (desc.dsc_scale) + REPLACE_ATTRIBUTE (field, att_scale, attype_numeric, desc.dsc_scale); + +if (!edit_string) + { + edit_string = (TEXT*) PICSTR_default_edit_string (&desc, buffer); + REPLACE_ATTRIBUTE (field, att_edit_string, attype_string, edit_string); + picture = PICSTR_analyze (edit_string, NULL); + } + +REPLACE_ATTRIBUTE (field, att_width, attype_numeric, picture->pic_length); + +if (!(attribute = GET_ATTRIBUTE (field, att_fill_string))) + { + switch (picture->pic_type) + { + case pic_alpha : c = 'X'; break; + case pic_numeric: c = '9'; break; + case pic_date : c = 'D'; break; + case pic_float : c = 'F'; break; + case pic_text : c = 'T'; break; + } + + /* Make up fill string, possibly laboriously */ + + display_length = picture->pic_length; + string = NULL; + + if (display_length < 255) + p = buffer; + else + { + string = (STR) ALLOCDV (type_str, display_length); + p = string->str_data; + } + + do *p++ = c; while (--display_length); + *p = 0; + + if (string) + { + attribute = PUT_ATTRIBUTE (field, att_fill_string, attype_string, string->str_data); + PYXIS_release (string); + } + else + attribute = PUT_ATTRIBUTE (field, att_fill_string, attype_string, buffer); + } + +PYXIS_set_display_attribute (field, attribute); + +if (picture->pic_type == pic_numeric || picture->pic_type == pic_float) + REPLACE_ATTRIBUTE (field, att_insert_right, attype_numeric, TRUE); + +return TRUE; +} + +OBJ PYXIS_forms (dbb, transaction) + SLONG **dbb, **transaction; +{ + struct { + char isc_48 [32]; /* PYXIS$FORM_NAME */ + short isc_49; /* isc_utility */ + } isc_47; +/************************************** + * + * P Y X I S _ f o r m s + * + ************************************** + * + * Functional description + * Get menu all of forms, etc. + * + **************************************/ +OBJ menu, entree; +int *handle; + +DB = *dbb; +gds__trans = *transaction; +menu = PYXIS_create_object (NULL_PTR, 0); +handle = NULL; + +/*FOR (REQUEST_HANDLE handle) + X IN PYXIS$FORMS SORTED BY X.PYXIS$FORM_NAME*/ +{ +if (!handle) + isc_compile_request ((long*) 0L, &DB, &handle, (short) sizeof (isc_46), (char ISC_FAR *) isc_46); +isc_start_request ((long*) 0L, &handle, &gds__trans, (short) 0); +while (1) + { + isc_receive ((long*) 0L, &handle, (short) 0, (short) 34, &isc_47, (short) 0); + if (!isc_47.isc_49) break; + zap_string (/*X.PYXIS$FORM_NAME*/ + isc_47.isc_48); + PYXIS_create_entree (menu, /*X.PYXIS$FORM_NAME*/ + isc_47.isc_48, 0, NULL_PTR); +/*END_FOR;*/ + } +} + +gds__release_request (gds__status, GDS_REF (handle)); + +return menu; +} + +OBJ PYXIS_load (ptr) + TEXT **ptr; +{ +/************************************** + * + * P Y X I S _ l o a d + * + ************************************** + * + * Functional description + * Load an object from linear representation. + * + **************************************/ +OBJ object; +ATT attribute; +ATT_T type; +SLONG value, name, n, negate, buf_size; +TEXT *p, c, verb, *s, *string, *new_buf, *buf_end, buffer[1024]; + +p = *ptr; +object = PYXIS_create_object (NULL_PTR, 0); + +for (;;) + { + name = 0; + while (*p >= '0' && *p <= '9') + name = name * 10 + *p++ - '0'; + switch (verb = *p++) + { + case 'D': + case 'S': + c = *p++; + string = buffer; + buf_size = sizeof(buffer); + buf_end = string + buf_size; + s = string; + while (*p != c) + { + *s++ = *p++; + if (s == buf_end) + { + new_buf = (TEXT*) gds__alloc (2 * buf_size); + memcpy (new_buf, string, buf_size); + if (string != buffer) + gds__free (string); + string = new_buf; + s = string + buf_size; + buf_size = 2 * buf_size; + buf_end = string + buf_size; + } + } + *s = 0; + attribute = PUT_ATTRIBUTE (object, name, attype_string, string); + if (verb == 'D') + PYXIS_set_display_attribute (object, attribute); + p++; + if (string != buffer) + gds__free (string); + break; + + case 'N': + type = attype_numeric; + negate = ((*p == '-') ? (++p, TRUE) : (FALSE)); + n = 0; + while ((c = *p++) != '.') + n = n * 10 + c - '0'; + if (negate) + n = -n; + PUT_ATTRIBUTE (object, name, attype_numeric, n); + break; + + case 'O': + PUT_ATTRIBUTE (object, name, attype_object, PYXIS_load (&p)); + break; + + case 'E': + *ptr = p; + return object; + + default: + BUGCHECK ("Bad form definition"); + } + } +} + +OBJ PYXIS_load_form (status_vector, dbb, transaction, + form_handle, form_name_length, form_name) + int *status_vector; + SLONG **dbb, **transaction; + OBJ *form_handle; + USHORT *form_name_length; + TEXT *form_name; +{ + struct { + ISC_QUAD isc_41; /* PYXIS$FORM */ + short isc_42; /* isc_utility */ + } isc_40; + struct { + char isc_39 [32]; /* PYXIS$FORM_NAME */ + } isc_38; + isc_blob_handle isc_43; /* blob handle */ + char isc_44 [80]; /* blob segment */ + unsigned short isc_45; /* segment length */ +/************************************** + * + * P Y X I S _ l o a d _ f o r m + * + ************************************** + * + * Functional description + * Load a form from a database. + * If the form doesn't exist, return NULL. + * + **************************************/ +USHORT buf_len, out_size, length; +TEXT *ptr, buffer [4096], *buff, *p; +STATUS code; +SLONG temp_vector [20], handle, seg_count, max_seg; +SLONG size; + +DB = *dbb; +gds__trans = *transaction; +*form_handle = NULL; +handle = NULL; +ptr = NULL; + +/* Unless name is zero terminated, copy and terminate form name */ + +if (form_name_length && (length = *form_name_length)) + { + for (p = buffer; length; --length) + *p++ = *form_name++; + *p = 0; + form_name = buffer; + } + +buff = buffer; +buf_len = sizeof (buffer); + +/* Lookup form */ + +/*FOR (REQUEST_HANDLE handle) + X IN PYXIS$FORMS WITH X.PYXIS$FORM_NAME EQ form_name*/ +{ +if (!handle) + isc_compile_request (isc_status, &DB, &handle, (short) sizeof (isc_37), (char ISC_FAR *) isc_37); +isc_43 = 0; +isc_vtov (form_name, isc_38.isc_39, 32); +if (handle) + isc_start_and_send (isc_status, &handle, &gds__trans, (short) 0, (short) 32, &isc_38, (short) 0); +if (!isc_status [1]) { +while (1) + { + isc_receive (isc_status, &handle, (short) 1, (short) 10, &isc_40, (short) 0); + if (!isc_40.isc_42 || isc_status [1]) break; + /*OPEN_BLOB B IN X.PYXIS$FORM*/ + { + { + isc_open_blob2 (isc_status, &DB, &gds__trans, &isc_43, &isc_40.isc_41, (short) 0, (char*) 0); + }; + /*ON_ERROR*/ + if (isc_status [1]) + { + break; + /*END_ERROR;*/ + } + } + + if (gds__blob_size (&/*B*/ + isc_43, &size, &seg_count, &max_seg)) + if (size > sizeof (buffer)) + buff = ptr = (TEXT *) gds__alloc (size + 2); + + while (size > 0) + { + buf_len = MIN (buf_len, size); + if (code = gds__get_segment (gds__status, + GDS_REF (/*B*/ + isc_43), + GDS_REF (out_size), + buf_len, + GDS_VAL (buff))) + + { + + /* segment and segstr_eof codes are benign; + otherwise, we have an internal error */ + + if (code == gds__segstr_eof) + break; + if (code != gds__segment) + BUGCHECK ("Unable to load form"); + } + + buff += out_size; + size -= out_size; + } + /*CLOSE_BLOB B;*/ + { + isc_close_blob ((long*) 0L, &isc_43); + } + if (!(buff = ptr)) + buff = buffer; + *form_handle = PYXIS_load (&buff); + break; +/*END_FOR*/ + } + }; + /*ON_ERROR*/ + if (isc_status [1]) + { + /*END_ERROR;*/ + } + } + +gds__release_request (temp_vector, GDS_REF (handle)); + +/* If something failed and there isn't a status vector, + blow away user */ + +if (!status_vector && !*form_handle) + { + if (gds__status [1]) + gds__print_status (gds__status); + else + { + sprintf (buffer, "form %s not found\n", form_name); + gds__put_error (buffer); + } + exit (FINI_ERROR); + } + +if (ptr) + gds__free (ptr); + +/* Copy status vector */ + +if (status_vector) + MOVP_fast (gds__status, status_vector, 20 * sizeof (STATUS)); + +return (OBJ) gds__status [1]; +} + +OBJ PYXIS_relation_fields (dbb, transaction, relation_name) + SLONG **dbb, **transaction; + TEXT *relation_name; +{ + struct { + char isc_29 [32]; /* RDB$FIELD_NAME */ + short isc_30; /* isc_utility */ + char isc_31 [126]; /* RDB$EDIT_STRING */ + char isc_32 [126]; /* RDB$EDIT_STRING */ + short isc_33; /* RDB$SEGMENT_LENGTH */ + short isc_34; /* RDB$FIELD_TYPE */ + short isc_35; /* RDB$FIELD_LENGTH */ + short isc_36; /* RDB$FIELD_SCALE */ + } isc_28; + struct { + char isc_27 [32]; /* RDB$RELATION_NAME */ + } isc_26; +/************************************** + * + * P Y X I S _ r e l a t i o n _ f i e l d s + * + ************************************** + * + * Functional description + * Create an object containing fields for relation. This is + * NOT formatted as a form. + * + **************************************/ +ATT attribute; +OBJ form, field; +USHORT length, display_length, segment_length; +TEXT *p, c, *edit_string; +int *handle; +DSC desc; + +DB = *dbb; +gds__trans = *transaction; +form = PYXIS_create_object (NULL_PTR, 0); +handle = NULL; + +/*FOR (REQUEST_HANDLE handle) + RFR IN RDB$RELATION_FIELDS CROSS FLD IN RDB$FIELDS WITH + RFR.RDB$RELATION_NAME EQ relation_name AND + RFR.RDB$FIELD_SOURCE EQ FLD.RDB$FIELD_NAME + SORTED BY RFR.RDB$FIELD_POSITION*/ +{ +if (!handle) + isc_compile_request ((long*) 0L, &DB, &handle, (short) sizeof (isc_25), (char ISC_FAR *) isc_25); +isc_vtov (relation_name, isc_26.isc_27, 32); +isc_start_and_send ((long*) 0L, &handle, &gds__trans, (short) 0, (short) 32, &isc_26, (short) 0); +while (1) + { + isc_receive ((long*) 0L, &handle, (short) 1, (short) 294, &isc_28, (short) 0); + if (!isc_28.isc_30) break; + + /* Create field itself */ + + zap_string (/*RFR.RDB$FIELD_NAME*/ + isc_28.isc_29); + field = PYXIS_create_object (/*RFR.RDB$FIELD_NAME*/ + isc_28.isc_29, att_field_name); + + desc.dsc_scale = /*FLD.RDB$FIELD_SCALE*/ + isc_28.isc_36; + desc.dsc_length = /*FLD.RDB$FIELD_LENGTH*/ + isc_28.isc_35; + switch (/*FLD.RDB$FIELD_TYPE*/ + isc_28.isc_34) + { + case blr_text: + desc.dsc_dtype = dtype_text; + break; + + case blr_varying: + desc.dsc_dtype = dtype_varying; + desc.dsc_length += 2; + break; + + case blr_short: + desc.dsc_dtype = dtype_short; + desc.dsc_length = 2; + break; + + case blr_long: + desc.dsc_dtype = dtype_long; + desc.dsc_length = 4; + break; + + case blr_float: + desc.dsc_dtype = dtype_real; + desc.dsc_length = 4; + break; + + case blr_double: +#ifndef VMS + case blr_d_float: +#endif + desc.dsc_dtype = dtype_double; + desc.dsc_length = 8; + break; + +#ifdef VMS + case blr_d_float: + desc.dsc_dtype = dtype_d_float; + desc.dsc_length = 8; + break; +#endif + + case blr_timestamp: + desc.dsc_dtype = dtype_timestamp; + desc.dsc_length = 8; + break; + + case blr_sql_date: + desc.dsc_dtype = dtype_sql_date; + desc.dsc_length = 4; + break; + + case blr_sql_time: + desc.dsc_dtype = dtype_sql_time; + desc.dsc_length = 4; + break; + + case blr_blob: + desc.dsc_dtype = dtype_blob; + desc.dsc_length = 8; + if (segment_length = /*FLD.RDB$SEGMENT_LENGTH*/ + isc_28.isc_33) + PUT_ATTRIBUTE (field, att_segment_length, attype_numeric, segment_length); + break; + } + + PYXIS_put_attribute (field, att_dtype, attype_numeric, desc.dsc_dtype); + PYXIS_put_attribute (field, att_length, attype_numeric, desc.dsc_length); + if (desc.dsc_scale) + PYXIS_put_attribute (field, att_scale, attype_numeric, desc.dsc_scale); + + if (desc.dsc_dtype != dtype_blob) + { + edit_string = /*RFR.RDB$EDIT_STRING*/ + isc_28.isc_32; + if (!*edit_string || *edit_string == ' ') + edit_string = /*FLD.RDB$EDIT_STRING*/ + isc_28.isc_31; + if (*edit_string && *edit_string != ' ') + PUT_ATTRIBUTE (field, att_edit_string, attype_string, edit_string); + } + PUT_ATTRIBUTE (field, att_inactive, attype_numeric, TRUE); + PYXIS_create_entree (form, /*RFR.RDB$FIELD_NAME*/ + isc_28.isc_29, attype_object, field); +/*END_FOR;*/ + } +} + +gds__release_request (gds__status, GDS_REF (handle)); + +return form; +} + + +OBJ PYXIS_relation_form (window, fields) + WIN window; + OBJ fields; +{ +/************************************** + * + * P Y X I S _ r e l a t i o n _ f o r m + * + ************************************** + * + * Functional description + * Create a form from the fields of a relation. + * + **************************************/ +ATT attribute; +OBJ form, field, label; +TEXT *name; + +form = PYXIS_create_object (NULL_PTR, 0); + +for (attribute = NULL; + attribute = PYXIS_find_object (fields, attribute, att_entree, TRUE);) + if (field = GET_OBJECT ((OBJ)attribute->att_value, att_entree_value)) + { + field = PYXIS_clone (field); + if (GET_VALUE (field, att_dtype) != dtype_blob && + GET_VALUE (field, att_datatype) != blr_blob) + REPLACE_ATTRIBUTE (field, att_reverse_for_update, attype_numeric, TRUE); + PYXIS_field_defaults (field); + name = GET_STRING (field, att_field_name); + label = PYXIS_create_object (name, att_literal_string); + PUT_ATTRIBUTE (form, att_label, attype_object, label); + PUT_ATTRIBUTE (form, att_field, attype_object, field); + } + +PYXIS_format_form (form, window->win_width, window->win_height); + +return form; +} + +OBJ PYXIS_relations (dbb, transaction) + SLONG **dbb, **transaction; +{ + struct { + char isc_23 [32]; /* RDB$RELATION_NAME */ + short isc_24; /* isc_utility */ + } isc_22; +/************************************** + * + * P Y X I S _ r e l a t i o n s + * + ************************************** + * + * Functional description + * Get menu all of relations, etc. + * + **************************************/ +OBJ menu, entree; +int *handle; + +DB = *dbb; +gds__trans = *transaction; +menu = PYXIS_create_object (NULL_PTR, 0); +handle = NULL; + +/*FOR (REQUEST_HANDLE handle) + X IN RDB$RELATIONS WITH X.RDB$SYSTEM_FLAG == 0 SORTED BY X.RDB$RELATION_NAME*/ +{ +if (!handle) + isc_compile_request ((long*) 0L, &DB, &handle, (short) sizeof (isc_21), (char ISC_FAR *) isc_21); +isc_start_request ((long*) 0L, &handle, &gds__trans, (short) 0); +while (1) + { + isc_receive ((long*) 0L, &handle, (short) 0, (short) 34, &isc_22, (short) 0); + if (!isc_22.isc_24) break; + zap_string (/*X.RDB$RELATION_NAME*/ + isc_22.isc_23); + PYXIS_create_entree (menu, /*X.RDB$RELATION_NAME*/ + isc_22.isc_23, 0, NULL_PTR); +/*END_FOR;*/ + } +} + +gds__release_request (gds__status, GDS_REF (handle)); + +return menu; +} + + +PYXIS_store_form (dbb, transaction, form_name, form) + SLONG **dbb, **transaction; + TEXT *form_name; + OBJ form; +{ + struct { + ISC_QUAD isc_3; /* PYXIS$FORM */ + char isc_4 [32]; /* PYXIS$FORM_NAME */ + } isc_2; + isc_blob_handle isc_5; /* blob handle */ + char isc_6 [80]; /* blob segment */ + unsigned short isc_7; /* segment length */ + struct { + short isc_17; /* isc_utility */ + } isc_16; + struct { + ISC_QUAD isc_15; /* PYXIS$FORM */ + } isc_14; + struct { + ISC_QUAD isc_12; /* PYXIS$FORM */ + short isc_13; /* isc_utility */ + } isc_11; + struct { + char isc_10 [32]; /* PYXIS$FORM_NAME */ + } isc_9; + isc_blob_handle isc_18; /* blob handle */ + char isc_19 [80]; /* blob segment */ + unsigned short isc_20; /* segment length */ +/************************************** + * + * P Y X I S _ s t o r e _ f o r m + * + ************************************** + * + * Functional description + * Store a form in a database. If the form already exists, replace it. + * + **************************************/ +SLONG size; +TEXT *ptr, buffer [4096], *buff, *p; +int *handle; +USHORT seg_len; + +DB = *dbb; +gds__trans = *transaction; +handle = NULL; +ptr = NULL_PTR; +seg_len = sizeof (buffer); + +/* If local buffer is big enough use it; otherwise allocate buffer big enough */ + +size = PYXIS_dump_length (form); +buff = buffer; + +if (size > sizeof (buffer)) + buff = ptr = (TEXT*) gds__alloc (size); + +/* Linearize the form */ + +p = buff; +PYXIS_dump (form, &p); +size = p - buff; + +/* If form exists, modify it */ + +/*FOR (REQUEST_HANDLE handle) + X IN PYXIS$FORMS WITH X.PYXIS$FORM_NAME EQ form_name*/ +{ +if (!handle) + isc_compile_request ((long*) 0L, &DB, &handle, (short) sizeof (isc_8), (char ISC_FAR *) isc_8); +isc_18 = 0; +isc_vtov (form_name, isc_9.isc_10, 32); +isc_start_and_send ((long*) 0L, &handle, &gds__trans, (short) 0, (short) 32, &isc_9, (short) 0); +while (1) + { + isc_receive ((long*) 0L, &handle, (short) 1, (short) 10, &isc_11, (short) 0); + if (!isc_11.isc_13) break; + /*MODIFY X USING*/ + { + /*CREATE_BLOB B IN X.PYXIS$FORM;*/ + { + isc_create_blob2 ((long*) 0L, &DB, &gds__trans, &isc_18, &isc_11.isc_12, (short) 0, (char*) 0); + } + while (size > 0) + { + seg_len = MIN (seg_len, size); + if (gds__put_segment (gds__status, + GDS_REF (/*B*/ + isc_18), + seg_len, + GDS_VAL (buff))) + break; + buff += seg_len; + size -= seg_len; + } + if (gds__status[1]) + gds__print_status (gds__status); + /*CLOSE_BLOB B;*/ + { + isc_close_blob ((long*) 0L, &isc_18); + } + /*END_MODIFY;*/ + isc_14.isc_15 = isc_11.isc_12; + isc_send ((long*) 0L, &handle, (short) 2, (short) 8, &isc_14, (short) 0); + } + if (ptr) + gds__free (ptr); + gds__release_request (gds__status, GDS_REF (handle)); + return SUCCESS; /* gpre generates a gds__send call after this which + can never be reached; but it's ok */ +/*END_FOR;*/ + isc_send ((long*) 0L, &handle, (short) 3, (short) 2, &isc_16, (short) 0); + } +} + +gds__release_request (gds__status, GDS_REF (handle)); + +/* Form doesn't exist -- store a new record */ + +/*STORE (REQUEST_HANDLE handle) + X IN PYXIS$FORMS*/ +{ + +if (!handle) + isc_compile_request ((long*) 0L, &DB, &handle, (short) sizeof (isc_1), (char ISC_FAR *) isc_1); +isc_5 = 0; +isc_2.isc_3 = isc_blob_null; + strcpy (/*X.PYXIS$FORM_NAME*/ + isc_2.isc_4, form_name); + /*CREATE_BLOB B IN X.PYXIS$FORM;*/ + { + isc_create_blob2 ((long*) 0L, &DB, &gds__trans, &isc_5, &isc_2.isc_3, (short) 0, (char*) 0); + } + while (size > 0) + { + seg_len = MIN (seg_len, size); + if (gds__put_segment (gds__status, + GDS_REF (/*B*/ + isc_5), + seg_len, + GDS_VAL (buff))) + break; + buff += seg_len; + size -= seg_len; + } + if (gds__status[1]) + gds__print_status (gds__status); + /*CLOSE_BLOB B;*/ + { + isc_close_blob ((long*) 0L, &isc_5); + } +/*END_STORE;*/ + +isc_start_and_send ((long*) 0L, &handle, &gds__trans, (short) 0, (short) 40, &isc_2, (short) 0); +} + +gds__release_request (gds__status, GDS_REF (handle)); + +if (ptr) + gds__free (ptr); +} + +static zap_string (string) + TEXT *string; +{ +/************************************** + * + * z a p _ s t r i n g + * + ************************************** + * + * Functional description + * Zap trailing blanks in a string. + * + **************************************/ + +while (*string && *string != ' ') + string++; + +*string = 0; +}