/* * #include * (C99 6.10.2 Source file inclusion) */ static void handle_include(CppContext *ctx) { String *name; bool std; read_cpp_header_name(ctx, &name, &std); expect_newline(ctx); List *include_path = std ? ctx->include_path : make_list1(to_string("")); File *file = open_header(ctx, name, include_path); do_include(ctx, file); }
/* * C99 6.10.9 Pragma operator. * * _Pragma("tokens ...") is equivalent to #pragma tokens .... */ static void handle_pragma_macro(CppContext *ctx, Token *ignore) { Token *tok = read_cpp_token(ctx); if (!is_punct(tok, '(')) error_token(tok, "'(' expected, but got '%s'", token_to_string(tok)); Token *body = read_cpp_token(ctx); if (body->toktype != TOKTYPE_STRING) error_token(body, "string expected, but got '%s'", token_to_string(body)); tok = read_cpp_token(ctx); if (!is_punct(tok, ')')) error_token(tok, "')' expected, but got '%s'", token_to_string(tok)); File *file = make_string_file(body->val.str); do_include(ctx, file); handle_pragma(ctx); }
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 getblock(FILE **TEST_FILE, char **varname, char **vartitle, int *qualid ,char ***grouplist) /* Scan the file until a begin line is found. When "begin xxx" is found, read all the lines up until end xxx is found, stuffing them into a line pointed to by vartitle. This code is really ugly. Can't I make it better? */ { static char *start=0; static char *last=0; static char *next=0; char oline[MAXLINELENGTH]; char line[MAXLINELENGTH]; static char *blockname=0; static char **groups=0; char *toks[MAXTOKS]; int toklens[3], ntoks, itok, qualifier; char *stat; char *s; static char *thistype=0; int endflag, len; static int maxgroups=0; int i; static int EOF_PENDING=0; /* For cases where EOF happened in a file */ /* Scan for a begin line */ if(EOF_PENDING){ EOF_PENDING = 0; if(start) free(start); start = last = 0; return(S_FAILURE); /* Should be another code for EOF */ } toks[0] = line; /* Protect against blank lines */ /* Scan for "begin" statement or #include */ keep_looking_for_begin: while((stat=fgets(oline,MAXLINELENGTH,*TEST_FILE))){ strcpy(line,oline); s = line; while(*s && *s != '\n' && *s != COMCHAR) s++; *s = 0; { /* Break into tokens */ s = line; while(*s && isspace(*s)) s++; /* Skip white space to first character */ ntoks = 0; while(*s){ /* printf("|%s|\n",s);*/ toks[ntoks++] = s; while(*s && !isspace(*s)) s++; /* Skip over token */ if(*s){ *s++ = 0; while(*s && isspace(*s)) s++; /* Skip white space to next */ } } } itok = 0; if(strcasecmp(toks[itok++],BEGINSTR) == 0) break; if(strcasecmp(toks[0],INCLUDESTR) == 0) *TEST_FILE = do_include(toks[1]); } if(stat == NULL) { *TEST_FILE = myclose(*TEST_FILE); if(*TEST_FILE) { /* Not the true end of file */ goto keep_looking_for_begin; } else { if(start) free(start); start = last = 0; return(S_FAILURE); /* Should be another code for EOF */ } } /* Begin found at this point */ for(i=0;qualifiers[i];i++){ if(strncasecmp(toks[itok], qualifiers[i], strlen(qualifiers[i])) == 0){ itok++; break; } } *qualid = i; if(thistype) thistype = (char *) realloc(thistype,strlen(toks[itok])+1); else thistype = (char *) malloc(strlen(toks[itok])+1); for(i=0;types[i];i++){ if(strncasecmp(toks[itok],types[i],strlen(types[i])) == 0){ break; } } if(types[i] == 0) { fprintf(STDERR,"Unknown block type %s\n",toks[itok]); strcpy(thistype,toks[itok]); /* Need provision for user defined block types? */ } else { strcpy(thistype,types[i]); } itok++; { int len; len = strlen(BLOCKSTR) + strlen(thistype) + strlen(toks[itok]) + 3; if(blockname) blockname = (char *) realloc(blockname,len); else blockname = (char *) malloc(len); } strcpy(blockname,BLOCKSTR); strcat(blockname,"."); strcat(blockname,thistype); strcat(blockname,"."); strcat(blockname,toks[itok]); /* printf("|%s|\n",blockname);*/ /* Look for the group id */ itok++; if(!groups) { /* Initialize groups array */ groups = (char **) malloc(3*(sizeof(char *))); groups[0] = 0; groups[1] = 0; groups[2] = 0; maxgroups = 2; } /* Put it in the all group */ if(groups[0]) free(groups[0]); groups[0] = (char *) malloc(strlen(GROUPSTR)+strlen(thistype) +strlen(ALLGRPSTR)+3); strcpy(groups[0],GROUPSTR); strcat(groups[0],"."); strcat(groups[0],thistype); strcat(groups[0],"."); strcat(groups[0],ALLGRPSTR); if(ntoks-itok+1 > maxgroups) { int ig; groups = (char **) realloc(groups,(ntoks-itok+2)*(sizeof(char *))); for(ig=maxgroups+1;ig<ntoks-itok+2;ig++) { groups[ig] = 0; /* Zero new elements, */ } /* Makeing sure realloc will work */ maxgroups = ntoks-itok+1; } if(ntoks > itok) { int ig=1; /* Skip over all group */ for(;itok < ntoks;itok++) { /* Scan for the group keyword */ if(strncasecmp(toks[itok],GROUPSTR,strlen(GROUPSTR))==0) { char *grpnam; if(grpnam = strchr(toks[itok],'=')) { grpnam++; if(groups[ig]) free(groups[ig]); #if 0 /* For now, groups can only contain a single block type */ if(strchr(grpnam,'.')) { /* Class assigned already */ groups[ig] = (char *) malloc(strlen(GROUPSTR)+ strlen(toks[itok])+2); strcpy(groups[ig],GROUPSTR); strcat(groups[ig],"."); strcat(groups[ig],grpnam); } else { /* Prepend block type */ #endif groups[ig] = (char *) malloc(strlen(GROUPSTR)+ strlen(grpnam)+strlen(thistype)+3); strcpy(groups[ig],GROUPSTR); strcat(groups[ig],"."); strcat(groups[ig],thistype); strcat(groups[ig],"."); strcat(groups[ig],grpnam); #if 0 } #endif } /* else { ignore if = is missing } */ ig++; } } if(groups[ig]) { /* Null terminate list */ free(groups[ig]); groups[ig] = 0; } } else { /* No groups specified, use default group */ if(groups[1]) free(groups[1]); groups[1] = (char *) malloc(strlen(GROUPSTR)+strlen(thistype) +strlen(DEFAULTGRPSTR)+3); strcpy(groups[1],GROUPSTR); strcat(groups[1],"."); strcat(groups[1],thistype); strcat(groups[1],"."); strcat(groups[1],DEFAULTGRPSTR); if(groups[2]) { /* Null terminate list */ free(groups[2]); groups[2] = 0; } } strcpy(line,oline); /* Save the line */ endflag = 0; next = start; /* Initialize */ while(1){ len = strlen(line); if(next+len >= last){ int newsize; /* char *src,*dst,*newstart;*/ /* src = start;*/ newsize = max((last-start) + MAXLINELENGTH,(next-start) + len + 1); /* newstart = dst = (char *) malloc(newsize); while(src < next) *dst++ = *src++; if(start) free(start); last = newstart + newsize; start = newstart;*/ if(start) { char *newstart; newstart = (char *) realloc(start,newsize); next = next + (newstart-start); start = newstart; } else { start = (char *) malloc(newsize); next = start; } /* next = next + (dst-src);*/ } strcpy(next,line); next += len; if(endflag) break; reread: if((stat=fgets(line,MAXLINELENGTH,*TEST_FILE))){ s = line; while(*s && isspace(*s)) s++; if(strncasecmp(s,INCLUDESTR,strlen(INCLUDESTR)) == 0) { *TEST_FILE = do_include(s + strlen(INCLUDESTR)); goto reread; /* Get another line */ } if(strncasecmp(s,ENDSTR,strlen(ENDSTR))!=0) continue; s += strlen(ENDSTR)+1; while(*s && isspace(*s)) s++; if(strncasecmp(s,thistype,strlen(thistype))!=0) continue; /* Don't require block name to be restated s += strlen(thistype)+1; while(*s && isspace(*s)) s++; if(strncasecmp(s,BLOCKSTR,strlen(BLOCKSTR))!=0) continue; */ endflag = 1; } else { /* EOF */ *TEST_FILE = myclose(*TEST_FILE); if(!*TEST_FILE) { /* Test for true end of file */ strcpy(line,"end "); strcat(line,s); strcat(line," block\n"); endflag = 1; /* Terminate after writing end block */ } else { goto reread; /* Get another line */ } } } *varname = blockname; *vartitle = start; *grouplist = groups; return(S_SUCCESS); }
/* Traverse <buffer>, extracting tokens. Build nodes from tokens, and add to <parent> as fit. Recurse. */ static XmlNode * tree_build(XmlNode *parent, const char **buffer, int *complete) { DynStr *token = NULL; if(complete == NULL) { static int fake; complete = &fake; } *complete = 1; for(; *complete && **buffer;) { TokenStatus st; *buffer = token_get(*buffer, &token, &st); if(st == ERROR) { LOG_WARN(("XML parse error detected, aborting")); *complete = 0; return parent; } if(token != NULL) { if(st == TAG || st == TAGEMPTY) { const char *tag = dynstr_string(token); if(tag[0] == '?' || strncmp(tag, "!--", 3) == 0) dynstr_truncate(token, 0); else if(tag[0] == '/') { if(node_closes(parent, tag)) { dynstr_destroy(token, 1); return parent; } LOG_ERR(("Element nesting error in XML source, <%s> vs <%s>--aborting", tag, parent->element)); *complete = 0; return parent; } else { XmlNode *child = NULL, *subtree = NULL; child = node_new(tag); dynstr_destroy(token, 1); token = NULL; if(st == TAGEMPTY && strcmp(xmlnode_get_name(child), "xi:include") == 0) /* Use of xi:include? */ { XmlNode *inc; if((inc = do_include(xmlnode_attrib_get_value(child, "href"))) != NULL) { xmlnode_destroy(child); child = inc; } } if(st != TAGEMPTY) subtree = tree_build(child, buffer, complete); else subtree = child; if(parent != NULL && subtree != NULL) node_child_add(parent, subtree); else parent = child; } } else if(st == TEXT) { dynstr_trim(token); if(dynstr_length(token) > 0) { if(parent != NULL) node_text_add(parent, token); else { LOG_WARN(("Ignoring top-level text")); dynstr_destroy(token, 1); } token = NULL; } else /* If the text disappeared, it was all whitespace. Free the token. */ { dynstr_destroy(token, 1); token = NULL; } } else if(st == COMMENT) /* Ignore this comment. */ { dynstr_destroy(token, 1); token = NULL; } } else break; } return parent; }
int yylex() { for (;;) { int tk = get_token(1); switch(tk) { case UNDEF: do_undef(); break; case SDEFINE: do_definition(1); break; case DEFINE: do_definition(0); break; case TDEFINE: if (!nroff) do_definition(0); else ignore_definition(); break; case NDEFINE: if (nroff) do_definition(0); else ignore_definition(); break; case GSIZE: do_gsize(); break; case GFONT: do_gfont(); break; case GRFONT: do_grfont(); break; case GBFONT: do_gbfont(); break; case SPACE: do_space(); break; case INCLUDE: do_include(); break; case IFDEF: do_ifdef(); break; case DELIM: do_delim(); break; case CHARTYPE: do_chartype(); break; case SET: do_set(); break; case QUOTED_TEXT: case TEXT: token_buffer += '\0'; yylval.str = strsave(token_buffer.contents()); // fall through default: return tk; } } }
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); }