diff --git a/tcc.c b/tcc.c index bf84795..de9a257 100644 --- a/tcc.c +++ b/tcc.c @@ -209,8 +209,8 @@ typedef struct AttributeDef { #define IO_BUF_SIZE 8192 typedef struct BufferedFile { - unsigned char *buf_ptr; - unsigned char *buf_end; + uint8_t *buf_ptr; + uint8_t *buf_end; int fd; int line_num; /* current line number - here to simply code */ int ifndef_macro; /* #ifndef macro / #endif search */ @@ -1501,7 +1501,7 @@ BufferedFile *tcc_open(TCCState *s1, const char *filename) bf->buf_end = bf->buffer; bf->buffer[0] = CH_EOB; /* put eob symbol */ pstrcpy(bf->filename, sizeof(bf->filename), filename); - bf->line_num = 0; + bf->line_num = 1; bf->ifndef_macro = 0; bf->ifdef_stack_ptr = s1->ifdef_stack_ptr; // printf("opening '%s'\n", filename); @@ -1515,8 +1515,8 @@ void tcc_close(BufferedFile *bf) tcc_free(bf); } -/* fill input buffer and return next char */ -int tcc_getc_slow(BufferedFile *bf) +/* fill input buffer and peek next char */ +static int tcc_peekc_slow(BufferedFile *bf) { int len; /* only tries to read if really end of buffer */ @@ -1534,7 +1534,7 @@ int tcc_getc_slow(BufferedFile *bf) *bf->buf_end = CH_EOB; } if (bf->buf_ptr < bf->buf_end) { - return *bf->buf_ptr++; + return bf->buf_ptr[0]; } else { bf->buf_ptr = bf->buf_end; return CH_EOF; @@ -1545,15 +1545,15 @@ int tcc_getc_slow(BufferedFile *bf) void handle_eob(void) { /* no need to do anything if not at EOB */ - if (file->buf_ptr <= file->buf_end) + if (file->buf_ptr < file->buf_end) return; - ch = tcc_getc_slow(file); + ch = tcc_peekc_slow(file); } /* read next char from current input file and handle end of input buffer */ static inline void inp(void) { - ch = *(file->buf_ptr++); + ch = *(++(file->buf_ptr)); /* end of buffer/file handling */ if (ch == CH_EOB) handle_eob(); @@ -1596,51 +1596,87 @@ static void parse_line_comment(void) /* single line C++ comments */ /* XXX: accept '\\\n' ? */ inp(); - while (ch != '\n' && ch != TOK_EOF) + while (ch != '\n' && ch != CH_EOF) inp(); } static void parse_comment(void) { + uint8_t *p; + int c; + /* C comments */ minp(); + p = file->buf_ptr; for(;;) { /* fast skip loop */ - while (ch != '\n' && ch != '*' && ch != TOK_EOF) - inp(); + for(;;) { + c = *p; + if (c == '\n' || c == '*' || c == '\\') + break; + p++; + c = *p; + if (c == '\n' || c == '*' || c == '\\') + break; + p++; + } /* now we can handle all the cases */ - if (ch == '\n') { + if (c == '\n') { file->line_num++; - inp(); - } else if (ch == '*') { + p++; + } else if (c == '*') { + p++; for(;;) { - inp(); - if (ch == '/') { + c = *p; + if (c == '/') { goto end_of_comment; - } else if (ch == '\\') { - inp(); - if (ch == '\n') { + } else if (c == '\\') { + if (p >= file->buf_end) { + file->buf_ptr = p; + handle_eob(); + p = file->buf_ptr; + if (p >= file->buf_end) + goto eof_found; + continue; + } + p++; + c = *p; + if (c == '\n') { file->line_num++; - inp(); - } else if (ch == '\r') { - inp(); - if (ch != '\n') + p++; + } else if (c == '\r') { + p++; + c = *p; + if (c != '\n') break; file->line_num++; - inp(); + p++; } else { break; } - } else if (ch != '*') { + } else if (c == '*') { + p++; + } else { break; } } + } else if (p >= file->buf_end) { + file->buf_ptr = p; + handle_eob(); + p = file->buf_ptr; + if (p >= file->buf_end) { + eof_found: + error("unexpected end of file in comment"); + } } else { - error("unexpected end of file in comment"); + /* stray */ + p++; } } end_of_comment: - inp(); + p++; + file->buf_ptr = p; + ch = *p; } #define cinp minp @@ -2127,6 +2163,7 @@ static void preprocess(int is_bof) } else if (ch == '\"') { c = ch; read_name: + /* XXX: better stray handling */ minp(); q = buf; while (ch != c && ch != '\n' && ch != CH_EOF) { @@ -2135,6 +2172,7 @@ static void preprocess(int is_bof) minp(); } *q = '\0'; + minp(); #if 0 /* eat all spaces and comments after include */ /* XXX: slightly incorrect */ @@ -2172,7 +2210,6 @@ static void preprocess(int is_bof) } } - ch = '\n'; e = search_cached_include(s1, c, buf); if (e && define_find(e->ifndef_macro)) { /* no need to parse the include because the 'ifndef macro' @@ -2229,7 +2266,8 @@ static void preprocess(int is_bof) if (do_debug) { put_stabs(file->filename, N_BINCL, 0, 0, 0); } - tok_flags |= TOK_FLAG_BOF; + tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL; + ch = file->buf_ptr[0]; goto the_end; } break; @@ -2761,6 +2799,10 @@ static inline void next_nomacro1(void) goto redo_no_start; case '\\': + /* first look if it is in fact an end of buffer */ + handle_eob(); + if (ch != '\\') + goto redo_no_start; handle_stray(); goto redo_no_start; @@ -7641,7 +7683,7 @@ static int tcc_compile(TCCState *s1) s1->nb_errors = 0; s1->error_set_jmp_enabled = 1; - ch = '\n'; /* XXX: suppress that*/ + ch = file->buf_ptr[0]; tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; next(); decl(VT_CONST); @@ -7719,7 +7761,7 @@ void tcc_define_symbol(TCCState *s1, const char *sym, const char *value) s1->include_stack_ptr = s1->include_stack; /* parse with define parser */ - ch = '\n'; /* needed to parse correctly first preprocessor command */ + ch = file->buf_ptr[0]; next_nomacro(); parse_define(); file = NULL; diff --git a/tccelf.c b/tccelf.c index e534172..430c396 100644 --- a/tccelf.c +++ b/tccelf.c @@ -1890,7 +1890,8 @@ static int tcc_load_ldscript(TCCState *s1) char filename[1024]; int t; - inp(); + ch = file->buf_ptr[0]; + handle_eob(); for(;;) { t = ld_next(s1, cmd, sizeof(cmd)); if (t == LD_TOK_EOF)