F diff --git a/src/debug/wobler/wobler_tests.h b/src/debug/wobler/wobler_tests.h --- a/src/debug/wobler/wobler_tests.h +++ b/src/debug/wobler/wobler_tests.h.how_much_time_should_execution_take=TEST_TIME_BASELINE,},{+ .filenames={"test_declaration3.c"},+ .test_function=should_compile,+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,+ },+ {.filenames={"test_declaration_error.c"},.test_function=should_not_compile,.how_much_time_should_execution_take=TEST_TIME_BASELINE,F diff --git a/src/environment/error/gcc_error.c b/src/environment/error/gcc_error.c --- a/src/environment/error/gcc_error.c +++ b/src/environment/error/gcc_error.cargs);va_end(args);}+ void push_token_ptr_error(const char *message_format,struct Token_Pointer *ptr,...)+ {+ va_list args;+ va_start(args,ptr);+ push_translation_message_inner("[Error] ",+ message_format,+ ptr->program,+ ptr->context->filename,+ ptr->context->filename_size,+ ptr->context->line,+ ptr->context->column,+ args);+ va_end(args);+ }char* get_string_for_type_error(struct Type *type){char *ret;F diff --git a/src/environment/error/gcc_error.h b/src/environment/error/gcc_error.h --- a/src/environment/error/gcc_error.h +++ b/src/environment/error/gcc_error.h#include <common.h>#include <compile.h>#include <type.h>+ #include <translation_unit.h>struct Translation_Message{void push_program_error(const char *message_format,struct Program *program, ...);+ void push_token_ptr_error(const char *message_format,struct Token_Pointer *ptr,...);char* get_string_for_type_error(struct Type *type);char* get_string_for_denoted_error(struct Denoted *denoted);F diff --git a/src/frontend/lex/lex_preprocessing_directive.c b/src/frontend/lex/lex_preprocessing_directive.c --- a/src/frontend/lex/lex_preprocessing_directive.c +++ b/src/frontend/lex/lex_preprocessing_directive.c{return lexer_data->src->src[lexer_data->where_in_src]=='\n' || lexer_eof(lexer_data);}+ #warning a hashtag include "asdfadf" [ space ] makes the first assert fail. This is probably due to an empty token after the string onestruct token *preprocessing_make_token_finishing_on_node(struct Lexer_Data *lexer_data,struct Automata_Node *finishing_node,size_t start_position){struct Source_Location *token_location;case PKW_ENDIF:return get_error_token("PREPROCESSING ENDIF NOT DONE",token_location,lexer_data->previous_token_location,lexer_data->program);case PKW_INCLUDE:- return get_error_token("PREPROCESSING INCLUDE NOT DONE",token_location,lexer_data->previous_token_location,lexer_data->program);+ return preprocessing_lex_include_directive(lexer_data,token_location);case PKW_DEFINE:return get_error_token("PREPROCESSING DEFINE NOT DONE",token_location,lexer_data->previous_token_location,lexer_data->program);case PKW_UNDEF:F diff --git a/src/frontend/parse/parse_declaration.c b/src/frontend/parse/parse_declaration.c --- a/src/frontend/parse/parse_declaration.c +++ b/src/frontend/parse/parse_declaration.c#define WONKY_PARSE_DECLARATION_C WONKY_PARSE_DECLARATION_C#include <parse_declaration.h>+ #warning main(){return 0;} segfaults wonky/*declaration-specifiers init-declarator (,init-declarator)* ;*//* init-declarator: declarator [ = initializer ] */void parse_declaration_inner(struct Translation_Data *translation_data,struct Scope *scope,struct Queue *where_to_push_objects,struct Queue *where_to_push_function_definitions,_Bool parse_function_definitions)F diff --git a/src/misc/gcc_string.c b/src/misc/gcc_string.c --- a/src/misc/gcc_string.c +++ b/src/misc/gcc_string.creturn ret;}- char* gstrn_append(const char *lead,const char *follower,size_t overall_limit)+ char* gstrn_append(char *lead,char *follower,size_t overall_limit){- char *ret,*hold;+ char *ret;size_t lead_size;size_t follower_size;lead_size=gstrnlen(lead,overall_limit);- follower_size=gstrnlen(lead,overall_limit);+ follower_size=gstrnlen(follower,overall_limit);if(lead_size+follower_size>overall_limit)return gstrncpy("",1);- hold=ret=wonky_malloc(lead_size+follower_size);- while(*(hold++)=*(lead++));- hold--;- while(*(hold++)=*(follower++));+ ret=wonky_malloc(lead_size+follower_size);+ gmemmove(ret,lead,lead_size);+ gmemmove(ret+lead_size,follower,follower_size);return ret;}F diff --git a/src/misc/gcc_string.h b/src/misc/gcc_string.h --- a/src/misc/gcc_string.h +++ b/src/misc/gcc_string.hchar* gstr_dup(const char *first,const char *last,size_t limit);char* gstr_to_heap(const char *literal);void gmemmove(void *where_to,void *from_where,size_t how_many_bytes);- char* gstrn_append(const char *lead,const char *follower,size_t overall_limit);+ char* gstrn_append(char *lead,char *follower,size_t overall_limit);#endifF diff --git a/src/semantics/program/translation_unit.c b/src/semantics/program/translation_unit.c --- a/src/semantics/program/translation_unit.c +++ b/src/semantics/program/translation_unit.chold_token=token_ptr_get_token_under_pointer_inner(token_pointer);- if(hold_token->type==KW_STRING)+ if(hold_token->type==KW_STRING && token_pointer->state!=TOKEN_POINTER_STATE_PREPROCESSING){while( (hold_hold_hold_token=token_ptr_check_next_normal_token(token_pointer))->type==KW_STRING|| hold_hold_hold_token->type==PKW_FILE_MACRO{struct token *ret;+ token_ptr_goto_next_normal_token(token_pointer);+if(token_ptr_has_buffered_tokens(token_pointer))return token_ptr_check_buffered_token(token_pointer);void token_ptr_execute_include_directive(struct Token_Pointer *ptr,struct token_include_directive *include_directive){struct token *hold_token;+ struct Preprocessing_Translation_Unit *hold_unit;+ char *include_name;++ wonky_assert(include_directive->tokens->first);++ token_ptr_goto_next_token(ptr);+ token_ptr_jump_to(ptr,include_directive->tokens->first);ptr->state=TOKEN_POINTER_STATE_PREPROCESSING;-+hold_token=token_ptr_get_token_under_pointer(ptr);++ ptr->state=TOKEN_POINTER_STATE_NORMAL;+if(hold_token->type==KW_STRING){-+ if(ptr->context->current_token_node!=NULL)+ {+ push_token_ptr_error("Unexpected token at end of include directive",ptr);+ ptr->state=TOKEN_POINTER_STATE_ERROR;+ return;+ }+ include_name=((struct token_string*)hold_token)->constant->value;+ hold_unit=program_get_translation_unit(ptr->program,include_name,gstrnlen(include_name,100));++ if(hold_unit->tokens->first)+ token_ptr_jump_to(ptr,hold_unit->tokens->first);+ else+ token_ptr_goto_next_token(ptr);+ }else if(hold_token->type==KW_LESS)+ {+ ptr->state=TOKEN_POINTER_STATE_PREPROCESSING;+ include_name=gstrncpy("",2);+ hold_token=token_ptr_get_token_under_pointer(ptr);+ while(hold_token->type!=KW_MORE && hold_token->type!=KW_MORE_EQ)+ {+ switch(hold_token->type)+ {+ case KW_ID:+ include_name=gstrn_append(include_name,((struct token_identifier*)hold_token)->id->data,100);+ break;+ case KW_DIV:+ include_name=gstrn_append(include_name,"/",100);+ break;+ case KW_DOT:+ include_name=gstrn_append(include_name,".",100);+ break;+ default:+ push_token_ptr_error("Unsupported symbol found inside filename in include directive with angular brackets and macro expansion",ptr);+ ptr->state=TOKEN_POINTER_STATE_ERROR;+ return;/*NOTICE*/+ }+ hold_token=token_ptr_get_token_under_pointer(ptr);+ }+ ptr->state=TOKEN_POINTER_STATE_NORMAL;++ if(ptr->context->current_token_node!=NULL)+ {+ push_token_ptr_error("Unexpected token at end of include directive",ptr);+ ptr->state=TOKEN_POINTER_STATE_ERROR;+ return;+ }++ hold_unit=program_get_translation_unit(ptr->program,include_name,gstrnlen(include_name,100));++ if(hold_unit->tokens->first)+ token_ptr_jump_to(ptr,hold_unit->tokens->first);+ else+ token_ptr_goto_next_token(ptr);+ }else if(hold_token->type==KW_LESS_EQ)+ {+ push_token_ptr_error("'=' is not supported inside filename in include directive with angular brackets and macro expansion",ptr);+ ptr->state=TOKEN_POINTER_STATE_ERROR;+ return;}- ptr->state=TOKEN_POINTER_STATE_NORMAL;- token_ptr_goto_next_token(ptr);++}void token_ptr_execute_if_directive(struct Token_Pointer *ptr,struct token_if_directive *if_directive){}_Bool token_ptr_has_remaining_tokens(struct Token_Pointer *ptr){+ if(ptr->state==TOKEN_POINTER_STATE_ERROR)+ return 0;+if(token_ptr_has_buffered_tokens(ptr)){return 1;}else{++ while(ptr->context->current_token_node==NULL &&+ ptr->state!=TOKEN_POINTER_STATE_PREPROCESSING &&+ ptr->call_stack->size>0)+ {+ delete_token_ptr_context(ptr->context);+ ptr->context=Stack_Pop(ptr->call_stack);+ }return ptr->context->current_token_node!=NULL;}}{struct Token_Pointer_Context *new_context;+ if(ptr->call_stack->size>1000)+ {+ push_token_ptr_error("Preprocessing bounds exceeded",ptr);+ return;+ }new_context=get_token_ptr_context(where_to);Stack_Push(ptr->call_stack,ptr->context);ptr->context=new_context;}+ void delete_token_ptr_context(struct Token_Pointer_Context *context)+ {+ wonky_free(context);+ }#endifF diff --git a/src/semantics/program/translation_unit.h b/src/semantics/program/translation_unit.h --- a/src/semantics/program/translation_unit.h +++ b/src/semantics/program/translation_unit.hstruct token* token_ptr_check_buffered_token(struct Token_Pointer *ptr);void token_ptr_jump_to(struct Token_Pointer *ptr,struct Queue_Node *where_to);-+ void delete_token_ptr_context(struct Token_Pointer_Context *context);#endifF diff --git a/src/semantics/program/translation_unit.hh b/src/semantics/program/translation_unit.hh --- a/src/semantics/program/translation_unit.hh +++ b/src/semantics/program/translation_unit.hh{TOKEN_POINTER_STATE_NORMAL,TOKEN_POINTER_STATE_PREPROCESSING,+ TOKEN_POINTER_STATE_ERROR,TOKEN_POINTER_STATE_END};F diff --git a/src/syntax/identifier/identifier.c b/src/syntax/identifier/identifier.c --- a/src/syntax/identifier/identifier.c +++ b/src/syntax/identifier/identifier.cstruct identifier *ret;ret=wonky_malloc(sizeof(struct identifier));ret->size=size;- ret->data=data;+ ret->data=wonky_malloc(size+1);+ gmemmove(ret->data,data,size);+ ret->data[size]='\0';ret->last_defined_macro_with_this_id=NULL;ret->last_use_as_a_macro_argument=NULL;F diff --git a/src/syntax/token/token.c b/src/syntax/token/token.c --- a/src/syntax/token/token.c +++ b/src/syntax/token/token.creturn (struct token*)get_string_token(KW_STRING,current_location,current_location,"Time could not be determined",sizeof("Time could not be determined"));}+ char* get_string_from_token(struct token* token)+ {++ }#endifF diff --git a/src/syntax/token/token.h b/src/syntax/token/token.h --- a/src/syntax/token/token.h +++ b/src/syntax/token/token.hstruct token* get_stdc_hosted_macro_token(struct Source_Location *current_location,struct Source_Location *previous_location);struct token* get_stdc_version_macro_token(struct Source_Location *current_location,struct Source_Location *previous_location);struct token* get_time_macro_token(struct Source_Location *current_location,struct Source_Location *previous_location);+ char* get_string_from_token(struct token* token);#endifF diff --git a/tests/test_declaration3.c b/tests/test_declaration3.c new file mode 100644 --- /dev/null +++ b/tests/test_declaration3.c+ main()+ {+ return 0;+ }