Mercurial > hgrepos > Python2 > PyMuPDF
diff mupdf-source/source/fitz/getopt.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mupdf-source/source/fitz/getopt.c Mon Sep 15 11:43:07 2025 +0200 @@ -0,0 +1,226 @@ +/* + * This is a version of the public domain getopt implementation by + * Henry Spencer originally posted to net.sources. + * + * This file is in the public domain. + */ + +#include <stdio.h> +#include <string.h> + +#include "mupdf/fitz/getopt.h" +#include "mupdf/fitz/string-util.h" + +char *fz_optarg; /* Global argument pointer. */ +int fz_optind = 0; /* Global argv index. */ +const fz_getopt_long_options *fz_optlong = NULL; +int fz_optitem = 0; /* Which item in a long opt list is selected? */ + +static int +match_long_option(int argc, char * const *argv, const fz_getopt_long_options *longopts, char *opt) +{ + if (longopts == NULL) + { + fprintf(stderr, "%s: unknown option --%s\n", argv[0], opt); + return '?'; + } + + while (longopts->option) + { + const char *s = longopts->option; + const char *eq = strchr(s, '='); + size_t z = eq ? (size_t)(eq-s) : strlen(s); + int arg = 0; /* No arg */ + + if (s[z] == '=') + arg = 1; /* arg = 1 => Arg list given */ + else if (z && s[z-1] == ':') + arg = 2, z--; /* arg = 2 -> argument expected */ + + /* If we don't match, try the next one. */ + /* If we aren't expecting an argument, and the given string is longer than expected, try the next one. */ + /* If we are expecting an argument, and the given string doesn't either terminate or end in '=', try the next one. */ + if (strncmp(s, opt, z) || (arg == 0 && opt[z] != 0) || (arg != 0 && opt[z] != 0 && opt[z] != '=')) + { + longopts++; + continue; + } + + /* So we have a match. */ + fz_optind++; + if (opt[z]) + fz_optarg = &opt[z+1]; + else if (fz_optind < argc) + fz_optarg = argv[fz_optind++]; + else + { + fprintf(stderr, "%s: option requires argument --%s\n", argv[0], s); + return ':'; + } + + /* If there is an arg from a predefined list, try to match that here. */ + if (arg == 1) + { + fz_optitem = fz_opt_from_list(&opt[z+1], &s[z+1]); + if (longopts->flag) + *longopts->flag = fz_optitem; + if (fz_optitem < 0) + return '?'; + } + else if (arg == 2 && longopts->flag) + { + char *p = strchr(fz_optarg, ','); + if (*fz_optarg == 0) + { + fprintf(stderr, "%s: option requires argument --%s\n", argv[0], s); + return ':'; + } + else if (!fz_strcasecmp(fz_optarg, "yes") || !fz_strcasecmp(fz_optarg, "on") || !fz_strcasecmp(fz_optarg, "true")) + *longopts->flag = 1; + else if (!fz_strcasecmp(fz_optarg, "no") || !fz_strcasecmp(fz_optarg, "off") || !fz_strcasecmp(fz_optarg, "false")) + *longopts->flag = 0; + else + *longopts->flag = fz_atoi(fz_optarg); + fz_optarg = p ? p+1 : NULL; + } + fz_optlong = longopts; + return 0; + } + + fprintf(stderr, "%s: unknown option --%s\n", argv[0], opt); + return '?'; +} + +static char *scan = NULL; /* Private scan pointer. */ + +int +fz_getopt_long(int argc, char * const *argv, const char *optstring, const fz_getopt_long_options *longopts) +{ + int c; + const char *place; + + fz_optarg = NULL; + fz_optlong = NULL; + fz_optitem = -1; + + while (!scan || *scan == '\0') + { + if (fz_optind == 0) + fz_optind++; + + if (fz_optind >= argc || argv[fz_optind][0] != '-' || argv[fz_optind][1] == '\0') + return EOF; + if (argv[fz_optind][1] == '-' && argv[fz_optind][2] == '\0') { + fz_optind++; + return EOF; + } + if (argv[fz_optind][1] == '-') + { + scan = NULL; + return match_long_option(argc, argv, longopts, &argv[fz_optind][2]); + } + + scan = argv[fz_optind]+1; + fz_optind++; + } + + c = *scan++; + place = strchr(optstring, c); + + if (!place || c == ':') { + fprintf(stderr, "%s: unknown option -%c\n", argv[0], c); + return '?'; + } + + place++; + if (*place == ':') { + if (*scan != '\0') { + fz_optarg = scan; + scan = NULL; + } else if( fz_optind < argc ) { + fz_optarg = argv[fz_optind]; + fz_optind++; + } else { + fprintf(stderr, "%s: option requires argument -%c\n", argv[0], c); + return ':'; + } + } + + return c; +} + +int +fz_getopt(int argc, char *const *argv, const char *optstring) +{ + return fz_getopt_long(argc, argv, optstring, NULL); +} + +int +fz_opt_from_list(char *opt, const char *optlist) +{ + int n = 0; + + while (*optlist) + { + const char *optend = optlist; + + if (*optend == '*') + { + fz_optarg = opt; + return n; + } + + while (*optend != 0 && *optend != '|' && *optend != ':') + optend++; + + if (fz_strncasecmp(optlist, opt, optend-optlist)) + { + /* We didn't match. Carry on. */ + } + else if (opt[optend-optlist] == 0) + { + /* We matched, ending in NUL */ + fz_optarg = NULL; + return n; + } + else if (*optend == ':' && opt[optend-optlist] == ':') + { + /* We matched, and we both have some arguments and expected some. */ + fz_optarg = &opt[optend-optlist+1]; + return n; + } + + n++; + if (*optend == ':') + { + optend++; + if (*optend == '|') + optend++; + else if (*optend != 0) + { + fprintf(stderr, "Malformed options string"); + return -1; + } + } + if (*optend == '|') + optend++; + optlist = optend; + } + + fprintf(stderr, "Unrecognised option argument: %s\n", opt); + return -1; +} + +char * +fz_optpath(char *opt) +{ + if (!strcmp(opt, "-")) + return "/dev/stdout"; +#ifdef _WIN32 + if (!fz_strcasecmp(opt, "con")) + return "/dev/stdout"; + if (!fz_strcasecmp(opt, "nul")) + return "/dev/null"; +#endif + return opt; +}
