/* scan_args.c */ #include #include #include #include #include "pcode.h" #define PCODE_VERSION_BLURB \ "pcode " PCODE_VERSION_STR ", " PCODE_DATE_STR "\n" \ "Copyright 2004 Andy Goth .\n" \ "Adapted from pcode2.c by Agnieszka Szczurowska, 2000.\n" \ "Implements pcode as described by Bruce J. MacLennan, 1999.\n" \ "Check for updates at .\n" \ "pcode is free software, covered by the GNU General Public License; you\n"\ "are welcome to change and/or distribute it under certain conditions.\n" \ "There is absolutely no warranty for pcode. See COPYING for details.\n" #define PCODE_HELP_BLURB \ "Usage: %s [OPTION] ...\n" \ "Interprets a pcode program.\n" \ "\n" \ " -iFILE Read input data from FILE.\n" \ " -oFILE Write output data to FILE.\n" \ " -d Execute program interactively (debug mode).\n" \ " -c Colorize debug display.\n" \ " -h Print this message.\n" \ " -V Display version and copyright information.\n" \ "\n" \ "If FILE is `-' or not specified, stdin or stdout is used.\n" \ "\n" \ "Report bugs to Andy Goth .\n" int scan_args(int argc, char** argv, interp_t* interp) { int i, have_input = 0, have_output = 0, debug = 0, color = 0, *have; int retval = 0; FILE* input = stdin, *output = stdout, **file, *def; char opt, *progname, *string, *mode; /* Get program name. */ progname = strrchr(argv[0], '/'); if (progname != NULL) ++progname; else progname = argv[0]; /* Scan command line arguments. Too bad getopt_long(3) is GNU-only... */ for (i = 1; i < argc; ++i) { if (argv[i][0] == '-') opt = argv[i][1]; else opt = 0; /* Invalid; handled below. */ switch (opt) { case 'i': case 'o': if (argv[i][2] != 0) { /* `-ifilename' or `-ofilename' */ string = &argv[i][2]; } else { /* `-i filename' or `-o filename' */ ++i; if (i == argc) { fprintf(stderr, "Option `-%c' requires argument\n", opt); retval = -1; goto end; } string = argv[i]; } have = opt == 'i' ? &have_input : &have_output; file = opt == 'i' ? &input : &output ; def = opt == 'i' ? stdin : stdout ; mode = opt == 'i' ? "r" : "w" ; if (*have) { fprintf(stderr, "Too many `-%c' options\n", opt); retval = -1; goto end; } *have = 1; if (strcmp(string, "-") == 0) { *file = def; } else { *file = fopen(string, mode); if (*file == NULL) { fprintf(stderr, "`%s': %s\n", string, strerror(errno)); retval = -1; goto end; } } break; case 'd': debug = 1; break; case 'c': color = 1; break; case 'h': printf(PCODE_HELP_BLURB, progname); retval = 1; goto end; case 'V': printf(PCODE_VERSION_BLURB ); retval = 1; goto end; default: fprintf(stderr, "Invalid argument `%s'\n", argv[i]); fprintf(stderr, "Try `%s -h' for more information\n", progname); retval = -1; goto end; } } end: /* Store results. */ if (retval == 0 && debug && input == stdin) { fprintf(stderr, "In debug mode, cannot use stdin for program input\n"); retval = -1; } interp->input = input; interp->output = output; interp->debug = debug; interp->color = color; return retval; } /* vim: set ts=4 sts=4 sw=4 tw=80 et: */