📄 init.c
字号:
if (!ok) exit (2); 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. Returns one of line_ok, line_empty, line_syntax_error, or line_unknown_command. In case of line_ok, *COM and *VAL point to freshly allocated strings, and *COMIND points to com's index. In case of error or empty line, their values are unmodified. */static enum parse_lineparse_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 line_empty; p = line; cmdstart = p; while (p < end && (ISALNUM (*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 line_syntax_error; ++p; while (p < end && ISSPACE (*p)) ++p; valstart = p; valend = end; /* The syntax is valid (even though the command might not be). Fill in the command name and value. */ *com = strdupdelim (cmdstart, cmdend); *val = strdupdelim (valstart, valend); /* The line now known to be syntactically correct. Check whether the command is valid. */ BOUNDED_TO_ALLOCA (cmdstart, cmdend, cmdcopy); dehyphen (cmdcopy); ind = command_by_name (cmdcopy); if (ind == -1) return line_unknown_command; /* Report success to the caller. */ *comind = ind; return line_ok;}/* Run commands[comind].action. */static intsetval_internal (int comind, const char *com, const char *val){ assert (0 <= comind && comind < countof (commands)); DEBUGP (("Setting %s (%s) to %s\n", com, commands[comind].name, val)); return ((*commands[comind].action) (com, val, commands[comind].place));}/* 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() to modify Wget's behavior through command-line switches. Since COM is hard-coded in main(), it is not canonicalized, and this aborts when COM is not found. If COMIND's are exported to init.h, this function will be changed to accept COMIND directly. */voidsetoptval (const char *com, const char *val, const char *optname){ /* Prepend "--" to OPTNAME. */ char *dd_optname = (char *) alloca (2 + strlen (optname) + 1); dd_optname[0] = '-'; dd_optname[1] = '-'; strcpy (dd_optname + 2, optname); assert (val != NULL); if (!setval_internal (command_by_name (com), dd_optname, 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; switch (parse_line (opt, &com, &val, &comind)) { case line_ok: if (!setval_internal (comind, com, val)) exit (2); xfree (com); xfree (val); break; default: fprintf (stderr, _("%s: Invalid --execute command `%s'\n"), exec_name, opt); exit (2); }}/* Generic helper functions, for use with `commands'. *//* Forward declarations: */struct decode_item { const char *name; int code;};static int decode_string PARAMS ((const char *, const struct decode_item *, int, int *));static int simple_atoi PARAMS ((const char *, const char *, int *));static int simple_atof PARAMS ((const char *, const char *, double *));#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 PLACE. COM is ignored, except for error messages. */static intcmd_boolean (const char *com, const char *val, void *place){ 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 *)place = bool_value; return 1;}/* Store the lockable_boolean {2, 1, 0, -1} value from VAL to PLACE. 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") #### This hack is currently only used for passive FTP because a contributor had broken scripts specify --passive-ftp where he didn't want it. It should be removed because the same can now be achieved by replacing the wget executable with a script containing: exec wget "$@" --no-passive-ftp*/static intcmd_lockable_boolean (const char *com, const char *val, void *place){ int lockable_boolean_value; int oldval = *(int *)place; /* * 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 (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, "always")) lockable_boolean_value = 2; else if (0 == strcasecmp (val, "never")) lockable_boolean_value = -1; else { fprintf (stderr, _("%s: %s: Invalid extended boolean `%s';\n\use one of `on', `off', `always', or `never'.\n"), exec_name, com, val); return 0; } *(int *)place = lockable_boolean_value; return 1;}/* Set the non-negative integer value from VAL to PLACE. With incorrect specification, the number remains unchanged. */static intcmd_number (const char *com, const char *val, void *place){ if (!simple_atoi (val, val + strlen (val), place) || *(int *) place < 0) { 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 *place){ if (!strcasecmp (val, "inf")) { *(int *)place = 0; return 1; } return cmd_number (com, val, place);}/* Copy (strdup) the string at COM to a new location and place a pointer to *PLACE. */static intcmd_string (const char *com, const char *val, void *place){ char **pstring = (char **)place; xfree_null (*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 *place){ char **pstring = (char **)place; xfree_null (*pstring); /* #### If VAL is empty, perhaps should set *PLACE to NULL. */ if (!enable_tilde_expansion || !(*val == '~' && ISSEP (val[1]))) { noexpand: *pstring = xstrdup (val); } else { 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++) ; *pstring = concat_strings (home, "/", val, (char *) 0); }#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 *place){ 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, place)) return 0; s = *(char **)place; 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 PLACE argument. If VAL is empty, the PLACE vector is cleared instead. */static intcmd_vector (const char *com, const char *val, void *place){ char ***pvec = (char ***)place; 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 *place){ char ***pvec = (char ***)place; 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;}/* Engine for cmd_bytes and cmd_bytes_sum: 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) || number < 0) return 0; *result = number * mult; return 1;}/* Parse VAL as a number and set its value to PLACE (which should point to a wgint). By default, the value is assumed to be in bytes. If "K", "M", or "G" are appended, the value is multiplied with 1<<10, 1<<20, or 1<<30, respectively. Floating point values are allowed and are cast to integer before use. The idea is to be able to use things like 1.5k instead of "1536". The string "inf" is returned as 0. In case of error, 0 is returned and memory pointed to by PLACE remains unmodified. */static intcmd_bytes (const char *com, const char *val, void *place){ double byte_value; if (!parse_bytes_helper (val, &byte_value)) { fprintf (stderr, _("%s: %s: Invalid byte value `%s'\n"), exec_name, com, val); return 0; } *(wgint *)place = (wgint)byte_value; return 1;}/* Like cmd_bytes, but PLACE is interpreted as a pointer to SIZE_SUM. It works by converting the string to double, therefore working with values up to 2^53-1 without loss of precision. This value (8192 TB) is large enough to serve for a while. */static intcmd_bytes_sum (const char *com, const char *val, void *place){ double byte_value; if (!parse_bytes_helper (val, &byte_value)) { fprintf (stderr, _("%s: %s: Invalid byte value `%s'\n"), exec_name, com, val); return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -