/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */ /*====================================================================== Copyright (C) 2004,2005,2009 Walter Doekes This file is part of tthsum. tthsum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. tthsum is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with tthsum. If not, see . ======================================================================*/ #include "getopt.h" #ifdef USE_MY_GETOPT # include # include char* optarg; /* option argument */ int optind = 0; /* argv index */ int opterr = 1; /* print errors on stderr */ int optopt = 0; /* the character found for '?' characters */ static int optindind = 0; /* letter-index for options at optind */ int getopt(int argc, char* const argv[], const char* optstring) { /* if optindind is set, we're looking at an option at optind */ if (optindind != 0) { int ret; const char* p = strchr(optstring, argv[optind][optindind]); /* unknown option */ if (p == NULL) { ret = '?'; optopt = argv[optind][optindind]; if (argv[optind][optindind + 1] != '\0') { ++optindind; } else { optindind = 0; ++optind; } if (opterr) fprintf(stderr, "%s: invalid option -- %c\n", argv[0], optopt); return '?'; /* with-argument option */ } else if (p[1] == ':') { /* GNU extension: double colon means arg is optional */ ret = argv[optind][optindind]; /* argument is attached to option */ if (argv[optind][optindind + 1] != '\0') { optarg = argv[optind] + optindind + 1; optindind = 0; ++optind; /* argument is not attached and optional (GNU extension) */ } else if (p[2] == ':') { optarg = NULL; optindind = 0; ++optind; /* argument is not optional and loose */ } else { if (optind + 1 == argc) { optopt = ret; if (opterr) fprintf(stderr, "%s: option requires an argument" " -- %c\n", argv[0], optopt); ret = '?'; } else { ++optind; optarg = argv[optind]; } } optindind = 0; ++optind; /* correct non-argument option */ } else { ret = argv[optind][optindind]; if (argv[optind][optindind + 1] != '\0') { ++optindind; } else { optindind = 0; ++optind; } } return ret; } /* if optind is zero, we haven't run yet */ if (optind <= 0) { optind = 1; optindind = 0; } /* done? */ if (optind >= argc) return -1; /* end of options? */ if (argv[optind][0] == '-' && argv[optind][1] == '-' && argv[optind][2] == '\0') { ++optind; return -1; } /* not an option? */ if (argv[optind][0] != '-') { /* find option and move it to front */ const char** mut_argv = (const char**)argv; int i; for (i = optind + 1; i < argc; ++i) { if (argv[i][0] == '-') { if (argv[i][1] == '\0') continue; if (argv[i][1] == '-' && argv[i][2] == '\0') continue; /* found, move back */ for (; i > optind; --i) { const char* tmp; tmp = mut_argv[i]; mut_argv[i] = mut_argv[i - 1]; mut_argv[i - 1] = tmp; } break; } } if (i == argc) return -1; } /* we're here, so we have an option */ optindind = 1; return getopt(argc, argv, optstring); } #endif /* !USE_MY_GETOPT */