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.c
args);
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 one
struct 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.c
return 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.h
char* 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);
#endif
F 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.c
hold_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);
+ }
#endif
F 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.h
struct 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);
#endif
F 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.c
struct 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.c
return (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)
+ {
+
+ }
#endif
F 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.h
struct 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);
#endif
F 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;
+ }