📄 init.c
字号:
fprintf (stderr, _("\%s: Warning: Both system and user wgetrc point to `%s'.\n"), exec_name, file); } else#endif ok &= run_wgetrc (file); /* If there were errors processing either `.wgetrc', abort. */ 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. 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 boolsetval_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 bool decode_string (const char *, const struct decode_item *, int, int *);static bool simple_atoi (const char *, const char *, int *);static bool simple_atof (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 boolcmd_boolean (const char *com, const char *val, void *place){ bool value; if (CMP2 (val, 'o', 'n') || CMP3 (val, 'y', 'e', 's') || CMP1 (val, '1')) /* "on", "yes" and "1" mean true. */ value = true; else if (CMP3 (val, 'o', 'f', 'f') || CMP2 (val, 'n', 'o') || CMP1 (val, '0')) /* "off", "no" and "0" mean false. */ value = false; else { fprintf (stderr, _("%s: %s: Invalid boolean `%s'; use `on' or `off'.\n"), exec_name, com, val); return false; } *(bool *) place = value; return true;}/* Set the non-negative integer value from VAL to PLACE. With incorrect specification, the number remains unchanged. */static boolcmd_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 false; } return true;}/* Similar to cmd_number(), only accepts `inf' as a synonym for 0. */static boolcmd_number_inf (const char *com, const char *val, void *place){ if (!strcasecmp (val, "inf")) { *(int *) place = 0; return true; } return cmd_number (com, val, place);}/* Copy (strdup) the string at COM to a new location and place a pointer to *PLACE. */static boolcmd_string (const char *com, const char *val, void *place){ char **pstring = (char **)place; xfree_null (*pstring); *pstring = xstrdup (val); return true;}#if defined(WINDOWS) || defined(MSDOS)# define ISSEP(c) ((c) == '/' || (c) == '\\')#else# define ISSEP(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 boolcmd_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); }#if defined(WINDOWS) || defined(MSDOS) /* Convert "\" to "/". */ { char *s; for (s = *pstring; *s; s++) if (*s == '\\') *s = '/'; }#endif return true;}/* Like cmd_file, but strips trailing '/' characters. */static boolcmd_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 false; s = *(char **)place; t = s + strlen (s); while (t > s && *--t == '/') *t = '\0'; return true;}/* 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 boolcmd_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 true;}static boolcmd_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 true;}/* Engine for cmd_bytes and cmd_bytes_sum: converts a string such as "100k" or "2.5G" to a floating point number. */static boolparse_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 true; } /* Strip trailing whitespace. */ while (val < end && ISSPACE (end[-1])) --end; if (val == end) return false; 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 false; if (!simple_atof (val, end, &number) || number < 0) return false; *result = number * mult; return true;}/* 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, false is returned and memory pointed to by PLACE remains unmodified. */static boolcmd_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 false; } *(wgint *)place = (wgint)byte_value; return true;}/* 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 boolcmd_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 false; } *(SUM_SIZE_INT *) place = (SUM_SIZE_INT) byte_value; return true;}/* Store the value of VAL to *OUT. The value is a time period, by default expressed in seconds, but also accepting suffixes "m", "h", "d", and "w" for minutes, hours, days, and weeks respectively. */static boolcmd_time (const char *com, const char *val, void *place){ double number, mult; const char *end = val + strlen (val); /* Strip trailing whitespace. */ while (val < end && ISSPACE (end[-1])) --end; if (val == end) { err: fprintf (stderr, _("%s: %s: Invalid time period `%s'\n"), exec_name, com, val); return false; } switch (TOLOWER (end[-1])) { case 's': --end, mult = 1; /* seconds */ break; case 'm': --end, mult = 60; /* minutes */ break; case 'h': --end, mult = 3600; /* hours */ break; case 'd': --end, mult = 86400.0; /* days */ break; case 'w': --end, mult = 604800.0; /* weeks */ break; default: /* Not a recognized suffix: assume it belongs to the number. (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) goto err;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -