#include "main.h"
-enum {
- SOPT_END = UCHAR_MAX,
- LOPT_VERSION,
- LOPT_NO_TOUCH,
- LOPT_FILE_SEP,
- LOPT_M4,
- LOPT_M4_CLEAN,
- LOPT_M4_DIR
-};
+#include "options.h"
-static const char sopts[] = "wnho:";
+static const char sopts[] = SOPT_STRING;
static const struct option lopts[] = {
- { "help", 0, NULL, 'h' },
- { "version", 0, NULL, LOPT_VERSION },
- { "exit-on-warn", 0, NULL, 'w' },
- { "no-exit-on-warn", 0, &exit_on_warn, FALSE },
- { "for-cpp", 0, &for_cpp, TRUE },
- { "no-extern-c", 0, &no_extern_c, TRUE },
- { "no-gnu", 0, &no_gnu, TRUE },
- { "no-touch", 0, NULL, LOPT_NO_TOUCH },
- { "no-touch-headers", 0, &no_touch_headers, TRUE },
- { "always-private-header", 0, &private_header, PRIVATE_HEADER_ALWAYS },
- { "ondemand-private-header", 0, &private_header, PRIVATE_HEADER_ONDEMAND },
- { "no-private-header", 0, &private_header, PRIVATE_HEADER_NEVER },
- { "always-private-struct", 0, &always_private_struct, TRUE },
- { "m4", 0, NULL, LOPT_M4 },
- { "m4-clean", 0, NULL, LOPT_M4_CLEAN },
- { "m4-dir", 0, NULL, LOPT_M4_DIR },
- { "no-write", 0, NULL, 'n' },
- { "no-lines", 0, &no_lines, TRUE },
- { "no-self-alias", 0, &no_self_alias, TRUE },
- { "no-kill-underscores", 0, NULL, 0 /* no-op */ },
- { "output-dir", 1, NULL, 'o' },
- { "file-sep", 2, NULL, LOPT_FILE_SEP },
- { "gtk3", 0, >k3_ok, TRUE },
+ LOPTS_INITIALIZER,
{ 0 }
};
}
}
-static void
-print_help(void)
+/*
+ * Given a long option, return the corresponding short option character,
+ * or 0 if there is no such character.
+ */
+static char lopt_to_sopt(const char *sopts, const struct option *opt)
+{
+ int val = opt->val;
+ const char *c;
+
+ if (val <= 0 || val > CHAR_MAX)
+ return 0;
+
+ if (val == ':' || val == '+' || val == '-')
+ return 0;
+
+ c = strchr(sopts, opt->val);
+ if (c)
+ return *c;
+ return 0;
+}
+
+/*
+ * Print a string, with each line indented by i spaces. The first line
+ * will be indented by w fewer spaces (to account for the cursor being in
+ * some other column).
+ */
+static void print_block(const char *s, int i, int w)
+{
+ for (; *s; w = 0) {
+ const char *nl = strchr(s, '\n');
+ int n = (nl ? nl-s : -1);
+
+ printf("%*s%.*s\n", i-w, "", n, s);
+ if (!nl)
+ break;
+
+ s = nl+1;
+ }
+}
+
+static void print_help(void)
{
+ const struct option *opt;
+
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("This is \"GObject Builder\": a simple preprocessor to help with\n"
+ "implementing GObject types in C.");
+
+ puts("\nOptions:");
+ for (opt = lopts; opt->name; opt++) {
+ struct lopt_help help;
+ char sopt;
+ int w;
+
+ /* Don't display obsolete options that don't do anything */
+ if (!opt->flag && !opt->val)
+ continue;
+
+ if (!lopt_get_help(opt, &help))
+ continue;
+
+ if ((sopt = lopt_to_sopt(sopts, opt))) {
+ w = printf(opt->has_arg == 0 ? " -%c, --%s"
+ : opt->has_arg == 1 ? " -%c, --%s=%s"
+ : " -%c, --%s[=%s]",
+ sopt, opt->name, help.arg);
+ } else {
+ w = printf(opt->has_arg == 0 ? " --%s"
+ : opt->has_arg == 1 ? " --%s=%s"
+ : " --%s[=%s]",
+ opt->name, help.arg);
+ }
+
+ if (w < 0 || w > 18) {
+ putchar('\n');
+ w = 0;
+ }
+
+ print_block(help.desc, 20, w);
+ }
+ putchar('\n');
puts("End world hunger, donate to the World Food Programme: https://www.wfp.org/");
}
--- /dev/null
+-h, --help
+Print this message and then exit.
+
+--version
+Print a version message and then exit.
+
+-w, --exit-on-warn
+Exit with an error on any warning.
+--no-exit-on-warn (&exit_on_warn, FALSE)
+
+--for-cpp (&for_cpp, TRUE)
+Generate C++ output.
+
+--no-extern-c (&no_extern_c, TRUE)
+Omit C++ extern "C" declarations from headers.
+
+--no-gnu (&no_gnu, TRUE)
+Do not use any GNU language extensions.
+
+--no-touch-headers (&no_touch_headers, TRUE)
+Avoid modifying output header files if there would not be
+any changes, so that modification times are preserved.
+
+--no-touch
+Same as --no-touch-headers but applies to all output files.
+
+--always-private-struct (&always_private_struct, TRUE)
+Create the _priv pointer in the object structure even if
+there are no private members.
+
+--always-private-header (&private_header, PRIVATE_HEADER_ALWAYS)
+Create a private header file even if it would be empty.
+
+--ondemand-private-header (&private_header, PRIVATE_HEADER_ONDEMAND)
+Create a private header file only if required (default).
+
+--no-private-header (&private_header, PRIVATE_HEADER_NEVER)
+
+--m4
+Use M4 to produce input data. All non-option arguments
+and subsequent arguments are passed to m4.
+
+--m4-clean
+Same as --m4, except that no arguments other than those
+specified on the command line are passed to m4.
+
+--m4-dir
+Print the default m4 search directory and then exit.
+
+-n, --no-write
+Do not actually create any output files. The input is
+still parsed to check for syntax errors.
+
+--no-lines (&no_lines, TRUE)
+Do not output any #line directives.
+
+--no-self-alias (&no_self_alias, TRUE)
+Do not output the SELF macros or Self typedefs.
+
+--no-kill-underscores (0)
+
+-o, --output-dir=DIR
+Output files will be placed relative to DIR.
+
+--file-sep[=CHAR]
+Separate filename components with CHAR, as opposed to '-'.
+If CHAR is omitted, no separator is used.
+
+--gtk3 (>k3_ok, TRUE)
+Use GTK+3 interface names.