Mercurial > hgrepos > Python2 > PyMuPDF
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /* | |
| 2 * This is a version of the public domain getopt implementation by | |
| 3 * Henry Spencer originally posted to net.sources. | |
| 4 * | |
| 5 * This file is in the public domain. | |
| 6 */ | |
| 7 | |
| 8 #include <stdio.h> | |
| 9 #include <string.h> | |
| 10 | |
| 11 #include "mupdf/fitz/getopt.h" | |
| 12 #include "mupdf/fitz/string-util.h" | |
| 13 | |
| 14 char *fz_optarg; /* Global argument pointer. */ | |
| 15 int fz_optind = 0; /* Global argv index. */ | |
| 16 const fz_getopt_long_options *fz_optlong = NULL; | |
| 17 int fz_optitem = 0; /* Which item in a long opt list is selected? */ | |
| 18 | |
| 19 static int | |
| 20 match_long_option(int argc, char * const *argv, const fz_getopt_long_options *longopts, char *opt) | |
| 21 { | |
| 22 if (longopts == NULL) | |
| 23 { | |
| 24 fprintf(stderr, "%s: unknown option --%s\n", argv[0], opt); | |
| 25 return '?'; | |
| 26 } | |
| 27 | |
| 28 while (longopts->option) | |
| 29 { | |
| 30 const char *s = longopts->option; | |
| 31 const char *eq = strchr(s, '='); | |
| 32 size_t z = eq ? (size_t)(eq-s) : strlen(s); | |
| 33 int arg = 0; /* No arg */ | |
| 34 | |
| 35 if (s[z] == '=') | |
| 36 arg = 1; /* arg = 1 => Arg list given */ | |
| 37 else if (z && s[z-1] == ':') | |
| 38 arg = 2, z--; /* arg = 2 -> argument expected */ | |
| 39 | |
| 40 /* If we don't match, try the next one. */ | |
| 41 /* If we aren't expecting an argument, and the given string is longer than expected, try the next one. */ | |
| 42 /* If we are expecting an argument, and the given string doesn't either terminate or end in '=', try the next one. */ | |
| 43 if (strncmp(s, opt, z) || (arg == 0 && opt[z] != 0) || (arg != 0 && opt[z] != 0 && opt[z] != '=')) | |
| 44 { | |
| 45 longopts++; | |
| 46 continue; | |
| 47 } | |
| 48 | |
| 49 /* So we have a match. */ | |
| 50 fz_optind++; | |
| 51 if (opt[z]) | |
| 52 fz_optarg = &opt[z+1]; | |
| 53 else if (fz_optind < argc) | |
| 54 fz_optarg = argv[fz_optind++]; | |
| 55 else | |
| 56 { | |
| 57 fprintf(stderr, "%s: option requires argument --%s\n", argv[0], s); | |
| 58 return ':'; | |
| 59 } | |
| 60 | |
| 61 /* If there is an arg from a predefined list, try to match that here. */ | |
| 62 if (arg == 1) | |
| 63 { | |
| 64 fz_optitem = fz_opt_from_list(&opt[z+1], &s[z+1]); | |
| 65 if (longopts->flag) | |
| 66 *longopts->flag = fz_optitem; | |
| 67 if (fz_optitem < 0) | |
| 68 return '?'; | |
| 69 } | |
| 70 else if (arg == 2 && longopts->flag) | |
| 71 { | |
| 72 char *p = strchr(fz_optarg, ','); | |
| 73 if (*fz_optarg == 0) | |
| 74 { | |
| 75 fprintf(stderr, "%s: option requires argument --%s\n", argv[0], s); | |
| 76 return ':'; | |
| 77 } | |
| 78 else if (!fz_strcasecmp(fz_optarg, "yes") || !fz_strcasecmp(fz_optarg, "on") || !fz_strcasecmp(fz_optarg, "true")) | |
| 79 *longopts->flag = 1; | |
| 80 else if (!fz_strcasecmp(fz_optarg, "no") || !fz_strcasecmp(fz_optarg, "off") || !fz_strcasecmp(fz_optarg, "false")) | |
| 81 *longopts->flag = 0; | |
| 82 else | |
| 83 *longopts->flag = fz_atoi(fz_optarg); | |
| 84 fz_optarg = p ? p+1 : NULL; | |
| 85 } | |
| 86 fz_optlong = longopts; | |
| 87 return 0; | |
| 88 } | |
| 89 | |
| 90 fprintf(stderr, "%s: unknown option --%s\n", argv[0], opt); | |
| 91 return '?'; | |
| 92 } | |
| 93 | |
| 94 static char *scan = NULL; /* Private scan pointer. */ | |
| 95 | |
| 96 int | |
| 97 fz_getopt_long(int argc, char * const *argv, const char *optstring, const fz_getopt_long_options *longopts) | |
| 98 { | |
| 99 int c; | |
| 100 const char *place; | |
| 101 | |
| 102 fz_optarg = NULL; | |
| 103 fz_optlong = NULL; | |
| 104 fz_optitem = -1; | |
| 105 | |
| 106 while (!scan || *scan == '\0') | |
| 107 { | |
| 108 if (fz_optind == 0) | |
| 109 fz_optind++; | |
| 110 | |
| 111 if (fz_optind >= argc || argv[fz_optind][0] != '-' || argv[fz_optind][1] == '\0') | |
| 112 return EOF; | |
| 113 if (argv[fz_optind][1] == '-' && argv[fz_optind][2] == '\0') { | |
| 114 fz_optind++; | |
| 115 return EOF; | |
| 116 } | |
| 117 if (argv[fz_optind][1] == '-') | |
| 118 { | |
| 119 scan = NULL; | |
| 120 return match_long_option(argc, argv, longopts, &argv[fz_optind][2]); | |
| 121 } | |
| 122 | |
| 123 scan = argv[fz_optind]+1; | |
| 124 fz_optind++; | |
| 125 } | |
| 126 | |
| 127 c = *scan++; | |
| 128 place = strchr(optstring, c); | |
| 129 | |
| 130 if (!place || c == ':') { | |
| 131 fprintf(stderr, "%s: unknown option -%c\n", argv[0], c); | |
| 132 return '?'; | |
| 133 } | |
| 134 | |
| 135 place++; | |
| 136 if (*place == ':') { | |
| 137 if (*scan != '\0') { | |
| 138 fz_optarg = scan; | |
| 139 scan = NULL; | |
| 140 } else if( fz_optind < argc ) { | |
| 141 fz_optarg = argv[fz_optind]; | |
| 142 fz_optind++; | |
| 143 } else { | |
| 144 fprintf(stderr, "%s: option requires argument -%c\n", argv[0], c); | |
| 145 return ':'; | |
| 146 } | |
| 147 } | |
| 148 | |
| 149 return c; | |
| 150 } | |
| 151 | |
| 152 int | |
| 153 fz_getopt(int argc, char *const *argv, const char *optstring) | |
| 154 { | |
| 155 return fz_getopt_long(argc, argv, optstring, NULL); | |
| 156 } | |
| 157 | |
| 158 int | |
| 159 fz_opt_from_list(char *opt, const char *optlist) | |
| 160 { | |
| 161 int n = 0; | |
| 162 | |
| 163 while (*optlist) | |
| 164 { | |
| 165 const char *optend = optlist; | |
| 166 | |
| 167 if (*optend == '*') | |
| 168 { | |
| 169 fz_optarg = opt; | |
| 170 return n; | |
| 171 } | |
| 172 | |
| 173 while (*optend != 0 && *optend != '|' && *optend != ':') | |
| 174 optend++; | |
| 175 | |
| 176 if (fz_strncasecmp(optlist, opt, optend-optlist)) | |
| 177 { | |
| 178 /* We didn't match. Carry on. */ | |
| 179 } | |
| 180 else if (opt[optend-optlist] == 0) | |
| 181 { | |
| 182 /* We matched, ending in NUL */ | |
| 183 fz_optarg = NULL; | |
| 184 return n; | |
| 185 } | |
| 186 else if (*optend == ':' && opt[optend-optlist] == ':') | |
| 187 { | |
| 188 /* We matched, and we both have some arguments and expected some. */ | |
| 189 fz_optarg = &opt[optend-optlist+1]; | |
| 190 return n; | |
| 191 } | |
| 192 | |
| 193 n++; | |
| 194 if (*optend == ':') | |
| 195 { | |
| 196 optend++; | |
| 197 if (*optend == '|') | |
| 198 optend++; | |
| 199 else if (*optend != 0) | |
| 200 { | |
| 201 fprintf(stderr, "Malformed options string"); | |
| 202 return -1; | |
| 203 } | |
| 204 } | |
| 205 if (*optend == '|') | |
| 206 optend++; | |
| 207 optlist = optend; | |
| 208 } | |
| 209 | |
| 210 fprintf(stderr, "Unrecognised option argument: %s\n", opt); | |
| 211 return -1; | |
| 212 } | |
| 213 | |
| 214 char * | |
| 215 fz_optpath(char *opt) | |
| 216 { | |
| 217 if (!strcmp(opt, "-")) | |
| 218 return "/dev/stdout"; | |
| 219 #ifdef _WIN32 | |
| 220 if (!fz_strcasecmp(opt, "con")) | |
| 221 return "/dev/stdout"; | |
| 222 if (!fz_strcasecmp(opt, "nul")) | |
| 223 return "/dev/null"; | |
| 224 #endif | |
| 225 return opt; | |
| 226 } |
