This can be used by StreetLISP in order to automatically generate bindings for C libraries at run time rather than compile time.
Unified · Split
| @@ -704,6 +704,18 @@ LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc · 703 unmodified lines | |||
| 704 | s->error_func = error_func; | 704 | s->error_func = error_func; |
| 705 | } | 705 | } |
| 706 | 706 | ||
| 707 | LIBTCCAPI void tcc_set_decl_func(TCCState *s, void *decl_opaque, TCCDeclFunc *decl_func) | ||
| 708 | { | ||
| 709 | s->decl_opaque = decl_opaque; | ||
| 710 | s->decl_func = decl_func; | ||
| 711 | } | ||
| 712 | |||
| 713 | LIBTCCAPI void tcc_set_define_func(TCCState *s, void *define_opaque, TCCDefineFunc *define_func) | ||
| 714 | { | ||
| 715 | s->define_opaque = define_opaque; | ||
| 716 | s->define_func = define_func; | ||
| 717 | } | ||
| 718 | |||
| 707 | /* error without aborting current compilation */ | 719 | /* error without aborting current compilation */ |
| 708 | PUB_FUNC int _tcc_error_noabort(const char *fmt, ...) | 720 | PUB_FUNC int _tcc_error_noabort(const char *fmt, ...) |
| 709 | { | 721 | { |
| @@ -30,6 +30,13 @@ LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path); · 29 unmodified lines | |||
| 30 | typedef void TCCErrorFunc(void *opaque, const char *msg); | 30 | typedef void TCCErrorFunc(void *opaque, const char *msg); |
| 31 | LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc *error_func); | 31 | LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc *error_func); |
| 32 | 32 | ||
| 33 | typedef struct CType CType; | ||
| 34 | typedef void TCCDeclFunc(void *opaque, const char *file, int line, int v, int l, CType *type); | ||
| 35 | LIBTCCAPI void tcc_set_decl_func(TCCState *s, void *decl_opaque, TCCDeclFunc *decl_func); | ||
| 36 | |||
| 37 | typedef void TCCDefineFunc(void *opaque, const char *file, int line, int v, int macro_type, int *str); | ||
| 38 | LIBTCCAPI void tcc_set_define_func(TCCState *s, void *define_opaque, TCCDefineFunc *define_func); | ||
| 39 | |||
| 33 | /* set options as from command line (multiple supported) */ | 40 | /* set options as from command line (multiple supported) */ |
| 34 | LIBTCCAPI int tcc_set_options(TCCState *s, const char *str); | 41 | LIBTCCAPI int tcc_set_options(TCCState *s, const char *str); |
| 35 | 42 | ||
| @@ -843,6 +843,12 @@ struct TCCState { · 842 unmodified lines | |||
| 843 | /* -include options */ | 843 | /* -include options */ |
| 844 | CString cmdline_incl; | 844 | CString cmdline_incl; |
| 845 | 845 | ||
| 846 | /* user callbacks */ | ||
| 847 | void *decl_opaque; | ||
| 848 | void (*decl_func)(void *opaque, const char *filename, int line, int v, int l, CType *type); | ||
| 849 | void *define_opaque; | ||
| 850 | void (*define_func)(void *opaque, const char *filename, int line, int v, int macro_type, int *str); | ||
| 851 | |||
| 846 | /* error handling */ | 852 | /* error handling */ |
| 847 | void *error_opaque; | 853 | void *error_opaque; |
| 848 | void (*error_func)(void *opaque, const char *msg); | 854 | void (*error_func)(void *opaque, const char *msg); |
| @@ -8790,9 +8790,10 @@ static int decl(int l) · 8789 unmodified lines | |||
| 8790 | 8790 | ||
| 8791 | while (1) { /* iterate thru each declaration */ | 8791 | while (1) { /* iterate thru each declaration */ |
| 8792 | type = btype; | 8792 | type = btype; |
| 8793 | ad = adbase; | 8793 | ad = adbase; |
| 8794 | type_decl(&type, &ad, &v, l == VT_CMP ? TYPE_DIRECT | TYPE_PARAM : TYPE_DIRECT); | 8794 | type_decl(&type, &ad, &v, l == VT_CMP ? TYPE_DIRECT | TYPE_PARAM : TYPE_DIRECT); |
| 8795 | /*ptype("decl", &type, v);*/ | 8795 | /*ptype("decl", &type, v);*/ |
| 8796 | |||
| 8796 | if ((type.t & VT_BTYPE) == VT_FUNC) { | 8797 | if ((type.t & VT_BTYPE) == VT_FUNC) { |
| 8797 | if ((type.t & VT_STATIC) && (l != VT_CONST)) | 8798 | if ((type.t & VT_STATIC) && (l != VT_CONST)) |
| 8798 | tcc_error("function without file scope cannot be static"); | 8799 | tcc_error("function without file scope cannot be static"); |
| @@ -8878,6 +8879,8 @@ static int decl(int l) · 79 unmodified lines | |||
| 8878 | cur_text_section->sh_flags = text_section->sh_flags; | 8879 | cur_text_section->sh_flags = text_section->sh_flags; |
| 8879 | gen_function(sym); | 8880 | gen_function(sym); |
| 8880 | } | 8881 | } |
| 8882 | if (tcc_state->decl_func) | ||
| 8883 | tcc_state->decl_func(tcc_state->decl_opaque, file->filename, file->line_num, v, l, &type); | ||
| 8881 | break; | 8884 | break; |
| 8882 | } else { | 8885 | } else { |
| 8883 | has_init = 0; | 8886 | has_init = 0; |
| @@ -8969,6 +8972,8 @@ static int decl(int l) · 85 unmodified lines | |||
| 8969 | esym->st_value, esym->st_size, 1); | 8972 | esym->st_value, esym->st_size, 1); |
| 8970 | } | 8973 | } |
| 8971 | } | 8974 | } |
| 8975 | if (tcc_state->decl_func) | ||
| 8976 | tcc_state->decl_func(tcc_state->decl_opaque, file->filename, file->line_num, v, l, &type); | ||
| 8972 | if (tok != ',') { | 8977 | if (tok != ',') { |
| 8973 | if (l == VT_JMP) | 8978 | if (l == VT_JMP) |
| 8974 | return has_init ? v : 1; | 8979 | return has_init ? v : 1; |
| @@ -1266,6 +1266,7 @@ static int macro_is_equal(const int *a, const int *b) · 1265 unmodified lines | |||
| 1266 | /* defines handling */ | 1266 | /* defines handling */ |
| 1267 | ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg) | 1267 | ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg) |
| 1268 | { | 1268 | { |
| 1269 | TCCState *s1 = tcc_state; | ||
| 1269 | Sym *s, *o; | 1270 | Sym *s, *o; |
| 1270 | 1271 | ||
| 1271 | o = define_find(v); | 1272 | o = define_find(v); |
| @@ -1274,8 +1275,11 @@ ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg) · 2 unmodified lines | |||
| 1274 | s->next = first_arg; | 1275 | s->next = first_arg; |
| 1275 | table_ident[v - TOK_IDENT]->sym_define = s; | 1276 | table_ident[v - TOK_IDENT]->sym_define = s; |
| 1276 | 1277 | ||
| 1278 | if (s1->define_func != NULL) | ||
| 1279 | s1->define_func(s1->define_opaque, file->filename, file->line_num, v, macro_type, str); | ||
| 1280 | |||
| 1277 | if (o && !macro_is_equal(o->d, s->d)) | 1281 | if (o && !macro_is_equal(o->d, s->d)) |
| 1278 | tcc_warning("%s redefined", get_tok_str(v, NULL)); | 1282 | tcc_warning("%s redefined", get_tok_str(v, NULL)); |
| 1279 | } | 1283 | } |
| 1280 | 1284 | ||
| 1281 | /* undefined a define symbol. Its name is just set to zero */ | 1285 | /* undefined a define symbol. Its name is just set to zero */ |