Changeset a58727c in mainline for uspace/lib/conf/src/ini.c


Ignore:
Timestamp:
2020-07-05T21:00:33Z (4 years ago)
Author:
Matthieu Riolo <matthieu.riolo@…>
Children:
a81a950d
Parents:
0f5546a
git-author:
Michal Koutný <xm.koutny+hos@…> (2015-04-24 00:32:34)
git-committer:
Matthieu Riolo <matthieu.riolo@…> (2020-07-05 21:00:33)
Message:

libconf: Fix default INI section + tests
Conflicts:

.bzrignore

Conflicts:

uspace/lib/conf/Makefile

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/conf/src/ini.c

    r0f5546a ra58727c  
    5353} ini_item_t;
    5454
     55/** Line reader for generic parsing */
     56typedef char *(*line_reader_t)(char *, int, void *);
    5557
    5658/* Necessary forward declarations */
    5759static void ini_section_destroy(ini_section_t **);
    5860static void ini_item_destroy(ini_item_t **);
     61static ini_section_t *ini_section_create(void);
     62static ini_item_t *ini_item_create(void);
    5963
    6064/* Hash table functions */
     
    7377static size_t ini_section_ht_key_hash(void *key)
    7478{
     79        /* Nameless default section */
     80        if (key == NULL) {
     81                return 0;
     82        }
    7583        return hash_string((const char *)key);
    7684}
     
    8593static bool ini_section_ht_key_equal(void *key, const ht_link_t *item)
    8694{
    87         return str_cmp((const char *)key,
    88             hash_table_get_inst(item, ini_section_t, ht_link)->name) == 0;
     95        const char *name = key;
     96        ini_section_t *section =
     97            hash_table_get_inst(item, ini_section_t, ht_link);
     98
     99        if (key == NULL || section->name == NULL) {
     100                return section->name == key;
     101        }
     102
     103        return str_cmp(name, section->name) == 0;
    89104}
    90105
     
    145160};
    146161
    147 /* Actual INI functions */
    148 
    149 void ini_configuration_init(ini_configuration_t *conf)
    150 {
    151         hash_table_create(&conf->sections, 0, 0, &configuration_ht_ops);
    152 }
    153 
    154 /** INI configuration destructor
    155  *
    156  * Release all resources of INI structure but the structure itself.
    157  */
    158 void ini_configuration_deinit(ini_configuration_t *conf)
    159 {
    160         hash_table_destroy(&conf->sections);
    161 }
    162 
    163 static void ini_section_init(ini_section_t *section)
    164 {
    165         hash_table_create(&section->items, 0, 0, &section_ht_ops);
    166         section->name = NULL;
    167 }
    168 
    169 static ini_section_t* ini_section_create(void)
    170 {
    171         ini_section_t *section = malloc(sizeof(ini_section_t));
    172         if (section != NULL) {
    173                 ini_section_init(section);
    174         }
    175         return section;
    176 }
    177 
    178 static void ini_section_destroy(ini_section_t **section_ptr)
    179 {
    180         ini_section_t *section = *section_ptr;
    181         if (section == NULL) {
    182                 return;
    183         }
    184         hash_table_destroy(&section->items);
    185         free(section->name);
    186         free(section);
    187         *section_ptr = NULL;
    188 }
    189 
    190 static void ini_item_init(ini_item_t *item)
    191 {
    192         item->key = NULL;
    193         item->value = NULL;
    194 }
    195 
    196 static ini_item_t *ini_item_create(void)
    197 {
    198         ini_item_t *item = malloc(sizeof(ini_item_t));
    199         if (item != NULL) {
    200                 ini_item_init(item);
    201         }
    202         return item;
    203 }
    204 
    205 static void ini_item_destroy(ini_item_t **item_ptr)
    206 {
    207         ini_item_t *item = *item_ptr;
    208         if (item == NULL) {
    209                 return;
    210         }
    211         free(item->key);
    212         free(item->value);
    213         free(item);
    214         *item_ptr = NULL;
    215 }
    216 
    217 /** Parse file contents to INI structure
    218  *
    219  * @param[in]    filename
    220  * @param[out]   conf      initialized structure for configuration
    221  * @param[out]   parse     initialized structure to keep parsing errors
    222  *
    223  * @return EOK on success
    224  * @return EIO when file cannot be opened
    225  * @return ENOMEM
    226  * @return EINVAL on parse error (details in parse structure)
    227  */
    228 int ini_parse_file(const char *filename, ini_configuration_t *conf,
    229     text_parse_t *parse)
     162/*
     163 * Static functions
     164 */
     165static char *read_file(char *buffer, int size, void *data)
     166{
     167        return fgets(buffer, size, (FILE *)data);
     168}
     169
     170static char *read_string(char *buffer, int size, void *data)
     171{
     172        char **string_ptr = (char **)data;
     173        char *string = *string_ptr;
     174
     175        int i = 0;
     176        while (i < size - 1) {
     177                char c = string[i];
     178                if (c == '\0') {
     179                        break;
     180                }
     181
     182                buffer[i++] = c;
     183
     184                if (c == '\n') {
     185                        break;
     186                }
     187        }
     188
     189        if (i == 0) {
     190                return NULL;
     191        }
     192
     193        buffer[i] = '\0';
     194        *string_ptr = string + i;
     195        return buffer;
     196}
     197
     198static int ini_parse_generic(line_reader_t line_reader, void *reader_data,
     199    ini_configuration_t *conf, text_parse_t *parse)
    230200{
    231201        int rc = EOK;
    232         FILE *f = NULL;
    233202        char *line_buffer = NULL;
    234 
    235         f = fopen(filename, "r");
    236         if (f == NULL) {
    237                 rc = EIO;
    238                 goto finish;
    239         }
    240203
    241204        line_buffer = malloc(LINE_BUFFER);
     
    249212        size_t lineno = 0;
    250213
    251         while ((line = fgets(line_buffer, LINE_BUFFER - 1, f))) {
     214        while ((line = line_reader(line_buffer, LINE_BUFFER, reader_data))) {
    252215                ++lineno;
    253216                size_t line_len = str_size(line);
     
    361324
    362325finish:
    363         if (f) {
    364                 fclose(f);
    365         }
    366326        free(line_buffer);
    367327
    368328        return rc;
     329}
     330
     331
     332
     333/*
     334 * Actual INI functions
     335 */
     336
     337void ini_configuration_init(ini_configuration_t *conf)
     338{
     339        hash_table_create(&conf->sections, 0, 0, &configuration_ht_ops);
     340}
     341
     342/** INI configuration destructor
     343 *
     344 * Release all resources of INI structure but the structure itself.
     345 */
     346void ini_configuration_deinit(ini_configuration_t *conf)
     347{
     348        hash_table_destroy(&conf->sections);
     349}
     350
     351static void ini_section_init(ini_section_t *section)
     352{
     353        hash_table_create(&section->items, 0, 0, &section_ht_ops);
     354        section->name = NULL;
     355}
     356
     357static ini_section_t* ini_section_create(void)
     358{
     359        ini_section_t *section = malloc(sizeof(ini_section_t));
     360        if (section != NULL) {
     361                ini_section_init(section);
     362        }
     363        return section;
     364}
     365
     366static void ini_section_destroy(ini_section_t **section_ptr)
     367{
     368        ini_section_t *section = *section_ptr;
     369        if (section == NULL) {
     370                return;
     371        }
     372        hash_table_destroy(&section->items);
     373        free(section->name);
     374        free(section);
     375        *section_ptr = NULL;
     376}
     377
     378static void ini_item_init(ini_item_t *item)
     379{
     380        item->key = NULL;
     381        item->value = NULL;
     382}
     383
     384static ini_item_t *ini_item_create(void)
     385{
     386        ini_item_t *item = malloc(sizeof(ini_item_t));
     387        if (item != NULL) {
     388                ini_item_init(item);
     389        }
     390        return item;
     391}
     392
     393static void ini_item_destroy(ini_item_t **item_ptr)
     394{
     395        ini_item_t *item = *item_ptr;
     396        if (item == NULL) {
     397                return;
     398        }
     399        free(item->key);
     400        free(item->value);
     401        free(item);
     402        *item_ptr = NULL;
     403}
     404
     405
     406/** Parse file contents to INI structure
     407 *
     408 * @param[in]    filename
     409 * @param[out]   conf      initialized structure for configuration
     410 * @param[out]   parse     initialized structure to keep parsing errors
     411 *
     412 * @return EOK on success
     413 * @return EIO when file cannot be opened
     414 * @return ENOMEM
     415 * @return EINVAL on parse error (details in parse structure)
     416 */
     417int ini_parse_file(const char *filename, ini_configuration_t *conf,
     418    text_parse_t *parse)
     419{
     420        FILE *f = NULL;
     421        f = fopen(filename, "r");
     422        if (f == NULL) {
     423                return EIO;
     424        }
     425
     426        int rc = ini_parse_generic(&read_file, f, conf, parse);
     427        fclose(f);
     428        return rc;
     429}
     430
     431/** Parse string to INI structure
     432 *
     433 * @param[in]    string
     434 * @param[out]   conf      initialized structure for configuration
     435 * @param[out]   parse     initialized structure to keep parsing errors
     436 *
     437 * @return EOK on success
     438 * @return ENOMEM
     439 * @return EINVAL on parse error (details in parse structure)
     440 */
     441int ini_parse_string(const char *string, ini_configuration_t *conf,
     442    text_parse_t *parse)
     443{
     444        const char *string_ptr = string;
     445
     446        return ini_parse_generic(&read_string, &string_ptr, conf, parse);
    369447}
    370448
Note: See TracChangeset for help on using the changeset viewer.