Alien-TinyCCx
view release on metacpan or search on metacpan
src/libtcc.c view on Meta::CPAN
fd = 0, filename = "<stdin>";
else
fd = open(filename, O_RDONLY | O_BINARY);
if ((s1->verbose == 2 && fd >= 0) || s1->verbose == 3)
printf("%s %*s%s\n", fd < 0 ? "nf":"->",
(int)(s1->include_stack_ptr - s1->include_stack), "", filename);
if (fd < 0)
return -1;
tcc_open_bf(s1, filename, 0);
file->fd = fd;
return fd;
}
/* compile the C file opened in 'file'. Return non zero if errors. */
static int tcc_compile(TCCState *s1)
{
Sym *define_start;
/* #ifdef CONFIG_TCC_EXSYMTAB */
int tok_start;
/* #endif */
preprocess_start(s1);
/* #ifdef CONFIG_TCC_EXSYMTAB */
/* Note where we start adding new tokens */
tok_start = tok_ident;
/* #endif */
define_start = define_stack;
/* #ifdef CONFIG_TCC_EXSYMTAB */
/* Perform tokensym preparation */
if (s1->symtab_prep_callback) s1->symtab_prep_callback(s1->symtab_callback_data);
/* #endif */
if (setjmp(s1->error_jmp_buf) == 0) {
s1->nb_errors = 0;
s1->error_set_jmp_enabled = 1;
tccgen_start(s1);
#ifdef INC_DEBUG
printf("%s: **** new file\n", file->filename);
#endif
ch = file->buf_ptr[0];
tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR;
next();
decl(VT_CONST);
if (tok != TOK_EOF)
expect("declaration");
tccgen_end(s1);
}
s1->error_set_jmp_enabled = 0;
/* #ifdef CONFIG_TCC_EXSYMTAB */
/* Make an extended copy of the symbol table, if requested */
if (s1->nb_errors == 0 && s1->exsymtab == (extended_symtab*)1)
{
copy_extended_symtab(s1, define_start, tok_start);
/* Output the symbol table to a cache if requested */
if (s1->symtab_serialize_outfile)
tcc_serialize_extended_symtab(s1->exsymtab, s1->symtab_serialize_outfile);
/* Output the symbol names */
if (s1->dump_identifier_names_outfile)
tcc_dump_identifier_names(s1->exsymtab, s1->dump_identifier_names_outfile);
}
/* #endif */
free_inline_functions(s1);
/* reset define stack, but keep -D and built-ins */
free_defines(define_start);
sym_pop(&global_stack, NULL);
sym_pop(&local_stack, NULL);
return s1->nb_errors != 0 ? -1 : 0;
}
/* #ifdef CONFIG_TCC_EXSYMTAB */
LIBTCCAPI int tcc_compile_string_ex(TCCState *s, const char *str, int len, const char * filename, int line_num)
{
int ret;
/* Open the buffer and copy the contents */
tcc_open_bf(s, filename, len);
memcpy(file->buffer, str, len);
/* Set the line number */
file->line_num = line_num;
/* Compile and cleanup */
ret = tcc_compile(s);
tcc_close();
return ret;
}
/* #endif */
LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str)
{
int len, ret;
len = strlen(str);
tcc_open_bf(s, "<string>", len);
memcpy(file->buffer, str, len);
ret = tcc_compile(s);
tcc_close();
return ret;
}
/* define a preprocessor symbol. A value can also be provided with the '=' operator */
LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
{
int len1, len2;
/* default value */
if (!value)
value = "1";
len1 = strlen(sym);
len2 = strlen(value);
/* init file structure */
tcc_open_bf(s1, "<define>", len1 + len2 + 1);
memcpy(file->buffer, sym, len1);
file->buffer[len1] = ' ';
memcpy(file->buffer + len1 + 1, value, len2);
/* parse with define parser */
ch = file->buf_ptr[0];
next_nomacro();
parse_define();
src/libtcc.c view on Meta::CPAN
#endif
# if defined(__NetBSD__)
tcc_define_symbol(s, "__NetBSD__", "__NetBSD__");
# endif
# if defined(__OpenBSD__)
tcc_define_symbol(s, "__OpenBSD__", "__OpenBSD__");
# endif
/* TinyCC & gcc defines */
#if defined(TCC_TARGET_PE) && defined(TCC_TARGET_X86_64)
/* 64bit Windows. */
tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long long");
tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long long");
tcc_define_symbol(s, "__LLP64__", NULL);
#elif defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64)
/* Other 64bit systems. */
tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long");
tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long");
tcc_define_symbol(s, "__LP64__", NULL);
#else
/* Other 32bit systems. */
tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long");
tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long");
tcc_define_symbol(s, "__ILP32__", NULL);
#endif
#ifdef TCC_TARGET_PE
tcc_define_symbol(s, "__WCHAR_TYPE__", "unsigned short");
tcc_define_symbol(s, "__WINT_TYPE__", "unsigned short");
#else
tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
/* wint_t is unsigned int by default, but (signed) int on BSDs
and unsigned short on windows. Other OSes might have still
other conventions, sigh. */
# if defined(__FreeBSD__) || defined (__FreeBSD_kernel__) \
|| defined(__NetBSD__) || defined(__OpenBSD__)
tcc_define_symbol(s, "__WINT_TYPE__", "int");
# ifdef __FreeBSD__
/* define __GNUC__ to have some useful stuff from sys/cdefs.h
that are unconditionally used in FreeBSDs other system headers :/ */
tcc_define_symbol(s, "__GNUC__", "2");
tcc_define_symbol(s, "__GNUC_MINOR__", "7");
tcc_define_symbol(s, "__builtin_alloca", "alloca");
# endif
# else
tcc_define_symbol(s, "__WINT_TYPE__", "unsigned int");
/* glibc defines */
tcc_define_symbol(s, "__REDIRECT(name, proto, alias)",
"name proto __asm__ (#alias)");
tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)",
"name proto __asm__ (#alias) __THROW");
# endif
#endif /* ndef TCC_TARGET_PE */
/* #ifdef CONFIG_TCC_EXSYMTAB */
/* Extended symbol table API */
s->symtab_name_callback = NULL;
s->symtab_sym_used_callback = NULL;
s->symtab_prep_callback = NULL;
s->symtab_callback_data = NULL;
s->symtab_serialize_outfile = NULL;
s->dump_identifier_names_outfile = NULL;
/* #endif */
return s;
}
LIBTCCAPI void tcc_delete(TCCState *s1)
{
int bench = s1->do_bench;
tcc_cleanup();
/* #ifdef CONFIG_TCC_EXSYMTAB */
/* Clean up the extended symbol table if it was never copied. */
if (s1->exsymtab > (extended_symtab*)1)
tcc_delete_extended_symbol_table(s1->exsymtab);
/* free file paths related to caching */
tcc_free(s1->symtab_serialize_outfile);
tcc_free(s1->dump_identifier_names_outfile);
/* #endif */
/* free sections */
tccelf_delete(s1);
/* free library paths */
dynarray_reset(&s1->library_paths, &s1->nb_library_paths);
dynarray_reset(&s1->crt_paths, &s1->nb_crt_paths);
/* free include paths */
dynarray_reset(&s1->cached_includes, &s1->nb_cached_includes);
dynarray_reset(&s1->include_paths, &s1->nb_include_paths);
dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths);
tcc_free(s1->tcc_lib_path);
tcc_free(s1->soname);
tcc_free(s1->rpath);
tcc_free(s1->init_symbol);
tcc_free(s1->fini_symbol);
tcc_free(s1->outfile);
tcc_free(s1->deps_outfile);
dynarray_reset(&s1->files, &s1->nb_files);
dynarray_reset(&s1->target_deps, &s1->nb_target_deps);
dynarray_reset(&s1->pragma_libs, &s1->nb_pragma_libs);
#ifdef TCC_IS_NATIVE
/* free runtime memory */
tcc_run_free(s1);
#endif
tcc_free(s1->sym_attrs);
tcc_free(s1);
tcc_memstats(bench);
}
LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
{
s->output_type = output_type;
/* always elf for objects */
if (output_type == TCC_OUTPUT_OBJ)
s->output_format = TCC_OUTPUT_FORMAT_ELF;
if (s->char_is_unsigned)
tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);
if (!s->nostdinc) {
/* default include paths */
/* -isystem paths have already been handled */
tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS);
}
#ifdef CONFIG_TCC_BCHECK
if (s->do_bounds_check) {
/* if bound checking, then add corresponding sections */
tccelf_bounds_new(s);
/* define symbol */
tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
}
#endif
if (s->do_debug) {
/* add debug sections */
tccelf_stab_new(s);
}
tcc_add_library_path(s, CONFIG_TCC_LIBPATHS);
#ifdef TCC_TARGET_PE
# ifdef _WIN32
if (!s->nostdlib && output_type != TCC_OUTPUT_OBJ)
tcc_add_systemdir(s);
# endif
#else
/* paths for crt objects */
tcc_split_path(s, (void ***)&s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX);
/* add libc crt1/crti objects */
if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
!s->nostdlib) {
if (output_type != TCC_OUTPUT_DLL)
tcc_add_crt(s, "crt1.o");
tcc_add_crt(s, "crti.o");
src/libtcc.c view on Meta::CPAN
s->do_bench = 1;
break;
#ifdef CONFIG_TCC_BACKTRACE
case TCC_OPTION_bt:
tcc_set_num_callers(atoi(optarg));
break;
#endif
#ifdef CONFIG_TCC_BCHECK
case TCC_OPTION_b:
s->do_bounds_check = 1;
s->do_debug = 1;
break;
#endif
case TCC_OPTION_g:
s->do_debug = 1;
break;
case TCC_OPTION_c:
x = TCC_OUTPUT_OBJ;
set_output_type:
if (s->output_type)
tcc_warning("-%s: overriding compiler action already specified", popt->name);
s->output_type = x;
break;
case TCC_OPTION_d:
if (*optarg == 'D')
s->dflag = 3;
else if (*optarg == 'M')
s->dflag = 7;
else
goto unsupported_option;
break;
#ifdef TCC_TARGET_ARM
case TCC_OPTION_float_abi:
/* tcc doesn't support soft float yet */
if (!strcmp(optarg, "softfp")) {
s->float_abi = ARM_SOFTFP_FLOAT;
tcc_undefine_symbol(s, "__ARM_PCS_VFP");
} else if (!strcmp(optarg, "hard"))
s->float_abi = ARM_HARD_FLOAT;
else
tcc_error("unsupported float abi '%s'", optarg);
break;
#endif
case TCC_OPTION_static:
s->static_link = 1;
break;
case TCC_OPTION_std:
/* silently ignore, a current purpose:
allow to use a tcc as a reference compiler for "make test" */
break;
case TCC_OPTION_shared:
x = TCC_OUTPUT_DLL;
goto set_output_type;
case TCC_OPTION_soname:
s->soname = tcc_strdup(optarg);
break;
case TCC_OPTION_m:
s->option_m = tcc_strdup(optarg);
break;
case TCC_OPTION_o:
if (s->outfile) {
tcc_warning("multiple -o option");
tcc_free(s->outfile);
}
s->outfile = tcc_strdup(optarg);
break;
case TCC_OPTION_r:
/* generate a .o merging several output files */
s->option_r = 1;
x = TCC_OUTPUT_OBJ;
goto set_output_type;
case TCC_OPTION_isystem:
tcc_add_sysinclude_path(s, optarg);
break;
case TCC_OPTION_iwithprefix:
snprintf(buf, sizeof buf, "{B}/%s", optarg);
tcc_add_sysinclude_path(s, buf);
break;
case TCC_OPTION_nostdinc:
s->nostdinc = 1;
break;
case TCC_OPTION_nostdlib:
s->nostdlib = 1;
break;
case TCC_OPTION_print_search_dirs:
s->print_search_dirs = 1;
break;
case TCC_OPTION_run:
#ifndef TCC_IS_NATIVE
tcc_error("-run is not available in a cross compiler");
#endif
tcc_set_options(s, optarg);
run = 1;
x = TCC_OUTPUT_MEMORY;
goto set_output_type;
case TCC_OPTION_v:
do ++s->verbose; while (*optarg++ == 'v');
break;
case TCC_OPTION_f:
if (tcc_set_flag(s, optarg, 1) < 0)
goto unsupported_option;
break;
case TCC_OPTION_W:
if (tcc_set_warning(s, optarg, 1) < 0)
goto unsupported_option;
break;
case TCC_OPTION_w:
s->warn_none = 1;
break;
case TCC_OPTION_rdynamic:
s->rdynamic = 1;
break;
case TCC_OPTION_Wl:
if (linker_arg.size)
--linker_arg.size, cstr_ccat(&linker_arg, ',');
cstr_cat(&linker_arg, optarg, 0);
if (tcc_set_linker(s, linker_arg.data))
cstr_free(&linker_arg);
break;
case TCC_OPTION_E:
x = TCC_OUTPUT_PREPROCESS;
goto set_output_type;
case TCC_OPTION_P:
s->Pflag = atoi(optarg) + 1;
break;
case TCC_OPTION_MD:
s->gen_deps = 1;
break;
case TCC_OPTION_MF:
s->deps_outfile = tcc_strdup(optarg);
break;
/* #ifdef CONFIG_TCC_EXSYMTAB */
case TCC_OPTION_serialize_symtab:
s->symtab_serialize_outfile = tcc_strdup(optarg + 1);
s->exsymtab = (extended_symtab*)1;
break;
case TCC_OPTION_dump_identifier_names:
s->dump_identifier_names_outfile = tcc_strdup(optarg + 1);
s->exsymtab = (extended_symtab*)1;
break;
/* #endif */
case TCC_OPTION_dumpversion:
printf ("%s\n", TCC_VERSION);
exit(0);
break;
case TCC_OPTION_x:
if (*optarg == 'c')
s->filetype = AFF_TYPE_C;
else if (*optarg == 'a')
s->filetype = AFF_TYPE_ASMPP;
else if (*optarg == 'n')
s->filetype = AFF_TYPE_NONE;
else
tcc_warning("unsupported language '%s'", optarg);
break;
case TCC_OPTION_O:
x = atoi(optarg);
if (x > 0)
tcc_define_symbol(s, "__OPTIMIZE__", NULL);
break;
case TCC_OPTION_mms_bitfields:
s->ms_bitfields = 1;
break;
case TCC_OPTION_traditional:
case TCC_OPTION_pedantic:
case TCC_OPTION_pipe:
case TCC_OPTION_s:
/* ignored */
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;
( run in 0.869 second using v1.01-cache-2.11-cpan-f0fbb3f571b )