From 3b0540edd0e0cbe4534e2b4b44aecf53144bd8ab Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 5 Oct 2021 11:52:26 +0200 Subject: [PATCH] wrc: Avoid using getopt_long(). Signed-off-by: Alexandre Julliard --- tools/wrc/wrc.c | 345 +++++++++++++++++++++++------------------------- tools/wrc/wrc.h | 3 +- 2 files changed, 167 insertions(+), 181 deletions(-) diff --git a/tools/wrc/wrc.c b/tools/wrc/wrc.c index 4e2fdb56567..69faaf370a4 100644 --- a/tools/wrc/wrc.c +++ b/tools/wrc/wrc.c @@ -31,9 +31,6 @@ #include #include #include -#ifdef HAVE_GETOPT_H -# include -#endif #include "../tools.h" #include "wrc.h" @@ -154,9 +151,14 @@ static int pointer_size = sizeof(void *); static int verify_translations_mode; static char *output_name; /* The name given by the -o option */ -char *input_name = NULL; /* The name given on the command-line */ +const char *input_name = NULL; /* The name given on the command-line */ static char *temp_name = NULL; /* Temporary file for preprocess pipe */ +static struct strarray input_files; +static int stdinc = 1; +static int po_mode; +static const char *po_dir; +static const char *sysroot = ""; static const char *includedir; const char *nlsdirs[3] = { NULL, NLSDIR, NULL }; @@ -188,32 +190,32 @@ enum long_options_values static const char short_options[] = "b:D:Ef:F:hi:I:J:l:m:o:O:ruU:v"; -static const struct option long_options[] = { - { "debug", 1, NULL, LONG_OPT_DEBUG }, - { "define", 1, NULL, 'D' }, - { "endianness", 1, NULL, LONG_OPT_ENDIANNESS }, - { "help", 0, NULL, 'h' }, - { "include-dir", 1, NULL, 'I' }, - { "input", 1, NULL, 'i' }, - { "input-format", 1, NULL, 'J' }, - { "language", 1, NULL, 'l' }, - { "nls-dir", 1, NULL, LONG_OPT_NLS_DIR }, - { "no-use-temp-file", 0, NULL, LONG_OPT_NOTMPFILE }, - { "nostdinc", 0, NULL, LONG_OPT_NOSTDINC }, - { "output", 1, NULL, 'o' }, - { "output-format", 1, NULL, 'O' }, - { "pedantic", 0, NULL, LONG_OPT_PEDANTIC }, - { "po-dir", 1, NULL, LONG_OPT_PO_DIR }, - { "preprocessor", 1, NULL, LONG_OPT_PREPROCESSOR }, - { "sysroot", 1, NULL, LONG_OPT_SYSROOT }, - { "target", 1, NULL, 'F' }, - { "utf8", 0, NULL, 'u' }, - { "undefine", 1, NULL, 'U' }, - { "use-temp-file", 0, NULL, LONG_OPT_TMPFILE }, - { "verbose", 0, NULL, 'v' }, - { "verify-translations", 0, NULL, LONG_OPT_VERIFY_TRANSL }, - { "version", 0, NULL, LONG_OPT_VERSION }, - { NULL, 0, NULL, 0 } +static const struct long_option long_options[] = { + { "debug", 1, LONG_OPT_DEBUG }, + { "define", 1, 'D' }, + { "endianness", 1, LONG_OPT_ENDIANNESS }, + { "help", 0, 'h' }, + { "include-dir", 1, 'I' }, + { "input", 1, 'i' }, + { "input-format", 1, 'J' }, + { "language", 1, 'l' }, + { "nls-dir", 1, LONG_OPT_NLS_DIR }, + { "no-use-temp-file", 0, LONG_OPT_NOTMPFILE }, + { "nostdinc", 0, LONG_OPT_NOSTDINC }, + { "output", 1, 'o' }, + { "output-format", 1, 'O' }, + { "pedantic", 0, LONG_OPT_PEDANTIC }, + { "po-dir", 1, LONG_OPT_PO_DIR }, + { "preprocessor", 1, LONG_OPT_PREPROCESSOR }, + { "sysroot", 1, LONG_OPT_SYSROOT }, + { "target", 1, 'F' }, + { "utf8", 0, 'u' }, + { "undefine", 1, 'U' }, + { "use-temp-file", 0, LONG_OPT_TMPFILE }, + { "verbose", 0, 'v' }, + { "verify-translations", 0, LONG_OPT_VERIFY_TRANSL }, + { "version", 0, LONG_OPT_VERSION }, + { NULL } }; static void set_version_defines(void) @@ -350,18 +352,136 @@ static void init_argv0_dir( const char *argv0 ) #endif } +static void option_callback( int optc, char *optarg ) +{ + switch(optc) + { + case LONG_OPT_NOSTDINC: + stdinc = 0; + break; + case LONG_OPT_TMPFILE: + if (debuglevel) warning("--use-temp-file option not yet supported, ignored.\n"); + break; + case LONG_OPT_NOTMPFILE: + if (debuglevel) warning("--no-use-temp-file option not yet supported, ignored.\n"); + break; + case LONG_OPT_NLS_DIR: + nlsdirs[0] = xstrdup( optarg ); + break; + case LONG_OPT_PO_DIR: + po_dir = xstrdup( optarg ); + break; + case LONG_OPT_PREPROCESSOR: + if (strcmp(optarg, "cat") == 0) no_preprocess = 1; + else fprintf(stderr, "-P option not yet supported, ignored.\n"); + break; + case LONG_OPT_SYSROOT: + sysroot = xstrdup( optarg ); + break; + case LONG_OPT_VERSION: + printf(version_string); + exit(0); + break; + case LONG_OPT_DEBUG: + debuglevel = strtol(optarg, NULL, 0); + break; + case LONG_OPT_ENDIANNESS: + switch(optarg[0]) + { + case 'n': + case 'N': + byteorder = WRC_BO_NATIVE; + break; + case 'l': + case 'L': + byteorder = WRC_BO_LITTLE; + break; + case 'b': + case 'B': + byteorder = WRC_BO_BIG; + break; + default: + error("Byte ordering must be n[ative], l[ittle] or b[ig]\n"); + } + break; + case LONG_OPT_PEDANTIC: + pedantic = 1; + break; + case LONG_OPT_VERIFY_TRANSL: + verify_translations_mode = 1; + break; + case 'D': + wpp_add_cmdline_define(optarg); + break; + case 'E': + preprocess_only = 1; + break; + case 'b': + case 'F': + set_target( optarg ); + break; + case 'h': + printf(usage); + exit(0); + case 'i': + strarray_add( &input_files, optarg ); + break; + case 'I': + wpp_add_include_path(optarg); + break; + case 'J': + if (strcmp(optarg, "rc16") == 0) extensions = 0; + else if (strcmp(optarg, "rc")) error("Output format %s not supported.\n", optarg); + break; + case 'l': + { + int lan; + lan = strtol(optarg, NULL, 0); + if (get_language_codepage(PRIMARYLANGID(lan), SUBLANGID(lan)) == -1) + error("Language %04x is not supported\n", lan); + defaultlanguage = new_language(PRIMARYLANGID(lan), SUBLANGID(lan)); + } + break; + case 'm': + if (!strcmp( optarg, "16" )) win32 = 0; + else if (!strcmp( optarg, "32" )) { win32 = 1; pointer_size = 4; } + else if (!strcmp( optarg, "64" )) { win32 = 1; pointer_size = 8; } + break; + case 'f': + if (*optarg != 'o') error("Unknown option: -f%s\n", optarg); + optarg++; + /* fall through */ + case 'o': + if (!output_name) output_name = strdup(optarg); + else error("Too many output files.\n"); + break; + case 'O': + if (strcmp(optarg, "po") == 0) po_mode = 1; + else if (strcmp(optarg, "pot") == 0) po_mode = 2; + else if (strcmp(optarg, "res16") == 0) win32 = 0; + else if (strcmp(optarg, "res")) warning("Output format %s not supported.\n", optarg); + break; + case 'r': + /* ignored for compatibility with rc */ + break; + case 'u': + utf8_input = 1; + break; + case 'U': + wpp_del_define(optarg); + break; + case 'v': + debuglevel = DEBUGLEVEL_CHAT; + break; + case '?': + fprintf(stderr, "wrc: %s\n\n%s", optarg, usage); + exit(1); + } +} + int main(int argc,char *argv[]) { - int optc; - int opti = 0; - int stdinc = 1; - int lose = 0; - int nb_files = 0; int i; - int po_mode = 0; - char *po_dir = NULL; - const char *sysroot = ""; - char **files = xmalloc( argc * sizeof(*files) ); signal(SIGSEGV, segvhandler); signal( SIGTERM, exit_on_signal ); @@ -377,139 +497,8 @@ int main(int argc,char *argv[]) /* Microsoft RC always searches current directory */ wpp_add_include_path("."); - while((optc = getopt_long(argc, argv, short_options, long_options, &opti)) != EOF) - { - switch(optc) - { - case LONG_OPT_NOSTDINC: - stdinc = 0; - break; - case LONG_OPT_TMPFILE: - if (debuglevel) warning("--use-temp-file option not yet supported, ignored.\n"); - break; - case LONG_OPT_NOTMPFILE: - if (debuglevel) warning("--no-use-temp-file option not yet supported, ignored.\n"); - break; - case LONG_OPT_NLS_DIR: - nlsdirs[0] = xstrdup( optarg ); - break; - case LONG_OPT_PO_DIR: - po_dir = xstrdup( optarg ); - break; - case LONG_OPT_PREPROCESSOR: - if (strcmp(optarg, "cat") == 0) no_preprocess = 1; - else fprintf(stderr, "-P option not yet supported, ignored.\n"); - break; - case LONG_OPT_SYSROOT: - sysroot = xstrdup( optarg ); - break; - case LONG_OPT_VERSION: - printf(version_string); - exit(0); - break; - case LONG_OPT_DEBUG: - debuglevel = strtol(optarg, NULL, 0); - break; - case LONG_OPT_ENDIANNESS: - switch(optarg[0]) - { - case 'n': - case 'N': - byteorder = WRC_BO_NATIVE; - break; - case 'l': - case 'L': - byteorder = WRC_BO_LITTLE; - break; - case 'b': - case 'B': - byteorder = WRC_BO_BIG; - break; - default: - fprintf(stderr, "Byte ordering must be n[ative], l[ittle] or b[ig]\n"); - lose++; - } - break; - case LONG_OPT_PEDANTIC: - pedantic = 1; - break; - case LONG_OPT_VERIFY_TRANSL: - verify_translations_mode = 1; - break; - case 'D': - wpp_add_cmdline_define(optarg); - break; - case 'E': - preprocess_only = 1; - break; - case 'b': - case 'F': - set_target( optarg ); - break; - case 'h': - printf(usage); - exit(0); - case 'i': - files[nb_files++] = optarg; - break; - case 'I': - wpp_add_include_path(optarg); - break; - case 'J': - if (strcmp(optarg, "rc16") == 0) extensions = 0; - else if (strcmp(optarg, "rc")) error("Output format %s not supported.\n", optarg); - break; - case 'l': - { - int lan; - lan = strtol(optarg, NULL, 0); - if (get_language_codepage(PRIMARYLANGID(lan), SUBLANGID(lan)) == -1) - error("Language %04x is not supported\n", lan); - defaultlanguage = new_language(PRIMARYLANGID(lan), SUBLANGID(lan)); - } - break; - case 'm': - if (!strcmp( optarg, "16" )) win32 = 0; - else if (!strcmp( optarg, "32" )) { win32 = 1; pointer_size = 4; } - else if (!strcmp( optarg, "64" )) { win32 = 1; pointer_size = 8; } - break; - case 'f': - if (*optarg != 'o') error("Unknown option: -f%s\n", optarg); - optarg++; - /* fall through */ - case 'o': - if (!output_name) output_name = strdup(optarg); - else error("Too many output files.\n"); - break; - case 'O': - if (strcmp(optarg, "po") == 0) po_mode = 1; - else if (strcmp(optarg, "pot") == 0) po_mode = 2; - else if (strcmp(optarg, "res16") == 0) win32 = 0; - else if (strcmp(optarg, "res")) warning("Output format %s not supported.\n", optarg); - break; - case 'r': - /* ignored for compatibility with rc */ - break; - case 'u': - utf8_input = 1; - break; - case 'U': - wpp_del_define(optarg); - break; - case 'v': - debuglevel = DEBUGLEVEL_CHAT; - break; - default: - lose++; - break; - } - } - - if(lose) - { - fprintf(stderr, usage); - return 1; - } + strarray_addall( &input_files, + parse_options( argc, argv, short_options, long_options, 0, option_callback )); if (win32) { @@ -555,15 +544,13 @@ int main(int argc,char *argv[]) atexit(cleanup_files); - while (optind < argc) files[nb_files++] = argv[optind++]; - - for (i = 0; i < nb_files; i++) + for (i = 0; i < input_files.count; i++) { - input_name = files[i]; + input_name = input_files.str[i]; if (load_file( input_name, output_name )) exit(1); } /* stdin special case. NULL means "stdin" for wpp. */ - if (nb_files == 0 && load_file( NULL, output_name )) exit(1); + if (input_files.count == 0 && load_file( NULL, output_name )) exit(1); if(debuglevel & DEBUGLEVEL_DUMP) dump_resources(resource_top); @@ -585,7 +572,7 @@ int main(int argc,char *argv[]) { if (!output_name) { - const char *name = nb_files ? get_basename(files[0]) : "wrc.tab"; + const char *name = input_files.count ? get_basename(input_files.str[0]) : "wrc.tab"; output_name = replace_extension( name, ".rc", ".pot" ); } write_pot_file( output_name ); @@ -602,7 +589,7 @@ int main(int argc,char *argv[]) chat("Writing .res-file\n"); if (!output_name) { - const char *name = nb_files ? get_basename(files[0]) : "wrc.tab"; + const char *name = input_files.count ? get_basename(input_files.str[0]) : "wrc.tab"; output_name = replace_extension( name, ".rc", ".res" ); } write_resfile(output_name, resource_top); diff --git a/tools/wrc/wrc.h b/tools/wrc/wrc.h index d086c5c60f9..78caab6fb84 100644 --- a/tools/wrc/wrc.h +++ b/tools/wrc/wrc.h @@ -41,8 +41,7 @@ extern int no_preprocess; extern int utf8_input; extern int check_utf8; -extern char *input_name; - +extern const char *input_name; extern const char *nlsdirs[]; extern int line_number;