orl_return ElfParseDrectve( char *contents, orl_sec_size len, orl_note_callbacks *cb, void *cookie ) /**************************************************************************************************/ { char *cmd; EatWhite( &contents, &len ); while( len > 0 ) { if( *contents != '-' ) break; // - should be start of token contents++; len--; cmd = contents; contents = pstrncspn( contents, ":", &len); if( contents == NULL ) break; contents++; len--; if( memicmp( cmd, "export", 6 ) == 0 ) { if( ParseExport( &contents, &len, cb, cookie ) != ORL_OKAY ) break; } else if( memicmp( cmd, "defaultlib", 10 ) == 0 ) { if( ParseDefLibEntry( &contents, &len, cb->deflib_fn, cookie ) != ORL_OKAY ) break; } else if( memicmp( cmd, "entry", 5 ) == 0 ) { if( ParseDefLibEntry( &contents, &len, cb->entry_fn, cookie ) != ORL_OKAY ) break; } EatWhite( &contents, &len ); } return( ORL_OKAY ); }
// Used by config file parsing, gets string between a text block void GetTextFromBlock(std::ifstream &file, std::string &text) { std::string tmp; text.erase(0, 1); // Remove [ EatWhite(text); while (file) { std::getline(file, tmp); text += '\n' + EatWhite(tmp); if (text[text.length()-1] == ']') { // Don't use "\]" as exit point(this way we can use a ] in a text block) if ((text.length() > 1) && (text[text.length()-2] == '\\')) text.erase(text.length()-2, 1); else break; } } if (text[text.length()-1] == ']') { text.erase(text.length()-1, 1); // Remove ] EatWhite(text); } }
extern bool InitParsing( void ) /*****************************/ // initialize the parsing stuff, and see if there is anything on the command // line. { CmdFile = MemAlloc( sizeof( cmdfilelist ) ); CmdFile->next = NULL; CmdFile->buffer = MemAlloc( MAX_LINE ); // maximum size of a command line. CmdFile->how = COMMANDLINE; CmdFile->oldhow = COMMANDLINE; CmdFile->where = MIDST; CmdFile->name = NULL; CmdFile->file = NIL_HANDLE; getcmd( CmdFile->buffer ); CmdFile->current = CmdFile->buffer; EatWhite(); return( true ); }
extern void ParseDefFile( void ) /******************************/ // parse a .def file { char hmm; while( CmdFile->where != ENDOFFILE ) { switch( CmdFile->where ) { case MIDST: EatWhite(); hmm = *CmdFile->current; switch( hmm ) { case '\0': if( CmdFile->how == BUFFERED ) { CmdFile->where = ENDOFFILE; break; } // NOTE the fall through. case '\n': if( CmdFile->how == BUFFERED ) { CmdFile->current++; } else { CmdFile->where = ENDOFLINE; } break; case ';': CmdFile->where = ENDOFLINE; // a comment. break; default: // must be a command ProcessDefCommand(); break; } break; case ENDOFLINE: GetNewLine( DEF_SLOT ); break; } } RestoreCmdLine(); }
local void ProcessRecord( // PROCESS A RECORD OF INPUT int kw, // - key-word for record char *record )// - record { SEGMENT *seg; // - current segment switch( kw ) { case KW_SEGMENT: PushSegStack(); switch( ProcessMode ) { case MODE_DELETE: ProcessMode = MODE_SKIPPING; break; case MODE_OUTPUT: SegmentCheck(); break; } break; case KW_ELSESEGMENT: switch( ProcessMode ) { case MODE_DELETE: EatWhite(); if( *Rptr == '\0' ) { ProcessMode = MODE_OUTPUT; } else { SegmentCheck(); } break; case MODE_OUTPUT: ProcessMode = MODE_SKIPPING; break; } break; case KW_ENDSEGMENT: PopSegStack(); break; case KW_KEEP: switch( ProcessMode ) { case MODE_OUTPUT: seg = ScanSegment(); if( seg != NULL ) seg->seg_type = SEG_KEEP; break; } break; case KW_REMOVE: switch( ProcessMode ) { case MODE_OUTPUT: seg = ScanSegment(); if( seg != NULL ) seg->seg_type = SEG_REMOVE; break; } break; case KW_INCLUDE: switch( ProcessMode ) { case MODE_OUTPUT: if( ScanString() ) { OpenFileNormal( Token, "r" ); } else { Error( "Missing or invalid inclusion file" ); } break; } break; case KW_TEXT: switch( ProcessMode ) { case MODE_OUTPUT: OutputString( OutFmt, record ); PutNL(); break; } break; } }
static void GetExport( void ) /***************************/ { char *internal; size_t intlen; char *name; size_t namelen; unsigned long value; unsigned long iopl; bool isresident; bool gottoken; bool gotnodata; size_t toklen; char *command; char *currloc; if( !MakeToken( SEP_NO, true ) ) { Warning( "invalid export name", OPTION_SLOT ); return; } DUPBUF_STACK( name, CmdFile->token, CmdFile->len ); // store it temporarily toklen = namelen = CmdFile->len; internal = NULL; intlen = 0; if( MakeToken( SEP_EQUALS, true ) ) { // got an internal name. DUPBUF_STACK( internal, CmdFile->token, CmdFile->len ); // store it temporarily intlen = CmdFile->len; toklen += intlen + 1; // +1 for = sign. } value = 0xFFFFF; // arbitrary >64K. if( MakeToken( SEP_AT, true ) ) { // got an ordinal. if( !GetNumber( &value ) || value > (64 * 1024UL) ) { Warning( "export ordinal value is invalid", OPTION_SLOT ); return; } else { toklen += 6; // maximum integer length + dot } } isresident = false; EatWhite(); gottoken = MakeToken( SEP_NO, true ); if( gottoken ) { if( CmdFile->len == 12 && memicmp( CmdFile->token, "residentname", 12 ) == 0 ) { isresident = true; gottoken = MakeToken( SEP_NO, true ); toklen += 9; // length of resident + space. } } gotnodata = false; if( gottoken ) { if( memicmp( CmdFile->token, "nodata", 6 ) == 0 ) { gottoken = MakeToken( SEP_NO, true ); gotnodata = true; } } iopl = 1024; // arbitrary > 63 if( gottoken ) { if( !GetNumber( &iopl ) || iopl > 63 ) { Warning( "iopl value is invalid", OPTION_SLOT ); } else { toklen += 3; // maximum iopl length + space. } if( !gotnodata ) { gottoken = MakeToken( SEP_NO, true ); } } if( gottoken && !gotnodata ) { if( memicmp( CmdFile->token, "nodata", 6 ) == 0 ) { gotnodata = true; } else { CmdFile->current = CmdFile->token; // reparse the token later } } toklen += 8; // export keyword + space + nullchar; command = MemAlloc( toklen ); memcpy( command, "export ", 7 ); currloc = command + 7; memcpy( currloc, name, namelen ); currloc += namelen; if( value <= (64*1024UL) ) { // if an ordinal was specified.... *currloc++ = '.'; ultoa( value, currloc, 10 ); while( *currloc != '\0' ) { // find end of string. currloc++; } } if( internal != NULL ) { *currloc++ = '='; memcpy( currloc, internal, intlen ); currloc += intlen; } if( isresident ) { *currloc++ = ' '; memcpy( currloc, "resident", 8 ); currloc += 8; } if( iopl <= 63 ) { *currloc++ = ' '; ultoa( iopl * 2, currloc, 10 ); // convert iopl value to a byte value } else { *currloc = '\0'; } AddCommand( command, OPTION_SLOT, false ); }
extern bool MakeToken( sep_type separator, bool include_fn ) /**********************************************************/ // include_fn == true if '.' and ':' are allowed to be part of the token // (include filename). { int quit; char hmm; char matchchar; int len; bool forcematch; bool hitmatch; EatWhite(); hmm = *CmdFile->current; CmdFile->token = CmdFile->current; if( hmm == '\0' || hmm == '\n' ) { CmdFile->len = 0; return( false ); } matchchar = '\0'; CmdFile->len = 1; // for error reporting. switch( separator ){ case SEP_QUOTE: if( hmm != '\'' && hmm != '"' ) { return( false ); } matchchar = hmm; break; case SEP_AT: if( hmm != '@' ) { return( false ); } break; case SEP_COLON: if( hmm != ':' ) { return( false ); } break; case SEP_EQUALS: if( hmm != '=' ) { return( false ); } break; case SEP_PERIOD: if( hmm != '.' ) { return( false ); } break; default: CmdFile->current--; // no separator wanted. } CmdFile->current++; // skip separator. CmdFile->token = CmdFile->current; hmm = *CmdFile->current; if( hmm == '\0' || hmm == '\n' || hmm == ';' ) { CmdFile->len = 0; return( false ); } len = 0; quit = false; forcematch = (separator == SEP_QUOTE ); hitmatch = false; while( !quit ) { len++; CmdFile->current++; hmm = *CmdFile->current; switch( hmm ) { case '\'': case '"': if( separator == SEP_QUOTE && hmm == matchchar ) { CmdFile->current++; // don't include end quote in next token. hitmatch = true; quit = true; } break; case ')': // Right paren separates only in overlay, left never if( OverlayLevel == 0 ) break; // NOTE: possible fall through case '+': // break a token on any of these. case ',': case ';': case '=': case '@': if( separator == SEP_SPACE ) break; // NOTE: possible fall through case '/': case ' ': case '\t': if( !forcematch ) { quit = true; } break; case '.': case ':': if( !forcematch && !include_fn ) { quit = true; } break; case '\0': case '\r': case '\n': quit = true; break; } } CmdFile->len = len; if( forcematch && !hitmatch ) { return( false ); } return( true ); }