/* * GCI_migrateStreng converts a streng into a GCI_str. No further memory * allocation is done and it is STRONGLY forbidden to use GCI_strfree. * The return value shall be used for further operations. */ static const GCI_str *GCI_migrateStreng( GCI_str *str, const streng *string ) { if ( Str_len( string ) == RX_NO_STRING ) { str->used = str->max = 0; str->val = NULL; } else if ( ( str->val = (char *) Str_val( string ) ) == NULL ) str->used = str->max = 0; else str->used = str->max = (int) Str_len( string ); return str; }
static void tracemsg( tsd_t *TSD ) { streng *message; const streng *msg; msg = errortext( TSD, 0, 3, 0, 0 ); message = Str_makeTSD( 12 + Str_len( msg ) ); Str_catstrTSD( message, " +++ " ); Str_catTSD( message, msg ); printout( TSD, message ); Free_stringTSD( message ); }
void set_trace( tsd_t *TSD, const streng *setting ) { int cptr,error; tra_tsd_t *tt; if ( myisnumber( TSD, setting ) ) { cptr = streng_to_int( TSD, setting, &error ); if ( error ) exiterror( ERR_INVALID_INTEGER, 7, tmpstr_of( TSD, setting ) ); /* * If the number is positive, interactive tracing continues * for the supplied number of clauses, but no pausing is done. * If the number is negative, no trace output is inhibited * (as is the pauses) for the supplied number of clauses. * If the number is zero, this is the same as TRACE OFF */ tt = (tra_tsd_t *)TSD->tra_tsd; if ( cptr == 0 ) { TSD->currlevel->tracestat = 'O'; TSD->systeminfo->interactive = 0; TSD->currlevel->traceint = 0; TSD->trace_stat = TSD->currlevel->tracestat; } else if ( cptr > 0 ) { tt->quiet = 0; tt->intercount = cptr + 1; } else { tt->quiet = 1; tt->intercount = -cptr + 1; } } else { for ( cptr = 0; cptr < Str_len( setting ); cptr++ ) { set_trace_char( TSD, setting->value[cptr] ); if ( rx_isalpha( setting->value[cptr] ) ) return; } } }
void doparse( tsd_t *TSD, const streng *source, cnodeptr thisptr, int caseless ) { int start=0,point=0,length=0, end=0, nextstart=0, solid=0 ; const streng *pattern=NULL ; const streng *xtmp=NULL ; char tch=' ' ; nextstart = 0 ; /* too keep gcc from complaining about uninitialized */ tch = TSD->currlevel->tracestat ; TSD->traceparse = ((tch=='I') || (tch=='R')) ; recurse: /* * Cache the length of source, to avoid chasing ponters later. * Then make pattern default to the nullstring. The nullstring is * so muched used, that we don't want to allocate and deallocate * that all the time. */ length = source->len ; pattern = &nullstring ; /* * There are two main cases, either this is the last pattern, in * which case we use the rest of the string. Or either there is * another pattern further out, in which case we have to find it. * */ if (thisptr->p[1]) { /* * We are not the last pattern, so first find the next pattern. * First cache the type, so we don't chase pointers. There are * two main choises: either seek for a string of some sort, or * use an offset of some sort. */ solid = thisptr->p[1]->type ; if ((solid==X_TPL_MVE)||(solid==X_TPL_VAR)) { /* * The pattern to search for is either a literal string, or it * is the value hold in a variable, set pattern to whatever * it might be. Pattern previous points to a statically * allocated variable, so don't bother to deallocate. */ if (solid==X_TPL_MVE) pattern = thisptr->p[1]->name ; else pattern = handle_var( TSD, thisptr->p[1]->p[0] ) ; /* * Then we must find where in the source string pattern occurs. * If it don't occur there, we use the rest of the string, else * we use the string up to, but not including, the first char * that matched pattern. The 'bmstrstr' returns -1 for not * found, so correct that to rest-of-string. Also note that if * the pattern is the nullstring, it should match the end of * the string. */ if (Str_len(pattern)) { end = bmstrstr( source, start, pattern, caseless ) ; if (end<0) { point = end = length ; nextstart = end ; } else { nextstart = end + Str_len(pattern) ; point = end ; } } else { nextstart = point = end = length ; } /* * While 'end' marks how much to stuff into variables, nextstart * marks where to start the search for the next pattern (if * any). Remember that patterns "eat" up the part of the * parse string that they match. */ /* nextstart = end + Str_len(pattern) ; */ } else { /* * The next pattern to match is not a string to match, but a * positional movement, which will always be numeric, and if * it contains a sign, that should have been stripped off during * parsing. But a variable may be negative, too. */ if (thisptr->p[1]->name) xtmp = thisptr->p[1]->name ; else xtmp = handle_var( TSD, thisptr->p[1]->p[0] ) ; end = streng_to_int( TSD, xtmp, &nextstart ) ; if (nextstart) exiterror( ERR_INVALID_INTEGER, 4, tmpstr_of( TSD, xtmp ) ); /* * Depending on what sort of positional movement, do the right * thing. */ if (solid==X_NEG_OFFS) { /* * If it is a movement backwards, the concept goes something * like move-it-foreward-to-a-backwards-position. That is, * the string to be parsed continues forwards to the end of * the sting and stops there, while the nextposition wraps * round to the start again. * * Anyway, parse all the rest of the sting in this parse, and * start on the specified position for the next parse. */ start = point ; nextstart = point - end ; end = length ; if (nextstart > length) nextstart = length; if (nextstart < 0) nextstart = 0; point = nextstart ; } else if (solid==X_POS_OFFS) { /* * If the movement is forward, it is simpler, just move the * position of both the end of thisptr, and the start of next * to the right point. */ start = point ; nextstart = point + end ; if (nextstart > length) nextstart = length; if (nextstart < 0) nextstart = 0; end = nextstart ; if (end<=start) end = length ; point = nextstart ; } else if (solid==X_ABS_OFFS) { /* * Same applies if the position is absolute, just move it. */ end--; if (end > length) end = length; if (end < 0) /* fixes bug 1107757 */ end = 0; point = nextstart = end; if (end <= start) end = length; } } } else /* * We are last pattern to match, set the end of the string to * be parsed to the rest of the string available. */ end = nextstart = length ; /* * Make sure that we didn't do anything illegal when we pushed * around on the value of end and nextstart. These should have been * set correctly in the statements above. */ assert((0<=nextstart) && (nextstart<=length)) ; /* * Then handle end. It must be _after_ the last character in * the pattern, while it must not be larger than length. */ assert((start <= end) && (end <= length)) ; /* * Now we have marked off an area to be parsed, so call 'doparse3' to * put values into the variables. Note that end is decremented, * since doparse3 expects ptr to last char to use, not ptr to char * after last char to use. */ if (thisptr->p[0]) { doparse3( TSD, thisptr->p[0], source->value+start, end-start); --end; } /* * Then make a tailrecursive call, or rather, simulate one. This * operation will take care of the next set of variables to be * parsed values into. */ if ((thisptr=thisptr->p[2]) != NULL) { start = nextstart ; goto recurse ; } }
int intertrace( tsd_t *TSD ) { streng *str=NULL; int retvalue1,rc; tra_tsd_t *tt; tt = (tra_tsd_t *)TSD->tra_tsd; if ( tt->intercount ) { tt->intercount -= 1; if ( tt->intercount == 0 ) { tt->quiet = 0; tt->traceflag = 0; } else return 0; } if ( tt->traceflag ) return 0; if ( tt->notnow == 1 ) { tt->notnow = 2; return 0; } else if ( tt->notnow == 2 ) { tt->notnow = 0; tracemsg( TSD ); } tt->traceflag = 1; retvalue1 = -1; for ( ; retvalue1 < 0; ) { rc = HOOK_GO_ON; if ( TSD->systeminfo->hooks & HOOK_MASK( HOOK_TRCIN ) ) rc = hookup_input( TSD, HOOK_TRCIN, &str ); if ( rc == HOOK_GO_ON ) str = readkbdline( TSD ); if ( str->len == 0 ) { tt->traceflag = 0; retvalue1 = 0; } if ( ( Str_len( str ) == 1 ) && (str->value[0] == '=' ) ) { tt->traceflag = 0; retvalue1 = 1; } else if ( str->len ) { dointerpret( TSD, str ); if ( !TSD->systeminfo->interactive ) { tt->intercount = tt->quiet = 0; return 0; } if ( tt->intercount ) { if ( tt->quiet ) tt->traceflag = 1; else tt->traceflag = 0; return 0; } } } return retvalue1; }
PFN wrapper_get_addr( const tsd_t *TSD, const struct library *lptr, const streng *name ) { PFN addr; handle_type handle=(handle_type)lptr->handle; char *funcname ; #if defined(DYNAMIC_WIN32) char LoadError[256]; char *entryname; unsigned u; char c; #endif #if defined(DYNAMIC_OS2) char *entryname; unsigned u; char c; ULONG ordinal; APIRET rc=0L; #endif #if defined(DYNAMIC_BEOS) status_t rc=0; #endif #if defined(DYNAMIC_STATIC) int rc=0; #endif #if defined(MODULES_NEED_USCORE) streng *us_func; #endif funcname = str_of( TSD, name ) ; #if defined(DYNAMIC_STATIC) rc = static_dlsym( handle, funcname,(void **)&addr ); if ( rc != 0 ) { char buf[150]; sprintf(buf,"static_dlsym() failed with %d looking for %s", rc, funcname ); set_err_message(TSD, buf, "" ) ; addr = NULL; } #elif defined(DYNAMIC_DLOPEN) # if defined(MODULES_NEED_USCORE) /* * Some platforms need to have an underscore prepended to the function * name to be found in a loadable module. */ FreeTSD( funcname ); us_func = Str_makeTSD( Str_len( name ) + 1 ); memcpy( us_func->value, "_", 1 ); us_func->len = 1; Str_catTSD( us_func, name ); funcname = str_of( TSD, us_func ); Free_stringTSD( us_func ); # endif /* * Note, the following assignment is not allowed by ANSI, but SVR4.2 * includes it as an example, so it is probably safe in this context */ addr = (PFN)(dlsym( handle, funcname )) ; /* deal with, eg 'SysLoadFuncs' when the function is 'sysloadfuncs' or 'SYSLOADFUNCS' */ if (addr == NULL) { mem_upper( funcname, strlen( funcname ) ); addr = (PFN)(dlsym( handle, funcname )) ; if (addr == NULL) { mem_lower( funcname, strlen( funcname ) ); addr = (PFN)(dlsym( handle, funcname )) ; if (addr==NULL) set_err_message( TSD, "dlsym() failed: ", dlerror() ); } } #elif defined(DYNAMIC_HPSHLOAD) { long eaddr ; int rc; if (rc = shl_findsym( &handle, funcname, TYPE_PROCEDURE, &eaddr )) { mem_upper( funcname, strlen( funcname ) ); if (rc = shl_findsym( &handle, funcname, TYPE_PROCEDURE, &eaddr )) { mem_lower( funcname, strlen( funcname ) ); if (rc = shl_findsym( &handle, funcname, TYPE_PROCEDURE, &eaddr )) { addr = NULL ; set_err_message( TSD, "shl_findsym() failed: ", strerror(errno) ); } } } if (!rc) addr = (PFN)eaddr ; } #elif defined(DYNAMIC_AIXLOAD) addr = (PFN)handle ; #elif defined(DYNAMIC_OS2) if ( ( sscanf( funcname, "#%u%c", &u, &c ) == 1 ) && ( u != 0 ) ) { ordinal = (ULONG) u; entryname = NULL; } else { ordinal = 0L; entryname = funcname; } rc = DosQueryProcAddr(handle,ordinal,entryname,&addr); if (rc) { char buf[150]; sprintf(buf,"DosQueryProcAddr() failed with %lu looking for %.90s", (long) rc, funcname ); set_err_message(TSD, buf, "" ) ; } #elif defined(DYNAMIC_WIN32) /* 13/12/1999 JH moved cast, (HMODULE), from second parm to first. Removed * a compiler warning, */ if ( ( sscanf( funcname, "#%u%c", &u, &c ) == 1 ) && ( u != 0 ) && ( u <= 0xFFFF ) ) entryname = (char *) u; else entryname = funcname; addr = (PFN) GetProcAddress( (HMODULE) handle, entryname ); if ( ( addr == NULL ) && ( funcname == entryname ) ) { strlwr(funcname); addr = (PFN)GetProcAddress((HMODULE)handle,funcname); if (addr == NULL) { strupr(funcname); addr = (PFN)GetProcAddress((HMODULE)handle, funcname); } } if (addr == NULL) { char buf[150]; FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), LoadError, 256, NULL ); sprintf( buf, "Failed to find \"%s\" in external library: GetProcAddress() failed: ", funcname ); set_err_message( TSD, buf, LoadError ); } #elif defined(DYNAMIC_BEOS) rc = get_image_symbol(handle,funcname,B_SYMBOL_TYPE_TEXT,(void **)&addr); if (rc == B_BAD_IMAGE_ID) { char buf[150]; sprintf(buf,"get_image_symbol() failed with %d looking for %s", rc, funcname ); set_err_message( TSD, buf, "" ); addr = NULL; } #elif defined(DYNAMIC_SKYOS) fprintf(stderr,"%s %d:\n",__FILE__,__LINE__); addr = (PFN)GetDllFunction( handle, funcname ); if ( addr == NULL ) { char buf[150]; sprintf(buf,"GetDllFunction() failed looking for %s", funcname ); set_err_message( TSD, buf, "" ); addr = NULL; } fprintf(stderr,"%s %d:\n",__FILE__,__LINE__); #endif FreeTSD( funcname ); if (addr) return (PFN)addr ; else return NULL ; }
void *wrapper_load( const tsd_t *TSD, const streng *module ) { handle_type handle=(handle_type)NULL ; #if defined(DYNAMIC_OS2) CHAR LoadError[256]; APIRET rc=0L; #endif #if defined(DYNAMIC_WIN32) char LoadError[256]; #endif #if defined(DYNAMIC_HPSHLOAD) || defined(DYNAMIC_BEOS) char buf[1024]; #endif #ifdef DYNAMIC_SKYOS sDllHandle tmp_handle; #endif char *file_name, *module_name, *udpart, *postfix, *orig_module; orig_module = str_ofTSD( module ); #ifdef DYNLIBLEN module_name = (char *)MallocTSD( Str_len( module ) + strlen(DYNLIBPRE) + strlen(DYNLIBPST) + 1 ) ; strcpy(module_name, DYNLIBPRE ); udpart = module_name + strlen(DYNLIBPRE); memcpy(udpart, module->value, Str_len(module) ); strcpy(udpart + Str_len(module), DYNLIBPST ); file_name = module_name; postfix = udpart + Str_len(module); # if defined(DYNAMIC_HPSHLOAD) file_name = buf; # endif #else file_name = module_name = str_ofTSD(module); #endif #if defined(DYNAMIC_STATIC) handle = static_dlopen( file_name ); if (handle == NULL) { set_err_message(TSD, "static_dlopen() failed loading:", file_name ); handle = (handle_type)NULL; } #elif defined(DYNAMIC_DLOPEN) /* * Try and load the module name exactly as specified (before wrapping it * in lib*.so) */ handle = dlopen( orig_module, RTLD_LAZY ) ; if (handle == NULL) { handle = dlopen( file_name, RTLD_LAZY ) ; /* deal with incorrect case in call */ if (handle == NULL) { mem_lower( udpart, Str_len( module ) ); handle = dlopen(module_name, RTLD_LAZY); if (handle == NULL) { mem_upper( udpart, Str_len( module ) ); handle = dlopen(module_name, RTLD_LAZY); /* * Reset the original module portion of the filename to be * searched again so that any error message returned uses the * original module name */ if ( handle == NULL ) { memcpy(udpart, module->value, Str_len(module) ); handle = dlopen(module_name, RTLD_LAZY); } } } } /* or maybe it's just not there */ if (handle==NULL) { char *msg=NULL; msg = dlerror(); if (msg) set_err_message(TSD, "dlopen() failed: ", msg ) ; else set_err_message(TSD, "", ""); } #elif defined(DYNAMIC_HPSHLOAD) /* * Try and load the module name exactly as specified (before wrapping it * in lib*.sl) */ find_shared_library( TSD, orig_module, "SHLIB_PATH", buf ); handle = shl_load( file_name, BIND_IMMEDIATE | DYNAMIC_PATH, 0L ) ; if (handle == NULL) { find_shared_library(TSD,module_name,"SHLIB_PATH",buf); handle = shl_load( file_name, BIND_IMMEDIATE | DYNAMIC_PATH, 0L ) ; if (handle == NULL) { mem_lower( udpart, Str_len( module ) ); find_shared_library( TSD, module_name, "SHLIB_PATH", buf ); handle = shl_load( file_name, BIND_IMMEDIATE | DYNAMIC_PATH ,0L ) ; if (handle == NULL) { mem_upper( udpart, Str_len( module ) ); find_shared_library( TSD, module_name, "SHLIB_PATH", buf ); handle = shl_load( file_name, BIND_IMMEDIATE | DYNAMIC_PATH ,0L ) ; } } } if (handle==NULL) set_err_message(TSD, "shl_load() failed: ", strerror(errno)) ; #elif defined(DYNAMIC_AIXLOAD) /* * Try and load the module name exactly as specified (before wrapping it * in lib*.a) */ handle = load( orig_module, 1, NULL ) ; if ( handle == NULL ) { handle = load( file_name, 1, NULL ) ; if ( handle == NULL ) { set_err_message(TSD, "load() failed: ", strerror( errno )) ; } else { int rc=loadbind( 0, (void *)wrapper_dummy_for_aix, (void *)handle ) ; if (rc) { handle = NULL ; set_err_message(TSD, "loadbind() failed: ", strerror( errno )) ; } } #elif defined(DYNAMIC_OS2) rc = DosLoadModule( LoadError, sizeof(LoadError), file_name, &handle ) ; if (rc) { set_err_message(TSD, "DosLoadModule() unable to load DLL: ", LoadError); handle = (handle_type)NULL; } #elif defined(DYNAMIC_WIN32) handle = LoadLibrary( file_name ) ; if (handle==NULL) { char buf[150]; FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), LoadError, 256, NULL ) ; sprintf( buf, "Failed to load \"%s\" library: LoadLibrary() failed: ", file_name ); set_err_message(TSD, buf, LoadError); } #elif defined(DYNAMIC_BEOS) handle = load_add_on( orig_module ); if (handle < B_NO_ERROR) { handle = load_add_on( file_name ); if (handle < B_NO_ERROR) { sprintf( buf, "load_add_on() failed loading \"%s\" with error:", file_name ); set_err_message(TSD, buf, strerror( handle ) ); handle = (handle_type)NULL; } } #elif defined(DYNAMIC_SKYOS) handle = (handle_type)MallocTSD( sizeof( sDllHandle ) ); /* * Don't try and load the module without the trimmings. * You get a binary popup window otherwise! */ fprintf(stderr,"%s %d %x %s:\n",__FILE__,__LINE__,handle,file_name); if ( DllLoad( file_name, &tmp_handle ) != 0 ) { char buf[150]; sprintf( buf, "Failed to load \"%s\" library: DllLoad() failed: ", file_name ); set_err_message(TSD, buf, strerror( errno ) ); FreeTSD( handle ); handle = (handle_type)NULL; } fprintf(stderr,"%s %d:\n",__FILE__,__LINE__); memcpy( handle, &tmp_handle, sizeof( sDllHandle ) ); fprintf(stderr,"%s %d:\n",__FILE__,__LINE__); #endif FreeTSD( module_name ); FreeTSD( orig_module ); return (void *)handle ; } void wrapper_unload( const tsd_t *TSD, void *libhandle ) { #ifdef DYNAMIC_STATIC libhandle = libhandle; #elif defined(DYNAMIC_DLOPEN) dlclose((handle_type) libhandle); #elif defined(DYNAMIC_HPSHLOAD) shl_unload((handle_type) libhandle); #elif defined(DYNAMIC_AIXLOAD) unload((handle_type) libhandle); #elif defined(DYNAMIC_OS2) DosFreeModule((handle_type) libhandle); #elif defined(DYNAMIC_WIN32) FreeLibrary((handle_type) libhandle); #elif defined(DYNAMIC_BEOS) unload_add_on((handle_type) libhandle); #elif defined(DYNAMIC_SKYOS) fprintf(stderr,"%s %d:\n",__FILE__,__LINE__); FreeTSD( libhandle ); #else (libhandle = libhandle); #endif }
/* get the next line of input, normalize end of line termination (i.e. convert "\r", "\r\n" and "\n\r" to "\n" Calls the new_line_cb call back and returns the pointer to the null-terminated text data in Str *line, including the final "\n". Returns NULL on end of file. */ char *SrcFile_getline( SrcFile *self ) { int c, c1; bool found_newline; char *line; /* clear result string */ Str_clear( self->line ); /* check for line stack */ if ( ! List_empty( self->line_stack ) ) { line = List_pop( self->line_stack ); /* we own the string now and need to release memory */ Str_set( self->line, line ); m_free( line ); /* dont increment line number as we are still on same file input line */ return Str_data(self->line); } /* check for EOF condition */ if ( self->file == NULL ) return NULL; /* read characters */ found_newline = false; while ( ! found_newline && ( c = getc( self->file ) ) != EOF ) { switch ( c ) { case '\r': case '\n': c1 = getc( self->file ); if ( ( c1 == '\r' || c1 == '\n' ) && /* next char also newline */ c1 != c ) /* "\r\n" or "\n\r" */ { /* c1 will be discarded */ } else /* not composite newline - push back */ { if ( c1 != EOF ) { ungetc( c1, self->file ); /* push back except EOF */ } } /* normalize newline and fall through to default */ found_newline = true; c = '\n'; default: Str_append_char( self->line, c ); } } /* terminate string if needed */ if ( Str_len(self->line) > 0 && ! found_newline ) Str_append_char( self->line, '\n' ); /* signal new line, even empty one, to show end line in list */ self->line_nr += self->line_inc; call_new_line_cb( self->line_filename, self->line_nr, Str_data(self->line) ); /* check for end of file even if EOF found, we need to return any chars in line first */ if ( Str_len(self->line) > 0 ) { return Str_data(self->line); } else { /* EOF - close file */ xfclose( self->file ); /* close input */ self->file = NULL; // call_new_line_cb( NULL, 0, NULL ); return NULL; /* EOF */ } }