Alien-TinyCCx
view release on metacpan or search on metacpan
src/tccpp.c view on Meta::CPAN
/*
* TCC - Tiny C Compiler
*
* 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
*/
#include "tcc.h"
/********************************************************/
/* global variables */
ST_DATA int tok_flags;
ST_DATA int parse_flags;
ST_DATA struct BufferedFile *file;
ST_DATA int ch, tok;
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 total_lines;
ST_DATA int total_bytes;
ST_DATA int tok_ident;
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 TokenString tokstr_buf;
static unsigned char isidnum_table[256 - CH_EOF];
static int pp_debug_tok, pp_debug_symv;
static int pp_once;
static void tok_print(const char *msg, const int *str);
static struct TinyAlloc *toksym_alloc;
static struct TinyAlloc *tokstr_alloc;
static struct TinyAlloc *cstr_alloc;
/* isidnum_table flags: */
#define IS_SPC 1
#define IS_ID 2
#define IS_NUM 4
static TokenString *macro_stack;
static const char tcc_keywords[] =
#define DEF(id, str) str "\0"
#include "tcctok.h"
#undef DEF
;
/* WARNING: the content of this string encodes token numbers */
static const unsigned char tok_two_chars[] =
/* outdated -- gr
"<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253"
"-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
*/{
'<','=', TOK_LE,
'>','=', TOK_GE,
'!','=', TOK_NE,
'&','&', TOK_LAND,
'|','|', TOK_LOR,
'+','+', TOK_INC,
'-','-', TOK_DEC,
'=','=', TOK_EQ,
'<','<', TOK_SHL,
'>','>', TOK_SAR,
src/tccpp.c view on Meta::CPAN
/* #endif */
if (v >= TOK_IDENT && v < tok_ident)
table_ident[v - TOK_IDENT]->sym_define = NULL;
}
ST_INLN Sym *define_find(int v)
{
/* #ifdef CONFIG_TCC_EXSYMTAB */
v &= ~SYM_EXTENDED;
/* #endif */
v -= TOK_IDENT;
if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
return NULL;
return table_ident[v]->sym_define;
}
/* free define stack until top reaches 'b' */
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);
}
/* restore remaining (-D or predefined) symbols */
while (b) {
int v = b->v;
if (v >= TOK_IDENT && v < tok_ident) {
Sym **d = &table_ident[v - TOK_IDENT]->sym_define;
if (!*d)
*d = b;
}
b = b->prev;
}
}
/* label lookup */
ST_FUNC Sym *label_find(int v)
{
/* #ifdef CONFIG_TCC_EXSYMTAB */
v &= ~SYM_EXTENDED;
/* #endif */
v -= TOK_IDENT;
if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
return NULL;
return table_ident[v]->sym_label;
}
ST_FUNC Sym *label_push(Sym **ptop, int v, int flags)
{
Sym *s, **ps;
/* #ifdef CONFIG_TCC_EXSYMTAB */
v &= ~SYM_EXTENDED;
/* #endif */
s = sym_push2(ptop, v, 0, 0);
s->r = flags;
ps = &table_ident[v - TOK_IDENT]->sym_label;
if (ptop == &global_label_stack) {
/* modify the top most local identifier, so that
sym_identifier will point to 's' when popped */
while (*ps != NULL)
ps = &(*ps)->prev_tok;
}
s->prev_tok = *ps;
*ps = s;
return s;
}
/* pop labels until element last is reached. Look if any labels are
undefined. Define symbols if '&&label' was used. */
ST_FUNC void label_pop(Sym **ptop, Sym *slast)
{
Sym *s, *s1;
for(s = *ptop; s != slast; s = s1) {
s1 = s->prev;
if (s->r == LABEL_DECLARED) {
tcc_warning("label '%s' declared but not used", get_tok_str(s->v, NULL));
} else if (s->r == LABEL_FORWARD) {
tcc_error("label '%s' used but not defined",
get_tok_str(s->v, NULL));
} else {
if (s->c) {
/* define corresponding symbol. A size of
1 is put. */
put_extern_sym(s, cur_text_section, s->jnext, 1);
}
}
/* remove label */
table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok;
sym_free(s);
}
*ptop = slast;
}
/* eval an expression for #if/#elif */
static int expr_preprocess(void)
{
int c, t;
TokenString *str;
str = tok_str_alloc();
while (tok != TOK_LINEFEED && tok != TOK_EOF) {
next(); /* do macro subst */
if (tok == TOK_DEFINED) {
next_nomacro();
t = tok;
if (t == '(')
next_nomacro();
c = define_find(tok) != 0;
if (t == '(')
next_nomacro();
tok = TOK_CINT;
tokc.i = c;
} else if (tok >= TOK_IDENT) {
/* if undefined macro */
tok = TOK_CINT;
tokc.i = 0;
}
( run in 0.439 second using v1.01-cache-2.11-cpan-13bb782fe5a )