diff options
author | Marc-André Lureau <marcandre.lureau@gmail.com> | 2010-11-23 17:00:17 +0100 |
---|---|---|
committer | Marc-André Lureau <marcandre.lureau@gmail.com> | 2010-11-23 17:00:17 +0100 |
commit | d960229a091a7bd5b3ce4a29ae5f5648978af51c (patch) | |
tree | 2ba6dee45d82e551029c42e3a3bc4d5df58495ac /common/win/my_getopt-1.5/main.c | |
download | spice-gtk-d960229a091a7bd5b3ce4a29ae5f5648978af51c.tar.gz spice-gtk-d960229a091a7bd5b3ce4a29ae5f5648978af51c.tar.xz spice-gtk-d960229a091a7bd5b3ce4a29ae5f5648978af51c.zip |
Initial import from SPICE
Diffstat (limited to 'common/win/my_getopt-1.5/main.c')
-rw-r--r-- | common/win/my_getopt-1.5/main.c | 387 |
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 0000000..25674e1 --- /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; +} |