char * short_options (struct option * long_options, unsigned n_options) { char * opt; char * optn; unsigned i; opt = malloc_or_exit (n_options * 2); /* Write point of the string. */ optn = opt; for (i = 0; i < n_options; i++) { switch (long_options[i].has_arg) { case required_argument: optn += sprintf (optn, "%c:", long_options[i].val); break; case no_argument: optn += sprintf (optn, "%c", long_options[i].val); break; case optional_argument: optn += sprintf (optn, "%c::", long_options[i].val); break; default: error ("unknown `has_arg' field in long_options with name %s", long_options[i].name); } } return opt; }
static char * make_version_name (const char * file, int version) { char *backup_name; backup_name = malloc_or_exit (strlen (file) + 16); sprintf (backup_name, "%s.~%d~", file, version); return backup_name; }
static char * concat (const char *str1, const char *str2) { char *newstr; int str1_length = strlen (str1); newstr = malloc_or_exit (str1_length + strlen (str2) + 1); strcpy (newstr, str1); strcpy (newstr + str1_length, str2); return newstr; }
static void inc_n_arg (void) { if (++n_arg >= max_arg) { unsigned i; max_arg += TRAD_INC; if (args) args = realloc_or_exit (args, sizeof (struct arg *) * max_arg); else args = malloc_or_exit (sizeof (struct arg *) * max_arg); for (i = n_arg; i < max_arg; i++) args[i] = 0; } }
int main(int argc, char *argv[]) { unsigned * order; unsigned i; program_name = "options"; while (1) { i = getopt (argc, argv, "mtc"); if (i == EOF) { break; } switch (i) { case 'm': mode = man; break; case 't': mode = texi; break; case '?': return 1; default: error ("unknown option: '%c'", i); } } if (optind < argc) error ("can't have arguments"); if (mode == man) fcopy (stdout, "man.head"); switch (mode) { case texi: printf ("%s", texi_begin); break; case man: printf ("%s", man_begin); break; default: error (""); } /* Sort things into the alphabetical order of the short options. */ order = malloc_or_exit (sizeof (unsigned) * n_options); for (i = 0; i < n_options; i++) { order [i] = i; } qsort (order, n_options, sizeof (unsigned), compare_letter_options); for (i = 0; i < n_options; i++) { unsigned j = order[i]; if (! usage[j]) { error ("empty usage message for option '%c'", long_options[j].val); } switch (mode) { case texi: printf ("@cindex @code{-%c}\n@cindex @code{--%s}\n", long_options [j].val, long_options [j].name); printf ("@item -%c ", long_options [j].val); if (long_options [j].has_arg == required_argument) { printf (" @var{argument}"); } printf ("\n@itemx --%s ", long_options [j].name); if (long_options [j].has_arg == required_argument) { printf (" @var{argument}"); } printf ("\n%s.\n", usage[j]); /* if (other_stuff[j].cross_ref) { printf ("@xref{%s}.\n", other_stuff[j].cross_ref); } if (other_stuff[j].rc_name) { printf ("This can also be controlled with a line `%s' " "in @file{.cfunctionsrc}\n", other_stuff[j].rc_name); } printf ("\n"); */ break; case man: printf (".TP\n\\fB-%c\\fP", long_options [j].val); if (long_options [j].has_arg == required_argument) { printf (" \\fIargument\\fP"); } printf (", \\fB--%s\\fP", long_options [j].name); if (long_options [j].has_arg == required_argument) { printf (" \\fIargument\\fP"); } printf ("\n%s.\n", usage[j]); /* if (other_stuff[j].cross_ref) { printf ("See node `%s' in the info documentation.\n", other_stuff[j].cross_ref); } if (other_stuff[j].rc_name) { printf ("This can also be controlled with a line `%s' " "in $HOME/.cfunctionsrc\n", other_stuff[j].rc_name); } */ break; default: error (""); } } switch (mode) { case texi: printf ("%s", texi_end); break; case man: printf ("%s", man_end); fcopy (stdout, "man.tail"); break; default: error (""); } return 0; }