Alien-TinyCCx
view release on metacpan or search on metacpan
src/libtcc.c view on Meta::CPAN
if (!ptr) {
ptr = tcc_malloc_debug(size, file, line);
return ptr;
}
ptr = (char *)ptr - sizeof(mem_debug_header_t);
header = (mem_debug_header_t *)ptr;
if (header->magic1 != MEM_DEBUG_MAGIC1 ||
header->magic2 != MEM_DEBUG_MAGIC2 ||
header->size == (size_t)-1 )
{
check_error:
tcc_error("tcc_realloc check failed");
}
mem_debug_chain_update = (header == mem_debug_chain);
mem_cur_size -= header->size;
ptr = realloc(ptr, sizeof(mem_debug_header_t) + size);
if (!ptr)
tcc_error("memory full (realloc)");
header = (mem_debug_header_t *)ptr;
if (header->magic1 != MEM_DEBUG_MAGIC1 ||
header->magic2 != MEM_DEBUG_MAGIC2)
{
goto check_error;
}
mem_cur_size += size;
if (mem_cur_size > mem_max_size)
mem_max_size = mem_cur_size;
header->size = size;
if (header->next)
header->next->prev = header;
if (header->prev)
header->prev->next = header;
if (mem_debug_chain_update)
mem_debug_chain = header;
ptr = (char *)ptr + sizeof(mem_debug_header_t);
return ptr;
}
PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line)
{
char *ptr;
ptr = tcc_malloc_debug(strlen(str) + 1, file, line);
strcpy(ptr, str);
return ptr;
}
PUB_FUNC void tcc_memstats(int bench)
{
if (mem_cur_size) {
mem_debug_header_t *header = mem_debug_chain;
fprintf(stderr, "MEM_DEBUG: mem_leak= %d bytes, mem_max_size= %d bytes\n",
mem_cur_size, mem_max_size);
while (header) {
fprintf(stderr, "%s:%u: error: %u bytes leaked\n",
header->file_name, header->line_num, header->size);
header = header->next;
}
}
else if (bench)
fprintf(stderr, "mem_max_size= %d bytes\n", mem_max_size);
}
#undef MEM_DEBUG_MAGIC1
#undef MEM_DEBUG_MAGIC2
#undef MEM_DEBUG_FILE_LEN
#endif
#define free(p) use_tcc_free(p)
#define malloc(s) use_tcc_malloc(s)
#define realloc(p, s) use_tcc_realloc(p, s)
/********************************************************/
/* dynarrays */
ST_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data)
{
int nb, nb_alloc;
void **pp;
nb = *nb_ptr;
pp = *ptab;
/* every power of two we double array size */
if ((nb & (nb - 1)) == 0) {
if (!nb)
nb_alloc = 1;
else
nb_alloc = nb * 2;
pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
*ptab = pp;
}
pp[nb++] = data;
*nb_ptr = nb;
}
ST_FUNC void dynarray_reset(void *pp, int *n)
{
void **p;
for (p = *(void***)pp; *n; ++p, --*n)
if (*p)
tcc_free(*p);
tcc_free(*(void**)pp);
*(void**)pp = NULL;
}
static void tcc_split_path(TCCState *s, void ***p_ary, int *p_nb_ary, const char *in)
{
const char *p;
do {
int c;
CString str;
cstr_new(&str);
for (p = in; c = *p, c != '\0' && c != PATHSEP; ++p) {
if (c == '{' && p[1] && p[2] == '}') {
c = p[1], p += 2;
if (c == 'B')
cstr_cat(&str, s->tcc_lib_path, -1);
} else {
cstr_ccat(&str, c);
}
}
if (str.size) {
cstr_ccat(&str, '\0');
dynarray_add(p_ary, p_nb_ary, tcc_strdup(str.data));
}
cstr_free(&str);
in = p+1;
} while (*p);
}
/********************************************************/
static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
{
int len;
len = strlen(buf);
vsnprintf(buf + len, buf_size - len, fmt, ap);
}
static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
strcat_vprintf(buf, buf_size, fmt, ap);
va_end(ap);
}
static void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
{
char buf[2048];
BufferedFile **pf, *f;
buf[0] = '\0';
/* use upper file if inline ":asm:" or token ":paste:" */
for (f = file; f && f->filename[0] == ':'; f = f->prev)
;
if (f) {
for(pf = s1->include_stack; pf < s1->include_stack_ptr; pf++)
strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
(*pf)->filename, (*pf)->line_num);
if (f->line_num > 0) {
strcat_printf(buf, sizeof(buf), "%s:%d: ",
f->filename, f->line_num - !!(tok_flags & TOK_FLAG_BOL));
} else {
strcat_printf(buf, sizeof(buf), "%s: ",
f->filename);
}
} else {
strcat_printf(buf, sizeof(buf), "tcc: ");
}
if (is_warning)
strcat_printf(buf, sizeof(buf), "warning: ");
else
strcat_printf(buf, sizeof(buf), "error: ");
strcat_vprintf(buf, sizeof(buf), fmt, ap);
if (!s1->error_func) {
/* default case: stderr */
if (s1->ppfp) /* print a newline during tcc -E */
fprintf(s1->ppfp, "\n"), fflush(s1->ppfp);
fprintf(stderr, "%s\n", buf);
fflush(stderr); /* print error/warning now (win32) */
} else {
s1->error_func(s1->error_opaque, buf);
}
if (!is_warning || s1->warn_error)
s1->nb_errors++;
}
LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque,
void (*error_func)(void *opaque, const char *msg))
{
s->error_opaque = error_opaque;
s->error_func = error_func;
}
/* error without aborting current compilation */
PUB_FUNC void tcc_error_noabort(const char *fmt, ...)
{
TCCState *s1 = tcc_state;
va_list ap;
va_start(ap, fmt);
error1(s1, 0, fmt, ap);
va_end(ap);
}
PUB_FUNC void tcc_error(const char *fmt, ...)
{
TCCState *s1 = tcc_state;
va_list ap;
va_start(ap, fmt);
error1(s1, 0, fmt, ap);
va_end(ap);
/* better than nothing: in some cases, we accept to handle errors */
if (s1->error_set_jmp_enabled) {
longjmp(s1->error_jmp_buf, 1);
} else {
/* XXX: eliminate this someday */
exit(1);
}
}
PUB_FUNC void tcc_warning(const char *fmt, ...)
{
TCCState *s1 = tcc_state;
va_list ap;
if (s1->warn_none)
return;
va_start(ap, fmt);
error1(s1, 1, fmt, ap);
va_end(ap);
}
/********************************************************/
/* I/O layer */
ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen)
{
src/libtcc.c view on Meta::CPAN
break;
default:
unsupported_option:
if (s->warn_unsupported)
tcc_warning("unsupported option '%s'", r);
break;
}
}
if (linker_arg.size) {
r = linker_arg.data;
goto arg_err;
}
return optind;
}
LIBTCCAPI int tcc_set_options(TCCState *s, const char *r)
{
char **argv;
int argc;
int ret, q, c;
CString str;
argc = 0, argv = NULL;
for(;;) {
while (c = (unsigned char)*r, c && c <= ' ')
++r;
if (c == 0)
break;
q = 0;
cstr_new(&str);
while (c = (unsigned char)*r, c) {
++r;
if (c == '\\' && (*r == '"' || *r == '\\')) {
c = *r++;
} else if (c == '"') {
q = !q;
continue;
} else if (q == 0 && c <= ' ') {
break;
}
cstr_ccat(&str, c);
}
cstr_ccat(&str, 0);
//printf("<%s>\n", str.data), fflush(stdout);
dynarray_add((void ***)&argv, &argc, tcc_strdup(str.data));
cstr_free(&str);
}
ret = tcc_parse_args(s, argc, argv);
dynarray_reset(&argv, &argc);
return ret;
}
PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time)
{
if (total_time < 1)
total_time = 1;
if (total_bytes < 1)
total_bytes = 1;
fprintf(stderr, "%d idents, %d lines, %d bytes, %0.3f s, %u lines/s, %0.1f MB/s\n",
tok_ident - TOK_IDENT, total_lines, total_bytes,
(double)total_time/1000,
(unsigned)total_lines*1000/total_time,
(double)total_bytes/1000/total_time);
}
PUB_FUNC void tcc_set_environment(TCCState *s)
{
char * path;
path = getenv("C_INCLUDE_PATH");
if(path != NULL) {
tcc_add_include_path(s, path);
}
path = getenv("CPATH");
if(path != NULL) {
tcc_add_include_path(s, path);
}
path = getenv("LIBRARY_PATH");
if(path != NULL) {
tcc_add_library_path(s, path);
}
}
( run in 0.686 second using v1.01-cache-2.11-cpan-13bb782fe5a )