mirror of
https://github.com/mirror/tinycc.git
synced 2025-03-10 08:50:07 +08:00
CStrings leakless
avoid memory leaks with lost CStrings on stack after errors. tccpp.c: - use/abuse static Cstring tokcstr where possible tccgen.c: - use/abuse static Cstring initstr where possible tcc.h/libtcc.a: - add 'stk_data' array to track memory pointer on stack - add macros stk_push/pop() and cstr_new/free_s() tccasm.c: - use that - use char[16] instead of char* for op.constraint
This commit is contained in:
parent
40131b7e0f
commit
a045400501
8
libtcc.c
8
libtcc.c
@ -68,6 +68,9 @@
|
||||
/* XXX: get rid of this ASAP (or maybe not) */
|
||||
ST_DATA struct TCCState *tcc_state;
|
||||
TCC_SEM(static tcc_compile_sem);
|
||||
/* an array of pointers to memory to be free'd after errors */
|
||||
ST_DATA void** stk_data;
|
||||
ST_DATA int nb_stk_data;
|
||||
|
||||
/********************************************************/
|
||||
#ifdef _WIN32
|
||||
@ -609,8 +612,11 @@ static void error1(int mode, const char *fmt, va_list ap)
|
||||
cstr_free(&cs);
|
||||
if (mode != ERROR_WARN)
|
||||
s1->nb_errors++;
|
||||
if (mode == ERROR_ERROR && s1->error_set_jmp_enabled)
|
||||
if (mode == ERROR_ERROR && s1->error_set_jmp_enabled) {
|
||||
while (nb_stk_data)
|
||||
tcc_free(*(void**)stk_data[--nb_stk_data]);
|
||||
longjmp(s1->error_jmp_buf, 1);
|
||||
}
|
||||
}
|
||||
|
||||
LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc error_func)
|
||||
|
17
tcc.h
17
tcc.h
@ -495,6 +495,7 @@ typedef struct CString {
|
||||
int size; /* size in bytes */
|
||||
int size_allocated;
|
||||
void *data; /* either 'char *' or 'nwchar_t *' */
|
||||
struct CString *prev;
|
||||
} CString;
|
||||
|
||||
/* type definition */
|
||||
@ -733,7 +734,7 @@ typedef struct ExprValue {
|
||||
#define MAX_ASM_OPERANDS 30
|
||||
typedef struct ASMOperand {
|
||||
int id; /* GCC 3 optional identifier (0 if number only supported) */
|
||||
char *constraint;
|
||||
char constraint[16];
|
||||
char asm_str[16]; /* computed asm string for operand */
|
||||
SValue *vt; /* C value of the expression */
|
||||
int ref_index; /* if >= 0, gives reference to a output constraint */
|
||||
@ -1208,6 +1209,8 @@ enum tcc_token {
|
||||
/* ------------ libtcc.c ------------ */
|
||||
|
||||
ST_DATA struct TCCState *tcc_state;
|
||||
ST_DATA void** stk_data;
|
||||
ST_DATA int nb_stk_data;
|
||||
|
||||
/* public functions currently used by the tcc main function */
|
||||
ST_FUNC char *pstrcpy(char *buf, size_t buf_size, const char *s);
|
||||
@ -1257,11 +1260,17 @@ ST_FUNC void cstr_free(CString *cstr);
|
||||
ST_FUNC int cstr_printf(CString *cs, const char *fmt, ...) PRINTF_LIKE(2,3);
|
||||
ST_FUNC int cstr_vprintf(CString *cstr, const char *fmt, va_list ap);
|
||||
ST_FUNC void cstr_reset(CString *cstr);
|
||||
|
||||
ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen);
|
||||
ST_FUNC int tcc_open(TCCState *s1, const char *filename);
|
||||
ST_FUNC void tcc_close(void);
|
||||
|
||||
/* mark a memory pointer on stack for cleanup after errors */
|
||||
#define stk_push(p) dynarray_add(&stk_data, &nb_stk_data, p)
|
||||
#define stk_pop() (--nb_stk_data)
|
||||
/* mark CString on stack for cleanup errors */
|
||||
#define cstr_new_s(cstr) (cstr_new(cstr), stk_push(&(cstr)->data))
|
||||
#define cstr_free_s(cstr) (cstr_free(cstr), stk_pop())
|
||||
|
||||
ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags);
|
||||
/* flags: */
|
||||
#define AFF_PRINT_ERROR 0x10 /* print error if file not found */
|
||||
@ -1483,8 +1492,8 @@ ST_FUNC int type_size(CType *type, int *a);
|
||||
ST_FUNC void mk_pointer(CType *type);
|
||||
ST_FUNC void vstore(void);
|
||||
ST_FUNC void inc(int post, int c);
|
||||
ST_FUNC void parse_mult_str (CString *astr, const char *msg);
|
||||
ST_FUNC void parse_asm_str(CString *astr);
|
||||
ST_FUNC CString* parse_mult_str(const char *msg);
|
||||
ST_FUNC CString* parse_asm_str(void);
|
||||
ST_FUNC void indir(void);
|
||||
ST_FUNC void unary(void);
|
||||
ST_FUNC void gexpr(void);
|
||||
|
48
tccasm.c
48
tccasm.c
@ -1064,15 +1064,12 @@ ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands,
|
||||
}
|
||||
|
||||
static void subst_asm_operands(ASMOperand *operands, int nb_operands,
|
||||
CString *out_str, CString *in_str)
|
||||
CString *out_str, const char *str)
|
||||
{
|
||||
int c, index, modifier;
|
||||
const char *str;
|
||||
ASMOperand *op;
|
||||
SValue sv;
|
||||
|
||||
cstr_new(out_str);
|
||||
str = in_str->data;
|
||||
for(;;) {
|
||||
c = *str++;
|
||||
if (c == '%') {
|
||||
@ -1118,11 +1115,11 @@ static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr,
|
||||
{
|
||||
ASMOperand *op;
|
||||
int nb_operands;
|
||||
char* astr;
|
||||
|
||||
if (tok != ':') {
|
||||
nb_operands = *nb_operands_ptr;
|
||||
for(;;) {
|
||||
CString astr;
|
||||
if (nb_operands >= MAX_ASM_OPERANDS)
|
||||
tcc_error("too many asm operands");
|
||||
op = &operands[nb_operands++];
|
||||
@ -1135,10 +1132,8 @@ static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr,
|
||||
next();
|
||||
skip(']');
|
||||
}
|
||||
parse_mult_str(&astr, "string constant");
|
||||
op->constraint = tcc_malloc(astr.size);
|
||||
strcpy(op->constraint, astr.data);
|
||||
cstr_free(&astr);
|
||||
astr = parse_mult_str("string constant")->data;
|
||||
pstrcpy(op->constraint, sizeof op->constraint, astr);
|
||||
skip('(');
|
||||
gexpr();
|
||||
if (is_output) {
|
||||
@ -1171,7 +1166,8 @@ static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr,
|
||||
/* parse the GCC asm() instruction */
|
||||
ST_FUNC void asm_instr(void)
|
||||
{
|
||||
CString astr, astr1;
|
||||
CString astr, *astr1;
|
||||
|
||||
ASMOperand operands[MAX_ASM_OPERANDS];
|
||||
int nb_outputs, nb_operands, i, must_subst, out_reg, nb_labels;
|
||||
uint8_t clobber_regs[NB_ASM_REGS];
|
||||
@ -1183,7 +1179,11 @@ ST_FUNC void asm_instr(void)
|
||||
|| tok == TOK_GOTO) {
|
||||
next();
|
||||
}
|
||||
parse_asm_str(&astr);
|
||||
|
||||
astr1 = parse_asm_str();
|
||||
cstr_new_s(&astr);
|
||||
cstr_cat(&astr, astr1->data, astr1->size);
|
||||
|
||||
nb_operands = 0;
|
||||
nb_outputs = 0;
|
||||
nb_labels = 0;
|
||||
@ -1273,13 +1273,14 @@ ST_FUNC void asm_instr(void)
|
||||
printf("asm: \"%s\"\n", (char *)astr.data);
|
||||
#endif
|
||||
if (must_subst) {
|
||||
subst_asm_operands(operands, nb_operands + nb_labels, &astr1, &astr);
|
||||
cstr_free(&astr);
|
||||
} else {
|
||||
astr1 = astr;
|
||||
cstr_reset(astr1);
|
||||
cstr_cat(astr1, astr.data, astr.size);
|
||||
cstr_reset(&astr);
|
||||
subst_asm_operands(operands, nb_operands + nb_labels, &astr, astr1->data);
|
||||
}
|
||||
|
||||
#ifdef ASM_DEBUG
|
||||
printf("subst_asm: \"%s\"\n", (char *)astr1.data);
|
||||
printf("subst_asm: \"%s\"\n", (char *)astr.data);
|
||||
#endif
|
||||
|
||||
/* generate loads */
|
||||
@ -1290,7 +1291,8 @@ ST_FUNC void asm_instr(void)
|
||||
bleed out to surrounding code. */
|
||||
sec = cur_text_section;
|
||||
/* assemble the string with tcc internal assembler */
|
||||
tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1, 0);
|
||||
tcc_assemble_inline(tcc_state, astr.data, astr.size - 1, 0);
|
||||
cstr_free_s(&astr);
|
||||
if (sec != cur_text_section) {
|
||||
tcc_warning("inline asm tries to change current section");
|
||||
use_section1(tcc_state, sec);
|
||||
@ -1305,23 +1307,20 @@ ST_FUNC void asm_instr(void)
|
||||
|
||||
/* free everything */
|
||||
for(i=0;i<nb_operands;i++) {
|
||||
ASMOperand *op;
|
||||
op = &operands[i];
|
||||
tcc_free(op->constraint);
|
||||
vpop();
|
||||
}
|
||||
cstr_free(&astr1);
|
||||
|
||||
}
|
||||
|
||||
ST_FUNC void asm_global_instr(void)
|
||||
{
|
||||
CString astr;
|
||||
CString *astr;
|
||||
int saved_nocode_wanted = nocode_wanted;
|
||||
|
||||
/* Global asm blocks are always emitted. */
|
||||
nocode_wanted = 0;
|
||||
next();
|
||||
parse_asm_str(&astr);
|
||||
astr = parse_asm_str();
|
||||
skip(')');
|
||||
/* NOTE: we do not eat the ';' so that we can restore the current
|
||||
token after the assembler parsing */
|
||||
@ -1335,14 +1334,13 @@ ST_FUNC void asm_global_instr(void)
|
||||
ind = cur_text_section->data_offset;
|
||||
|
||||
/* assemble the string with tcc internal assembler */
|
||||
tcc_assemble_inline(tcc_state, astr.data, astr.size - 1, 1);
|
||||
tcc_assemble_inline(tcc_state, astr->data, astr->size - 1, 1);
|
||||
|
||||
cur_text_section->data_offset = ind;
|
||||
|
||||
/* restore the current C token */
|
||||
next();
|
||||
|
||||
cstr_free(&astr);
|
||||
nocode_wanted = saved_nocode_wanted;
|
||||
}
|
||||
|
||||
|
86
tccgen.c
86
tccgen.c
@ -402,7 +402,6 @@ ST_FUNC int tccgen_compile(TCCState *s1)
|
||||
ST_FUNC void tccgen_finish(TCCState *s1)
|
||||
{
|
||||
tcc_debug_end(s1); /* just in case of errors: free memory */
|
||||
cstr_free(&initstr);
|
||||
free_inline_functions(s1);
|
||||
sym_pop(&global_stack, NULL, 0);
|
||||
sym_pop(&local_stack, NULL, 0);
|
||||
@ -412,6 +411,8 @@ ST_FUNC void tccgen_finish(TCCState *s1)
|
||||
dynarray_reset(&sym_pools, &nb_sym_pools);
|
||||
sym_free_first = NULL;
|
||||
global_label_stack = local_label_stack = NULL;
|
||||
cstr_free(&initstr);
|
||||
dynarray_reset(&stk_data, &nb_stk_data);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@ -3756,18 +3757,19 @@ ST_FUNC void inc(int post, int c)
|
||||
vpop(); /* if post op, return saved value */
|
||||
}
|
||||
|
||||
ST_FUNC void parse_mult_str (CString *astr, const char *msg)
|
||||
ST_FUNC CString* parse_mult_str (const char *msg)
|
||||
{
|
||||
/* read the string */
|
||||
if (tok != TOK_STR)
|
||||
expect(msg);
|
||||
cstr_new(astr);
|
||||
cstr_reset(&initstr);
|
||||
while (tok == TOK_STR) {
|
||||
/* XXX: add \0 handling too ? */
|
||||
cstr_cat(astr, tokc.str.data, -1);
|
||||
cstr_cat(&initstr, tokc.str.data, -1);
|
||||
next();
|
||||
}
|
||||
cstr_ccat(astr, '\0');
|
||||
cstr_ccat(&initstr, '\0');
|
||||
return &initstr;
|
||||
}
|
||||
|
||||
/* If I is >= 1 and a power of two, returns log2(i)+1.
|
||||
@ -3792,7 +3794,7 @@ ST_FUNC int exact_log2p1(int i)
|
||||
static void parse_attribute(AttributeDef *ad)
|
||||
{
|
||||
int t, n;
|
||||
CString astr;
|
||||
char *astr;
|
||||
|
||||
redo:
|
||||
if (tok != TOK_ATTRIBUTE1 && tok != TOK_ATTRIBUTE2)
|
||||
@ -3839,37 +3841,33 @@ redo:
|
||||
case TOK_SECTION1:
|
||||
case TOK_SECTION2:
|
||||
skip('(');
|
||||
parse_mult_str(&astr, "section name");
|
||||
ad->section = find_section(tcc_state, (char *)astr.data);
|
||||
astr = parse_mult_str("section name")->data;
|
||||
ad->section = find_section(tcc_state, astr);
|
||||
skip(')');
|
||||
cstr_free(&astr);
|
||||
break;
|
||||
case TOK_ALIAS1:
|
||||
case TOK_ALIAS2:
|
||||
skip('(');
|
||||
parse_mult_str(&astr, "alias(\"target\")");
|
||||
ad->alias_target = /* save string as token, for later */
|
||||
tok_alloc((char*)astr.data, astr.size-1)->tok;
|
||||
astr = parse_mult_str("alias(\"target\")")->data;
|
||||
/* save string as token, for later */
|
||||
ad->alias_target = tok_alloc_const(astr);
|
||||
skip(')');
|
||||
cstr_free(&astr);
|
||||
break;
|
||||
case TOK_VISIBILITY1:
|
||||
case TOK_VISIBILITY2:
|
||||
skip('(');
|
||||
parse_mult_str(&astr,
|
||||
"visibility(\"default|hidden|internal|protected\")");
|
||||
if (!strcmp (astr.data, "default"))
|
||||
astr = parse_mult_str("visibility(\"default|hidden|internal|protected\")")->data;
|
||||
if (!strcmp (astr, "default"))
|
||||
ad->a.visibility = STV_DEFAULT;
|
||||
else if (!strcmp (astr.data, "hidden"))
|
||||
else if (!strcmp (astr, "hidden"))
|
||||
ad->a.visibility = STV_HIDDEN;
|
||||
else if (!strcmp (astr.data, "internal"))
|
||||
else if (!strcmp (astr, "internal"))
|
||||
ad->a.visibility = STV_INTERNAL;
|
||||
else if (!strcmp (astr.data, "protected"))
|
||||
else if (!strcmp (astr, "protected"))
|
||||
ad->a.visibility = STV_PROTECTED;
|
||||
else
|
||||
expect("visibility(\"default|hidden|internal|protected\")");
|
||||
skip(')');
|
||||
cstr_free(&astr);
|
||||
break;
|
||||
case TOK_ALIGNED1:
|
||||
case TOK_ALIGNED2:
|
||||
@ -4818,26 +4816,25 @@ static inline void convert_parameter_type(CType *pt)
|
||||
}
|
||||
}
|
||||
|
||||
ST_FUNC void parse_asm_str(CString *astr)
|
||||
ST_FUNC CString* parse_asm_str(void)
|
||||
{
|
||||
skip('(');
|
||||
parse_mult_str(astr, "string constant");
|
||||
return parse_mult_str("string constant");
|
||||
}
|
||||
|
||||
/* Parse an asm label and return the token */
|
||||
static int asm_label_instr(void)
|
||||
{
|
||||
int v;
|
||||
CString astr;
|
||||
char *astr;
|
||||
|
||||
next();
|
||||
parse_asm_str(&astr);
|
||||
astr = parse_asm_str()->data;
|
||||
skip(')');
|
||||
#ifdef ASM_DEBUG
|
||||
printf("asm_alias: \"%s\"\n", (char *)astr.data);
|
||||
printf("asm_alias: \"%s\"\n", astr);
|
||||
#endif
|
||||
v = tok_alloc(astr.data, astr.size - 1)->tok;
|
||||
cstr_free(&astr);
|
||||
v = tok_alloc_const(astr);
|
||||
return v;
|
||||
}
|
||||
|
||||
@ -8357,29 +8354,23 @@ static void free_inline_functions(TCCState *s)
|
||||
dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
|
||||
}
|
||||
|
||||
static void do_Static_assert(void){
|
||||
CString error_str;
|
||||
static void do_Static_assert(void)
|
||||
{
|
||||
int c;
|
||||
const char *msg;
|
||||
|
||||
next();
|
||||
skip('(');
|
||||
c = expr_const();
|
||||
|
||||
if (tok == ')') {
|
||||
if (!c)
|
||||
tcc_error("_Static_assert fail");
|
||||
next();
|
||||
goto static_assert_out;
|
||||
msg = "_Static_assert fail";
|
||||
if (tok == ',') {
|
||||
next();
|
||||
msg = parse_mult_str("string constant")->data;
|
||||
}
|
||||
|
||||
skip(',');
|
||||
parse_mult_str(&error_str, "string constant");
|
||||
if (c == 0)
|
||||
tcc_error("%s", (char *)error_str.data);
|
||||
cstr_free(&error_str);
|
||||
skip(')');
|
||||
static_assert_out:
|
||||
skip(';');
|
||||
if (c == 0)
|
||||
tcc_error("%s", msg);
|
||||
skip(';');
|
||||
}
|
||||
|
||||
/* 'l' is VT_LOCAL or VT_CONST to define default storage type
|
||||
@ -8393,10 +8384,11 @@ static int decl(int l)
|
||||
AttributeDef ad, adbase;
|
||||
|
||||
while (1) {
|
||||
if (tok == TOK_STATIC_ASSERT) {
|
||||
do_Static_assert();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tok == TOK_STATIC_ASSERT) {
|
||||
do_Static_assert();
|
||||
continue;
|
||||
}
|
||||
|
||||
oldint = 0;
|
||||
if (!parse_btype(&btype, &adbase, l == VT_LOCAL)) {
|
||||
|
82
tccpp.c
82
tccpp.c
@ -45,7 +45,6 @@ ST_DATA TokenSym **table_ident;
|
||||
static TokenSym *hash_ident[TOK_HASH_SIZE];
|
||||
static char token_buf[STRING_MAX_SIZE + 1];
|
||||
static CString cstr_buf;
|
||||
static CString macro_equal_buf;
|
||||
static TokenString tokstr_buf;
|
||||
static unsigned char isidnum_table[256 - CH_EOF];
|
||||
static int pp_debug_tok, pp_debug_symv;
|
||||
@ -399,7 +398,6 @@ ST_FUNC void cstr_new(CString *cstr)
|
||||
ST_FUNC void cstr_free(CString *cstr)
|
||||
{
|
||||
tcc_free(cstr->data);
|
||||
cstr_new(cstr);
|
||||
}
|
||||
|
||||
/* reset string to empty */
|
||||
@ -1273,12 +1271,11 @@ static int macro_is_equal(const int *a, const int *b)
|
||||
return 1;
|
||||
|
||||
while (*a && *b) {
|
||||
/* first time preallocate macro_equal_buf, next time only reset position to start */
|
||||
cstr_reset(¯o_equal_buf);
|
||||
cstr_reset(&tokcstr);
|
||||
TOK_GET(&t, &a, &cv);
|
||||
cstr_cat(¯o_equal_buf, get_tok_str(t, &cv), 0);
|
||||
cstr_cat(&tokcstr, get_tok_str(t, &cv), 0);
|
||||
TOK_GET(&t, &b, &cv);
|
||||
if (strcmp(macro_equal_buf.data, get_tok_str(t, &cv)))
|
||||
if (strcmp(tokcstr.data, get_tok_str(t, &cv)))
|
||||
return 0;
|
||||
}
|
||||
return !(*a || *b);
|
||||
@ -1348,14 +1345,15 @@ search_cached_include(TCCState *s1, const char *filename, int add);
|
||||
static int parse_include(TCCState *s1, int do_next, int test)
|
||||
{
|
||||
int c, i;
|
||||
CString cs;
|
||||
char name[1024], buf[1024], *p;
|
||||
CachedInclude *e;
|
||||
|
||||
cstr_new(&cs);
|
||||
c = skip_spaces();
|
||||
if (c == '<' || c == '\"') {
|
||||
file->buf_ptr = parse_pp_string(file->buf_ptr, c == '<' ? '>' : c, &cs);
|
||||
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);
|
||||
next_nomacro();
|
||||
} else {
|
||||
/* computed #include : concatenate tokens until result is one of
|
||||
@ -1363,24 +1361,22 @@ static int parse_include(TCCState *s1, int do_next, int test)
|
||||
parse_flags = PARSE_FLAG_PREPROCESS
|
||||
| PARSE_FLAG_LINEFEED
|
||||
| (parse_flags & PARSE_FLAG_ASM_FILE);
|
||||
name[0] = 0;
|
||||
for (;;) {
|
||||
next();
|
||||
p = cs.data, i = cs.size - 1;
|
||||
p = name, i = strlen(p) - 1;
|
||||
if (i > 0
|
||||
&& ((p[0] == '"' && p[i] == '"')
|
||||
|| (p[0] == '<' && p[i] == '>')))
|
||||
break;
|
||||
if (tok == TOK_LINEFEED)
|
||||
tcc_error("'#include' expects \"FILENAME\" or <FILENAME>");
|
||||
cstr_cat(&cs, get_tok_str(tok, &tokc), -1);
|
||||
pstrcat(name, sizeof name, get_tok_str(tok, &tokc));
|
||||
}
|
||||
c = p[0];
|
||||
/* remove '<>|""' */
|
||||
memmove(p, p + 1, cs.size -= 2);
|
||||
memmove(p, p + 1, i - 1), p[i - 1] = 0;
|
||||
}
|
||||
cstr_ccat(&cs, '\0');
|
||||
pstrcpy(name, sizeof name, cs.data);
|
||||
cstr_free(&cs);
|
||||
|
||||
i = do_next ? file->include_next_index : -1;
|
||||
for (;;) {
|
||||
@ -2934,7 +2930,6 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args)
|
||||
Sym *s;
|
||||
CValue cval;
|
||||
TokenString str;
|
||||
CString cstr;
|
||||
|
||||
tok_str_new(&str);
|
||||
t0 = t1 = 0;
|
||||
@ -2949,8 +2944,8 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args)
|
||||
goto bad_stringy;
|
||||
s = sym_find2(args, t);
|
||||
if (s) {
|
||||
cstr_new(&cstr);
|
||||
cstr_ccat(&cstr, '\"');
|
||||
cstr_reset(&tokcstr);
|
||||
cstr_ccat(&tokcstr, '\"');
|
||||
st = s->d;
|
||||
spc = 0;
|
||||
while (*st >= 0) {
|
||||
@ -2961,24 +2956,23 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args)
|
||||
const char *s = get_tok_str(t, &cval);
|
||||
while (*s) {
|
||||
if (t == TOK_PPSTR && *s != '\'')
|
||||
add_char(&cstr, *s);
|
||||
add_char(&tokcstr, *s);
|
||||
else
|
||||
cstr_ccat(&cstr, *s);
|
||||
cstr_ccat(&tokcstr, *s);
|
||||
++s;
|
||||
}
|
||||
}
|
||||
}
|
||||
cstr.size -= spc;
|
||||
cstr_ccat(&cstr, '\"');
|
||||
cstr_ccat(&cstr, '\0');
|
||||
tokcstr.size -= spc;
|
||||
cstr_ccat(&tokcstr, '\"');
|
||||
cstr_ccat(&tokcstr, '\0');
|
||||
#ifdef PP_DEBUG
|
||||
printf("\nstringize: <%s>\n", (char *)cstr.data);
|
||||
printf("\nstringize: <%s>\n", (char *)tokcstr.data);
|
||||
#endif
|
||||
/* add string */
|
||||
cval.str.size = cstr.size;
|
||||
cval.str.data = cstr.data;
|
||||
cval.str.size = tokcstr.size;
|
||||
cval.str.data = tokcstr.data;
|
||||
tok_str_add2(&str, TOK_PPSTR, &cval);
|
||||
cstr_free(&cstr);
|
||||
} else {
|
||||
bad_stringy:
|
||||
expect("macro parameter after '#'");
|
||||
@ -3047,19 +3041,19 @@ static char const ab_month_name[12][4] =
|
||||
|
||||
static int paste_tokens(int t1, CValue *v1, int t2, CValue *v2)
|
||||
{
|
||||
CString cstr;
|
||||
int n, ret = 1;
|
||||
|
||||
cstr_new(&cstr);
|
||||
cstr_reset(&tokcstr);
|
||||
if (t1 != TOK_PLCHLDR)
|
||||
cstr_cat(&cstr, get_tok_str(t1, v1), -1);
|
||||
n = cstr.size;
|
||||
cstr_cat(&tokcstr, get_tok_str(t1, v1), -1);
|
||||
n = tokcstr.size;
|
||||
if (t2 != TOK_PLCHLDR)
|
||||
cstr_cat(&cstr, get_tok_str(t2, v2), -1);
|
||||
cstr_ccat(&cstr, '\0');
|
||||
cstr_cat(&tokcstr, get_tok_str(t2, v2), -1);
|
||||
cstr_ccat(&tokcstr, '\0');
|
||||
//printf("paste <%s>\n", (char*)tokcstr.data);
|
||||
|
||||
tcc_open_bf(tcc_state, ":paste:", cstr.size);
|
||||
memcpy(file->buffer, cstr.data, cstr.size);
|
||||
tcc_open_bf(tcc_state, ":paste:", tokcstr.size);
|
||||
memcpy(file->buffer, tokcstr.data, tokcstr.size);
|
||||
tok_flags = 0;
|
||||
for (;;) {
|
||||
next_nomacro1();
|
||||
@ -3068,13 +3062,11 @@ static int paste_tokens(int t1, CValue *v1, int t2, CValue *v2)
|
||||
if (is_space(tok))
|
||||
continue;
|
||||
tcc_warning("pasting \"%.*s\" and \"%s\" does not give a valid"
|
||||
" preprocessing token", n, (char *)cstr.data, (char*)cstr.data + n);
|
||||
" preprocessing token", n, file->buffer, file->buffer + n);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
tcc_close();
|
||||
//printf("paste <%s>\n", (char*)cstr.data);
|
||||
cstr_free(&cstr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -3214,7 +3206,6 @@ static int macro_subst_tok(
|
||||
TokenString str;
|
||||
char *cstrval;
|
||||
CValue cval;
|
||||
CString cstr;
|
||||
char buf[32];
|
||||
|
||||
/* if symbol is a macro, prepare substitution */
|
||||
@ -3245,12 +3236,11 @@ static int macro_subst_tok(
|
||||
add_cstr:
|
||||
t1 = TOK_STR;
|
||||
add_cstr1:
|
||||
cstr_new(&cstr);
|
||||
cstr_cat(&cstr, cstrval, 0);
|
||||
cval.str.size = cstr.size;
|
||||
cval.str.data = cstr.data;
|
||||
cstr_reset(&tokcstr);
|
||||
cstr_cat(&tokcstr, cstrval, 0);
|
||||
cval.str.size = tokcstr.size;
|
||||
cval.str.data = tokcstr.data;
|
||||
tok_str_add2(tok_str, t1, &cval);
|
||||
cstr_free(&cstr);
|
||||
} else if (s->d) {
|
||||
int saved_parse_flags = parse_flags;
|
||||
int *joined_str = NULL;
|
||||
@ -3634,7 +3624,6 @@ static void tcc_predefs(TCCState *s1, CString *cs, int is_asm)
|
||||
ST_FUNC void preprocess_start(TCCState *s1, int filetype)
|
||||
{
|
||||
int is_asm = !!(filetype & (AFF_TYPE_ASM|AFF_TYPE_ASMPP));
|
||||
CString cstr;
|
||||
|
||||
tccpp_new(s1);
|
||||
|
||||
@ -3652,6 +3641,7 @@ ST_FUNC void preprocess_start(TCCState *s1, int filetype)
|
||||
set_idnum('.', is_asm ? IS_ID : 0);
|
||||
|
||||
if (!(filetype & AFF_TYPE_ASM)) {
|
||||
CString cstr;
|
||||
cstr_new(&cstr);
|
||||
tcc_predefs(s1, &cstr, is_asm);
|
||||
if (s1->cmdline_defs.size)
|
||||
@ -3710,6 +3700,7 @@ ST_FUNC void tccpp_new(TCCState *s)
|
||||
memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
|
||||
memset(s->cached_includes_hash, 0, sizeof s->cached_includes_hash);
|
||||
|
||||
cstr_new(&tokcstr);
|
||||
cstr_new(&cstr_buf);
|
||||
cstr_realloc(&cstr_buf, STRING_MAX_SIZE);
|
||||
tok_str_new(&tokstr_buf);
|
||||
@ -3755,7 +3746,6 @@ ST_FUNC void tccpp_delete(TCCState *s)
|
||||
/* free static buffers */
|
||||
cstr_free(&tokcstr);
|
||||
cstr_free(&cstr_buf);
|
||||
cstr_free(¯o_equal_buf);
|
||||
tok_str_free_str(tokstr_buf.str);
|
||||
|
||||
/* free allocators */
|
||||
|
Loading…
Reference in New Issue
Block a user