Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/curl/src/tool_parsecfg.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 * _ _ ____ _ | |
| 3 * Project ___| | | | _ \| | | |
| 4 * / __| | | | |_) | | | |
| 5 * | (__| |_| | _ <| |___ | |
| 6 * \___|\___/|_| \_\_____| | |
| 7 * | |
| 8 * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. | |
| 9 * | |
| 10 * This software is licensed as described in the file COPYING, which | |
| 11 * you should have received as part of this distribution. The terms | |
| 12 * are also available at https://curl.haxx.se/docs/copyright.html. | |
| 13 * | |
| 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell | |
| 15 * copies of the Software, and permit persons to whom the Software is | |
| 16 * furnished to do so, under the terms of the COPYING file. | |
| 17 * | |
| 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | |
| 19 * KIND, either express or implied. | |
| 20 * | |
| 21 ***************************************************************************/ | |
| 22 #include "tool_setup.h" | |
| 23 | |
| 24 #define ENABLE_CURLX_PRINTF | |
| 25 /* use our own printf() functions */ | |
| 26 #include "curlx.h" | |
| 27 | |
| 28 #include "tool_cfgable.h" | |
| 29 #include "tool_getparam.h" | |
| 30 #include "tool_helpers.h" | |
| 31 #include "tool_homedir.h" | |
| 32 #include "tool_msgs.h" | |
| 33 #include "tool_parsecfg.h" | |
| 34 | |
| 35 #include "memdebug.h" /* keep this as LAST include */ | |
| 36 | |
| 37 /* only acknowledge colon or equals as separators if the option was not | |
| 38 specified with an initial dash! */ | |
| 39 #define ISSEP(x,dash) (!dash && (((x) == '=') || ((x) == ':'))) | |
| 40 | |
| 41 static const char *unslashquote(const char *line, char *param); | |
| 42 static char *my_get_line(FILE *fp); | |
| 43 | |
| 44 #ifdef WIN32 | |
| 45 static FILE *execpath(const char *filename) | |
| 46 { | |
| 47 char filebuffer[512]; | |
| 48 /* Get the filename of our executable. GetModuleFileName is already declared | |
| 49 * via inclusions done in setup header file. We assume that we are using | |
| 50 * the ASCII version here. | |
| 51 */ | |
| 52 unsigned long len = GetModuleFileNameA(0, filebuffer, sizeof(filebuffer)); | |
| 53 if(len > 0 && len < sizeof(filebuffer)) { | |
| 54 /* We got a valid filename - get the directory part */ | |
| 55 char *lastdirchar = strrchr(filebuffer, '\\'); | |
| 56 if(lastdirchar) { | |
| 57 size_t remaining; | |
| 58 *lastdirchar = 0; | |
| 59 /* If we have enough space, build the RC filename */ | |
| 60 remaining = sizeof(filebuffer) - strlen(filebuffer); | |
| 61 if(strlen(filename) < remaining - 1) { | |
| 62 msnprintf(lastdirchar, remaining, "%s%s", DIR_CHAR, filename); | |
| 63 return fopen(filebuffer, FOPEN_READTEXT); | |
| 64 } | |
| 65 } | |
| 66 } | |
| 67 | |
| 68 return NULL; | |
| 69 } | |
| 70 #endif | |
| 71 | |
| 72 | |
| 73 /* return 0 on everything-is-fine, and non-zero otherwise */ | |
| 74 int parseconfig(const char *filename, struct GlobalConfig *global) | |
| 75 { | |
| 76 FILE *file = NULL; | |
| 77 bool usedarg = FALSE; | |
| 78 int rc = 0; | |
| 79 struct OperationConfig *operation = global->first; | |
| 80 char *pathalloc = NULL; | |
| 81 | |
| 82 if(!filename || !*filename) { | |
| 83 /* NULL or no file name attempts to load .curlrc from the homedir! */ | |
| 84 | |
| 85 char *home = homedir(); /* portable homedir finder */ | |
| 86 #ifndef WIN32 | |
| 87 if(home) { | |
| 88 pathalloc = curl_maprintf("%s%s.curlrc", home, DIR_CHAR); | |
| 89 if(!pathalloc) { | |
| 90 free(home); | |
| 91 return 1; /* out of memory */ | |
| 92 } | |
| 93 filename = pathalloc; | |
| 94 } | |
| 95 #else /* Windows */ | |
| 96 if(home) { | |
| 97 int i = 0; | |
| 98 char prefix = '.'; | |
| 99 do { | |
| 100 /* check for .curlrc then _curlrc in the home dir */ | |
| 101 pathalloc = curl_maprintf("%s%s%ccurlrc", home, DIR_CHAR, prefix); | |
| 102 if(!pathalloc) { | |
| 103 free(home); | |
| 104 return 1; /* out of memory */ | |
| 105 } | |
| 106 | |
| 107 /* Check if the file exists - if not, try _curlrc */ | |
| 108 file = fopen(pathalloc, FOPEN_READTEXT); | |
| 109 if(file) { | |
| 110 filename = pathalloc; | |
| 111 break; | |
| 112 } | |
| 113 prefix = '_'; | |
| 114 } while(++i < 2); | |
| 115 } | |
| 116 if(!filename) { | |
| 117 /* check for .curlrc then _curlrc in the dir of the executable */ | |
| 118 file = execpath(".curlrc"); | |
| 119 if(!file) | |
| 120 file = execpath("_curlrc"); | |
| 121 } | |
| 122 #endif | |
| 123 | |
| 124 Curl_safefree(home); /* we've used it, now free it */ | |
| 125 } | |
| 126 | |
| 127 if(!file && filename) { /* no need to fopen() again */ | |
| 128 if(strcmp(filename, "-")) | |
| 129 file = fopen(filename, FOPEN_READTEXT); | |
| 130 else | |
| 131 file = stdin; | |
| 132 } | |
| 133 | |
| 134 if(file) { | |
| 135 char *line; | |
| 136 char *aline; | |
| 137 char *option; | |
| 138 char *param; | |
| 139 int lineno = 0; | |
| 140 bool dashed_option; | |
| 141 | |
| 142 while(NULL != (aline = my_get_line(file))) { | |
| 143 int res; | |
| 144 bool alloced_param = FALSE; | |
| 145 lineno++; | |
| 146 line = aline; | |
| 147 | |
| 148 /* line with # in the first non-blank column is a comment! */ | |
| 149 while(*line && ISSPACE(*line)) | |
| 150 line++; | |
| 151 | |
| 152 switch(*line) { | |
| 153 case '#': | |
| 154 case '/': | |
| 155 case '\r': | |
| 156 case '\n': | |
| 157 case '*': | |
| 158 case '\0': | |
| 159 Curl_safefree(aline); | |
| 160 continue; | |
| 161 } | |
| 162 | |
| 163 /* the option keywords starts here */ | |
| 164 option = line; | |
| 165 | |
| 166 /* the option starts with a dash? */ | |
| 167 dashed_option = option[0]=='-'?TRUE:FALSE; | |
| 168 | |
| 169 while(*line && !ISSPACE(*line) && !ISSEP(*line, dashed_option)) | |
| 170 line++; | |
| 171 /* ... and has ended here */ | |
| 172 | |
| 173 if(*line) | |
| 174 *line++ = '\0'; /* zero terminate, we have a local copy of the data */ | |
| 175 | |
| 176 #ifdef DEBUG_CONFIG | |
| 177 fprintf(stderr, "GOT: %s\n", option); | |
| 178 #endif | |
| 179 | |
| 180 /* pass spaces and separator(s) */ | |
| 181 while(*line && (ISSPACE(*line) || ISSEP(*line, dashed_option))) | |
| 182 line++; | |
| 183 | |
| 184 /* the parameter starts here (unless quoted) */ | |
| 185 if(*line == '\"') { | |
| 186 /* quoted parameter, do the quote dance */ | |
| 187 line++; | |
| 188 param = malloc(strlen(line) + 1); /* parameter */ | |
| 189 if(!param) { | |
| 190 /* out of memory */ | |
| 191 Curl_safefree(aline); | |
| 192 rc = 1; | |
| 193 break; | |
| 194 } | |
| 195 alloced_param = TRUE; | |
| 196 (void)unslashquote(line, param); | |
| 197 } | |
| 198 else { | |
| 199 param = line; /* parameter starts here */ | |
| 200 while(*line && !ISSPACE(*line)) | |
| 201 line++; | |
| 202 | |
| 203 if(*line) { | |
| 204 *line = '\0'; /* zero terminate */ | |
| 205 | |
| 206 /* to detect mistakes better, see if there's data following */ | |
| 207 line++; | |
| 208 /* pass all spaces */ | |
| 209 while(*line && ISSPACE(*line)) | |
| 210 line++; | |
| 211 | |
| 212 switch(*line) { | |
| 213 case '\0': | |
| 214 case '\r': | |
| 215 case '\n': | |
| 216 case '#': /* comment */ | |
| 217 break; | |
| 218 default: | |
| 219 warnf(operation->global, "%s:%d: warning: '%s' uses unquoted " | |
| 220 "white space in the line that may cause side-effects!\n", | |
| 221 filename, lineno, option); | |
| 222 } | |
| 223 } | |
| 224 if(!*param) | |
| 225 /* do this so getparameter can check for required parameters. | |
| 226 Otherwise it always thinks there's a parameter. */ | |
| 227 param = NULL; | |
| 228 } | |
| 229 | |
| 230 #ifdef DEBUG_CONFIG | |
| 231 fprintf(stderr, "PARAM: \"%s\"\n",(param ? param : "(null)")); | |
| 232 #endif | |
| 233 res = getparameter(option, param, &usedarg, global, operation); | |
| 234 | |
| 235 if(!res && param && *param && !usedarg) | |
| 236 /* we passed in a parameter that wasn't used! */ | |
| 237 res = PARAM_GOT_EXTRA_PARAMETER; | |
| 238 | |
| 239 if(res == PARAM_NEXT_OPERATION) { | |
| 240 if(operation->url_list && operation->url_list->url) { | |
| 241 /* Allocate the next config */ | |
| 242 operation->next = malloc(sizeof(struct OperationConfig)); | |
| 243 if(operation->next) { | |
| 244 /* Initialise the newly created config */ | |
| 245 config_init(operation->next); | |
| 246 | |
| 247 /* Set the global config pointer */ | |
| 248 operation->next->global = global; | |
| 249 | |
| 250 /* Update the last operation pointer */ | |
| 251 global->last = operation->next; | |
| 252 | |
| 253 /* Move onto the new config */ | |
| 254 operation->next->prev = operation; | |
| 255 operation = operation->next; | |
| 256 } | |
| 257 else | |
| 258 res = PARAM_NO_MEM; | |
| 259 } | |
| 260 } | |
| 261 | |
| 262 if(res != PARAM_OK && res != PARAM_NEXT_OPERATION) { | |
| 263 /* the help request isn't really an error */ | |
| 264 if(!strcmp(filename, "-")) { | |
| 265 filename = "<stdin>"; | |
| 266 } | |
| 267 if(res != PARAM_HELP_REQUESTED && | |
| 268 res != PARAM_MANUAL_REQUESTED && | |
| 269 res != PARAM_VERSION_INFO_REQUESTED && | |
| 270 res != PARAM_ENGINES_REQUESTED) { | |
| 271 const char *reason = param2text(res); | |
| 272 warnf(operation->global, "%s:%d: warning: '%s' %s\n", | |
| 273 filename, lineno, option, reason); | |
| 274 } | |
| 275 } | |
| 276 | |
| 277 if(alloced_param) | |
| 278 Curl_safefree(param); | |
| 279 | |
| 280 Curl_safefree(aline); | |
| 281 } | |
| 282 if(file != stdin) | |
| 283 fclose(file); | |
| 284 } | |
| 285 else | |
| 286 rc = 1; /* couldn't open the file */ | |
| 287 | |
| 288 free(pathalloc); | |
| 289 return rc; | |
| 290 } | |
| 291 | |
| 292 /* | |
| 293 * Copies the string from line to the buffer at param, unquoting | |
| 294 * backslash-quoted characters and NUL-terminating the output string. | |
| 295 * Stops at the first non-backslash-quoted double quote character or the | |
| 296 * end of the input string. param must be at least as long as the input | |
| 297 * string. Returns the pointer after the last handled input character. | |
| 298 */ | |
| 299 static const char *unslashquote(const char *line, char *param) | |
| 300 { | |
| 301 while(*line && (*line != '\"')) { | |
| 302 if(*line == '\\') { | |
| 303 char out; | |
| 304 line++; | |
| 305 | |
| 306 /* default is to output the letter after the backslash */ | |
| 307 switch(out = *line) { | |
| 308 case '\0': | |
| 309 continue; /* this'll break out of the loop */ | |
| 310 case 't': | |
| 311 out = '\t'; | |
| 312 break; | |
| 313 case 'n': | |
| 314 out = '\n'; | |
| 315 break; | |
| 316 case 'r': | |
| 317 out = '\r'; | |
| 318 break; | |
| 319 case 'v': | |
| 320 out = '\v'; | |
| 321 break; | |
| 322 } | |
| 323 *param++ = out; | |
| 324 line++; | |
| 325 } | |
| 326 else | |
| 327 *param++ = *line++; | |
| 328 } | |
| 329 *param = '\0'; /* always zero terminate */ | |
| 330 return line; | |
| 331 } | |
| 332 | |
| 333 /* | |
| 334 * Reads a line from the given file, ensuring is NUL terminated. | |
| 335 * The pointer must be freed by the caller. | |
| 336 * NULL is returned on an out of memory condition. | |
| 337 */ | |
| 338 static char *my_get_line(FILE *fp) | |
| 339 { | |
| 340 char buf[4096]; | |
| 341 char *nl = NULL; | |
| 342 char *line = NULL; | |
| 343 | |
| 344 do { | |
| 345 if(NULL == fgets(buf, sizeof(buf), fp)) | |
| 346 break; | |
| 347 if(!line) { | |
| 348 line = strdup(buf); | |
| 349 if(!line) | |
| 350 return NULL; | |
| 351 } | |
| 352 else { | |
| 353 char *ptr; | |
| 354 size_t linelen = strlen(line); | |
| 355 ptr = realloc(line, linelen + strlen(buf) + 1); | |
| 356 if(!ptr) { | |
| 357 Curl_safefree(line); | |
| 358 return NULL; | |
| 359 } | |
| 360 line = ptr; | |
| 361 strcpy(&line[linelen], buf); | |
| 362 } | |
| 363 nl = strchr(line, '\n'); | |
| 364 } while(!nl); | |
| 365 | |
| 366 if(nl) | |
| 367 *nl = '\0'; | |
| 368 | |
| 369 return line; | |
| 370 } |
