/* * UUID: bb188d3b-e320-11dc-8b9d-00502c05c241 * Author: Brian M. Ames, bames@apk.net * Copyright: Copyright (C) 2008 by Brian M. Ames */ #include #include #include #include #include #include "parser_routines.h" #include "rinchi_string.h" #include "lexer.h" #include "tree.h" #include "include_path.h" char *comment_buf; int cbp; char char_buf[CHAR_BUF_SIZE]; int char_buf_ptr=0; struct nodeIdentifier *current_identifier_node = NULL; struct nodeIdentifier *macro_identifier_node = NULL; struct nodeMacro *current_macro = NULL; struct nodeLocation *current_location; void *macro_root = NULL; void *uoc_root = NULL; void *dep_root = NULL; void *inc_root = NULL; int replacement = 0; int uoc_def; int uoc_try; int uoc_match; signed char condition[CONDITION_DEPTH]; int condition_ptr=0; int invalid_macro_id = 0; extern int yypp_debug; extern int out_comments; extern int out_location; extern FILE *outfile; extern FILE *depfile; extern struct nodeFile *curfilenode; extern char *repl_id[]; extern int repl_level; char **macro_args; int macro_arg_index; int macro_arg_count = 0; struct tm *trans_time; /* * Initialize parser routines. */ int parser_routines_init() { condition[0] = 1; return 0; } /* * Define predefined macros as specified by ISO/IEC 14882-2003. */ int predefined_macro_init() { char buf[32]; time_t tmt; handle_token_open(PREDEFINED_MACRO_INDEX); time(&tmt); trans_time = localtime(&tmt); handle_command_line_define(strdup("__LINE__")); handle_command_line_define(strdup("__FILE__")); strftime (buf, 31, "__DATE__:\"%F\"", trans_time); handle_command_line_define(strdup(buf)); strftime (buf, 31, "__TIME__:\"%T\"", trans_time); handle_command_line_define(strdup(buf)); handle_command_line_define(strdup("__STDC__:1")); handle_command_line_define(strdup("__cplusplus:1")); handle_token_close(PREDEFINED_MACRO_INDEX); return 0; } /* * Compare two nodeIdentifier structs. */ int idncmp(const void *idn1, const void *idn2) { char *cp1,*cp2; cp1 = ((struct nodeIdentifier *) idn1)->identifier; cp2 = ((struct nodeIdentifier *) idn2)->identifier; return strcmp(cp1,cp2); } /* * Compare two identifiers. */ int idcmp(const void *id1, const void *id2) { return strcmp((char *) id1,(char *) id2); } /* * Compare two paths. */ int depcmp(const void *idn1, const void *idn2) { char *cp1,*cp2; cp1 = (char *) idn1; cp2 = (char *) idn2; if (*cp1 == '/' && *cp2 != '/') return 1; if (*cp1 != '/' && *cp2 == '/') return -1; return strcmp(cp1,cp2); } /* * Compare two nodeMacro structs. */ int mcrcmp(const void *mcr1, const void *mcr2) { char *cp1,*cp2; cp1 = ((struct nodeMacro *) mcr1)->identifier; cp2 = ((struct nodeMacro *) mcr2)->identifier; return strcmp(cp1,cp2); } /* * Add a path to the dependency list. */ int add_dependency(char *dep_path) { void **tsr; if (yypp_debug != 0) { fprintf(stderr,"%s(%s); start\n",__func__,dep_path); } tsr = tfind(dep_path, &dep_root, depcmp); if (tsr == NULL) { tsr = tsearch(dep_path, &dep_root, depcmp); } else { fprintf(stderr,"Warning, file %s has already been included.\n",dep_path); // return 1; } return 0; } /* * Add a character to the buffer. */ void add_char(int ch) { if (char_buf_ptr < (CHAR_BUF_SIZE-1)) { char_buf[char_buf_ptr++] = ch; char_buf[char_buf_ptr] = 0; } } /* * Copy a string to the buffer. */ void copy_string(char *chars) { char *cp=chars; while(*cp != 0) add_char(*cp++); } /* * Copy a string less first and last characters to the buffer. Used for * include headers. */ void copy_string_less(char *chars) { char *cp; size_t sz; cp = chars+1; sz=strlen(cp)-1; cp[sz]=0; while(*cp != 0) add_char(*cp++); } /* * Return char_buf as a string; */ char *get_str() { char *cp = strdup(char_buf); char_buf_ptr=0; char_buf[0] = 0; return cp; } //char *strndup(const char *S, size_t SIZE); /* * Copy UTF-8 characters to the buffer using Universal Character Names. */ void copy_utf8(unsigned char *chars) { char buf[11]; unsigned int ch; ch = chars[0]; if ((ch & 0x80) == 0x00) { add_char(chars[0]); return; } else if ((ch & 0xE0) == 0xC0) { ch = ((chars[0] & 0x1F) << 6) | (chars[1] & 0x3F); } else if ((ch & 0xF0) == 0xE0) { ch = ((chars[0] & 0x0F) << 6) | (chars[1] & 0x3F); ch <<= 6; ch |= (chars[2] & 0x3F); } else if ((ch & 0xF8) == 0xF0) { ch = ((chars[0] & 0x07) << 6) | (chars[1] & 0x3F); ch <<= 6; ch |= (chars[2] & 0x3F); ch <<= 6; ch |= (chars[3] & 0x3F); } if (ch <= 0xFFFF) { sprintf(buf,"\\u%04X",ch); } else { sprintf(buf,"\\U%08X",ch); } copy_string(buf); } /* * Return char_buf interpreted as an octal value. */ long get_value_octal() { char *tail; long res; res = strtol(char_buf, &tail, 8); char_buf_ptr = 0; // char_buf[0] = 0; return res; } /* * Return char_buf interpreted as an decimal value. */ long get_value_decimal() { char *tail; long res; res = strtol(char_buf, &tail, 10); char_buf_ptr = 0; // char_buf[0] = 0; return res; } /* * Return char_buf interpreted as an hexadecimal value. */ long get_value_hexadecimal() { char *tail; long res; res = strtol(char_buf, &tail, 16); char_buf_ptr = 0; // char_buf[0] = 0; return res; } /* * */ void handle_comment(char *tokenString) { struct nodeComment *node; if (yypp_debug != 0) { fprintf(stderr,"%s\n",__func__); } if(out_comments != 0) { node = newNodeComment(COMMENT_INDEX); node->comment = strdup(tokenString); add(node); } } /* * */ void handle_begin_comment() { comment_buf = (char *) malloc(COMMENT_BUFFER_SIZE); cbp = 0; } /* * */ void handle_comment_char(int ch) { if((cbp > 0 || ch != ' ') && (cbp < MAX_COMMENT_STRING)) { comment_buf[cbp++] = ch; } } /* * */ void handle_end_comment() { struct nodeComment *node; comment_buf[cbp] = 0; cbp--; while( cbp >=0 && comment_buf[cbp] == ' ') { comment_buf[cbp--] = 0; } if(out_comments != 0) { node = newNodeComment(BLOCK_COMMENT_INDEX); node->comment = strdup(comment_buf); add(node); } free(comment_buf); comment_buf = NULL; } /* * */ void handle_file_begin(enum tokenIndex ti) { if (yypp_debug != 0) { fprintf(stderr,"%s\n",__func__); } if (condition[condition_ptr] == 1) { push(curfilenode); } } /* * */ void handle_file_end(enum tokenIndex token) { union treeNode *node; if (yypp_debug != 0) { fprintf(stderr,"%s\n",__func__); } if (condition[condition_ptr] == 1) { node = pop(); } } /* * */ void handle_location() { if (yypp_debug != 0) { fprintf(stderr,"%s();\n",__func__); fprintf(stderr,"condition[%d] == %d\n",condition_ptr,condition[condition_ptr]); } if (condition[condition_ptr] == 1) { if(out_location == 0) { current_location = newNodeLocation(); current_location->common.nodeType = NODE_TYPE_LOCATION; current_location->file = getCurrentFilename(); current_location->line = getCurrentLineNumber(); current_location->common.tokenIndex = LOCATION_INDEX; add(current_location); } } if (yypp_debug != 0) { fprintf(stderr,"%s(); end\n",__func__); } } /* * */ void handle_token(enum tokenIndex ti) { struct nodeCommon *node; if (yypp_debug != 0) { fprintf(stderr,"%s %s\n",__func__,tokenString[ti]); } if (condition[condition_ptr] == 1) { node = newNodeCommon(ti); add(node); } } /* * */ void handle_string_token(enum tokenIndex ti) { struct nodeText *node; if (yypp_debug != 0) { fprintf(stderr,"%s(%d,\"%s\");\n",__func__,ti,char_buf); } if (condition[condition_ptr] == 1) { node = newNodeText(ti); node->text = strdup(char_buf); add(node); } char_buf_ptr = 0; char_buf[0] = 0; } /* * */ void handle_token_open(enum tokenIndex ti) { struct nodeCommon *node; if (yypp_debug != 0) { fprintf(stderr,"%s\n",__func__); } if (condition[condition_ptr] == 1) { node = newNodeCommon(ti); push(node); } } /* * */ void handle_token_close(enum tokenIndex token) { union treeNode *node; if (yypp_debug != 0) { fprintf(stderr,"%s\n",__func__); } if (condition[condition_ptr] == 1) { node = pop(); } } /* * Processes the identifier currently stored in char_buf */ int test_identifier() { struct nodeMacro *node; struct nodeMacro **tsr; // char **tsr2; struct nodeCommon *argnode; char *identifier; int result = 0; int i; int scr; if (yypp_debug != 0) { fprintf(stderr,"%s(\"%s\")\n",__func__,char_buf); } identifier = strdup(char_buf); char_buf_ptr = 0; node = newNodeMacro(IDENTIFIER_INDEX); node->identifier = identifier; tsr = (struct nodeMacro**) tfind(node, ¯o_root, mcrcmp); if (tsr == NULL) { current_macro = NULL; } else { current_macro = (struct nodeMacro *) *tsr; repl_id[repl_level+1] = identifier; if (repl_level >= 20) return 0; // probably an infinite loop switch(current_macro->common.tokenIndex) { case object_macro_index: for (i=1; i<=repl_level; i++) { if(repl_id[repl_level] != NULL) { scr = strcmp(identifier, repl_id[i]); if(scr == 0) { if (yypp_debug != 0) { fprintf(stderr,"%s(\"%s\") = 0;\n",__func__,current_macro->identifier); } return 0; } } } if(repl_id[repl_level] == NULL || strcmp(identifier, repl_id[repl_level]) != 0) { if (current_macro->replacement == NULL) { result = 1; } else { result = 2; } } break; case function_macro_index: macro_arg_count = 0; for (argnode = current_macro->common.firstChild; argnode != NULL; argnode = argnode->nextSibling) macro_arg_count++; if (macro_arg_count == 0) { result = 3; } else { result = 4; macro_args = (char **) malloc(macro_arg_count * sizeof(char *)); macro_arg_index = 0; } break; default: fprintf(stderr,"%s(?);\n",__func__); result = 1; break; } } if (yypp_debug != 0) { if (current_macro == NULL) { fprintf(stderr,"%s(\"%s\") = %d;\n",__func__,identifier,result); } else { fprintf(stderr,"%s(\"%s\") = %d;\n",__func__,current_macro->identifier,result); } } return result; } /* * */ char *get_replacement_string() { union treeNode *node; // struct nodeText *text; int sz = 2; int stringize = 0; int index; int i; char *repl = NULL; char *cp; char *buf; if(strcmp(current_macro->identifier,"__LINE__") == 0) { buf = (char *) malloc(20); sprintf(buf,"%d",getCurrentLineNumber()-1); repl = strdup(buf); free(buf); return repl; } else if(strcmp(current_macro->identifier,"__FILE__") == 0) { buf = getCurrentFilename(); repl = (char *) malloc(strlen(buf)+3); sprintf(repl,"\"%s\"",buf); return repl; } // macro_identifier_node for(node = (union treeNode *) current_macro->replacement->common.firstChild; node != NULL; node = (union treeNode *) node->common.nextSibling) { switch(node->common.nodeType) { case NODE_TYPE_COMMON: switch(node->common.tokenIndex) { case OP_TOKEN_SPLICE_INDEX: break; case OP_STRINGIZE_INDEX: sz += 2; break; default: break; } break; case NODE_TYPE_IDENTIFIER: if (node->common.replaceable_flag == 0) { sz += strlen(node->identifier.identifier)+1; } else { index = get_param_index(node->identifier.identifier); if (index >=0 && index < macro_arg_count) { if (stringize == 1) { sz += strlen(node->identifier.identifier)+2; } else { sz += strlen(macro_args[index]); if(strcmp(macro_args[index],current_macro->identifier) == 0) { sz++; } } } } break; case NODE_TYPE_TEXT: sz += strlen(node->text.text); break; default: break; } } repl = (char *) malloc(sz); memset(repl, 0, sz); for(node = (union treeNode *) current_macro->replacement->common.firstChild; node != NULL; node = (union treeNode *) node->common.nextSibling) { switch(node->common.nodeType) { case NODE_TYPE_COMMON: switch(node->common.tokenIndex) { case OP_TOKEN_SPLICE_INDEX: break; case OP_STRINGIZE_INDEX: stringize=1; break; default: break; } break; case NODE_TYPE_IDENTIFIER: if (node->common.replaceable_flag == 0) { strcat(repl,node->identifier.identifier); // strcat(repl,"\033"); // strcat(repl,"_"); strcat(repl,"\x9b"); } else { index = get_param_index(node->identifier.identifier); if (index >=0 && index < macro_arg_count) { if (stringize == 1) { strcat(repl,"\""); i = strlen(repl); for(cp = macro_args[index]; *cp == ' ' || *cp == '\t'; cp++); while(*cp != 0) { if(*cp == ' ' || *cp == '\t') { cp++; if (*cp == ' ' || *cp == '\t' || *cp == 0) { } else { repl[i++] = ' '; } } else { repl[i++] = *cp++; } } strcat(repl,"\""); } else { strcat(repl,macro_args[index]); if(strcmp(macro_args[index],current_macro->identifier) == 0) { strcat(repl,"\x9b"); } } } } stringize=0; break; case NODE_TYPE_TEXT: strcat(repl,node->text.text); break; default: if (yypp_debug != 0) { fprintf(stderr,"token=\"%s\"\n", tokenString[node->common.tokenIndex]); } break; } } if (yypp_debug != 0) { fprintf(stderr,"%s() repl=\"%s\"\n",__func__, repl); } if(current_macro->common.tokenIndex == function_macro_index) { strcat(repl,"\033"); } return repl; } /* * */ void handle_identifier(enum tokenIndex ti) { struct nodeIdentifier *node; if (condition[condition_ptr] == 1) { if(current_identifier_node == NULL) { node = newNodeIdentifier(ti); node->identifier = strdup(char_buf); } else { node = current_identifier_node; current_identifier_node = NULL; } add(node); if (replacement) { if(strcmp(node->identifier,current_macro->identifier) == 0) { node->common.replaceable_flag = 0; } else { node->common.replaceable_flag = 1; } } if (yypp_debug != 0) { fprintf(stderr,"%s(\"%s\",%d)\n",__func__,node->identifier,node->common.replaceable_flag); } } else { if (yypp_debug != 0) { fprintf(stderr,"%s\n",__func__); } } char_buf_ptr = 0; char_buf[0] = 0; } /* * */ void handle_nonrepl_identifier(enum tokenIndex ti) { struct nodeIdentifier *node; // if (yypp_debug != 0) { // fprintf(stderr,"%s\n",__func__); // } if (condition[condition_ptr] == 1) { if(current_identifier_node == NULL) { node = newNodeIdentifier(ti); node->identifier = strdup(char_buf); node->common.replaceable_flag = 0; } else { node = current_identifier_node; current_identifier_node = NULL; } add(node); if (yypp_debug != 0) { fprintf(stderr,"%s(\"%s\",%d)\n",__func__,node->identifier,node->common.replaceable_flag); } } else { if (yypp_debug != 0) { fprintf(stderr,"%s\n",__func__); } } char_buf_ptr = 0; char_buf[0] = 0; } /* * */ void handle_identifier_open(enum tokenIndex ti) { struct nodeIdentifier *node; if (yypp_debug != 0) { fprintf(stderr,"%s\n",__func__); } if (condition[condition_ptr] == 1) { node = newNodeIdentifier(ti); node->identifier = strdup(char_buf); push(node); } char_buf_ptr = 0; char_buf[0] = 0; } /* * */ void handle_include(enum tokenIndex ti) { if (condition[condition_ptr] == 1) { handle_include_file(); } } /* * */ void handle_command_line_define(char *arg) { char *cp; if (yypp_debug != 0) { fprintf(stderr,"%s(\"%s\");\n",__func__,arg); } for(cp = arg; *cp != '=' && *cp != ':' && *cp != 0; cp++); if (*cp == 0) { copy_string(arg); handle_macro_open(object_macro_index); } else { *cp++ = 0; copy_string(arg); handle_macro_open(object_macro_index); copy_string(cp); handle_string_token(STRING_LITERAL_INDEX); } handle_macro_close (object_macro_index); } /* * */ void handle_define(const char *identifier) { void **tsr; fprintf(stderr,"1 %s(\"%s\");\n",__func__,identifier); if (condition[condition_ptr] == 1) { if((curfilenode->guarded == 1) && (0 == strcmp(identifier, curfilenode->guardId))) { curfilenode->guarded = 2; } else { curfilenode->guarded = -1; } tsr = tfind(identifier, ¯o_root, idcmp); if (tsr == NULL) { tsr = tsearch(identifier, ¯o_root, idcmp); } else { fprintf(stderr,"Error, macro %s is already defined.\n",identifier); } } if (yypp_debug != 0) { fprintf(stderr,"%s(\"%s\");\n",__func__,identifier); fprintf(stderr,"condition[%d]=%d\n",condition_ptr,condition[condition_ptr]); fprintf(stderr,"guarded=%d\n",curfilenode->guarded); } } /* * */ void handle_replacement_open(enum tokenIndex ti) { struct nodeCommon *node; struct nodeCommon *current; if (yypp_debug != 0) { fprintf(stderr,"%s\n",__func__); } if (condition[condition_ptr] == 1) { current = (struct nodeCommon *) getCurrent(); // current_macro = (struct nodeMacro *) getParent(); node = newNodeCommon(ti); push(node); if(current != NULL) { current->nextSibling = NULL; } current_macro->replacement = (union treeNode*) node; replacement = 1; } } /* * */ void handle_replacement_close(enum tokenIndex token) { union treeNode *node; if (yypp_debug != 0) { fprintf(stderr,"%s\n",__func__); } if (condition[condition_ptr] == 1) { node = pop(); if(current_macro->common.tokenIndex == object_macro_index) { current_macro->common.firstChild = 0; } replacement = 0; } } /* * */ int skip_line() { int result = 1; if (condition[condition_ptr] > 0) { result = 0; } if (yypp_debug != 0) { fprintf(stderr,"%s() = %d;\n",__func__, result); fprintf(stderr,"condition[%d] = %d\n",condition_ptr,condition[condition_ptr]); } return result; } /* * */ int dont_care() { int result = 1; if (condition[condition_ptr] >= 0) { result = 0; } if (yypp_debug != 0) { fprintf(stderr,"%s() = %d;\n",__func__, result); fprintf(stderr,"condition[%d] = %d\n",condition_ptr,condition[condition_ptr]); } return result; } /* * Return the index of the macro parameter with the given name or -1 if * it is not found. */ int get_param_index(char *identifier) { struct nodeIdentifier *node; int index = -1; int i; if (yypp_debug != 0) { fprintf(stderr,"%s(\"%s\");\n",__func__,identifier); } i = 0; if (current_macro != NULL && current_macro->common.firstChild != NULL) { for (node = (struct nodeIdentifier *) current_macro->common.firstChild; node != NULL; node = (struct nodeIdentifier *) node->common.nextSibling) { if (node != NULL && node->common.tokenIndex == IDENTIFIER_INDEX) { if (node->identifier != NULL) { if (strcmp(identifier,node->identifier) == 0) { index=i; break; } } } i++; } } if (yypp_debug != 0) { fprintf(stderr,"%s(\"%s\")=%d;\n",__func__,identifier,index); } return index; } /* * Tests the identifier in char_buf to see if it matches a macro parameter name. * Returns 1 if it matches, 0 otherwise. */ int is_param_id() { int index; if (yypp_debug != 0) { fprintf(stderr,"%s(\"%s\");\n",__func__,char_buf); } if (current_macro == NULL || current_macro->common.tokenIndex == object_macro_index) { index = -1; } else { index = get_param_index(char_buf); } return (index < 0) ? 0 : 1; } /* * */ int is_macro_id() { int index; if (yypp_debug != 0) { fprintf(stderr,"%s(\"%s\");\n",__func__,char_buf); } index = strcmp(char_buf,current_macro->identifier); return (index == 0) ? 1 : 0; } /* * */ void handle_macro_arg() { if (yypp_debug != 0) { fprintf(stderr,"%s(%s);\n",__func__,char_buf); } if (macro_arg_index < macro_arg_count) { macro_args[macro_arg_index++] = strdup(char_buf); } else { fprintf(stderr,"Too many arguments for macro.\n"); } char_buf_ptr = 0; char_buf[0] = 0; } /* * */ void handle_macro_open(enum tokenIndex ti) { current_macro = newNodeMacro(ti); current_macro->identifier = strdup(char_buf); if (condition[condition_ptr] == 1) { push(current_macro); if((curfilenode->guarded == 1) && (0 == strcmp(current_macro->identifier, curfilenode->guardId))) { curfilenode->guarded = 2; } else { curfilenode->guarded = -1; } } if (yypp_debug != 0) { fprintf(stderr,"%s(\"%s\");\n",__func__,char_buf); fprintf(stderr,"condition[%d]=%d\n",condition_ptr,condition[condition_ptr]); fprintf(stderr,"guarded=%d\n",curfilenode->guarded); } char_buf_ptr = 0; char_buf[0] = 0; } /* * */ void handle_macro_close(enum tokenIndex ti) { struct nodeMacro *node; void *tsr; if (yypp_debug != 0) { fprintf(stderr,"%s\n",__func__); } if (condition[condition_ptr] == 1) { node = (struct nodeMacro *) pop(); tsr = tfind(node, ¯o_root, idncmp); if (invalid_macro_id == 0) { if (tsr == NULL) { tsr = tsearch(node, ¯o_root, idncmp); } else { fprintf(stderr,"Warning, macro %s is already defined.\n",node->identifier); } } } invalid_macro_id = 0; } /* * */ void handle_macro_undef(enum tokenIndex ti) { struct nodeMacro *node; void *tsr; if (yypp_debug != 0) { fprintf(stderr,"%s(\"%s\")\n",__func__,char_buf); } if (condition[condition_ptr] == 1) { node = newNodeMacro(ti); node->identifier = strdup(char_buf); node->common.replaceable_flag = 0; add(node); tsr = tfind(node, ¯o_root, idncmp); if (tsr == NULL) { } else { tsr = tdelete(node, ¯o_root, idncmp); } } char_buf_ptr = 0; char_buf[0] = 0; } /* * */ void handle_if_open(enum tokenIndex ti, int value) { if (yypp_debug != 0) { fprintf(stderr,"%s(%d,%d)\n",__func__,ti,value); fprintf(stderr,"condition[%d]=%d\n",condition_ptr,condition[condition_ptr]); } if (condition[condition_ptr] != 1) { condition[++condition_ptr] = -1; } else { condition_ptr++; char_buf_ptr = 0; char_buf[0] = 0; if (value == 0) { condition[condition_ptr] = 0; enter_cond_state(); } else { condition[condition_ptr] = 1; exit_cond_state(); } } if (yypp_debug != 0) { fprintf(stderr,"condition[%d]=%d\n",condition_ptr,condition[condition_ptr]); } } /* * */ void handle_ifdef_open(enum tokenIndex ti) { struct nodeIdentifier *node; void *tsr; if (yypp_debug != 0) { fprintf(stderr,"%s\n",__func__); fprintf(stderr,"condition[%d]=%d\n",condition_ptr,condition[condition_ptr]); } if (condition[condition_ptr] != 1) { condition[++condition_ptr] = -1; } else { condition_ptr++; node = newNodeIdentifier(ti); node->identifier = strdup(char_buf); char_buf_ptr = 0; char_buf[0] = 0; tsr = tfind(node, ¯o_root, idncmp); if (tsr == NULL) { condition[condition_ptr] = 0; enter_cond_state(); } else { condition[condition_ptr] = 1; exit_cond_state(); } free(node); } if (yypp_debug != 0) { fprintf(stderr,"condition[%d]=%d\n",condition_ptr,condition[condition_ptr]); } } /* * */ void handle_ifndef_open(enum tokenIndex ti) { char *identifier; struct nodeIdentifier *node; void *tsr; if (yypp_debug != 0) { fprintf(stderr,"%s\n",__func__); fprintf(stderr,"condition[%d]=%d\n",condition_ptr,condition[condition_ptr]); fprintf(stderr,"guarded=%d\n",curfilenode->guarded); } identifier = strdup(char_buf); if(curfilenode->guarded == 0) { if (condition[condition_ptr] == 1) { curfilenode->guarded = 1; curfilenode->guardId = identifier; } else { curfilenode->guarded = -1; } } if (condition[condition_ptr++] != 1) { condition[condition_ptr] = -1; } else { node = newNodeIdentifier(ti); node->identifier = strdup(char_buf); char_buf_ptr = 0; char_buf[0] = 0; tsr = tfind(node, ¯o_root, idncmp); if (tsr == NULL) { condition[condition_ptr] = 1; exit_cond_state(); } else { condition[condition_ptr] = 0; enter_cond_state(); } free(node); } if (yypp_debug != 0) { fprintf(stderr,"condition[%d]=%d\n",condition_ptr,condition[condition_ptr]); } } /* * */ void handle_else_open(enum tokenIndex ti) { if (yypp_debug != 0) { fprintf(stderr,"%s\n",__func__); fprintf(stderr,"condition[%d]=%d\n",condition_ptr-1,condition[condition_ptr-1]); fprintf(stderr,"condition[%d]=%d\n",condition_ptr,condition[condition_ptr]); } if (condition[condition_ptr-1] == -1) { } else { if (condition[condition_ptr] == 0) { condition[condition_ptr] = 1; exit_cond_state(); } else { condition[condition_ptr] = 0; enter_cond_state(); } } if (yypp_debug != 0) { fprintf(stderr,"condition[%d]=%d\n",condition_ptr,condition[condition_ptr]); } } /* * */ void handle_elif_open(enum tokenIndex ti, int value) { if (yypp_debug != 0) { fprintf(stderr,"%s(%d,%d)\n",__func__,ti,value); fprintf(stderr,"condition[%d]=%d\n",condition_ptr,condition[condition_ptr]); } if (condition[condition_ptr-1] == -1) { } else { if (condition[condition_ptr++] == 0) { if (value == 0) { condition[condition_ptr] = 0; } else { condition[condition_ptr] = 1; condition[condition_ptr-1] = 1; } } else { condition[condition_ptr] = -1; } } if (yypp_debug != 0) { fprintf(stderr,"condition[%d]=%d\n",condition_ptr,condition[condition_ptr]); } } /* * check if we need this */ void handle_elif_close(enum tokenIndex ti) { if (yypp_debug != 0) { fprintf(stderr,"%s(%d)\n",__func__,ti); fprintf(stderr,"condition[%d]=%d\n",condition_ptr,condition[condition_ptr]); } condition_ptr--; } /* * */ void handle_endif(enum tokenIndex ti) { condition_ptr--; if (condition[condition_ptr] == 0) { enter_cond_state(); } else { exit_cond_state(); } if (yypp_debug != 0) { fprintf(stderr,"%s\n",__func__); fprintf(stderr,"condition[%d]=%d\n",condition_ptr,condition[condition_ptr]); } } /* * */ void handle_header_name(enum tokenIndex ti) { extern char *include_file_name; struct nodeText *node; if (yypp_debug != 0) { fprintf(stderr,"%s\n",__func__); } if (condition[condition_ptr] == 1) { node = newNodeText(ti); node->text = strdup(char_buf); add(node); include_file_name=node->text; } char_buf_ptr = 0; char_buf[0] = 0; } /* * Handle preprocessing number. */ void handle_pp_number() { struct nodeText *node; if (yypp_debug != 0) { fprintf(stderr,"%s\n",__func__); } if (condition[condition_ptr] == 1) { node = newNodeText(PP_NUMBER_INDEX); node->text = strdup(char_buf); add(node); } char_buf_ptr = 0; char_buf[0] = 0; } /* * Handle an invalid macro identifier. */ void handle_invalid_macro_id(enum tokenIndex ti) { struct nodeError *node; if (yypp_debug != 0) { fprintf(stderr,"%s\n",__func__); } if (condition[condition_ptr] == 1) { node = newNodeError(ti); node->format = " error=\""%s" cannot be used as a macro name as it is an operator in C++\""; push(node); invalid_macro_id = 1; } } /* * Add the given use on code to those to be selected. */ void define_use_on_code(const char *use_on_code) { struct nodeText *node; void **tsr; if (yypp_debug != 0) { fprintf(stderr,"%s(\"%s\");\n",__func__,use_on_code); } uoc_def++; tsr = tfind(use_on_code, &uoc_root, idcmp); if (tsr == NULL) { tsr = tsearch(use_on_code, &uoc_root, idcmp); node = newNodeText(USE_ON_CODE_INDEX); node->text = strdup(use_on_code); add(node); } else { fprintf(stderr, "Warning, use on code %s is already defined.\n",use_on_code); } } /* * Try the use on code against those selected, if any. */ void handle_use_on_code(const char *use_on_code) { void **tsr; if(uoc_def > 0) { tsr = tfind(use_on_code, &uoc_root, idcmp); uoc_try++; if (tsr == NULL) { } else { uoc_match = 1; } } if (yypp_debug != 0) { fprintf(stderr,"%s(\"%s\") = %d;\n",__func__,use_on_code, uoc_match); } } /* * Test to see if a use on code has been matched or no tries have occurred. */ int use_on_code_matched() { int result = 0; if (uoc_try == 0 || uoc_match == 1) { result = 1; } uoc_try = 0; uoc_match = 0; if (yypp_debug != 0) { fprintf(stderr,"%s(uoc_try=%d,uoc_match=%d) = %d;\n",__func__,uoc_try,uoc_match, result); } return result; } /* * Add a directory to the list of those to be searched for included files. */ void define_include_directory(char *directory) { void **tsr; if (yypp_debug != 0) { fprintf(stderr,"%s(\"%s\");\n",__func__,directory); } tsr = tfind(directory, &inc_root, depcmp); if (tsr == NULL) { tsr = tsearch(directory, &inc_root, depcmp); add_incl_path(directory); if (yypp_debug != 0) { fprintf(stderr,"Include directory %s added.\n",directory); } } else { fprintf(stderr, "Warning, include directory %s is already defined.\n",directory); } }