better command line parsing - added -r option

This commit is contained in:
bellard 2002-08-30 22:46:35 +00:00
parent d2115bfb27
commit 6dd6a026c3

106
tcc.c
View File

@ -7213,16 +7213,18 @@ void help(void)
" -llib link with dynamic or static library 'lib'\n" " -llib link with dynamic or static library 'lib'\n"
" -shared generate a shared library\n" " -shared generate a shared library\n"
" -static static linking\n" " -static static linking\n"
" -r relocatable output\n"
); );
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
char *r, *outfile; char *r, *outfile;
int optind, output_type, multiple_files, i; int optind, output_type, multiple_files, i, reloc_output;
TCCState *s; TCCState *s;
char **libraries; char **files;
int nb_libraries; int nb_files, nb_libraries, nb_objfiles;
char objfilename[1024];
s = tcc_new(); s = tcc_new();
output_type = TCC_OUTPUT_MEMORY; output_type = TCC_OUTPUT_MEMORY;
@ -7230,23 +7232,37 @@ int main(int argc, char **argv)
optind = 1; optind = 1;
outfile = NULL; outfile = NULL;
multiple_files = 0; multiple_files = 0;
libraries = NULL; files = NULL;
nb_files = 0;
nb_libraries = 0; nb_libraries = 0;
reloc_output = 0;
while (1) { while (1) {
if (optind >= argc) { if (optind >= argc) {
if (nb_files == 0)
goto show_help;
else
break;
}
r = argv[optind++];
if (r[0] != '-') {
/* add a new file */
dynarray_add((void ***)&files, &nb_files, r);
if (!multiple_files) {
optind--;
/* argv[0] will be this file */
break;
}
} else if (r[1] == '-') {
/* '--' enables multiple files input and also ends several file input */
if (multiple_files) {
optind--; /* argv[0] will be '--' */
break;
}
multiple_files = 1;
} else if (r[1] == 'h' || r[1] == '?') {
show_help: show_help:
help(); help();
return 1; return 1;
}
r = argv[optind];
if (r[0] != '-')
break;
optind++;
if (r[1] == '-') {
/* '--' enables multiple files input */
multiple_files = 1;
} else if (r[1] == 'h' || r[1] == '?') {
goto show_help;
} else if (r[1] == 'I') { } else if (r[1] == 'I') {
if (tcc_add_include_path(s, r + 2) < 0) if (tcc_add_include_path(s, r + 2) < 0)
error("too many include paths"); error("too many include paths");
@ -7267,7 +7283,8 @@ int main(int argc, char **argv)
/* set tcc utilities path (mainly for tcc development) */ /* set tcc utilities path (mainly for tcc development) */
tcc_lib_path = r + 2; tcc_lib_path = r + 2;
} else if (r[1] == 'l') { } else if (r[1] == 'l') {
dynarray_add((void ***)&libraries, &nb_libraries, r + 2); dynarray_add((void ***)&files, &nb_files, r);
nb_libraries++;
} else if (!strcmp(r + 1, "bench")) { } else if (!strcmp(r + 1, "bench")) {
do_bench = 1; do_bench = 1;
} else } else
@ -7291,36 +7308,61 @@ int main(int argc, char **argv)
goto show_help; goto show_help;
multiple_files = 1; multiple_files = 1;
outfile = argv[optind++]; outfile = argv[optind++];
} else if (r[1] == 'r') {
/* generate a .o merging several output files */
reloc_output = 1;
output_type = TCC_OUTPUT_OBJ;
} else { } else {
error("invalid option -- '%s'", r); error("invalid option -- '%s'", r);
} }
} }
nb_objfiles = nb_files - nb_libraries;
/* if outfile provided without other options, we output an /* if outfile provided without other options, we output an
executable */ executable */
if (outfile && output_type == TCC_OUTPUT_MEMORY) if (outfile && output_type == TCC_OUTPUT_MEMORY)
output_type = TCC_OUTPUT_EXE; output_type = TCC_OUTPUT_EXE;
tcc_set_output_type(s, output_type);
tcc_add_file(s, argv[optind]); /* check -c consistency : only single file handled. XXX: checks file type */
if (multiple_files) { if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
while ((optind + 1) < argc) { /* accepts only a single input file */
optind++; if (nb_objfiles != 1)
r = argv[optind]; error("cannot specify multiple files with -c");
if (r[0] == '-') { if (nb_libraries != 0)
if (r[1] != '-') error("cannot specify libraries with -c");
error("'--' expected"); }
break;
} /* compute default outfile name */
tcc_add_file(s, r); if (output_type != TCC_OUTPUT_MEMORY && !outfile) {
if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
char *ext;
/* add .o extension */
pstrcpy(objfilename, sizeof(objfilename) - 1, files[0]);
ext = strrchr(objfilename, '.');
if (!ext)
goto default_outfile;
strcpy(ext + 1, "o");
} else {
default_outfile:
pstrcpy(objfilename, sizeof(objfilename), "a.out");
} }
outfile = objfilename;
} }
/* add specified libraries */ tcc_set_output_type(s, output_type);
for(i = 0; i < nb_libraries;i++) {
if (tcc_add_library(s, libraries[i]) < 0) /* compile or add each files or library */
error("cannot find -l%s", libraries[i]); for(i = 0;i < nb_files; i++) {
const char *filename;
filename = files[i];
if (filename[0] == '-') {
if (tcc_add_library(s, filename + 2) < 0)
error("cannot find %s", filename);
} else {
tcc_add_file(s, filename);
}
} }
if (do_bench) { if (do_bench) {