📄 init.c
字号:
fprintf (stderr, _("\%s: Warning: Both system and user wgetrc point to `%s'.\n"), exec_name, file); } else#endif run_wgetrc (file); xfree (file); return;}/* Remove dashes and underscores from S, modifying S in the process. */static voiddehyphen (char *s){ char *t = s; /* t - tortoise */ char *h = s; /* h - hare */ while (*h) if (*h == '_' || *h == '-') ++h; else *t++ = *h++; *t = '\0';}/* Parse the line pointed by line, with the syntax: <sp>* command <sp>* = <sp>* value <sp>* Uses malloc to allocate space for command and value. If the line is invalid, data is freed and 0 is returned. Return values: 1 - success 0 - error -1 - empty In case of success, *COM and *VAL point to freshly allocated strings, and *COMIND points to com's index. In case of error or empty line, those values are unaffected. */static intparse_line (const char *line, char **com, char **val, int *comind){ const char *p; const char *end = line + strlen (line); const char *cmdstart, *cmdend; const char *valstart, *valend; char *cmdcopy; int ind; /* Skip leading and trailing whitespace. */ while (*line && ISSPACE (*line)) ++line; while (end > line && ISSPACE (end[-1])) --end; /* Skip empty lines and comments. */ if (!*line || *line == '#') return -1; p = line; cmdstart = p; while (p < end && (ISALPHA (*p) || *p == '_' || *p == '-')) ++p; cmdend = p; /* Skip '=', as well as any space before or after it. */ while (p < end && ISSPACE (*p)) ++p; if (p == end || *p != '=') return 0; ++p; while (p < end && ISSPACE (*p)) ++p; valstart = p; valend = end; /* The line now known to be syntactically correct. Check whether the command is valid. */ BOUNDED_TO_ALLOCA (cmdstart, cmdend, cmdcopy); dehyphen (cmdcopy); ind = findcmd (cmdcopy); if (ind == -1) return 0; /* The command is valid. Now fill in the values and report success to the caller. */ *comind = ind; *com = strdupdelim (cmdstart, cmdend); *val = strdupdelim (valstart, valend); return 1;}/* Run commands[comind].action. */static intsetval_internal (int comind, const char *com, const char *val){ assert (0 <= comind && comind < countof (commands)); return ((*commands[comind].action) (com, val, commands[comind].closure));}/* Run command COM with value VAL. If running the command produces an error, report the error and exit. This is intended to be called from main() with commands not provided by the user, therefore it aborts when an unknown command is encountered. Once the COMIND's are exported to init.h, this function will be changed to accept COMIND directly. */voidsetoptval (const char *com, const char *val){ if (!setval_internal (findcmd (com), com, val)) exit (2);}/* Parse OPT into command and value and run it. For example, run_command("foo=bar") is equivalent to setoptval("foo", "bar"). This is used by the `--execute' flag in main.c. */voidrun_command (const char *opt){ char *com, *val; int comind; int status = parse_line (opt, &com, &val, &comind); if (status == 1) { if (!setval_internal (comind, com, val)) exit (2); xfree (com); xfree (val); } else if (status == 0) { fprintf (stderr, _("%s: Invalid --execute command `%s'\n"), exec_name, opt); exit (2); }}/* Generic helper functions, for use with `commands'. */#define CMP1(p, c0) (TOLOWER((p)[0]) == (c0) && (p)[1] == '\0')#define CMP2(p, c0, c1) (TOLOWER((p)[0]) == (c0) \ && TOLOWER((p)[1]) == (c1) \ && (p)[2] == '\0')#define CMP3(p, c0, c1, c2) (TOLOWER((p)[0]) == (c0) \ && TOLOWER((p)[1]) == (c1) \ && TOLOWER((p)[2]) == (c2) \ && (p)[3] == '\0')/* Store the boolean value from VAL to CLOSURE. COM is ignored, except for error messages. */static intcmd_boolean (const char *com, const char *val, void *closure){ int bool_value; if (CMP2 (val, 'o', 'n') || CMP3 (val, 'y', 'e', 's') || CMP1 (val, '1')) /* "on", "yes" and "1" mean true. */ bool_value = 1; else if (CMP3 (val, 'o', 'f', 'f') || CMP2 (val, 'n', 'o') || CMP1 (val, '0')) /* "off", "no" and "0" mean false. */ bool_value = 0; else { fprintf (stderr, _("%s: %s: Invalid boolean `%s', use `on' or `off'.\n"), exec_name, com, val); return 0; } *(int *)closure = bool_value; return 1;}/* Store the lockable_boolean {2, 1, 0, -1} value from VAL to CLOSURE. COM is ignored, except for error messages. Values 2 and -1 indicate that once defined, the value may not be changed by successive wgetrc files or command-line arguments. Values: 2 - Enable a particular option for good ("always") 1 - Enable an option ("on") 0 - Disable an option ("off") -1 - Disable an option for good ("never") */static intcmd_lockable_boolean (const char *com, const char *val, void *closure){ int lockable_boolean_value; int oldval = *(int *)closure; /* * If a config file said "always" or "never", don't allow command line * arguments to override the config file. */ if (oldval == -1 || oldval == 2) return 1; if (0 == strcasecmp (val, "always") || CMP1 (val, '2')) lockable_boolean_value = 2; else if (CMP2 (val, 'o', 'n') || CMP3 (val, 'y', 'e', 's') || CMP1 (val, '1')) lockable_boolean_value = 1; else if (CMP3 (val, 'o', 'f', 'f') || CMP2 (val, 'n', 'o') || CMP1 (val, '0')) lockable_boolean_value = 0; else if (0 == strcasecmp (val, "never") || CMP2 (val, '-', '1')) lockable_boolean_value = -1; else { fprintf (stderr, _("%s: %s: Invalid boolean `%s', use always, on, off, or never.\n"), exec_name, com, val); return 0; } *(int *)closure = lockable_boolean_value; return 1;}static int simple_atoi PARAMS ((const char *, const char *, int *));/* Set the non-negative integer value from VAL to CLOSURE. With incorrect specification, the number remains unchanged. */static intcmd_number (const char *com, const char *val, void *closure){ if (!simple_atoi (val, val + strlen (val), closure)) { fprintf (stderr, _("%s: %s: Invalid number `%s'.\n"), exec_name, com, val); return 0; } return 1;}/* Similar to cmd_number(), only accepts `inf' as a synonym for 0. */static intcmd_number_inf (const char *com, const char *val, void *closure){ if (!strcasecmp (val, "inf")) { *(int *)closure = 0; return 1; } return cmd_number (com, val, closure);}/* Copy (strdup) the string at COM to a new location and place a pointer to *CLOSURE. */static intcmd_string (const char *com, const char *val, void *closure){ char **pstring = (char **)closure; FREE_MAYBE (*pstring); *pstring = xstrdup (val); return 1;}#ifndef WINDOWS# define ISSEP(c) ((c) == '/')#else# define ISSEP(c) ((c) == '/' || (c) == '\\')#endif/* Like the above, but handles tilde-expansion when reading a user's `.wgetrc'. In that case, and if VAL begins with `~', the tilde gets expanded to the user's home directory. */static intcmd_file (const char *com, const char *val, void *closure){ char **pstring = (char **)closure; FREE_MAYBE (*pstring); /* #### If VAL is empty, perhaps should set *CLOSURE to NULL. */ if (!enable_tilde_expansion || !(*val == '~' && ISSEP (val[1]))) { noexpand: *pstring = xstrdup (val); } else { char *result; int homelen; char *home = home_dir (); if (!home) goto noexpand; homelen = strlen (home); while (homelen && ISSEP (home[homelen - 1])) home[--homelen] = '\0'; /* Skip the leading "~/". */ for (++val; ISSEP (*val); val++) ; result = xmalloc (homelen + 1 + strlen (val) + 1); memcpy (result, home, homelen); result[homelen] = '/'; strcpy (result + homelen + 1, val); *pstring = result; }#ifdef WINDOWS /* Convert "\" to "/". */ { char *s; for (s = *pstring; *s; s++) if (*s == '\\') *s = '/'; }#endif return 1;}/* Like cmd_file, but strips trailing '/' characters. */static intcmd_directory (const char *com, const char *val, void *closure){ char *s, *t; /* Call cmd_file() for tilde expansion and separator canonicalization (backslash -> slash under Windows). These things should perhaps be in a separate function. */ if (!cmd_file (com, val, closure)) return 0; s = *(char **)closure; t = s + strlen (s); while (t > s && *--t == '/') *t = '\0'; return 1;}/* Split VAL by space to a vector of values, and append those values to vector pointed to by the CLOSURE argument. If VAL is empty, the CLOSURE vector is cleared instead. */static intcmd_vector (const char *com, const char *val, void *closure){ char ***pvec = (char ***)closure; if (*val) *pvec = merge_vecs (*pvec, sepstring (val)); else { free_vec (*pvec); *pvec = NULL; } return 1;}static intcmd_directory_vector (const char *com, const char *val, void *closure){ char ***pvec = (char ***)closure; if (*val) { /* Strip the trailing slashes from directories. */ char **t, **seps; seps = sepstring (val); for (t = seps; t && *t; t++) { int len = strlen (*t); /* Skip degenerate case of root directory. */ if (len > 1) { if ((*t)[len - 1] == '/') (*t)[len - 1] = '\0'; } } *pvec = merge_vecs (*pvec, seps); } else { free_vec (*pvec); *pvec = NULL; } return 1;}static int simple_atof PARAMS ((const char *, const char *, double *));/* Enginge for cmd_bytes and cmd_bytes_large: converts a string such as "100k" or "2.5G" to a floating point number. */static intparse_bytes_helper (const char *val, double *result){ double number, mult; const char *end = val + strlen (val); /* Check for "inf". */ if (0 == strcmp (val, "inf")) { *result = 0; return 1; } /* Strip trailing whitespace. */ while (val < end && ISSPACE (end[-1])) --end; if (val == end) return 0; switch (TOLOWER (end[-1])) { case 'k': --end, mult = 1024.0; break; case 'm': --end, mult = 1048576.0; break; case 'g': --end, mult = 1073741824.0; break; case 't': --end, mult = 1099511627776.0; break; default: /* Not a recognized suffix: assume it's a digit. (If not, simple_atof will raise an error.) */ mult = 1; } /* Skip leading and trailing whitespace. */ while (val < end && ISSPACE (*val)) ++val; while (val < end && ISSPACE (end[-1])) --end; if (val == end) return 0; if (!simple_atof (val, end, &number)) return 0; *result = number * mult;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -