/* c4code.c (c)Copyright Sequiter Software Inc., 1990-1994. All rights reserved. */ #include "d4all.h" #ifdef S4TESTING #include #include #include #endif #ifndef S4UNIX #ifdef __TURBOC__ #pragma hdrstop #ifndef __DLL__ #ifndef S4OS2PM extern unsigned _stklen ; #endif #endif #endif #ifdef _MSC_VER #ifndef __DLL__ #include #endif #endif #endif #ifdef S4CBPP #ifdef __cplusplus #include "d4data.hpp" #endif #endif #ifdef S4TESTING int s4test_handle ; #endif char f4memo_null_char = '\0' ; char *expr4buf = 0 ; #ifdef S4OS2 #ifdef S4OS2SEM #include static char sem4mem[20], sem4expr[20] ; static HMTX hmtx4mem, hmtx4expr ; #endif #endif #ifdef __DLL__ #ifdef S4PASCAL typedef char far* LPSTR ; typedef unsigned int HANDLE ; typedef unsigned short WORD ; #define PASCAL _pascal #define S4USE_WEP #endif #ifdef S4WINDOWS #ifdef _MSC_VER #if _MSC_VER != 800 #define S4USE_WEP #endif #else #define S4USE_WEP #endif HINSTANCE cb5inst = NULL; #endif #ifdef S4OS2 ULONG _dllmain (ULONG termflag, HMODULE modhandle) { #ifdef S4OS2SEM int i ; APIRET rc ; time_t t ; #endif if ( termflag == 0 ) { mem4init() ; #ifdef S4OS2SEM strcpy( sem4expr, "\\SEM32\\S4A" ) ; strcpy( sem4mem, "\\SEM32\\S4B" ) ; for ( i = 0 ; i < 100 ; i++ ) { u4delay_sec() ; time( &t ) ; t %= 10000L ; c4ltoa45( t, sem4expr + 10, -4 ) ; c4ltoa45( t, sem4mem + 10, -4 ) ; rc = DosCreateMutexSem( sem4expr, &hmtx4expr, 0, 0 ) ; if ( rc != 0 ) continue ; rc = DosCreateMutexSem( sem4mem, &hmtx4mem, 0, 0 ) ; if ( rc != 0 ) { DosCloseMutexSem( hmtx4expr ) ; continue ; } return 1 ; } #else return 1 ; #endif } else { mem4reset() ; #ifdef S4OS2SEM DosCloseMutexSem( hmtx4mem ) ; DosCloseMutexSem( hmtx4expr ) ; #endif } return 1; } #endif #ifdef S4PASCAL_DOS int far PASCAL LibMain( HANDLE hInstance, WORD wDataSeg, WORD cbHeapSize, LPSTR lpCmdLine ) { mem4init() ; return 1 ; } #endif #ifdef S4WINDOWS #ifndef S4PASCAL_DOS #pragma argsused int far PASCAL LibMain( HINSTANCE hInstance, WORD wDataSeg, WORD cbHeapSize, LPSTR lpCmdLine ) { if( !cb5inst ) cb5inst = hInstance; mem4init() ; return 1 ; } HINSTANCE CALLBACK c4dll_inst( void ) { return cb5inst; } #endif /* S4PASCAL_DOS */ #endif /* S4WINDOWS */ #ifdef S4USE_WEP #pragma argsused int S4FUNCTION WEP( int nParameter ) { mem4reset() ; return 1 ; } #endif #endif /* __DLL__ */ void S4FUNCTION d4init( CODE4 *c4 ) { #ifdef S4OS2SEM #ifdef S4OS2 #ifndef __DLL__ time_t t ; int i ; APIRET rc ; #endif #endif #endif #ifdef S4TESTING int oflag ; #endif if ( c4 == 0 ) #ifdef S4DEBUG e4severe( e4parm, E4_D4INIT ) ; #else return ; #endif #ifdef S4WINDOWS SetHandleCount(40); #endif memset( (void *)c4, 0, sizeof( CODE4 ) ) ; /* if a DLL, can't check the stack length since this is a separate executable */ #ifndef S4WIN32 #ifndef S4WINDOWS #ifndef __DLL__ #ifdef __TURBOC__ #ifndef S4OS2PM if ( _stklen < 5000U ) /* 5000 seems to be an appropriate minimum */ #ifdef S4DEBUG e4severe( e4result, E4_RESULT_STC ) ; #else e4( c4, e4result, E4_RESULT_STC ) ; #endif #endif #endif #endif #ifdef _MSC_VER if ( stackavail() < 5000U ) #ifdef S4DEBUG e4severe( e4result, E4_RESULT_STC ) ; #else e4( c4, e4result, E4_RESULT_STC ) ; #endif #endif #endif #endif c4->debug_int = 0x5281 ; /* Some random value for double checking. */ c4->mem_size_block = 0x400 ; /* 1024 */ c4->mem_size_sort_pool = 0xF000 ; /* 61440 */ c4->mem_size_sort_buffer = 0x1000 ; /* 4096 */ c4->mem_size_buffer = 0x4000 ; /* 16384 */ c4->mem_size_memo = 0x200 ; /* 512 */ c4->mem_size_memo_expr = 0x400 ; /* 1024 */ c4->default_unique_error = r4unique_continue ; #ifndef S4LANGUAGE u4ncpy( c4->date_format, "MM/DD/YY", sizeof(c4->date_format) ) ; #else #ifdef S4GERMAN u4ncpy( c4->date_format, "DD.MM.YY", sizeof(c4->date_format) ) ; #endif #ifdef S4FRENCH u4ncpy( c4->date_format, "MM/DD/YY", sizeof(c4->date_format) ) ; #endif #ifdef S4SWEDISH u4ncpy( c4->date_format, "YYYY-MM-DD", sizeof(c4->date_format) ) ; #endif #ifdef S4FINNISH u4ncpy( c4->date_format, "YYYY-MM-DD", sizeof(c4->date_format) ) ; #endif #ifdef S4NORWEGIAN u4ncpy( c4->date_format, "DD-MM-YYYY", sizeof(c4->date_format) ) ; #endif #endif #ifdef S4CLIPPER c4->numeric_str_len = 17 ; /* default length for clipper numeric keys is 10 */ c4->decimals = 2 ; #endif /* S4CLIPPER */ /* Flags initialization */ c4->go_error = c4->open_error = c4->create_error = c4->tag_name_error = c4->auto_open = c4->field_name_error = c4->safety = c4->skip_error = c4->expr_error = 1 ; c4->lock_attempts = -1 ; /* wait forever */ c4->mem_start_index = c4->mem_expand_index = c4->mem_expand_data = c4->mem_start_data = 5 ; c4->mem_start_block = c4->mem_expand_block = c4->mem_start_tag = c4->mem_expand_tag = 10 ; c4->relate_error = 1 ; c4->do_index_verify = 1 ; #ifndef S4OPTIMIZE_OFF c4->do_opt = 1 ; /* by default do optimization */ c4->optimize = -1 ; /* by default optimize non-shared files */ c4->optimize_write = -1 ; #ifdef S4OS2 c4->mem_start_max = 0xF0000L ; #else #ifdef S4UNIX c4->mem_start_max = 0xF0000L ; #else #ifdef S4WINDOWS c4->mem_start_max = 0xF0000L ; #else c4->mem_start_max = 0x50000L ; #endif /* S4WINDOWS */ #endif #endif #endif /* not S4OPTIMIZE_OFF */ /* set up the semaphores */ #ifdef S4OS2SEM #ifdef S4OS2 #ifndef __DLL__ /* create new ones */ strcpy( sem4expr, "\\SEM32\\S4A" ) ; strcpy( sem4mem, "\\SEM32\\S4B" ) ; for ( i = 0 ; i < 100 ; i++ ) { u4delay_sec() ; time( &t ) ; t %= 10000L ; c4ltoa45( t, sem4expr + 10, -4 ) ; c4ltoa45( t, sem4mem + 10, -4 ) ; rc = DosCreateMutexSem( sem4expr, &hmtx4expr, 0, 0 ) ; if ( rc != 0 ) continue ; rc = DosCreateMutexSem( sem4mem, &hmtx4mem, 0, 0 ) ; if ( rc != 0 ) { DosCloseMutexSem( hmtx4expr ) ; continue ; } break ; } #endif /* make sure created and can open... assign to code_base pointer */ if ( DosOpenMutexSem( sem4expr, &c4->hmtx_expr ) != 0 ) e4( c4, e4info, "OS/2 Semaphore open failed" ) ; if ( DosOpenMutexSem( sem4mem, &c4->hmtx_mem ) != 0 ) e4( c4, e4info, "OS/2 Semaphore open failed" ) ; #endif #endif #ifdef S4TESTING oflag = O_APPEND | O_CREAT | O_RDWR | O_TEXT ; s4test_handle = open("S4TEST.ERR", oflag, S_IWRITE ) ; #endif } /* if do_init is set to 1, d4init() is called on the allocated CODE4 */ CODE4 *S4FUNCTION code4alloc( int do_init ) { CODE4 *c4 ; #ifndef S4CBPP c4 = (CODE4 *)u4alloc( sizeof( CODE4 ) ) ; #else #ifdef __cplusplus c4 = (CODE4 *)u4alloc( sizeof( Code4 ) ) ; #else c4 = (CODE4 *)u4alloc( sizeof( CODE4 ) ) ; #endif #endif if ( c4 == 0 ) return 0 ; if ( do_init == 1 ) d4init( c4 ) ; return c4 ; } int S4FUNCTION d4init_undo( CODE4 *c4 ) { if ( c4 == 0 ) #ifdef S4DEBUG e4severe( e4parm, E4_D4INIT_UNDO ) ; #else return -1 ; #endif #ifdef S4OS2 #ifdef S4OS2SEM DosCloseMutexSem( hmtx4mem ) ; DosCloseMutexSem( hmtx4expr ) ; #endif #endif #ifndef S4OPTIMIZE_OFF d4opt_suspend( c4 ) ; #endif d4close_all( c4 ) ; mem4release( c4->index_memory ) ; c4->index_memory = 0 ; mem4release( c4->bitmap_memory ) ; c4->bitmap_memory = 0 ; mem4release( c4->data_memory ) ; c4->data_memory = 0 ; mem4release( c4->tag_memory ) ; c4->tag_memory = 0 ; mem4release( c4->bitmap_memory ) ; c4->bitmap_memory = 0 ; u4free( c4->expr_work_buf ) ; c4->expr_work_buf = 0 ; c4->expr_buf_len = 0 ; u4free( c4->field_buffer ) ; c4->field_buffer = 0 ; c4->buf_len = 0 ; u4free ( c4->stored_key ) ; c4->stored_key = 0 ; c4->stored_key_len = 0 ; return c4->error_code ; } int S4FUNCTION d4close_all( CODE4 *c4 ) { DATA4 *data_on, *data_next ; int rc ; #ifdef S4VBASIC if ( c4parm_check( c4, 1, E4_D4CLOSE_ALL ) ) return -1 ; #endif /* S4VBASIC */ if ( c4 == 0 ) #ifdef S4DEBUG e4severe( e4parm, E4_D4CLOSE_ALL ) ; #else return -1 ; #endif rc = 0 ; for ( data_next = (DATA4 *)l4first( &c4->data_list ) ; ; ) { data_on = data_next ; if ( !data_on ) break ; data_next = (DATA4 *)l4next( &c4->data_list, data_next ) ; if ( d4close( data_on ) < 0 ) rc = -1 ; } if ( c4->error_code < 0 ) return -1 ; return rc ; } DATA4 *S4FUNCTION d4data( CODE4 *c4, char *alias_name ) { char buf[12] ; DATA4 *data_on ; #ifdef S4DEBUG DATA4 *data_result ; #endif #ifdef S4VBASIC if ( c4parm_check( c4, 1, E4_D4DATA ) ) return 0 ; #endif /* S4VBASIC */ if ( c4 == 0 || alias_name == 0 ) #ifdef S4DEBUG e4severe( e4parm, E4_D4DATA ) ; #else return 0 ; #endif u4ncpy( buf, alias_name, sizeof( buf ) ) ; #ifndef S4UNIX c4upper( buf ) ; #endif data_on = 0 ; #ifdef S4DEBUG data_result = 0 ; #endif for(;;) { data_on = (DATA4 *)l4next( &c4->data_list, data_on ) ; if ( !data_on ) break ; if ( strcmp( buf, data_on->alias ) == 0 ) { #ifdef S4DEBUG if ( data_result != 0 ) e4severe( e4info, E4_INFO_DUP ) ; data_result = data_on ; #else return data_on ; #endif /* S4DEBUG */ } } #ifdef S4DEBUG return data_result ; #else return data_on ; #endif } #ifdef S4FOX #define S4FORMAT 1 #endif #ifdef S4CLIPPER #ifdef S4FORMAT error Choose only one CodeBase index file compatibility option. #endif #define S4FORMAT 2 #endif #ifdef S4MDX #ifdef S4FORMAT error Choose only one CodeBase index file compatibility option. #endif #define S4FORMAT 4 #endif #ifdef S4NDX #ifdef S4FORMAT error Choose only one CodeBase index file compatibility option. #endif #define S4FORMAT 8 #endif #ifndef S4FORMAT error You must define either S4FOX, S4CLIPPER, S4NDX or S4MDX #endif #ifdef S4DLL_BUILD #define S4OPERATING 0x10 #endif #ifdef S4WINDOWS #undef S4OPERATING #define S4OPERATING 0x20 #endif #ifdef S4OS2 #ifdef S4OPERATING error Choose one of CodeBase switches S4DLL/S4WINDOWS, S4OS2, and S4CODE_SCREENS #endif #define S4OPERATING 0x40 #endif #ifdef S4CODE_SCREENS #ifdef S4OPERATING error Choose one of CodeBase switches S4DLL/S4WINDOWS, S4OS2, and S4CODE_SCREENS #endif #define S4OPERATING 0x80 #endif #ifndef S4OPERATING #define S4OPERATING 0 #endif #ifdef S4DEBUG #define S4DEBUG_VAL 0x100 #else #define S4DEBUG_VAL 0 #endif #ifdef S4ERROR_HOOK #define S4ERROR_HOOK_VAL 0x200 #else #define S4ERROR_HOOK_VAL 0 #endif #ifdef S4LOCK_CHECK #define S4LOCK_CHECK_VAL 0x400 #else #define S4LOCK_CHECK_VAL 0 #endif #ifdef S4LOCK_HOOK #define S4LOCK_HOOK_VAL 0x800 #else #define S4LOCK_HOOK_VAL 0 #endif #ifdef S4MAX #define S4MAX_VAL 0x1000 #else #define S4MAX_VAL 0 #endif #ifdef S4MEMO_OFF #define S4MEMO_OFF_VAL 0x2000 #else #define S4MEMO_OFF_VAL 0 #endif #ifdef S4OLD_CODE #define S4OLD_CODE_VAL 0x4000 #else #define S4OLD_CODE_VAL 0 #endif #ifdef S4OPTIMIZE_OFF #define S4OPTIMIZE_OFF_VAL 0x8000 #else #define S4OPTIMIZE_OFF_VAL 0 #endif #ifdef S4SAFE #define S4SAFE_VAL 0x20000 #else #define S4SAFE_VAL 0 #endif #ifdef S4SINGLE #define S4SINGLE_VAL 0x40000 #else #define S4SINGLE_VAL 0 #endif #if S4VERSION != 5104 error Your CodeBase source version does not match your header file version. #endif long S4FUNCTION u4switch() { return (long) ( S4FORMAT + S4OPERATING + S4DEBUG_VAL + S4ERROR_HOOK_VAL + S4LOCK_CHECK_VAL + S4LOCK_HOOK_VAL + S4MAX_VAL + S4MEMO_OFF_VAL + S4OLD_CODE_VAL + S4OPTIMIZE_OFF_VAL + S4SAFE_VAL + S4SINGLE_VAL ) ; } #ifdef S4VB_DOS DATA4 *d4data_v( CODE4 *c4, char *alias ) { return d4data( c4, c4str(alias) ) ; } #endif #ifdef S4DLL_BUILD #ifndef S4PASCAL_DOS /*Structures for CodeControls Functions */ typedef struct ctrl4code_tag { LINK4 link; HINSTANCE hInst; CODE4 *code; int alloc; LIST4 form; }CTRL4CODE; /***************************************************************\ \***************************************************************/ int S4FUNCTION ctrl4addCode(HINSTANCE hInst ); //450 void S4FUNCTION ctrl4codeListInit(void); //451 void S4FUNCTION ctrl4freeCtrlNode(CTRL4CODE *node); void S4FUNCTION ctrl4freeCodeList(void); //452 CTRL4CODE * S4FUNCTION ctrl4getCtrlCode(HINSTANCE hInst); //453 void S4FUNCTION ctrl4initVBX(CODE4 *code,HINSTANCE hInstance,int initialize); //454 void S4FUNCTION ctrl4initVBXUndo(CODE4 *code,HINSTANCE hInstance); //455 /***************************************************************\ * List Containing CODE4 and hInstance * structures for CodeControls \***************************************************************/ LIST4 ctrl4codeListVBX; /***************************************************************\ \***************************************************************/ void S4FUNCTION ctrl4codeListInit(void) { //memset(&ctrl4codeListVBX,0,sizeof(LIST4)); } /***************************************************************\ \***************************************************************/ int S4FUNCTION ctrl4addCode(HINSTANCE hInst ) { CTRL4CODE *node; if(!hInst) return -1; node = (CTRL4CODE *) u4alloc(sizeof(CTRL4CODE)); if(node) { node->hInst = hInst; node->alloc = 1; node->code = NULL; l4add(&ctrl4codeListVBX,node); } return 0; } /***************************************************************\ \***************************************************************/ void S4FUNCTION ctrl4freeCtrlNode(CTRL4CODE *node) { if(node) { l4remove(&ctrl4codeListVBX,node); if(node->code) { d4init_undo(node->code); u4free(node->code); } u4free(node); } } /***************************************************************\ \***************************************************************/ void S4FUNCTION ctrl4freeCodeList(void) { CTRL4CODE *node; for(node = (CTRL4CODE *) l4first(&ctrl4codeListVBX);node != NULL;) { l4remove(&ctrl4codeListVBX,node); if(node->code && node->alloc) { d4init_undo(node->code); u4free(node->code); } u4free(node); node = (CTRL4CODE *) l4next(&ctrl4codeListVBX,node); } } /***************************************************************\ \***************************************************************/ CTRL4CODE * S4FUNCTION ctrl4getCtrlCode(HINSTANCE hInst) { CTRL4CODE *node,*newnode,*returnnode = NULL; if(hInst == 0) return NULL; for(node = (CTRL4CODE *) l4first(&ctrl4codeListVBX);node != NULL;) { if(node->hInst == hInst) { returnnode = node; node = NULL; } else node = (CTRL4CODE *) l4next(&ctrl4codeListVBX,node); } return returnnode; } /***************************************************************\ \***************************************************************/ void S4FUNCTION ctrl4initVBXUndo(CODE4 *code,HINSTANCE hInstance) { CTRL4CODE *node; node = ctrl4getCtrlCode(hInstance); if(node) { if(code != node->code) d4init_undo(code); d4init_undo(node->code); if(node->alloc) { u4free(node->code); } l4remove(&ctrl4codeListVBX,node); u4free(node); } } /***************************************************************\ \***************************************************************/ void S4FUNCTION ctrl4initVBX(CODE4 *code,HINSTANCE hInstance,int initialize) { CODE4 *oldcode; CTRL4CODE *node; int dealloc; if(code) { node = ctrl4getCtrlCode(hInstance); if(!node) { ctrl4addCode(hInstance); node = ctrl4getCtrlCode(hInstance); if(node) node->alloc = 0; } if(node) { if(node->code) { dealloc = 0; if(node->alloc) dealloc = IDYES; else dealloc = MessageBox(0,"Warning! Detected two calls to ctrl4init\nwithout intervening call to ctrl4initUndo!\n\nOk to free previously allocated CODE4 memory ?","Multiple CODE4 Detected",MB_YESNO|MB_TASKMODAL|MB_ICONEXCLAMATION); if(dealloc == IDYES) { oldcode = node->code; ctrl4initVBXUndo(node->code,hInstance); u4free(oldcode); node->code = NULL; } } node->alloc = 0; node->code = code; if(initialize) d4init(code); } } } #endif /* S4PASCAL_DOS */ #endif /* S4DLL_BUILD */