LCOV - code coverage report
Current view: top level - ini - ini_print.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 24 115 20.9 %
Date: 2014-04-01 Functions: 2 10 20.0 %

          Line data    Source code
       1             : /*
       2             :     INI LIBRARY
       3             : 
       4             :     Parsing functions of the INI interface
       5             : 
       6             :     Copyright (C) Dmitri Pal <dpal@redhat.com> 2009
       7             : 
       8             :     INI Library is free software: you can redistribute it and/or modify
       9             :     it under the terms of the GNU Lesser General Public License as published by
      10             :     the Free Software Foundation, either version 3 of the License, or
      11             :     (at your option) any later version.
      12             : 
      13             :     INI Library is distributed in the hope that it will be useful,
      14             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :     GNU Lesser General Public License for more details.
      17             : 
      18             :     You should have received a copy of the GNU Lesser General Public License
      19             :     along with INI Library.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "config.h"
      23             : #include <stdio.h>
      24             : /* For error text */
      25             : #include <libintl.h>
      26             : #define _(String) gettext (String)
      27             : /* INI file is used as a collection */
      28             : #include "trace.h"
      29             : #include "collection.h"
      30             : #include "collection_tools.h"
      31             : #include "ini_defines.h"
      32             : #include "ini_config_priv.h"
      33             : #include "ini_configobj.h"
      34             : 
      35             : /* Following declarations are from header file ini_config.h. This file was not
      36             :  * included, because we don't want on include header file
      37             :  * with old interface(ini_config.h) and new interface(ini_configobj.h)
      38             :  * into the one file.
      39             :  */
      40             : void print_config_parsing_errors(FILE *file,
      41             :                                  struct collection_item *error_set);
      42             : 
      43             : 
      44             : void print_file_parsing_errors(FILE *file,
      45             :                                struct collection_item *error_list);
      46             : 
      47             : 
      48             : /*============================================================*/
      49             : /* The following classes moved here from the public header
      50             :  * They are reserved for future use.
      51             :  *
      52             :  * NOTE: before exposing these constants again in the common header
      53             :  * check that the class IDs did not get reused over time by
      54             :  * other classes.
      55             :  */
      56             : /**
      57             :  * @brief Collection of error collections.
      58             :  *
      59             :  * When multiple files are read during one call
      60             :  * each file has its own set of parsing errors
      61             :  * and warnings. This is the collection
      62             :  * of such sets.
      63             :  */
      64             : #define COL_CLASS_INI_PESET       COL_CLASS_INI_BASE + 3
      65             : 
      66             : /** @brief Collection of grammar errors.
      67             :  *
      68             :  * Reserved for future use.
      69             :  */
      70             : #define COL_CLASS_INI_GERROR      COL_CLASS_INI_BASE + 5
      71             : /** @brief Collection of validation errors.
      72             :  *
      73             :  * Reserved for future use.
      74             :  */
      75             : #define COL_CLASS_INI_VERROR      COL_CLASS_INI_BASE + 6
      76             : 
      77             : /**
      78             :  * @}
      79             :  */
      80             : 
      81             : /**
      82             :  * @defgroup gramerr Grammar errors and warnings
      83             :  *
      84             :  * Placeholder for now. Reserved for future use.
      85             :  *
      86             :  * @{
      87             :  */
      88             : #define ERR_MAXGRAMMAR      0
      89             : /**
      90             :  * @}
      91             :  */
      92             : 
      93             : /**
      94             :  * @defgroup valerr Validation errors and warnings
      95             :  *
      96             :  * Placeholder for now. Reserved for future use.
      97             :  *
      98             :  * @{
      99             :  */
     100             : #define ERR_MAXVALID        0
     101             : 
     102             : 
     103             : /**
     104             :  * @}
     105             :  */
     106             : 
     107             : 
     108             : #ifdef HAVE_VALIDATION
     109             : 
     110             : /** @brief Collection of lines from the INI file.
     111             :  *
     112             :  * Reserved for future use
     113             :  */
     114             : #define COL_CLASS_INI_LINES       COL_CLASS_INI_BASE + 7
     115             : 
     116             : #endif /* HAVE_VALIDATION */
     117             : /*============================================================*/
     118             : 
     119             : 
     120             : /* Function to return parsing error */
     121          91 : static const char *parsing_error_str(int parsing_error)
     122             : {
     123          91 :     const char *placeholder= _("Unknown pasing error.");
     124        1365 :     const char *str_error[] = { _("Data is too long."),
     125          91 :                                 _("No closing bracket."),
     126          91 :                                 _("Section name is missing."),
     127          91 :                                 _("Section name is too long."),
     128          91 :                                 _("Equal sign is missing."),
     129          91 :                                 _("Property name is missing."),
     130          91 :                                 _("Property name is too long."),
     131          91 :                                 _("Failed to read line."),
     132          91 :                                 _("Invalid space character at the "
     133             :                                   "beginning of the line."),
     134          91 :                                 _("Duplicate key is not allowed."),
     135          91 :                                 _("Duplicate key is detected while "
     136             :                                   "merging sections."),
     137          91 :                                 _("Duplicate section is not allowed."),
     138          91 :                                 _("Invalid character at the "
     139             :                                   "beginning of the line."),
     140          91 :                                 _("Invalid tab character at the "
     141             :                                   "beginning of the line."),
     142          91 :                                 _("Incomplete comment at the "
     143             :                                   "end of the file.")
     144             :     };
     145             : 
     146             :     /* Check the range */
     147          91 :     if ((parsing_error < 1) || (parsing_error > ERR_MAXPARSE))
     148             :             return placeholder;
     149             :     else
     150          91 :             return str_error[parsing_error-1];
     151             : }
     152             : 
     153             : /* Function to return grammar error.
     154             :  * This function is currently not used.
     155             :  * It is planned to be used by the INI
     156             :  * file grammar parser.
     157             :  *
     158             :  * The following doxygen description is moved here.
     159             :  * When the function gets exposed move it into
     160             :  * the header file.
     161             :  */
     162             : /** @brief Function to return a grammar error in template.
     163             :  *
     164             :  * EXPERIMENTAL. Reserved for future use.
     165             :  *
     166             :  * This error is returned when the template
     167             :  * is translated into the grammar object.
     168             :  *
     169             :  * @param[in] grammar_error    Error code for the grammar error.
     170             :  *
     171             :  * @return Error string.
     172             :  */
     173             : 
     174           0 : static const char *grammar_error_str(int grammar_error)
     175             : {
     176           0 :     const char *placeholder= _("Unknown grammar error.");
     177             :     /* THIS IS A TEMPORARY PLACEHOLDER !!!! */
     178           0 :     const char *str_error[] = { _(""),
     179           0 :                                 _(""),
     180           0 :                                 _(""),
     181           0 :                                 _(""),
     182           0 :                                 _(""),
     183           0 :                                 _(""),
     184           0 :                                 _("")
     185             :     };
     186             : 
     187             :     /* Check the range */
     188             :     if ((grammar_error < 1) || (grammar_error > ERR_MAXGRAMMAR))
     189             :             return placeholder;
     190             :     else
     191             :             return str_error[grammar_error-1];
     192             : }
     193             : 
     194             : /* Function to return validation error.
     195             :  * This function is currently not used.
     196             :  * It is planned to be used by the INI
     197             :  * file grammar validator.
     198             :  *
     199             :  * The following doxygen description is moved here.
     200             :  * When the function gets exposed move it into
     201             :  * the header file.
     202             :  */
     203             : /** @brief Function to return a validation error.
     204             :  *
     205             :  * EXPERIMENTAL. Reserved for future use.
     206             :  *
     207             :  * This is the error that it is returned when
     208             :  * the INI file is validated against the
     209             :  * grammar object.
     210             :  *
     211             :  * @param[in] validation_error    Error code for the validation error.
     212             :  *
     213             :  * @return Error string.
     214             :  */
     215           0 : static const char *validation_error_str(int validation_error)
     216             : {
     217           0 :     const char *placeholder= _("Unknown validation error.");
     218             :     /* THIS IS A TEMPORARY PLACEHOLDER !!!! */
     219           0 :     const char *str_error[] = { _(""),
     220           0 :                                 _(""),
     221           0 :                                 _(""),
     222           0 :                                 _(""),
     223           0 :                                 _(""),
     224           0 :                                 _(""),
     225           0 :                                 _("")
     226             :     };
     227             : 
     228             :     /* Check the range */
     229             :     if ((validation_error < 1) || (validation_error > ERR_MAXVALID))
     230             :             return placeholder;
     231             :     else
     232             :             return str_error[validation_error-1];
     233             : }
     234             : 
     235             : /* Wrapper to print errors */
     236          91 : const char *ini_get_error_str(int error, int family)
     237             : {
     238             :     const char *val;
     239             :     TRACE_FLOW_ENTRY();
     240             : 
     241          91 :     switch(family) {
     242             :     case INI_FAMILY_PARSING:
     243          91 :         val = parsing_error_str(error);
     244          91 :         break;
     245             :     case INI_FAMILY_VALIDATION:
     246           0 :         val = validation_error_str(error);
     247           0 :         break;
     248             :     case INI_FAMILY_GRAMMAR:
     249           0 :         val = grammar_error_str(error);
     250           0 :         break;
     251             :     default:
     252           0 :         val = _("Unknown error category.");
     253           0 :         break;
     254             :     }
     255             : 
     256             :     TRACE_FLOW_EXIT();
     257          91 :     return val;
     258             : }
     259             : 
     260             : /* Internal function that prints errors */
     261           0 : static void print_error_list(FILE *file,
     262             :                              struct collection_item *error_list,
     263             :                              int cclass,
     264             :                              char *wrong_col_error,
     265             :                              char *failed_to_process,
     266             :                              char *error_header,
     267             :                              char *line_format,
     268             :                              int family)
     269             : {
     270             :     struct collection_iterator *iterator;
     271             :     int error;
     272           0 :     struct collection_item *item = NULL;
     273             :     struct ini_parse_error *pe;
     274             :     unsigned int count;
     275             : 
     276             :     TRACE_FLOW_STRING("print_error_list", "Entry");
     277             : 
     278             :     /* If we have something to print print it */
     279           0 :     if (error_list == NULL) {
     280             :         TRACE_ERROR_STRING("No error list","");
     281           0 :         return;
     282             :     }
     283             : 
     284             :     /* Make sure we go the right collection */
     285           0 :     if (!col_is_of_class(error_list, cclass)) {
     286             :         TRACE_ERROR_STRING("Wrong collection class:", wrong_col_error);
     287           0 :         fprintf(file,"%s\n", wrong_col_error);
     288           0 :         return;
     289             :     }
     290             : 
     291             :     /* Bind iterator */
     292           0 :     error =  col_bind_iterator(&iterator, error_list, COL_TRAVERSE_DEFAULT);
     293           0 :     if (error) {
     294             :         TRACE_ERROR_STRING("Error (bind):", failed_to_process);
     295           0 :         fprintf(file, "%s\n", failed_to_process);
     296           0 :         return;
     297             :     }
     298             : 
     299             :     while(1) {
     300             :         /* Loop through a collection */
     301           0 :         error = col_iterate_collection(iterator, &item);
     302           0 :         if (error) {
     303             :             TRACE_ERROR_STRING("Error (iterate):", failed_to_process);
     304           0 :             fprintf(file, "%s\n", failed_to_process);
     305           0 :             col_unbind_iterator(iterator);
     306           0 :             return;
     307             :         }
     308             : 
     309             :         /* Are we done ? */
     310           0 :         if (item == NULL) break;
     311             : 
     312             :         /* Process collection header */
     313           0 :         if (col_get_item_type(item) == COL_TYPE_COLLECTION) {
     314           0 :             col_get_collection_count(item, &count);
     315           0 :             if (count <= 2) break;
     316           0 :         } else if (col_get_item_type(item) == COL_TYPE_STRING) {
     317           0 :             fprintf(file, error_header, (char *)col_get_item_data(item));
     318             :         }
     319             :         else {
     320             :             /* Put error into provided format */
     321           0 :             pe = (struct ini_parse_error *)(col_get_item_data(item));
     322           0 :             fprintf(file, line_format,
     323             :                     col_get_item_property(item, NULL), /* Error or warning */
     324             :                     pe->error,                         /* Error */
     325             :                     pe->line,                          /* Line */
     326             :                     ini_get_error_str(pe->error,
     327             :                                       family));        /* Error str */
     328             :         }
     329             : 
     330             :     }
     331             : 
     332             :     /* Do not forget to unbind iterator - otherwise there will be a leak */
     333           0 :     col_unbind_iterator(iterator);
     334             : 
     335             :     TRACE_FLOW_STRING("print_error_list", "Exit");
     336             : }
     337             : 
     338             : /* Print errors and warnings that were detected while parsing one file */
     339           0 : void print_file_parsing_errors(FILE *file,
     340             :                                struct collection_item *error_list)
     341             : {
     342           0 :     print_error_list(file,
     343             :                      error_list,
     344             :                      COL_CLASS_INI_PERROR,
     345             :                      WRONG_COLLECTION,
     346             :                      FAILED_TO_PROCCESS,
     347             :                      ERROR_HEADER,
     348             :                      LINE_FORMAT,
     349             :                      INI_FAMILY_PARSING);
     350           0 : }
     351             : 
     352             : 
     353             : void print_grammar_errors(FILE *file,
     354             :                           struct collection_item *error_list);
     355             : /* Print errors and warnings that were detected while processing grammar.
     356             :  *
     357             :  * The following doxygen description is moved here.
     358             :  * When the function gets exposed move it into
     359             :  * the header file and remove prototype from this file.
     360             :  */
     361             : /**
     362             :  * @brief Print errors and warnings that were detected while
     363             :  * checking grammar of the template.
     364             :  *
     365             :  * EXPERIMENTAL. Reserved for future use.
     366             :  *
     367             :  * @param[in] file           File descriptor.
     368             :  * @param[in] error_list     List of the parsing errors.
     369             :  *
     370             :  */
     371           0 : void print_grammar_errors(FILE *file,
     372             :                           struct collection_item *error_list)
     373             : {
     374           0 :     print_error_list(file,
     375             :                      error_list,
     376             :                      COL_CLASS_INI_GERROR,
     377             :                      WRONG_GRAMMAR,
     378             :                      FAILED_TO_PROC_G,
     379             :                      ERROR_HEADER_G,
     380             :                      LINE_FORMAT,
     381             :                      INI_FAMILY_GRAMMAR);
     382           0 : }
     383             : 
     384             : void print_validation_errors(FILE *file,
     385             :                              struct collection_item *error_list);
     386             : /* Print errors and warnings that were detected while validating INI file.
     387             :  *
     388             :  * The following doxygen description is moved here.
     389             :  * When the function gets exposed move it into
     390             :  * the header file and remove prototype from this file.
     391             :  */
     392             : /**
     393             :  * @brief Print errors and warnings that were detected while
     394             :  * checking INI file against the grammar object.
     395             :  *
     396             :  * EXPERIMENTAL. Reserved for future use.
     397             :  *
     398             :  * @param[in] file           File descriptor.
     399             :  * @param[in] error_list     List of the parsing errors.
     400             :  *
     401             :  */
     402           0 : void print_validation_errors(FILE *file,
     403             :                              struct collection_item *error_list)
     404             : {
     405           0 :     print_error_list(file,
     406             :                      error_list,
     407             :                      COL_CLASS_INI_VERROR,
     408             :                      WRONG_VALIDATION,
     409             :                      FAILED_TO_PROC_V,
     410             :                      ERROR_HEADER_V,
     411             :                      LINE_FORMAT,
     412             :                      INI_FAMILY_VALIDATION);
     413           0 : }
     414             : 
     415             : /* Print errors and warnings that were detected while parsing
     416             :  * the whole configuration */
     417           0 : void print_config_parsing_errors(FILE *file,
     418             :                                  struct collection_item *error_list)
     419             : {
     420             :     struct collection_iterator *iterator;
     421             :     int error;
     422           0 :     struct collection_item *item = NULL;
     423           0 :     struct collection_item *file_errors = NULL;
     424             : 
     425             :     TRACE_FLOW_STRING("print_config_parsing_errors", "Entry");
     426             : 
     427             :     /* If we have something to print print it */
     428           0 :     if (error_list == NULL) {
     429             :         TRACE_ERROR_STRING("No error list", "");
     430           0 :         return;
     431             :     }
     432             : 
     433             :     /* Make sure we go the right collection */
     434           0 :     if (!col_is_of_class(error_list, COL_CLASS_INI_PESET)) {
     435             :         TRACE_ERROR_STRING("Wrong collection class:", WRONG_COLLECTION);
     436           0 :         fprintf(file, "%s\n", WRONG_COLLECTION);
     437           0 :         return;
     438             :     }
     439             : 
     440             :     /* Bind iterator */
     441           0 :     error =  col_bind_iterator(&iterator, error_list, COL_TRAVERSE_DEFAULT);
     442           0 :     if (error) {
     443             :         TRACE_ERROR_STRING("Error (bind):", FAILED_TO_PROCCESS);
     444           0 :         fprintf(file,"%s\n", FAILED_TO_PROCCESS);
     445           0 :         return;
     446             :     }
     447             : 
     448             :     while(1) {
     449             :         /* Loop through a collection */
     450           0 :         error = col_iterate_collection(iterator, &item);
     451           0 :         if (error) {
     452             :             TRACE_ERROR_STRING("Error (iterate):", FAILED_TO_PROCCESS);
     453           0 :             fprintf(file, "%s\n", FAILED_TO_PROCCESS);
     454           0 :             col_unbind_iterator(iterator);
     455           0 :             return;
     456             :         }
     457             : 
     458             :         /* Are we done ? */
     459           0 :         if (item == NULL) break;
     460             : 
     461             :         /* Print per file sets of errors */
     462           0 :         if (col_get_item_type(item) == COL_TYPE_COLLECTIONREF) {
     463             :             /* Extract a sub collection */
     464           0 :             error = col_get_reference_from_item(item, &file_errors);
     465           0 :             if (error) {
     466             :                 TRACE_ERROR_STRING("Error (extract):", FAILED_TO_PROCCESS);
     467           0 :                 fprintf(file, "%s\n", FAILED_TO_PROCCESS);
     468           0 :                 col_unbind_iterator(iterator);
     469           0 :                 return;
     470             :             }
     471           0 :             print_file_parsing_errors(file, file_errors);
     472           0 :             col_destroy_collection(file_errors);
     473             :         }
     474             :     }
     475             : 
     476             :     /* Do not forget to unbind iterator - otherwise there will be a leak */
     477           0 :     col_unbind_iterator(iterator);
     478             : 
     479             :     TRACE_FLOW_STRING("print_config_parsing_errors", "Exit");
     480             : }
     481             : 
     482             : /* Function to print errors from the list */
     483           0 : void ini_config_print_errors(FILE *file, char **error_list)
     484             : {
     485           0 :     unsigned count = 0;
     486             : 
     487             :     TRACE_FLOW_ENTRY();
     488             : 
     489           0 :     if (!error_list) {
     490             :         TRACE_FLOW_STRING("List is empty.", "");
     491             :         return;
     492             :     }
     493             : 
     494           0 :     while (error_list[count]) {
     495           0 :         fprintf(file, "%s\n", error_list[count]);
     496           0 :         count++;
     497             :     }
     498             : 
     499             :     TRACE_FLOW_EXIT();
     500             :     return;
     501             : }

Generated by: LCOV version 1.10