void parse_config_file(char *map, size_t len) { int *end = (int *) (map + len); /* start at +1, so that p can never be < map */ int *m = (int *) map + 1; char *p, *q; for (; m < end; m++) { if (*m == INT_CONF) { p = (char *) m ; goto conf; } if (*m == INT_ONFI) { p = (char *) m-1; goto conf; } if (*m == INT_NFIG) { p = (char *) m-2; goto conf; } if (*m == INT_FIG_) { p = (char *) m-3; goto conf; } continue; conf: if (p > map + len - 7) continue; if (memcmp(p, "CONFIG_", 7)) continue; for (q = p + 7; q < map + len; q++) { if (!(isalnum(*q) || *q == '_')) goto found; } continue; found: if (!memcmp(q - 7, "_MODULE", 7)) q -= 7; if( (q-p-7) < 0 ) continue; use_config(p+7, q-p-7); } }
void parse_config_file(char *map, size_t len) { /* modified for bbox */ char *end_4 = map + len - 4; /* 4 == length of "USE_" */ char *end_7 = map + len - 7; char *p = map; char *q; int off; for (; p < end_4; p++) { if (p < end_7 && p[6] == '_') { if (!memcmp(p, "CONFIG", 6)) goto conf7; if (!memcmp(p, "ENABLE", 6)) goto conf7; } /* We have at least 5 chars: for() has * "p < end-4", not "p <= end-4" * therefore we don't need to check p <= end-5 here */ if (p[4] == '_') if (!memcmp(p, "SKIP", 4)) goto conf5; /* Ehhh, gcc is too stupid to just compare it as 32bit int */ if (p[0] == 'U') if (!memcmp(p, "USE_", 4)) goto conf4; continue; conf4: off = 4; conf5: off = 5; conf7: off = 7; p += off; for (q = p; q < end_4+4; q++) { if (!(isalnum(*q) || *q == '_')) break; } use_config(p, q-p); } }
void parse_config_file(char *map, size_t len) { /* modified for bbox */ char *end_3 = map + len - 3; /* 3 == length of "IF_" */ char *end_7 = map + len - 7; char *p = map; char *q; int off; for (; p <= end_3; p++) { /* Find next identifier's beginning */ if (!(isalnum(*p) || *p == '_')) continue; /* Check it */ if (p < end_7 && p[6] == '_') { if (!memcmp(p, "CONFIG", 6)) goto conf7; if (!memcmp(p, "ENABLE", 6)) goto conf7; if (!memcmp(p, "IF_NOT", 6)) goto conf7; } /* we have at least 3 chars because of p <= end_3 */ /*if (!memcmp(p, "IF_", 3)) ...*/ if (p[0] == 'I' && p[1] == 'F' && p[2] == '_') { off = 3; goto conf; } /* This identifier is not interesting, skip it */ while (p <= end_3 && (isalnum(*p) || *p == '_')) p++; continue; conf7: off = 7; conf: p += off; for (q = p; q < end_3+3; q++) { if (!(isalnum(*q) || *q == '_')) break; } if (q != p) { use_config(p, q-p); } } }
/* * The state machine looks for (approximately) these Perl regular expressions: * * m|\/\*.*?\*\/| * m|\/\/.*| * m|'.*?'| * m|".*?"| * m|#\s*include\s*"(.*?)"| * m|#\s*include\s*<(.*?>"| * m|#\s*(?define|undef)\s*CONFIG_(\w*)| * m|(?!\w)CONFIG_| * * About 98% of the CPU time is spent here, and most of that is in * the 'start' paragraph. Because the current characters are * in a register, the start loop usually eats 4 or 8 characters * per memory read. The MAX5 and MIN5 tests dispose of most * input characters with 1 or 2 comparisons. */ void state_machine(const char * map, const char * end) { const char * next = map; const char * map_dot; unsigned long __buf = 0; for (;;) { start: GETNEXT __start: if (current > MAX5('/','\'','"','#','C')) goto start; if (current < MIN5('/','\'','"','#','C')) goto start; CASE('/', slash); CASE('\'', squote); CASE('"', dquote); CASE('#', pound); CASE('C', cee); goto start; /* // */ slash_slash: GETNEXT CASE('\n', start); NOTCASE('\\', slash_slash); GETNEXT goto slash_slash; /* / */ slash: GETNEXT CASE('/', slash_slash); NOTCASE('*', __start); slash_star_dot_star: GETNEXT __slash_star_dot_star: NOTCASE('*', slash_star_dot_star); GETNEXT NOTCASE('/', __slash_star_dot_star); goto start; /* '.*?' */ squote: GETNEXT CASE('\'', start); NOTCASE('\\', squote); GETNEXT goto squote; /* ".*?" */ dquote: GETNEXT CASE('"', start); NOTCASE('\\', dquote); GETNEXT goto dquote; /* #\s* */ pound: GETNEXT CASE(' ', pound); CASE('\t', pound); CASE('i', pound_i); CASE('d', pound_d); CASE('u', pound_u); goto __start; /* #\s*i */ pound_i: GETNEXT NOTCASE('n', __start); GETNEXT NOTCASE('c', __start); GETNEXT NOTCASE('l', __start); GETNEXT NOTCASE('u', __start); GETNEXT NOTCASE('d', __start); GETNEXT NOTCASE('e', __start); goto pound_include; /* #\s*include\s* */ pound_include: GETNEXT CASE(' ', pound_include); CASE('\t', pound_include); map_dot = next; CASE('"', pound_include_dquote); CASE('<', pound_include_langle); goto __start; /* #\s*include\s*"(.*)" */ pound_include_dquote: GETNEXT CASE('\n', start); NOTCASE('"', pound_include_dquote); handle_include(0, map_dot, next - map_dot - 1); goto start; /* #\s*include\s*<(.*)> */ pound_include_langle: GETNEXT CASE('\n', start); NOTCASE('>', pound_include_langle); handle_include(1, map_dot, next - map_dot - 1); goto start; /* #\s*d */ pound_d: GETNEXT NOTCASE('e', __start); GETNEXT NOTCASE('f', __start); GETNEXT NOTCASE('i', __start); GETNEXT NOTCASE('n', __start); GETNEXT NOTCASE('e', __start); goto pound_define_undef; /* #\s*u */ pound_u: GETNEXT NOTCASE('n', __start); GETNEXT NOTCASE('d', __start); GETNEXT NOTCASE('e', __start); GETNEXT NOTCASE('f', __start); goto pound_define_undef; /* * #\s*(define|undef)\s*CONFIG_(\w*) * * this does not define the word, because it could be inside another * conditional (#if 0). But I do parse the word so that this instance * does not count as a use. -- mec */ pound_define_undef: GETNEXT CASE(' ', pound_define_undef); CASE('\t', pound_define_undef); NOTCASE('C', __start); GETNEXT NOTCASE('O', __start); GETNEXT NOTCASE('N', __start); GETNEXT NOTCASE('F', __start); GETNEXT NOTCASE('I', __start); GETNEXT NOTCASE('G', __start); GETNEXT NOTCASE('_', __start); map_dot = next; pound_define_undef_CONFIG_word: GETNEXT if (isalnum(current) || current == '_') goto pound_define_undef_CONFIG_word; goto __start; /* \<CONFIG_(\w*) */ cee: if (next >= map+2 && (isalnum(next[-2]) || next[-2] == '_')) goto start; GETNEXT NOTCASE('O', __start); GETNEXT NOTCASE('N', __start); GETNEXT NOTCASE('F', __start); GETNEXT NOTCASE('I', __start); GETNEXT NOTCASE('G', __start); GETNEXT NOTCASE('_', __start); map_dot = next; cee_CONFIG_word: GETNEXT if (isalnum(current) || current == '_') goto cee_CONFIG_word; use_config(map_dot, next - map_dot - 1); goto __start; } }
static void parse_config_file(const char *map, size_t len) { const int *end = (const int *) (map + len); /* start at +1, so that p can never be < map */ const int *m = (const int *) map + 1; const char *p, *q; char tmp_buf[256] = "SPL_"; /* hack for U-Boot */ for (; m < end; m++) { if (*m == INT_CONF) { p = (char *) m ; goto conf; } if (*m == INT_ONFI) { p = (char *) m-1; goto conf; } if (*m == INT_NFIG) { p = (char *) m-2; goto conf; } if (*m == INT_FIG_) { p = (char *) m-3; goto conf; } continue; conf: if (p > map + len - 7) continue; if (memcmp(p, "CONFIG_", 7)) continue; p += 7; for (q = p; q < map + len; q++) { if (!(isalnum(*q) || *q == '_')) goto found; } continue; found: if (!memcmp(q - 7, "_MODULE", 7)) q -= 7; if (q - p < 0) continue; /* * U-Boot also handles * CONFIG_IS_ENABLED(...) * CONFIG_IS_BUILTIN(...) * CONFIG_IS_MODULE(...) * CONFIG_VAL(...) */ if ((q - p == 10 && !memcmp(p, "IS_ENABLED(", 11)) || (q - p == 10 && !memcmp(p, "IS_BUILTIN(", 11)) || (q - p == 9 && !memcmp(p, "IS_MODULE(", 10)) || (q - p == 3 && !memcmp(p, "VAL(", 4))) { p = q + 1; for (q = p; q < map + len; q++) if (*q == ')') goto found2; continue; found2: if (is_spl_build) { memcpy(tmp_buf + 4, p, q - p); q = tmp_buf + 4 + (q - p); p = tmp_buf; } } /* end U-Boot hack */ use_config(p, q - p); } }