diff options
author | Paul Smith <psmith@gnu.org> | 2013-06-22 00:22:08 -0400 |
---|---|---|
committer | Paul Smith <psmith@gnu.org> | 2013-06-22 00:22:08 -0400 |
commit | cc85b927cdc1a4dad3217842215903a45044fc43 (patch) | |
tree | 74ae34c9306f5dde33e258c4181215ee04d4203f /main.c | |
parent | bee4d93a591f7f729717f6079f7d62ef555d9887 (diff) | |
download | gunmake-cc85b927cdc1a4dad3217842215903a45044fc43.tar.gz |
Create a character map to use for locating stop-points in strings.
In various places we were passing flags and characters to compare, then
using complex conditionals to see where to stop in string searches.
Performance numbers reveal that we were spending as much as 23% of our
processing time in these functions, most of it in the comparison lines.
Instead create a character map and use a single bitwise comparison to
determine if this is any one of the stop characters.
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 48 |
1 files changed, 46 insertions, 2 deletions
@@ -548,6 +548,13 @@ int not_parallel; warning at the end of the run. */ int clock_skew_detected; + +/* Map of possible stop characters for searching strings. */ +#ifndef UCHAR_MAX +# define UCHAR_MAX 255 +#endif +unsigned short stopchar_map[UCHAR_MAX + 1] = {0}; + /* Mask of signals that are being caught with fatal_error_signal. */ @@ -590,6 +597,41 @@ initialize_global_hash_tables (void) hash_init_function_table (); } +/* This character map locate stop chars when parsing GNU makefiles. + Each element is true if we should stop parsing on that character. */ + +static void +initialize_stopchar_map () +{ + int i; + + stopchar_map[(int)'\0'] = MAP_NUL; + stopchar_map[(int)'#'] = MAP_COMMENT; + stopchar_map[(int)';'] = MAP_SEMI; + stopchar_map[(int)'='] = MAP_EQUALS; + stopchar_map[(int)':'] = MAP_COLON; + stopchar_map[(int)'%'] = MAP_PERCENT; + stopchar_map[(int)'|'] = MAP_PIPE; + stopchar_map[(int)'.'] = MAP_DOT; + stopchar_map[(int)','] = MAP_COMMA; + stopchar_map[(int)'$'] = MAP_VARIABLE; + + stopchar_map[(int)'/'] = MAP_PATHSEP; +#if defined(VMS) + stopchar_map[(int)']'] = MAP_PATHSEP; +#elif defined(HAVE_DOS_PATHS) + stopchar_map[(int)'\\'] = MAP_PATHSEP; +#endif + + for (i = 1; i <= UCHAR_MAX; ++i) + { + if (isblank(i)) + stopchar_map[i] = MAP_BLANK; + if (isspace(i)) + stopchar_map[i] |= MAP_SPACE; + } +} + static const char * expand_command_line_file (char *name) { @@ -1026,6 +1068,8 @@ main (int argc, char **argv, char **envp) no_default_sh_exe = 1; #endif + initialize_stopchar_map(); + #ifdef SET_STACK_SIZE /* Get rid of any avoidable limit on stack size. */ { @@ -1278,7 +1322,7 @@ main (int argc, char **argv, char **envp) int do_not_define = 0; char *ep = envp[i]; - while (*ep != '\0' && *ep != '=') + while (! STOP_SET (*ep, MAP_EQUALS)) ++ep; #ifdef WINDOWS32 if (!unix_path && strneq (envp[i], "PATH=", 5)) @@ -2420,7 +2464,7 @@ main (int argc, char **argv, char **envp) { struct nameseq *ns; - ns = PARSE_FILE_SEQ (&p, struct nameseq, '\0', NULL, 0); + ns = PARSE_FILE_SEQ (&p, struct nameseq, MAP_NUL, NULL, 0); if (ns) { /* .DEFAULT_GOAL should contain one target. */ |