From 64b66547c713ea23bc16a741bb2ad2ccdff3c1c8 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Wed, 15 Jul 2020 14:19:51 -0400 Subject: require #include filename to be a string literal --- allocator.c | 9 +++++++++ copy.c | 1 - misc.c | 4 ++++ parse.c | 8 +++++--- types.c | 30 +++++++++++++----------------- types.h | 2 +- 6 files changed, 32 insertions(+), 22 deletions(-) diff --git a/allocator.c b/allocator.c index 25ac923..8c2859f 100644 --- a/allocator.c +++ b/allocator.c @@ -104,6 +104,14 @@ static void *allocr_realloc(Allocator *a, void *data, size_t old_size, size_t ne return ret; } +static char *allocr_str_to_cstr(Allocator *a, String s) { + size_t len = s.len; + char *ret = allocr_malloc(a, len + 1); + memcpy(ret, s.str, len); + ret[len] = 0; + return ret; +} + static void allocr_free_all(Allocator *a) { for (Page *page = a->first; page;) { Page *next = page->next; @@ -111,3 +119,4 @@ static void allocr_free_all(Allocator *a) { page = next; } } + diff --git a/copy.c b/copy.c index 630f556..0c2d3e5 100644 --- a/copy.c +++ b/copy.c @@ -359,7 +359,6 @@ static void copy_stmt(Copier *c, Statement *out, Statement *in) { case STMT_INCLUDE: out->inc = copier_malloc(c, sizeof *out->inc); *out->inc = *in->inc; - copy_expr(c, &out->inc->filename, &in->inc->filename); break; case STMT_EXPR: out->expr = copy_expr_(c, in->expr); diff --git a/misc.c b/misc.c index 8354b69..429e458 100644 --- a/misc.c +++ b/misc.c @@ -74,6 +74,10 @@ static inline bool streq(const char *a, const char *b) { return strcmp(a, b) == 0; } +static inline void fprint_string(FILE *out, String s) { + fwrite(s.str, 1, s.len, out); +} + static inline U32 rand_u32(U32 seed) { U64 seed64 = (U64)seed; return (U32)((seed64 * 0x832f0fda4e1a8642 + 0x41d49cd5459a2ab4) >> 32); diff --git a/parse.c b/parse.c index 2f47d9a..aa6169c 100644 --- a/parse.c +++ b/parse.c @@ -2489,10 +2489,12 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { i->flags |= INC_FORCED; ++t->token; } - if (!parse_expr(p, &i->filename, expr_find_end(p, EXPR_CAN_END_WITH_COMMA))) { - tokr_skip_semicolon(t); + if (t->token->kind != TOKEN_LITERAL_STR) { + tokr_err(t, "Expected string literal for #include file name."); return false; } + i->filename = t->token->str; + ++t->token; if (token_is_kw(t->token, KW_COMMA)) { ++t->token; if (t->token->kind != TOKEN_IDENT) { @@ -2883,7 +2885,7 @@ static void fprint_stmt(FILE *out, Statement *s) { case STMT_INCLUDE: { Include *i = s->inc; fprintf(out, "#include "); - fprint_expr(out, &i->filename); + fprint_string(out, i->filename); fprintf(out, ";\n"); } break; case STMT_MESSAGE: { diff --git a/types.c b/types.c index c9bbec6..885feed 100644 --- a/types.c +++ b/types.c @@ -4085,9 +4085,8 @@ top: } break; case STMT_INCLUDE: { Include *inc = s->inc; - char *filename = eval_expr_as_cstr(tr, &inc->filename, "import filename"); - if (!filename) - return false; + char *filename = allocr_str_to_cstr(tr->allocr, inc->filename); + size_t filename_len = inc->filename.len; Namespace *prev_nms = tr->nms; Block *prev_block = tr->block; IncludedFile *inc_f = NULL; @@ -4145,24 +4144,23 @@ top: } if (!(inc->flags & INC_FORCED)) { - size_t filename_len = strlen(filename); if (streq(filename, tr->gctx->main_file->filename)) { err_print(s->where, "Circular #include detected. You can add #force to this #include to force it to be included."); - success = false; goto nms_done; + success = false; goto inc_end; } inc_f = str_hash_table_get(&tr->included_files, filename, filename_len); if (inc_f) { // has already been included if (inc_f->flags & INC_FILE_INCLUDING) { err_print(s->where, "Circular #include detected. You can add #force to this #include to force it to be included."); - success = false; goto nms_done; + success = false; goto inc_end; } if (s->kind == STMT_INLINE_BLOCK) s->inline_block = NULL; // nothing needed here // just set ident declarations if (!include_stmts_link_to_nms(tr, inc_f->main_nms, inc_f->stmts)) { - success = false; goto nms_done; + success = false; goto inc_end; } - goto nms_done; + goto inc_end; } inc_f = str_hash_table_insert(&tr->included_files, filename, filename_len); inc_f->flags |= INC_FILE_INCLUDING; @@ -4171,7 +4169,7 @@ top: { char *contents = read_file_contents(tr->allocr, filename, s->where); if (!contents) { - success = false; goto nms_done; + success = false; goto inc_end; } Tokenizer tokr; @@ -4182,14 +4180,14 @@ top: file->ctx = tr->gctx->err_ctx; if (!tokenize_file(&tokr, file)) { - success = false; goto nms_done; + success = false; goto inc_end; } Parser parser; parser_create(&parser, tr->globals, &tokr, tr->allocr, tr->gctx); parser.block = tr->block; ParsedFile parsed_file; if (!parse_file(&parser, &parsed_file)) { - success = false; goto nms_done; + success = false; goto inc_end; } Statement *stmts_inc = parsed_file.stmts; if (inc_f) { @@ -4198,18 +4196,16 @@ top: if (s->kind == STMT_INLINE_BLOCK) s->inline_block = stmts_inc; arr_foreach(stmts_inc, Statement, s_incd) { if (!types_stmt(tr, s_incd)) { - success = false; goto nms_done; + success = false; goto inc_end; } } if (inc_nms) { inc_nms->body.stmts = stmts_inc; } } - nms_done: - if (inc_nms) { - tr->nms = prev_nms; - tr->block = prev_block; - } + inc_end: + tr->nms = prev_nms; + tr->block = prev_block; if (inc_f) inc_f->flags &= (IncFileFlags)~(IncFileFlags)INC_FILE_INCLUDING; if (!success) { // give up on typing if #include failed diff --git a/types.h b/types.h index 99648ad..9028624 100644 --- a/types.h +++ b/types.h @@ -929,7 +929,7 @@ enum { typedef struct { U8 flags; - Expression filename; + String filename; char *nms; // NULL if this is just a plain old #include, otherwise string which can be used with ident_get } Include; -- cgit v1.2.3