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(path, "r");
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