#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/");
}