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)
 | 
			
		||||
{
 | 
			
		||||
    int i, n;
 | 
			
		||||
    CSym *def;
 | 
			
		||||
    if (NULL == tcc_state)
 | 
			
		||||
        return;
 | 
			
		||||
    tcc_state = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -877,8 +878,11 @@ static void tcc_cleanup(void)
 | 
			
		|||
 | 
			
		||||
    /* free tokens */
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
    /* free sym_pools */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								tcc.h
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								tcc.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -303,15 +303,22 @@
 | 
			
		|||
#define VSTACK_SIZE         256
 | 
			
		||||
#define STRING_MAX_SIZE     1024
 | 
			
		||||
#define PACK_STACK_SIZE     8
 | 
			
		||||
#define MACRO_STACK_SIZE    4
 | 
			
		||||
 | 
			
		||||
#define TOK_HASH_SIZE       8192 /* 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 */
 | 
			
		||||
 | 
			
		||||
typedef struct CSym {
 | 
			
		||||
    int off;
 | 
			
		||||
    int size;/* size in *sym */
 | 
			
		||||
    struct Sym **data; /* if non NULL, data has been malloced */
 | 
			
		||||
} CSym;
 | 
			
		||||
 | 
			
		||||
/* token symbol management */
 | 
			
		||||
typedef struct TokenSym {
 | 
			
		||||
    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_struct; /* direct pointer to structure */
 | 
			
		||||
    struct Sym *sym_identifier; /* direct pointer to identifier */
 | 
			
		||||
| 
						 | 
				
			
			@ -1125,6 +1132,7 @@ ST_DATA TokenSym **table_ident;
 | 
			
		|||
                                        returned at eof */
 | 
			
		||||
#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_PACK         0x0020 /* #pragma pack */
 | 
			
		||||
 | 
			
		||||
ST_FUNC TokenSym *tok_alloc(const char *str, int len);
 | 
			
		||||
ST_FUNC char *get_tok_str(int v, CValue *cv);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										6
									
								
								tccgen.c
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								tccgen.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -5234,13 +5234,13 @@ static void init_putz(CType *t, Section *sec, unsigned long c, int size)
 | 
			
		|||
    } else {
 | 
			
		||||
        vpush_global_sym(&func_old_type, TOK_memset);
 | 
			
		||||
        vseti(VT_LOCAL, c);
 | 
			
		||||
#ifdef TCC_TARGET_ARM
 | 
			
		||||
#   ifdef TCC_TARGET_ARM
 | 
			
		||||
        vpushs(size);
 | 
			
		||||
        vpushi(0);
 | 
			
		||||
#else
 | 
			
		||||
#   else
 | 
			
		||||
        vpushi(0);
 | 
			
		||||
        vpushs(size);
 | 
			
		||||
#endif
 | 
			
		||||
#   endif
 | 
			
		||||
        gfunc_call(3);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										300
									
								
								tccpp.c
									
										
									
									
									
								
							
							
						
						
									
										300
									
								
								tccpp.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -234,7 +234,10 @@ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
 | 
			
		|||
    ts = tcc_malloc(sizeof(TokenSym) + len);
 | 
			
		||||
    table_ident[i] = ts;
 | 
			
		||||
    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_struct = 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)
 | 
			
		||||
{
 | 
			
		||||
    Sym *s;
 | 
			
		||||
 | 
			
		||||
	CSym *def;
 | 
			
		||||
    s = define_find(v);
 | 
			
		||||
    if (s && !macro_is_equal(s->d, str))
 | 
			
		||||
        tcc_warning("%s redefined", get_tok_str(v, NULL));
 | 
			
		||||
 | 
			
		||||
    s = sym_push2(&define_stack, v, macro_type, 0);
 | 
			
		||||
    s->d = str;
 | 
			
		||||
    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 */
 | 
			
		||||
ST_FUNC void define_undef(Sym *s)
 | 
			
		||||
{
 | 
			
		||||
    int v;
 | 
			
		||||
    v = s->v;
 | 
			
		||||
    if (v >= TOK_IDENT && v < tok_ident)
 | 
			
		||||
        table_ident[v - TOK_IDENT]->sym_define = NULL;
 | 
			
		||||
    s->v = 0;
 | 
			
		||||
	CSym *def;
 | 
			
		||||
    v = s->v - TOK_IDENT;
 | 
			
		||||
    if ((unsigned)v < (unsigned)(tok_ident - TOK_IDENT)){
 | 
			
		||||
		def = &table_ident[v]->sym_define;
 | 
			
		||||
		def->data[def->off] = NULL;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ST_INLN Sym *define_find(int v)
 | 
			
		||||
{
 | 
			
		||||
    CSym *def;
 | 
			
		||||
    v -= TOK_IDENT;
 | 
			
		||||
    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
 | 
			
		||||
        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' */
 | 
			
		||||
ST_FUNC void free_defines(Sym *b)
 | 
			
		||||
{
 | 
			
		||||
    Sym *top, *top1;
 | 
			
		||||
    Sym *top, *tmp;
 | 
			
		||||
    int v;
 | 
			
		||||
	CSym *def;
 | 
			
		||||
 | 
			
		||||
    top = define_stack;
 | 
			
		||||
    while (top != b) {
 | 
			
		||||
        top1 = top->prev;
 | 
			
		||||
        tmp = top->prev;
 | 
			
		||||
        /* do not free args or predefined defines */
 | 
			
		||||
        if (top->d)
 | 
			
		||||
            tok_str_free(top->d);
 | 
			
		||||
        v = top->v;
 | 
			
		||||
        if (v >= TOK_IDENT && v < tok_ident)
 | 
			
		||||
            table_ident[v - TOK_IDENT]->sym_define = NULL;
 | 
			
		||||
        v = top->v - TOK_IDENT;
 | 
			
		||||
        if ((unsigned)v < (unsigned)(tok_ident - TOK_IDENT)){
 | 
			
		||||
			def = &table_ident[v]->sym_define;
 | 
			
		||||
			if(def->off)
 | 
			
		||||
				def->off = 0;
 | 
			
		||||
            if(def->data[0])
 | 
			
		||||
				def->data[0] = NULL;
 | 
			
		||||
		}
 | 
			
		||||
        sym_free(top);
 | 
			
		||||
        top = top1;
 | 
			
		||||
        top = tmp;
 | 
			
		||||
    }
 | 
			
		||||
    define_stack = b;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1339,66 +1352,18 @@ static inline void add_cached_include(TCCState *s1, const char *filename, int if
 | 
			
		|||
    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 */
 | 
			
		||||
ST_FUNC void preprocess(int is_bof)
 | 
			
		||||
{
 | 
			
		||||
    TCCState *s1 = tcc_state;
 | 
			
		||||
    int i, c, n, saved_parse_flags;
 | 
			
		||||
    char buf[1024], *q;
 | 
			
		||||
    uint8_t buf[1024], *p;
 | 
			
		||||
    Sym *s;
 | 
			
		||||
 | 
			
		||||
    saved_parse_flags = parse_flags;
 | 
			
		||||
    parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | 
 | 
			
		||||
        PARSE_FLAG_LINEFEED;
 | 
			
		||||
    parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_LINEFEED;
 | 
			
		||||
    next_nomacro();
 | 
			
		||||
 redo:
 | 
			
		||||
redo:
 | 
			
		||||
    switch(tok) {
 | 
			
		||||
    case TOK_DEFINE:
 | 
			
		||||
        next_nomacro();
 | 
			
		||||
| 
						 | 
				
			
			@ -1421,19 +1386,21 @@ ST_FUNC void preprocess(int is_bof)
 | 
			
		|||
            goto read_name;
 | 
			
		||||
        } else if (ch == '\"') {
 | 
			
		||||
            c = ch;
 | 
			
		||||
        read_name:
 | 
			
		||||
read_name:
 | 
			
		||||
            inp();
 | 
			
		||||
            q = buf;
 | 
			
		||||
            p = buf;
 | 
			
		||||
            while (ch != c && ch != '\n' && ch != CH_EOF) {
 | 
			
		||||
                if ((q - buf) < sizeof(buf) - 1)
 | 
			
		||||
                    *q++ = ch;
 | 
			
		||||
                if ((p - buf) < sizeof(buf) - 1)
 | 
			
		||||
                    *p++ = ch;
 | 
			
		||||
                if (ch == '\\') {
 | 
			
		||||
                    if (handle_stray_noerror() == 0)
 | 
			
		||||
                        --q;
 | 
			
		||||
                        --p;
 | 
			
		||||
                } else
 | 
			
		||||
                    inp();
 | 
			
		||||
            }
 | 
			
		||||
            *q = '\0';
 | 
			
		||||
			if (ch != c)
 | 
			
		||||
				goto include_syntax;
 | 
			
		||||
            *p = '\0';
 | 
			
		||||
            minp();
 | 
			
		||||
#if 0
 | 
			
		||||
            /* eat all spaces and comments after include */
 | 
			
		||||
| 
						 | 
				
			
			@ -1471,6 +1438,8 @@ ST_FUNC void preprocess(int is_bof)
 | 
			
		|||
                c = '>';
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
		if(!buf[0])
 | 
			
		||||
			tcc_error(" empty filename in #include");
 | 
			
		||||
 | 
			
		||||
        if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
 | 
			
		||||
            tcc_error("#include recursion too deep");
 | 
			
		||||
| 
						 | 
				
			
			@ -1537,8 +1506,7 @@ include_trynext:
 | 
			
		|||
            printf("%s: including %s\n", file->prev->filename, file->filename);
 | 
			
		||||
#endif
 | 
			
		||||
            /* update target deps */
 | 
			
		||||
            dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
 | 
			
		||||
                    tcc_strdup(buf1));
 | 
			
		||||
            dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps, tcc_strdup(buf1));
 | 
			
		||||
            /* push current file in stack */
 | 
			
		||||
            ++s1->include_stack_ptr;
 | 
			
		||||
            /* add include file debug info */
 | 
			
		||||
| 
						 | 
				
			
			@ -1571,7 +1539,7 @@ include_done:
 | 
			
		|||
                file->ifndef_macro = tok;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        c = (define_find(tok) != 0) ^ c;
 | 
			
		||||
        c = !!define_find(tok) ^ c;
 | 
			
		||||
    do_if:
 | 
			
		||||
        if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
 | 
			
		||||
            tcc_error("memory full (ifdef)");
 | 
			
		||||
| 
						 | 
				
			
			@ -1595,12 +1563,12 @@ include_done:
 | 
			
		|||
            goto skip;
 | 
			
		||||
        c = expr_preprocess();
 | 
			
		||||
        s1->ifdef_stack_ptr[-1] = c;
 | 
			
		||||
    test_else:
 | 
			
		||||
test_else:
 | 
			
		||||
        if (s1->ifdef_stack_ptr == file->ifdef_stack_ptr + 1)
 | 
			
		||||
            file->ifndef_macro = 0;
 | 
			
		||||
    test_skip:
 | 
			
		||||
test_skip:
 | 
			
		||||
        if (!(c & 1)) {
 | 
			
		||||
        skip:
 | 
			
		||||
skip:
 | 
			
		||||
            preprocess_skip();
 | 
			
		||||
            is_bof = 0;
 | 
			
		||||
            goto redo;
 | 
			
		||||
| 
						 | 
				
			
			@ -1618,11 +1586,11 @@ include_done:
 | 
			
		|||
            /* need to set to zero to avoid false matches if another
 | 
			
		||||
               #ifndef at middle of file */
 | 
			
		||||
            file->ifndef_macro = 0;
 | 
			
		||||
            while (tok != TOK_LINEFEED)
 | 
			
		||||
                next_nomacro();
 | 
			
		||||
            tok_flags |= TOK_FLAG_ENDIF;
 | 
			
		||||
            goto the_end;
 | 
			
		||||
        }
 | 
			
		||||
		next_nomacro();
 | 
			
		||||
		if (tok != TOK_LINEFEED)
 | 
			
		||||
			tcc_warning("Ignoring: %s", get_tok_str(tok, &tokc));
 | 
			
		||||
        break;
 | 
			
		||||
    case TOK_LINE:
 | 
			
		||||
        next();
 | 
			
		||||
| 
						 | 
				
			
			@ -1633,8 +1601,7 @@ include_done:
 | 
			
		|||
        if (tok != TOK_LINEFEED) {
 | 
			
		||||
            if (tok != TOK_STR)
 | 
			
		||||
                tcc_error("#line");
 | 
			
		||||
            pstrcpy(file->filename, sizeof(file->filename), 
 | 
			
		||||
                    (char *)tokc.cstr->data);
 | 
			
		||||
            pstrcpy(file->filename, sizeof(file->filename), (char *)tokc.cstr->data);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case TOK_ERROR:
 | 
			
		||||
| 
						 | 
				
			
			@ -1642,24 +1609,161 @@ include_done:
 | 
			
		|||
        c = tok;
 | 
			
		||||
        ch = file->buf_ptr[0];
 | 
			
		||||
        skip_spaces();
 | 
			
		||||
        q = buf;
 | 
			
		||||
        p = buf;
 | 
			
		||||
        while (ch != '\n' && ch != CH_EOF) {
 | 
			
		||||
            if ((q - buf) < sizeof(buf) - 1)
 | 
			
		||||
                *q++ = ch;
 | 
			
		||||
            if ((p - buf) < sizeof(buf) - 1)
 | 
			
		||||
                *p++ = ch;
 | 
			
		||||
            if (ch == '\\') {
 | 
			
		||||
                if (handle_stray_noerror() == 0)
 | 
			
		||||
                    --q;
 | 
			
		||||
                    --p;
 | 
			
		||||
            } else
 | 
			
		||||
                inp();
 | 
			
		||||
        }
 | 
			
		||||
        *q = '\0';
 | 
			
		||||
        *p = '\0';
 | 
			
		||||
        if (c == TOK_ERROR)
 | 
			
		||||
            tcc_error("#error %s", buf);
 | 
			
		||||
        else
 | 
			
		||||
            tcc_warning("#warning %s", buf);
 | 
			
		||||
        break;
 | 
			
		||||
    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;
 | 
			
		||||
    default:
 | 
			
		||||
        if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_PPNUM) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1679,7 +1783,7 @@ include_done:
 | 
			
		|||
    /* ignore other preprocess commands or #! for C scripts */
 | 
			
		||||
    while (tok != TOK_LINEFEED)
 | 
			
		||||
        next_nomacro();
 | 
			
		||||
 the_end:
 | 
			
		||||
the_end:
 | 
			
		||||
    parse_flags = saved_parse_flags;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3141,7 +3245,8 @@ ST_FUNC int tcc_preprocess(TCCState *s1)
 | 
			
		|||
    line_ref = 0;
 | 
			
		||||
    file_ref = NULL;
 | 
			
		||||
    iptr = s1->include_stack_ptr;
 | 
			
		||||
 | 
			
		||||
	tok = TOK_LINEFEED;	/* print line */
 | 
			
		||||
	goto print_line;
 | 
			
		||||
    for (;;) {
 | 
			
		||||
        next();
 | 
			
		||||
        if (tok == TOK_EOF) {
 | 
			
		||||
| 
						 | 
				
			
			@ -3149,11 +3254,11 @@ ST_FUNC int tcc_preprocess(TCCState *s1)
 | 
			
		|||
        } else if (file != file_ref) {
 | 
			
		||||
            goto print_line;
 | 
			
		||||
        } else if (tok == TOK_LINEFEED) {
 | 
			
		||||
            if (!token_seen)
 | 
			
		||||
            if (token_seen)
 | 
			
		||||
                continue;
 | 
			
		||||
            ++line_ref;
 | 
			
		||||
            token_seen = 0;
 | 
			
		||||
        } else if (!token_seen) {
 | 
			
		||||
            token_seen = 1;
 | 
			
		||||
        } else if (token_seen) {
 | 
			
		||||
            d = file->line_num - line_ref;
 | 
			
		||||
            if (file != file_ref || d < 0 || d >= 8) {
 | 
			
		||||
print_line:
 | 
			
		||||
| 
						 | 
				
			
			@ -3161,8 +3266,7 @@ print_line:
 | 
			
		|||
                s = iptr_new > iptr ? " 1"
 | 
			
		||||
                  : iptr_new < iptr ? " 2"
 | 
			
		||||
                  : iptr_new > s1->include_stack ? " 3"
 | 
			
		||||
                  : ""
 | 
			
		||||
                  ;
 | 
			
		||||
                  : "";
 | 
			
		||||
                iptr = iptr_new;
 | 
			
		||||
                fprintf(s1->ppfp, "# %d \"%s\"%s\n", file->line_num, file->filename, s);
 | 
			
		||||
            } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -3170,8 +3274,8 @@ print_line:
 | 
			
		|||
                    fputs("\n", s1->ppfp), --d;
 | 
			
		||||
            }
 | 
			
		||||
            line_ref = (file_ref = file)->line_num;
 | 
			
		||||
            token_seen = tok != TOK_LINEFEED;
 | 
			
		||||
            if (!token_seen)
 | 
			
		||||
            token_seen = tok == TOK_LINEFEED;
 | 
			
		||||
            if (token_seen)
 | 
			
		||||
                continue;
 | 
			
		||||
        }
 | 
			
		||||
        fputs(get_tok_str(tok, &tokc), s1->ppfp);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								tcctok.h
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								tcctok.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -138,6 +138,8 @@
 | 
			
		|||
 | 
			
		||||
/* pragma */
 | 
			
		||||
     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)
 | 
			
		||||
     /* already defined for assembler */
 | 
			
		||||
     DEF(TOK_ASM_push, "push")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -379,6 +379,23 @@ comment
 | 
			
		|||
    /* And again when the name and parenthes are separated by a
 | 
			
		||||
       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;
 | 
			
		||||
 | 
			
		||||
#if 1
 | 
			
		||||
 | 
			
		||||
#if 1
 | 
			
		||||
    pri\
 | 
			
		||||
ntf("whitspace:\n");
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -2178,7 +2196,8 @@ ntf("min=%d\n", 4);
 | 
			
		|||
";
 | 
			
		||||
    printf("len1=%d str[0]=%d\n", strlen(str), str[0]);
 | 
			
		||||
#endif
 | 
			
		||||
    printf("len1=%d\n", strlen("
a
 | 
			
		||||
    printf("len1=%d\n", strlen("
 | 
			
		||||
a
 | 
			
		||||
"));
 | 
			
		||||
#endif /* ACCEPT_CR_IN_STRINGS */
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue