restore 2dd8587c2f32d17a2cd0443a60a614a3fa9bbe29
This commit is contained in:
		
							parent
							
								
									72f466c24c
								
							
						
					
					
						commit
						c6345b5a8a
					
				
					 6 changed files with 248 additions and 111 deletions
				
			
		
							
								
								
									
										6
									
								
								libtcc.c
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								libtcc.c
									
										
									
									
									
								
							| 
						 | 
					@ -868,6 +868,7 @@ LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym)
 | 
				
			||||||
static void tcc_cleanup(void)
 | 
					static void tcc_cleanup(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int i, n;
 | 
					    int i, n;
 | 
				
			||||||
 | 
					    CSym *def;
 | 
				
			||||||
    if (NULL == tcc_state)
 | 
					    if (NULL == tcc_state)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    tcc_state = NULL;
 | 
					    tcc_state = NULL;
 | 
				
			||||||
| 
						 | 
					@ -877,8 +878,11 @@ static void tcc_cleanup(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* free tokens */
 | 
					    /* free tokens */
 | 
				
			||||||
    n = tok_ident - TOK_IDENT;
 | 
					    n = tok_ident - TOK_IDENT;
 | 
				
			||||||
    for(i = 0; i < n; i++)
 | 
					    for(i = 0; i < n; i++){
 | 
				
			||||||
 | 
							def = &table_ident[i]->sym_define;
 | 
				
			||||||
 | 
							tcc_free(def->data);
 | 
				
			||||||
        tcc_free(table_ident[i]);
 | 
					        tcc_free(table_ident[i]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
    tcc_free(table_ident);
 | 
					    tcc_free(table_ident);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* free sym_pools */
 | 
					    /* free sym_pools */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										10
									
								
								tcc.h
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								tcc.h
									
										
									
									
									
								
							| 
						 | 
					@ -303,15 +303,22 @@
 | 
				
			||||||
#define VSTACK_SIZE         256
 | 
					#define VSTACK_SIZE         256
 | 
				
			||||||
#define STRING_MAX_SIZE     1024
 | 
					#define STRING_MAX_SIZE     1024
 | 
				
			||||||
#define PACK_STACK_SIZE     8
 | 
					#define PACK_STACK_SIZE     8
 | 
				
			||||||
 | 
					#define MACRO_STACK_SIZE    4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TOK_HASH_SIZE       8192 /* must be a power of two */
 | 
					#define TOK_HASH_SIZE       8192 /* must be a power of two */
 | 
				
			||||||
#define TOK_ALLOC_INCR      512  /* must be a power of two */
 | 
					#define TOK_ALLOC_INCR      512  /* must be a power of two */
 | 
				
			||||||
#define TOK_MAX_SIZE        4 /* token max size in int unit when stored in string */
 | 
					#define TOK_MAX_SIZE        4 /* token max size in int unit when stored in string */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct CSym {
 | 
				
			||||||
 | 
					    int off;
 | 
				
			||||||
 | 
					    int size;/* size in *sym */
 | 
				
			||||||
 | 
					    struct Sym **data; /* if non NULL, data has been malloced */
 | 
				
			||||||
 | 
					} CSym;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* token symbol management */
 | 
					/* token symbol management */
 | 
				
			||||||
typedef struct TokenSym {
 | 
					typedef struct TokenSym {
 | 
				
			||||||
    struct TokenSym *hash_next;
 | 
					    struct TokenSym *hash_next;
 | 
				
			||||||
    struct Sym *sym_define; /* direct pointer to define */
 | 
					    struct CSym sym_define; /* direct pointer to define */
 | 
				
			||||||
    struct Sym *sym_label; /* direct pointer to label */
 | 
					    struct Sym *sym_label; /* direct pointer to label */
 | 
				
			||||||
    struct Sym *sym_struct; /* direct pointer to structure */
 | 
					    struct Sym *sym_struct; /* direct pointer to structure */
 | 
				
			||||||
    struct Sym *sym_identifier; /* direct pointer to identifier */
 | 
					    struct Sym *sym_identifier; /* direct pointer to identifier */
 | 
				
			||||||
| 
						 | 
					@ -1125,6 +1132,7 @@ ST_DATA TokenSym **table_ident;
 | 
				
			||||||
                                        returned at eof */
 | 
					                                        returned at eof */
 | 
				
			||||||
#define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
 | 
					#define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
 | 
				
			||||||
#define PARSE_FLAG_SPACES       0x0010 /* next() returns space tokens (for -E) */
 | 
					#define PARSE_FLAG_SPACES       0x0010 /* next() returns space tokens (for -E) */
 | 
				
			||||||
 | 
					#define PARSE_FLAG_PACK         0x0020 /* #pragma pack */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ST_FUNC TokenSym *tok_alloc(const char *str, int len);
 | 
					ST_FUNC TokenSym *tok_alloc(const char *str, int len);
 | 
				
			||||||
ST_FUNC char *get_tok_str(int v, CValue *cv);
 | 
					ST_FUNC char *get_tok_str(int v, CValue *cv);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										288
									
								
								tccpp.c
									
										
									
									
									
								
							
							
						
						
									
										288
									
								
								tccpp.c
									
										
									
									
									
								
							| 
						 | 
					@ -234,7 +234,10 @@ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
 | 
				
			||||||
    ts = tcc_malloc(sizeof(TokenSym) + len);
 | 
					    ts = tcc_malloc(sizeof(TokenSym) + len);
 | 
				
			||||||
    table_ident[i] = ts;
 | 
					    table_ident[i] = ts;
 | 
				
			||||||
    ts->tok = tok_ident++;
 | 
					    ts->tok = tok_ident++;
 | 
				
			||||||
    ts->sym_define = NULL;
 | 
					    ts->sym_define.data = tcc_malloc(sizeof(Sym**));
 | 
				
			||||||
 | 
					    ts->sym_define.off = 0;
 | 
				
			||||||
 | 
					    ts->sym_define.data[0] = NULL;
 | 
				
			||||||
 | 
					    ts->sym_define.size = 1;
 | 
				
			||||||
    ts->sym_label = NULL;
 | 
					    ts->sym_label = NULL;
 | 
				
			||||||
    ts->sym_struct = NULL;
 | 
					    ts->sym_struct = NULL;
 | 
				
			||||||
    ts->sym_identifier = NULL;
 | 
					    ts->sym_identifier = NULL;
 | 
				
			||||||
| 
						 | 
					@ -1053,52 +1056,62 @@ static int macro_is_equal(const int *a, const int *b)
 | 
				
			||||||
ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg)
 | 
					ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Sym *s;
 | 
					    Sym *s;
 | 
				
			||||||
 | 
						CSym *def;
 | 
				
			||||||
    s = define_find(v);
 | 
					    s = define_find(v);
 | 
				
			||||||
    if (s && !macro_is_equal(s->d, str))
 | 
					    if (s && !macro_is_equal(s->d, str))
 | 
				
			||||||
        tcc_warning("%s redefined", get_tok_str(v, NULL));
 | 
					        tcc_warning("%s redefined", get_tok_str(v, NULL));
 | 
				
			||||||
 | 
					 | 
				
			||||||
    s = sym_push2(&define_stack, v, macro_type, 0);
 | 
					    s = sym_push2(&define_stack, v, macro_type, 0);
 | 
				
			||||||
    s->d = str;
 | 
					    s->d = str;
 | 
				
			||||||
    s->next = first_arg;
 | 
					    s->next = first_arg;
 | 
				
			||||||
    table_ident[v - TOK_IDENT]->sym_define = s;
 | 
					    def = &table_ident[v - TOK_IDENT]->sym_define;
 | 
				
			||||||
 | 
						def->data[def->off] = s;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* undefined a define symbol. Its name is just set to zero */
 | 
					/* undefined a define symbol. Its name is just set to zero */
 | 
				
			||||||
ST_FUNC void define_undef(Sym *s)
 | 
					ST_FUNC void define_undef(Sym *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int v;
 | 
					    int v;
 | 
				
			||||||
    v = s->v;
 | 
						CSym *def;
 | 
				
			||||||
    if (v >= TOK_IDENT && v < tok_ident)
 | 
					    v = s->v - TOK_IDENT;
 | 
				
			||||||
        table_ident[v - TOK_IDENT]->sym_define = NULL;
 | 
					    if ((unsigned)v < (unsigned)(tok_ident - TOK_IDENT)){
 | 
				
			||||||
    s->v = 0;
 | 
							def = &table_ident[v]->sym_define;
 | 
				
			||||||
 | 
							def->data[def->off] = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ST_INLN Sym *define_find(int v)
 | 
					ST_INLN Sym *define_find(int v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    CSym *def;
 | 
				
			||||||
    v -= TOK_IDENT;
 | 
					    v -= TOK_IDENT;
 | 
				
			||||||
    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
 | 
					    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    return table_ident[v]->sym_define;
 | 
						def = &table_ident[v]->sym_define;
 | 
				
			||||||
 | 
					    return def->data[def->off];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* free define stack until top reaches 'b' */
 | 
					/* free define stack until top reaches 'b' */
 | 
				
			||||||
ST_FUNC void free_defines(Sym *b)
 | 
					ST_FUNC void free_defines(Sym *b)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Sym *top, *top1;
 | 
					    Sym *top, *tmp;
 | 
				
			||||||
    int v;
 | 
					    int v;
 | 
				
			||||||
 | 
						CSym *def;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    top = define_stack;
 | 
					    top = define_stack;
 | 
				
			||||||
    while (top != b) {
 | 
					    while (top != b) {
 | 
				
			||||||
        top1 = top->prev;
 | 
					        tmp = top->prev;
 | 
				
			||||||
        /* do not free args or predefined defines */
 | 
					        /* do not free args or predefined defines */
 | 
				
			||||||
        if (top->d)
 | 
					        if (top->d)
 | 
				
			||||||
            tok_str_free(top->d);
 | 
					            tok_str_free(top->d);
 | 
				
			||||||
        v = top->v;
 | 
					        v = top->v - TOK_IDENT;
 | 
				
			||||||
        if (v >= TOK_IDENT && v < tok_ident)
 | 
					        if ((unsigned)v < (unsigned)(tok_ident - TOK_IDENT)){
 | 
				
			||||||
            table_ident[v - TOK_IDENT]->sym_define = NULL;
 | 
								def = &table_ident[v]->sym_define;
 | 
				
			||||||
 | 
								if(def->off)
 | 
				
			||||||
 | 
									def->off = 0;
 | 
				
			||||||
 | 
					            if(def->data[0])
 | 
				
			||||||
 | 
									def->data[0] = NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
        sym_free(top);
 | 
					        sym_free(top);
 | 
				
			||||||
        top = top1;
 | 
					        top = tmp;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    define_stack = b;
 | 
					    define_stack = b;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1339,64 +1352,16 @@ static inline void add_cached_include(TCCState *s1, const char *filename, int if
 | 
				
			||||||
    s1->cached_includes_hash[h] = s1->nb_cached_includes;
 | 
					    s1->cached_includes_hash[h] = s1->nb_cached_includes;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void pragma_parse(TCCState *s1)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int val;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    next();
 | 
					 | 
				
			||||||
    if (tok == TOK_pack) {
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
          This may be:
 | 
					 | 
				
			||||||
          #pragma pack(1) // set
 | 
					 | 
				
			||||||
          #pragma pack() // reset to default
 | 
					 | 
				
			||||||
          #pragma pack(push,1) // push & set
 | 
					 | 
				
			||||||
          #pragma pack(pop) // restore previous
 | 
					 | 
				
			||||||
        */
 | 
					 | 
				
			||||||
        next();
 | 
					 | 
				
			||||||
        skip('(');
 | 
					 | 
				
			||||||
        if (tok == TOK_ASM_pop) {
 | 
					 | 
				
			||||||
            next();
 | 
					 | 
				
			||||||
            if (s1->pack_stack_ptr <= s1->pack_stack) {
 | 
					 | 
				
			||||||
            stk_error:
 | 
					 | 
				
			||||||
                tcc_error("out of pack stack");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            s1->pack_stack_ptr--;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            val = 0;
 | 
					 | 
				
			||||||
            if (tok != ')') {
 | 
					 | 
				
			||||||
                if (tok == TOK_ASM_push) {
 | 
					 | 
				
			||||||
                    next();
 | 
					 | 
				
			||||||
                    if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1)
 | 
					 | 
				
			||||||
                        goto stk_error;
 | 
					 | 
				
			||||||
                    s1->pack_stack_ptr++;
 | 
					 | 
				
			||||||
                    skip(',');
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                if (tok != TOK_CINT) {
 | 
					 | 
				
			||||||
                pack_error:
 | 
					 | 
				
			||||||
                    tcc_error("invalid pack pragma");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                val = tokc.i;
 | 
					 | 
				
			||||||
                if (val < 1 || val > 16 || (val & (val - 1)) != 0)
 | 
					 | 
				
			||||||
                    goto pack_error;
 | 
					 | 
				
			||||||
                next();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            *s1->pack_stack_ptr = val;
 | 
					 | 
				
			||||||
            skip(')');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* is_bof is true if first non space token at beginning of file */
 | 
					/* is_bof is true if first non space token at beginning of file */
 | 
				
			||||||
ST_FUNC void preprocess(int is_bof)
 | 
					ST_FUNC void preprocess(int is_bof)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    TCCState *s1 = tcc_state;
 | 
					    TCCState *s1 = tcc_state;
 | 
				
			||||||
    int i, c, n, saved_parse_flags;
 | 
					    int i, c, n, saved_parse_flags;
 | 
				
			||||||
    char buf[1024], *q;
 | 
					    uint8_t buf[1024], *p;
 | 
				
			||||||
    Sym *s;
 | 
					    Sym *s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    saved_parse_flags = parse_flags;
 | 
					    saved_parse_flags = parse_flags;
 | 
				
			||||||
    parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | 
 | 
					    parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_LINEFEED;
 | 
				
			||||||
        PARSE_FLAG_LINEFEED;
 | 
					 | 
				
			||||||
    next_nomacro();
 | 
					    next_nomacro();
 | 
				
			||||||
redo:
 | 
					redo:
 | 
				
			||||||
    switch(tok) {
 | 
					    switch(tok) {
 | 
				
			||||||
| 
						 | 
					@ -1423,17 +1388,19 @@ ST_FUNC void preprocess(int is_bof)
 | 
				
			||||||
            c = ch;
 | 
					            c = ch;
 | 
				
			||||||
read_name:
 | 
					read_name:
 | 
				
			||||||
            inp();
 | 
					            inp();
 | 
				
			||||||
            q = buf;
 | 
					            p = buf;
 | 
				
			||||||
            while (ch != c && ch != '\n' && ch != CH_EOF) {
 | 
					            while (ch != c && ch != '\n' && ch != CH_EOF) {
 | 
				
			||||||
                if ((q - buf) < sizeof(buf) - 1)
 | 
					                if ((p - buf) < sizeof(buf) - 1)
 | 
				
			||||||
                    *q++ = ch;
 | 
					                    *p++ = ch;
 | 
				
			||||||
                if (ch == '\\') {
 | 
					                if (ch == '\\') {
 | 
				
			||||||
                    if (handle_stray_noerror() == 0)
 | 
					                    if (handle_stray_noerror() == 0)
 | 
				
			||||||
                        --q;
 | 
					                        --p;
 | 
				
			||||||
                } else
 | 
					                } else
 | 
				
			||||||
                    inp();
 | 
					                    inp();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            *q = '\0';
 | 
								if (ch != c)
 | 
				
			||||||
 | 
									goto include_syntax;
 | 
				
			||||||
 | 
					            *p = '\0';
 | 
				
			||||||
            minp();
 | 
					            minp();
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
            /* eat all spaces and comments after include */
 | 
					            /* eat all spaces and comments after include */
 | 
				
			||||||
| 
						 | 
					@ -1471,6 +1438,8 @@ ST_FUNC void preprocess(int is_bof)
 | 
				
			||||||
                c = '>';
 | 
					                c = '>';
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
							if(!buf[0])
 | 
				
			||||||
 | 
								tcc_error(" empty filename in #include");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
 | 
					        if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
 | 
				
			||||||
            tcc_error("#include recursion too deep");
 | 
					            tcc_error("#include recursion too deep");
 | 
				
			||||||
| 
						 | 
					@ -1537,8 +1506,7 @@ include_trynext:
 | 
				
			||||||
            printf("%s: including %s\n", file->prev->filename, file->filename);
 | 
					            printf("%s: including %s\n", file->prev->filename, file->filename);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
            /* update target deps */
 | 
					            /* update target deps */
 | 
				
			||||||
            dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
 | 
					            dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps, tcc_strdup(buf1));
 | 
				
			||||||
                    tcc_strdup(buf1));
 | 
					 | 
				
			||||||
            /* push current file in stack */
 | 
					            /* push current file in stack */
 | 
				
			||||||
            ++s1->include_stack_ptr;
 | 
					            ++s1->include_stack_ptr;
 | 
				
			||||||
            /* add include file debug info */
 | 
					            /* add include file debug info */
 | 
				
			||||||
| 
						 | 
					@ -1571,7 +1539,7 @@ include_done:
 | 
				
			||||||
                file->ifndef_macro = tok;
 | 
					                file->ifndef_macro = tok;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        c = (define_find(tok) != 0) ^ c;
 | 
					        c = !!define_find(tok) ^ c;
 | 
				
			||||||
    do_if:
 | 
					    do_if:
 | 
				
			||||||
        if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
 | 
					        if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
 | 
				
			||||||
            tcc_error("memory full (ifdef)");
 | 
					            tcc_error("memory full (ifdef)");
 | 
				
			||||||
| 
						 | 
					@ -1618,11 +1586,11 @@ include_done:
 | 
				
			||||||
            /* need to set to zero to avoid false matches if another
 | 
					            /* need to set to zero to avoid false matches if another
 | 
				
			||||||
               #ifndef at middle of file */
 | 
					               #ifndef at middle of file */
 | 
				
			||||||
            file->ifndef_macro = 0;
 | 
					            file->ifndef_macro = 0;
 | 
				
			||||||
            while (tok != TOK_LINEFEED)
 | 
					 | 
				
			||||||
                next_nomacro();
 | 
					 | 
				
			||||||
            tok_flags |= TOK_FLAG_ENDIF;
 | 
					            tok_flags |= TOK_FLAG_ENDIF;
 | 
				
			||||||
            goto the_end;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
							next_nomacro();
 | 
				
			||||||
 | 
							if (tok != TOK_LINEFEED)
 | 
				
			||||||
 | 
								tcc_warning("Ignoring: %s", get_tok_str(tok, &tokc));
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case TOK_LINE:
 | 
					    case TOK_LINE:
 | 
				
			||||||
        next();
 | 
					        next();
 | 
				
			||||||
| 
						 | 
					@ -1633,8 +1601,7 @@ include_done:
 | 
				
			||||||
        if (tok != TOK_LINEFEED) {
 | 
					        if (tok != TOK_LINEFEED) {
 | 
				
			||||||
            if (tok != TOK_STR)
 | 
					            if (tok != TOK_STR)
 | 
				
			||||||
                tcc_error("#line");
 | 
					                tcc_error("#line");
 | 
				
			||||||
            pstrcpy(file->filename, sizeof(file->filename), 
 | 
					            pstrcpy(file->filename, sizeof(file->filename), (char *)tokc.cstr->data);
 | 
				
			||||||
                    (char *)tokc.cstr->data);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case TOK_ERROR:
 | 
					    case TOK_ERROR:
 | 
				
			||||||
| 
						 | 
					@ -1642,24 +1609,161 @@ include_done:
 | 
				
			||||||
        c = tok;
 | 
					        c = tok;
 | 
				
			||||||
        ch = file->buf_ptr[0];
 | 
					        ch = file->buf_ptr[0];
 | 
				
			||||||
        skip_spaces();
 | 
					        skip_spaces();
 | 
				
			||||||
        q = buf;
 | 
					        p = buf;
 | 
				
			||||||
        while (ch != '\n' && ch != CH_EOF) {
 | 
					        while (ch != '\n' && ch != CH_EOF) {
 | 
				
			||||||
            if ((q - buf) < sizeof(buf) - 1)
 | 
					            if ((p - buf) < sizeof(buf) - 1)
 | 
				
			||||||
                *q++ = ch;
 | 
					                *p++ = ch;
 | 
				
			||||||
            if (ch == '\\') {
 | 
					            if (ch == '\\') {
 | 
				
			||||||
                if (handle_stray_noerror() == 0)
 | 
					                if (handle_stray_noerror() == 0)
 | 
				
			||||||
                    --q;
 | 
					                    --p;
 | 
				
			||||||
            } else
 | 
					            } else
 | 
				
			||||||
                inp();
 | 
					                inp();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        *q = '\0';
 | 
					        *p = '\0';
 | 
				
			||||||
        if (c == TOK_ERROR)
 | 
					        if (c == TOK_ERROR)
 | 
				
			||||||
            tcc_error("#error %s", buf);
 | 
					            tcc_error("#error %s", buf);
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            tcc_warning("#warning %s", buf);
 | 
					            tcc_warning("#warning %s", buf);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case TOK_PRAGMA:
 | 
					    case TOK_PRAGMA:
 | 
				
			||||||
        pragma_parse(s1);
 | 
							next();
 | 
				
			||||||
 | 
							if (tok == TOK_pack && parse_flags & PARSE_FLAG_PACK) {
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
 | 
								  This may be:
 | 
				
			||||||
 | 
								  #pragma pack(1) // set
 | 
				
			||||||
 | 
								  #pragma pack() // reset to default
 | 
				
			||||||
 | 
								  #pragma pack(push,1) // push & set
 | 
				
			||||||
 | 
								  #pragma pack(pop) // restore previous
 | 
				
			||||||
 | 
								*/
 | 
				
			||||||
 | 
								next();
 | 
				
			||||||
 | 
								skip('(');
 | 
				
			||||||
 | 
								if (tok == TOK_ASM_pop) {
 | 
				
			||||||
 | 
									next();
 | 
				
			||||||
 | 
									if (s1->pack_stack_ptr <= s1->pack_stack) {
 | 
				
			||||||
 | 
					stk_error:
 | 
				
			||||||
 | 
										tcc_error("out of pack stack");
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									s1->pack_stack_ptr--;
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									int val = 0;
 | 
				
			||||||
 | 
									if (tok != ')') {
 | 
				
			||||||
 | 
										if (tok == TOK_ASM_push) {
 | 
				
			||||||
 | 
											next();
 | 
				
			||||||
 | 
											s1->pack_stack_ptr++;
 | 
				
			||||||
 | 
											if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE)
 | 
				
			||||||
 | 
												goto stk_error;
 | 
				
			||||||
 | 
											skip(',');
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if (tok != TOK_CINT) {
 | 
				
			||||||
 | 
					pack_error:
 | 
				
			||||||
 | 
											tcc_error("invalid pack pragma");
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										val = tokc.i;
 | 
				
			||||||
 | 
										if (val < 1 || val > 16)
 | 
				
			||||||
 | 
											goto pack_error;
 | 
				
			||||||
 | 
										if (val < 1 || val > 16)
 | 
				
			||||||
 | 
											tcc_error("Value must be greater than 1 is less than or equal to 16");
 | 
				
			||||||
 | 
										if ((val & (val - 1)) != 0)
 | 
				
			||||||
 | 
											tcc_error("Value must be a power of 2 curtain");
 | 
				
			||||||
 | 
										next();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									*s1->pack_stack_ptr = val;
 | 
				
			||||||
 | 
									skip(')');
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}else if (tok == TOK_PUSH_MACRO || tok == TOK_POP_MACRO) {
 | 
				
			||||||
 | 
								TokenSym *ts;
 | 
				
			||||||
 | 
								CSym *def;
 | 
				
			||||||
 | 
								uint8_t *p1;
 | 
				
			||||||
 | 
								int len, t;
 | 
				
			||||||
 | 
								t = tok;
 | 
				
			||||||
 | 
								ch = file->buf_ptr[0];
 | 
				
			||||||
 | 
								skip_spaces();
 | 
				
			||||||
 | 
								if (ch != '(')
 | 
				
			||||||
 | 
									goto macro_xxx_syntax;
 | 
				
			||||||
 | 
								/* XXX: incorrect if comments : use next_nomacro with a special mode */
 | 
				
			||||||
 | 
								inp();
 | 
				
			||||||
 | 
								skip_spaces();
 | 
				
			||||||
 | 
								if (ch == '\"'){
 | 
				
			||||||
 | 
									inp();
 | 
				
			||||||
 | 
									p = buf;
 | 
				
			||||||
 | 
									while (ch != '\"' && ch != '\n' && ch != CH_EOF) {
 | 
				
			||||||
 | 
										if ((p - buf) < sizeof(buf) - 1)
 | 
				
			||||||
 | 
											*p++ = ch;
 | 
				
			||||||
 | 
										if (ch == CH_EOB) {
 | 
				
			||||||
 | 
											--p;
 | 
				
			||||||
 | 
											handle_stray();
 | 
				
			||||||
 | 
										}else
 | 
				
			||||||
 | 
											inp();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if(ch != '\"')
 | 
				
			||||||
 | 
										goto macro_xxx_syntax;
 | 
				
			||||||
 | 
									*p = '\0';
 | 
				
			||||||
 | 
									minp();
 | 
				
			||||||
 | 
									next();
 | 
				
			||||||
 | 
								}else{
 | 
				
			||||||
 | 
									/* computed #pragma macro_xxx for #define xxx */
 | 
				
			||||||
 | 
									next();
 | 
				
			||||||
 | 
									buf[0] = '\0';
 | 
				
			||||||
 | 
									while (tok != ')') {
 | 
				
			||||||
 | 
										if (tok != TOK_STR) {
 | 
				
			||||||
 | 
										macro_xxx_syntax:
 | 
				
			||||||
 | 
											tcc_error("'macro_xxx' expects (\"NAME\")");
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
 | 
				
			||||||
 | 
										next();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								skip (')');
 | 
				
			||||||
 | 
								if(!buf[0])
 | 
				
			||||||
 | 
									tcc_error(" empty string in #pragma");
 | 
				
			||||||
 | 
								/* find TokenSym */
 | 
				
			||||||
 | 
								p = buf;
 | 
				
			||||||
 | 
								while (is_space(*p))
 | 
				
			||||||
 | 
									p++;
 | 
				
			||||||
 | 
								p1 = p;
 | 
				
			||||||
 | 
								for(;;){
 | 
				
			||||||
 | 
					                if (!isidnum_table[p[0] - CH_EOF])
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
									++p;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								len = p - p1;
 | 
				
			||||||
 | 
								while (is_space(*p))
 | 
				
			||||||
 | 
									p++;
 | 
				
			||||||
 | 
								if(!p) //'\0'
 | 
				
			||||||
 | 
									tcc_error("unrecognized string: %s", buf);
 | 
				
			||||||
 | 
								ts = tok_alloc(p1, len);
 | 
				
			||||||
 | 
								if(ts){
 | 
				
			||||||
 | 
									def = &ts->sym_define;
 | 
				
			||||||
 | 
									if(t == TOK_PUSH_MACRO){
 | 
				
			||||||
 | 
										void *tmp = def->data[def->off];
 | 
				
			||||||
 | 
										if(tmp){
 | 
				
			||||||
 | 
											def->off++;
 | 
				
			||||||
 | 
											if(def->off >= def->size){
 | 
				
			||||||
 | 
												int size = def->size;
 | 
				
			||||||
 | 
												size *= 2;
 | 
				
			||||||
 | 
												if (size >= MACRO_STACK_SIZE)
 | 
				
			||||||
 | 
													tcc_error("stack full");
 | 
				
			||||||
 | 
												def->data = tcc_realloc(def->data, size*sizeof(Sym**));
 | 
				
			||||||
 | 
												def->size = size;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											def->data[def->off] = tmp;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}else{
 | 
				
			||||||
 | 
										if(def->off){
 | 
				
			||||||
 | 
											--def->off;
 | 
				
			||||||
 | 
										}else{
 | 
				
			||||||
 | 
											tcc_warning("stack empty");
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}else{
 | 
				
			||||||
 | 
								fputs("#pragma ", s1->ppfp);
 | 
				
			||||||
 | 
								while (tok != TOK_LINEFEED){
 | 
				
			||||||
 | 
									fputs(get_tok_str(tok, &tokc), s1->ppfp);
 | 
				
			||||||
 | 
									next();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								goto the_end;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_PPNUM) {
 | 
					        if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_PPNUM) {
 | 
				
			||||||
| 
						 | 
					@ -3141,7 +3245,8 @@ ST_FUNC int tcc_preprocess(TCCState *s1)
 | 
				
			||||||
    line_ref = 0;
 | 
					    line_ref = 0;
 | 
				
			||||||
    file_ref = NULL;
 | 
					    file_ref = NULL;
 | 
				
			||||||
    iptr = s1->include_stack_ptr;
 | 
					    iptr = s1->include_stack_ptr;
 | 
				
			||||||
 | 
						tok = TOK_LINEFEED;	/* print line */
 | 
				
			||||||
 | 
						goto print_line;
 | 
				
			||||||
    for (;;) {
 | 
					    for (;;) {
 | 
				
			||||||
        next();
 | 
					        next();
 | 
				
			||||||
        if (tok == TOK_EOF) {
 | 
					        if (tok == TOK_EOF) {
 | 
				
			||||||
| 
						 | 
					@ -3149,11 +3254,11 @@ ST_FUNC int tcc_preprocess(TCCState *s1)
 | 
				
			||||||
        } else if (file != file_ref) {
 | 
					        } else if (file != file_ref) {
 | 
				
			||||||
            goto print_line;
 | 
					            goto print_line;
 | 
				
			||||||
        } else if (tok == TOK_LINEFEED) {
 | 
					        } else if (tok == TOK_LINEFEED) {
 | 
				
			||||||
            if (!token_seen)
 | 
					            if (token_seen)
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            ++line_ref;
 | 
					            ++line_ref;
 | 
				
			||||||
            token_seen = 0;
 | 
					            token_seen = 1;
 | 
				
			||||||
        } else if (!token_seen) {
 | 
					        } else if (token_seen) {
 | 
				
			||||||
            d = file->line_num - line_ref;
 | 
					            d = file->line_num - line_ref;
 | 
				
			||||||
            if (file != file_ref || d < 0 || d >= 8) {
 | 
					            if (file != file_ref || d < 0 || d >= 8) {
 | 
				
			||||||
print_line:
 | 
					print_line:
 | 
				
			||||||
| 
						 | 
					@ -3161,8 +3266,7 @@ print_line:
 | 
				
			||||||
                s = iptr_new > iptr ? " 1"
 | 
					                s = iptr_new > iptr ? " 1"
 | 
				
			||||||
                  : iptr_new < iptr ? " 2"
 | 
					                  : iptr_new < iptr ? " 2"
 | 
				
			||||||
                  : iptr_new > s1->include_stack ? " 3"
 | 
					                  : iptr_new > s1->include_stack ? " 3"
 | 
				
			||||||
                  : ""
 | 
					                  : "";
 | 
				
			||||||
                  ;
 | 
					 | 
				
			||||||
                iptr = iptr_new;
 | 
					                iptr = iptr_new;
 | 
				
			||||||
                fprintf(s1->ppfp, "# %d \"%s\"%s\n", file->line_num, file->filename, s);
 | 
					                fprintf(s1->ppfp, "# %d \"%s\"%s\n", file->line_num, file->filename, s);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
| 
						 | 
					@ -3170,8 +3274,8 @@ print_line:
 | 
				
			||||||
                    fputs("\n", s1->ppfp), --d;
 | 
					                    fputs("\n", s1->ppfp), --d;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            line_ref = (file_ref = file)->line_num;
 | 
					            line_ref = (file_ref = file)->line_num;
 | 
				
			||||||
            token_seen = tok != TOK_LINEFEED;
 | 
					            token_seen = tok == TOK_LINEFEED;
 | 
				
			||||||
            if (!token_seen)
 | 
					            if (token_seen)
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        fputs(get_tok_str(tok, &tokc), s1->ppfp);
 | 
					        fputs(get_tok_str(tok, &tokc), s1->ppfp);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								tcctok.h
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								tcctok.h
									
										
									
									
									
								
							| 
						 | 
					@ -138,6 +138,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* pragma */
 | 
					/* pragma */
 | 
				
			||||||
     DEF(TOK_pack, "pack")
 | 
					     DEF(TOK_pack, "pack")
 | 
				
			||||||
 | 
					     DEF(TOK_PUSH_MACRO, "push_macro")
 | 
				
			||||||
 | 
						 DEF(TOK_POP_MACRO, "pop_macro")
 | 
				
			||||||
#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_X86_64)
 | 
					#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_X86_64)
 | 
				
			||||||
     /* already defined for assembler */
 | 
					     /* already defined for assembler */
 | 
				
			||||||
     DEF(TOK_ASM_push, "push")
 | 
					     DEF(TOK_ASM_push, "push")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -379,6 +379,23 @@ comment
 | 
				
			||||||
    /* And again when the name and parenthes are separated by a
 | 
					    /* And again when the name and parenthes are separated by a
 | 
				
			||||||
       comment.  */
 | 
					       comment.  */
 | 
				
			||||||
    TEST2 /* the comment */ ();
 | 
					    TEST2 /* the comment */ ();
 | 
				
			||||||
 | 
					    /* macro_push and macro_pop test */
 | 
				
			||||||
 | 
						#define MACRO_TEST "macro_test1\n"
 | 
				
			||||||
 | 
						#pragma push_macro("MACRO_TEST")
 | 
				
			||||||
 | 
						#undef MACRO_TEST
 | 
				
			||||||
 | 
						#define MACRO_TEST "macro_test2\n"
 | 
				
			||||||
 | 
						printf(MACRO_TEST);
 | 
				
			||||||
 | 
						#pragma pop_macro("MACRO_TEST")
 | 
				
			||||||
 | 
						printf(MACRO_TEST);
 | 
				
			||||||
 | 
					/* gcc does not support
 | 
				
			||||||
 | 
						#define MACRO_TEST_MACRO "MACRO_TEST"
 | 
				
			||||||
 | 
						#pragma push_macro(MACRO_TEST_MACRO)
 | 
				
			||||||
 | 
						#undef MACRO_TEST
 | 
				
			||||||
 | 
						#define MACRO_TEST "macro_test3\n"
 | 
				
			||||||
 | 
						printf(MACRO_TEST);
 | 
				
			||||||
 | 
						#pragma pop_macro(MACRO_TEST_MACRO)
 | 
				
			||||||
 | 
						printf(MACRO_TEST);
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2155,7 +2172,8 @@ void whitespace_test(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char *str;
 | 
					    char *str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if 1
 | 
					
 | 
				
			||||||
 | 
					#if 1
 | 
				
			||||||
    pri\
 | 
					    pri\
 | 
				
			||||||
ntf("whitspace:\n");
 | 
					ntf("whitspace:\n");
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -2178,7 +2196,8 @@ ntf("min=%d\n", 4);
 | 
				
			||||||
";
 | 
					";
 | 
				
			||||||
    printf("len1=%d str[0]=%d\n", strlen(str), str[0]);
 | 
					    printf("len1=%d str[0]=%d\n", strlen(str), str[0]);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    printf("len1=%d\n", strlen("
a
 | 
					    printf("len1=%d\n", strlen("
 | 
				
			||||||
 | 
					a
 | 
				
			||||||
"));
 | 
					"));
 | 
				
			||||||
#endif /* ACCEPT_CR_IN_STRINGS */
 | 
					#endif /* ACCEPT_CR_IN_STRINGS */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue