summaryrefslogtreecommitdiffstats
path: root/common/ini/ini_config.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/ini/ini_config.c')
-rw-r--r--common/ini/ini_config.c251
1 files changed, 221 insertions, 30 deletions
diff --git a/common/ini/ini_config.c b/common/ini/ini_config.c
index 7effc0426..0652bd1cf 100644
--- a/common/ini/ini_config.c
+++ b/common/ini/ini_config.c
@@ -46,12 +46,23 @@
#define FILE_ERROR_SET "ini_file_error_set"
/* Text error strings used when errors are printed out */
-#define WARNING_TXT _("Warning")
-#define ERROR_TXT _("Error")
-#define WRONG_COLLECTION _("Passed in list is not a list of parse errors.\n")
-#define FAILED_TO_PROCCESS _("Internal Error. Failed to process error list.\n")
-#define ERROR_HEADER _("Parsing errors and warnings in file: %s\n")
-#define LINE_FORMAT _("%s (%d) on line %d: %s\n")
+#define WARNING_TXT _("Warning")
+#define ERROR_TXT _("Error")
+/* For parse errors */
+#define WRONG_COLLECTION _("Passed in list is not a list of parse errors.\n")
+#define FAILED_TO_PROCCESS _("Internal Error. Failed to process error list.\n")
+#define ERROR_HEADER _("Parsing errors and warnings in file: %s\n")
+/* For grammar errors */
+#define WRONG_GRAMMAR _("Passed in list is not a list of grammar errors.\n")
+#define FAILED_TO_PROC_G _("Internal Error. Failed to process list of grammar errors.\n")
+#define ERROR_HEADER_G _("Logical errors and warnings in file: %s\n")
+/* For validation errors */
+#define WRONG_VALIDATION _("Passed in list is not a list of validation errors.\n")
+#define FAILED_TO_PROC_V _("Internal Error. Failed to process list of validation errors.\n")
+#define ERROR_HEADER_V _("Validation errors and warnings in file: %s\n")
+
+#define LINE_FORMAT _("%s (%d) on line %d: %s\n")
+
/* Codes that parsing function can return */
#define RET_PAIR 0
@@ -62,11 +73,13 @@
#define RET_EOF 5
#define RET_ERROR 6
+/* Different error string functions can be passed as callbacks */
+typedef const char * (*error_fn)(int error);
/* Function to return parsing error */
inline const char *parsing_error_str(int parsing_error)
{
- const char *placeholder= _("Unknown error.");
+ const char *placeholder= _("Unknown pasing error.");
const char *str_error[] = { _("Data is too long."),
_("No closing bracket."),
_("Section name is missing."),
@@ -83,6 +96,47 @@ inline const char *parsing_error_str(int parsing_error)
return str_error[parsing_error-1];
}
+/* Function to return grammar error */
+inline const char *grammar_error_str(int grammar_error)
+{
+ const char *placeholder= _("Unknown grammar error.");
+ const char *str_error[] = { _(""),
+ _(""),
+ _(""),
+ _(""),
+ _(""),
+ _(""),
+ _("")
+ };
+
+ /* Check the range */
+ if ((grammar_error < 1) || (grammar_error > ERR_MAXGRAMMAR))
+ return placeholder;
+ else
+ return str_error[grammar_error-1];
+}
+
+/* Function to return validation error */
+inline const char *validation_error_str(int validation_error)
+{
+ const char *placeholder= _("Unknown validation error.");
+ const char *str_error[] = { _(""),
+ _(""),
+ _(""),
+ _(""),
+ _(""),
+ _(""),
+ _("")
+ };
+
+ /* Check the range */
+ if ((validation_error < 1) || (validation_error > ERR_MAXVALID))
+ return placeholder;
+ else
+ return str_error[validation_error-1];
+}
+
+
/* Internal function to read line from INI file */
int read_line(FILE *file,
char *buf,
@@ -100,7 +154,7 @@ static int add_or_update(struct collection_item *current_section,
int type)
{
int found = COL_NOMATCH;
- int error;
+ int error;
TRACE_FLOW_STRING("add_or_update", "Entry");
@@ -129,7 +183,8 @@ static int add_or_update(struct collection_item *current_section,
static int ini_to_collection(const char *filename,
struct collection_item *ini_config,
int error_level,
- struct collection_item **error_list)
+ struct collection_item **error_list,
+ struct collection_item **lines)
{
FILE *file;
int error;
@@ -178,6 +233,21 @@ static int ini_to_collection(const char *filename,
switch (status) {
case RET_PAIR:
+ /* Add line to the collection of lines */
+ if (lines) {
+ error = add_int_property(*lines, NULL, key, line);
+ if (error) {
+ TRACE_ERROR_NUMBER("Failed to add line to line collection", error);
+ fclose(file);
+ destroy_collection(current_section);
+ if (created) {
+ destroy_collection(*error_list);
+ *error_list = NULL;
+ }
+ return error;
+ }
+ }
+
/* Do we have a section at the top of the file ? */
if (section_count == 0) {
/* Check if collection already exists */
@@ -221,6 +291,21 @@ static int ini_to_collection(const char *filename,
break;
case RET_SECTION:
+ /* Add line to the collection of lines */
+ if (lines) {
+ error = add_int_property(*lines, NULL, key, line);
+ if (error) {
+ TRACE_ERROR_NUMBER("Failed to add line to line collection", error);
+ fclose(file);
+ destroy_collection(current_section);
+ if (created) {
+ destroy_collection(*error_list);
+ *error_list = NULL;
+ }
+ return error;
+ }
+ }
+
/* Read a new section */
destroy_collection(current_section);
current_section = NULL;
@@ -324,14 +409,38 @@ static int ini_to_collection(const char *filename,
/*********************************************************************/
/* Read configuration information from a file */
-int config_from_file(const char *application,
+inline int config_from_file(const char *application,
const char *config_file,
struct collection_item **ini_config,
int error_level,
struct collection_item **error_list)
{
int error;
+
+ TRACE_FLOW_STRING("config_from_file", "Entry");
+ error = config_from_file_with_lines(application,
+ config_file,
+ ini_config,
+ error_level,
+ error_list,
+ NULL);
+ TRACE_FLOW_NUMBER("config_from_file. Returns", error);
+ return error;
+}
+
+/* Function to read the ini file and have a collection
+ * of which item appers on which line
+ */
+int config_from_file_with_lines(const char *application,
+ const char *config_file,
+ struct collection_item **ini_config,
+ int error_level,
+ struct collection_item **error_list,
+ struct collection_item **lines)
+{
+ int error;
int created = 0;
+ int created_lines = 0;
TRACE_FLOW_STRING("config_from_file", "Entry");
@@ -358,14 +467,47 @@ int config_from_file(const char *application,
return EINVAL;
}
+
+ /* Create collection if needed */
+ if (lines) {
+
+ /* Make sure that the lines collection is empty */
+ if (*lines) {
+ TRACE_ERROR_NUMBER("Collection of lines is not empty", EINVAL);
+ if (created) {
+ destroy_collection(*ini_config);
+ *ini_config = NULL;
+ }
+ return EINVAL;
+ }
+
+ error = create_collection(lines,
+ application,
+ COL_CLASS_INI_LINES);
+ if (error != EOK) {
+ TRACE_ERROR_NUMBER("Failed to create collection", error);
+ if (created) {
+ destroy_collection(*ini_config);
+ *ini_config = NULL;
+ }
+ return error;
+ }
+ created_lines = 1;
+ }
+
/* Do the actual work */
error = ini_to_collection(config_file, *ini_config,
- error_level, error_list);
+ error_level, error_list, lines);
/* In case of error when we created collection - delete it */
if (error && created) {
destroy_collection(*ini_config);
*ini_config = NULL;
}
+ /* Also create collection of lines if we created it */
+ if (error && created_lines) {
+ destroy_collection(*lines);
+ *lines = NULL;
+ }
TRACE_FLOW_NUMBER("config_from_file. Returns", error);
return error;
@@ -439,7 +581,7 @@ int config_for_app(const char *application,
if (config_file != NULL) {
TRACE_INFO_STRING("Reading master file:", config_file);
error = ini_to_collection(config_file, *ini_config,
- error_level, pass_common);
+ error_level, pass_common, NULL);
/* ENOENT and EOK are Ok */
if (error && (error != ENOENT)) {
TRACE_ERROR_NUMBER("Failed to read master file", error);
@@ -490,8 +632,8 @@ int config_for_app(const char *application,
TRACE_INFO_STRING("Opening file:", file_name);
/* Read master file */
- error = ini_to_collection(file_name, *ini_config,
- error_level, pass_specific);
+ error = ini_to_collection(file_name, *ini_config,
+ error_level, pass_specific, NULL);
free(file_name);
/* ENOENT and EOK are Ok */
if (error && (error != ENOENT)) {
@@ -688,9 +830,16 @@ int read_line(FILE *file,
}
-/* Print errors and warnings that were detected while parsing one file */
-void print_file_parsing_errors(FILE *file,
- struct collection_item *error_list)
+
+/* Internal function that prints errors */
+static void print_error_list(FILE *file,
+ struct collection_item *error_list,
+ int cclass,
+ char *wrong_col_error,
+ char *failed_to_process,
+ char *error_header,
+ char *line_format,
+ error_fn error_function)
{
struct collection_iterator *iterator;
int error;
@@ -698,7 +847,7 @@ void print_file_parsing_errors(FILE *file,
struct parse_error *pe;
unsigned int count;
- TRACE_FLOW_STRING("print_file_parsing_errors", "Entry");
+ TRACE_FLOW_STRING("print_error_list", "Entry");
/* If we have something to print print it */
if (error_list == NULL) {
@@ -707,17 +856,17 @@ void print_file_parsing_errors(FILE *file,
}
/* Make sure we go the right collection */
- if (!is_of_class(error_list, COL_CLASS_INI_PERROR)) {
- TRACE_ERROR_STRING("Wrong collection class:", WRONG_COLLECTION);
- fprintf(file,"%s\n", WRONG_COLLECTION);
+ if (!is_of_class(error_list, cclass)) {
+ TRACE_ERROR_STRING("Wrong collection class:", wrong_col_error);
+ fprintf(file,"%s\n", wrong_col_error);
return;
}
/* Bind iterator */
error = bind_iterator(&iterator, error_list, COL_TRAVERSE_DEFAULT);
if (error) {
- TRACE_ERROR_STRING("Error (bind):", FAILED_TO_PROCCESS);
- fprintf(file, "%s\n", FAILED_TO_PROCCESS);
+ TRACE_ERROR_STRING("Error (bind):", failed_to_process);
+ fprintf(file, "%s\n", failed_to_process);
return;
}
@@ -725,8 +874,8 @@ void print_file_parsing_errors(FILE *file,
/* Loop through a collection */
error = iterate_collection(iterator, &item);
if (error) {
- TRACE_ERROR_STRING("Error (iterate):", FAILED_TO_PROCCESS);
- fprintf(file, "%s\n", FAILED_TO_PROCCESS);
+ TRACE_ERROR_STRING("Error (iterate):", failed_to_process);
+ fprintf(file, "%s\n", failed_to_process);
unbind_iterator(iterator);
return;
}
@@ -738,17 +887,17 @@ void print_file_parsing_errors(FILE *file,
if (get_item_type(item) == COL_TYPE_COLLECTION) {
get_collection_count(item, &count);
if (count > 1)
- fprintf(file, ERROR_HEADER, get_item_property(item, NULL));
+ fprintf(file, error_header, get_item_property(item, NULL));
else break;
}
else {
/* Put error into provided format */
pe = (struct parse_error *)(get_item_data(item));
- fprintf(file, LINE_FORMAT,
+ fprintf(file, line_format,
get_item_property(item, NULL), /* Error or warning */
pe->error, /* Error */
- pe->line, /* Line */
- parsing_error_str(pe->error)); /* Error str */
+ pe->line, /* Line */
+ error_function(pe->error)); /* Error str */
}
}
@@ -756,9 +905,51 @@ void print_file_parsing_errors(FILE *file,
/* Do not forget to unbind iterator - otherwise there will be a leak */
unbind_iterator(iterator);
- TRACE_FLOW_STRING("print_file_parsing_errors", "Exit");
+ TRACE_FLOW_STRING("print_error_list", "Exit");
}
+/* Print errors and warnings that were detected while parsing one file */
+void inline print_file_parsing_errors(FILE *file,
+ struct collection_item *error_list)
+{
+ print_error_list(file,
+ error_list,
+ COL_CLASS_INI_PERROR,
+ WRONG_COLLECTION,
+ FAILED_TO_PROCCESS,
+ ERROR_HEADER,
+ LINE_FORMAT,
+ parsing_error_str);
+}
+
+
+/* Print errors and warnings that were detected while processing grammar */
+void inline print_grammar_errors(FILE *file,
+ struct collection_item *error_list)
+{
+ print_error_list(file,
+ error_list,
+ COL_CLASS_INI_GERROR,
+ WRONG_GRAMMAR,
+ FAILED_TO_PROC_G,
+ ERROR_HEADER_G,
+ LINE_FORMAT,
+ grammar_error_str);
+}
+
+/* Print errors and warnings that were detected while validating INI file. */
+void inline print_validation_errors(FILE *file,
+ struct collection_item *error_list)
+{
+ print_error_list(file,
+ error_list,
+ COL_CLASS_INI_VERROR,
+ WRONG_VALIDATION,
+ FAILED_TO_PROC_V,
+ ERROR_HEADER_V,
+ LINE_FORMAT,
+ validation_error_str);
+}
/* Print errors and warnings that were detected while parsing
* the whole configuration */