读取并分析wgetrc文件
main():
/* If the user did not specify a config, read the system wgetrc and ~/.wgetrc. */ if (use_userconfig == false) initialize ();initialize():
/* Initialize the defaults and run the system wgetrc and user's own wgetrc. */ void initialize (void) { char *file, *env_sysrc; bool ok = true; /* Run a non-standard system rc file when the according environment variable has been set. For internal testing purposes only! */ env_sysrc = getenv ("SYSTEM_WGETRC"); if (env_sysrc && file_exists_p (env_sysrc)) { ok &= run_wgetrc (env_sysrc); /* If there are any problems parsing the system wgetrc file, tell the user and exit */ if (! ok) { fprintf (stderr, _("\ Parsing system wgetrc file (env SYSTEM_WGETRC) failed. Please check\n\ '%s',\n\ or specify a different file using --config.\n"), env_sysrc); exit (2); } } /* Otherwise, if SYSTEM_WGETRC is defined, use it. */ #ifdef SYSTEM_WGETRC else if (file_exists_p (SYSTEM_WGETRC)) ok &= run_wgetrc (SYSTEM_WGETRC); /* If there are any problems parsing the system wgetrc file, tell the user and exit */ if (! ok) { fprintf (stderr, _("\ Parsing system wgetrc file failed. Please check\n\ '%s',\n\ or specify a different file using --config.\n"), SYSTEM_WGETRC); exit (2); } #endif /* Override it with your own, if one exists. */ file = wgetrc_file_name (); if (!file) return; /* #### We should canonicalize `file' and SYSTEM_WGETRC with something like realpath() before comparing them with `strcmp' */ #ifdef SYSTEM_WGETRC if (!strcmp (file, SYSTEM_WGETRC)) { fprintf (stderr, _("\ %s: Warning: Both system and user wgetrc point to %s.\n"), exec_name, quote (file)); } else #endif ok &= run_wgetrc (file); /* If there were errors processing either `.wgetrc', abort. */ if (!ok) exit (2); xfree (file); return; }
run_wgetrc():
/* Initialize variables from a wgetrc file. Returns zero (failure) if there were errors in the file. */ bool run_wgetrc (const char *file) { FILE *fp; char *line; int ln; int errcnt = 0; fp = fopen (file, "r"); if (!fp) { fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name, file, strerror (errno)); return true; /* not a fatal error */ } ln = 1; while ((line = read_whole_line (fp)) != NULL) { char *com = NULL, *val = NULL; int comind; /* Parse the line. */ switch (parse_line (line, &com, &val, &comind)) { case line_ok: /* If everything is OK, set the value. */ if (!setval_internal_tilde (comind, com, val)) { fprintf (stderr, _("%s: Error in %s at line %d.\n"), exec_name, file, ln); ++errcnt; } break; case line_syntax_error: fprintf (stderr, _("%s: Syntax error in %s at line %d.\n"), exec_name, file, ln); ++errcnt; break; case line_unknown_command: fprintf (stderr, _("%s: Unknown command %s in %s at line %d.\n"), exec_name, quote (com), file, ln); ++errcnt; break; case line_empty: break; default: abort (); } xfree_null (com); xfree_null (val); xfree (line); ++ln; } fclose (fp); return errcnt == 0; }
parse_line():
static enum parse_line parse_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 && c_isspace (*line)) ++line; while (end > line && c_isspace (end[-1])) --end; /* Skip empty lines and comments. */ if (!*line || *line == '#') return line_empty; p = line; cmdstart = p; while (p < end && (c_isalnum (*p) || *p == '_' || *p == '-')) ++p; cmdend = p; /* Skip '=', as well as any space before or after it. */ while (p < end && c_isspace (*p)) ++p; if (p == end || *p != '=') return line_syntax_error; ++p; while (p < end && c_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; }