static void conf_parse_file(const char *filename, void (*conf_keyvalue)(void *data, const char *key, const char *value), void *data) { FILE *f = fopen(filename, "r"); if (!f) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO, "Unable to open file: %s", filename); return; } char line[BUFSIZ]; int lineno = 0; while (fgets(line, BUFSIZ, f) != NULL) { lineno++; switch (line[0]) { case '#': case '\n': break; default: { char *key; char *value; if (parse_line(line, &key, &value) == 0) { conf_keyvalue(data, key, value); free(key); free(value); } else { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Parse error on line #%d: %s", lineno, line); } } } } fclose(f); return; }
static bool conf_parse_file(const char *filename, void (*conf_keyvalue)(void *data, const char *key, const char *value), void *data) { FILE *f = fopen(filename, "r"); if (!f) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO, "Unable to open file: %s", filename); return false; } char line[BUFSIZ]; const char *str_regex = "^[[:space:]]*([[:alnum:]_.]+)[[:space:]]*=[[:space:]]*(\"(.+)\"|([^[:space:]]+))[[:space:]]*$"; regex_t preg; if (regcomp(&preg, str_regex, REG_EXTENDED | REG_NOTEOL) != 0) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Regular expression used for configuration file parsing is not valid."); fclose(f); return false; } size_t nmatch = preg.re_nsub + 1; regmatch_t *pmatch = malloc(sizeof(*pmatch) * nmatch); if (!pmatch) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Not enough memory: malloc failed."); regfree(&preg); fclose(f); return false; } int lineno = 0; while (fgets(line, BUFSIZ, f) != NULL) { lineno++; switch (line[0]) { case '#': case '\n': break; default: { int match; if ((match = regexec(&preg, line, nmatch, pmatch, 0)) == 0) { const size_t key_size = pmatch[1].rm_eo - pmatch[1].rm_so; const off_t value_pmatch = pmatch[3].rm_eo != -1 ? 3 : 4; const size_t value_size = pmatch[value_pmatch].rm_eo - pmatch[value_pmatch].rm_so; char key[key_size + 1]; char value[value_size + 1]; strncpy(key, line + (pmatch[1].rm_so), key_size); key[key_size] = '\0'; strncpy(value, line + (pmatch[value_pmatch].rm_so), value_size); value[value_size] = '\0'; conf_keyvalue(data, key, value); } else { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Parse error on line #%d: %s", lineno, line); } } break; } } free(pmatch); regfree(&preg); fclose(f); return false; }