// Make a token with the specified ID and current token text static token_t* make_token_with_text(lexer_t* lexer, token_id id) { token_t* t = make_token(lexer, id); if(lexer->buffer == NULL) // No text for token token_set_string(t, stringtab(""), 0); else token_set_string(t, stringtab_len(lexer->buffer, lexer->buflen), lexer->buflen); return t; }
/* cpp_callback_directive */ static int _cpp_callback_directive(Parser * parser, Token * token, int c, void * data) { CppParser * cpp = data; char * str; size_t i; if(cpp->directive_control != 1 || cpp->queue_code != CPP_CODE_NULL || !_cpp_isword(c)) return 1; DEBUG_CALLBACK(); if((str = _cpp_parse_word(parser, c)) == NULL) return -1; for(i = 0; _cpp_directives[i] != NULL; i++) if(strcmp(str, _cpp_directives[i]) == 0) break; if(_cpp_directives[i] != NULL) { cpp->queue_code = CPP_CODE_META_FIRST + i; cpp->queue_string = NULL; } else { cpp->queue_code = CPP_CODE_META_ERROR; cpp->queue_string = string_new_append("Invalid directive: #", str, ":", NULL); /* XXX check for errors */ } token_set_code(token, CPP_CODE_META_DATA); token_set_string(token, str); free(str); return 0; }
/* cpp_token_set */ static int _cpp_token_set(CppParser * cp, Token * token, TokenCode code, char const * string) { if(token_set_string(token, string) != 0) return -1; if(cp->queue_code == CPP_CODE_NULL) { token_set_code(token, code); return 0; } /* we are parsing a directive */ token_set_code(token, CPP_CODE_META_DATA); if(code == CPP_CODE_COMMENT) /* comments within directives are whitespaces */ string = " "; if(cp->queue_string == NULL) { /* left-trim spaces */ for(; isspace((unsigned char)string[0]); string++); if((cp->queue_string = string_new(string)) == NULL) return -1; } else if(string_append(&cp->queue_string, string) != 0) return -1; return 0; }
// Make a token with the specified ID and current token text static token_t* make_token_with_text(lexer_t* lexer, token_id id) { token_t* t = make_token(lexer, id); append_to_token(lexer, '\0'); token_set_string(t, stringtab(lexer->buffer)); return t; }
/* cpp_callback_dequeue */ static int _cpp_callback_dequeue(Parser * parser, Token * token, int c, void * data) { int ret = 0; CppParser * cpp = data; if(cpp->queue_ready == 0) return 1; cpp->queue_ready = 0; if(cpp->queue_code == CPP_CODE_NULL && cpp->queue_string == NULL) return 1; DEBUG_CALLBACK(); token_set_code(token, cpp->queue_code); switch(cpp->queue_code) { case CPP_CODE_META_DEFINE: case CPP_CODE_META_ELIF: case CPP_CODE_META_IF: case CPP_CODE_META_IFDEF: case CPP_CODE_META_IFNDEF: case CPP_CODE_META_INCLUDE: case CPP_CODE_META_UNDEF: token_set_string(token, ""); token_set_data(token, cpp->queue_string); cpp->queue_string = NULL; break; case CPP_CODE_META_ERROR: case CPP_CODE_META_WARNING: token_set_string(token, (cpp->queue_string != NULL) ? cpp->queue_string : ""); break; default: token_set_string(token, ""); break; } cpp->queue_code = CPP_CODE_NULL; string_delete(cpp->queue_string); cpp->queue_string = NULL; cpp->directive_newline = 1; cpp->directive_control = 0; return ret; }
/* cpp_callback_header */ static int _cpp_callback_header(Parser * parser, Token * token, int c, void * data) { CppParser * cp = data; char end; char * str = NULL; size_t len = 0; char * p; if(cp->directive_control != 1 || cp->queue_code != CPP_CODE_META_INCLUDE || (c != '<' && c != '"')) return 1; DEBUG_CALLBACK(); end = (c == '<') ? '>' : '"'; while((p = realloc(str, len + 3)) != NULL) { str = p; str[len++] = c; if((c = parser_scan_filter(parser)) == EOF || c == '\n') break; else if(c == end) break; } if(p == NULL) /* there was an error with realloc() */ { error_set_code(1, "%s", strerror(errno)); free(str); return -1; } else if(c == end) /* the header name is properly closed */ { str[len++] = c; parser_scan_filter(parser); } str[len] = '\0'; token_set_code(token, CPP_CODE_META_DATA); token_set_string(token, str); if(cp->queue_string == NULL || strlen(cp->queue_string) == 0) { free(cp->queue_string); cp->queue_string = str; } else { free(str); cp->queue_code = CPP_CODE_META_ERROR; free(cp->queue_string); /* XXX may be followed by junk */ cp->queue_string = strdup("Syntax error"); } return 0; }
ast_t* ast_from_string(ast_t* ast, const char* name) { if(name == NULL) return ast_from(ast, TK_NONE); token_t* t = token_dup(ast->t); token_set_id(t, TK_ID); token_set_string(t, name, 0); ast_t* new_ast = ast_token(t); set_scope_no_parent(new_ast, ast->parent); return new_ast; }
/* cpp_callback_whitespace */ static int _cpp_callback_whitespace(Parser * parser, Token * token, int c, void * data) { CppParser * cpp = data; char * str = NULL; size_t len = 0; char * p; if(!isspace(c)) return 1; DEBUG_CALLBACK(); do { if(c != '\n') continue; if((p = realloc(str, len + 2)) == NULL) { free(str); return -1; } str = p; str[len++] = c; } while(isspace((c = parser_scan_filter(parser)))); token_set_code(token, CPP_CODE_WHITESPACE); if(str != NULL) /* some newlines were encountered */ { str[len] = '\0'; token_set_string(token, str); free(str); cpp->directive_newline = 1; cpp->queue_ready = 1; return 0; } token_set_string(token, " "); if(cpp->queue_code != CPP_CODE_NULL && cpp->queue_string != NULL) string_append(&cpp->queue_string, " "); return 0; }
/* cpp_callback_newline */ static int _cpp_callback_newline(Parser * parser, Token * token, int c, void * data) { CppParser * cpp = data; if(c != '\n') return 1; DEBUG_CALLBACK(); cpp->directive_newline = 1; cpp->queue_ready = 1; parser_scan_filter(parser); token_set_code(token, CPP_CODE_NEWLINE); token_set_string(token, "\n"); return 0; }
/* cpp_callback_control */ static int _cpp_callback_control(Parser * parser, Token * token, int c, void * data) { CppParser * cpp = data; if(cpp->directive_newline != 1 || c != '#') { cpp->directive_newline = 0; return 1; } DEBUG_CALLBACK(); parser_scan_filter(parser); token_set_code(token, CPP_CODE_META_DATA); token_set_string(token, "#"); cpp->directive_newline = 0; cpp->directive_control = 1; cpp->queue_code = CPP_CODE_NULL; return 0; }
void ast_set_name(ast_t* ast, const char* name) { assert(ast != NULL); token_set_string(ast->t, name, 0); }