2009-05-06 02:17:11 +08:00
|
|
|
/*
|
|
|
|
* TCC - Tiny C Compiler
|
2015-07-30 04:53:57 +08:00
|
|
|
*
|
2009-05-06 02:17:11 +08:00
|
|
|
* Copyright (c) 2001-2004 Fabrice Bellard
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
2019-12-11 07:37:18 +08:00
|
|
|
#define USING_GLOBALS
|
2009-12-20 08:53:49 +08:00
|
|
|
#include "tcc.h"
|
|
|
|
|
2022-07-16 04:31:24 +08:00
|
|
|
/* #define to 1 to enable (see parse_pp_string()) */
|
|
|
|
#define ACCEPT_LF_IN_STRINGS 0
|
|
|
|
|
2009-12-20 08:53:49 +08:00
|
|
|
/********************************************************/
|
|
|
|
/* global variables */
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_DATA int tok_flags;
|
|
|
|
ST_DATA int parse_flags;
|
|
|
|
|
|
|
|
ST_DATA struct BufferedFile *file;
|
2022-08-18 16:43:28 +08:00
|
|
|
ST_DATA int tok;
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_DATA CValue tokc;
|
|
|
|
ST_DATA const int *macro_ptr;
|
|
|
|
ST_DATA CString tokcstr; /* current parsed string, if any */
|
|
|
|
|
|
|
|
/* display benchmark infos */
|
|
|
|
ST_DATA int tok_ident;
|
|
|
|
ST_DATA TokenSym **table_ident;
|
|
|
|
|
2009-12-20 08:53:49 +08:00
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static TokenSym *hash_ident[TOK_HASH_SIZE];
|
|
|
|
static char token_buf[STRING_MAX_SIZE + 1];
|
|
|
|
static CString cstr_buf;
|
|
|
|
static TokenString tokstr_buf;
|
|
|
|
static unsigned char isidnum_table[256 - CH_EOF];
|
|
|
|
static int pp_debug_tok, pp_debug_symv;
|
|
|
|
static int pp_once;
|
|
|
|
static int pp_expr;
|
|
|
|
static int pp_counter;
|
|
|
|
static void tok_print(const char *msg, const int *str);
|
|
|
|
|
|
|
|
static struct TinyAlloc *toksym_alloc;
|
|
|
|
static struct TinyAlloc *tokstr_alloc;
|
|
|
|
|
|
|
|
static TokenString *macro_stack;
|
2009-05-06 02:30:39 +08:00
|
|
|
|
2015-07-30 04:53:57 +08:00
|
|
|
static const char tcc_keywords[] =
|
2009-05-06 02:30:39 +08:00
|
|
|
#define DEF(id, str) str "\0"
|
|
|
|
#include "tcctok.h"
|
|
|
|
#undef DEF
|
|
|
|
;
|
|
|
|
|
|
|
|
/* WARNING: the content of this string encodes token numbers */
|
2009-07-19 04:07:42 +08:00
|
|
|
static const unsigned char tok_two_chars[] =
|
2014-03-29 23:40:54 +08:00
|
|
|
/* outdated -- gr
|
2009-07-19 04:07:42 +08:00
|
|
|
"<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253"
|
|
|
|
"-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
|
2014-03-29 23:40:54 +08:00
|
|
|
*/{
|
|
|
|
'<','=', TOK_LE,
|
|
|
|
'>','=', TOK_GE,
|
|
|
|
'!','=', TOK_NE,
|
|
|
|
'&','&', TOK_LAND,
|
|
|
|
'|','|', TOK_LOR,
|
|
|
|
'+','+', TOK_INC,
|
|
|
|
'-','-', TOK_DEC,
|
|
|
|
'=','=', TOK_EQ,
|
|
|
|
'<','<', TOK_SHL,
|
2014-03-31 21:24:32 +08:00
|
|
|
'>','>', TOK_SAR,
|
2014-03-29 23:40:54 +08:00
|
|
|
'+','=', TOK_A_ADD,
|
|
|
|
'-','=', TOK_A_SUB,
|
|
|
|
'*','=', TOK_A_MUL,
|
|
|
|
'/','=', TOK_A_DIV,
|
|
|
|
'%','=', TOK_A_MOD,
|
|
|
|
'&','=', TOK_A_AND,
|
|
|
|
'^','=', TOK_A_XOR,
|
|
|
|
'|','=', TOK_A_OR,
|
|
|
|
'-','>', TOK_ARROW,
|
2017-09-25 00:57:48 +08:00
|
|
|
'.','.', TOK_TWODOTS,
|
2014-03-29 23:40:54 +08:00
|
|
|
'#','#', TOK_TWOSHARPS,
|
2020-12-18 07:33:44 +08:00
|
|
|
'#','#', TOK_PPJOIN,
|
2014-03-29 23:40:54 +08:00
|
|
|
0
|
|
|
|
};
|
2009-05-06 02:30:39 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static void next_nomacro(void);
|
2009-12-20 08:53:49 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void skip(int c)
|
2009-12-20 08:53:49 +08:00
|
|
|
{
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok != c)
|
|
|
|
tcc_error("'%c' expected (got \"%s\")", c, get_tok_str(tok, &tokc));
|
|
|
|
next();
|
2009-12-20 08:53:49 +08:00
|
|
|
}
|
2009-05-12 00:45:56 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void expect(const char *msg)
|
2011-08-11 22:55:30 +08:00
|
|
|
{
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("%s expected", msg);
|
2011-08-11 22:55:30 +08:00
|
|
|
}
|
|
|
|
|
2016-10-02 02:26:50 +08:00
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
/* Custom allocator for tiny objects */
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2016-10-02 02:26:50 +08:00
|
|
|
#define USE_TAL
|
|
|
|
|
|
|
|
#ifndef USE_TAL
|
2021-10-22 13:39:54 +08:00
|
|
|
#define tal_free(al, p) tcc_free(p)
|
|
|
|
#define tal_realloc(al, p, size) tcc_realloc(p, size)
|
|
|
|
#define tal_new(a,b,c)
|
|
|
|
#define tal_delete(a)
|
2016-10-02 02:26:50 +08:00
|
|
|
#else
|
|
|
|
#if !defined(MEM_DEBUG)
|
2021-10-22 13:39:54 +08:00
|
|
|
#define tal_free(al, p) tal_free_impl(al, p)
|
|
|
|
#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size)
|
2016-10-02 02:26:50 +08:00
|
|
|
#define TAL_DEBUG_PARAMS
|
|
|
|
#else
|
|
|
|
#define TAL_DEBUG 1
|
2016-10-10 02:33:14 +08:00
|
|
|
//#define TAL_INFO 1 /* collect and dump allocators stats */
|
2021-10-22 13:39:54 +08:00
|
|
|
#define tal_free(al, p) tal_free_impl(al, p, __FILE__, __LINE__)
|
|
|
|
#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size, __FILE__, __LINE__)
|
2016-10-02 02:26:50 +08:00
|
|
|
#define TAL_DEBUG_PARAMS , const char *file, int line
|
2017-06-05 19:21:39 +08:00
|
|
|
#define TAL_DEBUG_FILE_LEN 40
|
2016-10-02 02:26:50 +08:00
|
|
|
#endif
|
2016-10-10 02:33:14 +08:00
|
|
|
|
|
|
|
#define TOKSYM_TAL_SIZE (768 * 1024) /* allocator for tiny TokenSym in table_ident */
|
|
|
|
#define TOKSTR_TAL_SIZE (768 * 1024) /* allocator for tiny TokenString instances */
|
|
|
|
#define CSTR_TAL_SIZE (256 * 1024) /* allocator for tiny CString instances */
|
|
|
|
#define TOKSYM_TAL_LIMIT 256 /* prefer unique limits to distinguish allocators debug msgs */
|
|
|
|
#define TOKSTR_TAL_LIMIT 128 /* 32 * sizeof(int) */
|
|
|
|
#define CSTR_TAL_LIMIT 1024
|
2016-10-02 02:26:50 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
typedef struct TinyAlloc {
|
|
|
|
unsigned limit;
|
|
|
|
unsigned size;
|
|
|
|
uint8_t *buffer;
|
|
|
|
uint8_t *p;
|
|
|
|
unsigned nb_allocs;
|
|
|
|
struct TinyAlloc *next, *top;
|
|
|
|
#ifdef TAL_INFO
|
|
|
|
unsigned nb_peak;
|
|
|
|
unsigned nb_total;
|
|
|
|
unsigned nb_missed;
|
|
|
|
uint8_t *peak_p;
|
|
|
|
#endif
|
|
|
|
} TinyAlloc;
|
|
|
|
|
2016-10-02 02:26:50 +08:00
|
|
|
typedef struct tal_header_t {
|
2016-12-19 05:05:42 +08:00
|
|
|
unsigned size;
|
2016-10-02 02:26:50 +08:00
|
|
|
#ifdef TAL_DEBUG
|
|
|
|
int line_num; /* negative line_num used for double free check */
|
|
|
|
char file_name[TAL_DEBUG_FILE_LEN + 1];
|
|
|
|
#endif
|
|
|
|
} tal_header_t;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2016-04-17 21:22:50 +08:00
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static TinyAlloc *tal_new(TinyAlloc **pal, unsigned limit, unsigned size)
|
2016-04-17 21:22:50 +08:00
|
|
|
{
|
2021-10-22 13:39:54 +08:00
|
|
|
TinyAlloc *al = tcc_mallocz(sizeof(TinyAlloc));
|
|
|
|
al->p = al->buffer = tcc_malloc(size);
|
2016-04-17 21:22:50 +08:00
|
|
|
al->limit = limit;
|
|
|
|
al->size = size;
|
|
|
|
if (pal) *pal = al;
|
|
|
|
return al;
|
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static void tal_delete(TinyAlloc *al)
|
2016-04-17 21:22:50 +08:00
|
|
|
{
|
|
|
|
TinyAlloc *next;
|
|
|
|
|
|
|
|
tail_call:
|
|
|
|
if (!al)
|
|
|
|
return;
|
|
|
|
#ifdef TAL_INFO
|
|
|
|
fprintf(stderr, "limit=%5d, size=%5g MB, nb_peak=%6d, nb_total=%8d, nb_missed=%6d, usage=%5.1f%%\n",
|
|
|
|
al->limit, al->size / 1024.0 / 1024.0, al->nb_peak, al->nb_total, al->nb_missed,
|
|
|
|
(al->peak_p - al->buffer) * 100.0 / al->size);
|
|
|
|
#endif
|
|
|
|
#ifdef TAL_DEBUG
|
|
|
|
if (al->nb_allocs > 0) {
|
2016-10-02 02:26:50 +08:00
|
|
|
uint8_t *p;
|
2016-12-19 05:57:03 +08:00
|
|
|
fprintf(stderr, "TAL_DEBUG: memory leak %d chunk(s) (limit= %d)\n",
|
2016-04-17 21:22:50 +08:00
|
|
|
al->nb_allocs, al->limit);
|
2016-10-02 02:26:50 +08:00
|
|
|
p = al->buffer;
|
2016-04-17 21:22:50 +08:00
|
|
|
while (p < al->p) {
|
|
|
|
tal_header_t *header = (tal_header_t *)p;
|
|
|
|
if (header->line_num > 0) {
|
2016-12-19 05:57:03 +08:00
|
|
|
fprintf(stderr, "%s:%d: chunk of %d bytes leaked\n",
|
2016-04-17 21:22:50 +08:00
|
|
|
header->file_name, header->line_num, header->size);
|
|
|
|
}
|
|
|
|
p += header->size + sizeof(tal_header_t);
|
|
|
|
}
|
2016-12-19 05:05:42 +08:00
|
|
|
#if MEM_DEBUG-0 == 2
|
|
|
|
exit(2);
|
|
|
|
#endif
|
2016-04-17 21:22:50 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
next = al->next;
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_free(al->buffer);
|
|
|
|
tcc_free(al);
|
2016-04-17 21:22:50 +08:00
|
|
|
al = next;
|
|
|
|
goto tail_call;
|
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static void tal_free_impl(TinyAlloc *al, void *p TAL_DEBUG_PARAMS)
|
2016-04-17 21:22:50 +08:00
|
|
|
{
|
|
|
|
if (!p)
|
|
|
|
return;
|
|
|
|
tail_call:
|
|
|
|
if (al->buffer <= (uint8_t *)p && (uint8_t *)p < al->buffer + al->size) {
|
|
|
|
#ifdef TAL_DEBUG
|
|
|
|
tal_header_t *header = (((tal_header_t *)p) - 1);
|
|
|
|
if (header->line_num < 0) {
|
2016-12-19 05:05:42 +08:00
|
|
|
fprintf(stderr, "%s:%d: TAL_DEBUG: double frees chunk from\n",
|
2016-04-17 21:22:50 +08:00
|
|
|
file, line);
|
2016-12-19 05:05:42 +08:00
|
|
|
fprintf(stderr, "%s:%d: %d bytes\n",
|
|
|
|
header->file_name, (int)-header->line_num, (int)header->size);
|
2016-04-17 21:22:50 +08:00
|
|
|
} else
|
|
|
|
header->line_num = -header->line_num;
|
|
|
|
#endif
|
|
|
|
al->nb_allocs--;
|
|
|
|
if (!al->nb_allocs)
|
|
|
|
al->p = al->buffer;
|
|
|
|
} else if (al->next) {
|
|
|
|
al = al->next;
|
|
|
|
goto tail_call;
|
|
|
|
}
|
|
|
|
else
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_free(p);
|
2016-04-17 21:22:50 +08:00
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static void *tal_realloc_impl(TinyAlloc **pal, void *p, unsigned size TAL_DEBUG_PARAMS)
|
2016-04-17 21:22:50 +08:00
|
|
|
{
|
|
|
|
tal_header_t *header;
|
|
|
|
void *ret;
|
|
|
|
int is_own;
|
2016-12-19 05:05:42 +08:00
|
|
|
unsigned adj_size = (size + 3) & -4;
|
2016-04-17 21:22:50 +08:00
|
|
|
TinyAlloc *al = *pal;
|
|
|
|
|
|
|
|
tail_call:
|
|
|
|
is_own = (al->buffer <= (uint8_t *)p && (uint8_t *)p < al->buffer + al->size);
|
|
|
|
if ((!p || is_own) && size <= al->limit) {
|
2020-01-18 05:58:39 +08:00
|
|
|
if (al->p - al->buffer + adj_size + sizeof(tal_header_t) < al->size) {
|
2016-04-17 21:22:50 +08:00
|
|
|
header = (tal_header_t *)al->p;
|
|
|
|
header->size = adj_size;
|
|
|
|
#ifdef TAL_DEBUG
|
2016-10-02 02:26:50 +08:00
|
|
|
{ int ofs = strlen(file) - TAL_DEBUG_FILE_LEN;
|
2016-04-17 21:22:50 +08:00
|
|
|
strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), TAL_DEBUG_FILE_LEN);
|
|
|
|
header->file_name[TAL_DEBUG_FILE_LEN] = 0;
|
2016-10-02 02:26:50 +08:00
|
|
|
header->line_num = line; }
|
2016-04-17 21:22:50 +08:00
|
|
|
#endif
|
|
|
|
ret = al->p + sizeof(tal_header_t);
|
|
|
|
al->p += adj_size + sizeof(tal_header_t);
|
|
|
|
if (is_own) {
|
|
|
|
header = (((tal_header_t *)p) - 1);
|
2020-05-24 02:27:43 +08:00
|
|
|
if (p) memcpy(ret, p, header->size);
|
2016-04-17 21:22:50 +08:00
|
|
|
#ifdef TAL_DEBUG
|
|
|
|
header->line_num = -header->line_num;
|
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
al->nb_allocs++;
|
|
|
|
}
|
|
|
|
#ifdef TAL_INFO
|
|
|
|
if (al->nb_peak < al->nb_allocs)
|
|
|
|
al->nb_peak = al->nb_allocs;
|
|
|
|
if (al->peak_p < al->p)
|
|
|
|
al->peak_p = al->p;
|
|
|
|
al->nb_total++;
|
|
|
|
#endif
|
|
|
|
return ret;
|
2016-04-23 01:32:15 +08:00
|
|
|
} else if (is_own) {
|
2016-04-17 21:22:50 +08:00
|
|
|
al->nb_allocs--;
|
2021-10-22 13:39:54 +08:00
|
|
|
ret = tal_realloc(*pal, 0, size);
|
2016-04-17 21:22:50 +08:00
|
|
|
header = (((tal_header_t *)p) - 1);
|
2020-05-24 02:27:43 +08:00
|
|
|
if (p) memcpy(ret, p, header->size);
|
2016-04-17 21:22:50 +08:00
|
|
|
#ifdef TAL_DEBUG
|
|
|
|
header->line_num = -header->line_num;
|
|
|
|
#endif
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
if (al->next) {
|
|
|
|
al = al->next;
|
|
|
|
} else {
|
|
|
|
TinyAlloc *bottom = al, *next = al->top ? al->top : al;
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
al = tal_new(pal, next->limit, next->size * 2);
|
2016-04-17 21:22:50 +08:00
|
|
|
al->next = next;
|
|
|
|
bottom->top = al;
|
|
|
|
}
|
|
|
|
goto tail_call;
|
|
|
|
}
|
|
|
|
if (is_own) {
|
|
|
|
al->nb_allocs--;
|
2021-10-22 13:39:54 +08:00
|
|
|
ret = tcc_malloc(size);
|
2016-04-17 21:22:50 +08:00
|
|
|
header = (((tal_header_t *)p) - 1);
|
2020-05-24 02:27:43 +08:00
|
|
|
if (p) memcpy(ret, p, header->size);
|
2016-04-17 21:22:50 +08:00
|
|
|
#ifdef TAL_DEBUG
|
|
|
|
header->line_num = -header->line_num;
|
|
|
|
#endif
|
|
|
|
} else if (al->next) {
|
|
|
|
al = al->next;
|
|
|
|
goto tail_call;
|
|
|
|
} else
|
2021-10-22 13:39:54 +08:00
|
|
|
ret = tcc_realloc(p, size);
|
2016-04-17 21:22:50 +08:00
|
|
|
#ifdef TAL_INFO
|
|
|
|
al->nb_missed++;
|
|
|
|
#endif
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-10-02 02:26:50 +08:00
|
|
|
#endif /* USE_TAL */
|
|
|
|
|
2009-12-20 08:53:49 +08:00
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
/* CString handling */
|
2021-10-22 13:39:54 +08:00
|
|
|
static void cstr_realloc(CString *cstr, int new_size)
|
2009-12-20 08:53:49 +08:00
|
|
|
{
|
|
|
|
int size;
|
|
|
|
|
|
|
|
size = cstr->size_allocated;
|
2016-04-17 21:37:23 +08:00
|
|
|
if (size < 8)
|
2009-12-20 08:53:49 +08:00
|
|
|
size = 8; /* no need to allocate a too small first string */
|
|
|
|
while (size < new_size)
|
|
|
|
size = size * 2;
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr->data = tcc_realloc(cstr->data, size);
|
2009-12-20 08:53:49 +08:00
|
|
|
cstr->size_allocated = size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* add a byte */
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_INLN void cstr_ccat(CString *cstr, int ch)
|
2009-12-20 08:53:49 +08:00
|
|
|
{
|
|
|
|
int size;
|
|
|
|
size = cstr->size + 1;
|
|
|
|
if (size > cstr->size_allocated)
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_realloc(cstr, size);
|
2009-12-20 08:53:49 +08:00
|
|
|
((unsigned char *)cstr->data)[size - 1] = ch;
|
|
|
|
cstr->size = size;
|
|
|
|
}
|
|
|
|
|
2021-02-18 20:41:47 +08:00
|
|
|
ST_INLN char *unicode_to_utf8 (char *b, uint32_t Uc)
|
2021-01-18 05:21:07 +08:00
|
|
|
{
|
|
|
|
if (Uc<0x80) *b++=Uc;
|
|
|
|
else if (Uc<0x800) *b++=192+Uc/64, *b++=128+Uc%64;
|
2022-05-14 21:55:27 +08:00
|
|
|
else if (Uc-0xd800u<0x800) goto error;
|
2021-01-18 05:21:07 +08:00
|
|
|
else if (Uc<0x10000) *b++=224+Uc/4096, *b++=128+Uc/64%64, *b++=128+Uc%64;
|
|
|
|
else if (Uc<0x110000) *b++=240+Uc/262144, *b++=128+Uc/4096%64, *b++=128+Uc/64%64, *b++=128+Uc%64;
|
2022-05-14 21:55:27 +08:00
|
|
|
else error: tcc_error("0x%x is not a valid universal character", Uc);
|
2021-01-18 05:21:07 +08:00
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* add a unicode character expanded into utf8 */
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_INLN void cstr_u8cat(CString *cstr, int ch)
|
2021-01-18 05:21:07 +08:00
|
|
|
{
|
2021-01-24 23:20:48 +08:00
|
|
|
char buf[4], *e;
|
|
|
|
e = unicode_to_utf8(buf, (uint32_t)ch);
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_cat(cstr, buf, e - buf);
|
2021-01-18 05:21:07 +08:00
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void cstr_cat(CString *cstr, const char *str, int len)
|
2009-12-20 08:53:49 +08:00
|
|
|
{
|
2016-04-17 21:37:23 +08:00
|
|
|
int size;
|
|
|
|
if (len <= 0)
|
|
|
|
len = strlen(str) + 1 + len;
|
|
|
|
size = cstr->size + len;
|
|
|
|
if (size > cstr->size_allocated)
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_realloc(cstr, size);
|
2016-04-22 23:21:09 +08:00
|
|
|
memmove(((unsigned char *)cstr->data) + cstr->size, str, len);
|
2016-04-17 21:37:23 +08:00
|
|
|
cstr->size = size;
|
2009-12-20 08:53:49 +08:00
|
|
|
}
|
2009-05-12 00:45:56 +08:00
|
|
|
|
2009-12-20 08:53:49 +08:00
|
|
|
/* add a wide char */
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void cstr_wccat(CString *cstr, int ch)
|
2009-12-20 08:53:49 +08:00
|
|
|
{
|
|
|
|
int size;
|
|
|
|
size = cstr->size + sizeof(nwchar_t);
|
|
|
|
if (size > cstr->size_allocated)
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_realloc(cstr, size);
|
2009-12-20 08:53:49 +08:00
|
|
|
*(nwchar_t *)(((unsigned char *)cstr->data) + size - sizeof(nwchar_t)) = ch;
|
|
|
|
cstr->size = size;
|
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void cstr_new(CString *cstr)
|
2009-12-20 08:53:49 +08:00
|
|
|
{
|
|
|
|
memset(cstr, 0, sizeof(CString));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* free string and reset it to NULL */
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void cstr_free(CString *cstr)
|
2009-12-20 08:53:49 +08:00
|
|
|
{
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_free(cstr->data);
|
2009-12-20 08:53:49 +08:00
|
|
|
}
|
|
|
|
|
Optimize cstr_reset() to only reset string to empty, not call free() and later malloc()
A CString could be reset to empty just setting its .size to 0.
If memory was already allocated, that would be remembered in
.data_allocated and .size_allocated and on consequent string
manipulations that memory will be used without immediate need to call
malloc().
For
$ ./tcc -B. -bench -DONE_SOURCE -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" -c tcc.c
after the patch malloc/free are called less often:
(tcc is run in loop; perf record -a sleep 10 && perf report)
before:
# Overhead Command Shared Object Symbol
# ........ ........... .................. ..........................................
#
13.89% tcc tcc [.] next_nomacro1
4.73% tcc libc-2.13.so [.] _int_malloc
4.39% tcc tcc [.] next
2.94% tcc tcc [.] tok_str_add2
2.78% tcc tcc [.] macro_subst_tok
2.75% tcc libc-2.13.so [.] free
2.74% tcc tcc [.] macro_subst
2.63% tcc libc-2.13.so [.] _int_free
2.28% tcc tcc [.] vswap
2.24% tcc tcc [.] next_nomacro_spc
2.06% tcc libc-2.13.so [.] realloc
2.00% tcc libc-2.13.so [.] malloc
1.99% tcc tcc [.] unary
1.85% tcc libc-2.13.so [.] __i686.get_pc_thunk.bx
1.76% kworker/0:1 [kernel.kallsyms] [k] delay_tsc
1.70% tcc tcc [.] next_nomacro
1.62% tcc tcc [.] preprocess
1.41% tcc libc-2.13.so [.] __memcmp_ssse3
1.38% tcc [kernel.kallsyms] [k] memset
1.10% tcc tcc [.] g
1.06% tcc tcc [.] parse_btype
1.05% tcc tcc [.] sym_push2
1.04% tcc libc-2.13.so [.] _int_realloc
1.00% tcc libc-2.13.so [.] malloc_consolidate
after:
# Overhead Command Shared Object Symbol
# ........ ........... .................. ..............................................
#
15.26% tcc tcc [.] next_nomacro1
5.07% tcc libc-2.13.so [.] _int_malloc
4.62% tcc tcc [.] next
3.22% tcc tcc [.] tok_str_add2
3.03% tcc tcc [.] macro_subst_tok
3.02% tcc tcc [.] macro_subst
2.59% tcc tcc [.] next_nomacro_spc
2.44% tcc tcc [.] vswap
2.39% tcc libc-2.13.so [.] _int_free
2.28% tcc libc-2.13.so [.] free
2.22% tcc tcc [.] unary
2.07% tcc libc-2.13.so [.] realloc
1.97% tcc libc-2.13.so [.] malloc
1.70% tcc tcc [.] preprocess
1.69% tcc libc-2.13.so [.] __i686.get_pc_thunk.bx
1.68% tcc tcc [.] next_nomacro
1.59% tcc [kernel.kallsyms] [k] memset
1.55% tcc libc-2.13.so [.] __memcmp_ssse3
1.22% tcc tcc [.] parse_comment
1.11% tcc tcc [.] g
1.11% tcc tcc [.] sym_push2
1.10% tcc tcc [.] parse_btype
1.10% tcc libc-2.13.so [.] _int_realloc
1.06% tcc tcc [.] vsetc
0.98% tcc libc-2.13.so [.] malloc_consolidate
and this gains small speedup for tcc:
# best of 5 runs
before: 8268 idents, 47191 lines, 1526670 bytes, 0.153 s, 307997 lines/s, 10.0 MB/s
after: 8268 idents, 47203 lines, 1526763 bytes, 0.148 s, 319217 lines/s, 10.3 MB/s
2012-12-21 16:21:59 +08:00
|
|
|
/* reset string to empty */
|
2013-02-13 02:13:28 +08:00
|
|
|
ST_FUNC void cstr_reset(CString *cstr)
|
Optimize cstr_reset() to only reset string to empty, not call free() and later malloc()
A CString could be reset to empty just setting its .size to 0.
If memory was already allocated, that would be remembered in
.data_allocated and .size_allocated and on consequent string
manipulations that memory will be used without immediate need to call
malloc().
For
$ ./tcc -B. -bench -DONE_SOURCE -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" -c tcc.c
after the patch malloc/free are called less often:
(tcc is run in loop; perf record -a sleep 10 && perf report)
before:
# Overhead Command Shared Object Symbol
# ........ ........... .................. ..........................................
#
13.89% tcc tcc [.] next_nomacro1
4.73% tcc libc-2.13.so [.] _int_malloc
4.39% tcc tcc [.] next
2.94% tcc tcc [.] tok_str_add2
2.78% tcc tcc [.] macro_subst_tok
2.75% tcc libc-2.13.so [.] free
2.74% tcc tcc [.] macro_subst
2.63% tcc libc-2.13.so [.] _int_free
2.28% tcc tcc [.] vswap
2.24% tcc tcc [.] next_nomacro_spc
2.06% tcc libc-2.13.so [.] realloc
2.00% tcc libc-2.13.so [.] malloc
1.99% tcc tcc [.] unary
1.85% tcc libc-2.13.so [.] __i686.get_pc_thunk.bx
1.76% kworker/0:1 [kernel.kallsyms] [k] delay_tsc
1.70% tcc tcc [.] next_nomacro
1.62% tcc tcc [.] preprocess
1.41% tcc libc-2.13.so [.] __memcmp_ssse3
1.38% tcc [kernel.kallsyms] [k] memset
1.10% tcc tcc [.] g
1.06% tcc tcc [.] parse_btype
1.05% tcc tcc [.] sym_push2
1.04% tcc libc-2.13.so [.] _int_realloc
1.00% tcc libc-2.13.so [.] malloc_consolidate
after:
# Overhead Command Shared Object Symbol
# ........ ........... .................. ..............................................
#
15.26% tcc tcc [.] next_nomacro1
5.07% tcc libc-2.13.so [.] _int_malloc
4.62% tcc tcc [.] next
3.22% tcc tcc [.] tok_str_add2
3.03% tcc tcc [.] macro_subst_tok
3.02% tcc tcc [.] macro_subst
2.59% tcc tcc [.] next_nomacro_spc
2.44% tcc tcc [.] vswap
2.39% tcc libc-2.13.so [.] _int_free
2.28% tcc libc-2.13.so [.] free
2.22% tcc tcc [.] unary
2.07% tcc libc-2.13.so [.] realloc
1.97% tcc libc-2.13.so [.] malloc
1.70% tcc tcc [.] preprocess
1.69% tcc libc-2.13.so [.] __i686.get_pc_thunk.bx
1.68% tcc tcc [.] next_nomacro
1.59% tcc [kernel.kallsyms] [k] memset
1.55% tcc libc-2.13.so [.] __memcmp_ssse3
1.22% tcc tcc [.] parse_comment
1.11% tcc tcc [.] g
1.11% tcc tcc [.] sym_push2
1.10% tcc tcc [.] parse_btype
1.10% tcc libc-2.13.so [.] _int_realloc
1.06% tcc tcc [.] vsetc
0.98% tcc libc-2.13.so [.] malloc_consolidate
and this gains small speedup for tcc:
# best of 5 runs
before: 8268 idents, 47191 lines, 1526670 bytes, 0.153 s, 307997 lines/s, 10.0 MB/s
after: 8268 idents, 47203 lines, 1526763 bytes, 0.148 s, 319217 lines/s, 10.3 MB/s
2012-12-21 16:21:59 +08:00
|
|
|
{
|
|
|
|
cstr->size = 0;
|
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC int cstr_vprintf(CString *cstr, const char *fmt, va_list ap)
|
2019-12-11 07:37:18 +08:00
|
|
|
{
|
|
|
|
va_list v;
|
2020-12-18 07:33:44 +08:00
|
|
|
int len, size = 80;
|
|
|
|
for (;;) {
|
|
|
|
size += cstr->size;
|
|
|
|
if (size > cstr->size_allocated)
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_realloc(cstr, size);
|
2020-12-18 07:33:44 +08:00
|
|
|
size = cstr->size_allocated - cstr->size;
|
2021-08-02 02:04:46 +08:00
|
|
|
va_copy(v, ap);
|
2020-12-18 07:33:44 +08:00
|
|
|
len = vsnprintf((char*)cstr->data + cstr->size, size, fmt, v);
|
|
|
|
va_end(v);
|
2022-11-30 02:45:05 +08:00
|
|
|
if (len >= 0 && len < size)
|
2020-12-18 07:33:44 +08:00
|
|
|
break;
|
|
|
|
size *= 2;
|
|
|
|
}
|
2019-12-11 07:37:18 +08:00
|
|
|
cstr->size += len;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC int cstr_printf(CString *cstr, const char *fmt, ...)
|
2021-08-02 02:04:46 +08:00
|
|
|
{
|
|
|
|
va_list ap; int len;
|
|
|
|
va_start(ap, fmt);
|
2021-10-22 13:39:54 +08:00
|
|
|
len = cstr_vprintf(cstr, fmt, ap);
|
2021-08-02 02:04:46 +08:00
|
|
|
va_end(ap);
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2009-12-20 08:53:49 +08:00
|
|
|
/* XXX: unicode ? */
|
2021-10-22 13:39:54 +08:00
|
|
|
static void add_char(CString *cstr, int c)
|
2009-12-20 08:53:49 +08:00
|
|
|
{
|
|
|
|
if (c == '\'' || c == '\"' || c == '\\') {
|
|
|
|
/* XXX: could be more precise if char or string */
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_ccat(cstr, '\\');
|
2009-12-20 08:53:49 +08:00
|
|
|
}
|
|
|
|
if (c >= 32 && c <= 126) {
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_ccat(cstr, c);
|
2009-12-20 08:53:49 +08:00
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_ccat(cstr, '\\');
|
2009-12-20 08:53:49 +08:00
|
|
|
if (c == '\n') {
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_ccat(cstr, 'n');
|
2009-12-20 08:53:49 +08:00
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_ccat(cstr, '0' + ((c >> 6) & 7));
|
|
|
|
cstr_ccat(cstr, '0' + ((c >> 3) & 7));
|
|
|
|
cstr_ccat(cstr, '0' + (c & 7));
|
2009-12-20 08:53:49 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------- */
|
2009-05-06 02:30:39 +08:00
|
|
|
/* allocate a new token */
|
2021-10-22 13:39:54 +08:00
|
|
|
static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
|
2009-05-06 02:30:39 +08:00
|
|
|
{
|
|
|
|
TokenSym *ts, **ptable;
|
|
|
|
int i;
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok_ident >= SYM_FIRST_ANOM)
|
|
|
|
tcc_error("memory full (symbols)");
|
2009-05-06 02:30:39 +08:00
|
|
|
|
|
|
|
/* expand token table if needed */
|
2021-10-22 13:39:54 +08:00
|
|
|
i = tok_ident - TOK_IDENT;
|
2009-05-06 02:30:39 +08:00
|
|
|
if ((i % TOK_ALLOC_INCR) == 0) {
|
2021-10-22 13:39:54 +08:00
|
|
|
ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
|
|
|
|
table_ident = ptable;
|
2009-05-06 02:30:39 +08:00
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ts = tal_realloc(toksym_alloc, 0, sizeof(TokenSym) + len);
|
|
|
|
table_ident[i] = ts;
|
|
|
|
ts->tok = tok_ident++;
|
2009-05-06 02:30:39 +08:00
|
|
|
ts->sym_define = NULL;
|
|
|
|
ts->sym_label = NULL;
|
|
|
|
ts->sym_struct = NULL;
|
|
|
|
ts->sym_identifier = NULL;
|
|
|
|
ts->len = len;
|
|
|
|
ts->hash_next = NULL;
|
|
|
|
memcpy(ts->str, str, len);
|
|
|
|
ts->str[len] = '\0';
|
|
|
|
*pts = ts;
|
|
|
|
return ts;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define TOK_HASH_INIT 1
|
2016-04-17 21:37:23 +08:00
|
|
|
#define TOK_HASH_FUNC(h, c) ((h) + ((h) << 5) + ((h) >> 27) + (c))
|
|
|
|
|
2009-05-06 02:30:39 +08:00
|
|
|
|
|
|
|
/* find a token and add it if not found */
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC TokenSym *tok_alloc(const char *str, int len)
|
2009-05-06 02:30:39 +08:00
|
|
|
{
|
|
|
|
TokenSym *ts, **pts;
|
|
|
|
int i;
|
|
|
|
unsigned int h;
|
2015-07-30 04:53:57 +08:00
|
|
|
|
2009-05-06 02:30:39 +08:00
|
|
|
h = TOK_HASH_INIT;
|
|
|
|
for(i=0;i<len;i++)
|
|
|
|
h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
|
|
|
|
h &= (TOK_HASH_SIZE - 1);
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
pts = &hash_ident[h];
|
2009-05-06 02:30:39 +08:00
|
|
|
for(;;) {
|
|
|
|
ts = *pts;
|
|
|
|
if (!ts)
|
|
|
|
break;
|
|
|
|
if (ts->len == len && !memcmp(ts->str, str, len))
|
|
|
|
return ts;
|
|
|
|
pts = &(ts->hash_next);
|
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
return tok_alloc_new(pts, str, len);
|
2009-05-06 02:30:39 +08:00
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC int tok_alloc_const(const char *str)
|
2021-01-04 20:16:05 +08:00
|
|
|
{
|
2021-10-22 13:39:54 +08:00
|
|
|
return tok_alloc(str, strlen(str))->tok;
|
2021-01-04 20:16:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-05-06 02:30:39 +08:00
|
|
|
/* XXX: buffer overflow */
|
|
|
|
/* XXX: float tokens */
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC const char *get_tok_str(int v, CValue *cv)
|
2009-05-06 02:30:39 +08:00
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
int i, len;
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_reset(&cstr_buf);
|
|
|
|
p = cstr_buf.data;
|
2009-05-06 02:30:39 +08:00
|
|
|
|
|
|
|
switch(v) {
|
|
|
|
case TOK_CINT:
|
|
|
|
case TOK_CUINT:
|
mutiples fix for _Generic
* check that _Generic don't match unsigned char * with char *
this case is usefull as with -funsigned-char, 'char *' are unsigned
* change VT_LONG so it's now a qualifier
VT_LONG are never use for code generation, but only durring parsing state,
in _Generic we need to be able to make diference between
'long' and 'long long'
So VT_LONG is now use as a type qualifier, it's old behaviour is still
here, but we can keep trace of what was a long and what wasn't
* add TOK_CLONG and TOK_CULONG
tcc was directly converting value like '7171L' into TOK_CLLONG or
TOK_CINT depending of the machine architecture.
because of that, we was unable to make diference between a long and a
long long, which doesn't work with _Generic.
So now 7171L is a TOK_CLONG, and we can handle _Generic properly
* check that _Generic can make diference between long and long long
* uncomment "type match twice" as it should now pass tests on any platforms
* add inside_generic global
the point of this variable is to use VT_LONG in comparaison only
when we are evaluating a _Generic.
problem is with my lastest patchs tcc can now make the diference between
a 'long long' and a 'long', but in 64 bit stddef.h typedef uint64_t as
typedef signed long long int int64_t and stdint.h as unsigned long int, so tcc
break when stdint.h and stddef.h are include together.
Another solution woud be to modifie include/stddef.h so it define uint64_t as
unsigned long int when processor is 64 bit, but this could break some
legacy code, so for now, VT_LONG are use only inside generc.
* check that _Generic parse first argument correctly
* check that _Generic evaluate correctly exresion like "f() / 2"
2017-07-10 23:44:53 +08:00
|
|
|
case TOK_CLONG:
|
|
|
|
case TOK_CULONG:
|
2009-05-06 02:30:39 +08:00
|
|
|
case TOK_CLLONG:
|
|
|
|
case TOK_CULLONG:
|
|
|
|
/* XXX: not quite exact, but only useful for testing */
|
2009-07-19 04:05:58 +08:00
|
|
|
#ifdef _WIN32
|
2015-11-18 03:09:35 +08:00
|
|
|
sprintf(p, "%u", (unsigned)cv->i);
|
2009-07-19 04:05:58 +08:00
|
|
|
#else
|
2015-11-18 03:09:35 +08:00
|
|
|
sprintf(p, "%llu", (unsigned long long)cv->i);
|
2009-07-19 04:05:58 +08:00
|
|
|
#endif
|
2009-05-06 02:30:39 +08:00
|
|
|
break;
|
|
|
|
case TOK_LCHAR:
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_ccat(&cstr_buf, 'L');
|
2009-05-06 02:30:39 +08:00
|
|
|
case TOK_CCHAR:
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_ccat(&cstr_buf, '\'');
|
|
|
|
add_char(&cstr_buf, cv->i);
|
|
|
|
cstr_ccat(&cstr_buf, '\'');
|
|
|
|
cstr_ccat(&cstr_buf, '\0');
|
2009-05-06 02:30:39 +08:00
|
|
|
break;
|
|
|
|
case TOK_PPNUM:
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
case TOK_PPSTR:
|
2015-11-21 19:23:53 +08:00
|
|
|
return (char*)cv->str.data;
|
2009-05-06 02:30:39 +08:00
|
|
|
case TOK_LSTR:
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_ccat(&cstr_buf, 'L');
|
2009-05-06 02:30:39 +08:00
|
|
|
case TOK_STR:
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_ccat(&cstr_buf, '\"');
|
2009-05-06 02:30:39 +08:00
|
|
|
if (v == TOK_STR) {
|
2015-11-21 19:23:53 +08:00
|
|
|
len = cv->str.size - 1;
|
2009-05-06 02:30:39 +08:00
|
|
|
for(i=0;i<len;i++)
|
2021-10-22 13:39:54 +08:00
|
|
|
add_char(&cstr_buf, ((unsigned char *)cv->str.data)[i]);
|
2009-05-06 02:30:39 +08:00
|
|
|
} else {
|
2015-11-21 19:23:53 +08:00
|
|
|
len = (cv->str.size / sizeof(nwchar_t)) - 1;
|
2009-05-06 02:30:39 +08:00
|
|
|
for(i=0;i<len;i++)
|
2021-10-22 13:39:54 +08:00
|
|
|
add_char(&cstr_buf, ((nwchar_t *)cv->str.data)[i]);
|
2009-05-06 02:30:39 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_ccat(&cstr_buf, '\"');
|
|
|
|
cstr_ccat(&cstr_buf, '\0');
|
2009-05-06 02:30:39 +08:00
|
|
|
break;
|
2014-03-29 23:40:54 +08:00
|
|
|
|
|
|
|
case TOK_CFLOAT:
|
2023-03-06 09:04:17 +08:00
|
|
|
return strcpy(p, "<float>");
|
2014-03-29 23:40:54 +08:00
|
|
|
case TOK_CDOUBLE:
|
2023-03-06 09:04:17 +08:00
|
|
|
return strcpy(p, "<double>");
|
2014-03-29 23:40:54 +08:00
|
|
|
case TOK_CLDOUBLE:
|
2023-03-06 09:04:17 +08:00
|
|
|
return strcpy(p, "<long double>");
|
2014-03-29 23:40:54 +08:00
|
|
|
case TOK_LINENUM:
|
2023-03-06 09:04:17 +08:00
|
|
|
return strcpy(p, "<linenumber");
|
2014-03-29 23:40:54 +08:00
|
|
|
|
|
|
|
/* above tokens have value, the ones below don't */
|
2009-05-06 02:30:39 +08:00
|
|
|
case TOK_LT:
|
|
|
|
v = '<';
|
|
|
|
goto addv;
|
|
|
|
case TOK_GT:
|
|
|
|
v = '>';
|
|
|
|
goto addv;
|
|
|
|
case TOK_DOTS:
|
|
|
|
return strcpy(p, "...");
|
|
|
|
case TOK_A_SHL:
|
|
|
|
return strcpy(p, "<<=");
|
|
|
|
case TOK_A_SAR:
|
|
|
|
return strcpy(p, ">>=");
|
2017-07-09 18:07:40 +08:00
|
|
|
case TOK_EOF:
|
|
|
|
return strcpy(p, "<eof>");
|
2023-03-06 09:04:17 +08:00
|
|
|
case 0: /* anonymous nameless symbols */
|
|
|
|
return strcpy(p, "<no name>");
|
2009-05-06 02:30:39 +08:00
|
|
|
default:
|
|
|
|
if (v < TOK_IDENT) {
|
|
|
|
/* search in two bytes table */
|
2009-07-19 04:07:42 +08:00
|
|
|
const unsigned char *q = tok_two_chars;
|
2009-05-06 02:30:39 +08:00
|
|
|
while (*q) {
|
|
|
|
if (q[2] == v) {
|
|
|
|
*p++ = q[0];
|
|
|
|
*p++ = q[1];
|
|
|
|
*p = '\0';
|
2021-10-22 13:39:54 +08:00
|
|
|
return cstr_buf.data;
|
2009-05-06 02:30:39 +08:00
|
|
|
}
|
|
|
|
q += 3;
|
|
|
|
}
|
2023-03-06 09:04:17 +08:00
|
|
|
if (v >= 127 || (v < 32 && !is_space(v) && v != '\n')) {
|
|
|
|
sprintf(p, "<\\x%02x>", v);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
addv:
|
2009-05-06 02:30:39 +08:00
|
|
|
*p++ = v;
|
|
|
|
*p = '\0';
|
2021-10-22 13:39:54 +08:00
|
|
|
} else if (v < tok_ident) {
|
|
|
|
return table_ident[v - TOK_IDENT]->str;
|
2009-05-06 02:30:39 +08:00
|
|
|
} else if (v >= SYM_FIRST_ANOM) {
|
|
|
|
/* special name for anonymous symbol */
|
|
|
|
sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
|
|
|
|
} else {
|
|
|
|
/* should never happen */
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
return cstr_buf.data;
|
2009-05-06 02:30:39 +08:00
|
|
|
}
|
|
|
|
|
2022-08-18 16:43:28 +08:00
|
|
|
static inline int check_space(int t, int *spc)
|
|
|
|
{
|
|
|
|
if (t < 256 && (isidnum_table[t - CH_EOF] & IS_SPC)) {
|
|
|
|
if (*spc)
|
|
|
|
return 1;
|
|
|
|
*spc = 1;
|
|
|
|
} else
|
|
|
|
*spc = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
/* return the current character, handling end of block if necessary
|
|
|
|
(but not stray) */
|
2021-10-22 13:39:54 +08:00
|
|
|
static int handle_eob(void)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
2021-10-22 13:39:54 +08:00
|
|
|
BufferedFile *bf = file;
|
2009-05-06 02:17:49 +08:00
|
|
|
int len;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
/* only tries to read if really end of buffer */
|
|
|
|
if (bf->buf_ptr >= bf->buf_end) {
|
various stuff
win32/Makefile ("for cygwin") removed
- On cygwin, the normal ./configure && make can be used with either
cygwin's "GCC for Win32 Toolchain"
./configure --cross-prefix=i686-w64-mingw32-
or with an existing tcc:
./configure --cc=<old-tccdir>/tcc.exe
tcctest.c:
- exclude test_high_clobbers() on _WIN64 (does not work)
tests2/95_bitfield.c:
- use 'signed char' for ARM (where default 'char' is unsigned)
tests:
- remove -I "expr" diff option to allow tests with
busybox-diff.
libtcc.c, tcc.c:
- removed -iwithprefix option. It is supposed to be
combined with -iprefix which we don't have either.
tccgen.c:
- fix assignments and return of 'void', as in
void f() {
void *p, *q;
*p = *q:
return *p;
}
This appears to be allowed but should do nothing.
tcc.h, libtcc.c, tccpp.c:
- Revert "Introduce VIP sysinclude paths which are always searched first"
This reverts commit 1d5e386b0a78393ac6b670c209a185849ec798a1.
The patch was giving tcc's system includes priority over -I which
is not how it should be.
tccelf.c:
- add DT_TEXTREL tag only if text relocations are actually
used (which is likely not the case on x86_64)
- prepare_dynamic_rel(): avoid relocation of unresolved
(weak) symbols
tccrun.c:
- for HAVE_SELINUX, use two mappings to the same (real) file.
(it was so once except the RX mapping wasn't used at all).
tccpe.c:
- fix relocation constant used for x86_64 (by Andrei E. Warentin)
- #ifndef _WIN32 do "chmod 755 ..." to get runnable exes on cygwin.
tccasm.c:
- keep forward asm labels static, otherwise they will endup
in dynsym eventually.
configure, Makefile:
- mingw32: respect ./configure options --bindir --docdir --libdir
- allow overriding tcc when building libtcc1.a and libtcc.def with
make XTCC=<tcc program to use>
- use $(wildcard ...) for install to allow installing just
a cross compiler for example
make cross-arm
make install
- use name <target>-libtcc1.a
build-tcc.bat:
- add options: -clean, -b bindir
2017-10-12 00:13:43 +08:00
|
|
|
if (bf->fd >= 0) {
|
2009-05-06 02:17:49 +08:00
|
|
|
#if defined(PARSE_DEBUG)
|
2015-05-01 05:31:32 +08:00
|
|
|
len = 1;
|
2009-05-06 02:17:49 +08:00
|
|
|
#else
|
|
|
|
len = IO_BUF_SIZE;
|
|
|
|
#endif
|
2013-01-15 00:34:07 +08:00
|
|
|
len = read(bf->fd, bf->buffer, len);
|
2009-05-06 02:17:49 +08:00
|
|
|
if (len < 0)
|
|
|
|
len = 0;
|
|
|
|
} else {
|
|
|
|
len = 0;
|
|
|
|
}
|
|
|
|
total_bytes += len;
|
|
|
|
bf->buf_ptr = bf->buffer;
|
|
|
|
bf->buf_end = bf->buffer + len;
|
|
|
|
*bf->buf_end = CH_EOB;
|
|
|
|
}
|
|
|
|
if (bf->buf_ptr < bf->buf_end) {
|
|
|
|
return bf->buf_ptr[0];
|
|
|
|
} else {
|
|
|
|
bf->buf_ptr = bf->buf_end;
|
|
|
|
return CH_EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* read next char from current input file and handle end of input buffer */
|
2022-08-18 16:43:28 +08:00
|
|
|
static int next_c(void)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
2022-08-18 16:43:28 +08:00
|
|
|
int ch = *++file->buf_ptr;
|
2009-05-06 02:17:49 +08:00
|
|
|
/* end of buffer/file handling */
|
2022-08-18 16:43:28 +08:00
|
|
|
if (ch == CH_EOB && file->buf_ptr >= file->buf_end)
|
2021-10-22 13:39:54 +08:00
|
|
|
ch = handle_eob();
|
2022-08-18 16:43:28 +08:00
|
|
|
return ch;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
2022-08-18 16:43:28 +08:00
|
|
|
/* input with '\[\r]\n' handling. */
|
|
|
|
static int handle_stray_noerror(int err)
|
2021-10-22 13:39:54 +08:00
|
|
|
{
|
2022-08-18 16:43:28 +08:00
|
|
|
int ch;
|
|
|
|
while ((ch = next_c()) == '\\') {
|
|
|
|
ch = next_c();
|
2021-10-22 13:39:54 +08:00
|
|
|
if (ch == '\n') {
|
2022-08-18 16:43:28 +08:00
|
|
|
newl:
|
2021-10-22 13:39:54 +08:00
|
|
|
file->line_num++;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
2022-08-18 16:43:28 +08:00
|
|
|
if (ch == '\r') {
|
|
|
|
ch = next_c();
|
|
|
|
if (ch == '\n')
|
|
|
|
goto newl;
|
|
|
|
*--file->buf_ptr = '\r';
|
|
|
|
}
|
|
|
|
if (err)
|
|
|
|
tcc_error("stray '\\' in program");
|
|
|
|
/* may take advantage of 'BufferedFile.unget[4}' */
|
|
|
|
return *--file->buf_ptr = '\\';
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
}
|
2022-08-18 16:43:28 +08:00
|
|
|
return ch;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
2022-08-18 16:43:28 +08:00
|
|
|
#define ninp() handle_stray_noerror(0)
|
|
|
|
|
|
|
|
/* handle '\\' in strings, comments and skipped regions */
|
|
|
|
static int handle_bs(uint8_t **p)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
2022-08-18 16:43:28 +08:00
|
|
|
int c;
|
|
|
|
file->buf_ptr = *p - 1;
|
|
|
|
c = ninp();
|
|
|
|
*p = file->buf_ptr;
|
|
|
|
return c;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* skip the stray and handle the \\n case. Output an error if
|
|
|
|
incorrect char after the stray */
|
2022-08-18 16:43:28 +08:00
|
|
|
static int handle_stray(uint8_t **p)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
|
|
|
int c;
|
2022-08-18 16:43:28 +08:00
|
|
|
file->buf_ptr = *p - 1;
|
|
|
|
c = handle_stray_noerror(!(parse_flags & PARSE_FLAG_ACCEPT_STRAYS));
|
|
|
|
*p = file->buf_ptr;
|
2009-05-06 02:17:49 +08:00
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* handle the complicated stray case */
|
|
|
|
#define PEEKC(c, p)\
|
|
|
|
{\
|
2022-08-18 16:43:28 +08:00
|
|
|
c = *++p;\
|
|
|
|
if (c == '\\')\
|
|
|
|
c = handle_stray(&p); \
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
2022-08-18 16:43:28 +08:00
|
|
|
static int skip_spaces(void)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
2022-08-18 16:43:28 +08:00
|
|
|
int ch;
|
|
|
|
--file->buf_ptr;
|
|
|
|
do {
|
|
|
|
ch = ninp();
|
|
|
|
} while (isidnum_table[ch - CH_EOF] & IS_SPC);
|
|
|
|
return ch;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* single line C++ comments */
|
2021-10-22 13:39:54 +08:00
|
|
|
static uint8_t *parse_line_comment(uint8_t *p)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
|
|
|
int c;
|
|
|
|
for(;;) {
|
2022-08-18 16:43:28 +08:00
|
|
|
for (;;) {
|
|
|
|
c = *++p;
|
2009-05-06 02:17:49 +08:00
|
|
|
redo:
|
2022-08-18 16:43:28 +08:00
|
|
|
if (c == '\n' || c == '\\')
|
|
|
|
break;
|
|
|
|
c = *++p;
|
|
|
|
if (c == '\n' || c == '\\')
|
|
|
|
break;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2022-08-18 16:43:28 +08:00
|
|
|
if (c == '\n')
|
|
|
|
break;
|
|
|
|
c = handle_bs(&p);
|
|
|
|
if (c == CH_EOF)
|
|
|
|
break;
|
|
|
|
if (c != '\\')
|
|
|
|
goto redo;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* C comments */
|
2021-10-22 13:39:54 +08:00
|
|
|
static uint8_t *parse_comment(uint8_t *p)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
|
|
|
int c;
|
|
|
|
for(;;) {
|
|
|
|
/* fast skip loop */
|
|
|
|
for(;;) {
|
2022-08-18 16:43:28 +08:00
|
|
|
c = *++p;
|
|
|
|
redo:
|
2009-05-06 02:17:49 +08:00
|
|
|
if (c == '\n' || c == '*' || c == '\\')
|
|
|
|
break;
|
2022-08-18 16:43:28 +08:00
|
|
|
c = *++p;
|
2009-05-06 02:17:49 +08:00
|
|
|
if (c == '\n' || c == '*' || c == '\\')
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* now we can handle all the cases */
|
|
|
|
if (c == '\n') {
|
2021-10-22 13:39:54 +08:00
|
|
|
file->line_num++;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else if (c == '*') {
|
2022-08-18 16:43:28 +08:00
|
|
|
do {
|
|
|
|
c = *++p;
|
|
|
|
} while (c == '*');
|
|
|
|
if (c == '\\')
|
|
|
|
c = handle_bs(&p);
|
|
|
|
if (c == '/')
|
|
|
|
break;
|
|
|
|
goto check_eof;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
2022-08-18 16:43:28 +08:00
|
|
|
c = handle_bs(&p);
|
|
|
|
check_eof:
|
|
|
|
if (c == CH_EOF)
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("unexpected end of file in comment");
|
2022-08-18 16:43:28 +08:00
|
|
|
if (c != '\\')
|
|
|
|
goto redo;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
}
|
2022-08-18 16:43:28 +08:00
|
|
|
return p + 1;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* parse a string without interpreting escapes */
|
2022-08-18 16:43:28 +08:00
|
|
|
static uint8_t *parse_pp_string(uint8_t *p, int sep, CString *str)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
|
|
|
int c;
|
|
|
|
for(;;) {
|
2022-08-18 16:43:28 +08:00
|
|
|
c = *++p;
|
|
|
|
redo:
|
2009-05-06 02:17:49 +08:00
|
|
|
if (c == sep) {
|
|
|
|
break;
|
|
|
|
} else if (c == '\\') {
|
2022-08-18 16:43:28 +08:00
|
|
|
c = handle_bs(&p);
|
2009-05-06 02:17:49 +08:00
|
|
|
if (c == CH_EOF) {
|
2022-08-18 16:43:28 +08:00
|
|
|
unterminated_string:
|
2009-05-06 02:17:49 +08:00
|
|
|
/* XXX: indicate line number of start of string */
|
2022-08-20 18:58:56 +08:00
|
|
|
tok_flags &= ~TOK_FLAG_BOL;
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("missing terminating %c character", sep);
|
2009-05-06 02:17:49 +08:00
|
|
|
} else if (c == '\\') {
|
2022-08-18 16:43:28 +08:00
|
|
|
if (str)
|
|
|
|
cstr_ccat(str, c);
|
|
|
|
c = *++p;
|
|
|
|
/* add char after '\\' unconditionally */
|
|
|
|
if (c == '\\') {
|
|
|
|
c = handle_bs(&p);
|
|
|
|
if (c == CH_EOF)
|
|
|
|
goto unterminated_string;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2022-08-18 16:43:28 +08:00
|
|
|
goto add_char;
|
|
|
|
} else {
|
|
|
|
goto redo;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
} else if (c == '\n') {
|
2022-07-16 04:31:24 +08:00
|
|
|
add_lf:
|
|
|
|
if (ACCEPT_LF_IN_STRINGS) {
|
|
|
|
file->line_num++;
|
|
|
|
goto add_char;
|
|
|
|
} else if (str) { /* not skipping */
|
|
|
|
goto unterminated_string;
|
|
|
|
} else {
|
2022-08-18 16:43:28 +08:00
|
|
|
//tcc_warning("missing terminating %c character", sep);
|
2022-07-16 04:31:24 +08:00
|
|
|
return p;
|
|
|
|
}
|
2009-05-06 02:17:49 +08:00
|
|
|
} else if (c == '\r') {
|
2022-08-18 16:43:28 +08:00
|
|
|
c = *++p;
|
|
|
|
if (c == '\\')
|
|
|
|
c = handle_bs(&p);
|
|
|
|
if (c == '\n')
|
2022-07-16 04:31:24 +08:00
|
|
|
goto add_lf;
|
2022-08-18 16:43:28 +08:00
|
|
|
if (c == CH_EOF)
|
|
|
|
goto unterminated_string;
|
|
|
|
if (str)
|
|
|
|
cstr_ccat(str, '\r');
|
|
|
|
goto redo;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
2022-07-16 04:31:24 +08:00
|
|
|
add_char:
|
2009-05-06 02:17:49 +08:00
|
|
|
if (str)
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_ccat(str, c);
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
p++;
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* skip block of text until #else, #elif or #endif. skip also pairs of
|
|
|
|
#if/#endif */
|
2021-10-22 13:39:54 +08:00
|
|
|
static void preprocess_skip(void)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
|
|
|
int a, start_of_line, c, in_warn_or_error;
|
|
|
|
uint8_t *p;
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
p = file->buf_ptr;
|
2009-05-06 02:17:49 +08:00
|
|
|
a = 0;
|
|
|
|
redo_start:
|
|
|
|
start_of_line = 1;
|
|
|
|
in_warn_or_error = 0;
|
|
|
|
for(;;) {
|
|
|
|
redo_no_start:
|
|
|
|
c = *p;
|
|
|
|
switch(c) {
|
|
|
|
case ' ':
|
|
|
|
case '\t':
|
|
|
|
case '\f':
|
|
|
|
case '\v':
|
|
|
|
case '\r':
|
|
|
|
p++;
|
|
|
|
goto redo_no_start;
|
|
|
|
case '\n':
|
2021-10-22 13:39:54 +08:00
|
|
|
file->line_num++;
|
2009-05-06 02:17:49 +08:00
|
|
|
p++;
|
|
|
|
goto redo_start;
|
|
|
|
case '\\':
|
2022-08-18 16:43:28 +08:00
|
|
|
c = handle_bs(&p);
|
|
|
|
if (c == CH_EOF)
|
2021-10-22 13:39:54 +08:00
|
|
|
expect("#endif");
|
2022-08-18 16:43:28 +08:00
|
|
|
if (c == '\\')
|
|
|
|
++p;
|
2009-05-06 02:17:49 +08:00
|
|
|
goto redo_no_start;
|
|
|
|
/* skip strings */
|
|
|
|
case '\"':
|
|
|
|
case '\'':
|
|
|
|
if (in_warn_or_error)
|
|
|
|
goto _default;
|
2022-07-16 04:31:24 +08:00
|
|
|
tok_flags &= ~TOK_FLAG_BOL;
|
2021-10-22 13:39:54 +08:00
|
|
|
p = parse_pp_string(p, c, NULL);
|
2009-05-06 02:17:49 +08:00
|
|
|
break;
|
|
|
|
/* skip comments */
|
|
|
|
case '/':
|
|
|
|
if (in_warn_or_error)
|
|
|
|
goto _default;
|
2022-08-18 16:43:28 +08:00
|
|
|
++p;
|
|
|
|
c = handle_bs(&p);
|
|
|
|
if (c == '*') {
|
2021-10-22 13:39:54 +08:00
|
|
|
p = parse_comment(p);
|
2022-08-18 16:43:28 +08:00
|
|
|
} else if (c == '/') {
|
2021-10-22 13:39:54 +08:00
|
|
|
p = parse_line_comment(p);
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '#':
|
|
|
|
p++;
|
|
|
|
if (start_of_line) {
|
2021-10-22 13:39:54 +08:00
|
|
|
file->buf_ptr = p;
|
|
|
|
next_nomacro();
|
|
|
|
p = file->buf_ptr;
|
2015-07-30 04:53:57 +08:00
|
|
|
if (a == 0 &&
|
2021-10-22 13:39:54 +08:00
|
|
|
(tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
|
2009-05-06 02:17:49 +08:00
|
|
|
goto the_end;
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
|
2009-05-06 02:17:49 +08:00
|
|
|
a++;
|
2021-10-22 13:39:54 +08:00
|
|
|
else if (tok == TOK_ENDIF)
|
2009-05-06 02:17:49 +08:00
|
|
|
a--;
|
2021-10-22 13:39:54 +08:00
|
|
|
else if( tok == TOK_ERROR || tok == TOK_WARNING)
|
2009-05-06 02:17:49 +08:00
|
|
|
in_warn_or_error = 1;
|
2021-10-22 13:39:54 +08:00
|
|
|
else if (tok == TOK_LINEFEED)
|
2011-03-07 02:13:12 +08:00
|
|
|
goto redo_start;
|
2021-10-22 13:39:54 +08:00
|
|
|
else if (parse_flags & PARSE_FLAG_ASM_FILE)
|
|
|
|
p = parse_line_comment(p - 1);
|
2020-12-26 23:29:41 +08:00
|
|
|
}
|
|
|
|
#if !defined(TCC_TARGET_ARM)
|
2021-10-22 13:39:54 +08:00
|
|
|
else if (parse_flags & PARSE_FLAG_ASM_FILE)
|
|
|
|
p = parse_line_comment(p - 1);
|
2020-12-26 23:29:41 +08:00
|
|
|
#else
|
|
|
|
/* ARM assembly uses '#' for constants */
|
|
|
|
#endif
|
2009-05-06 02:17:49 +08:00
|
|
|
break;
|
|
|
|
_default:
|
|
|
|
default:
|
|
|
|
p++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
start_of_line = 0;
|
|
|
|
}
|
|
|
|
the_end: ;
|
2021-10-22 13:39:54 +08:00
|
|
|
file->buf_ptr = p;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
2017-04-26 03:01:54 +08:00
|
|
|
#if 0
|
|
|
|
/* return the number of additional 'ints' necessary to store the
|
|
|
|
token */
|
|
|
|
static inline int tok_size(const int *p)
|
|
|
|
{
|
|
|
|
switch(*p) {
|
|
|
|
/* 4 bytes */
|
|
|
|
case TOK_CINT:
|
|
|
|
case TOK_CUINT:
|
|
|
|
case TOK_CCHAR:
|
|
|
|
case TOK_LCHAR:
|
|
|
|
case TOK_CFLOAT:
|
|
|
|
case TOK_LINENUM:
|
|
|
|
return 1 + 1;
|
|
|
|
case TOK_STR:
|
|
|
|
case TOK_LSTR:
|
|
|
|
case TOK_PPNUM:
|
|
|
|
case TOK_PPSTR:
|
|
|
|
return 1 + ((sizeof(CString) + ((CString *)(p+1))->size + 3) >> 2);
|
2017-09-25 00:57:48 +08:00
|
|
|
case TOK_CLONG:
|
|
|
|
case TOK_CULONG:
|
|
|
|
return 1 + LONG_SIZE / 4;
|
2017-04-26 03:01:54 +08:00
|
|
|
case TOK_CDOUBLE:
|
|
|
|
case TOK_CLLONG:
|
|
|
|
case TOK_CULLONG:
|
|
|
|
return 1 + 2;
|
|
|
|
case TOK_CLDOUBLE:
|
2023-04-25 14:59:42 +08:00
|
|
|
#ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
|
|
|
|
return 1 + 8 / 4;
|
|
|
|
#else
|
2017-04-26 03:01:54 +08:00
|
|
|
return 1 + LDOUBLE_SIZE / 4;
|
2023-04-25 14:59:42 +08:00
|
|
|
#endif
|
2017-04-26 03:01:54 +08:00
|
|
|
default:
|
|
|
|
return 1 + 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2009-05-06 02:17:49 +08:00
|
|
|
|
2017-04-26 03:01:54 +08:00
|
|
|
/* token string handling */
|
2009-12-20 08:53:49 +08:00
|
|
|
ST_INLN void tok_str_new(TokenString *s)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
|
|
|
s->str = NULL;
|
2017-06-05 19:21:39 +08:00
|
|
|
s->len = s->lastlen = 0;
|
2009-05-06 02:17:49 +08:00
|
|
|
s->allocated_len = 0;
|
|
|
|
s->last_line_num = -1;
|
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC TokenString *tok_str_alloc(void)
|
2016-10-02 02:26:50 +08:00
|
|
|
{
|
2021-10-22 13:39:54 +08:00
|
|
|
TokenString *str = tal_realloc(tokstr_alloc, 0, sizeof *str);
|
2016-10-02 02:26:50 +08:00
|
|
|
tok_str_new(str);
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC int *tok_str_dup(TokenString *s)
|
2016-04-17 21:37:23 +08:00
|
|
|
{
|
|
|
|
int *str;
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
str = tal_realloc(tokstr_alloc, 0, s->len * sizeof(int));
|
2016-04-17 21:37:23 +08:00
|
|
|
memcpy(str, s->str, s->len * sizeof(int));
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void tok_str_free_str(int *str)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
2021-10-22 13:39:54 +08:00
|
|
|
tal_free(tokstr_alloc, str);
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void tok_str_free(TokenString *str)
|
2016-11-12 03:25:13 +08:00
|
|
|
{
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_free_str(str->str);
|
|
|
|
tal_free(tokstr_alloc, str);
|
2016-11-12 03:25:13 +08:00
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC int *tok_str_realloc(TokenString *s, int new_size)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
2016-04-17 21:37:23 +08:00
|
|
|
int *str, size;
|
2009-05-06 02:17:49 +08:00
|
|
|
|
2016-04-17 21:37:23 +08:00
|
|
|
size = s->allocated_len;
|
|
|
|
if (size < 16)
|
|
|
|
size = 16;
|
|
|
|
while (size < new_size)
|
|
|
|
size = size * 2;
|
|
|
|
if (size > s->allocated_len) {
|
2021-10-22 13:39:54 +08:00
|
|
|
str = tal_realloc(tokstr_alloc, s->str, size * sizeof(int));
|
2016-04-17 21:37:23 +08:00
|
|
|
s->allocated_len = size;
|
|
|
|
s->str = str;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2016-04-17 21:37:23 +08:00
|
|
|
return s->str;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void tok_str_add(TokenString *s, int t)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
|
|
|
int len, *str;
|
|
|
|
|
|
|
|
len = s->len;
|
|
|
|
str = s->str;
|
|
|
|
if (len >= s->allocated_len)
|
2021-10-22 13:39:54 +08:00
|
|
|
str = tok_str_realloc(s, len + 1);
|
2009-05-06 02:17:49 +08:00
|
|
|
str[len++] = t;
|
|
|
|
s->len = len;
|
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void begin_macro(TokenString *str, int alloc)
|
2016-10-02 02:26:50 +08:00
|
|
|
{
|
|
|
|
str->alloc = alloc;
|
2021-10-22 13:39:54 +08:00
|
|
|
str->prev = macro_stack;
|
|
|
|
str->prev_ptr = macro_ptr;
|
|
|
|
str->save_line_num = file->line_num;
|
|
|
|
macro_ptr = str->str;
|
|
|
|
macro_stack = str;
|
2016-10-02 02:26:50 +08:00
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void end_macro(void)
|
2016-10-02 02:26:50 +08:00
|
|
|
{
|
2021-10-22 13:39:54 +08:00
|
|
|
TokenString *str = macro_stack;
|
|
|
|
macro_stack = str->prev;
|
|
|
|
macro_ptr = str->prev_ptr;
|
|
|
|
file->line_num = str->save_line_num;
|
2022-07-11 21:27:51 +08:00
|
|
|
str->len = 0; /* matters if str not alloced, may be tokstr_buf */
|
2018-06-08 21:31:40 +08:00
|
|
|
if (str->alloc != 0) {
|
|
|
|
if (str->alloc == 2)
|
|
|
|
str->str = NULL; /* don't free */
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_free(str);
|
2016-10-02 02:26:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static void tok_str_add2(TokenString *s, int t, CValue *cv)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
|
|
|
int len, *str;
|
|
|
|
|
2017-06-05 19:21:39 +08:00
|
|
|
len = s->lastlen = s->len;
|
2009-05-06 02:17:49 +08:00
|
|
|
str = s->str;
|
|
|
|
|
|
|
|
/* allocate space for worst case */
|
2016-04-17 21:37:23 +08:00
|
|
|
if (len + TOK_MAX_SIZE >= s->allocated_len)
|
2021-10-22 13:39:54 +08:00
|
|
|
str = tok_str_realloc(s, len + TOK_MAX_SIZE + 1);
|
2009-05-06 02:17:49 +08:00
|
|
|
str[len++] = t;
|
|
|
|
switch(t) {
|
|
|
|
case TOK_CINT:
|
|
|
|
case TOK_CUINT:
|
|
|
|
case TOK_CCHAR:
|
|
|
|
case TOK_LCHAR:
|
|
|
|
case TOK_CFLOAT:
|
|
|
|
case TOK_LINENUM:
|
2017-09-25 00:57:48 +08:00
|
|
|
#if LONG_SIZE == 4
|
mutiples fix for _Generic
* check that _Generic don't match unsigned char * with char *
this case is usefull as with -funsigned-char, 'char *' are unsigned
* change VT_LONG so it's now a qualifier
VT_LONG are never use for code generation, but only durring parsing state,
in _Generic we need to be able to make diference between
'long' and 'long long'
So VT_LONG is now use as a type qualifier, it's old behaviour is still
here, but we can keep trace of what was a long and what wasn't
* add TOK_CLONG and TOK_CULONG
tcc was directly converting value like '7171L' into TOK_CLLONG or
TOK_CINT depending of the machine architecture.
because of that, we was unable to make diference between a long and a
long long, which doesn't work with _Generic.
So now 7171L is a TOK_CLONG, and we can handle _Generic properly
* check that _Generic can make diference between long and long long
* uncomment "type match twice" as it should now pass tests on any platforms
* add inside_generic global
the point of this variable is to use VT_LONG in comparaison only
when we are evaluating a _Generic.
problem is with my lastest patchs tcc can now make the diference between
a 'long long' and a 'long', but in 64 bit stddef.h typedef uint64_t as
typedef signed long long int int64_t and stdint.h as unsigned long int, so tcc
break when stdint.h and stddef.h are include together.
Another solution woud be to modifie include/stddef.h so it define uint64_t as
unsigned long int when processor is 64 bit, but this could break some
legacy code, so for now, VT_LONG are use only inside generc.
* check that _Generic parse first argument correctly
* check that _Generic evaluate correctly exresion like "f() / 2"
2017-07-10 23:44:53 +08:00
|
|
|
case TOK_CLONG:
|
|
|
|
case TOK_CULONG:
|
|
|
|
#endif
|
2009-05-06 02:17:49 +08:00
|
|
|
str[len++] = cv->tab[0];
|
|
|
|
break;
|
|
|
|
case TOK_PPNUM:
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
case TOK_PPSTR:
|
2009-05-06 02:17:49 +08:00
|
|
|
case TOK_STR:
|
|
|
|
case TOK_LSTR:
|
|
|
|
{
|
2015-11-21 19:23:53 +08:00
|
|
|
/* Insert the string into the int array. */
|
|
|
|
size_t nb_words =
|
|
|
|
1 + (cv->str.size + sizeof(int) - 1) / sizeof(int);
|
2016-04-17 21:37:23 +08:00
|
|
|
if (len + nb_words >= s->allocated_len)
|
2021-10-22 13:39:54 +08:00
|
|
|
str = tok_str_realloc(s, len + nb_words + 1);
|
2015-11-21 19:23:53 +08:00
|
|
|
str[len] = cv->str.size;
|
|
|
|
memcpy(&str[len + 1], cv->str.data, cv->str.size);
|
2009-05-06 02:17:49 +08:00
|
|
|
len += nb_words;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case TOK_CDOUBLE:
|
|
|
|
case TOK_CLLONG:
|
|
|
|
case TOK_CULLONG:
|
2017-09-25 00:57:48 +08:00
|
|
|
#if LONG_SIZE == 8
|
mutiples fix for _Generic
* check that _Generic don't match unsigned char * with char *
this case is usefull as with -funsigned-char, 'char *' are unsigned
* change VT_LONG so it's now a qualifier
VT_LONG are never use for code generation, but only durring parsing state,
in _Generic we need to be able to make diference between
'long' and 'long long'
So VT_LONG is now use as a type qualifier, it's old behaviour is still
here, but we can keep trace of what was a long and what wasn't
* add TOK_CLONG and TOK_CULONG
tcc was directly converting value like '7171L' into TOK_CLLONG or
TOK_CINT depending of the machine architecture.
because of that, we was unable to make diference between a long and a
long long, which doesn't work with _Generic.
So now 7171L is a TOK_CLONG, and we can handle _Generic properly
* check that _Generic can make diference between long and long long
* uncomment "type match twice" as it should now pass tests on any platforms
* add inside_generic global
the point of this variable is to use VT_LONG in comparaison only
when we are evaluating a _Generic.
problem is with my lastest patchs tcc can now make the diference between
a 'long long' and a 'long', but in 64 bit stddef.h typedef uint64_t as
typedef signed long long int int64_t and stdint.h as unsigned long int, so tcc
break when stdint.h and stddef.h are include together.
Another solution woud be to modifie include/stddef.h so it define uint64_t as
unsigned long int when processor is 64 bit, but this could break some
legacy code, so for now, VT_LONG are use only inside generc.
* check that _Generic parse first argument correctly
* check that _Generic evaluate correctly exresion like "f() / 2"
2017-07-10 23:44:53 +08:00
|
|
|
case TOK_CLONG:
|
|
|
|
case TOK_CULONG:
|
2009-05-06 02:17:49 +08:00
|
|
|
#endif
|
|
|
|
str[len++] = cv->tab[0];
|
|
|
|
str[len++] = cv->tab[1];
|
|
|
|
break;
|
|
|
|
case TOK_CLDOUBLE:
|
2023-04-25 14:59:42 +08:00
|
|
|
#if LDOUBLE_SIZE == 8 || defined TCC_USING_DOUBLE_FOR_LDOUBLE
|
|
|
|
str[len++] = cv->tab[0];
|
|
|
|
str[len++] = cv->tab[1];
|
|
|
|
#elif LDOUBLE_SIZE == 12
|
2009-05-06 02:17:49 +08:00
|
|
|
str[len++] = cv->tab[0];
|
|
|
|
str[len++] = cv->tab[1];
|
|
|
|
str[len++] = cv->tab[2];
|
|
|
|
#elif LDOUBLE_SIZE == 16
|
|
|
|
str[len++] = cv->tab[0];
|
|
|
|
str[len++] = cv->tab[1];
|
|
|
|
str[len++] = cv->tab[2];
|
|
|
|
str[len++] = cv->tab[3];
|
2023-04-25 14:59:42 +08:00
|
|
|
#else
|
2009-05-06 02:17:49 +08:00
|
|
|
#error add long double size support
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
s->len = len;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* add the current parse token in token string 's' */
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void tok_str_add_tok(TokenString *s)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
|
|
|
CValue cval;
|
|
|
|
|
|
|
|
/* save line number info */
|
2021-10-22 13:39:54 +08:00
|
|
|
if (file->line_num != s->last_line_num) {
|
|
|
|
s->last_line_num = file->line_num;
|
2009-05-06 02:17:49 +08:00
|
|
|
cval.i = s->last_line_num;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_add2(s, TOK_LINENUM, &cval);
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_add2(s, tok, &tokc);
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
2019-01-14 01:16:46 +08:00
|
|
|
/* get a token from an integer array and increment pointer. */
|
2020-06-18 00:08:09 +08:00
|
|
|
static inline void tok_get(int *t, const int **pp, CValue *cv)
|
2010-01-15 03:58:03 +08:00
|
|
|
{
|
|
|
|
const int *p = *pp;
|
|
|
|
int n, *tab;
|
|
|
|
|
|
|
|
tab = cv->tab;
|
|
|
|
switch(*t = *p++) {
|
2017-09-25 00:57:48 +08:00
|
|
|
#if LONG_SIZE == 4
|
|
|
|
case TOK_CLONG:
|
|
|
|
#endif
|
2010-01-15 03:58:03 +08:00
|
|
|
case TOK_CINT:
|
|
|
|
case TOK_CCHAR:
|
|
|
|
case TOK_LCHAR:
|
|
|
|
case TOK_LINENUM:
|
2017-09-25 00:57:48 +08:00
|
|
|
cv->i = *p++;
|
|
|
|
break;
|
|
|
|
#if LONG_SIZE == 4
|
mutiples fix for _Generic
* check that _Generic don't match unsigned char * with char *
this case is usefull as with -funsigned-char, 'char *' are unsigned
* change VT_LONG so it's now a qualifier
VT_LONG are never use for code generation, but only durring parsing state,
in _Generic we need to be able to make diference between
'long' and 'long long'
So VT_LONG is now use as a type qualifier, it's old behaviour is still
here, but we can keep trace of what was a long and what wasn't
* add TOK_CLONG and TOK_CULONG
tcc was directly converting value like '7171L' into TOK_CLLONG or
TOK_CINT depending of the machine architecture.
because of that, we was unable to make diference between a long and a
long long, which doesn't work with _Generic.
So now 7171L is a TOK_CLONG, and we can handle _Generic properly
* check that _Generic can make diference between long and long long
* uncomment "type match twice" as it should now pass tests on any platforms
* add inside_generic global
the point of this variable is to use VT_LONG in comparaison only
when we are evaluating a _Generic.
problem is with my lastest patchs tcc can now make the diference between
a 'long long' and a 'long', but in 64 bit stddef.h typedef uint64_t as
typedef signed long long int int64_t and stdint.h as unsigned long int, so tcc
break when stdint.h and stddef.h are include together.
Another solution woud be to modifie include/stddef.h so it define uint64_t as
unsigned long int when processor is 64 bit, but this could break some
legacy code, so for now, VT_LONG are use only inside generc.
* check that _Generic parse first argument correctly
* check that _Generic evaluate correctly exresion like "f() / 2"
2017-07-10 23:44:53 +08:00
|
|
|
case TOK_CULONG:
|
|
|
|
#endif
|
2017-09-25 00:57:48 +08:00
|
|
|
case TOK_CUINT:
|
|
|
|
cv->i = (unsigned)*p++;
|
2010-01-15 03:58:03 +08:00
|
|
|
break;
|
2017-03-07 04:45:41 +08:00
|
|
|
case TOK_CFLOAT:
|
|
|
|
tab[0] = *p++;
|
|
|
|
break;
|
2010-01-15 03:58:03 +08:00
|
|
|
case TOK_STR:
|
|
|
|
case TOK_LSTR:
|
|
|
|
case TOK_PPNUM:
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
case TOK_PPSTR:
|
2015-11-21 19:23:53 +08:00
|
|
|
cv->str.size = *p++;
|
|
|
|
cv->str.data = p;
|
|
|
|
p += (cv->str.size + sizeof(int) - 1) / sizeof(int);
|
2010-01-15 03:58:03 +08:00
|
|
|
break;
|
|
|
|
case TOK_CDOUBLE:
|
|
|
|
case TOK_CLLONG:
|
|
|
|
case TOK_CULLONG:
|
2017-09-25 00:57:48 +08:00
|
|
|
#if LONG_SIZE == 8
|
mutiples fix for _Generic
* check that _Generic don't match unsigned char * with char *
this case is usefull as with -funsigned-char, 'char *' are unsigned
* change VT_LONG so it's now a qualifier
VT_LONG are never use for code generation, but only durring parsing state,
in _Generic we need to be able to make diference between
'long' and 'long long'
So VT_LONG is now use as a type qualifier, it's old behaviour is still
here, but we can keep trace of what was a long and what wasn't
* add TOK_CLONG and TOK_CULONG
tcc was directly converting value like '7171L' into TOK_CLLONG or
TOK_CINT depending of the machine architecture.
because of that, we was unable to make diference between a long and a
long long, which doesn't work with _Generic.
So now 7171L is a TOK_CLONG, and we can handle _Generic properly
* check that _Generic can make diference between long and long long
* uncomment "type match twice" as it should now pass tests on any platforms
* add inside_generic global
the point of this variable is to use VT_LONG in comparaison only
when we are evaluating a _Generic.
problem is with my lastest patchs tcc can now make the diference between
a 'long long' and a 'long', but in 64 bit stddef.h typedef uint64_t as
typedef signed long long int int64_t and stdint.h as unsigned long int, so tcc
break when stdint.h and stddef.h are include together.
Another solution woud be to modifie include/stddef.h so it define uint64_t as
unsigned long int when processor is 64 bit, but this could break some
legacy code, so for now, VT_LONG are use only inside generc.
* check that _Generic parse first argument correctly
* check that _Generic evaluate correctly exresion like "f() / 2"
2017-07-10 23:44:53 +08:00
|
|
|
case TOK_CLONG:
|
|
|
|
case TOK_CULONG:
|
|
|
|
#endif
|
2010-01-15 03:58:03 +08:00
|
|
|
n = 2;
|
|
|
|
goto copy;
|
|
|
|
case TOK_CLDOUBLE:
|
2023-04-25 14:59:42 +08:00
|
|
|
#if LDOUBLE_SIZE == 8 || defined TCC_USING_DOUBLE_FOR_LDOUBLE
|
|
|
|
n = 2;
|
2009-05-06 02:17:49 +08:00
|
|
|
#elif LDOUBLE_SIZE == 12
|
2010-01-15 03:58:03 +08:00
|
|
|
n = 3;
|
2023-04-25 14:59:42 +08:00
|
|
|
#elif LDOUBLE_SIZE == 16
|
|
|
|
n = 4;
|
2009-05-06 02:17:49 +08:00
|
|
|
#else
|
2010-01-15 03:58:03 +08:00
|
|
|
# error add long double size support
|
2009-05-06 02:17:49 +08:00
|
|
|
#endif
|
2010-01-15 03:58:03 +08:00
|
|
|
copy:
|
|
|
|
do
|
|
|
|
*tab++ = *p++;
|
|
|
|
while (--n);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
*pp = p;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
2020-06-18 00:08:09 +08:00
|
|
|
#if 0
|
|
|
|
# define TOK_GET(t,p,c) tok_get(t,p,c)
|
|
|
|
#else
|
|
|
|
# define TOK_GET(t,p,c) do { \
|
|
|
|
int _t = **(p); \
|
|
|
|
if (TOK_HAS_VALUE(_t)) \
|
|
|
|
tok_get(t, p, c); \
|
|
|
|
else \
|
|
|
|
*(t) = _t, ++*(p); \
|
|
|
|
} while (0)
|
|
|
|
#endif
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static int macro_is_equal(const int *a, const int *b)
|
2010-01-15 03:57:50 +08:00
|
|
|
{
|
After several days searching why my code refactoring to remove globals was crashing,
I found the problem it was because CValue stack variables have rubish as it inital values
and assigning to a member that is smaller than the big union item and trying to
recover it later as a different member gives bak garbage.
ST_FUNC void vset(TCCState* tcc_state, CType *type, int r, int v)
{
CValue cval;
memset(&cval, 0, sizeof(CValue));
cval.i = v; //,<<<<<<<<<<< here is the main bug that mix with garbage
vsetc(tcc_state, type, r, &cval);
}
/* store a value or an expression directly in global data or in local array */
static void init_putv(TCCState* tcc_state, CType *type, Section *sec, unsigned long c,
int v, int expr_type)
{
...
case VT_PTR:
if (tcc_state->tccgen_vtop->r & VT_SYM) {
greloc(tcc_state, sec, tcc_state->tccgen_vtop->sym, c, R_DATA_PTR);
}
//<<< on the next line is where we try to get the assigned value to cvalue.i as cvalue.ull
*(addr_t *)ptr |= (tcc_state->tccgen_vtop->c.ull & bit_mask) << bit_pos;
break;
Also this patch makes vla tests pass on linux 32 bits
2014-03-27 04:14:39 +08:00
|
|
|
CValue cv;
|
2014-04-05 02:18:39 +08:00
|
|
|
int t;
|
2016-05-05 20:12:53 +08:00
|
|
|
|
|
|
|
if (!a || !b)
|
|
|
|
return 1;
|
|
|
|
|
2010-01-15 03:57:50 +08:00
|
|
|
while (*a && *b) {
|
2023-04-25 03:58:50 +08:00
|
|
|
cstr_reset(&tokcstr);
|
2010-01-15 03:58:03 +08:00
|
|
|
TOK_GET(&t, &a, &cv);
|
2023-04-25 03:58:50 +08:00
|
|
|
cstr_cat(&tokcstr, get_tok_str(t, &cv), 0);
|
2010-01-15 03:58:03 +08:00
|
|
|
TOK_GET(&t, &b, &cv);
|
2023-04-25 03:58:50 +08:00
|
|
|
if (strcmp(tokcstr.data, get_tok_str(t, &cv)))
|
2010-01-15 03:57:50 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return !(*a || *b);
|
|
|
|
}
|
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
/* defines handling */
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
2016-05-05 20:12:53 +08:00
|
|
|
Sym *s, *o;
|
2010-01-15 03:57:50 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
o = define_find(v);
|
|
|
|
s = sym_push2(&define_stack, v, macro_type, 0);
|
2016-10-02 02:26:50 +08:00
|
|
|
s->d = str;
|
2009-05-06 02:17:49 +08:00
|
|
|
s->next = first_arg;
|
2021-10-22 13:39:54 +08:00
|
|
|
table_ident[v - TOK_IDENT]->sym_define = s;
|
2016-05-05 20:12:53 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
if (o && !macro_is_equal(o->d, s->d))
|
|
|
|
tcc_warning("%s redefined", get_tok_str(v, NULL));
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* undefined a define symbol. Its name is just set to zero */
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void define_undef(Sym *s)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
2015-05-13 17:16:00 +08:00
|
|
|
int v = s->v;
|
2021-10-22 13:39:54 +08:00
|
|
|
if (v >= TOK_IDENT && v < tok_ident)
|
|
|
|
table_ident[v - TOK_IDENT]->sym_define = NULL;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_INLN Sym *define_find(int v)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
|
|
|
v -= TOK_IDENT;
|
2021-10-22 13:39:54 +08:00
|
|
|
if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
|
2009-05-06 02:17:49 +08:00
|
|
|
return NULL;
|
2021-10-22 13:39:54 +08:00
|
|
|
return table_ident[v]->sym_define;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* free define stack until top reaches 'b' */
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void free_defines(Sym *b)
|
|
|
|
{
|
|
|
|
while (define_stack != b) {
|
|
|
|
Sym *top = define_stack;
|
|
|
|
define_stack = top->prev;
|
|
|
|
tok_str_free_str(top->d);
|
|
|
|
define_undef(top);
|
|
|
|
sym_free(top);
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-21 04:21:27 +08:00
|
|
|
/* fake the nth "#if defined test_..." for tcc -dt -run */
|
2021-10-22 13:39:54 +08:00
|
|
|
static void maybe_run_test(TCCState *s)
|
2017-07-21 04:21:27 +08:00
|
|
|
{
|
|
|
|
const char *p;
|
2021-10-22 13:39:54 +08:00
|
|
|
if (s->include_stack_ptr != s->include_stack)
|
2017-07-21 04:21:27 +08:00
|
|
|
return;
|
2021-10-22 13:39:54 +08:00
|
|
|
p = get_tok_str(tok, NULL);
|
2017-07-21 04:21:27 +08:00
|
|
|
if (0 != memcmp(p, "test_", 5))
|
|
|
|
return;
|
2021-10-22 13:39:54 +08:00
|
|
|
if (0 != --s->run_test)
|
2017-07-21 04:21:27 +08:00
|
|
|
return;
|
2021-10-22 13:39:54 +08:00
|
|
|
fprintf(s->ppfp, &"\n[%s]\n"[!(s->dflag & 32)], p), fflush(s->ppfp);
|
|
|
|
define_push(tok, MACRO_OBJ, NULL, NULL);
|
2017-07-21 04:21:27 +08:00
|
|
|
}
|
|
|
|
|
2022-08-18 16:23:13 +08:00
|
|
|
static CachedInclude *
|
|
|
|
search_cached_include(TCCState *s1, const char *filename, int add);
|
|
|
|
|
|
|
|
static int parse_include(TCCState *s1, int do_next, int test)
|
2022-08-14 18:17:31 +08:00
|
|
|
{
|
2022-08-18 16:23:13 +08:00
|
|
|
int c, i;
|
|
|
|
char name[1024], buf[1024], *p;
|
|
|
|
CachedInclude *e;
|
2022-08-14 18:17:31 +08:00
|
|
|
|
2022-08-18 16:43:28 +08:00
|
|
|
c = skip_spaces();
|
2022-08-18 16:23:13 +08:00
|
|
|
if (c == '<' || c == '\"') {
|
2023-04-25 03:58:50 +08:00
|
|
|
cstr_reset(&tokcstr);
|
|
|
|
file->buf_ptr = parse_pp_string(file->buf_ptr, c == '<' ? '>' : c, &tokcstr);
|
|
|
|
i = tokcstr.size;
|
|
|
|
pstrncpy(name, tokcstr.data, i >= sizeof name ? sizeof name - 1 : i);
|
2022-08-18 16:23:13 +08:00
|
|
|
next_nomacro();
|
|
|
|
} else {
|
|
|
|
/* computed #include : concatenate tokens until result is one of
|
|
|
|
the two accepted forms. Don't convert pp-tokens to tokens here. */
|
|
|
|
parse_flags = PARSE_FLAG_PREPROCESS
|
|
|
|
| PARSE_FLAG_LINEFEED
|
|
|
|
| (parse_flags & PARSE_FLAG_ASM_FILE);
|
2023-04-25 03:58:50 +08:00
|
|
|
name[0] = 0;
|
2022-08-18 16:23:13 +08:00
|
|
|
for (;;) {
|
|
|
|
next();
|
2023-04-25 03:58:50 +08:00
|
|
|
p = name, i = strlen(p) - 1;
|
2022-08-18 16:23:13 +08:00
|
|
|
if (i > 0
|
|
|
|
&& ((p[0] == '"' && p[i] == '"')
|
|
|
|
|| (p[0] == '<' && p[i] == '>')))
|
|
|
|
break;
|
|
|
|
if (tok == TOK_LINEFEED)
|
|
|
|
tcc_error("'#include' expects \"FILENAME\" or <FILENAME>");
|
2023-04-25 03:58:50 +08:00
|
|
|
pstrcat(name, sizeof name, get_tok_str(tok, &tokc));
|
2022-08-18 16:23:13 +08:00
|
|
|
}
|
|
|
|
c = p[0];
|
|
|
|
/* remove '<>|""' */
|
2023-04-25 03:58:50 +08:00
|
|
|
memmove(p, p + 1, i - 1), p[i - 1] = 0;
|
2022-08-18 16:23:13 +08:00
|
|
|
}
|
2022-08-14 18:17:31 +08:00
|
|
|
|
2022-08-18 16:23:13 +08:00
|
|
|
i = do_next ? file->include_next_index : -1;
|
|
|
|
for (;;) {
|
|
|
|
++i;
|
|
|
|
if (i == 0) {
|
|
|
|
/* check absolute include path */
|
|
|
|
if (!IS_ABSPATH(name))
|
|
|
|
continue;
|
|
|
|
buf[0] = '\0';
|
|
|
|
} else if (i == 1) {
|
|
|
|
/* search in file's dir if "header.h" */
|
|
|
|
if (c != '\"')
|
|
|
|
continue;
|
|
|
|
p = file->true_filename;
|
|
|
|
pstrncpy(buf, p, tcc_basename(p) - p);
|
|
|
|
} else {
|
|
|
|
int j = i - 2, k = j - s1->nb_include_paths;
|
|
|
|
if (k < 0)
|
|
|
|
p = s1->include_paths[j];
|
|
|
|
else if (k < s1->nb_sysinclude_paths)
|
|
|
|
p = s1->sysinclude_paths[k];
|
|
|
|
else if (test)
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
tcc_error("include file '%s' not found", name);
|
|
|
|
pstrcpy(buf, sizeof buf, p);
|
|
|
|
pstrcat(buf, sizeof buf, "/");
|
2022-08-14 18:17:31 +08:00
|
|
|
}
|
2022-08-18 16:23:13 +08:00
|
|
|
pstrcat(buf, sizeof buf, name);
|
|
|
|
e = search_cached_include(s1, buf, 0);
|
|
|
|
if (e && (define_find(e->ifndef_macro) || e->once == pp_once)) {
|
|
|
|
/* no need to parse the include because the 'ifndef macro'
|
|
|
|
is defined (or had #pragma once) */
|
|
|
|
#ifdef INC_DEBUG
|
|
|
|
printf("%s: skipping cached %s\n", file->filename, buf);
|
2022-08-14 18:17:31 +08:00
|
|
|
#endif
|
2022-08-18 16:23:13 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (tcc_open(s1, buf) >= 0)
|
|
|
|
break;
|
2022-08-14 18:17:31 +08:00
|
|
|
}
|
|
|
|
|
2022-08-18 16:23:13 +08:00
|
|
|
if (test) {
|
|
|
|
tcc_close();
|
2022-08-14 18:17:31 +08:00
|
|
|
} else {
|
2022-08-18 16:23:13 +08:00
|
|
|
if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
|
|
|
|
tcc_error("#include recursion too deep");
|
|
|
|
/* push previous file on stack */
|
|
|
|
*s1->include_stack_ptr++ = file->prev;
|
|
|
|
file->include_next_index = i;
|
|
|
|
#ifdef INC_DEBUG
|
|
|
|
printf("%s: including %s\n", file->prev->filename, file->filename);
|
|
|
|
#endif
|
|
|
|
/* update target deps */
|
|
|
|
if (s1->gen_deps) {
|
|
|
|
BufferedFile *bf = file;
|
|
|
|
while (i == 1 && (bf = bf->prev))
|
|
|
|
i = bf->include_next_index;
|
|
|
|
/* skip system include files */
|
|
|
|
if (s1->include_sys_deps || i - 2 < s1->nb_include_paths)
|
|
|
|
dynarray_add(&s1->target_deps, &s1->nb_target_deps,
|
|
|
|
tcc_strdup(buf));
|
|
|
|
}
|
|
|
|
/* add include file debug info */
|
|
|
|
tcc_debug_bincl(s1);
|
|
|
|
tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
|
2022-08-14 18:17:31 +08:00
|
|
|
}
|
2022-08-18 16:23:13 +08:00
|
|
|
return 1;
|
2022-08-14 18:17:31 +08:00
|
|
|
}
|
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
/* eval an expression for #if/#elif */
|
2022-08-14 18:17:31 +08:00
|
|
|
static int expr_preprocess(TCCState *s1)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
|
|
|
int c, t;
|
2016-10-02 02:26:50 +08:00
|
|
|
TokenString *str;
|
2015-07-30 04:53:57 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
str = tok_str_alloc();
|
|
|
|
pp_expr = 1;
|
|
|
|
while (tok != TOK_LINEFEED && tok != TOK_EOF) {
|
|
|
|
next(); /* do macro subst */
|
2020-05-09 06:39:45 +08:00
|
|
|
redo:
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok == TOK_DEFINED) {
|
|
|
|
next_nomacro();
|
|
|
|
t = tok;
|
2015-07-30 04:53:57 +08:00
|
|
|
if (t == '(')
|
2021-10-22 13:39:54 +08:00
|
|
|
next_nomacro();
|
2022-08-18 16:23:13 +08:00
|
|
|
if (tok < TOK_IDENT)
|
|
|
|
expect("identifier");
|
|
|
|
if (s1->run_test)
|
|
|
|
maybe_run_test(s1);
|
|
|
|
c = 0;
|
|
|
|
if (define_find(tok)
|
|
|
|
|| tok == TOK___HAS_INCLUDE
|
|
|
|
|| tok == TOK___HAS_INCLUDE_NEXT)
|
|
|
|
c = 1;
|
2017-06-05 19:21:39 +08:00
|
|
|
if (t == '(') {
|
2021-10-22 13:39:54 +08:00
|
|
|
next_nomacro();
|
|
|
|
if (tok != ')')
|
|
|
|
expect("')'");
|
2017-06-05 19:21:39 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_CINT;
|
|
|
|
tokc.i = c;
|
2022-08-14 18:17:31 +08:00
|
|
|
} else if (tok == TOK___HAS_INCLUDE ||
|
|
|
|
tok == TOK___HAS_INCLUDE_NEXT) {
|
2022-08-18 16:23:13 +08:00
|
|
|
t = tok;
|
2022-08-14 18:17:31 +08:00
|
|
|
next_nomacro();
|
|
|
|
if (tok != '(')
|
|
|
|
expect("(");
|
2022-08-18 16:23:13 +08:00
|
|
|
c = parse_include(s1, t - TOK___HAS_INCLUDE, 1);
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok != ')')
|
2022-08-14 18:17:31 +08:00
|
|
|
expect("')'");
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_CINT;
|
2022-08-18 16:23:13 +08:00
|
|
|
tokc.i = c;
|
2021-10-22 13:39:54 +08:00
|
|
|
} else if (tok >= TOK_IDENT) {
|
2020-05-09 06:39:45 +08:00
|
|
|
/* if undefined macro, replace with zero, check for func-like */
|
2021-10-22 13:39:54 +08:00
|
|
|
t = tok;
|
|
|
|
tok = TOK_CINT;
|
|
|
|
tokc.i = 0;
|
|
|
|
tok_str_add_tok(str);
|
|
|
|
next();
|
|
|
|
if (tok == '(')
|
|
|
|
tcc_error("function-like macro '%s' is not defined",
|
|
|
|
get_tok_str(t, NULL));
|
2020-05-09 06:39:45 +08:00
|
|
|
goto redo;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_add_tok(str);
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
pp_expr = 0;
|
|
|
|
tok_str_add(str, -1); /* simulate end of file */
|
|
|
|
tok_str_add(str, 0);
|
2009-05-06 02:17:49 +08:00
|
|
|
/* now evaluate C constant expression */
|
2021-10-22 13:39:54 +08:00
|
|
|
begin_macro(str, 1);
|
|
|
|
next();
|
|
|
|
c = expr_const();
|
|
|
|
end_macro();
|
2009-05-06 02:17:49 +08:00
|
|
|
return c != 0;
|
|
|
|
}
|
|
|
|
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
/* parse after #define */
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void parse_define(void)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
|
|
|
Sym *s, *first, **ps;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
int v, t, varg, is_vaargs, spc;
|
2021-10-22 13:39:54 +08:00
|
|
|
int saved_parse_flags = parse_flags;
|
2014-04-08 22:19:48 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
v = tok;
|
2017-06-05 19:21:39 +08:00
|
|
|
if (v < TOK_IDENT || v == TOK_DEFINED)
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("invalid macro name '%s'", get_tok_str(tok, &tokc));
|
2009-05-06 02:17:49 +08:00
|
|
|
/* XXX: should check if same macro (ANSI) */
|
|
|
|
first = NULL;
|
|
|
|
t = MACRO_OBJ;
|
2016-08-25 22:40:50 +08:00
|
|
|
/* We have to parse the whole define as if not in asm mode, in particular
|
|
|
|
no line comment with '#' must be ignored. Also for function
|
|
|
|
macros the argument list must be parsed without '.' being an ID
|
|
|
|
character. */
|
2021-10-22 13:39:54 +08:00
|
|
|
parse_flags = ((parse_flags & ~PARSE_FLAG_ASM_FILE) | PARSE_FLAG_SPACES);
|
2009-05-06 02:17:49 +08:00
|
|
|
/* '(' must be just after macro definition for MACRO_FUNC */
|
2021-10-22 13:39:54 +08:00
|
|
|
next_nomacro();
|
|
|
|
parse_flags &= ~PARSE_FLAG_SPACES;
|
|
|
|
if (tok == '(') {
|
|
|
|
int dotid = set_idnum('.', 0);
|
|
|
|
next_nomacro();
|
2009-05-06 02:17:49 +08:00
|
|
|
ps = &first;
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok != ')') for (;;) {
|
|
|
|
varg = tok;
|
|
|
|
next_nomacro();
|
2009-05-06 02:17:49 +08:00
|
|
|
is_vaargs = 0;
|
|
|
|
if (varg == TOK_DOTS) {
|
|
|
|
varg = TOK___VA_ARGS__;
|
|
|
|
is_vaargs = 1;
|
2021-10-22 13:39:54 +08:00
|
|
|
} else if (tok == TOK_DOTS && gnu_ext) {
|
2009-05-06 02:17:49 +08:00
|
|
|
is_vaargs = 1;
|
2021-10-22 13:39:54 +08:00
|
|
|
next_nomacro();
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
if (varg < TOK_IDENT)
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
bad_list:
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("bad macro parameter list");
|
|
|
|
s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
|
2009-05-06 02:17:49 +08:00
|
|
|
*ps = s;
|
|
|
|
ps = &s->next;
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok == ')')
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
break;
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok != ',' || is_vaargs)
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
goto bad_list;
|
2021-10-22 13:39:54 +08:00
|
|
|
next_nomacro();
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
parse_flags |= PARSE_FLAG_SPACES;
|
|
|
|
next_nomacro();
|
2009-05-06 02:17:49 +08:00
|
|
|
t = MACRO_FUNC;
|
2021-10-22 13:39:54 +08:00
|
|
|
set_idnum('.', dotid);
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2016-04-17 21:37:23 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
tokstr_buf.len = 0;
|
2009-05-06 02:17:49 +08:00
|
|
|
spc = 2;
|
2021-10-22 13:39:54 +08:00
|
|
|
parse_flags |= PARSE_FLAG_ACCEPT_STRAYS | PARSE_FLAG_SPACES | PARSE_FLAG_LINEFEED;
|
2016-08-25 22:40:50 +08:00
|
|
|
/* The body of a macro definition should be parsed such that identifiers
|
|
|
|
are parsed like the file mode determines (i.e. with '.' being an
|
|
|
|
ID character in asm mode). But '#' should be retained instead of
|
|
|
|
regarded as line comment leader, so still don't set ASM_FILE
|
|
|
|
in parse_flags. */
|
2021-10-22 13:39:54 +08:00
|
|
|
while (tok != TOK_LINEFEED && tok != TOK_EOF) {
|
2014-04-08 22:19:48 +08:00
|
|
|
/* remove spaces around ## and after '#' */
|
2021-10-22 13:39:54 +08:00
|
|
|
if (TOK_TWOSHARPS == tok) {
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
if (2 == spc)
|
|
|
|
goto bad_twosharp;
|
2009-05-06 02:17:49 +08:00
|
|
|
if (1 == spc)
|
2021-10-22 13:39:54 +08:00
|
|
|
--tokstr_buf.len;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
spc = 3;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_PPJOIN;
|
|
|
|
} else if ('#' == tok) {
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
spc = 4;
|
2021-10-22 13:39:54 +08:00
|
|
|
} else if (check_space(tok, &spc)) {
|
2009-05-06 02:17:49 +08:00
|
|
|
goto skip;
|
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_add2(&tokstr_buf, tok, &tokc);
|
2009-05-06 02:17:49 +08:00
|
|
|
skip:
|
2021-10-22 13:39:54 +08:00
|
|
|
next_nomacro();
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
parse_flags = saved_parse_flags;
|
2009-05-06 02:17:49 +08:00
|
|
|
if (spc == 1)
|
2021-10-22 13:39:54 +08:00
|
|
|
--tokstr_buf.len; /* remove trailing space */
|
|
|
|
tok_str_add(&tokstr_buf, 0);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
if (3 == spc)
|
|
|
|
bad_twosharp:
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("'##' cannot appear at either end of macro");
|
|
|
|
define_push(v, t, tok_str_dup(&tokstr_buf), first);
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static CachedInclude *search_cached_include(TCCState *s1, const char *filename, int add)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
|
|
|
const unsigned char *s;
|
|
|
|
unsigned int h;
|
2016-10-02 02:03:48 +08:00
|
|
|
CachedInclude *e;
|
|
|
|
int i;
|
2009-05-06 02:17:49 +08:00
|
|
|
|
|
|
|
h = TOK_HASH_INIT;
|
2014-03-09 22:52:31 +08:00
|
|
|
s = (unsigned char *) filename;
|
2009-05-06 02:17:49 +08:00
|
|
|
while (*s) {
|
2016-10-02 02:03:48 +08:00
|
|
|
#ifdef _WIN32
|
|
|
|
h = TOK_HASH_FUNC(h, toup(*s));
|
|
|
|
#else
|
2009-05-06 02:17:49 +08:00
|
|
|
h = TOK_HASH_FUNC(h, *s);
|
2016-10-02 02:03:48 +08:00
|
|
|
#endif
|
2009-05-06 02:17:49 +08:00
|
|
|
s++;
|
|
|
|
}
|
|
|
|
h &= (CACHED_INCLUDES_HASH_SIZE - 1);
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
i = s1->cached_includes_hash[h];
|
2009-05-06 02:17:49 +08:00
|
|
|
for(;;) {
|
|
|
|
if (i == 0)
|
|
|
|
break;
|
2021-10-22 13:39:54 +08:00
|
|
|
e = s1->cached_includes[i - 1];
|
2013-01-07 00:20:44 +08:00
|
|
|
if (0 == PATHCMP(e->filename, filename))
|
2009-05-06 02:17:49 +08:00
|
|
|
return e;
|
|
|
|
i = e->hash_next;
|
|
|
|
}
|
2016-10-02 02:03:48 +08:00
|
|
|
if (!add)
|
|
|
|
return NULL;
|
2009-05-06 02:17:49 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
|
2009-05-06 02:17:49 +08:00
|
|
|
strcpy(e->filename, filename);
|
2016-10-02 02:03:48 +08:00
|
|
|
e->ifndef_macro = e->once = 0;
|
2021-10-22 13:39:54 +08:00
|
|
|
dynarray_add(&s1->cached_includes, &s1->nb_cached_includes, e);
|
2009-05-06 02:17:49 +08:00
|
|
|
/* add in hash table */
|
2021-10-22 13:39:54 +08:00
|
|
|
e->hash_next = s1->cached_includes_hash[h];
|
|
|
|
s1->cached_includes_hash[h] = s1->nb_cached_includes;
|
2016-10-02 02:03:48 +08:00
|
|
|
#ifdef INC_DEBUG
|
|
|
|
printf("adding cached '%s'\n", filename);
|
|
|
|
#endif
|
|
|
|
return e;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static void pragma_parse(TCCState *s1)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
2021-10-22 13:39:54 +08:00
|
|
|
next_nomacro();
|
|
|
|
if (tok == TOK_push_macro || tok == TOK_pop_macro) {
|
|
|
|
int t = tok, v;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
Sym *s;
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
if (next(), tok != '(')
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
goto pragma_err;
|
2021-10-22 13:39:54 +08:00
|
|
|
if (next(), tok != TOK_STR)
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
goto pragma_err;
|
2021-10-22 13:39:54 +08:00
|
|
|
v = tok_alloc(tokc.str.data, tokc.str.size - 1)->tok;
|
|
|
|
if (next(), tok != ')')
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
goto pragma_err;
|
|
|
|
if (t == TOK_push_macro) {
|
2021-10-22 13:39:54 +08:00
|
|
|
while (NULL == (s = define_find(v)))
|
|
|
|
define_push(v, 0, NULL, NULL);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
s->type.ref = s; /* set push boundary */
|
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
for (s = define_stack; s; s = s->prev)
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
if (s->v == v && s->type.ref == s) {
|
|
|
|
s->type.ref = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (s)
|
2021-10-22 13:39:54 +08:00
|
|
|
table_ident[v - TOK_IDENT]->sym_define = s->d ? s : NULL;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
else
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_warning("unbalanced #pragma pop_macro");
|
|
|
|
pp_debug_tok = t, pp_debug_symv = v;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
} else if (tok == TOK_once) {
|
|
|
|
search_cached_include(s1, file->filename, 1)->once = pp_once;
|
2016-10-02 02:03:48 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
} else if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
/* tcc -E: keep pragmas below unchanged */
|
2021-10-22 13:39:54 +08:00
|
|
|
unget_tok(' ');
|
|
|
|
unget_tok(TOK_PRAGMA);
|
|
|
|
unget_tok('#');
|
|
|
|
unget_tok(TOK_LINEFEED);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
} else if (tok == TOK_pack) {
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
/* This may be:
|
|
|
|
#pragma pack(1) // set
|
|
|
|
#pragma pack() // reset to default
|
2021-08-20 01:01:23 +08:00
|
|
|
#pragma pack(push) // push current
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
#pragma pack(push,1) // push & set
|
|
|
|
#pragma pack(pop) // restore previous */
|
2021-10-22 13:39:54 +08:00
|
|
|
next();
|
|
|
|
skip('(');
|
|
|
|
if (tok == TOK_ASM_pop) {
|
|
|
|
next();
|
|
|
|
if (s1->pack_stack_ptr <= s1->pack_stack) {
|
2009-05-06 02:17:49 +08:00
|
|
|
stk_error:
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("out of pack stack");
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
s1->pack_stack_ptr--;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
2015-04-24 05:27:36 +08:00
|
|
|
int val = 0;
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok != ')') {
|
|
|
|
if (tok == TOK_ASM_push) {
|
|
|
|
next();
|
|
|
|
if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1)
|
2009-05-06 02:17:49 +08:00
|
|
|
goto stk_error;
|
2021-10-22 13:39:54 +08:00
|
|
|
val = *s1->pack_stack_ptr++;
|
|
|
|
if (tok != ',')
|
2021-08-20 01:01:23 +08:00
|
|
|
goto pack_set;
|
2021-10-22 13:39:54 +08:00
|
|
|
next();
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok != TOK_CINT)
|
2015-04-24 05:27:36 +08:00
|
|
|
goto pragma_err;
|
2021-10-22 13:39:54 +08:00
|
|
|
val = tokc.i;
|
2009-05-06 02:17:49 +08:00
|
|
|
if (val < 1 || val > 16 || (val & (val - 1)) != 0)
|
2015-04-24 05:27:36 +08:00
|
|
|
goto pragma_err;
|
2021-10-22 13:39:54 +08:00
|
|
|
next();
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2021-08-20 01:01:23 +08:00
|
|
|
pack_set:
|
2021-10-22 13:39:54 +08:00
|
|
|
*s1->pack_stack_ptr = val;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok != ')')
|
2015-04-24 05:27:36 +08:00
|
|
|
goto pragma_err;
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
} else if (tok == TOK_comment) {
|
2017-07-15 01:26:01 +08:00
|
|
|
char *p; int t;
|
2021-10-22 13:39:54 +08:00
|
|
|
next();
|
|
|
|
skip('(');
|
|
|
|
t = tok;
|
|
|
|
next();
|
|
|
|
skip(',');
|
|
|
|
if (tok != TOK_STR)
|
2015-04-24 05:27:36 +08:00
|
|
|
goto pragma_err;
|
2021-10-22 13:39:54 +08:00
|
|
|
p = tcc_strdup((char *)tokc.str.data);
|
|
|
|
next();
|
|
|
|
if (tok != ')')
|
2015-04-24 05:27:36 +08:00
|
|
|
goto pragma_err;
|
2017-07-15 01:26:01 +08:00
|
|
|
if (t == TOK_lib) {
|
2021-10-22 13:39:54 +08:00
|
|
|
dynarray_add(&s1->pragma_libs, &s1->nb_pragma_libs, p);
|
2017-07-15 01:26:01 +08:00
|
|
|
} else {
|
|
|
|
if (t == TOK_option)
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_set_options(s1, p);
|
|
|
|
tcc_free(p);
|
2017-07-15 01:26:01 +08:00
|
|
|
}
|
|
|
|
|
2021-08-01 02:44:51 +08:00
|
|
|
} else
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_warning_c(warn_unsupported)("#pragma %s ignored", get_tok_str(tok, &tokc));
|
2015-04-24 05:27:36 +08:00
|
|
|
return;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2015-04-24 05:27:36 +08:00
|
|
|
pragma_err:
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("malformed #pragma directive");
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
return;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* is_bof is true if first non space token at beginning of file */
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void preprocess(int is_bof)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
2021-10-22 13:39:54 +08:00
|
|
|
TCCState *s1 = tcc_state;
|
2022-08-18 16:23:13 +08:00
|
|
|
int c, n, saved_parse_flags;
|
2009-05-06 02:17:49 +08:00
|
|
|
char buf[1024], *q;
|
|
|
|
Sym *s;
|
2009-05-12 00:55:16 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
saved_parse_flags = parse_flags;
|
|
|
|
parse_flags = PARSE_FLAG_PREPROCESS
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
| PARSE_FLAG_TOK_NUM
|
|
|
|
| PARSE_FLAG_TOK_STR
|
|
|
|
| PARSE_FLAG_LINEFEED
|
2021-10-22 13:39:54 +08:00
|
|
|
| (parse_flags & PARSE_FLAG_ASM_FILE)
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
;
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
next_nomacro();
|
2009-05-06 02:17:49 +08:00
|
|
|
redo:
|
2021-10-22 13:39:54 +08:00
|
|
|
switch(tok) {
|
2009-05-06 02:17:49 +08:00
|
|
|
case TOK_DEFINE:
|
2021-10-22 13:39:54 +08:00
|
|
|
pp_debug_tok = tok;
|
|
|
|
next_nomacro();
|
|
|
|
pp_debug_symv = tok;
|
|
|
|
parse_define();
|
2009-05-06 02:17:49 +08:00
|
|
|
break;
|
|
|
|
case TOK_UNDEF:
|
2021-10-22 13:39:54 +08:00
|
|
|
pp_debug_tok = tok;
|
|
|
|
next_nomacro();
|
|
|
|
pp_debug_symv = tok;
|
|
|
|
s = define_find(tok);
|
2009-05-06 02:17:49 +08:00
|
|
|
/* undefine symbol by putting an invalid name */
|
|
|
|
if (s)
|
2021-10-22 13:39:54 +08:00
|
|
|
define_undef(s);
|
2009-05-06 02:17:49 +08:00
|
|
|
break;
|
|
|
|
case TOK_INCLUDE:
|
|
|
|
case TOK_INCLUDE_NEXT:
|
2022-08-18 16:23:13 +08:00
|
|
|
parse_include(s1, tok - TOK_INCLUDE, 0);
|
2015-11-20 19:05:55 +08:00
|
|
|
break;
|
2009-05-06 02:17:49 +08:00
|
|
|
case TOK_IFNDEF:
|
|
|
|
c = 1;
|
|
|
|
goto do_ifdef;
|
|
|
|
case TOK_IF:
|
2022-08-14 18:17:31 +08:00
|
|
|
c = expr_preprocess(s1);
|
2009-05-06 02:17:49 +08:00
|
|
|
goto do_if;
|
|
|
|
case TOK_IFDEF:
|
|
|
|
c = 0;
|
|
|
|
do_ifdef:
|
2021-10-22 13:39:54 +08:00
|
|
|
next_nomacro();
|
|
|
|
if (tok < TOK_IDENT)
|
|
|
|
tcc_error("invalid argument for '#if%sdef'", c ? "n" : "");
|
2009-05-06 02:17:49 +08:00
|
|
|
if (is_bof) {
|
|
|
|
if (c) {
|
2015-11-20 19:05:55 +08:00
|
|
|
#ifdef INC_DEBUG
|
2021-10-22 13:39:54 +08:00
|
|
|
printf("#ifndef %s\n", get_tok_str(tok, NULL));
|
2015-11-20 19:05:55 +08:00
|
|
|
#endif
|
2021-10-22 13:39:54 +08:00
|
|
|
file->ifndef_macro = tok;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
}
|
2022-08-18 16:23:13 +08:00
|
|
|
if (define_find(tok)
|
|
|
|
|| tok == TOK___HAS_INCLUDE
|
|
|
|
|| tok == TOK___HAS_INCLUDE_NEXT)
|
|
|
|
c ^= 1;
|
2009-05-06 02:17:49 +08:00
|
|
|
do_if:
|
2021-10-22 13:39:54 +08:00
|
|
|
if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
|
|
|
|
tcc_error("memory full (ifdef)");
|
|
|
|
*s1->ifdef_stack_ptr++ = c;
|
2009-05-06 02:17:49 +08:00
|
|
|
goto test_skip;
|
|
|
|
case TOK_ELSE:
|
2021-10-22 13:39:54 +08:00
|
|
|
if (s1->ifdef_stack_ptr == s1->ifdef_stack)
|
|
|
|
tcc_error("#else without matching #if");
|
|
|
|
if (s1->ifdef_stack_ptr[-1] & 2)
|
|
|
|
tcc_error("#else after #else");
|
|
|
|
c = (s1->ifdef_stack_ptr[-1] ^= 3);
|
2009-07-24 01:21:14 +08:00
|
|
|
goto test_else;
|
2009-05-06 02:17:49 +08:00
|
|
|
case TOK_ELIF:
|
2021-10-22 13:39:54 +08:00
|
|
|
if (s1->ifdef_stack_ptr == s1->ifdef_stack)
|
|
|
|
tcc_error("#elif without matching #if");
|
|
|
|
c = s1->ifdef_stack_ptr[-1];
|
2009-05-06 02:17:49 +08:00
|
|
|
if (c > 1)
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("#elif after #else");
|
2009-05-06 02:17:49 +08:00
|
|
|
/* last #if/#elif expression was true: we skip */
|
2016-10-04 23:31:40 +08:00
|
|
|
if (c == 1) {
|
|
|
|
c = 0;
|
|
|
|
} else {
|
2022-08-14 18:17:31 +08:00
|
|
|
c = expr_preprocess(s1);
|
2021-10-22 13:39:54 +08:00
|
|
|
s1->ifdef_stack_ptr[-1] = c;
|
2016-10-04 23:31:40 +08:00
|
|
|
}
|
2009-07-24 01:21:14 +08:00
|
|
|
test_else:
|
2021-10-22 13:39:54 +08:00
|
|
|
if (s1->ifdef_stack_ptr == file->ifdef_stack_ptr + 1)
|
|
|
|
file->ifndef_macro = 0;
|
2009-05-06 02:17:49 +08:00
|
|
|
test_skip:
|
|
|
|
if (!(c & 1)) {
|
2021-10-22 13:39:54 +08:00
|
|
|
preprocess_skip();
|
2009-05-06 02:17:49 +08:00
|
|
|
is_bof = 0;
|
|
|
|
goto redo;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case TOK_ENDIF:
|
2021-10-22 13:39:54 +08:00
|
|
|
if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
|
|
|
|
tcc_error("#endif without matching #if");
|
|
|
|
s1->ifdef_stack_ptr--;
|
2009-05-06 02:17:49 +08:00
|
|
|
/* '#ifndef macro' was at the start of file. Now we check if
|
|
|
|
an '#endif' is exactly at the end of file */
|
2021-10-22 13:39:54 +08:00
|
|
|
if (file->ifndef_macro &&
|
|
|
|
s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
|
|
|
|
file->ifndef_macro_saved = file->ifndef_macro;
|
2009-05-06 02:17:49 +08:00
|
|
|
/* need to set to zero to avoid false matches if another
|
|
|
|
#ifndef at middle of file */
|
2021-10-22 13:39:54 +08:00
|
|
|
file->ifndef_macro = 0;
|
|
|
|
while (tok != TOK_LINEFEED)
|
|
|
|
next_nomacro();
|
|
|
|
tok_flags |= TOK_FLAG_ENDIF;
|
2009-05-06 02:17:49 +08:00
|
|
|
goto the_end;
|
|
|
|
}
|
|
|
|
break;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
case TOK_PPNUM:
|
2021-10-22 13:39:54 +08:00
|
|
|
n = strtoul((char*)tokc.str.data, &q, 10);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
goto _line_num;
|
2009-05-06 02:17:49 +08:00
|
|
|
case TOK_LINE:
|
2021-10-22 13:39:54 +08:00
|
|
|
next();
|
|
|
|
if (tok != TOK_CINT)
|
2016-10-04 23:31:40 +08:00
|
|
|
_line_err:
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("wrong #line format");
|
|
|
|
n = tokc.i;
|
2016-10-04 23:31:40 +08:00
|
|
|
_line_num:
|
2021-10-22 13:39:54 +08:00
|
|
|
next();
|
|
|
|
if (tok != TOK_LINEFEED) {
|
|
|
|
if (tok == TOK_STR) {
|
|
|
|
if (file->true_filename == file->filename)
|
|
|
|
file->true_filename = tcc_strdup(file->filename);
|
2022-05-08 05:16:13 +08:00
|
|
|
q = (char *)tokc.str.data;
|
|
|
|
buf[0] = 0;
|
|
|
|
if (!IS_ABSPATH(q)) {
|
|
|
|
/* prepend directory from real file */
|
|
|
|
pstrcpy(buf, sizeof buf, file->true_filename);
|
|
|
|
*tcc_basename(buf) = 0;
|
|
|
|
}
|
|
|
|
pstrcat(buf, sizeof buf, q);
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_debug_putfile(s1, buf);
|
|
|
|
} else if (parse_flags & PARSE_FLAG_ASM_FILE)
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
break;
|
|
|
|
else
|
|
|
|
goto _line_err;
|
|
|
|
--n;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
if (file->fd > 0)
|
|
|
|
total_lines += file->line_num - n;
|
|
|
|
file->line_num = n;
|
2009-05-06 02:17:49 +08:00
|
|
|
break;
|
|
|
|
case TOK_ERROR:
|
|
|
|
case TOK_WARNING:
|
|
|
|
q = buf;
|
2022-08-18 16:43:28 +08:00
|
|
|
c = skip_spaces();
|
|
|
|
while (c != '\n' && c != CH_EOF) {
|
2009-05-06 02:17:49 +08:00
|
|
|
if ((q - buf) < sizeof(buf) - 1)
|
2022-08-18 16:43:28 +08:00
|
|
|
*q++ = c;
|
|
|
|
c = ninp();
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
*q = '\0';
|
2022-08-18 16:43:28 +08:00
|
|
|
if (tok == TOK_ERROR)
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("#error %s", buf);
|
2009-05-06 02:17:49 +08:00
|
|
|
else
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_warning("#warning %s", buf);
|
2009-05-06 02:17:49 +08:00
|
|
|
break;
|
|
|
|
case TOK_PRAGMA:
|
2021-10-22 13:39:54 +08:00
|
|
|
pragma_parse(s1);
|
2009-05-06 02:17:49 +08:00
|
|
|
break;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
case TOK_LINEFEED:
|
|
|
|
goto the_end;
|
2009-05-06 02:17:49 +08:00
|
|
|
default:
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
/* ignore gas line comment in an 'S' file. */
|
|
|
|
if (saved_parse_flags & PARSE_FLAG_ASM_FILE)
|
|
|
|
goto ignore;
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok == '!' && is_bof)
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
/* '!' is ignored at beginning to allow C scripts. */
|
|
|
|
goto ignore;
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc));
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
ignore:
|
2021-10-22 13:39:54 +08:00
|
|
|
file->buf_ptr = parse_line_comment(file->buf_ptr - 1);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
goto the_end;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
/* ignore other preprocess commands or #! for C scripts */
|
2021-10-22 13:39:54 +08:00
|
|
|
while (tok != TOK_LINEFEED)
|
|
|
|
next_nomacro();
|
2009-05-06 02:17:49 +08:00
|
|
|
the_end:
|
2021-10-22 13:39:54 +08:00
|
|
|
parse_flags = saved_parse_flags;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* evaluate escape codes in a string. */
|
2021-10-22 13:39:54 +08:00
|
|
|
static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
2021-01-24 23:20:48 +08:00
|
|
|
int c, n, i;
|
2009-05-06 02:17:49 +08:00
|
|
|
const uint8_t *p;
|
|
|
|
|
|
|
|
p = buf;
|
|
|
|
for(;;) {
|
|
|
|
c = *p;
|
|
|
|
if (c == '\0')
|
|
|
|
break;
|
|
|
|
if (c == '\\') {
|
|
|
|
p++;
|
|
|
|
/* escape */
|
|
|
|
c = *p;
|
|
|
|
switch(c) {
|
|
|
|
case '0': case '1': case '2': case '3':
|
|
|
|
case '4': case '5': case '6': case '7':
|
|
|
|
/* at most three octal digits */
|
|
|
|
n = c - '0';
|
|
|
|
p++;
|
|
|
|
c = *p;
|
|
|
|
if (isoct(c)) {
|
|
|
|
n = n * 8 + c - '0';
|
|
|
|
p++;
|
|
|
|
c = *p;
|
|
|
|
if (isoct(c)) {
|
|
|
|
n = n * 8 + c - '0';
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
c = n;
|
|
|
|
goto add_char_nonext;
|
2021-01-24 23:20:48 +08:00
|
|
|
case 'x': i = 0; goto parse_hex_or_ucn;
|
|
|
|
case 'u': i = 4; goto parse_hex_or_ucn;
|
|
|
|
case 'U': i = 8; goto parse_hex_or_ucn;
|
|
|
|
parse_hex_or_ucn:
|
2009-05-06 02:17:49 +08:00
|
|
|
p++;
|
|
|
|
n = 0;
|
2021-01-24 23:20:48 +08:00
|
|
|
do {
|
2009-05-06 02:17:49 +08:00
|
|
|
c = *p;
|
|
|
|
if (c >= 'a' && c <= 'f')
|
|
|
|
c = c - 'a' + 10;
|
|
|
|
else if (c >= 'A' && c <= 'F')
|
|
|
|
c = c - 'A' + 10;
|
|
|
|
else if (isnum(c))
|
|
|
|
c = c - '0';
|
2021-01-24 23:20:48 +08:00
|
|
|
else if (i > 0)
|
2021-10-22 13:39:54 +08:00
|
|
|
expect("more hex digits in universal-character-name");
|
2022-08-11 14:37:00 +08:00
|
|
|
else
|
|
|
|
goto add_hex_or_ucn;
|
2009-05-06 02:17:49 +08:00
|
|
|
n = n * 16 + c;
|
|
|
|
p++;
|
2021-01-24 23:20:48 +08:00
|
|
|
} while (--i);
|
2022-08-11 14:37:00 +08:00
|
|
|
if (is_long) {
|
|
|
|
add_hex_or_ucn:
|
|
|
|
c = n;
|
|
|
|
goto add_char_nonext;
|
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_u8cat(outstr, n);
|
2021-01-18 05:21:07 +08:00
|
|
|
continue;
|
2009-05-06 02:17:49 +08:00
|
|
|
case 'a':
|
|
|
|
c = '\a';
|
|
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
c = '\b';
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
c = '\f';
|
|
|
|
break;
|
|
|
|
case 'n':
|
|
|
|
c = '\n';
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
c = '\r';
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
c = '\t';
|
|
|
|
break;
|
|
|
|
case 'v':
|
|
|
|
c = '\v';
|
|
|
|
break;
|
|
|
|
case 'e':
|
|
|
|
if (!gnu_ext)
|
|
|
|
goto invalid_escape;
|
|
|
|
c = 27;
|
|
|
|
break;
|
|
|
|
case '\'':
|
|
|
|
case '\"':
|
2015-07-30 04:53:57 +08:00
|
|
|
case '\\':
|
2009-05-06 02:17:49 +08:00
|
|
|
case '?':
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
invalid_escape:
|
|
|
|
if (c >= '!' && c <= '~')
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_warning("unknown escape sequence: \'\\%c\'", c);
|
2009-05-06 02:17:49 +08:00
|
|
|
else
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_warning("unknown escape sequence: \'\\x%x\'", c);
|
2009-05-06 02:17:49 +08:00
|
|
|
break;
|
|
|
|
}
|
2017-09-09 20:37:43 +08:00
|
|
|
} else if (is_long && c >= 0x80) {
|
|
|
|
/* assume we are processing UTF-8 sequence */
|
|
|
|
/* reference: The Unicode Standard, Version 10.0, ch3.9 */
|
|
|
|
|
|
|
|
int cont; /* count of continuation bytes */
|
2017-09-25 09:03:26 +08:00
|
|
|
int skip; /* how many bytes should skip when error occurred */
|
2017-09-09 20:37:43 +08:00
|
|
|
int i;
|
|
|
|
|
|
|
|
/* decode leading byte */
|
|
|
|
if (c < 0xC2) {
|
|
|
|
skip = 1; goto invalid_utf8_sequence;
|
|
|
|
} else if (c <= 0xDF) {
|
|
|
|
cont = 1; n = c & 0x1f;
|
|
|
|
} else if (c <= 0xEF) {
|
|
|
|
cont = 2; n = c & 0xf;
|
|
|
|
} else if (c <= 0xF4) {
|
|
|
|
cont = 3; n = c & 0x7;
|
|
|
|
} else {
|
|
|
|
skip = 1; goto invalid_utf8_sequence;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* decode continuation bytes */
|
|
|
|
for (i = 1; i <= cont; i++) {
|
|
|
|
int l = 0x80, h = 0xBF;
|
|
|
|
|
|
|
|
/* adjust limit for second byte */
|
|
|
|
if (i == 1) {
|
|
|
|
switch (c) {
|
|
|
|
case 0xE0: l = 0xA0; break;
|
|
|
|
case 0xED: h = 0x9F; break;
|
|
|
|
case 0xF0: l = 0x90; break;
|
|
|
|
case 0xF4: h = 0x8F; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (p[i] < l || p[i] > h) {
|
|
|
|
skip = i; goto invalid_utf8_sequence;
|
|
|
|
}
|
|
|
|
|
|
|
|
n = (n << 6) | (p[i] & 0x3f);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* advance pointer */
|
|
|
|
p += 1 + cont;
|
|
|
|
c = n;
|
|
|
|
goto add_char_nonext;
|
|
|
|
|
|
|
|
/* error handling */
|
|
|
|
invalid_utf8_sequence:
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_warning("ill-formed UTF-8 subsequence starting with: \'\\x%x\'", c);
|
2017-09-09 20:37:43 +08:00
|
|
|
c = 0xFFFD;
|
|
|
|
p += skip;
|
|
|
|
goto add_char_nonext;
|
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
p++;
|
|
|
|
add_char_nonext:
|
|
|
|
if (!is_long)
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_ccat(outstr, c);
|
2017-09-09 20:37:43 +08:00
|
|
|
else {
|
|
|
|
#ifdef TCC_TARGET_PE
|
|
|
|
/* store as UTF-16 */
|
|
|
|
if (c < 0x10000) {
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_wccat(outstr, c);
|
2017-09-09 20:37:43 +08:00
|
|
|
} else {
|
|
|
|
c -= 0x10000;
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_wccat(outstr, (c >> 10) + 0xD800);
|
|
|
|
cstr_wccat(outstr, (c & 0x3FF) + 0xDC00);
|
2017-09-09 20:37:43 +08:00
|
|
|
}
|
|
|
|
#else
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_wccat(outstr, c);
|
2017-09-09 20:37:43 +08:00
|
|
|
#endif
|
|
|
|
}
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
/* add a trailing '\0' */
|
|
|
|
if (!is_long)
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_ccat(outstr, '\0');
|
2009-05-06 02:17:49 +08:00
|
|
|
else
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_wccat(outstr, '\0');
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static void parse_string(const char *s, int len)
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
{
|
|
|
|
uint8_t buf[1000], *p = buf;
|
|
|
|
int is_long, sep;
|
|
|
|
|
|
|
|
if ((is_long = *s == 'L'))
|
|
|
|
++s, --len;
|
|
|
|
sep = *s++;
|
|
|
|
len -= 2;
|
|
|
|
if (len >= sizeof buf)
|
2021-10-22 13:39:54 +08:00
|
|
|
p = tcc_malloc(len + 1);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
memcpy(p, s, len);
|
|
|
|
p[len] = 0;
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_reset(&tokcstr);
|
|
|
|
parse_escape_string(&tokcstr, p, is_long);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
if (p != buf)
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_free(p);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
|
|
|
if (sep == '\'') {
|
2017-09-25 00:57:48 +08:00
|
|
|
int char_size, i, n, c;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
/* XXX: make it portable */
|
|
|
|
if (!is_long)
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_CCHAR, char_size = 1;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
else
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_LCHAR, char_size = sizeof(nwchar_t);
|
|
|
|
n = tokcstr.size / char_size - 1;
|
2017-09-25 00:57:48 +08:00
|
|
|
if (n < 1)
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("empty character constant");
|
2017-09-25 00:57:48 +08:00
|
|
|
if (n > 1)
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_warning_c(warn_all)("multi-character character constant");
|
2017-09-25 00:57:48 +08:00
|
|
|
for (c = i = 0; i < n; ++i) {
|
|
|
|
if (is_long)
|
2021-10-22 13:39:54 +08:00
|
|
|
c = ((nwchar_t *)tokcstr.data)[i];
|
2017-09-25 00:57:48 +08:00
|
|
|
else
|
2021-10-22 13:39:54 +08:00
|
|
|
c = (c << 8) | ((char *)tokcstr.data)[i];
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
tokc.i = c;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
tokc.str.size = tokcstr.size;
|
|
|
|
tokc.str.data = tokcstr.data;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
if (!is_long)
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_STR;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
else
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_LSTR;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
/* we use 64 bit numbers */
|
|
|
|
#define BN_SIZE 2
|
|
|
|
|
|
|
|
/* bn = (bn << shift) | or_val */
|
2009-12-20 08:53:49 +08:00
|
|
|
static void bn_lshift(unsigned int *bn, int shift, int or_val)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
unsigned int v;
|
|
|
|
for(i=0;i<BN_SIZE;i++) {
|
|
|
|
v = bn[i];
|
|
|
|
bn[i] = (v << shift) | or_val;
|
|
|
|
or_val = v >> (32 - shift);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-20 08:53:49 +08:00
|
|
|
static void bn_zero(unsigned int *bn)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for(i=0;i<BN_SIZE;i++) {
|
|
|
|
bn[i] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* parse number in null terminated string 'p' and return it in the
|
|
|
|
current token */
|
2021-10-22 13:39:54 +08:00
|
|
|
static void parse_number(const char *p)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
|
|
|
int b, t, shift, frac_bits, s, exp_val, ch;
|
|
|
|
char *q;
|
|
|
|
unsigned int bn[BN_SIZE];
|
|
|
|
double d;
|
|
|
|
|
|
|
|
/* number */
|
2021-10-22 13:39:54 +08:00
|
|
|
q = token_buf;
|
2009-05-06 02:17:49 +08:00
|
|
|
ch = *p++;
|
|
|
|
t = ch;
|
|
|
|
ch = *p++;
|
|
|
|
*q++ = t;
|
|
|
|
b = 10;
|
|
|
|
if (t == '.') {
|
|
|
|
goto float_frac_parse;
|
|
|
|
} else if (t == '0') {
|
|
|
|
if (ch == 'x' || ch == 'X') {
|
|
|
|
q--;
|
|
|
|
ch = *p++;
|
|
|
|
b = 16;
|
2021-10-22 13:39:54 +08:00
|
|
|
} else if (tcc_state->tcc_ext && (ch == 'b' || ch == 'B')) {
|
2009-05-06 02:17:49 +08:00
|
|
|
q--;
|
|
|
|
ch = *p++;
|
|
|
|
b = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* parse all digits. cannot check octal numbers at this stage
|
|
|
|
because of floating point constants */
|
|
|
|
while (1) {
|
|
|
|
if (ch >= 'a' && ch <= 'f')
|
|
|
|
t = ch - 'a' + 10;
|
|
|
|
else if (ch >= 'A' && ch <= 'F')
|
|
|
|
t = ch - 'A' + 10;
|
|
|
|
else if (isnum(ch))
|
|
|
|
t = ch - '0';
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
if (t >= b)
|
|
|
|
break;
|
2021-10-22 13:39:54 +08:00
|
|
|
if (q >= token_buf + STRING_MAX_SIZE) {
|
2009-05-06 02:17:49 +08:00
|
|
|
num_too_long:
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("number too long");
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
*q++ = ch;
|
|
|
|
ch = *p++;
|
|
|
|
}
|
|
|
|
if (ch == '.' ||
|
|
|
|
((ch == 'e' || ch == 'E') && b == 10) ||
|
|
|
|
((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
|
|
|
|
if (b != 10) {
|
|
|
|
/* NOTE: strtox should support that for hexa numbers, but
|
|
|
|
non ISOC99 libcs do not support it, so we prefer to do
|
|
|
|
it by hand */
|
|
|
|
/* hexadecimal or binary floats */
|
|
|
|
/* XXX: handle overflows */
|
|
|
|
*q = '\0';
|
|
|
|
if (b == 16)
|
|
|
|
shift = 4;
|
2015-07-30 04:53:57 +08:00
|
|
|
else
|
2014-12-15 16:32:08 +08:00
|
|
|
shift = 1;
|
2009-05-06 02:17:49 +08:00
|
|
|
bn_zero(bn);
|
2021-10-22 13:39:54 +08:00
|
|
|
q = token_buf;
|
2009-05-06 02:17:49 +08:00
|
|
|
while (1) {
|
|
|
|
t = *q++;
|
|
|
|
if (t == '\0') {
|
|
|
|
break;
|
|
|
|
} else if (t >= 'a') {
|
|
|
|
t = t - 'a' + 10;
|
|
|
|
} else if (t >= 'A') {
|
|
|
|
t = t - 'A' + 10;
|
|
|
|
} else {
|
|
|
|
t = t - '0';
|
|
|
|
}
|
|
|
|
bn_lshift(bn, shift, t);
|
|
|
|
}
|
|
|
|
frac_bits = 0;
|
|
|
|
if (ch == '.') {
|
|
|
|
ch = *p++;
|
|
|
|
while (1) {
|
|
|
|
t = ch;
|
|
|
|
if (t >= 'a' && t <= 'f') {
|
|
|
|
t = t - 'a' + 10;
|
|
|
|
} else if (t >= 'A' && t <= 'F') {
|
|
|
|
t = t - 'A' + 10;
|
|
|
|
} else if (t >= '0' && t <= '9') {
|
|
|
|
t = t - '0';
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (t >= b)
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("invalid digit");
|
2009-05-06 02:17:49 +08:00
|
|
|
bn_lshift(bn, shift, t);
|
|
|
|
frac_bits += shift;
|
|
|
|
ch = *p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ch != 'p' && ch != 'P')
|
2021-10-22 13:39:54 +08:00
|
|
|
expect("exponent");
|
2009-05-06 02:17:49 +08:00
|
|
|
ch = *p++;
|
|
|
|
s = 1;
|
|
|
|
exp_val = 0;
|
|
|
|
if (ch == '+') {
|
|
|
|
ch = *p++;
|
|
|
|
} else if (ch == '-') {
|
|
|
|
s = -1;
|
|
|
|
ch = *p++;
|
|
|
|
}
|
|
|
|
if (ch < '0' || ch > '9')
|
2021-10-22 13:39:54 +08:00
|
|
|
expect("exponent digits");
|
2009-05-06 02:17:49 +08:00
|
|
|
while (ch >= '0' && ch <= '9') {
|
|
|
|
exp_val = exp_val * 10 + ch - '0';
|
|
|
|
ch = *p++;
|
|
|
|
}
|
|
|
|
exp_val = exp_val * s;
|
2015-07-30 04:53:57 +08:00
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
/* now we can generate the number */
|
|
|
|
/* XXX: should patch directly float number */
|
|
|
|
d = (double)bn[1] * 4294967296.0 + (double)bn[0];
|
|
|
|
d = ldexp(d, exp_val - frac_bits);
|
|
|
|
t = toup(ch);
|
|
|
|
if (t == 'F') {
|
|
|
|
ch = *p++;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_CFLOAT;
|
2009-05-06 02:17:49 +08:00
|
|
|
/* float : should handle overflow */
|
2021-10-22 13:39:54 +08:00
|
|
|
tokc.f = (float)d;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else if (t == 'L') {
|
|
|
|
ch = *p++;
|
2023-04-25 14:59:42 +08:00
|
|
|
tok = TOK_CLDOUBLE;
|
2021-07-26 02:39:11 +08:00
|
|
|
#ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
|
2021-10-22 13:39:54 +08:00
|
|
|
tokc.d = d;
|
2009-07-19 04:07:17 +08:00
|
|
|
#else
|
2009-05-06 02:17:49 +08:00
|
|
|
/* XXX: not large enough */
|
2021-10-22 13:39:54 +08:00
|
|
|
tokc.ld = (long double)d;
|
2009-07-19 04:07:17 +08:00
|
|
|
#endif
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_CDOUBLE;
|
|
|
|
tokc.d = d;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* decimal floats */
|
|
|
|
if (ch == '.') {
|
2021-10-22 13:39:54 +08:00
|
|
|
if (q >= token_buf + STRING_MAX_SIZE)
|
2009-05-06 02:17:49 +08:00
|
|
|
goto num_too_long;
|
|
|
|
*q++ = ch;
|
|
|
|
ch = *p++;
|
|
|
|
float_frac_parse:
|
|
|
|
while (ch >= '0' && ch <= '9') {
|
2021-10-22 13:39:54 +08:00
|
|
|
if (q >= token_buf + STRING_MAX_SIZE)
|
2009-05-06 02:17:49 +08:00
|
|
|
goto num_too_long;
|
|
|
|
*q++ = ch;
|
|
|
|
ch = *p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ch == 'e' || ch == 'E') {
|
2021-10-22 13:39:54 +08:00
|
|
|
if (q >= token_buf + STRING_MAX_SIZE)
|
2009-05-06 02:17:49 +08:00
|
|
|
goto num_too_long;
|
|
|
|
*q++ = ch;
|
|
|
|
ch = *p++;
|
|
|
|
if (ch == '-' || ch == '+') {
|
2021-10-22 13:39:54 +08:00
|
|
|
if (q >= token_buf + STRING_MAX_SIZE)
|
2009-05-06 02:17:49 +08:00
|
|
|
goto num_too_long;
|
|
|
|
*q++ = ch;
|
|
|
|
ch = *p++;
|
|
|
|
}
|
|
|
|
if (ch < '0' || ch > '9')
|
2021-10-22 13:39:54 +08:00
|
|
|
expect("exponent digits");
|
2009-05-06 02:17:49 +08:00
|
|
|
while (ch >= '0' && ch <= '9') {
|
2021-10-22 13:39:54 +08:00
|
|
|
if (q >= token_buf + STRING_MAX_SIZE)
|
2009-05-06 02:17:49 +08:00
|
|
|
goto num_too_long;
|
|
|
|
*q++ = ch;
|
|
|
|
ch = *p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*q = '\0';
|
|
|
|
t = toup(ch);
|
|
|
|
errno = 0;
|
|
|
|
if (t == 'F') {
|
|
|
|
ch = *p++;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_CFLOAT;
|
|
|
|
tokc.f = strtof(token_buf, NULL);
|
2009-05-06 02:17:49 +08:00
|
|
|
} else if (t == 'L') {
|
|
|
|
ch = *p++;
|
2023-04-25 14:59:42 +08:00
|
|
|
tok = TOK_CLDOUBLE;
|
2021-07-26 02:39:11 +08:00
|
|
|
#ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
|
2021-10-22 13:39:54 +08:00
|
|
|
tokc.d = strtod(token_buf, NULL);
|
2009-07-19 04:07:17 +08:00
|
|
|
#else
|
2021-10-22 13:39:54 +08:00
|
|
|
tokc.ld = strtold(token_buf, NULL);
|
2009-07-19 04:07:17 +08:00
|
|
|
#endif
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_CDOUBLE;
|
|
|
|
tokc.d = strtod(token_buf, NULL);
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
unsigned long long n, n1;
|
2017-09-25 00:57:48 +08:00
|
|
|
int lcount, ucount, ov = 0;
|
2015-02-18 12:22:25 +08:00
|
|
|
const char *p1;
|
2009-05-06 02:17:49 +08:00
|
|
|
|
|
|
|
/* integer number */
|
|
|
|
*q = '\0';
|
2021-10-22 13:39:54 +08:00
|
|
|
q = token_buf;
|
2009-05-06 02:17:49 +08:00
|
|
|
if (b == 10 && *q == '0') {
|
|
|
|
b = 8;
|
|
|
|
q++;
|
|
|
|
}
|
|
|
|
n = 0;
|
|
|
|
while(1) {
|
|
|
|
t = *q++;
|
|
|
|
/* no need for checks except for base 10 / 8 errors */
|
2015-02-18 12:22:25 +08:00
|
|
|
if (t == '\0')
|
2009-05-06 02:17:49 +08:00
|
|
|
break;
|
2015-02-18 12:22:25 +08:00
|
|
|
else if (t >= 'a')
|
2009-05-06 02:17:49 +08:00
|
|
|
t = t - 'a' + 10;
|
2015-02-18 12:22:25 +08:00
|
|
|
else if (t >= 'A')
|
2009-05-06 02:17:49 +08:00
|
|
|
t = t - 'A' + 10;
|
2015-02-18 12:22:25 +08:00
|
|
|
else
|
2009-05-06 02:17:49 +08:00
|
|
|
t = t - '0';
|
2015-02-18 12:22:25 +08:00
|
|
|
if (t >= b)
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("invalid digit");
|
2009-05-06 02:17:49 +08:00
|
|
|
n1 = n;
|
|
|
|
n = n * b + t;
|
|
|
|
/* detect overflow */
|
2017-09-25 00:57:48 +08:00
|
|
|
if (n1 >= 0x1000000000000000ULL && n / b != n1)
|
|
|
|
ov = 1;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2015-02-18 12:22:25 +08:00
|
|
|
|
|
|
|
/* Determine the characteristics (unsigned and/or 64bit) the type of
|
|
|
|
the constant must have according to the constant suffix(es) */
|
2017-09-25 00:57:48 +08:00
|
|
|
lcount = ucount = 0;
|
2015-02-18 12:22:25 +08:00
|
|
|
p1 = p;
|
2009-05-06 02:17:49 +08:00
|
|
|
for(;;) {
|
|
|
|
t = toup(ch);
|
|
|
|
if (t == 'L') {
|
|
|
|
if (lcount >= 2)
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("three 'l's in integer constant");
|
2015-02-18 12:22:25 +08:00
|
|
|
if (lcount && *(p - 1) != ch)
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("incorrect integer suffix: %s", p1);
|
2009-05-06 02:17:49 +08:00
|
|
|
lcount++;
|
|
|
|
ch = *p++;
|
|
|
|
} else if (t == 'U') {
|
|
|
|
if (ucount >= 1)
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("two 'u's in integer constant");
|
2009-05-06 02:17:49 +08:00
|
|
|
ucount++;
|
|
|
|
ch = *p++;
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2015-02-18 12:22:25 +08:00
|
|
|
|
2017-09-25 00:57:48 +08:00
|
|
|
/* Determine if it needs 64 bits and/or unsigned in order to fit */
|
|
|
|
if (ucount == 0 && b == 10) {
|
|
|
|
if (lcount <= (LONG_SIZE == 4)) {
|
|
|
|
if (n >= 0x80000000U)
|
|
|
|
lcount = (LONG_SIZE == 4) + 1;
|
|
|
|
}
|
|
|
|
if (n >= 0x8000000000000000ULL)
|
|
|
|
ov = 1, ucount = 1;
|
|
|
|
} else {
|
|
|
|
if (lcount <= (LONG_SIZE == 4)) {
|
|
|
|
if (n >= 0x100000000ULL)
|
|
|
|
lcount = (LONG_SIZE == 4) + 1;
|
|
|
|
else if (n >= 0x80000000U)
|
|
|
|
ucount = 1;
|
|
|
|
}
|
|
|
|
if (n >= 0x8000000000000000ULL)
|
|
|
|
ucount = 1;
|
2015-02-18 12:22:25 +08:00
|
|
|
}
|
|
|
|
|
2017-09-25 00:57:48 +08:00
|
|
|
if (ov)
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_warning("integer constant overflow");
|
2015-02-18 12:22:25 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_CINT;
|
2017-09-25 00:57:48 +08:00
|
|
|
if (lcount) {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_CLONG;
|
2017-09-25 00:57:48 +08:00
|
|
|
if (lcount == 2)
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_CLLONG;
|
2017-09-25 00:57:48 +08:00
|
|
|
}
|
|
|
|
if (ucount)
|
2021-10-22 13:39:54 +08:00
|
|
|
++tok; /* TOK_CU... */
|
|
|
|
tokc.i = n;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
if (ch)
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("invalid number");
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define PARSE2(c1, tok1, c2, tok2) \
|
|
|
|
case c1: \
|
|
|
|
PEEKC(c, p); \
|
|
|
|
if (c == c2) { \
|
|
|
|
p++; \
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = tok2; \
|
2009-05-06 02:17:49 +08:00
|
|
|
} else { \
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = tok1; \
|
2009-05-06 02:17:49 +08:00
|
|
|
} \
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* return next token without macro substitution */
|
2021-10-22 13:39:54 +08:00
|
|
|
static inline void next_nomacro1(void)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
2016-04-17 21:37:23 +08:00
|
|
|
int t, c, is_long, len;
|
2009-05-06 02:17:49 +08:00
|
|
|
TokenSym *ts;
|
|
|
|
uint8_t *p, *p1;
|
|
|
|
unsigned int h;
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
p = file->buf_ptr;
|
2009-05-06 02:17:49 +08:00
|
|
|
redo_no_start:
|
|
|
|
c = *p;
|
|
|
|
switch(c) {
|
|
|
|
case ' ':
|
|
|
|
case '\t':
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = c;
|
2009-05-06 02:17:49 +08:00
|
|
|
p++;
|
2020-06-18 00:08:09 +08:00
|
|
|
maybe_space:
|
2021-10-22 13:39:54 +08:00
|
|
|
if (parse_flags & PARSE_FLAG_SPACES)
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
goto keep_tok_flags;
|
2021-10-22 13:39:54 +08:00
|
|
|
while (isidnum_table[*p - CH_EOF] & IS_SPC)
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
++p;
|
|
|
|
goto redo_no_start;
|
2009-05-06 02:17:49 +08:00
|
|
|
case '\f':
|
|
|
|
case '\v':
|
|
|
|
case '\r':
|
|
|
|
p++;
|
|
|
|
goto redo_no_start;
|
|
|
|
case '\\':
|
|
|
|
/* first look if it is in fact an end of buffer */
|
2022-08-18 16:43:28 +08:00
|
|
|
c = handle_stray(&p);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
if (c == '\\')
|
|
|
|
goto parse_simple;
|
2022-08-18 16:43:28 +08:00
|
|
|
if (c == CH_EOF) {
|
2021-10-22 13:39:54 +08:00
|
|
|
TCCState *s1 = tcc_state;
|
|
|
|
if ((parse_flags & PARSE_FLAG_LINEFEED)
|
|
|
|
&& !(tok_flags & TOK_FLAG_EOF)) {
|
|
|
|
tok_flags |= TOK_FLAG_EOF;
|
|
|
|
tok = TOK_LINEFEED;
|
2009-05-06 02:17:49 +08:00
|
|
|
goto keep_tok_flags;
|
2021-10-22 13:39:54 +08:00
|
|
|
} else if (!(parse_flags & PARSE_FLAG_PREPROCESS)) {
|
|
|
|
tok = TOK_EOF;
|
|
|
|
} else if (s1->ifdef_stack_ptr != file->ifdef_stack_ptr) {
|
|
|
|
tcc_error("missing #endif");
|
|
|
|
} else if (s1->include_stack_ptr == s1->include_stack) {
|
2009-05-06 02:17:49 +08:00
|
|
|
/* no include left : end of file. */
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_EOF;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_flags &= ~TOK_FLAG_EOF;
|
2009-05-06 02:17:49 +08:00
|
|
|
/* pop include file */
|
2015-07-30 04:53:57 +08:00
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
/* test if previous '#endif' was after a #ifdef at
|
|
|
|
start of file */
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok_flags & TOK_FLAG_ENDIF) {
|
2009-05-06 02:17:49 +08:00
|
|
|
#ifdef INC_DEBUG
|
2021-10-22 13:39:54 +08:00
|
|
|
printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
|
2009-05-06 02:17:49 +08:00
|
|
|
#endif
|
2021-10-22 13:39:54 +08:00
|
|
|
search_cached_include(s1, file->filename, 1)
|
|
|
|
->ifndef_macro = file->ifndef_macro_saved;
|
|
|
|
tok_flags &= ~TOK_FLAG_ENDIF;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* add end of include file debug info */
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_debug_eincl(tcc_state);
|
2009-05-06 02:17:49 +08:00
|
|
|
/* pop include stack */
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_close();
|
|
|
|
s1->include_stack_ptr--;
|
|
|
|
p = file->buf_ptr;
|
|
|
|
if (p == file->buffer)
|
2022-09-12 17:37:47 +08:00
|
|
|
tok_flags = TOK_FLAG_BOF;
|
|
|
|
tok_flags |= TOK_FLAG_BOL;
|
2009-05-06 02:17:49 +08:00
|
|
|
goto redo_no_start;
|
|
|
|
}
|
2022-08-18 16:43:28 +08:00
|
|
|
} else {
|
|
|
|
goto redo_no_start;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '\n':
|
2021-10-22 13:39:54 +08:00
|
|
|
file->line_num++;
|
|
|
|
tok_flags |= TOK_FLAG_BOL;
|
2009-05-06 02:17:49 +08:00
|
|
|
p++;
|
2009-07-07 03:12:45 +08:00
|
|
|
maybe_newline:
|
2021-10-22 13:39:54 +08:00
|
|
|
if (0 == (parse_flags & PARSE_FLAG_LINEFEED))
|
2009-05-06 02:17:49 +08:00
|
|
|
goto redo_no_start;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_LINEFEED;
|
2009-05-06 02:17:49 +08:00
|
|
|
goto keep_tok_flags;
|
|
|
|
|
|
|
|
case '#':
|
|
|
|
/* XXX: simplify */
|
|
|
|
PEEKC(c, p);
|
2021-10-22 13:39:54 +08:00
|
|
|
if ((tok_flags & TOK_FLAG_BOL) &&
|
|
|
|
(parse_flags & PARSE_FLAG_PREPROCESS)) {
|
|
|
|
file->buf_ptr = p;
|
|
|
|
preprocess(tok_flags & TOK_FLAG_BOF);
|
|
|
|
p = file->buf_ptr;
|
2009-07-07 03:12:45 +08:00
|
|
|
goto maybe_newline;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
|
|
|
if (c == '#') {
|
|
|
|
p++;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_TWOSHARPS;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
2020-12-26 23:29:41 +08:00
|
|
|
#if !defined(TCC_TARGET_ARM)
|
2021-10-22 13:39:54 +08:00
|
|
|
if (parse_flags & PARSE_FLAG_ASM_FILE) {
|
|
|
|
p = parse_line_comment(p - 1);
|
2009-05-06 02:17:49 +08:00
|
|
|
goto redo_no_start;
|
2020-12-26 23:29:41 +08:00
|
|
|
} else
|
|
|
|
#endif
|
|
|
|
{
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = '#';
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2015-07-30 04:53:57 +08:00
|
|
|
|
2015-04-20 08:44:08 +08:00
|
|
|
/* dollar is allowed to start identifiers when not parsing asm */
|
|
|
|
case '$':
|
2021-10-22 13:39:54 +08:00
|
|
|
if (!(isidnum_table[c - CH_EOF] & IS_ID)
|
|
|
|
|| (parse_flags & PARSE_FLAG_ASM_FILE))
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
goto parse_simple;
|
2015-04-20 08:44:08 +08:00
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
case 'a': case 'b': case 'c': case 'd':
|
|
|
|
case 'e': case 'f': case 'g': case 'h':
|
|
|
|
case 'i': case 'j': case 'k': case 'l':
|
|
|
|
case 'm': case 'n': case 'o': case 'p':
|
|
|
|
case 'q': case 'r': case 's': case 't':
|
|
|
|
case 'u': case 'v': case 'w': case 'x':
|
2015-07-30 04:53:57 +08:00
|
|
|
case 'y': case 'z':
|
2009-05-06 02:17:49 +08:00
|
|
|
case 'A': case 'B': case 'C': case 'D':
|
|
|
|
case 'E': case 'F': case 'G': case 'H':
|
2015-07-30 04:53:57 +08:00
|
|
|
case 'I': case 'J': case 'K':
|
2009-05-06 02:17:49 +08:00
|
|
|
case 'M': case 'N': case 'O': case 'P':
|
|
|
|
case 'Q': case 'R': case 'S': case 'T':
|
|
|
|
case 'U': case 'V': case 'W': case 'X':
|
2015-07-30 04:53:57 +08:00
|
|
|
case 'Y': case 'Z':
|
2009-05-06 02:17:49 +08:00
|
|
|
case '_':
|
|
|
|
parse_ident_fast:
|
|
|
|
p1 = p;
|
|
|
|
h = TOK_HASH_INIT;
|
|
|
|
h = TOK_HASH_FUNC(h, c);
|
2021-10-22 13:39:54 +08:00
|
|
|
while (c = *++p, isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
|
2009-05-06 02:17:49 +08:00
|
|
|
h = TOK_HASH_FUNC(h, c);
|
2016-04-17 21:37:23 +08:00
|
|
|
len = p - p1;
|
2009-05-06 02:17:49 +08:00
|
|
|
if (c != '\\') {
|
|
|
|
TokenSym **pts;
|
|
|
|
|
|
|
|
/* fast case : no stray found, so we have the full token
|
|
|
|
and we have already hashed it */
|
|
|
|
h &= (TOK_HASH_SIZE - 1);
|
2021-10-22 13:39:54 +08:00
|
|
|
pts = &hash_ident[h];
|
2009-05-06 02:17:49 +08:00
|
|
|
for(;;) {
|
|
|
|
ts = *pts;
|
|
|
|
if (!ts)
|
|
|
|
break;
|
|
|
|
if (ts->len == len && !memcmp(ts->str, p1, len))
|
|
|
|
goto token_found;
|
|
|
|
pts = &(ts->hash_next);
|
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
ts = tok_alloc_new(pts, (char *) p1, len);
|
2009-05-06 02:17:49 +08:00
|
|
|
token_found: ;
|
|
|
|
} else {
|
|
|
|
/* slower case */
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_reset(&tokcstr);
|
|
|
|
cstr_cat(&tokcstr, (char *) p1, len);
|
2009-05-06 02:17:49 +08:00
|
|
|
p--;
|
|
|
|
PEEKC(c, p);
|
|
|
|
parse_ident_slow:
|
2021-10-22 13:39:54 +08:00
|
|
|
while (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
|
2016-04-13 15:23:46 +08:00
|
|
|
{
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_ccat(&tokcstr, c);
|
2009-05-06 02:17:49 +08:00
|
|
|
PEEKC(c, p);
|
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
ts = tok_alloc(tokcstr.data, tokcstr.size);
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = ts->tok;
|
2009-05-06 02:17:49 +08:00
|
|
|
break;
|
|
|
|
case 'L':
|
|
|
|
t = p[1];
|
|
|
|
if (t != '\\' && t != '\'' && t != '\"') {
|
|
|
|
/* fast case */
|
|
|
|
goto parse_ident_fast;
|
|
|
|
} else {
|
|
|
|
PEEKC(c, p);
|
|
|
|
if (c == '\'' || c == '\"') {
|
|
|
|
is_long = 1;
|
|
|
|
goto str_const;
|
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_reset(&tokcstr);
|
|
|
|
cstr_ccat(&tokcstr, 'L');
|
2009-05-06 02:17:49 +08:00
|
|
|
goto parse_ident_slow;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2016-05-05 03:27:39 +08:00
|
|
|
case '0': case '1': case '2': case '3':
|
2009-05-06 02:17:49 +08:00
|
|
|
case '4': case '5': case '6': case '7':
|
|
|
|
case '8': case '9':
|
2016-10-02 03:58:02 +08:00
|
|
|
t = c;
|
|
|
|
PEEKC(c, p);
|
2016-05-05 03:27:39 +08:00
|
|
|
/* after the first digit, accept digits, alpha, '.' or sign if
|
|
|
|
prefixed by 'eEpP' */
|
2009-05-06 02:17:49 +08:00
|
|
|
parse_num:
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_reset(&tokcstr);
|
2009-05-06 02:17:49 +08:00
|
|
|
for(;;) {
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_ccat(&tokcstr, t);
|
|
|
|
if (!((isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
|
2016-05-05 03:27:39 +08:00
|
|
|
|| c == '.'
|
|
|
|
|| ((c == '+' || c == '-')
|
2016-10-02 03:58:02 +08:00
|
|
|
&& (((t == 'e' || t == 'E')
|
2021-10-22 13:39:54 +08:00
|
|
|
&& !(parse_flags & PARSE_FLAG_ASM_FILE
|
2016-10-02 03:58:02 +08:00
|
|
|
/* 0xe+1 is 3 tokens in asm */
|
2021-10-22 13:39:54 +08:00
|
|
|
&& ((char*)tokcstr.data)[0] == '0'
|
|
|
|
&& toup(((char*)tokcstr.data)[1]) == 'X'))
|
2016-10-02 03:58:02 +08:00
|
|
|
|| t == 'p' || t == 'P'))))
|
2016-05-05 03:27:39 +08:00
|
|
|
break;
|
2016-10-02 03:58:02 +08:00
|
|
|
t = c;
|
|
|
|
PEEKC(c, p);
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
/* We add a trailing '\0' to ease parsing */
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_ccat(&tokcstr, '\0');
|
|
|
|
tokc.str.size = tokcstr.size;
|
|
|
|
tokc.str.data = tokcstr.data;
|
|
|
|
tok = TOK_PPNUM;
|
2009-05-06 02:17:49 +08:00
|
|
|
break;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
case '.':
|
|
|
|
/* special dot handling because it can also start a number */
|
|
|
|
PEEKC(c, p);
|
|
|
|
if (isnum(c)) {
|
2016-10-02 03:58:02 +08:00
|
|
|
t = '.';
|
2009-05-06 02:17:49 +08:00
|
|
|
goto parse_num;
|
2021-10-22 13:39:54 +08:00
|
|
|
} else if ((isidnum_table['.' - CH_EOF] & IS_ID)
|
|
|
|
&& (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))) {
|
2016-03-15 00:14:52 +08:00
|
|
|
*--p = c = '.';
|
|
|
|
goto parse_ident_fast;
|
2016-03-24 22:58:32 +08:00
|
|
|
} else if (c == '.') {
|
|
|
|
PEEKC(c, p);
|
|
|
|
if (c == '.') {
|
|
|
|
p++;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_DOTS;
|
2016-03-24 22:58:32 +08:00
|
|
|
} else {
|
|
|
|
*--p = '.'; /* may underflow into file->unget[] */
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = '.';
|
2016-03-24 22:58:32 +08:00
|
|
|
}
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = '.';
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '\'':
|
|
|
|
case '\"':
|
|
|
|
is_long = 0;
|
|
|
|
str_const:
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_reset(&tokcstr);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
if (is_long)
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_ccat(&tokcstr, 'L');
|
|
|
|
cstr_ccat(&tokcstr, c);
|
|
|
|
p = parse_pp_string(p, c, &tokcstr);
|
|
|
|
cstr_ccat(&tokcstr, c);
|
|
|
|
cstr_ccat(&tokcstr, '\0');
|
|
|
|
tokc.str.size = tokcstr.size;
|
|
|
|
tokc.str.data = tokcstr.data;
|
|
|
|
tok = TOK_PPSTR;
|
2009-05-06 02:17:49 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case '<':
|
|
|
|
PEEKC(c, p);
|
|
|
|
if (c == '=') {
|
|
|
|
p++;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_LE;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else if (c == '<') {
|
|
|
|
PEEKC(c, p);
|
|
|
|
if (c == '=') {
|
|
|
|
p++;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_A_SHL;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_SHL;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_LT;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '>':
|
|
|
|
PEEKC(c, p);
|
|
|
|
if (c == '=') {
|
|
|
|
p++;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_GE;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else if (c == '>') {
|
|
|
|
PEEKC(c, p);
|
|
|
|
if (c == '=') {
|
|
|
|
p++;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_A_SAR;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_SAR;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_GT;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
break;
|
2015-07-30 04:53:57 +08:00
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
case '&':
|
|
|
|
PEEKC(c, p);
|
|
|
|
if (c == '&') {
|
|
|
|
p++;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_LAND;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else if (c == '=') {
|
|
|
|
p++;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_A_AND;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = '&';
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
break;
|
2015-07-30 04:53:57 +08:00
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
case '|':
|
|
|
|
PEEKC(c, p);
|
|
|
|
if (c == '|') {
|
|
|
|
p++;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_LOR;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else if (c == '=') {
|
|
|
|
p++;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_A_OR;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = '|';
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '+':
|
|
|
|
PEEKC(c, p);
|
|
|
|
if (c == '+') {
|
|
|
|
p++;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_INC;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else if (c == '=') {
|
|
|
|
p++;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_A_ADD;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = '+';
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
break;
|
2015-07-30 04:53:57 +08:00
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
case '-':
|
|
|
|
PEEKC(c, p);
|
|
|
|
if (c == '-') {
|
|
|
|
p++;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_DEC;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else if (c == '=') {
|
|
|
|
p++;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_A_SUB;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else if (c == '>') {
|
|
|
|
p++;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_ARROW;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = '-';
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
PARSE2('!', '!', '=', TOK_NE)
|
|
|
|
PARSE2('=', '=', '=', TOK_EQ)
|
|
|
|
PARSE2('*', '*', '=', TOK_A_MUL)
|
|
|
|
PARSE2('%', '%', '=', TOK_A_MOD)
|
|
|
|
PARSE2('^', '^', '=', TOK_A_XOR)
|
2015-07-30 04:53:57 +08:00
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
/* comments or operator */
|
|
|
|
case '/':
|
|
|
|
PEEKC(c, p);
|
|
|
|
if (c == '*') {
|
2021-10-22 13:39:54 +08:00
|
|
|
p = parse_comment(p);
|
2011-03-01 09:19:43 +08:00
|
|
|
/* comments replaced by a blank */
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = ' ';
|
2020-06-18 00:08:09 +08:00
|
|
|
goto maybe_space;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else if (c == '/') {
|
2021-10-22 13:39:54 +08:00
|
|
|
p = parse_line_comment(p);
|
|
|
|
tok = ' ';
|
2020-06-18 00:08:09 +08:00
|
|
|
goto maybe_space;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else if (c == '=') {
|
|
|
|
p++;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = TOK_A_DIV;
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = '/';
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
break;
|
2015-07-30 04:53:57 +08:00
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
/* simple tokens */
|
|
|
|
case '(':
|
|
|
|
case ')':
|
|
|
|
case '[':
|
|
|
|
case ']':
|
|
|
|
case '{':
|
|
|
|
case '}':
|
|
|
|
case ',':
|
|
|
|
case ';':
|
|
|
|
case ':':
|
|
|
|
case '?':
|
|
|
|
case '~':
|
2015-04-12 20:32:03 +08:00
|
|
|
case '@': /* only used in assembler */
|
|
|
|
parse_simple:
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = c;
|
2009-05-06 02:17:49 +08:00
|
|
|
p++;
|
|
|
|
break;
|
|
|
|
default:
|
2016-10-02 02:26:50 +08:00
|
|
|
if (c >= 0x80 && c <= 0xFF) /* utf8 identifiers */
|
|
|
|
goto parse_ident_fast;
|
2021-10-22 13:39:54 +08:00
|
|
|
if (parse_flags & PARSE_FLAG_ASM_FILE)
|
2016-04-15 02:46:46 +08:00
|
|
|
goto parse_simple;
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("unrecognized character \\x%02x", c);
|
2009-05-06 02:17:49 +08:00
|
|
|
break;
|
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_flags = 0;
|
2009-05-06 02:17:49 +08:00
|
|
|
keep_tok_flags:
|
2021-10-22 13:39:54 +08:00
|
|
|
file->buf_ptr = p;
|
2009-05-06 02:17:49 +08:00
|
|
|
#if defined(PARSE_DEBUG)
|
2021-10-22 13:39:54 +08:00
|
|
|
printf("token = %d %s\n", tok, get_tok_str(tok, &tokc));
|
2009-05-06 02:17:49 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static void macro_subst(
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
TokenString *tok_str,
|
|
|
|
Sym **nested_list,
|
2017-07-09 10:53:24 +08:00
|
|
|
const int *macro_str
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
);
|
|
|
|
|
2014-04-12 12:00:13 +08:00
|
|
|
/* substitute arguments in replacement lists in macro_str by the values in
|
|
|
|
args (field d) and return allocated string */
|
2021-10-22 13:39:54 +08:00
|
|
|
static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
int t, t0, t1, spc;
|
2010-01-15 03:58:03 +08:00
|
|
|
const int *st;
|
2009-05-06 02:17:49 +08:00
|
|
|
Sym *s;
|
2014-04-05 02:18:39 +08:00
|
|
|
CValue cval;
|
2009-05-06 02:17:49 +08:00
|
|
|
TokenString str;
|
|
|
|
|
|
|
|
tok_str_new(&str);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
t0 = t1 = 0;
|
2009-05-06 02:17:49 +08:00
|
|
|
while(1) {
|
2010-01-15 03:58:03 +08:00
|
|
|
TOK_GET(&t, ¯o_str, &cval);
|
2009-05-06 02:17:49 +08:00
|
|
|
if (!t)
|
|
|
|
break;
|
|
|
|
if (t == '#') {
|
|
|
|
/* stringize */
|
2010-01-15 03:58:03 +08:00
|
|
|
TOK_GET(&t, ¯o_str, &cval);
|
2009-05-06 02:17:49 +08:00
|
|
|
if (!t)
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
goto bad_stringy;
|
2009-05-06 02:17:49 +08:00
|
|
|
s = sym_find2(args, t);
|
|
|
|
if (s) {
|
2023-04-25 03:58:50 +08:00
|
|
|
cstr_reset(&tokcstr);
|
|
|
|
cstr_ccat(&tokcstr, '\"');
|
2009-07-07 03:16:41 +08:00
|
|
|
st = s->d;
|
2009-05-06 02:17:49 +08:00
|
|
|
spc = 0;
|
2017-07-09 10:30:36 +08:00
|
|
|
while (*st >= 0) {
|
2010-01-15 03:58:03 +08:00
|
|
|
TOK_GET(&t, &st, &cval);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
if (t != TOK_PLCHLDR
|
|
|
|
&& t != TOK_NOSUBST
|
2021-10-22 13:39:54 +08:00
|
|
|
&& 0 == check_space(t, &spc)) {
|
|
|
|
const char *s = get_tok_str(t, &cval);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
while (*s) {
|
2016-03-15 00:26:41 +08:00
|
|
|
if (t == TOK_PPSTR && *s != '\'')
|
2023-04-25 03:58:50 +08:00
|
|
|
add_char(&tokcstr, *s);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
else
|
2023-04-25 03:58:50 +08:00
|
|
|
cstr_ccat(&tokcstr, *s);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
++s;
|
|
|
|
}
|
|
|
|
}
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2023-04-25 03:58:50 +08:00
|
|
|
tokcstr.size -= spc;
|
|
|
|
cstr_ccat(&tokcstr, '\"');
|
|
|
|
cstr_ccat(&tokcstr, '\0');
|
2009-05-06 02:17:49 +08:00
|
|
|
#ifdef PP_DEBUG
|
2023-04-25 03:58:50 +08:00
|
|
|
printf("\nstringize: <%s>\n", (char *)tokcstr.data);
|
2009-05-06 02:17:49 +08:00
|
|
|
#endif
|
|
|
|
/* add string */
|
2023-04-25 03:58:50 +08:00
|
|
|
cval.str.size = tokcstr.size;
|
|
|
|
cval.str.data = tokcstr.data;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_add2(&str, TOK_PPSTR, &cval);
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
bad_stringy:
|
2021-10-22 13:39:54 +08:00
|
|
|
expect("macro parameter after '#'");
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
} else if (t >= TOK_IDENT) {
|
|
|
|
s = sym_find2(args, t);
|
|
|
|
if (s) {
|
2009-07-07 03:16:41 +08:00
|
|
|
st = s->d;
|
2009-05-06 02:17:49 +08:00
|
|
|
/* if '##' is present before or after, no arg substitution */
|
2016-10-31 10:59:31 +08:00
|
|
|
if (*macro_str == TOK_PPJOIN || t1 == TOK_PPJOIN) {
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
/* special case for var arg macros : ## eats the ','
|
|
|
|
if empty VA_ARGS variable. */
|
2016-10-31 10:59:31 +08:00
|
|
|
if (t1 == TOK_PPJOIN && t0 == ',' && gnu_ext && s->type.t) {
|
2017-07-09 10:30:36 +08:00
|
|
|
if (*st <= 0) {
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
/* suppress ',' '##' */
|
|
|
|
str.len -= 2;
|
|
|
|
} else {
|
|
|
|
/* suppress '##' and add variable */
|
|
|
|
str.len--;
|
|
|
|
goto add_var;
|
|
|
|
}
|
2015-05-02 22:27:49 +08:00
|
|
|
}
|
|
|
|
} else {
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
add_var:
|
2017-07-09 11:30:47 +08:00
|
|
|
if (!s->next) {
|
|
|
|
/* Expand arguments tokens and store them. In most
|
|
|
|
cases we could also re-expand each argument if
|
|
|
|
used multiple times, but not if the argument
|
|
|
|
contains the __COUNTER__ macro. */
|
|
|
|
TokenString str2;
|
2021-10-22 13:39:54 +08:00
|
|
|
sym_push2(&s->next, s->v, s->type.t, 0);
|
2017-07-09 11:30:47 +08:00
|
|
|
tok_str_new(&str2);
|
2021-10-22 13:39:54 +08:00
|
|
|
macro_subst(&str2, nested_list, st);
|
|
|
|
tok_str_add(&str2, 0);
|
2017-07-09 11:30:47 +08:00
|
|
|
s->next->d = str2.str;
|
|
|
|
}
|
|
|
|
st = s->next->d;
|
|
|
|
}
|
2023-04-07 06:45:20 +08:00
|
|
|
if (*st <= 0) {
|
|
|
|
/* expanded to empty string */
|
|
|
|
tok_str_add(&str, TOK_PLCHLDR);
|
|
|
|
} else for (;;) {
|
2017-07-09 11:30:47 +08:00
|
|
|
int t2;
|
|
|
|
TOK_GET(&t2, &st, &cval);
|
|
|
|
if (t2 <= 0)
|
|
|
|
break;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_add2(&str, t2, &cval);
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_add(&str, t);
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_add2(&str, t, &cval);
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
t0 = t1, t1 = t;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_add(&str, 0);
|
2009-05-06 02:17:49 +08:00
|
|
|
return str.str;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char const ab_month_name[12][4] =
|
|
|
|
{
|
|
|
|
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
|
|
|
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
|
|
|
};
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static int paste_tokens(int t1, CValue *v1, int t2, CValue *v2)
|
2017-07-09 10:53:24 +08:00
|
|
|
{
|
|
|
|
int n, ret = 1;
|
|
|
|
|
2023-04-25 03:58:50 +08:00
|
|
|
cstr_reset(&tokcstr);
|
2017-07-09 10:53:24 +08:00
|
|
|
if (t1 != TOK_PLCHLDR)
|
2023-04-25 03:58:50 +08:00
|
|
|
cstr_cat(&tokcstr, get_tok_str(t1, v1), -1);
|
|
|
|
n = tokcstr.size;
|
2017-07-09 10:53:24 +08:00
|
|
|
if (t2 != TOK_PLCHLDR)
|
2023-04-25 03:58:50 +08:00
|
|
|
cstr_cat(&tokcstr, get_tok_str(t2, v2), -1);
|
|
|
|
cstr_ccat(&tokcstr, '\0');
|
|
|
|
//printf("paste <%s>\n", (char*)tokcstr.data);
|
2017-07-09 10:53:24 +08:00
|
|
|
|
2023-04-25 03:58:50 +08:00
|
|
|
tcc_open_bf(tcc_state, ":paste:", tokcstr.size);
|
|
|
|
memcpy(file->buffer, tokcstr.data, tokcstr.size);
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_flags = 0;
|
2017-07-09 10:53:24 +08:00
|
|
|
for (;;) {
|
2021-10-22 13:39:54 +08:00
|
|
|
next_nomacro1();
|
|
|
|
if (0 == *file->buf_ptr)
|
2017-07-09 10:53:24 +08:00
|
|
|
break;
|
2021-10-22 13:39:54 +08:00
|
|
|
if (is_space(tok))
|
2017-07-09 10:53:24 +08:00
|
|
|
continue;
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_warning("pasting \"%.*s\" and \"%s\" does not give a valid"
|
2023-04-25 03:58:50 +08:00
|
|
|
" preprocessing token", n, file->buffer, file->buffer + n);
|
2017-07-09 10:53:24 +08:00
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_close();
|
2017-07-09 10:53:24 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* handle the '##' operator. Return NULL if no '##' seen. Otherwise
|
|
|
|
return the resulting string (which must be freed). */
|
2021-10-22 13:39:54 +08:00
|
|
|
static inline int *macro_twosharps(const int *ptr0)
|
2017-07-09 10:53:24 +08:00
|
|
|
{
|
|
|
|
int t;
|
|
|
|
CValue cval;
|
|
|
|
TokenString macro_str1;
|
|
|
|
int start_of_nosubsts = -1;
|
|
|
|
const int *ptr;
|
|
|
|
|
|
|
|
/* we search the first '##' */
|
|
|
|
for (ptr = ptr0;;) {
|
|
|
|
TOK_GET(&t, &ptr, &cval);
|
|
|
|
if (t == TOK_PPJOIN)
|
|
|
|
break;
|
|
|
|
if (t == 0)
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
tok_str_new(¯o_str1);
|
|
|
|
|
|
|
|
//tok_print(" $$$", ptr0);
|
|
|
|
for (ptr = ptr0;;) {
|
|
|
|
TOK_GET(&t, &ptr, &cval);
|
|
|
|
if (t == 0)
|
|
|
|
break;
|
|
|
|
if (t == TOK_PPJOIN)
|
|
|
|
continue;
|
|
|
|
while (*ptr == TOK_PPJOIN) {
|
|
|
|
int t1; CValue cv1;
|
|
|
|
/* given 'a##b', remove nosubsts preceding 'a' */
|
|
|
|
if (start_of_nosubsts >= 0)
|
|
|
|
macro_str1.len = start_of_nosubsts;
|
|
|
|
/* given 'a##b', remove nosubsts preceding 'b' */
|
|
|
|
while ((t1 = *++ptr) == TOK_NOSUBST)
|
|
|
|
;
|
|
|
|
if (t1 && t1 != TOK_PPJOIN) {
|
|
|
|
TOK_GET(&t1, &ptr, &cv1);
|
|
|
|
if (t != TOK_PLCHLDR || t1 != TOK_PLCHLDR) {
|
2021-10-22 13:39:54 +08:00
|
|
|
if (paste_tokens(t, &cval, t1, &cv1)) {
|
|
|
|
t = tok, cval = tokc;
|
2017-07-09 10:53:24 +08:00
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_add2(¯o_str1, t, &cval);
|
2017-07-09 10:53:24 +08:00
|
|
|
t = t1, cval = cv1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (t == TOK_NOSUBST) {
|
|
|
|
if (start_of_nosubsts < 0)
|
|
|
|
start_of_nosubsts = macro_str1.len;
|
|
|
|
} else {
|
|
|
|
start_of_nosubsts = -1;
|
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_add2(¯o_str1, t, &cval);
|
2017-07-09 10:53:24 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_add(¯o_str1, 0);
|
2017-07-09 10:53:24 +08:00
|
|
|
//tok_print(" ###", macro_str1.str);
|
|
|
|
return macro_str1.str;
|
|
|
|
}
|
|
|
|
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
/* peek or read [ws_str == NULL] next token from function macro call,
|
|
|
|
walking up macro levels up to the file if necessary */
|
2021-10-22 13:39:54 +08:00
|
|
|
static int next_argstream(Sym **nested_list, TokenString *ws_str)
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
{
|
|
|
|
int t;
|
|
|
|
const int *p;
|
|
|
|
Sym *sa;
|
|
|
|
|
|
|
|
for (;;) {
|
2021-10-22 13:39:54 +08:00
|
|
|
if (macro_ptr) {
|
|
|
|
p = macro_ptr, t = *p;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
if (ws_str) {
|
2017-04-16 01:24:13 +08:00
|
|
|
while (is_space(t) || TOK_LINEFEED == t || TOK_PLCHLDR == t)
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_add(ws_str, t), t = *++p;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
}
|
2017-07-09 10:30:36 +08:00
|
|
|
if (t == 0) {
|
2021-10-22 13:39:54 +08:00
|
|
|
end_macro();
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
/* also, end of scope for nested defined symbol */
|
|
|
|
sa = *nested_list;
|
2016-04-30 01:00:33 +08:00
|
|
|
while (sa && sa->v == 0)
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
sa = sa->prev;
|
|
|
|
if (sa)
|
2016-04-30 01:00:33 +08:00
|
|
|
sa->v = 0;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} else {
|
2022-08-18 16:43:28 +08:00
|
|
|
uint8_t *p = file->buf_ptr;
|
|
|
|
int ch = handle_bs(&p);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
if (ws_str) {
|
2021-10-22 13:39:54 +08:00
|
|
|
while (is_space(ch) || ch == '\n' || ch == '/') {
|
|
|
|
if (ch == '/') {
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
int c;
|
|
|
|
PEEKC(c, p);
|
|
|
|
if (c == '*') {
|
2022-08-18 16:43:28 +08:00
|
|
|
p = parse_comment(p) - 1;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
} else if (c == '/') {
|
2022-08-18 16:43:28 +08:00
|
|
|
p = parse_line_comment(p) - 1;
|
|
|
|
} else {
|
2022-10-09 07:40:18 +08:00
|
|
|
*--p = ch;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
break;
|
2022-08-18 16:43:28 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
ch = ' ';
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
if (ch == '\n')
|
|
|
|
file->line_num++;
|
|
|
|
if (!(ch == '\f' || ch == '\v' || ch == '\r'))
|
|
|
|
tok_str_add(ws_str, ch);
|
2022-08-18 16:43:28 +08:00
|
|
|
PEEKC(ch, p);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
}
|
|
|
|
}
|
2022-08-18 16:43:28 +08:00
|
|
|
file->buf_ptr = p;
|
2021-10-22 13:39:54 +08:00
|
|
|
t = ch;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ws_str)
|
|
|
|
return t;
|
2021-10-22 13:39:54 +08:00
|
|
|
next_nomacro();
|
|
|
|
return tok;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
/* do macro substitution of current token with macro 's' and add
|
|
|
|
result to (tok_str,tok_len). 'nested_list' is the list of all
|
|
|
|
macros we got inside to avoid recursing. Return non zero if no
|
|
|
|
substitution needs to be done */
|
2021-10-22 13:39:54 +08:00
|
|
|
static int macro_subst_tok(
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
TokenString *tok_str,
|
|
|
|
Sym **nested_list,
|
2017-07-09 10:53:24 +08:00
|
|
|
Sym *s)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
|
|
|
Sym *args, *sa, *sa1;
|
2017-07-24 03:24:11 +08:00
|
|
|
int parlevel, t, t1, spc;
|
2009-05-06 02:17:49 +08:00
|
|
|
TokenString str;
|
|
|
|
char *cstrval;
|
2014-04-05 02:18:39 +08:00
|
|
|
CValue cval;
|
2009-05-06 02:17:49 +08:00
|
|
|
char buf[32];
|
2017-07-24 03:24:11 +08:00
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
/* if symbol is a macro, prepare substitution */
|
|
|
|
/* special macros */
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok == TOK___LINE__ || tok == TOK___COUNTER__) {
|
|
|
|
t = tok == TOK___LINE__ ? file->line_num : pp_counter++;
|
2017-07-09 11:30:47 +08:00
|
|
|
snprintf(buf, sizeof(buf), "%d", t);
|
2009-05-06 02:17:49 +08:00
|
|
|
cstrval = buf;
|
|
|
|
t1 = TOK_PPNUM;
|
|
|
|
goto add_cstr1;
|
2021-10-22 13:39:54 +08:00
|
|
|
} else if (tok == TOK___FILE__) {
|
|
|
|
cstrval = file->filename;
|
2009-05-06 02:17:49 +08:00
|
|
|
goto add_cstr;
|
2021-10-22 13:39:54 +08:00
|
|
|
} else if (tok == TOK___DATE__ || tok == TOK___TIME__) {
|
2009-05-06 02:17:49 +08:00
|
|
|
time_t ti;
|
|
|
|
struct tm *tm;
|
|
|
|
|
|
|
|
time(&ti);
|
|
|
|
tm = localtime(&ti);
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok == TOK___DATE__) {
|
2015-07-30 04:53:57 +08:00
|
|
|
snprintf(buf, sizeof(buf), "%s %2d %d",
|
2009-05-06 02:17:49 +08:00
|
|
|
ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
|
|
|
|
} else {
|
2015-07-30 04:53:57 +08:00
|
|
|
snprintf(buf, sizeof(buf), "%02d:%02d:%02d",
|
2009-05-06 02:17:49 +08:00
|
|
|
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
|
|
|
}
|
|
|
|
cstrval = buf;
|
|
|
|
add_cstr:
|
|
|
|
t1 = TOK_STR;
|
|
|
|
add_cstr1:
|
2023-04-25 03:58:50 +08:00
|
|
|
cstr_reset(&tokcstr);
|
|
|
|
cstr_cat(&tokcstr, cstrval, 0);
|
|
|
|
cval.str.size = tokcstr.size;
|
|
|
|
cval.str.data = tokcstr.data;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_add2(tok_str, t1, &cval);
|
2017-07-24 03:24:11 +08:00
|
|
|
} else if (s->d) {
|
2021-10-22 13:39:54 +08:00
|
|
|
int saved_parse_flags = parse_flags;
|
2017-07-09 10:53:24 +08:00
|
|
|
int *joined_str = NULL;
|
2017-07-24 03:24:11 +08:00
|
|
|
int *mstr = s->d;
|
tccpp.c: correct # stringification
Fix handling of escape characters, spaces, and line feeds in macros or
macro arguments that might yet be subject to # stringification.
Should this be an -f option? I think memory usage increases only very
slightly (in particular, while line feeds, stray \s, and spaces are
preserved, comments are not), so it's probably not worth it to make it
one.
Note that macro_subst now checks for stray \s which are still left in
the input stream after macro substitution, if desired.
This patch depends on the previous patch, so if you revert that, please
revert this patch, too.
See http://lists.nongnu.org/archive/html/tinycc-devel/2015-05/msg00002.html
2015-05-02 21:19:14 +08:00
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
if (s->type.t == MACRO_FUNC) {
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
/* whitespace between macro name and argument list */
|
|
|
|
TokenString ws_str;
|
2015-05-02 21:55:42 +08:00
|
|
|
tok_str_new(&ws_str);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2015-05-02 21:55:42 +08:00
|
|
|
spc = 0;
|
2021-10-22 13:39:54 +08:00
|
|
|
parse_flags |= PARSE_FLAG_SPACES | PARSE_FLAG_LINEFEED
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
| PARSE_FLAG_ACCEPT_STRAYS;
|
|
|
|
|
|
|
|
/* get next token from argument stream */
|
2021-10-22 13:39:54 +08:00
|
|
|
t = next_argstream(nested_list, &ws_str);
|
tccpp.c: correct # stringification
Fix handling of escape characters, spaces, and line feeds in macros or
macro arguments that might yet be subject to # stringification.
Should this be an -f option? I think memory usage increases only very
slightly (in particular, while line feeds, stray \s, and spaces are
preserved, comments are not), so it's probably not worth it to make it
one.
Note that macro_subst now checks for stray \s which are still left in
the input stream after macro substitution, if desired.
This patch depends on the previous patch, so if you revert that, please
revert this patch, too.
See http://lists.nongnu.org/archive/html/tinycc-devel/2015-05/msg00002.html
2015-05-02 21:19:14 +08:00
|
|
|
if (t != '(') {
|
2015-05-02 21:55:42 +08:00
|
|
|
/* not a macro substitution after all, restore the
|
|
|
|
* macro token plus all whitespace we've read.
|
|
|
|
* whitespace is intentionally not merged to preserve
|
|
|
|
* newlines. */
|
2021-10-22 13:39:54 +08:00
|
|
|
parse_flags = saved_parse_flags;
|
|
|
|
tok_str_add(tok_str, tok);
|
|
|
|
if (parse_flags & PARSE_FLAG_SPACES) {
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
int i;
|
|
|
|
for (i = 0; i < ws_str.len; i++)
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_add(tok_str, ws_str.str[i]);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
}
|
2022-10-17 13:49:47 +08:00
|
|
|
if (ws_str.len && ws_str.str[ws_str.len - 1] == '\n')
|
|
|
|
tok_flags |= TOK_FLAG_BOL;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_free_str(ws_str.str);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
return 0;
|
2015-05-02 21:55:42 +08:00
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_free_str(ws_str.str);
|
tccpp.c: correct # stringification
Fix handling of escape characters, spaces, and line feeds in macros or
macro arguments that might yet be subject to # stringification.
Should this be an -f option? I think memory usage increases only very
slightly (in particular, while line feeds, stray \s, and spaces are
preserved, comments are not), so it's probably not worth it to make it
one.
Note that macro_subst now checks for stray \s which are still left in
the input stream after macro substitution, if desired.
This patch depends on the previous patch, so if you revert that, please
revert this patch, too.
See http://lists.nongnu.org/archive/html/tinycc-devel/2015-05/msg00002.html
2015-05-02 21:19:14 +08:00
|
|
|
}
|
2017-04-16 01:24:13 +08:00
|
|
|
do {
|
2021-10-22 13:39:54 +08:00
|
|
|
next_nomacro(); /* eat '(' */
|
|
|
|
} while (tok == TOK_PLCHLDR || is_space(tok));
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
/* argument macro */
|
|
|
|
args = NULL;
|
|
|
|
sa = s->next;
|
|
|
|
/* NOTE: empty args are allowed, except if no args */
|
|
|
|
for(;;) {
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
do {
|
2021-10-22 13:39:54 +08:00
|
|
|
next_argstream(nested_list, NULL);
|
|
|
|
} while (tok == TOK_PLCHLDR || is_space(tok) ||
|
|
|
|
TOK_LINEFEED == tok);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
empty_arg:
|
2009-05-06 02:17:49 +08:00
|
|
|
/* handle '()' case */
|
2021-10-22 13:39:54 +08:00
|
|
|
if (!args && !sa && tok == ')')
|
2009-05-06 02:17:49 +08:00
|
|
|
break;
|
|
|
|
if (!sa)
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("macro '%s' used with too many args",
|
|
|
|
get_tok_str(s->v, 0));
|
2009-05-06 02:17:49 +08:00
|
|
|
tok_str_new(&str);
|
|
|
|
parlevel = spc = 0;
|
|
|
|
/* NOTE: non zero sa->t indicates VA_ARGS */
|
2015-07-30 04:53:57 +08:00
|
|
|
while ((parlevel > 0 ||
|
2021-10-22 13:39:54 +08:00
|
|
|
(tok != ')' &&
|
|
|
|
(tok != ',' || sa->type.t)))) {
|
|
|
|
if (tok == TOK_EOF || tok == 0)
|
2015-05-02 20:33:45 +08:00
|
|
|
break;
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok == '(')
|
2009-05-06 02:17:49 +08:00
|
|
|
parlevel++;
|
2021-10-22 13:39:54 +08:00
|
|
|
else if (tok == ')')
|
2009-05-06 02:17:49 +08:00
|
|
|
parlevel--;
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok == TOK_LINEFEED)
|
|
|
|
tok = ' ';
|
|
|
|
if (!check_space(tok, &spc))
|
|
|
|
tok_str_add2(&str, tok, &tokc);
|
|
|
|
next_argstream(nested_list, NULL);
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2015-05-02 22:47:11 +08:00
|
|
|
if (parlevel)
|
2021-10-22 13:39:54 +08:00
|
|
|
expect(")");
|
2009-05-06 02:17:49 +08:00
|
|
|
str.len -= spc;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_add(&str, -1);
|
|
|
|
tok_str_add(&str, 0);
|
|
|
|
sa1 = sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, 0);
|
2009-07-07 03:16:41 +08:00
|
|
|
sa1->d = str.str;
|
2009-05-06 02:17:49 +08:00
|
|
|
sa = sa->next;
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok == ')') {
|
2009-05-06 02:17:49 +08:00
|
|
|
/* special case for gcc var args: add an empty
|
|
|
|
var arg argument if it is omitted */
|
|
|
|
if (sa && sa->type.t && gnu_ext)
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
goto empty_arg;
|
|
|
|
break;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
if (tok != ',')
|
|
|
|
expect(",");
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
if (sa) {
|
2021-10-22 13:39:54 +08:00
|
|
|
tcc_error("macro '%s' used with too few args",
|
|
|
|
get_tok_str(s->v, 0));
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* now subst each arg */
|
2021-10-22 13:39:54 +08:00
|
|
|
mstr = macro_arg_subst(nested_list, mstr, args);
|
2009-05-06 02:17:49 +08:00
|
|
|
/* free memory */
|
|
|
|
sa = args;
|
|
|
|
while (sa) {
|
|
|
|
sa1 = sa->prev;
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_free_str(sa->d);
|
2017-07-09 11:30:47 +08:00
|
|
|
if (sa->next) {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_free_str(sa->next->d);
|
|
|
|
sym_free(sa->next);
|
2017-07-09 11:30:47 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
sym_free(sa);
|
2009-05-06 02:17:49 +08:00
|
|
|
sa = sa1;
|
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
parse_flags = saved_parse_flags;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
sym_push2(nested_list, s->v, 0, 0);
|
|
|
|
parse_flags = saved_parse_flags;
|
|
|
|
joined_str = macro_twosharps(mstr);
|
|
|
|
macro_subst(tok_str, nested_list, joined_str ? joined_str : mstr);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
/* pop nested defined symbol */
|
|
|
|
sa1 = *nested_list;
|
|
|
|
*nested_list = sa1->prev;
|
2021-10-22 13:39:54 +08:00
|
|
|
sym_free(sa1);
|
2017-07-09 10:53:24 +08:00
|
|
|
if (joined_str)
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_free_str(joined_str);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
if (mstr != s->d)
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_free_str(mstr);
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* do macro substitution of macro_str and add result to
|
|
|
|
(tok_str,tok_len). 'nested_list' is the list of all macros we got
|
|
|
|
inside to avoid recursing. */
|
2021-10-22 13:39:54 +08:00
|
|
|
static void macro_subst(
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
TokenString *tok_str,
|
|
|
|
Sym **nested_list,
|
2017-07-09 10:53:24 +08:00
|
|
|
const int *macro_str
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
|
|
|
Sym *s;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
int t, spc, nosubst;
|
2014-04-05 02:18:39 +08:00
|
|
|
CValue cval;
|
2015-07-30 04:53:57 +08:00
|
|
|
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
spc = nosubst = 0;
|
tcc -E: append a ' ' after subst
We need a ' ' after subst of m in the following case
#define m(name,r) name ## r
#define m0(a,b,c) int m(a,b) c
#define m1(a,b,c) int m(a,b)c
m0(a, b, c);
m1(a, b, c);
2011-02-27 10:15:15 +08:00
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
while (1) {
|
2017-07-09 10:53:24 +08:00
|
|
|
TOK_GET(&t, ¯o_str, &cval);
|
2017-07-09 10:30:36 +08:00
|
|
|
if (t <= 0)
|
2009-05-06 02:17:49 +08:00
|
|
|
break;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
|
|
|
if (t >= TOK_IDENT && 0 == nosubst) {
|
2021-10-22 13:39:54 +08:00
|
|
|
s = define_find(t);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
if (s == NULL)
|
|
|
|
goto no_subst;
|
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
/* if nested substitution, do nothing */
|
2011-02-02 05:23:40 +08:00
|
|
|
if (sym_find2(*nested_list, t)) {
|
|
|
|
/* and mark it as TOK_NOSUBST, so it doesn't get subst'd again */
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_str_add2(tok_str, TOK_NOSUBST, NULL);
|
2009-05-06 02:17:49 +08:00
|
|
|
goto no_subst;
|
2011-02-02 05:23:40 +08:00
|
|
|
}
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
|
|
|
{
|
2021-10-22 13:39:54 +08:00
|
|
|
TokenString *str = tok_str_alloc();
|
2018-06-08 21:31:40 +08:00
|
|
|
str->str = (int*)macro_str;
|
2021-10-22 13:39:54 +08:00
|
|
|
begin_macro(str, 2);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = t;
|
|
|
|
macro_subst_tok(tok_str, nested_list, s);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
if (macro_stack != str) {
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
/* already finished by reading function macro arguments */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
macro_str = macro_ptr;
|
|
|
|
end_macro ();
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
}
|
2017-06-05 19:21:39 +08:00
|
|
|
if (tok_str->len)
|
|
|
|
spc = is_space(t = tok_str->str[tok_str->lastlen]);
|
2009-05-06 02:17:49 +08:00
|
|
|
} else {
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
no_subst:
|
2021-10-22 13:39:54 +08:00
|
|
|
if (!check_space(t, &spc))
|
|
|
|
tok_str_add2(tok_str, t, &cval);
|
2017-06-05 19:21:39 +08:00
|
|
|
|
|
|
|
if (nosubst) {
|
|
|
|
if (nosubst > 1 && (spc || (++nosubst == 3 && t == '(')))
|
|
|
|
continue;
|
|
|
|
nosubst = 0;
|
|
|
|
}
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
if (t == TOK_NOSUBST)
|
|
|
|
nosubst = 1;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2017-09-25 09:03:26 +08:00
|
|
|
/* GCC supports 'defined' as result of a macro substitution */
|
2021-10-22 13:39:54 +08:00
|
|
|
if (t == TOK_DEFINED && pp_expr)
|
2017-06-05 19:21:39 +08:00
|
|
|
nosubst = 2;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-18 00:08:09 +08:00
|
|
|
/* return next token without macro substitution. Can read input from
|
|
|
|
macro_ptr buffer */
|
2021-10-22 13:39:54 +08:00
|
|
|
static void next_nomacro(void)
|
2020-06-18 00:08:09 +08:00
|
|
|
{
|
|
|
|
int t;
|
2021-10-22 13:39:54 +08:00
|
|
|
if (macro_ptr) {
|
2020-06-18 00:08:09 +08:00
|
|
|
redo:
|
2021-10-22 13:39:54 +08:00
|
|
|
t = *macro_ptr;
|
2020-06-18 00:08:09 +08:00
|
|
|
if (TOK_HAS_VALUE(t)) {
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_get(&tok, ¯o_ptr, &tokc);
|
2020-06-18 00:08:09 +08:00
|
|
|
if (t == TOK_LINENUM) {
|
2021-10-22 13:39:54 +08:00
|
|
|
file->line_num = tokc.i;
|
2020-06-18 00:08:09 +08:00
|
|
|
goto redo;
|
|
|
|
}
|
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
macro_ptr++;
|
2020-06-18 00:08:09 +08:00
|
|
|
if (t < TOK_IDENT) {
|
2021-10-22 13:39:54 +08:00
|
|
|
if (!(parse_flags & PARSE_FLAG_SPACES)
|
|
|
|
&& (isidnum_table[t - CH_EOF] & IS_SPC))
|
2020-06-18 00:08:09 +08:00
|
|
|
goto redo;
|
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
tok = t;
|
2020-06-18 00:08:09 +08:00
|
|
|
}
|
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
next_nomacro1();
|
2020-06-18 00:08:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-06 02:17:49 +08:00
|
|
|
/* return next token with macro substitution */
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void next(void)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
2020-06-18 00:08:09 +08:00
|
|
|
int t;
|
2009-05-06 02:17:49 +08:00
|
|
|
redo:
|
2021-10-22 13:39:54 +08:00
|
|
|
next_nomacro();
|
|
|
|
t = tok;
|
|
|
|
if (macro_ptr) {
|
2020-06-18 00:08:09 +08:00
|
|
|
if (!TOK_HAS_VALUE(t)) {
|
|
|
|
if (t == TOK_NOSUBST || t == TOK_PLCHLDR) {
|
|
|
|
/* discard preprocessor markers */
|
|
|
|
goto redo;
|
|
|
|
} else if (t == 0) {
|
|
|
|
/* end of macro or unget token string */
|
2021-10-22 13:39:54 +08:00
|
|
|
end_macro();
|
2020-06-18 00:08:09 +08:00
|
|
|
goto redo;
|
|
|
|
} else if (t == '\\') {
|
2021-10-22 13:39:54 +08:00
|
|
|
if (!(parse_flags & PARSE_FLAG_ACCEPT_STRAYS))
|
|
|
|
tcc_error("stray '\\' in program");
|
2020-06-18 00:08:09 +08:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
} else if (t >= TOK_IDENT && (parse_flags & PARSE_FLAG_PREPROCESS)) {
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
/* if reading from file, try to substitute macros */
|
2021-10-22 13:39:54 +08:00
|
|
|
Sym *s = define_find(t);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
if (s) {
|
2016-05-05 03:14:39 +08:00
|
|
|
Sym *nested_list = NULL;
|
2021-10-22 13:39:54 +08:00
|
|
|
tokstr_buf.len = 0;
|
|
|
|
macro_subst_tok(&tokstr_buf, &nested_list, s);
|
|
|
|
tok_str_add(&tokstr_buf, 0);
|
|
|
|
begin_macro(&tokstr_buf, 0);
|
2011-02-02 05:23:40 +08:00
|
|
|
goto redo;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
2020-06-18 00:08:09 +08:00
|
|
|
return;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
/* convert preprocessor tokens into C tokens */
|
2020-06-18 00:08:09 +08:00
|
|
|
if (t == TOK_PPNUM) {
|
2021-10-22 13:39:54 +08:00
|
|
|
if (parse_flags & PARSE_FLAG_TOK_NUM)
|
|
|
|
parse_number((char *)tokc.str.data);
|
2020-06-18 00:08:09 +08:00
|
|
|
} else if (t == TOK_PPSTR) {
|
2021-10-22 13:39:54 +08:00
|
|
|
if (parse_flags & PARSE_FLAG_TOK_STR)
|
|
|
|
parse_string((char *)tokc.str.data, tokc.str.size - 1);
|
2020-05-14 05:52:48 +08:00
|
|
|
}
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* push back current token and set current token to 'last_tok'. Only
|
|
|
|
identifier case handled for labels. */
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_INLN void unget_tok(int last_tok)
|
2009-05-06 02:17:49 +08:00
|
|
|
{
|
2016-10-02 02:26:50 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
TokenString *str = tok_str_alloc();
|
|
|
|
tok_str_add2(str, tok, &tokc);
|
|
|
|
tok_str_add(str, 0);
|
|
|
|
begin_macro(str, 1);
|
|
|
|
tok = last_tok;
|
2009-05-06 02:17:49 +08:00
|
|
|
}
|
|
|
|
|
2020-12-23 04:10:22 +08:00
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
/* init preprocessor */
|
2020-12-18 07:33:44 +08:00
|
|
|
|
2021-02-01 22:10:58 +08:00
|
|
|
static const char * const target_os_defs =
|
2020-12-18 07:33:44 +08:00
|
|
|
#ifdef TCC_TARGET_PE
|
2020-12-23 04:10:22 +08:00
|
|
|
"_WIN32\0"
|
|
|
|
# if PTR_SIZE == 8
|
|
|
|
"_WIN64\0"
|
|
|
|
# endif
|
2020-12-17 03:08:43 +08:00
|
|
|
#else
|
2020-12-18 07:33:44 +08:00
|
|
|
# if defined TCC_TARGET_MACHO
|
2020-12-23 04:10:22 +08:00
|
|
|
"__APPLE__\0"
|
2020-12-18 07:33:44 +08:00
|
|
|
# elif TARGETOS_FreeBSD
|
2020-12-23 04:10:22 +08:00
|
|
|
"__FreeBSD__ 12\0"
|
2020-12-18 07:33:44 +08:00
|
|
|
# elif TARGETOS_FreeBSD_kernel
|
2020-12-23 04:10:22 +08:00
|
|
|
"__FreeBSD_kernel__\0"
|
2020-12-18 07:33:44 +08:00
|
|
|
# elif TARGETOS_NetBSD
|
2020-12-23 04:10:22 +08:00
|
|
|
"__NetBSD__\0"
|
2020-12-18 07:33:44 +08:00
|
|
|
# elif TARGETOS_OpenBSD
|
2020-12-23 04:10:22 +08:00
|
|
|
"__OpenBSD__\0"
|
2020-12-18 07:33:44 +08:00
|
|
|
# else
|
2020-12-23 04:10:22 +08:00
|
|
|
"__linux__\0"
|
|
|
|
"__linux\0"
|
2022-05-18 04:28:32 +08:00
|
|
|
# if TARGETOS_ANDROID
|
|
|
|
"__ANDROID__\0"
|
|
|
|
# endif
|
2020-12-18 07:33:44 +08:00
|
|
|
# endif
|
2020-12-23 04:10:22 +08:00
|
|
|
"__unix__\0"
|
|
|
|
"__unix\0"
|
|
|
|
#endif
|
|
|
|
;
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static void putdef(CString *cs, const char *p)
|
2020-12-23 04:10:22 +08:00
|
|
|
{
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_printf(cs, "#define %s%s\n", p, &" 1"[!!strchr(p, ' ')*2]);
|
2020-12-23 04:10:22 +08:00
|
|
|
}
|
|
|
|
|
2022-05-18 04:28:32 +08:00
|
|
|
static void putdefs(CString *cs, const char *p)
|
|
|
|
{
|
|
|
|
while (*p)
|
|
|
|
putdef(cs, p), p = strchr(p, 0) + 1;
|
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static void tcc_predefs(TCCState *s1, CString *cs, int is_asm)
|
2020-12-23 04:10:22 +08:00
|
|
|
{
|
|
|
|
int a, b, c;
|
|
|
|
|
|
|
|
sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c);
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_printf(cs, "#define __TINYC__ %d\n", a*10000 + b*100 + c);
|
2022-05-18 04:28:32 +08:00
|
|
|
|
|
|
|
putdefs(cs, target_machine_defs);
|
|
|
|
putdefs(cs, target_os_defs);
|
|
|
|
|
2020-12-23 04:10:22 +08:00
|
|
|
#ifdef TCC_TARGET_ARM
|
2021-10-22 13:39:54 +08:00
|
|
|
if (s1->float_abi == ARM_HARD_FLOAT)
|
|
|
|
putdef(cs, "__ARM_PCS_VFP");
|
2020-07-07 02:10:56 +08:00
|
|
|
#endif
|
2020-12-18 07:33:44 +08:00
|
|
|
if (is_asm)
|
2021-10-22 13:39:54 +08:00
|
|
|
putdef(cs, "__ASSEMBLER__");
|
|
|
|
if (s1->output_type == TCC_OUTPUT_PREPROCESS)
|
|
|
|
putdef(cs, "__TCC_PP__");
|
|
|
|
if (s1->output_type == TCC_OUTPUT_MEMORY)
|
|
|
|
putdef(cs, "__TCC_RUN__");
|
2023-04-01 00:20:49 +08:00
|
|
|
#ifdef CONFIG_TCC_BACKTRACE
|
|
|
|
if (s1->do_backtrace)
|
|
|
|
putdef(cs, "__TCC_BACKTRACE__");
|
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_TCC_BCHECK
|
|
|
|
if (s1->do_bounds_check)
|
|
|
|
putdef(cs, "__TCC_BCHECK__");
|
|
|
|
#endif
|
2021-10-22 13:39:54 +08:00
|
|
|
if (s1->char_is_unsigned)
|
|
|
|
putdef(cs, "__CHAR_UNSIGNED__");
|
|
|
|
if (s1->optimize > 0)
|
|
|
|
putdef(cs, "__OPTIMIZE__");
|
|
|
|
if (s1->option_pthread)
|
|
|
|
putdef(cs, "_REENTRANT");
|
|
|
|
if (s1->leading_underscore)
|
|
|
|
putdef(cs, "__leading_underscore");
|
|
|
|
cstr_printf(cs, "#define __SIZEOF_POINTER__ %d\n", PTR_SIZE);
|
|
|
|
cstr_printf(cs, "#define __SIZEOF_LONG__ %d\n", LONG_SIZE);
|
2020-12-18 07:33:44 +08:00
|
|
|
if (!is_asm) {
|
2021-10-22 13:39:54 +08:00
|
|
|
putdef(cs, "__STDC__");
|
|
|
|
cstr_printf(cs, "#define __STDC_VERSION__ %dL\n", s1->cversion);
|
|
|
|
cstr_cat(cs,
|
2020-12-18 07:33:44 +08:00
|
|
|
/* load more predefs and __builtins */
|
|
|
|
#if CONFIG_TCC_PREDEFS
|
|
|
|
#include "tccdefs_.h" /* include as strings */
|
|
|
|
#else
|
|
|
|
"#include <tccdefs.h>\n" /* load at runtime */
|
2020-07-06 06:00:42 +08:00
|
|
|
#endif
|
2020-12-18 07:33:44 +08:00
|
|
|
, -1);
|
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_printf(cs, "#define __BASE_FILE__ \"%s\"\n", file->filename);
|
2020-05-14 05:52:48 +08:00
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void preprocess_start(TCCState *s1, int filetype)
|
2009-05-06 02:30:39 +08:00
|
|
|
{
|
2020-07-07 00:12:35 +08:00
|
|
|
int is_asm = !!(filetype & (AFF_TYPE_ASM|AFF_TYPE_ASMPP));
|
2019-12-11 07:37:18 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
tccpp_new(s1);
|
2017-02-14 01:23:55 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
s1->include_stack_ptr = s1->include_stack;
|
|
|
|
s1->ifdef_stack_ptr = s1->ifdef_stack;
|
|
|
|
file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
|
|
|
|
pp_expr = 0;
|
|
|
|
pp_counter = 0;
|
|
|
|
pp_debug_tok = pp_debug_symv = 0;
|
|
|
|
pp_once++;
|
|
|
|
s1->pack_stack[0] = 0;
|
|
|
|
s1->pack_stack_ptr = s1->pack_stack;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
set_idnum('$', !is_asm && s1->dollars_in_identifiers ? IS_ID : 0);
|
|
|
|
set_idnum('.', is_asm ? IS_ID : 0);
|
2017-02-14 01:23:55 +08:00
|
|
|
|
2020-07-07 00:12:35 +08:00
|
|
|
if (!(filetype & AFF_TYPE_ASM)) {
|
2023-04-25 03:58:50 +08:00
|
|
|
CString cstr;
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_new(&cstr);
|
|
|
|
tcc_predefs(s1, &cstr, is_asm);
|
|
|
|
if (s1->cmdline_defs.size)
|
|
|
|
cstr_cat(&cstr, s1->cmdline_defs.data, s1->cmdline_defs.size);
|
|
|
|
if (s1->cmdline_incl.size)
|
|
|
|
cstr_cat(&cstr, s1->cmdline_incl.data, s1->cmdline_incl.size);
|
2020-07-07 00:12:35 +08:00
|
|
|
//printf("%s\n", (char*)cstr.data);
|
2021-10-22 13:39:54 +08:00
|
|
|
*s1->include_stack_ptr++ = file;
|
|
|
|
tcc_open_bf(s1, "<command line>", cstr.size);
|
|
|
|
memcpy(file->buffer, cstr.data, cstr.size);
|
|
|
|
cstr_free(&cstr);
|
2020-07-07 00:12:35 +08:00
|
|
|
}
|
2017-07-21 04:21:27 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
parse_flags = is_asm ? PARSE_FLAG_ASM_FILE : 0;
|
|
|
|
tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
|
2017-07-21 04:21:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* cleanup from error/setjmp */
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void preprocess_end(TCCState *s1)
|
2017-07-21 04:21:27 +08:00
|
|
|
{
|
2021-10-22 13:39:54 +08:00
|
|
|
while (macro_stack)
|
|
|
|
end_macro();
|
|
|
|
macro_ptr = NULL;
|
|
|
|
while (file)
|
|
|
|
tcc_close();
|
|
|
|
tccpp_delete(s1);
|
2009-05-06 02:30:39 +08:00
|
|
|
}
|
|
|
|
|
2022-08-18 16:43:28 +08:00
|
|
|
ST_FUNC int set_idnum(int c, int val)
|
|
|
|
{
|
|
|
|
int prev = isidnum_table[c - CH_EOF];
|
|
|
|
isidnum_table[c - CH_EOF] = val;
|
|
|
|
return prev;
|
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void tccpp_new(TCCState *s)
|
2009-05-06 02:30:39 +08:00
|
|
|
{
|
|
|
|
int i, c;
|
|
|
|
const char *p, *r;
|
|
|
|
|
|
|
|
/* init isid table */
|
2016-04-05 18:05:09 +08:00
|
|
|
for(i = CH_EOF; i<128; i++)
|
2021-10-22 13:39:54 +08:00
|
|
|
set_idnum(i,
|
2016-08-25 22:40:50 +08:00
|
|
|
is_space(i) ? IS_SPC
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
: isid(i) ? IS_ID
|
|
|
|
: isnum(i) ? IS_NUM
|
2016-08-25 22:40:50 +08:00
|
|
|
: 0);
|
2015-04-20 08:44:08 +08:00
|
|
|
|
2016-04-05 18:05:09 +08:00
|
|
|
for(i = 128; i<256; i++)
|
2021-10-22 13:39:54 +08:00
|
|
|
set_idnum(i, IS_ID);
|
2016-04-05 18:05:09 +08:00
|
|
|
|
2016-04-17 21:22:50 +08:00
|
|
|
/* init allocators */
|
2021-10-22 13:39:54 +08:00
|
|
|
tal_new(&toksym_alloc, TOKSYM_TAL_LIMIT, TOKSYM_TAL_SIZE);
|
|
|
|
tal_new(&tokstr_alloc, TOKSTR_TAL_LIMIT, TOKSTR_TAL_SIZE);
|
2016-04-17 21:22:50 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
|
|
|
|
memset(s->cached_includes_hash, 0, sizeof s->cached_includes_hash);
|
2019-12-11 07:37:18 +08:00
|
|
|
|
2023-04-25 03:58:50 +08:00
|
|
|
cstr_new(&tokcstr);
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_new(&cstr_buf);
|
|
|
|
cstr_realloc(&cstr_buf, STRING_MAX_SIZE);
|
|
|
|
tok_str_new(&tokstr_buf);
|
|
|
|
tok_str_realloc(&tokstr_buf, TOKSTR_MAX_SIZE);
|
2020-01-18 05:58:39 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_ident = TOK_IDENT;
|
2009-05-06 02:30:39 +08:00
|
|
|
p = tcc_keywords;
|
|
|
|
while (*p) {
|
|
|
|
r = p;
|
|
|
|
for(;;) {
|
|
|
|
c = *r++;
|
|
|
|
if (c == '\0')
|
|
|
|
break;
|
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_alloc(p, r - p - 1);
|
2009-05-06 02:30:39 +08:00
|
|
|
p = r;
|
|
|
|
}
|
2019-12-11 07:37:18 +08:00
|
|
|
|
|
|
|
/* we add dummy defines for some special macros to speed up tests
|
|
|
|
and to have working defined() */
|
2021-10-22 13:39:54 +08:00
|
|
|
define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
|
|
|
|
define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
|
|
|
|
define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
|
|
|
|
define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
|
|
|
|
define_push(TOK___COUNTER__, MACRO_OBJ, NULL, NULL);
|
2009-05-06 02:30:39 +08:00
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC void tccpp_delete(TCCState *s)
|
2015-03-03 19:19:14 +08:00
|
|
|
{
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
int i, n;
|
2015-03-03 19:19:14 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
dynarray_reset(&s->cached_includes, &s->nb_cached_includes);
|
2015-03-03 19:19:14 +08:00
|
|
|
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
/* free tokens */
|
2021-10-22 13:39:54 +08:00
|
|
|
n = tok_ident - TOK_IDENT;
|
2019-12-14 19:31:03 +08:00
|
|
|
if (n > total_idents)
|
|
|
|
total_idents = n;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
for(i = 0; i < n; i++)
|
2021-10-22 13:39:54 +08:00
|
|
|
tal_free(toksym_alloc, table_ident[i]);
|
|
|
|
tcc_free(table_ident);
|
|
|
|
table_ident = NULL;
|
2016-04-17 21:37:23 +08:00
|
|
|
|
|
|
|
/* free static buffers */
|
2021-10-22 13:39:54 +08:00
|
|
|
cstr_free(&tokcstr);
|
|
|
|
cstr_free(&cstr_buf);
|
|
|
|
tok_str_free_str(tokstr_buf.str);
|
2016-04-17 21:22:50 +08:00
|
|
|
|
|
|
|
/* free allocators */
|
2021-10-22 13:39:54 +08:00
|
|
|
tal_delete(toksym_alloc);
|
|
|
|
toksym_alloc = NULL;
|
|
|
|
tal_delete(tokstr_alloc);
|
|
|
|
tokstr_alloc = NULL;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
}
|
|
|
|
|
2016-05-05 20:12:53 +08:00
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
/* tcc -E [-P[1]] [-dD} support */
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static void tok_print(const char *msg, const int *str)
|
2016-05-05 20:12:53 +08:00
|
|
|
{
|
|
|
|
FILE *fp;
|
2017-07-21 04:21:27 +08:00
|
|
|
int t, s = 0;
|
2016-05-05 20:12:53 +08:00
|
|
|
CValue cval;
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
fp = tcc_state->ppfp;
|
2017-07-21 04:21:27 +08:00
|
|
|
fprintf(fp, "%s", msg);
|
2016-05-05 20:12:53 +08:00
|
|
|
while (str) {
|
|
|
|
TOK_GET(&t, &str, &cval);
|
|
|
|
if (!t)
|
|
|
|
break;
|
2021-10-22 13:39:54 +08:00
|
|
|
fprintf(fp, &" %s"[s], get_tok_str(t, &cval)), s = 1;
|
2016-05-05 20:12:53 +08:00
|
|
|
}
|
|
|
|
fprintf(fp, "\n");
|
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static void pp_line(TCCState *s1, BufferedFile *f, int level)
|
2016-05-05 20:12:53 +08:00
|
|
|
{
|
|
|
|
int d = f->line_num - f->line_ref;
|
2016-10-10 02:33:14 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
if (s1->dflag & 4)
|
2016-05-05 20:12:53 +08:00
|
|
|
return;
|
2016-10-10 02:33:14 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_NONE) {
|
2016-10-10 02:33:14 +08:00
|
|
|
;
|
2016-05-05 20:12:53 +08:00
|
|
|
} else if (level == 0 && f->line_ref && d < 8) {
|
|
|
|
while (d > 0)
|
2021-10-22 13:39:54 +08:00
|
|
|
fputs("\n", s1->ppfp), --d;
|
|
|
|
} else if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_STD) {
|
|
|
|
fprintf(s1->ppfp, "#line %d \"%s\"\n", f->line_num, f->filename);
|
2016-05-05 20:12:53 +08:00
|
|
|
} else {
|
2021-10-22 13:39:54 +08:00
|
|
|
fprintf(s1->ppfp, "# %d \"%s\"%s\n", f->line_num, f->filename,
|
2016-05-05 20:12:53 +08:00
|
|
|
level > 0 ? " 1" : level < 0 ? " 2" : "");
|
|
|
|
}
|
|
|
|
f->line_ref = f->line_num;
|
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static void define_print(TCCState *s1, int v)
|
2016-05-05 20:12:53 +08:00
|
|
|
{
|
|
|
|
FILE *fp;
|
|
|
|
Sym *s;
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
s = define_find(v);
|
2016-05-05 20:12:53 +08:00
|
|
|
if (NULL == s || NULL == s->d)
|
|
|
|
return;
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
fp = s1->ppfp;
|
|
|
|
fprintf(fp, "#define %s", get_tok_str(v, NULL));
|
2016-05-05 20:12:53 +08:00
|
|
|
if (s->type.t == MACRO_FUNC) {
|
|
|
|
Sym *a = s->next;
|
|
|
|
fprintf(fp,"(");
|
|
|
|
if (a)
|
|
|
|
for (;;) {
|
2021-10-22 13:39:54 +08:00
|
|
|
fprintf(fp,"%s", get_tok_str(a->v & ~SYM_FIELD, NULL));
|
2016-05-05 20:12:53 +08:00
|
|
|
if (!(a = a->next))
|
|
|
|
break;
|
|
|
|
fprintf(fp,",");
|
|
|
|
}
|
|
|
|
fprintf(fp,")");
|
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
tok_print("", s->d);
|
2016-05-05 20:12:53 +08:00
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static void pp_debug_defines(TCCState *s1)
|
2016-05-05 20:12:53 +08:00
|
|
|
{
|
|
|
|
int v, t;
|
|
|
|
const char *vs;
|
|
|
|
FILE *fp;
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
t = pp_debug_tok;
|
2016-05-05 20:12:53 +08:00
|
|
|
if (t == 0)
|
|
|
|
return;
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
file->line_num--;
|
|
|
|
pp_line(s1, file, 0);
|
|
|
|
file->line_ref = ++file->line_num;
|
2016-05-05 20:12:53 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
fp = s1->ppfp;
|
|
|
|
v = pp_debug_symv;
|
|
|
|
vs = get_tok_str(v, NULL);
|
2016-05-05 20:12:53 +08:00
|
|
|
if (t == TOK_DEFINE) {
|
2021-10-22 13:39:54 +08:00
|
|
|
define_print(s1, v);
|
2016-05-05 20:12:53 +08:00
|
|
|
} else if (t == TOK_UNDEF) {
|
|
|
|
fprintf(fp, "#undef %s\n", vs);
|
|
|
|
} else if (t == TOK_push_macro) {
|
|
|
|
fprintf(fp, "#pragma push_macro(\"%s\")\n", vs);
|
|
|
|
} else if (t == TOK_pop_macro) {
|
|
|
|
fprintf(fp, "#pragma pop_macro(\"%s\")\n", vs);
|
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
pp_debug_tok = 0;
|
2016-05-05 20:12:53 +08:00
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
static void pp_debug_builtins(TCCState *s1)
|
2016-05-05 20:12:53 +08:00
|
|
|
{
|
|
|
|
int v;
|
2021-10-22 13:39:54 +08:00
|
|
|
for (v = TOK_IDENT; v < tok_ident; ++v)
|
|
|
|
define_print(s1, v);
|
2016-05-05 20:12:53 +08:00
|
|
|
}
|
|
|
|
|
2016-10-02 03:52:11 +08:00
|
|
|
/* Add a space between tokens a and b to avoid unwanted textual pasting */
|
|
|
|
static int pp_need_space(int a, int b)
|
2016-05-05 04:37:11 +08:00
|
|
|
{
|
2016-10-02 03:52:11 +08:00
|
|
|
return 'E' == a ? '+' == b || '-' == b
|
|
|
|
: '+' == a ? TOK_INC == b || '+' == b
|
|
|
|
: '-' == a ? TOK_DEC == b || '-' == b
|
|
|
|
: a >= TOK_IDENT ? b >= TOK_IDENT
|
2017-07-09 10:30:36 +08:00
|
|
|
: a == TOK_PPNUM ? b >= TOK_IDENT
|
2016-10-02 03:52:11 +08:00
|
|
|
: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* maybe hex like 0x1e */
|
|
|
|
static int pp_check_he0xE(int t, const char *p)
|
|
|
|
{
|
|
|
|
if (t == TOK_PPNUM && toup(strchr(p, 0)[-1]) == 'E')
|
|
|
|
return 'E';
|
|
|
|
return t;
|
2016-05-05 04:37:11 +08:00
|
|
|
}
|
|
|
|
|
2009-05-06 02:30:39 +08:00
|
|
|
/* Preprocess the current file */
|
2021-10-22 13:39:54 +08:00
|
|
|
ST_FUNC int tcc_preprocess(TCCState *s1)
|
2009-05-06 02:30:39 +08:00
|
|
|
{
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
BufferedFile **iptr;
|
|
|
|
int token_seen, spcs, level;
|
2016-10-02 03:52:11 +08:00
|
|
|
const char *p;
|
2017-07-21 04:21:27 +08:00
|
|
|
char white[400];
|
2009-05-06 02:30:39 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
parse_flags = PARSE_FLAG_PREPROCESS
|
|
|
|
| (parse_flags & PARSE_FLAG_ASM_FILE)
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
| PARSE_FLAG_LINEFEED
|
|
|
|
| PARSE_FLAG_SPACES
|
|
|
|
| PARSE_FLAG_ACCEPT_STRAYS
|
|
|
|
;
|
2016-05-12 16:25:50 +08:00
|
|
|
/* Credits to Fabrice Bellard's initial revision to demonstrate its
|
|
|
|
capability to compile and run itself, provided all numbers are
|
|
|
|
given as decimals. tcc -E -P10 will do. */
|
2021-10-22 13:39:54 +08:00
|
|
|
if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_P10)
|
|
|
|
parse_flags |= PARSE_FLAG_TOK_NUM, s1->Pflag = 1;
|
2016-05-12 16:25:50 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
if (s1->do_bench) {
|
2018-05-27 05:08:54 +08:00
|
|
|
/* for PP benchmarks */
|
2021-10-22 13:39:54 +08:00
|
|
|
do next(); while (tok != TOK_EOF);
|
2018-05-27 05:08:54 +08:00
|
|
|
return 0;
|
|
|
|
}
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
if (s1->dflag & 1) {
|
|
|
|
pp_debug_builtins(s1);
|
|
|
|
s1->dflag &= ~1;
|
2016-05-05 20:12:53 +08:00
|
|
|
}
|
|
|
|
|
2020-06-17 14:21:37 +08:00
|
|
|
token_seen = TOK_LINEFEED, spcs = 0, level = 0;
|
2021-10-22 13:39:54 +08:00
|
|
|
if (file->prev)
|
|
|
|
pp_line(s1, file->prev, level++);
|
|
|
|
pp_line(s1, file, level);
|
2009-05-06 02:30:39 +08:00
|
|
|
for (;;) {
|
2021-10-22 13:39:54 +08:00
|
|
|
iptr = s1->include_stack_ptr;
|
|
|
|
next();
|
|
|
|
if (tok == TOK_EOF)
|
2009-05-06 02:30:39 +08:00
|
|
|
break;
|
2017-07-21 04:21:27 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
level = s1->include_stack_ptr - iptr;
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
if (level) {
|
|
|
|
if (level > 0)
|
2021-10-22 13:39:54 +08:00
|
|
|
pp_line(s1, *iptr, 0);
|
|
|
|
pp_line(s1, file, level);
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
}
|
2021-10-22 13:39:54 +08:00
|
|
|
if (s1->dflag & 7) {
|
|
|
|
pp_debug_defines(s1);
|
|
|
|
if (s1->dflag & 4)
|
2016-05-05 20:12:53 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
if (is_space(tok)) {
|
2017-07-21 04:21:27 +08:00
|
|
|
if (spcs < sizeof white - 1)
|
2021-10-22 13:39:54 +08:00
|
|
|
white[spcs++] = tok;
|
2017-07-21 04:21:27 +08:00
|
|
|
continue;
|
2021-10-22 13:39:54 +08:00
|
|
|
} else if (tok == TOK_LINEFEED) {
|
2017-07-21 04:21:27 +08:00
|
|
|
spcs = 0;
|
|
|
|
if (token_seen == TOK_LINEFEED)
|
|
|
|
continue;
|
2021-10-22 13:39:54 +08:00
|
|
|
++file->line_ref;
|
2017-07-21 04:21:27 +08:00
|
|
|
} else if (token_seen == TOK_LINEFEED) {
|
2021-10-22 13:39:54 +08:00
|
|
|
pp_line(s1, file, 0);
|
|
|
|
} else if (spcs == 0 && pp_need_space(token_seen, tok)) {
|
2017-07-21 04:21:27 +08:00
|
|
|
white[spcs++] = ' ';
|
2009-05-06 02:30:39 +08:00
|
|
|
}
|
tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc54345949535524d01319e1ca6378b7c2c201
a715d7143d9d17da17e67fec6af1c01409a71a31
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
2015-05-09 20:29:39 +08:00
|
|
|
|
2021-10-22 13:39:54 +08:00
|
|
|
white[spcs] = 0, fputs(white, s1->ppfp), spcs = 0;
|
|
|
|
fputs(p = get_tok_str(tok, &tokc), s1->ppfp);
|
|
|
|
token_seen = pp_check_he0xE(tok, p);
|
2016-05-05 20:12:53 +08:00
|
|
|
}
|
|
|
|
return 0;
|
2016-04-13 19:32:51 +08:00
|
|
|
}
|
|
|
|
|
2016-05-05 20:12:53 +08:00
|
|
|
/* ------------------------------------------------------------------------- */
|