From f415b094c750fb9f7cbfda0311bc5ba2024f385b Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Mon, 10 Feb 2020 20:33:54 -0500 Subject: [PATCH] Make --help output go to standard output. A program's help text, when requested by the user, is not an error message. Kind of silly to direct it to the standard error stream. Adjust the program so that help text goes to standard output, which is consistent with the GNU coding standards. For actual errors, print a simplified usage message to standard error instead of the full help text because otherwise the actual error message is going to scroll right off the screen. --- src/main.c | 119 +++++++++++++++++++++++++++-------------------- tests/options.at | 2 - 2 files changed, 68 insertions(+), 53 deletions(-) diff --git a/src/main.c b/src/main.c index 3bdc4f4..60c128a 100644 --- a/src/main.c +++ b/src/main.c @@ -4520,57 +4520,72 @@ generate_outfiles(void) print_header_postfixes(); } +static void print_usage(FILE *f) +{ + fprintf(f, "Usage: %s [options] file.gob\n", g_get_prgname()); + if (f == stderr) { + fprintf(f, "Try '%s --help' for more information.\n", + g_get_prgname()); + } +} + static void print_help(void) { - fprintf(stderr, "Gob version %s\n\n", VERSION); - fprintf(stderr, "gob [options] file.gob\n\n"); - fprintf(stderr, "Options:\n" - "\t--help,-h,-? Display this help\n" - "\t--version Display version\n" - "\t--exit-on-warn,-w Exit with an error on warnings\n" - "\t--no-exit-on-warn Don't exit on warnings [default]\n" - "\t--for-cpp Create C++ files\n" - "\t--no-extern-c Never print extern \"C\" into the " - "header\n" - "\t--no-gnu Never use GNU extentions\n" - "\t--no-touch Don't touch output files unless they " - "really\n" - "\t changed (implies --no-touch-headers)\n" - "\t--no-touch-headers Don't touch headers unless they " - "really changed\n" - "\t--always-private-header Always create a private header " - "file,\n" - "\t even if it would be empty\n" - "\t--ondemand-private-header Create private header only when " - "needed\n" - "\t [default]\n" - "\t--no-private-header Don't create a private header, " - "put private\n" - "\t structure and protected " - "prototypes inside c file\n" - "\t--always-private-struct Always create a private pointer " - "in\n" - "\t the object structure\n" - "\t--m4 Preprocess source with m4. " - "Following args will\n" - "\t be passed to m4\n" - "\t--m4-dir Print directory that will be " - "searched for m4\n" - "\t files\n" - "\t--no-write,-n Don't write output files, just " - "check syntax\n" - "\t--no-lines Don't print '#line' to output\n" - "\t--no-self-alias Don't create self type and macro " - "aliases\n" - "\t--no-kill-underscores Ignored for compatibility\n" - "\t-o,--output-dir The directory where output " - "should be placed\n" - "\t--file-sep[=c] replace default \'-\' file " - "name separator\n\n" - "\t--gtk3 Use gtk+3\n" - ); - fprintf(stderr, "End world hunger, donate to the World Food Programme, http://www.wfp.org\n"); + print_usage(stdout); + + puts( +"This is \"GObject Builder\": a simple preprocessor to help with\n" +"implementing GObject types in C.\n" + ); + + puts("Options:"); + puts(" --help,-h,-? Display this help\n" + " --version Display version\n" + " --exit-on-warn,-w Exit with an error on warnings\n" + " --no-exit-on-warn Don't exit on warnings [default]\n" + " --for-cpp Create C++ files\n" + " --no-extern-c Never print extern \"C\" into the " + "header\n" + " --no-gnu Never use GNU extentions\n" + " --no-touch Don't touch output files unless they " + "really\n" + " changed (implies --no-touch-headers)\n" + " --no-touch-headers Don't touch headers unless they " + "really changed\n" + " --always-private-header Always create a private header " + "file,\n" + " even if it would be empty\n" + " --ondemand-private-header Create private header only when " + "needed\n" + " [default]\n" + " --no-private-header Don't create a private header, " + "put private\n" + " structure and protected " + "prototypes inside c file\n" + " --always-private-struct Always create a private pointer " + "in\n" + " the object structure\n" + " --m4 Preprocess source with m4. " + "Following args will\n" + " be passed to m4\n" + " --m4-dir Print directory that will be " + "searched for m4\n" + " files\n" + " --no-write,-n Don't write output files, just " + "check syntax\n" + " --no-lines Don't print '#line' to output\n" + " --no-self-alias Don't create self type and macro " + "aliases\n" + " --no-kill-underscores Ignored for compatibility\n" + " -o,--output-dir The directory where output " + "should be placed\n" + " --file-sep[=c] replace default \'-\' file " + "name separator\n\n" + " --gtk3 Use gtk+3\n" + ); + + puts("End world hunger, donate to the World Food Programme: https://www.wfp.org/"); } static void @@ -4620,7 +4635,7 @@ parse_options(int argc, char *argv[]) /*must be a file*/ if(got_file) { fprintf(stderr, "Specify only one file!\n"); - print_help(); + print_usage(stderr); exit(1); } filename = argv[i]; @@ -4711,7 +4726,7 @@ parse_options(int argc, char *argv[]) } else if(strncmp(argv[i], "--", 2)==0) { /*unknown long option*/ fprintf(stderr, "Unknown option '%s'!\n", argv[i]); - print_help(); + print_usage(stderr); exit(1); } else { /*by now we know we have a string starting with @@ -4732,7 +4747,7 @@ parse_options(int argc, char *argv[]) default: fprintf(stderr, "Unknown option '%c'!\n", *p); - print_help(); + print_usage(stderr); exit(1); } } @@ -4831,6 +4846,8 @@ compare_and_move (const char *old_filename) int main(int argc, char *argv[]) { + g_set_prgname(argc > 0 ? argv[0] : "gob2"); + parse_options(argc, argv); if(use_m4) { diff --git a/tests/options.at b/tests/options.at index 2f85019..22e9609 100644 --- a/tests/options.at +++ b/tests/options.at @@ -8,8 +8,6 @@ dnl standard output. AT_SETUP([--help option]) AT_KEYWORDS([option])dnl -# Currently prints to standard error :( -AT_XFAIL_IF([:]) AT_CHECK([gob2 invalid-file.gob --help --invalid-option], [0], [ignore-nolog]) AT_CLEANUP -- 2.43.2