| @@ -1138,21 +1138,15 @@ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname) · 1137 unmodified lines |
| 1138 | 1138 | return 0; |
| 1139 | 1139 | } |
| 1140 | 1140 | |
| 1141 | | −ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) |
| 1141 | +ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags, int filetype) |
| 1142 | 1142 | { |
| 1143 | | − const char *ext; |
| 1144 | 1143 | ElfW(Ehdr) ehdr; |
| 1145 | 1144 | int fd, ret, size; |
| 1146 | 1145 | |
| 1147 | | − /* find source file type with extension */ |
| 1148 | | − ext = tcc_fileextension(filename); |
| 1149 | | − if (ext[0]) |
| 1150 | | − ext++; |
| 1151 | | − |
| 1152 | 1146 | parse_flags = 0; |
| 1153 | 1147 | #ifdef CONFIG_TCC_ASM |
| 1154 | 1148 | /* if .S file, define __ASSEMBLER__ like gcc does */ |
| 1155 | | − if (!strcmp(ext, "S") || !strcmp(ext, "s")) { |
| 1149 | + if ((filetype == TCC_FILETYPE_ASM) || (filetype == TCC_FILETYPE_ASM_PP)) { |
| 1156 | 1150 | tcc_define_symbol(s1, "__ASSEMBLER__", NULL); |
| 1157 | 1151 | parse_flags = PARSE_FLAG_ASM_FILE; |
| 1158 | 1152 | } |
| @@ -1175,20 +1169,20 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 16 unmodified lines |
| 1175 | 1169 | goto the_end; |
| 1176 | 1170 | } |
| 1177 | 1171 | |
| 1178 | | − if (!ext[0] || !PATHCMP(ext, "c") || !PATHCMP(ext, "i")) { |
| 1172 | + if (filetype == TCC_FILETYPE_C) { |
| 1179 | 1173 | /* C file assumed */ |
| 1180 | 1174 | ret = tcc_compile(s1); |
| 1181 | 1175 | goto the_end; |
| 1182 | 1176 | } |
| 1183 | 1177 | |
| 1184 | 1178 | #ifdef CONFIG_TCC_ASM |
| 1185 | | − if (!strcmp(ext, "S")) { |
| 1179 | + if (filetype == TCC_FILETYPE_ASM_PP) { |
| 1186 | 1180 | /* non preprocessed assembler */ |
| 1187 | 1181 | ret = tcc_assemble(s1, 1); |
| 1188 | 1182 | goto the_end; |
| 1189 | 1183 | } |
| 1190 | 1184 | |
| 1191 | | − if (!strcmp(ext, "s")) { |
| 1185 | + if (filetype == TCC_FILETYPE_ASM) { |
| 1192 | 1186 | /* preprocessed assembler */ |
| 1193 | 1187 | ret = tcc_assemble(s1, 0); |
| 1194 | 1188 | goto the_end; |
| @@ -1264,12 +1258,12 @@ the_end: · 69 unmodified lines |
| 1264 | 1258 | return ret; |
| 1265 | 1259 | } |
| 1266 | 1260 | |
| 1267 | | −LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) |
| 1261 | +LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename, int filetype) |
| 1268 | 1262 | { |
| 1269 | 1263 | if (s->output_type == TCC_OUTPUT_PREPROCESS) |
| 1270 | | − return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS); |
| 1264 | + return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS, filetype); |
| 1271 | 1265 | else |
| 1272 | | − return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR); |
| 1266 | + return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR, filetype); |
| 1273 | 1267 | } |
| 1274 | 1268 | |
| 1275 | 1269 | LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname) |
| @@ -1286,7 +1280,7 @@ static int tcc_add_library_internal(TCCState *s, const char *fmt, · 10 unmodified lines |
| 1286 | 1280 | |
| 1287 | 1281 | for(i = 0; i < nb_paths; i++) { |
| 1288 | 1282 | snprintf(buf, sizeof(buf), fmt, paths[i], filename); |
| 1289 | | − if (tcc_add_file_internal(s, buf, flags) == 0) |
| 1283 | + if (tcc_add_file_internal(s, buf, flags, TCC_FILETYPE_BINARY) == 0) |
| 1290 | 1284 | return 0; |
| 1291 | 1285 | } |
| 1292 | 1286 | return -1; |
| @@ -1782,6 +1776,37 @@ static void parse_option_D(TCCState *s1, const char *optarg) · 489 unmodified lines |
| 1782 | 1776 | tcc_free(sym); |
| 1783 | 1777 | } |
| 1784 | 1778 | |
| 1779 | +static void args_parser_add_file(TCCState *s, const char* filename, int filetype) |
| 1780 | +{ |
| 1781 | + int len = strlen(filename); |
| 1782 | + char *p = tcc_malloc(len + 2); |
| 1783 | + if (filetype) { |
| 1784 | + *p = filetype; |
| 1785 | + } |
| 1786 | + else { |
| 1787 | + /* use a file extension to detect a filetype */ |
| 1788 | + const char *ext = tcc_fileextension(filename); |
| 1789 | + if (ext[0]) { |
| 1790 | + ext++; |
| 1791 | + if (!strcmp(ext, "S")) |
| 1792 | + *p = TCC_FILETYPE_ASM_PP; |
| 1793 | + else |
| 1794 | + if (!strcmp(ext, "s")) |
| 1795 | + *p = TCC_FILETYPE_ASM; |
| 1796 | + else |
| 1797 | + if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i")) |
| 1798 | + *p = TCC_FILETYPE_C; |
| 1799 | + else |
| 1800 | + *p = TCC_FILETYPE_BINARY; |
| 1801 | + } |
| 1802 | + else { |
| 1803 | + *p = TCC_FILETYPE_C; |
| 1804 | + } |
| 1805 | + } |
| 1806 | + strcpy(p+1, filename); |
| 1807 | + dynarray_add((void ***)&s->files, &s->nb_files, p); |
| 1808 | +} |
| 1809 | + |
| 1785 | 1810 | PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) |
| 1786 | 1811 | { |
| 1787 | 1812 | const TCCOption *popt; |
| @@ -1789,6 +1814,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 1 unmodified line |
| 1789 | 1814 | int run = 0; |
| 1790 | 1815 | int pthread = 0; |
| 1791 | 1816 | int optind = 0; |
| 1817 | + int filetype = 0; |
| 1792 | 1818 | |
| 1793 | 1819 | /* collect -Wl options for input such as "-Wl,-rpath -Wl,<path>" */ |
| 1794 | 1820 | CString linker_arg; |
| @@ -1798,8 +1824,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 3 unmodified lines |
| 1798 | 1824 | |
| 1799 | 1825 | r = argv[optind++]; |
| 1800 | 1826 | if (r[0] != '-' || r[1] == '\0') { |
| 1801 | | − /* add a new file */ |
| 1802 | | − dynarray_add((void ***)&s->files, &s->nb_files, tcc_strdup(r)); |
| 1827 | + args_parser_add_file(s, r, filetype); |
| 1803 | 1828 | if (run) { |
| 1804 | 1829 | optind--; |
| 1805 | 1830 | /* argv[0] will be this file */ |
| @@ -1849,7 +1874,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 43 unmodified lines |
| 1849 | 1874 | tcc_set_lib_path(s, optarg); |
| 1850 | 1875 | break; |
| 1851 | 1876 | case TCC_OPTION_l: |
| 1852 | | − dynarray_add((void ***)&s->files, &s->nb_files, tcc_strdup(r)); |
| 1877 | + args_parser_add_file(s, r, TCC_FILETYPE_BINARY); |
| 1853 | 1878 | s->nb_libraries++; |
| 1854 | 1879 | break; |
| 1855 | 1880 | case TCC_OPTION_pthread: |
| @@ -1989,10 +2014,21 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 133 unmodified lines |
| 1989 | 2014 | case TCC_OPTION_s: |
| 1990 | 2015 | s->do_strip = 1; |
| 1991 | 2016 | break; |
| 2017 | + case TCC_OPTION_x: |
| 2018 | + if (*optarg == 'c') |
| 2019 | + filetype = TCC_FILETYPE_C; |
| 2020 | + else |
| 2021 | + if (*optarg == 'a') |
| 2022 | + filetype = TCC_FILETYPE_ASM_PP; |
| 2023 | + else |
| 2024 | + if (*optarg == 'n') |
| 2025 | + filetype = 0; |
| 2026 | + else |
| 2027 | + tcc_warning("unsupported language '%s'", optarg); |
| 2028 | + break; |
| 1992 | 2029 | case TCC_OPTION_O: |
| 1993 | 2030 | case TCC_OPTION_pedantic: |
| 1994 | 2031 | case TCC_OPTION_pipe: |
| 1995 | | − case TCC_OPTION_x: |
| 1996 | 2032 | /* ignored */ |
| 1997 | 2033 | break; |
| 1998 | 2034 | default: |