Welcome, guest! Login / Register - Why register?
Psst.. new poll here.
Psst.. new forums here.
Microsoft is blocking us again (TY IP Reputation!) so just use oauth login instead. :)

Paste

Pasted as C by Parse ( 15 years ago )
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "parse_config.h"
typedef struct ConfigParam
{
    char *name; //!< Имя параметра
    char *value; //!< Значение параметра
} ConfigParam;

struct ConfigFile
{
    int size; //!< Число использованных элементов в векторе
    int reserved; //!< Число элементов, под которые зарезервирована память
    ConfigParam *params; //!< Массив параметров
};
int
compare(const void * a, const void * b)
{
    ConfigParam *p1 = (ConfigParam *)a;
    ConfigParam *p2 = (ConfigParam *)b;
    return strcmp(p1 -> name, p2 -> name);
}
ConfigFile *
config_file_parse(const char *path, FILE *log_f)
{
    ConfigFile *cfg = (ConfigFile*) calloc(1, sizeof(*cfg));
    ConfigParam *par = NULL;
    int i = 0, res = 1, j, count = 0, k, s;
    char *p;
    FILE *f = fopen&#40;path, "r"&#41;;
    if (f == NULL)
    {
        fprintf(log_f, "Failed to open %s for readingn", path);
        return NULL;
    }
    char buf[1024];
    while(fgets(buf, sizeof(buf), f) != NULL)
    {
        count++;
        if ((p = strchr(buf, '#'))) {
            *p = 0;
        }
        if (strlen(buf) == 0)
        {
            continue;
        }
        j = 0;
        while((buf[j] == ' ') && (j < strlen(buf)))
        {
            j++;
        }
        if (j == strlen(buf) || buf[j] == 'n')
        {
            continue;
        }
        if (!isalpha(buf[j]) && buf[j] != '_')
        {
            fprintf(log_f, "Syntax error in line %d of %sn", count, path);
            fclose(f);
            return NULL;
        }
        i++;
        if (i == res)
        {
            res *= 2;
            if (par == NULL)
            {
                par = calloc(res, sizeof(ConfigParam));
            }
            else
            par = realloc(par, res * sizeof(ConfigParam ));
        }
        par[i - 1].name = calloc(1000, sizeof(char));
        k = 0;
        while((buf[j] != '=') && (j < strlen(buf)) && (buf[j] != ' '))
        {
            if (!isalpha(buf[j]) && !isdigit(buf[j]) && buf[j] != '_' && buf[j] != '-')
            {
                fprintf(log_f, "Syntax error in line %d of %sn", count, path);
                fclose(f);
                return NULL;
            }
            par[i - 1].name[k] = buf[j];
            k++;
            j++;
        }
        while((buf[j] == ' ') && (j < strlen(buf)))
        {
            j++;
        }
        if ((j >= strlen(buf)) || (buf[j] != '='))
        {
            fprintf(log_f, "Syntax error in line %d of %sn", count, path);
            fclose(f);
            return NULL;
        }
        for(s = 0; s < i - 1; s++)
        {
            if(strcmp(par[s].name, par[i - 1].name) == 0)
            {
                fprintf(log_f, "Duplicate parameter %s in %sn", par[i - 1].name, path);
                fclose(f);
                return NULL;
            }
        }
        par[i - 1].value = calloc(1000, sizeof(char));
        k = 0;
        j++;
        while((buf[j] == ' ') && (j < strlen(buf)))
        {
            j++;
        }
        while(j < strlen(buf))
        {
            par[i - 1].value[k] = buf[j];
            j++;
            k++;
        }
        k--;
        while(isspace(par[i - 1].value[k]) && k >= 0)
        {
            par[i - 1].value[k] = 0;
            k--;
        }
    }
    qsort(par, i, sizeof(ConfigParam), compare);
    cfg -> size = i;
    cfg -> reserved = res;
    cfg -> params = par;
    close(f);
    return cfg;
}
ConfigFile *
config_file_free(ConfigFile *cfg)
{
    int i, j;
    for(i = 0; i < cfg -> size; i++)
    {
            free(cfg -> params[i].name);
            free(cfg -> params[i].value);
    }
    free(cfg);
    return NULL;
}

const char *
config_file_get(const ConfigFile *cfg, const char *name)
{
    int first = 0;
    int last = cfg -> size - 1;
    int mid;
    if((strcmp(name, cfg -> params[first].name) < 0) ||(strcmp(name, cfg -> params[last].name) > 0))
        return NULL;
    while (first < last)
    {
        mid = (last + first) / 2;
        if (strcmp(cfg -> params[mid].name, name) >= 0)
        {
            last = mid;
        }
        else
        {
            first = mid + 1;
        }
    }
    if ((cfg -> size != 0) && (strcmp(cfg -> params[last].name, name) == 0))
        return cfg -> params[last].value;
    return NULL;
}

int
config_file_get_int(const ConfigFile *cfg, const char *name, int *p_value)
{
    const char *str = config_file_get(cfg, name);
    if (!str) {
        return 0;
    }
    char *eptr = NULL;
    errno = 0;
    int value = strtol(str, &eptr;, 10);
    if (*eptr || errno) {
        return -1;
    }
    *p_value = value;
    return 1;
}

void
config_print(const ConfigFile *cfg)
{
    int i = 0;
    for(i = 0; i < cfg -> size; i++)
    {
        printf("%s = "%s"n", cfg -> params[i].name, cfg -> params[i].value);
    }
}

 

Revise this Paste

Your Name: Code Language: