/* * Back up the current position in the current context to the last place * marked by MarkPosContext. */ void GoToMarkContext( void ) /**************************/ { if( !curContextInitialized ) Zoinks(); if( curContext.markPos == -1L ) Zoinks(); SetPosContext( curContext.markPos ); }
/* * Get a character from the current context. Returns a null byte if the * end of the context has been reached. */ int GetCharContext( void ) /************************/ { int ch; if( !curContextInitialized ) Zoinks(); switch( curContext.type ) { case COMMAND_LINE_CONTEXT: /* fall through */ case ENVIRON_VAR_CONTEXT: if( curContext.data - curContext.dataStart < curContext.dataLen ) { ch = *curContext.data; } else { ch = '\0'; } curContext.data++; break; case COMMAND_FILE_CONTEXT: ch = fgetc( curContext.fp ); if( ch == EOF ) ch = '\0'; break; default: Zoinks(); } return( ch ); }
/* * Warn when one of /G3, /G4, /G5, and /GB overrides another. */ static void handle_arch_i86( OPT_STORAGE *cmdOpts, int x ) /********************************************************/ { static int hasBeenCalled; static unsigned prevValue; char oldCpu, newCpu; x = x; oldCpu = 0; newCpu = 0; if( hasBeenCalled ) { if( prevValue != cmdOpts->arch_i86 ) { switch( prevValue ) { /* what is the old CPU? */ case OPT_arch_i86_G3: oldCpu = '3'; break; case OPT_arch_i86_G4: oldCpu = '4'; break; case OPT_arch_i86_G5: oldCpu = '5'; break; case OPT_arch_i86_GB: oldCpu = 'B'; break; default: Zoinks(); } switch( cmdOpts->arch_i86 ) { /* what is the new CPU? */ case OPT_arch_i86_G3: newCpu = '3'; break; case OPT_arch_i86_G4: newCpu = '4'; break; case OPT_arch_i86_G5: newCpu = '5'; break; case OPT_arch_i86_GB: newCpu = 'B'; break; default: Zoinks(); } Warning( "Overriding /G%c with /G%c", oldCpu, newCpu ); } } else { hasBeenCalled = 1; } prevValue = cmdOpts->arch_i86; }
/* * Disable the fuzzy linking module, freeing any allocated resources. */ void FiniFuzzy( void ) /********************/ { if( hashtable == NULL ) Zoinks(); FiniHash( hashtable, 1 ); hashtable = NULL; }
/* * Translate options related to precompiled headers. */ static void precomp_header_opts( struct XlatStatus *status, OPT_STORAGE *cmdOpts, CmdLine *compCmdLine ) /***************************************************************************/ { char * newpath; status = status; if( cmdOpts->Fp ) { newpath = PathConvert( cmdOpts->Fp_value->data, '"' ); AppendFmtCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-fhq=%s", newpath ); } else { switch( cmdOpts->precomp_headers ) { case OPT_precomp_headers_Yc: /* fall through */ case OPT_precomp_headers_Yu: /* fall through */ case OPT_precomp_headers_YX: AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-fhq" ); break; case OPT_precomp_headers_default: break; default: Zoinks(); } } if( cmdOpts->Yd ) { /* done by default */ } }
/* * Warn when one of /MD, /ML, and /MT overrides another. */ static void handle_threads_linking( OPT_STORAGE *cmdOpts, int x ) /***************************************************************/ { static int hasBeenCalled; static unsigned prevValue; char oldType, newType; x = x; oldType = 0; newType = 0; if( hasBeenCalled ) { if( prevValue != cmdOpts->threads_linking ) { switch( prevValue ) { /* what's the old type? */ case OPT_threads_linking_MD: oldType = 'D'; break; case OPT_threads_linking_ML: oldType = 'L'; break; case OPT_threads_linking_MT: oldType = 'T'; break; default: Zoinks(); } switch( cmdOpts->threads_linking ) { /* what's the new type? */ case OPT_threads_linking_MD: newType = 'D'; break; case OPT_threads_linking_ML: newType = 'L'; break; case OPT_threads_linking_MT: newType = 'T'; break; default: Zoinks(); } Warning( "Overriding /M%c with /M%c", oldType, newType ); } } else { hasBeenCalled = 1; } prevValue = cmdOpts->threads_linking; }
/* * Get the current position within the current context. */ int GetPosContext( void ) /***********************/ { if( !curContextInitialized ) Zoinks(); switch( curContext.type ) { case COMMAND_LINE_CONTEXT: /* fall through */ case ENVIRON_VAR_CONTEXT: return( curContext.data - curContext.dataStart ); break; case COMMAND_FILE_CONTEXT: return( ftell( curContext.fp ) ); break; default: Zoinks(); } return( EOF ); /* dummy value so compiler won't complain */ }
/* * Handle one line. Returns 0 if at EOF, and a positive value if there's * more data to handle. */ static int do_line( FILE *infile, FILE *miffile, char *outdir ) /*************************************************************/ { static int curline; char line[1024]; char * p; int numwords; char ** words; struct Alias alias; int count; /*** Prepare the next line ***/ p = fgets( line, 1024, infile ); if( p == NULL ) { if( ferror( infile ) ) { FatalError( "Error reading line %d", curline ); } else if( feof( infile ) ) { return( 0 ); } else { Zoinks(); } } if( line[0] == '#' ) { curline++; return( 2 ); /* skip comment lines */ } /*** Extract the individual words ***/ numwords = parse_words( line, NULL ); if( numwords == -1 ) { FatalError( "Error on line %d", curline ); return( -1 ); } if( numwords == 0 ) { /* skip blank lines */ curline++; return( 2 ); } words = (char **)AllocMem( (numwords+1) * sizeof(char*) ); numwords = parse_words( line, words ); if( numwords < 4 ) { FatalError( "Error on line %d", curline ); return( -1 ); } /*** Construct an Alias structure and create the alias ***/ alias.filename = words[0]; alias.realname = words[1]; alias.aliasname = words[2]; alias.systems = NULL; for( count=3; words[count]!=NULL; count++ ) { /* build system list */ add_system( &alias, words[count] ); } do_alias( miffile, &alias, outdir ); curline++; return( 1 ); }
/* * Pop the top context off the context stack, and make it the current * context. The current context must be closed before calling PopContext. */ void PopContext( void ) /*********************/ { CloseContext(); if( stackItems == 0 ) Zoinks(); memcpy( &curContext, &stack[stackItems-1], sizeof(struct Context) ); stackItems--; curContextInitialized = 1; }
/* * Set the current position within the current context. */ void SetPosContext( int pos ) /***************************/ { if( !curContextInitialized ) Zoinks(); if( pos < 0 ) Zoinks(); switch( curContext.type ) { case COMMAND_LINE_CONTEXT: /* fall through */ case ENVIRON_VAR_CONTEXT: curContext.data = curContext.dataStart + pos; break; case COMMAND_FILE_CONTEXT: fseek( curContext.fp, pos, SEEK_SET ); break; default: Zoinks(); } }
/* * Open a new file context. */ int OpenFileContext( const char *filename ) /*****************************************/ { if( curContextInitialized ) Zoinks(); clear_context( &curContext ); curContext.fp = fopen( filename, "rt" ); if( curContext.fp == NULL ) return( 1 ); curContextInitialized = 1; curContext.type = COMMAND_FILE_CONTEXT; return( 0 ); }
/* * Add one more parameter to the section specified by block. Reallocates * memory if necessary, and does all necessary bookkeeping. The stored * string is generated using the printf-style format string and any * additional parmameters. */ void AppendFmtCmdLine( CmdLine *cmdLine, int section, const char *format, ... ) /*****************************************************************************/ { static char buf[BUFFER_SIZE]; va_list args; /*** Format it, then pass it though to AppendCmdLine ***/ if( section < 0 || section >= cmdLine->numSections ) Zoinks(); va_start( args, format ); vsnprintf( buf, BUFFER_SIZE, format, args ); va_end( args ); AppendCmdLine( cmdLine, section, buf ); }
/* * Open a new environment variable context. */ int OpenEnvironContext( const char *envVar ) /******************************************/ { if( curContextInitialized ) Zoinks(); clear_context( &curContext ); curContext.data = getenv( envVar ); curContext.dataStart = curContext.data; if( curContext.data == NULL ) return( 1 ); curContext.dataLen = strlen( curContext.dataStart ); curContextInitialized = 1; curContext.type = ENVIRON_VAR_CONTEXT; return( 0 ); }
/* * Add one more parameter to the section specified by block. Reallocates * memory if necessary, and does all necessary bookkeeping. */ void AppendCmdLine( CmdLine *cmdLine, int section, const char *parm ) /*******************************************************************/ { /*** Allocate GRANULARITY more elements if we're out of room ***/ if( section < 0 || section >= cmdLine->numSections ) Zoinks(); if( cmdLine[section].curItems+2 > cmdLine[section].maxItems ) { cmdLine[section].args = ReallocMem( cmdLine[section].args, (cmdLine[section].maxItems+GRANULARITY) * sizeof(char*) ); cmdLine[section].maxItems += GRANULARITY; } /*** Store the specified pointer and update curItems ***/ if( parm != NULL ) parm = DupStrMem( parm ); /* copy it */ cmdLine[section].args[ cmdLine[section].curItems ] = (char*)parm; cmdLine[section].args[ cmdLine[section].curItems+1 ] = NULL;/* last one */ cmdLine[section].curItems++; }
/* * Returns the actual name of 'filename', searching 'libpaths' if necessary. * The caller is responsible for freeing the returned memory. If the file * cannot be found, NULL is returned. */ static char *find_file( const char *filename, const char *libpaths[] ) /********************************************************************/ { int rc; unsigned count; char * tryme; size_t len; const char * p; bool hasbackslash; /*** We might not have to go searching for it ***/ rc = access( filename, F_OK ); if( rc == 0 ) { return( DupStrMem( filename ) ); } /*** Not found, so check any directories in 'libpaths' ***/ if( libpaths != NULL ) { for( count=0; libpaths[count]!=NULL; count++ ) { /*** Determine if we need to add a backslash to the path ***/ len = strlen( libpaths[count] ); if( len == 0 ) Zoinks(); p = libpaths[count] + len - 1; if( *p == '\\' ) { hasbackslash = TRUE; } else { hasbackslash = FALSE; } /*** See if the file exists here ***/ len = strlen( libpaths[count] ) + ( hasbackslash ? 0 : 1 ) + strlen( filename ) + 1; tryme = AllocMem( len ); sprintf( tryme, "%s%s%s", libpaths[count], hasbackslash ? "" : "\\", filename ); rc = access( tryme, F_OK ); if( rc == 0 ) { return( tryme ); } else { FreeMem( tryme ); } } } return( NULL ); }
/* * Program entry point. */ int main( int argc, char *argv[] ) /*********************************/ { FILE * infile; FILE * miffile; char * outdir; int alive = 1; int rc; /*** Parse the command line ***/ if( argc != 4 ) { printf( "Usage: ALIASGEN <alias_file> <output_dir\\> <objects_mif_file>\n" ); return( EXIT_FAILURE ); } infile = fopen( argv[1], "rt" ); /* open alias file */ if( infile == NULL ) { FatalError( "Cannot open '%s'.", argv[1] ); } outdir = argv[2]; /* get output directory */ miffile = fopen( argv[3], "wt" ); /* open objects.mif file */ if( miffile == NULL ) { FatalError( "Cannot create '%s'.", argv[3] ); } /*** Handle the alias entries, one by one ***/ while( alive ) { rc = do_line( infile, miffile, outdir ); switch( rc ) { case 0: /* ok, but not done */ alive = 0; break; case 2: /* comment */ break; case 1: /* got one more */ fputc( '.', stdout ); fflush( stdout ); break; default: Zoinks(); break; } } fputc( '\n', stdout ); return( EXIT_SUCCESS ); }
/* * Open a new command line context. */ int OpenCmdLineContext( void ) /****************************/ { int len; if( curContextInitialized ) Zoinks(); clear_context( &curContext ); /*** Make a copy of the command line ***/ len = _bgetcmd( NULL, 0 ) + 1; curContext.dataStart = AllocMem( len ); getcmd( curContext.dataStart ); curContext.data = curContext.dataStart; curContext.dataLen = strlen( curContext.dataStart ); curContextInitialized = 1; curContext.type = COMMAND_LINE_CONTEXT; return( 0 ); }
/* * Close the current context. */ void CloseContext( void ) /***********************/ { if( curContextInitialized ) { switch( curContext.type ) { case COMMAND_LINE_CONTEXT: free( curContext.dataStart ); case ENVIRON_VAR_CONTEXT: break; case COMMAND_FILE_CONTEXT: fclose( curContext.fp ); break; default: Zoinks(); } } curContextInitialized = 0; clear_context( &curContext ); }
/* * Program entry point. */ void main( int argc, char *argv[] ) /*********************************/ { OPT_STORAGE cmdOpts; int itemsParsed; int rc = CVTRES_NOACTION; #ifndef __WATCOMC__ _argc = argc; _argv = argv; #endif /*** Initialize ***/ SetBannerFuncError( BannerMessage ); SetDefaultFile( TYPE_RES_FILE, "res" ); AllowTypeFile( TYPE_RES_FILE, TYPE_INVALID_FILE ); /*** Parse the command line ***/ InitParse( &cmdOpts ); itemsParsed = do_parsing( &cmdOpts ); if( itemsParsed==0 || cmdOpts.help ) { PrintHelpMessage(); exit( EXIT_SUCCESS ); } /*** Do the conversion ***/ rc = res_convert( &cmdOpts ); switch( rc ) { case CVTRES_ERROR: exit( EXIT_FAILURE ); break; case CVTRES_NOACTION: FatalError( "Nothing to do!" ); break; case CVTRES_SUCCESS: FiniParse( &cmdOpts ); exit( EXIT_SUCCESS ); break; default: Zoinks(); } }
/* * Initialize the command line sections. Use AppendCmdLine to insert * an item into any of these sections, and MergeCmdLine to merge them all * together. Valid sections will be in the range [0,sections-1]. */ CmdLine *InitCmdLine( int sections ) /**********************************/ { int count; CmdLine * cmdLine; /*** Allocate the sections ***/ if( sections < 1 ) Zoinks(); cmdLine = AllocMem( sections * sizeof(struct CmdLine) ); cmdLine->numSections = sections; cmdLine->merged = NULL; /*** Initialize each section ***/ for( count=0; count<sections; count++ ) { cmdLine[count].maxItems = GRANULARITY; /* some space to start with */ cmdLine[count].args = AllocMem( cmdLine[count].maxItems * sizeof(char*) ); cmdLine[count].curItems = 0; /* no parameters stored yet */ } return( cmdLine ); }
/* * Program entry point. */ void main( int argc, char *argv[] ) /*********************************/ { OPT_STORAGE cmdOpts; CmdLine * cmdLine; int itemsParsed; int rc = RC_NOACTION; /*** Initialize ***/ SetBannerFuncError( BannerMessage ); cmdLine = InitCmdLine( RC_NUM_SECTIONS ); SetDefaultFile( TYPE_RC_FILE, "rc" ); AllowTypeFile( TYPE_RC_FILE, TYPE_INVALID_FILE ); /*** Parse the command line and translate to Watcom options ***/ InitParse( &cmdOpts ); itemsParsed = do_parsing( &cmdOpts ); if( itemsParsed==0 || cmdOpts.help ) { PrintHelpMessage(); exit( EXIT_SUCCESS ); } OptionsTranslate( &cmdOpts, cmdLine ); /*** Spawn the compiler ***/ rc = res_compile( &cmdOpts, cmdLine ); switch( rc ) { case RC_ERROR: exit( EXIT_FAILURE ); break; case RC_NOACTION: FatalError( "Nothing to do!" ); break; case RC_SUCCESS: FiniParse( &cmdOpts ); exit( EXIT_SUCCESS ); break; default: Zoinks(); } }
/* * Add the specified types to the list of those which are allowed. The * last item must be TYPE_INVALID_FILE. Use TYPE_DEFAULT_FILE to disallow * all file types. Arguments are processed from left to right. */ void AllowTypeFile( int type, ... ) /*********************************/ { va_list args; bool alive = TRUE; int curType; bool gotFirst = FALSE; va_start( args, type ); while( alive ) { if( !gotFirst ) { curType = type; gotFirst = TRUE; } else { curType = va_arg( args, int ); } switch( curType ) { case TYPE_DEFAULT_FILE: allowC = FALSE; allowCPP = FALSE; allowDEF = FALSE; allowOBJ = FALSE; allowLIB = FALSE; allowRC = FALSE; allowRES = FALSE; allowRBJ = FALSE; allowRS = FALSE; allowEXP = FALSE; break; case TYPE_C_FILE: allowC = TRUE; break; case TYPE_CPP_FILE: allowCPP = TRUE; break; case TYPE_DEF_FILE: allowDEF = TRUE; break; case TYPE_OBJ_FILE: allowOBJ = TRUE; break; case TYPE_LIB_FILE: allowLIB = TRUE; break; case TYPE_RC_FILE: allowRC = TRUE; break; case TYPE_RES_FILE: allowRES = TRUE; break; case TYPE_RBJ_FILE: allowRBJ = TRUE; break; case TYPE_RS_FILE: allowRS = TRUE; break; case TYPE_EXP_FILE: allowEXP = TRUE; break; case TYPE_INVALID_FILE: alive = FALSE; break; default: Zoinks(); } } va_end( args ); }
/* * Activate options which have been parsed but not yet turned on. */ static void merge_opts( struct XlatStatus *status, OPT_STORAGE *cmdOpts, CmdLine *compCmdLine, CmdLine *linkCmdLine ) /**********************************************************************/ { char buf[128]; char * macro; /*** Handle /D and /U ***/ for( ;; ) { /* defines */ macro = GetNextDefineMacro(); if( macro == NULL ) break; AppendFmtCmdLine( compCmdLine, CL_C_MACROS_SECTION, "-d%s", macro ); } for( ;; ) { /* undefines */ macro = GetNextUndefineMacro(); if( macro == NULL ) break; AppendFmtCmdLine( compCmdLine, CL_C_MACROS_SECTION, "-u%s", macro ); } /*** Merge optimization options ***/ if( status->opt_od ) { AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-od" ); } else { strcpy( buf, "-o" ); #ifdef __TARGET_386__ if( status->opt_of ) strcat( buf, "f" ); if( status->opt_or ) strcat( buf, "r" ); #endif if( status->opt_oa ) strcat( buf, "a" ); if( status->opt_oi ) strcat( buf, "i" ); if( status->opt_ol ) strcat( buf, "l" ); if( status->opt_ol_plus ) strcat( buf, "l+" ); if( status->opt_om ) strcat( buf, "m" ); if( status->opt_on ) strcat( buf, "n" ); if( status->opt_op ) strcat( buf, "p" ); if( status->opt_os ) strcat( buf, "s" ); if( status->opt_ot ) strcat( buf, "t" ); if( status->opt_ox ) strcat( buf, "x" ); if( strcmp( buf, "-o" ) != 0 ) { AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, buf ); } } /*** Handle debugging options ***/ switch( status->debugLevel ) { case 0: /* no debugging info */ break; case 1: AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-d1" ); break; case 2: if (!cmdOpts->lesswd) { AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-d2" ); } else { AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-d1" ); } break; default: Zoinks(); } if( !status->charTypeUnsigned ) { AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-j" ); } AppendFmtCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-w%d", status->warnLevel ); if( cmdOpts->showwopts ) { AppendCmdLine( linkCmdLine, CL_L_OPTS_SECTION, "/showwopts" ); } if( cmdOpts->noinvoke ) { AppendCmdLine( linkCmdLine, CL_L_OPTS_SECTION, "/noinvoke" ); } if( cmdOpts->nowopts ) { AppendCmdLine( linkCmdLine, CL_L_OPTS_SECTION, "/nowopts" ); } }
/* * Unget a character back into the current context. */ void UngetCharContext( void ) /***************************/ { if( !curContextInitialized ) Zoinks(); SetPosContext( GetPosContext() - 1 ); }
/* * Mark the current position in the current context. Only one mark at a * time is stored; use GoToMarkContext to return to it. */ void MarkPosContext( void ) /*************************/ { if( !curContextInitialized ) Zoinks(); curContext.markPos = GetPosContext(); }
/* * Examine a file's extension to determine what type of file it is. If the * file has no extension, a warning is issued and TYPE_ASSUME_FILE is assumed. */ static int file_type( const char *filename ) /******************************************/ { char * newfilename; char * tempfilename; char ext[_MAX_EXT]; int type; /*** Strip quotes from filename ***/ newfilename = DupStrMem( filename ); if( *newfilename == '"' ) { tempfilename = newfilename + 1; /* skip leading " */ tempfilename[ strlen(tempfilename)-1 ] = '\0'; /* smite trailing " */ } else { tempfilename = newfilename; } _splitpath( tempfilename, NULL, NULL, NULL, ext ); if( allowC && !stricmp( ext, ".c" ) ) { type = TYPE_C_FILE; } else if( allowCPP && !stricmp( ext, ".cc" ) ) { type = TYPE_CPP_FILE; } else if( allowCPP && !stricmp( ext, ".cpp" ) ) { type = TYPE_CPP_FILE; } else if( allowCPP && !stricmp( ext, ".cxx" ) ) { type = TYPE_CPP_FILE; } else if( allowCPP && !stricmp( ext, ".odl" ) ) { type = TYPE_CPP_FILE; } else if( allowCPP && !stricmp( ext, ".idl" ) ) { type = TYPE_CPP_FILE; } else if( allowDEF && !stricmp( ext, ".def" ) ) { type = TYPE_DEF_FILE; } else if( allowOBJ && !stricmp( ext, ".obj" ) ) { type = TYPE_OBJ_FILE; } else if( allowLIB && !stricmp( ext, ".lib" ) ) { type = TYPE_LIB_FILE; } else if( allowRC && !stricmp( ext, ".rc" ) ) { type = TYPE_RC_FILE; } else if( allowRES && !stricmp( ext, ".res" ) ) { type = TYPE_RES_FILE; } else if( allowRBJ && !stricmp( ext, ".rbj" ) ) { type = TYPE_RBJ_FILE; } else if( allowRS && !stricmp( ext, ".rs" ) ) { type = TYPE_RS_FILE; } else if( allowEXP && !stricmp( ext, ".exp" ) ) { type = TYPE_EXP_FILE; } else { if( defaultType == TYPE_INVALID_FILE ) { Zoinks(); } if( languageToForce == FORCE_NONE ) { Warning( "Unrecognized file type '%s' -- %s file assumed", filename, defaultName ); } type = defaultType; } if( type == TYPE_C_FILE && languageToForce == FORCE_CPP_COMPILE ) { type = TYPE_CPP_FILE; } else if( type == TYPE_CPP_FILE && languageToForce == FORCE_C_COMPILE ) { type = TYPE_C_FILE; } FreeMem( newfilename ); return( type ); }
/* * Perform fuzzy matching on the given symbol. If exactly one match is * found, a pointer to the real symbol name (in ' quotes) is returned; * the caller is responsible for freeing this memory. In all other cases, * NULL is returned. */ char *MatchFuzzy( const char *entryname ) /***************************************/ { MatchingInfo info; char * retval; char * tmp; unsigned numfound = 0; ListElem * curelem; if( hashtable == NULL ) Zoinks(); /*** Strip quotes from 'entryname' ***/ tmp = DupStrMem( entryname ); if( *tmp == '\'' ) { info.basename = DupStrMem( tmp + 1 ); info.basename[ strlen(info.basename) - 1 ] = '\0'; FreeMem( tmp ); } else { info.basename = tmp; } /*** Check for an exact match ***/ info.findmode = MATCH_MODE_EXACT; info.found = NULL; WalkBucketHash( hashtable, info.basename, matching_callback, &info ); /*** Check for _symbol ***/ if( info.found == NULL ) { info.findmode = MATCH_MODE_UNDERBAR_SYMBOL; WalkBucketHash( hashtable, info.basename, matching_callback, &info ); } /*** Check for symbol_ ***/ if( info.found == NULL ) { info.findmode = MATCH_MODE_SYMBOL_UNDERBAR; WalkBucketHash( hashtable, info.basename, matching_callback, &info ); } /*** Check for _symbol@number ***/ if( info.found == NULL ) { info.findmode = MATCH_MODE_UNDERBAR_SYMBOL_AT_NUMBER; WalkBucketHash( hashtable, info.basename, matching_callback, &info ); } /*** Count how many matches we got ***/ numfound = 0; curelem = info.found; while( curelem != NULL ) { numfound++; curelem = curelem->next; } /*** If there was more than one match, complain ***/ if( numfound > 1 ) { Warning( "Symbol with entry name %s has %u matching internal names:", entryname, numfound ); curelem = info.found; while( curelem != NULL ) { Information( "%s", curelem->buff ); curelem = curelem->next; } Information( "Symbol will be ignored!" ); } /*** Return an appropriate value ***/ if( numfound == 1 ) { retval = DupQuoteStrMem( info.found->buff, '\'' ); } else { retval = NULL; } free_list( info.found ); return( retval ); }
/* * Check a hash table element during a walk of a hash table bucket. */ static int matching_callback( const void *name_, void *info_ ) /************************************************************/ { const char *name = name_; MatchingInfo *info = info_; char matchstr[MAX_SYMBOL_LEN+1]; bool addit = FALSE; const char * p; ListElem * newelem; ListElem * nextelem; if( name == NULL ) Zoinks(); if( strlen(info->basename)+2 > MAX_SYMBOL_LEN ) Zoinks(); /*** Try to match this symbol ***/ switch( info->findmode ) { case MATCH_MODE_EXACT: if( !strcmp( name, info->basename ) ) { addit = TRUE; } break; case MATCH_MODE_UNDERBAR_SYMBOL: sprintf( matchstr, "_%s", info->basename ); if( !strcmp( name, matchstr ) ) { addit = TRUE; } break; case MATCH_MODE_SYMBOL_UNDERBAR: sprintf( matchstr, "%s_", info->basename ); if( !strcmp( name, matchstr ) ) { addit = TRUE; } break; case MATCH_MODE_UNDERBAR_SYMBOL_AT_NUMBER: sprintf( matchstr, "_%s@", info->basename ); if( strstr( name, matchstr ) == name ) { p = name + strlen( matchstr ); while( isdigit( *p ) ) { p++; } if( *p == '\0' ) { addit = TRUE; } } break; default: Zoinks(); } /*** If it matches, add it to the found list ***/ if( addit ) { nextelem = info->found; newelem = AllocMem( sizeof( ListElem ) + strlen( name ) ); strcpy( newelem->buff, name ); newelem->next = nextelem; info->found = newelem; /*** Keep searching only if multiple matches are possible ***/ if( info->findmode == MATCH_MODE_UNDERBAR_SYMBOL_AT_NUMBER ) { return( 1 ); } else { return( 0 ); } } else { return( 1 ); } }
/* * Compile any C and C++ files. Returns COMPILE_NOACTION if there was no * file to compile, COMPILE_ERROR if the compiler returned a bad status code * or if the compiler could not be spawned, or else COMPILE_SUCCESS if * everything went smoothly. */ static int compile( const OPT_STORAGE *cmdOpts, CmdLine *compCmdLine ) /********************************************************************/ { CmdLine * cloneCmdLine; char ** args = NULL; char * filename; int fileType; char * compiler = NULL; int rc; int alive = 1; int numCompiled = 0; char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; char fullPath[_MAX_PATH]; int count; /*** Process all the source files, in the order they were given ***/ while( alive ) { filename = GetNextFile( &fileType, TYPE_C_FILE, TYPE_CPP_FILE, TYPE_INVALID_FILE ); if( filename == NULL ) break; /*** Prepare to spawn the compiler ***/ cloneCmdLine = CloneCmdLine( compCmdLine ); HandleFileTranslate( filename, cloneCmdLine, NULL ); switch( fileType ) { case TYPE_C_FILE: compiler = C_COMPILER; AppendCmdLine( cloneCmdLine, CL_C_PROGNAME_SECTION, compiler ); AppendCmdLine( cloneCmdLine, CL_C_FILENAMES_SECTION, filename ); if( !cmdOpts->nowopts ) { AppendCmdLine( cloneCmdLine, CL_C_OPTS_SECTION, "-aa" ); } args = MergeCmdLine( cloneCmdLine, CL_C_PROGNAME_SECTION, CL_C_MACROS_SECTION, CL_C_OPTS_SECTION, CL_C_FILENAMES_SECTION, INVALID_MERGE_CMDLINE ); break; case TYPE_CPP_FILE: compiler = CPP_COMPILER; AppendCmdLine( cloneCmdLine, CL_C_PROGNAME_SECTION, compiler ); AppendCmdLine( cloneCmdLine, CL_C_FILENAMES_SECTION, filename ); args = MergeCmdLine( cloneCmdLine, CL_C_PROGNAME_SECTION, CL_C_MACROS_SECTION, CL_C_OPTS_SECTION, CL_C_CPP_OPTS_SECTION, CL_C_FILENAMES_SECTION, INVALID_MERGE_CMDLINE ); break; default: Zoinks(); } /*** Spawn the compiler ***/ _splitpath( filename, drive, dir, fname, ext ); fprintf( stderr, "%s%s\n", fname, ext ); /* print name of file we're compiling */ if( cmdOpts->showwopts ) { for( count=0; args[count]!=NULL; count++ ) { fprintf( stderr, "%s ", args[count] ); } fprintf( stderr, "\n" ); } if( !cmdOpts->noinvoke ) { rc = spawnvp( P_WAIT, compiler, (const char **)args ); if( rc != 0 ) { if( rc == -1 || rc == 255 ) { FatalError( "Unable to execute '%s'", compiler ); } else { return( COMPILE_ERROR ); } } } /*** Add the object file to the linker list, observe -Fo ***/ if( cmdOpts->Fo ) { AddFile( TYPE_OBJ_FILE, PathConvert( cmdOpts->Fo_value->data, '"' ) ); } else { _makepath( fullPath, NULL, NULL, fname, ".obj" ); AddFile( TYPE_OBJ_FILE, fullPath ); } /*** Prepare for the next iteration ***/ DestroyCmdLine( cloneCmdLine ); numCompiled++; } if( numCompiled > 0 ) { return( COMPILE_SUCCESS ); } else { return( COMPILE_NOACTION ); } }
/* * Load a DLL. Returns NULL on failure. */ void *InitDllTool( int whichtool, const DllToolCallbacks *callbacks ) /*******************************************************************/ { DllTool * tool = AllocMem( sizeof( DllTool ) ); unsigned dllversion; IDECallBacks * dllcallbacks; /*** Load the DLL ***/ switch( whichtool ) { case DLLTOOL_WLIB: tool->dllhandle = LoadLibrary( WLIB_DLL_FILENAME ); break; default: Zoinks(); }; if( tool->dllhandle == NULL ) { return( NULL ); } /*** Grab the entry points ***/ tool->getversion = (GetVerFn)GetProcAddress( tool->dllhandle, DLL_GETVER ); tool->initdll = (InitDllFn)GetProcAddress( tool->dllhandle, DLL_INITDLL ); tool->initinfo = (InitInfoFn)GetProcAddress( tool->dllhandle, DLL_INITINFO ); tool->runyourself = (RunSelfFn)GetProcAddress( tool->dllhandle, DLL_RUNSELF ); tool->finidll = (FiniDllFn)GetProcAddress( tool->dllhandle, DLL_FINIDLL ); tool->stoprunning = (StopRunFn)GetProcAddress( tool->dllhandle, DLL_STOPRUN ); if( tool->getversion == NULL || tool->initdll == NULL || tool->runyourself == NULL || tool->finidll == NULL || tool->stoprunning == NULL ) { FreeLibrary( tool->dllhandle ); return( NULL ); } /*** Set up the callbacks ***/ dllversion = tool->getversion(); if( dllversion == 1 ) { memset( &tool->callbacks_ver1, 0, sizeof( IDECallBacks1 ) ); if( callbacks->printmessage != NULL ) { tool->callbacks_ver1.PrintMessage = callbacks->printmessage; } else { tool->callbacks_ver1.PrintMessage = print_message; } if( callbacks->printmessageCRLF != NULL ) { tool->callbacks_ver1.PrintWithCRLF = callbacks->printmessageCRLF; } else { tool->callbacks_ver1.PrintWithCRLF = print_message_crlf; } tool->callbacks_ver1.GetInfo = NULL; tool->callbacks_ver1.RunBatch = NULL; dllcallbacks = (IDECallBacks*) &tool->callbacks_ver1; } else if( dllversion > 1 ) { memset( &tool->callbacks, 0, sizeof( IDECallBacks ) ); if( callbacks->printmessage != NULL ) { tool->callbacks.PrintMessage = callbacks->printmessage; } else { tool->callbacks.PrintMessage = print_message; } if( callbacks->printmessageCRLF != NULL ) { tool->callbacks.PrintWithCRLF = callbacks->printmessageCRLF; } else { tool->callbacks.PrintWithCRLF = print_message_crlf; } if( dllversion == 2 ) { if( callbacks->printwithinfo != NULL ) { tool->callbacks.PrintWithInfo = (IDEMsgInfoFn)callbacks->printwithinfo2; } else { tool->callbacks.PrintWithInfo = (IDEMsgInfoFn)print_with_info2; } } else { /* dllversion >= 3 */ if( callbacks->printwithinfo != NULL ) { tool->callbacks.PrintWithInfo = callbacks->printwithinfo; } else { tool->callbacks.PrintWithInfo = print_with_info; } } tool->callbacks.GetInfo = NULL; tool->callbacks.RunBatch = NULL; tool->callbacks.ProgressMessage = NULL; dllcallbacks = &tool->callbacks; } else { FreeLibrary( tool->dllhandle ); return( NULL ); } /*** Tell the DLL to initialize itself ***/ if( tool->initdll( (IDECBHdl)callbacks->cookie, dllcallbacks, &tool->dllHdl ) ) { FreeLibrary( tool->dllhandle ); return( NULL ); } if( tool->initinfo != NULL ) { memset( &tool->initdata, 0, sizeof( tool->initdata ) ); tool->initdata.ver = IDE_CUR_INFO_VER; tool->initdata.ignore_env = 1; tool->initdata.cmd_line_has_files = 1; tool->initinfo( tool->dllHdl, &tool->initdata ); } return( (void*)tool ); }