extern void do_sharp (void) { char *w; char c; w = read_ctrl(); if (strcmp(w, "ifdef") == 0) { do_ifdef(1); } else if (strcmp(w, "ifndef") == 0) { do_ifndef(1); } else if (strcmp(w, "if") == 0) { do_if(1); } else if (strcmp(w, "else") == 0) { do_else(1); } else if (strcmp(w, "elif") == 0) { do_elif(1); } else if (strcmp(w, "endif") == 0) { do_endif(1); } else if (strcmp(w, "include") == 0) { do_include(1); } else if (strcmp(w, "define") == 0) { do_define(1, 0); } else if (strcmp(w, "undef") == 0) { do_undef(1); } else if (strcmp(w, "line") == 0) { do_line(); } else if (strcmp(w, "pragma") == 0) { do_pragma(); } else if (strcmp(w, "") == 0) {} else { int isnull; isnull = 0; if (strcmp(w, "") == 0) { c = Get(); if (c != '\n') { Push(c); } else { isnull = 1; } } if (!isnull && !in_false_if()) { err_head(); fprintf(stderr, "unknown control `%s'\n", w); flush_sharp_line(); } } maybe_print('\n'); os_free(w); }
bool Parser::SM_Run() { FILE *out_fp = included_files.top()->ofile; const char *pos; TRI_STATE result = TSV_0; const char *output = pline.from.c_str(); sym_t preprocessor; CC_STRING expanded_line; do { pos = pline.parsed.c_str(); preprocessor = GetPreprocessor(pos, &pos); if(preprocessor != pline.pp_id || (pline.content != -1 && pline.content + pline.parsed.c_str() != pos) ) { fprintf(stderr, "%s:%zu\n", dv_current_file, dv_current_line); fprintf(stderr, " (%d) %s\n", pline.content, pline.parsed.c_str()); fprintf(stderr, " %d vs %d\n", preprocessor, pline.pp_id); exit(1); } } while(0); pos = pline.parsed.c_str() + pline.content; dv_current_file = GetCurrentFileName().c_str(); dv_current_line = GetCurrentLineNumber(); // GDB_TRAP2(strstr(dv_current_file,"makeint.h"), (dv_current_line==30)); // GDB_TRAP2(strstr(dv_current_file,"/usr/include/features.h"), dv_current_line==131); switch(pline.pp_id) { case SSID_SHARP_IF: if( superior_conditional_value(true) != TSV_0 ) result = (TRI_STATE) Compute(pos); goto handle_if_branch; case SSID_SHARP_IFNDEF: if( superior_conditional_value(true) != TSV_0 ) result = (TRI_STATE) CheckSymbolDefined(pos, true, NULL); goto handle_if_branch; case SSID_SHARP_IFDEF: if( superior_conditional_value(true) != TSV_0 ) result = (TRI_STATE) CheckSymbolDefined(pos, false, NULL); handle_if_branch: if( result == TSV_X ) { if( gvar_preprocess_mode ) { if(errmsg.isnull()) errmsg = "Error on processing conditional"; goto done; } } conditionals.push(new CConditionalChain()); upper_chain()->enter_if(result); upper_chain()->filename = dv_current_file; upper_chain()->line = dv_current_line; if(eval_current_conditional() != TSV_X) output = NULL; included_files.top()->add_if(result); break; case SSID_SHARP_ELIF: if( superior_conditional_value(false) == TSV_0 ) { included_files.top()->add_elif(false); goto done; } if( upper_chain()->has_true() ) { upper_chain()->enter_elif(TSV_0); included_files.top()->add_elif(false); goto done; } result = (TRI_STATE) Compute(pos); if( gvar_preprocess_mode && result == TSV_X) goto done; /* * Transformation on the condition of: * * 1) #if 0 * #elif X --> #if X * * 2) #elif X * #elif 1 --> #else */ if( eval_current_conditional() == TSV_0 ) { if(result == TSV_X) { pline.to = do_elif(1); output = pline.to.c_str(); } else output = NULL; } else { if(result == TSV_1) { pline.to = do_elif(2); output = pline.to.c_str(); } else if(result == TSV_0) output = NULL; } upper_chain()->enter_elif(result); included_files.top()->add_elif(result); break; case SSID_SHARP_ELSE: if( superior_conditional_value(false) == TSV_0 ) { included_files.top()->add_else(false); goto done; } result = upper_chain()->enter_else(); included_files.top()->add_else(result); if( eval_current_conditional() != TSV_X ) output = NULL; break; case SSID_SHARP_ENDIF: included_files.top()->add_endif(); CConditionalChain *c; if( ! upper_chain()->keep_endif() ) output = NULL; if( conditionals.size() == 0 ) { errmsg = "Unmatched #endif"; goto done; } conditionals.pop(c); delete c; break; default: if(eval_current_conditional() == TSV_0) goto done; if(eval_current_conditional() == TSV_X) goto print_and_exit; switch(pline.pp_id) { case SSID_SHARP_DEFINE: if(!do_define(pos)) goto error_out; break; case SSID_SHARP_UNDEF: handle_undef(intab, pos); break; case SSID_SHARP_INCLUDE: case SSID_SHARP_INCLUDE_NEXT: if( gvar_preprocess_mode ) do_include(pline.pp_id, pos, &output); break; default: if(gvar_expand_macros) { pos = pline.parsed.c_str(); expanded_line = ExpandLine(intab, false, pos, errmsg); if(!errmsg.isnull()) goto error_out; if(included_files.size() == 1) { expanded_line += '\n'; output = expanded_line.c_str(); } } } } print_and_exit: if( out_fp != NULL && output != NULL ) fprintf(out_fp, "%s", output); done: pline.comment_start = -1; if(gvar_preprocess_mode && GetError()) { IncludedFile *tmp; CC_STRING pmsg, ts; while(included_files.size() > 0) { included_files.pop(tmp); ts.Format(" %s:%u\n", tmp->ifile->name.c_str(), tmp->ifile->line); pmsg += ts; } if( !pmsg.isnull() ) { errmsg = pmsg + errmsg; } } return gvar_preprocess_mode ? (GetError() == NULL) : true; error_out: return false; }
static Token next_token (void) { Token token; restart: outbuffer_off(); outbuffer_on(); token.startindex = out.buffindex; { int c = next_char(); switch (c) { case EOF: /* EOF */ token.type = eof; goto done; case ' ': case '\v': case '\t': case '\n': /* whitespace, ignore */ goto restart; case '\\': if (peek_char()=='\n') { /* backslash newline, ignore */ next_char(); goto restart; } goto separator; case '/': if (peek_char() == '*') { /* Comment */ next_char(); while (1) { c = next_char(); if (c==EOF) { fprintf(stderr,"Unfinished comment\n"); break; } if ((c=='*') && (peek_char()=='/')) { next_char(); break; } } goto restart; } goto separator; case '*': if (peek_char() == '/') fprintf(stderr,"End of comment outside comment in line %lu\n",input_line); goto separator; case '#': /* preprocessor directive */ { char* line = next_line(); if (line) { char* old_line = line; line = concat2("#",line); xfree(old_line); } else line = concat1("#"); while (line[strlen(line)-1] == '\\') { char* continuation_line = next_line(); line[strlen(line)-1] = '\0'; if (continuation_line) { char* old_line = line; line = concat2(line,continuation_line); xfree(old_line); xfree(continuation_line); } } { const char* condition; long line_directive; if ((condition = is_if(line)) != NULL) { do_if(condition); } else if (is_else(line)) { do_else(); line_repeat_else(); } else if ((condition = is_elif(line)) != NULL) { do_elif(condition); line_repeat_else(); } else if (is_endif(line)) { do_endif(); line_repeat_endif(); } else if ((line_directive = decode_line_directive(line)) >= 0) input_line = line_directive; #ifdef SPLIT_OBJECT_INITIALIZATIONS else { /* Replace "var object foo = ..." with "var object foo; foo = ..." in macros as well. */ if (out.buffindex < MAXHEADERLEN) { uintB* p; out.buffer[out.buffindex] = '\0'; for (p = &out.buffer[token.startindex]; ; p++) { p = (uintB*) strstr((char*)p,"var "); if (p == NULL) break; if ((strncmp((char*)p,"var object ", strlen("var object "))==0 || strncmp((char*)p,"var chart ", strlen("var chart "))==0) && (p[-1] == ' ' || p[-1] == '{')) { if (strncmp((char*)p,"var object ", strlen("var object "))==0) p += strlen("var object "); else if (strncmp((char*)p,"var chart ", strlen("var chart "))==0) p += strlen("var chart "); { uintB* q = p; if ((*q >= 'A' && *q <= 'Z') || (*q >= 'a' && *q <= 'z') || *q == '_') { do q++; while ((*q >= 'A' && *q <= 'Z') || (*q >= 'a' && *q <= 'z') || (*q >= '0' && *q <= '9') || *q == '_'); while (*q == ' ') q++; if (*q == '=') { uintL insertlen = 2+(q-p); if (out.buffindex + insertlen < MAXHEADERLEN) { memmove(q+insertlen,q, &out.buffer[out.buffindex]-q+1); q[0] = ';'; q[1] = ' '; memcpy(q+2, p, q-p); out.buffindex += insertlen; } } } } } } } } #endif } xfree(line); } goto separator; case '.': c = peek_char(); if (!(((c>='0') && (c<='9')) || (c=='.'))) goto separator; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* Digit. Continue reading as long as alphanumeric or '.'. */ while (1) { c = peek_char(); if (((c>='0') && (c<='9')) || ((c>='A') && (c<='Z')) || ((c>='a') && (c<='z')) || (c=='.')) next_char(); else break; } token.type = number; goto done; case '\'': /* Character constant */ while (1) { c = next_char(); if (c==EOF) { fprintf(stderr,"Unterminated character constant\n"); break; } if (c=='\'') break; if (c=='\\') c = next_char(); } token.type = charconst; goto done; case '\"': /* String constant */ while (1) { c = next_char(); if (c==EOF) { fprintf(stderr,"Unterminated string constant\n"); break; } if (c=='\"') break; if (c=='\\') c = next_char(); } token.type = stringconst; goto done; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case '_': /* Identifier. */ while (1) { c = peek_char(); if (((c>='0') && (c<='9')) || ((c>='A') && (c<='Z')) || ((c>='a') && (c<='z')) || (c=='_')) next_char(); else break; } token.type = ident; goto done; default: separator: token.type = sep; token.ch = c; goto done; } } done: token.endindex = out.buffindex; return token; }