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; }
int yylex() { if (delim_flag) { assert(lookahead_token == -1); if (delim_flag == 2) { if ((yylval.str = get_thru_arg()) != 0) return DELIMITED; else return 0; } else { if (get_delimited()) { token_buffer += '\0'; yylval.str = strsave(token_buffer.contents()); return DELIMITED; } else return 0; } } for (;;) { int t; if (lookahead_token >= 0) { t = lookahead_token; lookahead_token = -1; } else t = get_token(1); switch (t) { case '\n': return ';'; case EOF: return 0; case DEFINE: do_define(); break; case UNDEF: do_undef(); break; case ORDINAL: yylval.n = token_int; return t; case NUMBER: yylval.x = token_double; return t; case COMMAND_LINE: case TEXT: token_buffer += '\0'; if (!input_stack::get_location(&yylval.lstr.filename, &yylval.lstr.lineno)) { yylval.lstr.filename = 0; yylval.lstr.lineno = -1; } yylval.lstr.str = strsave(token_buffer.contents()); return t; case LABEL: case VARIABLE: token_buffer += '\0'; yylval.str = strsave(token_buffer.contents()); return t; case LEFT: // change LEFT to LEFT_CORNER when followed by OF old_context_buffer = context_buffer; lookahead_token = get_token(1); if (lookahead_token == OF) return LEFT_CORNER; else return t; case RIGHT: // change RIGHT to RIGHT_CORNER when followed by OF old_context_buffer = context_buffer; lookahead_token = get_token(1); if (lookahead_token == OF) return RIGHT_CORNER; else return t; case UPPER: // recognise UPPER only before LEFT or RIGHT old_context_buffer = context_buffer; lookahead_token = get_token(1); if (lookahead_token != LEFT && lookahead_token != RIGHT) { yylval.str = strsave("upper"); return VARIABLE; } else return t; case LOWER: // recognise LOWER only before LEFT or RIGHT old_context_buffer = context_buffer; lookahead_token = get_token(1); if (lookahead_token != LEFT && lookahead_token != RIGHT) { yylval.str = strsave("lower"); return VARIABLE; } else return t; case NORTH: // recognise NORTH only before OF old_context_buffer = context_buffer; lookahead_token = get_token(1); if (lookahead_token != OF) { yylval.str = strsave("north"); return VARIABLE; } else return t; case SOUTH: // recognise SOUTH only before OF old_context_buffer = context_buffer; lookahead_token = get_token(1); if (lookahead_token != OF) { yylval.str = strsave("south"); return VARIABLE; } else return t; case EAST: // recognise EAST only before OF old_context_buffer = context_buffer; lookahead_token = get_token(1); if (lookahead_token != OF) { yylval.str = strsave("east"); return VARIABLE; } else return t; case WEST: // recognise WEST only before OF old_context_buffer = context_buffer; lookahead_token = get_token(1); if (lookahead_token != OF) { yylval.str = strsave("west"); return VARIABLE; } else return t; case TOP: // recognise TOP only before OF old_context_buffer = context_buffer; lookahead_token = get_token(1); if (lookahead_token != OF) { yylval.str = strsave("top"); return VARIABLE; } else return t; case BOTTOM: // recognise BOTTOM only before OF old_context_buffer = context_buffer; lookahead_token = get_token(1); if (lookahead_token != OF) { yylval.str = strsave("bottom"); return VARIABLE; } else return t; case CENTER: // recognise CENTER only before OF old_context_buffer = context_buffer; lookahead_token = get_token(1); if (lookahead_token != OF) { yylval.str = strsave("center"); return VARIABLE; } else return t; case START: // recognise START only before OF old_context_buffer = context_buffer; lookahead_token = get_token(1); if (lookahead_token != OF) { yylval.str = strsave("start"); return VARIABLE; } else return t; case END: // recognise END only before OF old_context_buffer = context_buffer; lookahead_token = get_token(1); if (lookahead_token != OF) { yylval.str = strsave("end"); return VARIABLE; } else return t; default: return t; } } }