Package: gcc-9 Version: 9.3.0-3 Severity: normal Dear Maintainer,
I am writing a general purpose convenience library called Mu (for Miscellaneous Utilities). It includes an option parsing module intended to be a replacement for getopt_long(). Options are defined in structures which include various information, including an optional callback which will be called when the option is found. The parse_opts() function has a flag `OPT_HELP' (or `OPT_HELP_SHORT' or `OPT_HELP_LONG') which makes it automatically add a '-h' and/or a '--help' option which calls a callback to print a usage message. The problem is, when the test program (test.c) is compiled with optimization, the data fields (set at options.c:127-131) passed to the callback are optimized out. This causes a segmentation fault and/or error message when './test' is passed '-h' or '--help'. Note that when the program is compiled without optimization, no memory errors are reported when run under Valgrind (although memory errors *are* reported when the program is compiled with optimization). I thought that the problem may have been that I was casting the data pointer to (void *), but I tried creating a test program to test that, and that didn't seem to be the problem. To compile the program with optimization, I ran: $ make CC=gcc-9 CFLAGS='-Wall -O1' clean all And without optimization: $ make CC=gcc-9 CFLAGS='-Wall -O0' clean all Note that the problem can be reproduced with GCC 10 also (CC=gcc-10). Also note that no warnings are reported with -Wall, not even with -O3. Three warnings are reported with -Werror, but I don't think they are serious or relevant. Here they are, just in case (compiled with -O3 to catch warnings it might not otherwise): $ make CC=gcc-9 CFLAGS='-Wall -Wextra -O3' clean all rm -f *.o test gcc-9 -Wall -Wextra -O3 -c -o test.o test.c gcc-9 -Wall -Wextra -O3 -c -o compat.o compat.c gcc-9 -Wall -Wextra -O3 -c -o format.o format.c format.c: In function ‘format_list’: format.c:277:36: warning: comparison of integer expressions of different signedness: ‘size_t’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare] 277 | if (width && size + char_width > width - *col) { | ^ In file included from format.c:34: format.c:303:27: warning: comparison of integer expressions of different signedness: ‘size_t’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare] 303 | assert(index + tab_width > width - *col); | ^ format.c:314:19: warning: comparison of integer expressions of different signedness: ‘size_t’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare] 314 | assert(index + 1 > width - *col); | ^ gcc-9 -Wall -Wextra -O3 -c -o io.o io.c gcc-9 -Wall -Wextra -O3 -c -o options.o options.c gcc-9 -Wall -Wextra -O3 -c -o safe.o safe.c gcc-9 test.o compat.o format.o io.o options.o safe.o -o test Also note that when compiled with Clang (CC=clang), even with -O3, the program works as expected and no memory errors are reported by Valgrind. Note that only the -O* and all the -O* options trigger the bug. I tried manually passing all the -f* options which (according to the documentation) are enabled by the various -O* options. However, strangely, I could not reproduce the bug that way. The following patch adds a nop() function to options.c that is used to prevent the data fields from being optimized out. When this patch is applied, the issue is no longer present, even when compiled with -O3 (with gcc-9 or gcc-10).
--- options.c~ 2020-03-23 14:23:08.625333110 -0400 +++ options.c 2020-03-23 14:23:17.841369826 -0400 @@ -81,6 +81,13 @@ static int free_opts(const char *, const OPTION *); static int format_help_callback(void *, char *); +static void nop(const void *data, ...) { + /* We have to do this so GCC doesn't optimize calls to us away. */ + va_list ap; + va_start(ap, data); + va_end(ap); +} + /* * Parse options. Returns zero on success or nonzero on error, in * which case an error message will be printed to `stderr'. The last @@ -137,6 +144,7 @@ opt->callback_none = format_help_callback; opt->data = &data; opt->help = "print this help and exit"; + nop(data.prog_name, data.usage, data.desc, data.notes, data.options); } else { /* This is slightly evil (casting it to a non-const), but we know
Since I was not able write a simpler program that triggers the bug, I have attached the source tarball (mu.tar.gz). README.Bugs says that I should provide the *.i files, so I have included them in the tarball. Different .i files are produced under optimization, so I have included the ones produced with '-O0 --save-temps'. I have also attached a patch (nop_preprocessed.patch) that adds the nop() function to the preprocessed options.i. Here is the output of 'gcc-9 -v' and 'gcc-10 -v': $ gcc-9 -v Using built-in specs. COLLECT_GCC=gcc-9 COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none:hsa OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 9.3.0-3' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-mutex Thread model: posix gcc version 9.3.0 (Debian 9.3.0-3) $ gcc-10 -v Using built-in specs. COLLECT_GCC=gcc-10 COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/10/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa:hsa OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 10-20200312-2' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none,amdgcn-amdhsa,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 10.0.1 20200312 (experimental) [master revision c56871dd15a:7ba6e7f0f21:daf2852b883762d921361462dad1f99320faca2a] (Debian 10-20200312-2) I think this may be an upstream bug, but I'm not sure and README.Bugs says "If in doubt, report the bug to the Debian BTS." Thanks, Asher -- He was part of my dream, of course -- but then I was part of his dream too. -- Lewis Carroll -------- I prefer to send and receive mail encrypted. Please send me your public key, and if you do not have my public key, please let me know. Thanks. GPG fingerprint: 38F3 975C D173 4037 B397 8095 D4C9 C4FC 5460 8E68 -- System Information: Debian Release: bullseye/sid APT prefers testing-debug APT policy: (500, 'testing-debug'), (500, 'testing') Architecture: amd64 (x86_64) Kernel: Linux 5.4.0-4-amd64 (SMP w/2 CPU cores) Kernel taint flags: TAINT_FIRMWARE_WORKAROUND Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled Versions of packages gcc-9 depends on: ii binutils 2.34-5 ii cpp-9 9.3.0-3 ii gcc-9-base 9.3.0-3 ii libc6 2.30-2 ii libcc1-0 10-20200312-2 ii libgcc-9-dev 9.3.0-3 ii libgcc-s1 10-20200312-2 ii libgmp10 2:6.2.0+dfsg-4 ii libisl22 0.22.1-1 ii libmpc3 1.1.0-1 ii libmpfr6 4.0.2-1 ii libstdc++6 10-20200312-2 ii zlib1g 1:1.2.11.dfsg-2 Versions of packages gcc-9 recommends: ii libc6-dev 2.30-2 Versions of packages gcc-9 suggests: ii gcc-9-doc 9.2.0-1 pn gcc-9-locales <none> pn gcc-9-multilib <none> -- no debconf information
mu.tar.gz
Description: Mu source tarball
--- options.i~ 2020-03-23 14:56:38.434556710 -0400 +++ options.i 2020-03-23 14:56:47.334654330 -0400 @@ -2487,6 +2487,33 @@ static int free_opts(const char *, const OPTION *); static int format_help_callback(void *, char *); +static void nop(const void *data, ...) { + + va_list ap; + +# 87 "options.c" 3 4 + __builtin_va_start( +# 87 "options.c" + ap +# 87 "options.c" 3 4 + , +# 87 "options.c" + data +# 87 "options.c" 3 4 + ) +# 87 "options.c" + ; + +# 88 "options.c" 3 4 + __builtin_va_end( +# 88 "options.c" + ap +# 88 "options.c" 3 4 + ) +# 88 "options.c" + ; +} + @@ -2513,51 +2540,51 @@ for (n_opts = 0; !((options + n_opts)->short_opt == '\0' && (options + n_opts)->long_opt == -# 109 "options.c" 3 4 +# 116 "options.c" 3 4 ((void *)0) -# 109 "options.c" +# 116 "options.c" ); n_opts++) { const OPTION *opt = options + n_opts; if (flags & 0b00001000) -# 112 "options.c" 3 4 +# 119 "options.c" 3 4 ((void) sizeof (( -# 112 "options.c" +# 119 "options.c" opt->short_opt != 'h' -# 112 "options.c" 3 4 +# 119 "options.c" 3 4 ) ? 1 : 0), __extension__ ({ if ( -# 112 "options.c" +# 119 "options.c" opt->short_opt != 'h' -# 112 "options.c" 3 4 +# 119 "options.c" 3 4 ) ; else __assert_fail ( -# 112 "options.c" +# 119 "options.c" "opt->short_opt != 'h'" -# 112 "options.c" 3 4 -, "options.c", 112, __extension__ __PRETTY_FUNCTION__); })) -# 112 "options.c" +# 119 "options.c" 3 4 +, "options.c", 119, __extension__ __PRETTY_FUNCTION__); })) +# 119 "options.c" ; if (flags & 0b00010000) -# 114 "options.c" 3 4 +# 121 "options.c" 3 4 ((void) sizeof (( -# 114 "options.c" +# 121 "options.c" !opt->long_opt || strcmp(opt->long_opt, "help") -# 114 "options.c" 3 4 +# 121 "options.c" 3 4 ) ? 1 : 0), __extension__ ({ if ( -# 114 "options.c" +# 121 "options.c" !opt->long_opt || strcmp(opt->long_opt, "help") -# 114 "options.c" 3 4 +# 121 "options.c" 3 4 ) ; else __assert_fail ( -# 114 "options.c" +# 121 "options.c" "!opt->long_opt || strcmp(opt->long_opt, \"help\")" -# 114 "options.c" 3 4 -, "options.c", 114, __extension__ __PRETTY_FUNCTION__); })) -# 114 "options.c" +# 121 "options.c" 3 4 +, "options.c", 121, __extension__ __PRETTY_FUNCTION__); })) +# 121 "options.c" ; } - actual_opts = _xmalloc_line("options.c", 118, __func__, sizeof(*actual_opts) * (n_opts + 2)); + actual_opts = _xmalloc_line("options.c", 125, __func__, sizeof(*actual_opts) * (n_opts + 2)); memcpy(actual_opts, options, sizeof(*actual_opts) * n_opts); opt = actual_opts + n_opts; @@ -2579,6 +2606,7 @@ opt->callback_none = format_help_callback; opt->data = &data; opt->help = "print this help and exit"; + nop(data.prog_name, data.usage, data.desc, data.notes, data.options); } else { @@ -2589,9 +2617,9 @@ for (const OPTION *opt = actual_opts; !((opt)->short_opt == '\0' && (opt)->long_opt == -# 149 "options.c" 3 4 +# 157 "options.c" 3 4 ((void *)0) -# 149 "options.c" +# 157 "options.c" ); opt++) { if (opt->found_opt) *(opt->found_opt) = 0; @@ -2614,51 +2642,51 @@ break; case OPT_STRING: arg->arg_string = -# 170 "options.c" 3 4 +# 178 "options.c" 3 4 ((void *)0) -# 170 "options.c" +# 178 "options.c" ; break; case OPT_FILE: arg->arg_file = -# 173 "options.c" 3 4 +# 181 "options.c" 3 4 ((void *)0) -# 173 "options.c" +# 181 "options.c" ; break; case OPT_DIRECTORY: arg->arg_directory = -# 176 "options.c" 3 4 +# 184 "options.c" 3 4 ((void *)0) -# 176 "options.c" +# 184 "options.c" ; break; default: -# 179 "options.c" 3 4 +# 187 "options.c" 3 4 ((void) sizeof (( -# 179 "options.c" +# 187 "options.c" !"Invalid option type" -# 179 "options.c" 3 4 +# 187 "options.c" 3 4 ) ? 1 : 0), __extension__ ({ if ( -# 179 "options.c" +# 187 "options.c" !"Invalid option type" -# 179 "options.c" 3 4 +# 187 "options.c" 3 4 ) ; else __assert_fail ( -# 179 "options.c" +# 187 "options.c" "!\"Invalid option type\"" -# 179 "options.c" 3 4 - , "options.c", 179, __extension__ __PRETTY_FUNCTION__); })) -# 179 "options.c" +# 187 "options.c" 3 4 + , "options.c", 187, __extension__ __PRETTY_FUNCTION__); })) +# 187 "options.c" ; } } if (opt->argstr) *(opt->argstr) = -# 184 "options.c" 3 4 +# 192 "options.c" 3 4 ((void *)0) -# 184 "options.c" +# 192 "options.c" ; } } @@ -2666,9 +2694,9 @@ for (int i = 1; i < argc; i++) { char *optstr = argv[i]; const char *arg = (i + 1 < argc) ? argv[i+1] : -# 190 "options.c" 3 4 +# 198 "options.c" 3 4 ((void *)0) -# 190 "options.c" +# 198 "options.c" ; @@ -2702,21 +2730,21 @@ if (flags & 0b00000001) { -# 222 "options.c" 3 4 +# 230 "options.c" 3 4 ((void) sizeof (( -# 222 "options.c" +# 230 "options.c" !(flags & 0b00000010) -# 222 "options.c" 3 4 +# 230 "options.c" 3 4 ) ? 1 : 0), __extension__ ({ if ( -# 222 "options.c" +# 230 "options.c" !(flags & 0b00000010) -# 222 "options.c" 3 4 +# 230 "options.c" 3 4 ) ; else __assert_fail ( -# 222 "options.c" +# 230 "options.c" "!(flags & OPT_STOP_AFTER_ARG)" -# 222 "options.c" 3 4 - , "options.c", 222, __extension__ __PRETTY_FUNCTION__); })) -# 222 "options.c" +# 230 "options.c" 3 4 + , "options.c", 230, __extension__ __PRETTY_FUNCTION__); })) +# 230 "options.c" ; argv[(*p_argc)++] = optstr; } @@ -2731,9 +2759,9 @@ if (*p_argc < argc) argv[*p_argc] = -# 235 "options.c" 3 4 +# 243 "options.c" 3 4 ((void *)0) -# 235 "options.c" +# 243 "options.c" ; return ret == -1; @@ -2753,9 +2781,9 @@ struct winsize ws; if (ioctl(fileno(file), -# 253 "options.c" 3 4 +# 261 "options.c" 3 4 0x5413 -# 253 "options.c" +# 261 "options.c" , &ws) >= 0) width = ws.ws_col; else @@ -2768,9 +2796,9 @@ if (format(file, width, &cur_col, 0, 0, "Usage: %s %s\n%s\n%s", prog_name, usage, desc, ((options)->short_opt == '\0' && (options)->long_opt == -# 264 "options.c" 3 4 +# 272 "options.c" 3 4 ((void *)0) -# 264 "options.c" +# 272 "options.c" ) ? "" : "\n")) return 1; @@ -2781,9 +2809,9 @@ long_required_arg = short_opts = 0; for (const OPTION *opt = options; !((opt)->short_opt == '\0' && (opt)->long_opt == -# 273 "options.c" 3 4 +# 281 "options.c" 3 4 ((void *)0) -# 273 "options.c" +# 281 "options.c" ); opt++) { if (opt->short_opt) { short_opts = 1; @@ -2801,9 +2829,9 @@ for (const OPTION *opt = options; !((opt)->short_opt == '\0' && (opt)->long_opt == -# 289 "options.c" 3 4 +# 297 "options.c" 3 4 ((void *)0) -# 289 "options.c" +# 297 "options.c" ); opt++) { if (opt->short_opt) { if (format(file, width, &cur_col, 0, 0, " -%c", opt->short_opt)) @@ -2832,7 +2860,7 @@ return 0; } -# 328 "options.c" +# 336 "options.c" static int parse_short_opt(const char *prog_name, const char *optstr, const char *argument, const OPTION *options, int flags) { @@ -2844,30 +2872,30 @@ for (char c = *optstr; (c = *optstr); optstr++) { const OPTION *opt; const char *argstr = -# 338 "options.c" 3 4 +# 346 "options.c" 3 4 ((void *)0) -# 338 "options.c" +# 346 "options.c" ; for (opt = options; !((opt)->short_opt == '\0' && (opt)->long_opt == -# 341 "options.c" 3 4 +# 349 "options.c" 3 4 ((void *)0) -# 341 "options.c" +# 349 "options.c" ); opt++) { if (opt->short_opt == c) break; } if (((opt)->short_opt == '\0' && (opt)->long_opt == -# 346 "options.c" 3 4 +# 354 "options.c" 3 4 ((void *)0) -# 346 "options.c" +# 354 "options.c" )) { fprintf( -# 347 "options.c" 3 4 +# 355 "options.c" 3 4 stderr -# 347 "options.c" +# 355 "options.c" , "%s: '%c': invalid option\n", prog_name, c); return -1; } @@ -2922,9 +2950,9 @@ if (*optstr == '=') { fprintf( -# 400 "options.c" 3 4 +# 408 "options.c" 3 4 stderr -# 400 "options.c" +# 408 "options.c" , "%s: %s: invalid option\n", prog_name, optstr); return -1; } @@ -2933,9 +2961,9 @@ index = find_unambiguously(options, optstr); if (index < 0) { fprintf( -# 407 "options.c" 3 4 +# 415 "options.c" 3 4 stderr -# 407 "options.c" +# 415 "options.c" , "%s: %s: invalid option\n", prog_name, optstr); return -1; } @@ -2977,9 +3005,9 @@ optstr = opt->long_opt; fprintf( -# 447 "options.c" 3 4 +# 455 "options.c" 3 4 stderr -# 447 "options.c" +# 455 "options.c" , "%s: '%s': option requires argument\n", prog_name, optstr); return 1; @@ -2992,16 +3020,16 @@ if (opt->has_arg == OPT_NONE) { if (is_short) fprintf( -# 458 "options.c" 3 4 +# 466 "options.c" 3 4 stderr -# 458 "options.c" +# 466 "options.c" , "%s: '%c': option does not take argument\n", prog_name, opt->short_opt); else fprintf( -# 461 "options.c" 3 4 +# 469 "options.c" 3 4 stderr -# 461 "options.c" +# 469 "options.c" , "%s: %s: option does not take argument\n", prog_name, opt->long_opt); @@ -3034,17 +3062,17 @@ case OPT_INT: -# 492 "options.c" 3 4 +# 500 "options.c" 3 4 (*__errno_location ()) -# 492 "options.c" +# 500 "options.c" = 0; arg_int = strtol(argstr, &endptr, 0); if (*endptr) { fprintf( -# 496 "options.c" 3 4 +# 504 "options.c" 3 4 stderr -# 496 "options.c" +# 504 "options.c" , "%s: %s: not a%s\n", prog_name, argstr, (opt->type == OPT_BOOL) ? " yes or no value" : "n integer"); return 1; @@ -3052,34 +3080,34 @@ if (opt->type == OPT_INT) { if (! -# 502 "options.c" 3 4 +# 510 "options.c" 3 4 (*__errno_location ()) -# 502 "options.c" +# 510 "options.c" && (arg_int < opt->ibound.lower || arg_int > opt->ibound.upper)) -# 504 "options.c" 3 4 +# 512 "options.c" 3 4 (*__errno_location ()) -# 504 "options.c" +# 512 "options.c" = -# 504 "options.c" 3 4 +# 512 "options.c" 3 4 34 -# 504 "options.c" +# 512 "options.c" ; if ( -# 506 "options.c" 3 4 +# 514 "options.c" 3 4 (*__errno_location ()) -# 506 "options.c" +# 514 "options.c" ) { fprintf( -# 507 "options.c" 3 4 +# 515 "options.c" 3 4 stderr -# 507 "options.c" +# 515 "options.c" , "%s: %s: %s\n", prog_name, argstr, strerror( -# 507 "options.c" 3 4 +# 515 "options.c" 3 4 (*__errno_location ()) -# 507 "options.c" +# 515 "options.c" )); return 1; } @@ -3094,51 +3122,51 @@ case OPT_FLOAT: -# 520 "options.c" 3 4 +# 528 "options.c" 3 4 (*__errno_location ()) -# 520 "options.c" +# 528 "options.c" = 0; p_arg->arg_float = strtod(argstr, &endptr); if (*endptr) { fprintf( -# 524 "options.c" 3 4 +# 532 "options.c" 3 4 stderr -# 524 "options.c" +# 532 "options.c" , "%s: %s: not a floating-point number\n", prog_name, argstr); return 1; } if (! -# 529 "options.c" 3 4 +# 537 "options.c" 3 4 (*__errno_location ()) -# 529 "options.c" +# 537 "options.c" && (p_arg->arg_float < opt->fbound.lower || p_arg->arg_float > opt->fbound.upper)) -# 531 "options.c" 3 4 +# 539 "options.c" 3 4 (*__errno_location ()) -# 531 "options.c" +# 539 "options.c" = -# 531 "options.c" 3 4 +# 539 "options.c" 3 4 34 -# 531 "options.c" +# 539 "options.c" ; if ( -# 533 "options.c" 3 4 +# 541 "options.c" 3 4 (*__errno_location ()) -# 533 "options.c" +# 541 "options.c" ) { fprintf( -# 534 "options.c" 3 4 +# 542 "options.c" 3 4 stderr -# 534 "options.c" +# 542 "options.c" , "%s: %s: %s\n", prog_name, argstr, strerror( -# 534 "options.c" 3 4 +# 542 "options.c" 3 4 (*__errno_location ()) -# 534 "options.c" +# 542 "options.c" )); return 1; } @@ -3153,28 +3181,28 @@ p_arg->arg_file = file_open(argstr, opt->file_mode); if (!p_arg->arg_file) { fprintf( -# 547 "options.c" 3 4 +# 555 "options.c" 3 4 stderr -# 547 "options.c" +# 555 "options.c" , "%s: cannot open %s: %s\n", prog_name, argstr, strerror( -# 548 "options.c" 3 4 +# 556 "options.c" 3 4 (*__errno_location ()) -# 548 "options.c" +# 556 "options.c" )); return 1; } if (p_arg->arg_file == -# 552 "options.c" 3 4 +# 560 "options.c" 3 4 stdin -# 552 "options.c" +# 560 "options.c" ) argstr = "<stdin>"; else if (p_arg->arg_file == -# 554 "options.c" 3 4 +# 562 "options.c" 3 4 stdout -# 554 "options.c" +# 562 "options.c" ) argstr = "<stdout>"; @@ -3184,14 +3212,14 @@ p_arg->arg_directory = opendir(argstr); if (!p_arg->arg_directory) { fprintf( -# 562 "options.c" 3 4 +# 570 "options.c" 3 4 stderr -# 562 "options.c" +# 570 "options.c" , "%s: cannot open directory %s: %s\n", prog_name, argstr, strerror( -# 563 "options.c" 3 4 +# 571 "options.c" 3 4 (*__errno_location ()) -# 563 "options.c" +# 571 "options.c" )); return 1; } @@ -3200,21 +3228,21 @@ default: -# 570 "options.c" 3 4 +# 578 "options.c" 3 4 ((void) sizeof (( -# 570 "options.c" +# 578 "options.c" !"Invalid option type" -# 570 "options.c" 3 4 +# 578 "options.c" 3 4 ) ? 1 : 0), __extension__ ({ if ( -# 570 "options.c" +# 578 "options.c" !"Invalid option type" -# 570 "options.c" 3 4 +# 578 "options.c" 3 4 ) ; else __assert_fail ( -# 570 "options.c" +# 578 "options.c" "!\"Invalid option type\"" -# 570 "options.c" 3 4 - , "options.c", 570, __extension__ __PRETTY_FUNCTION__); })) -# 570 "options.c" +# 578 "options.c" 3 4 + , "options.c", 578, __extension__ __PRETTY_FUNCTION__); })) +# 578 "options.c" ; } } @@ -3263,30 +3291,30 @@ break; default: -# 617 "options.c" 3 4 +# 625 "options.c" 3 4 ((void) sizeof (( -# 617 "options.c" +# 625 "options.c" !"Invalid option type" -# 617 "options.c" 3 4 +# 625 "options.c" 3 4 ) ? 1 : 0), __extension__ ({ if ( -# 617 "options.c" +# 625 "options.c" !"Invalid option type" -# 617 "options.c" 3 4 +# 625 "options.c" 3 4 ) ; else __assert_fail ( -# 617 "options.c" +# 625 "options.c" "!\"Invalid option type\"" -# 617 "options.c" 3 4 -, "options.c", 617, __extension__ __PRETTY_FUNCTION__); })) -# 617 "options.c" +# 625 "options.c" 3 4 +, "options.c", 625, __extension__ __PRETTY_FUNCTION__); })) +# 625 "options.c" ; } } if (ret) fprintf( -# 622 "options.c" 3 4 +# 630 "options.c" 3 4 stderr -# 622 "options.c" +# 630 "options.c" , "%s: %s\n", prog_name, err); } @@ -3299,14 +3327,14 @@ case OPT_FILE: if (file_close(p_arg->arg_file)) { fprintf( -# 633 "options.c" 3 4 +# 641 "options.c" 3 4 stderr -# 633 "options.c" +# 641 "options.c" , "%s: cannot close %s: %s\n", prog_name, argstr, strerror( -# 634 "options.c" 3 4 +# 642 "options.c" 3 4 (*__errno_location ()) -# 634 "options.c" +# 642 "options.c" )); return 1; } @@ -3315,14 +3343,14 @@ case OPT_DIRECTORY: if (closedir(p_arg->arg_directory)) { fprintf( -# 641 "options.c" 3 4 +# 649 "options.c" 3 4 stderr -# 641 "options.c" +# 649 "options.c" , "%s: cannot close directory %s: %s\n", prog_name, argstr, strerror( -# 642 "options.c" 3 4 +# 650 "options.c" 3 4 (*__errno_location ()) -# 642 "options.c" +# 650 "options.c" )); return 1; } @@ -3356,36 +3384,36 @@ n_matches = 0; for (n_haystack = 0; !((haystack + n_haystack)->short_opt == '\0' && (haystack + n_haystack)->long_opt == -# 674 "options.c" 3 4 +# 682 "options.c" 3 4 ((void *)0) -# 674 "options.c" +# 682 "options.c" ); n_haystack++) { if (haystack[n_haystack].long_opt) n_matches++; } - matches = _xmalloc_line("options.c", 680, __func__, sizeof(*matches) * n_matches); + matches = _xmalloc_line("options.c", 688, __func__, sizeof(*matches) * n_matches); index = 0; for (int i = 0; i < n_haystack; i++) { const char *str = haystack[i].long_opt; if (str) { -# 685 "options.c" 3 4 +# 693 "options.c" 3 4 ((void) sizeof (( -# 685 "options.c" +# 693 "options.c" index < n_matches -# 685 "options.c" 3 4 +# 693 "options.c" 3 4 ) ? 1 : 0), __extension__ ({ if ( -# 685 "options.c" +# 693 "options.c" index < n_matches -# 685 "options.c" 3 4 +# 693 "options.c" 3 4 ) ; else __assert_fail ( -# 685 "options.c" +# 693 "options.c" "index < n_matches" -# 685 "options.c" 3 4 - , "options.c", 685, __extension__ __PRETTY_FUNCTION__); })) -# 685 "options.c" +# 693 "options.c" 3 4 + , "options.c", 693, __extension__ __PRETTY_FUNCTION__); })) +# 693 "options.c" ; matches[index].match = str; matches[index].index = i; @@ -3393,21 +3421,21 @@ } } -# 691 "options.c" 3 4 +# 699 "options.c" 3 4 ((void) sizeof (( -# 691 "options.c" +# 699 "options.c" index == n_matches -# 691 "options.c" 3 4 +# 699 "options.c" 3 4 ) ? 1 : 0), __extension__ ({ if ( -# 691 "options.c" +# 699 "options.c" index == n_matches -# 691 "options.c" 3 4 +# 699 "options.c" 3 4 ) ; else __assert_fail ( -# 691 "options.c" +# 699 "options.c" "index == n_matches" -# 691 "options.c" 3 4 - , "options.c", 691, __extension__ __PRETTY_FUNCTION__); })) -# 691 "options.c" +# 699 "options.c" 3 4 + , "options.c", 699, __extension__ __PRETTY_FUNCTION__); })) +# 699 "options.c" ; @@ -3463,9 +3491,9 @@ break; case OPT_STRING: arg->arg_string = -# 745 "options.c" 3 4 +# 753 "options.c" 3 4 ((void *)0) -# 745 "options.c" +# 753 "options.c" ; break; @@ -3473,21 +3501,21 @@ if (arg->arg_file) { if (file_close(arg->arg_file)) { fprintf( -# 751 "options.c" 3 4 +# 759 "options.c" 3 4 stderr -# 751 "options.c" +# 759 "options.c" , "%s: cannot close %s: %s\n", prog_name, opt->argstr ? *(opt->argstr) : "file", strerror( -# 752 "options.c" 3 4 +# 760 "options.c" 3 4 (*__errno_location ()) -# 752 "options.c" +# 760 "options.c" )); return 1; } arg->arg_file = -# 755 "options.c" 3 4 +# 763 "options.c" 3 4 ((void *)0) -# 755 "options.c" +# 763 "options.c" ; } break; @@ -3496,22 +3524,22 @@ if (arg->arg_directory) { if (closedir(arg->arg_directory)) { fprintf( -# 762 "options.c" 3 4 +# 770 "options.c" 3 4 stderr -# 762 "options.c" +# 770 "options.c" , "%s: cannot close directory%s%s: %s\n", prog_name, opt->argstr ? " " : "", opt->argstr ? *(opt->argstr) : "", strerror( -# 764 "options.c" 3 4 +# 772 "options.c" 3 4 (*__errno_location ()) -# 764 "options.c" +# 772 "options.c" )); return 1; } arg->arg_directory = -# 767 "options.c" 3 4 +# 775 "options.c" 3 4 ((void *)0) -# 767 "options.c" +# 775 "options.c" ; } @@ -3519,29 +3547,29 @@ default: -# 773 "options.c" 3 4 +# 781 "options.c" 3 4 ((void) sizeof (( -# 773 "options.c" +# 781 "options.c" !"Invalid option type" -# 773 "options.c" 3 4 +# 781 "options.c" 3 4 ) ? 1 : 0), __extension__ ({ if ( -# 773 "options.c" +# 781 "options.c" !"Invalid option type" -# 773 "options.c" 3 4 +# 781 "options.c" 3 4 ) ; else __assert_fail ( -# 773 "options.c" +# 781 "options.c" "!\"Invalid option type\"" -# 773 "options.c" 3 4 - , "options.c", 773, __extension__ __PRETTY_FUNCTION__); })) -# 773 "options.c" +# 781 "options.c" 3 4 + , "options.c", 781, __extension__ __PRETTY_FUNCTION__); })) +# 781 "options.c" ; } if (opt->argstr) *(opt->argstr) = -# 777 "options.c" 3 4 +# 785 "options.c" 3 4 ((void *)0) -# 777 "options.c" +# 785 "options.c" ; return 0; @@ -3555,9 +3583,9 @@ int ret = 0; for (const OPTION *opt = options; !((opt)->short_opt == '\0' && (opt)->long_opt == -# 789 "options.c" 3 4 +# 797 "options.c" 3 4 ((void *)0) -# 789 "options.c" +# 797 "options.c" ); opt++) ret += free_opt(prog_name, opt); @@ -3571,9 +3599,9 @@ static int format_help_callback(void *data, char *err) { struct help_callback_data *d = data; int ret = format_help( -# 801 "options.c" 3 4 +# 809 "options.c" 3 4 stdout -# 801 "options.c" +# 809 "options.c" , d->prog_name, d->usage, d->desc, d->notes, d->options); @@ -3581,15 +3609,15 @@ fflush( -# 807 "options.c" 3 4 +# 815 "options.c" 3 4 stdout -# 807 "options.c" +# 815 "options.c" ); snprintf(err, 256, "cannot print help message: %s", strerror( -# 809 "options.c" 3 4 +# 817 "options.c" 3 4 (*__errno_location ()) -# 809 "options.c" +# 817 "options.c" )); return ret; }
signature.asc
Description: PGP signature