c = '\n'; if ((f = config_file) != NULL) {
c = fgetc(f); if (c == '\r') { /* DOS like systems */
c = fgetc(f); if (c != '\n') {
ungetc(c, f);
c = '\r';
}
} if (c == '\n')
config_linenr++; if (c == EOF) {
config_file_eof = 1;
c = '\n';
}
} return c;
}
staticchar *parse_value(void)
{ staticchar value[1024]; int quote = 0, comment = 0, space = 0;
size_t len = 0;
for (;;) { int c = get_next_char();
if (len >= sizeof(value) - 1) return NULL; if (c == '\n') { if (quote) return NULL;
value[len] = 0; return value;
} if (comment) continue; if (isspace(c) && !quote) {
space = 1; continue;
} if (!quote) { if (c == ';' || c == '#') {
comment = 1; continue;
}
} if (space) { if (len)
value[len++] = ' ';
space = 0;
} if (c == '\\') {
c = get_next_char(); switch (c) { case'\n': continue; case't':
c = '\t'; break; case'b':
c = '\b'; break; case'n':
c = '\n'; break; /* Some characters escape as themselves */ case'\\': case'"': break; /* Reject unknown escape sequences */ default: return NULL;
}
value[len++] = c; continue;
} if (c == '"') {
quote = 1-quote; continue;
}
value[len++] = c;
}
}
staticinlineint iskeychar(int c)
{ return isalnum(c) || c == '-' || c == '_';
}
/* Get the full name */ for (;;) {
c = get_next_char(); if (config_file_eof) break; if (!iskeychar(c)) break;
name[len++] = c; if (len >= MAXNAME) return -1;
}
name[len] = 0; while (c == ' ' || c == '\t')
c = get_next_char();
value = NULL; if (c != '\n') { if (c != '=') return -1;
value = parse_value(); if (!value) return -1;
} return fn(name, value, data);
}
staticint get_extended_base_var(char *name, int baselen, int c)
{ do { if (c == '\n') return -1;
c = get_next_char();
} while (isspace(c));
/* We require the format to be '[base "extension"]' */ if (c != '"') return -1;
name[baselen++] = '.';
for (;;) { int ch = get_next_char();
if (ch == '\n') return -1; if (ch == '"') break; if (ch == '\\') {
ch = get_next_char(); if (ch == '\n') return -1;
}
name[baselen++] = ch; if (baselen > MAXNAME / 2) return -1;
}
/* Final ']' */ if (get_next_char() != ']') return -1; return baselen;
}
staticint get_base_var(char *name)
{ int baselen = 0;
for (;;) { int c = get_next_char(); if (config_file_eof) return -1; if (c == ']') return baselen; if (isspace(c)) return get_extended_base_var(name, baselen, c); if (!iskeychar(c) && c != '.') return -1; if (baselen > MAXNAME / 2) return -1;
name[baselen++] = tolower(c);
}
}
staticint perf_parse_file(config_fn_t fn, void *data)
{ int comment = 0; int baselen = 0; staticchar var[MAXNAME];
/* U+FEFF Byte Order Mark in UTF8 */ staticconstunsignedchar *utf8_bom = (unsignedchar *) "\xef\xbb\xbf"; constunsignedchar *bomptr = utf8_bom;
for (;;) { int line, c = get_next_char();
if (bomptr && *bomptr) { /* We are at the file beginning; skip UTF8-encoded BOM *ifpresent.Saneeditorswon'tputthisinontheir
* own, but e.g. Windows Notepad will do it happily. */ if ((unsignedchar) c == *bomptr) {
bomptr++; continue;
} else { /* Do not tolerate partial BOM. */ if (bomptr != utf8_bom) break; /* No BOM at file beginning. Cool. */
bomptr = NULL;
}
} if (c == '\n') { if (config_file_eof) return0;
comment = 0; continue;
} if (comment || isspace(c)) continue; if (c == '#' || c == ';') {
comment = 1; continue;
} if (c == '[') {
baselen = get_base_var(var); if (baselen <= 0) break;
var[baselen++] = '.';
var[baselen] = 0; continue;
} if (!isalpha(c)) break;
var[baselen] = tolower(c);
/* *Theget_valuefunctionmightormightnotreachthe'\n', *sosavingthecurrentlinenumberforerrorreporting.
*/
line = config_linenr; if (get_value(fn, data, var, baselen+1) < 0) {
config_linenr = line; break;
}
}
pr_err("bad config file line %d in %s\n", config_linenr, config_file_name); return -1;
}
if (!parse_unit_factor(end, &factor)) return0;
*ret = val * factor; return1;
} return0;
}
staticint perf_parse_long(constchar *value, long *ret)
{ if (value && *value) { char *end; long val = strtol(value, &end, 0); unsignedlong factor = 1; if (!parse_unit_factor(end, &factor)) return0;
*ret = val * factor; return1;
} return0;
}
staticvoid bad_config(constchar *name)
{ if (config_file_name)
pr_warning("bad config value for '%s' in %s, ignoring...\n", name, config_file_name); else
pr_warning("bad config value for '%s', ignoring...\n", name);
}
int perf_config_u64(u64 *dest, constchar *name, constchar *value)
{ longlong ret = 0;
if (!perf_parse_llong(value, &ret)) {
bad_config(name); return -1;
}
*dest = ret; return0;
}
int perf_config_int(int *dest, constchar *name, constchar *value)
{ long ret = 0; if (!perf_parse_long(value, &ret)) {
bad_config(name); return -1;
}
*dest = ret; return0;
}
int perf_config_u8(u8 *dest, constchar *name, constchar *value)
{ long ret = 0;
staticint perf_buildid_config(constchar *var, constchar *value)
{ /* same dir for all commands */ if (!strcmp(var, "buildid.dir")) { constchar *dir = perf_config_dirname(var, value);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.