summaryrefslogtreecommitdiffstats
path: root/common/win/my_getopt-1.5/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/win/my_getopt-1.5/main.c')
-rw-r--r--common/win/my_getopt-1.5/main.c387
1 files changed, 387 insertions, 0 deletions
diff --git a/common/win/my_getopt-1.5/main.c b/common/win/my_getopt-1.5/main.c
new file mode 100644
index 00000000..25674e1c
--- /dev/null
+++ b/common/win/my_getopt-1.5/main.c
@@ -0,0 +1,387 @@
+/*
+ * copy - test program for my getopt() re-implementation
+ *
+ * This program is in the public domain.
+ */
+
+#define VERSION \
+"0.3"
+
+#define COPYRIGHT \
+"This program is in the public domain."
+
+/* for isprint(), printf(), fopen(), perror(), getenv(), strcmp(), etc. */
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* for my getopt() re-implementation */
+#include "getopt.h"
+
+/* the default verbosity level is 0 (no verbose reporting) */
+static unsigned verbose = 0;
+
+/* print version and copyright information */
+static void
+version(char *progname)
+{
+ printf("%s version %s\n"
+ "%s\n",
+ progname,
+ VERSION,
+ COPYRIGHT);
+}
+
+/* print a help summary */
+static void
+help(char *progname)
+{
+ printf("Usage: %s [options] [FILE]...\n"
+ "Options:\n"
+ "-h or -help show this message and exit\n"
+ "-append append to the output file\n"
+ "-o FILE or\n"
+ "-output FILE send output to FILE (default is stdout)\n"
+ "-r or --rotate rotate letters 13 positions (rot13)\n"
+ "-rNUM or\n"
+ "--rotate=NUM rotate letters NUM positions\n"
+ "-truncate truncate the output file "
+ "(this is the default)\n"
+ "-v or -verbose increase the level of verbosity by 1"
+ "(the default is 0)\n"
+ "-vNUM or\n"
+ "-verbose=NUM set the level of verbosity to NUM\n"
+ "-V or -version print program version and exit\n"
+ "\n"
+ "This program reads the specified FILEs "
+ "(or stdin if none are given)\n"
+ "and writes their bytes to the specified output FILE "
+ "(or stdout if none is\n"
+ "given.) It can optionally rotate letters.\n",
+ progname);
+}
+
+/* print usage information to stderr */
+static void
+usage(char *progname)
+{
+ fprintf(stderr,
+ "Summary: %s [-help] [-version] [options] [FILE]...\n",
+ progname);
+}
+
+/* input file handler -- returns nonzero or exit()s on failure */
+static int
+handle(char *progname,
+ FILE *infile, char *infilename,
+ FILE *outfile, char *outfilename,
+ int rotate)
+{
+ int c;
+ unsigned long bytes_copied = 0;
+
+ if (verbose > 2)
+ {
+ fprintf(stderr,
+ "%s: copying from `%s' to `%s'\n",
+ progname,
+ infilename,
+ outfilename);
+ }
+ while ((c = getc(infile)) != EOF)
+ {
+ if (rotate && isalpha(c))
+ {
+ const char *letters = "abcdefghijklmnopqrstuvwxyz";
+ char *match;
+ if ((match = strchr(letters, tolower(c))))
+ {
+ char rc = letters[(match - letters + rotate) % 26];
+ if (isupper(c))
+ rc = toupper(rc);
+ c = rc;
+ }
+ }
+ if (putc(c, outfile) == EOF)
+ {
+ perror(outfilename);
+ exit(1);
+ }
+ bytes_copied ++;
+ }
+ if (! feof(infile))
+ {
+ perror(infilename);
+ return 1;
+ }
+ if (verbose > 2)
+ {
+ fprintf(stderr,
+ "%s: %lu bytes copied from `%s' to `%s'\n",
+ progname,
+ bytes_copied,
+ infilename,
+ outfilename);
+ }
+ return 0;
+}
+
+/* argument parser and dispatcher */
+int
+main(int argc, char * argv[])
+{
+ /* the program name */
+ char *progname = argv[0];
+ /* during argument parsing, opt contains the return value from getopt() */
+ int opt;
+ /* the output filename is initially 0 (a.k.a. stdout) */
+ char *outfilename = 0;
+ /* the default return value is initially 0 (success) */
+ int retval = 0;
+ /* initially we truncate */
+ int append = 0;
+ /* initially we don't rotate letters */
+ int rotate = 0;
+
+ /* short options string */
+ char *shortopts = "Vho:r::v::";
+ /* long options list */
+ struct option longopts[] =
+ {
+ /* name, has_arg, flag, val */ /* longind */
+ { "append", no_argument, 0, 0 }, /* 0 */
+ { "truncate", no_argument, 0, 0 }, /* 1 */
+ { "version", no_argument, 0, 'V' }, /* 3 */
+ { "help", no_argument, 0, 'h' }, /* 4 */
+ { "output", required_argument, 0, 'o' }, /* 5 */
+ { "rotate", optional_argument, 0, 'r' }, /* 6 */
+ { "verbose", optional_argument, 0, 'v' }, /* 7 */
+ /* end-of-list marker */
+ { 0, 0, 0, 0 }
+ };
+ /* long option list index */
+ int longind = 0;
+
+ /*
+ * print a warning when the POSIXLY_CORRECT environment variable will
+ * interfere with argument placement
+ */
+ if (getenv("POSIXLY_CORRECT"))
+ {
+ fprintf(stderr,
+ "%s: "
+ "Warning: implicit argument reordering disallowed by "
+ "POSIXLY_CORRECT\n",
+ progname);
+ }
+
+ /* parse all options from the command line */
+ while ((opt =
+ getopt_long_only(argc, argv, shortopts, longopts, &longind)) != -1)
+ switch (opt)
+ {
+ case 0: /* a long option without an equivalent short option */
+ switch (longind)
+ {
+ case 0: /* -append */
+ append = 1;
+ break;
+ case 1: /* -truncate */
+ append = 0;
+ break;
+ default: /* something unexpected has happened */
+ fprintf(stderr,
+ "%s: "
+ "getopt_long_only unexpectedly returned %d for `--%s'\n",
+ progname,
+ opt,
+ longopts[longind].name);
+ return 1;
+ }
+ break;
+ case 'V': /* -version */
+ version(progname);
+ return 0;
+ case 'h': /* -help */
+ help(progname);
+ return 0;
+ case 'r': /* -rotate[=NUM] */
+ if (optarg)
+ {
+ /* we use this while trying to parse a numeric argument */
+ char ignored;
+ if (sscanf(optarg,
+ "%d%c",
+ &rotate,
+ &ignored) != 1)
+ {
+ fprintf(stderr,
+ "%s: "
+ "rotation `%s' is not a number\n",
+ progname,
+ optarg);
+ usage(progname);
+ return 2;
+ }
+ /* normalize rotation */
+ while (rotate < 0)
+ {
+ rotate += 26;
+ }
+ rotate %= 26;
+ }
+ else
+ rotate = 13;
+ break;
+ case 'o': /* -output=FILE */
+ outfilename = optarg;
+ /* we allow "-" as a synonym for stdout here */
+ if (! strcmp(optarg, "-"))
+ {
+ outfilename = 0;
+ }
+ break;
+ case 'v': /* -verbose[=NUM] */
+ if (optarg)
+ {
+ /* we use this while trying to parse a numeric argument */
+ char ignored;
+ if (sscanf(optarg,
+ "%u%c",
+ &verbose,
+ &ignored) != 1)
+ {
+ fprintf(stderr,
+ "%s: "
+ "verbosity level `%s' is not a number\n",
+ progname,
+ optarg);
+ usage(progname);
+ return 2;
+ }
+ }
+ else
+ verbose ++;
+ break;
+ case '?': /* getopt_long_only noticed an error */
+ usage(progname);
+ return 2;
+ default: /* something unexpected has happened */
+ fprintf(stderr,
+ "%s: "
+ "getopt_long_only returned an unexpected value (%d)\n",
+ progname,
+ opt);
+ return 1;
+ }
+
+ /* re-open stdout to outfilename, if requested */
+ if (outfilename)
+ {
+ if (! freopen(outfilename, (append ? "a" : "w"), stdout))
+ {
+ perror(outfilename);
+ return 1;
+ }
+ }
+ else
+ {
+ /* make a human-readable version of the output filename "-" */
+ outfilename = "stdout";
+ /* you can't truncate stdout */
+ append = 1;
+ }
+
+ if (verbose)
+ {
+ fprintf(stderr,
+ "%s: verbosity level is %u; %s `%s'; rotation %d\n",
+ progname,
+ verbose,
+ (append ? "appending to" : "truncating"),
+ outfilename,
+ rotate);
+ }
+
+ if (verbose > 1)
+ {
+ fprintf(stderr,
+ "%s: %d input file(s) were given\n",
+ progname,
+ ((argc > optind) ? (argc - optind) : 0));
+ }
+
+ if (verbose > 3)
+ {
+ fprintf(stderr,
+ "\topterr: %d\n\toptind: %d\n\toptopt: %d (%c)\n\toptarg: %s\n",
+ opterr,
+ optind,
+ optopt, optopt,
+ optarg ? optarg : "(null)");
+ }
+
+ /* handle each of the input files (or stdin, if no files were given) */
+ if (optind < argc)
+ {
+ int argindex;
+
+ for (argindex = optind; argindex < argc; argindex ++)
+ {
+ char *infilename = argv[argindex];
+ FILE *infile;
+
+ /* we allow "-" as a synonym for stdin here */
+ if (! strcmp(infilename, "-"))
+ {
+ infile = stdin;
+ infilename = "stdin";
+ }
+ else if (! (infile = fopen(infilename, "r")))
+ {
+ perror(infilename);
+ retval = 1;
+ continue;
+ }
+ if (handle(progname,
+ infile, argv[optind],
+ stdout, outfilename,
+ rotate))
+ {
+ retval = 1;
+ fclose(infile);
+ continue;
+ }
+ if ((infile != stdin) && fclose(infile))
+ {
+ perror(infilename);
+ retval = 1;
+ }
+ }
+ }
+ else
+ {
+ retval =
+ handle(progname,
+ stdin, "stdin",
+ stdout, outfilename,
+ rotate);
+ }
+
+ /* close stdout */
+ if (fclose(stdout))
+ {
+ perror(outfilename);
+ return 1;
+ }
+
+ if (verbose > 3)
+ {
+ fprintf(stderr,
+ "%s: normal return, exit code is %d\n",
+ progname,
+ retval);
+ }
+ return retval;
+}