conf.cpp
来自「基于Linux下Epoll技术的EchoSvr」· C++ 代码 · 共 507 行
CPP
507 行
/**
* \file conf.c
* \author Jason Armstrong <ja@riverdrums.com>
* \version $Id: conf.c,v 1.3 2006/02/11 21:13:40 riverdrums Exp $
*
* \brief Configuration
*
* Functionality to read a configuration file that is in sections.
* A section starts with a name within braces [name]
*
* All sections before this that don't fall within a [] section
* are added to a section without a name ie ''
*
* Sections with the same name are amalgamated into one.
* Name / value pairs within a section are not added unless they
* are unique ie there is a check if they already exist.
*
* Multiple 'name' values are possible, and can be returned in
* a NULL terminated array.
*/
/*
COPYRIGHT (C) 2005 - 2006 RIVERDRUMS
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "Conf.h"
/** Read buffer size increment */
#define RD_BUFSIZE 128
Config::Config(char* f)
{
strcpy(filename,f);
configer = NULL;
}
Config::~Config()
{
cleanup();
}
void Config::cleanup()
{
int i, j;
struct rdconf *c = configer;
if (c == NULL) {
return;
}
/* Release in reverse order of acquisition */
for (i = c->secti - 1; i >= 0; i--) {
if (c->sect[i]) {
if (c->sect[i]->name) free(c->sect[i]->name);
for (j = c->sect[i]->nvi - 1; j >= 0; j--) {
if (c->sect[i]->nv[j]) {
if (c->sect[i]->nv[j]->name) free(c->sect[i]->nv[j]->name);
if (c->sect[i]->nv[j]->value) free(c->sect[i]->nv[j]->value);
free(c->sect[i]->nv[j]);
}
}
if (c->sect[i]->nv) free(c->sect[i]->nv);
free(c->sect[i]);
}
}
if (c) {
if (c->sect) free(c->sect);
free(c);
}
configer = NULL;
}
int Config::getInt(char *section, char *name)
{
char *s = getValue(section, name);
if (s == NULL) {
return -1; /* XXX This could also be a valid value */
}
return (atoi(s));
}
char * Config::getValue(char *section, char *name)
{
return getValue(configer,section,name);
}
char * Config::getValue(struct rdconf *c,char *section, char *name)
{
int i, j;
if (c == NULL || section == NULL || name == NULL) {
return NULL;
}
for (i = 0; i < c->secti; i++) {
if (strcmp(c->sect[i]->name, section) == 0) {
for (j = 0; j < c->sect[i]->nvi; j++) {
if (strcmp(c->sect[i]->nv[j]->name, name) == 0) {
return c->sect[i]->nv[j]->value;
}
}
}
}
return NULL;
}
bool Config::read()
{
if(configer != NULL)
return true;
char *buf, *sect, *name, *val, *tmp, *p, *c;
int linecount, len, gotsection, cs, s;
int sectsize, namesize, valsize;
struct rdconf *conf = NULL;
FILE *fp = NULL;
/* Initialise */
linecount = len = cs = gotsection = s = 0;
sectsize = namesize = valsize = 0;
buf = sect = name = val = tmp = p = c = NULL;
/* Allocate memory for our configuration structure */
if ( (configer = (struct rdconf *) malloc(sizeof(struct rdconf))) == NULL) {
false;
}
conf = configer;
char* section = NULL;
/* Start off with nothing */
memset(conf, 0, sizeof(struct rdconf));
/* Open the configuration file */
if ( (fp = fopen(filename, "r")) == NULL) {
//RD__error_add("Open '%s': %s", file, strerror(errno));
cleanup();
return false;
}
while ( (buf = readLine(fp, &buf, &s)) ) {
linecount++;
len = strlen(buf);
/* How did that happen */
if (len <= 0) {
continue;
}
/* The last character MUST be a \n */
if (buf[len - 1] != '\n') {
continue;
}
/* Strip trailing spaces (include \r \n) from the end */
while (len > 0 && isspace( (unsigned char) buf[len - 1])) {
buf[--len] = 0;
}
/* Check for comments and empty lines */
if (!buf[0] || buf[0] == '#' || buf[0] == ';') {
continue;
}
p = buf;
/* Get the section name */
if (p[0] == '[') {
/*
* If we're only looking for one section, and have it, then continue
* reading, because we might have another section with the same name
* later in the file. Disable adding name /values with gotsection
*/
if (section && gotsection) {
gotsection = 0;
continue;
}
p++;
if ( (c = strchr(p, ']')) == NULL) {
//RD__error_add("Missing closing ] on line %d", linecount);
fclose(fp);
if (buf) free(buf); if (sect) free(sect);
if (name) free(name); if (val) free(val);
cleanup();
return false;
}
/* Read the section name up to the closing ] */
if (sectsize < c - p) {
if ( (tmp = (char *) realloc(sect, c - p + 1)) == NULL) {
fclose(fp);
if (buf) free(buf); if (sect) free(sect);
if (name) free(name); if (val) free(val);
cleanup();
return false;
}
sect = tmp;
sectsize = c - p;
}
memcpy(sect, p, c - p);
sect[c - p] = 0;
if (!section || (section && strcmp(sect, section) == 0)) {
gotsection = 1;
} else {
continue;
}
if ( (cs = addSection(conf, sect)) < 0) {
fclose(fp);
if (sect) free(sect); if (buf) free(buf);
if (name) free(name); if (val) free(val);
cleanup();
return false;
}
continue;
}
/*
* Now we are in a section, reading name/value pairs
*/
/*
* Don't read here if we are looking for a particular section
* and haven't found it yet.
*/
if (section && !gotsection) {
continue;
}
/* Remove leading spaces */
while (*p && isspace( (unsigned char) *p)) {
p++;
}
if (!*p || *p == '#' || *p == ';') {
continue;
}
/* Read the name until the '=' delimiter */
c = p;
while (*c && *c != '=') {
c++;
}
/* Don't abort on error, just carry on */
if (!*c || *c != '=') {
//fprintf(stderr, "Invalid line %d\n", linecount);
continue;
}
if (namesize < c - p) {
if ( (tmp = (char *) realloc(name, c - p + 1)) == NULL) {
fclose(fp);
if (buf) free(buf); if (sect) free(sect);
if (name) free(name); if (val) free(val);
cleanup();
return false;
}
name = tmp;
namesize = c - p;
}
memcpy(name, p, c - p);
name[c - p] = 0;
/* Remove trailing spaces on the name */
len = strlen(name);
while (len && isspace( (unsigned char) name[len - 1]) ) {
name[--len] = 0;
}
p = c + 1;
/* Leading spaces in the value */
while (*p && isspace( (unsigned char) *p)) {
p++;
}
if (!*p) {
continue;
}
c = p;
while (*c) {
c++;
}
if (valsize < c - p) {
if ( (tmp = (char *) realloc(val, c - p + 1)) == NULL) {
fclose(fp);
if (buf) free(buf); if (sect) free(sect);
if (name) free(name); if (val) free(val);
cleanup();
return false;
}
val = tmp;
valsize = c - p;
}
memcpy(val, p, c - p);
val[c - p] = 0;
len = strlen(val);
while (len && isspace( (unsigned char) val[len - 1]) ) {
val[--len] = 0;
}
/* If we're in the start of the file and haven't found a
* section yet, then add one without a name */
if (!gotsection && !cs) {
if ( (cs = addSection(conf, "")) < 0) {
fclose(fp);
if (buf) free(buf); if (sect) free(sect);
if (name) free(name); if (val) free(val);
cleanup();
return false;
}
gotsection = 1;
}
if (addNameval(conf, cs, name, val) < 0) {
fclose(fp);
if (buf) free(buf); if (sect) free(sect);
if (name) free(name); if (val) free(val);
cleanup();
return false;;
}
}
if (buf) free(buf);
if (sect) free(sect);
if (name) free(name);
if (val) free(val);
fclose(fp);
return true;
}
char * Config::readLine(FILE *f, char **buf, int *s)
{
int o = 0;
char *tmp;
if (*buf == NULL) {
if ( (*buf = (char *) malloc(RD_BUFSIZE)) == NULL) {
return NULL;
}
*s = RD_BUFSIZE;
}
while (fgets(*buf + o, *s - o, f)) {
if (strchr(*buf + o, '\n')) {
return *buf;
} else {
o = *s - 1;
*s += RD_BUFSIZE;
if ( (tmp = (char *) realloc(*buf, *s)) == NULL) {
return NULL;
}
*buf = tmp;
}
}
return NULL;
}
int Config::addSection(struct rdconf *c,char *name)
{
int i = 0;
struct rdsection **tmp = c->sect;
if ( (i = findSection(c, name)) >= 0) {
return i;
}
i = c->secti;
if ( (c->sect =
(struct rdsection **)
realloc(i ? c->sect : NULL,
(i + 1) * sizeof(struct rdsection *))) == NULL) {
c->sect = tmp;
return -1;
}
c->secti++;
if ( (c->sect[i] =
(struct rdsection *)
malloc(sizeof(struct rdsection)) ) == NULL) {
return -1;
}
memset(c->sect[i], 0, sizeof(struct rdsection));
if ( (c->sect[i]->name = strdup(name)) == NULL) {
return -1;
}
return c->secti - 1;
}
int Config::findSection(struct rdconf *c, char *name)
{
int i;
for (i = 0; i < c->secti; i++)
{
if (strcmp(c->sect[i]->name, name) == 0)
{
return i;
}
}
return -1;
}
int Config::addNameval(struct rdconf *c, int cs, char *name, char *val)
{
struct rdnameval **tmp = NULL;
int i = c->sect[cs]->nvi;
char *check = NULL;
if ( (check = getValue(c, c->sect[cs]->name, name)) &&
strcmp(check, val) == 0) {
/* It's there already */
return 0;
}
/* Allocate a new rdnameval structure for storage */
if ( (tmp = (struct rdnameval **)
realloc(c->sect[cs]->nv,
(i + 1) * sizeof(struct rdnameval *))) == NULL) {
return -1;
}
c->sect[cs]->nv = tmp;
c->sect[cs]->nvi++;
if ( (c->sect[cs]->nv[i] =
(struct rdnameval *)
malloc(sizeof(struct rdnameval))) == NULL) {
return -1;
}
memset(c->sect[cs]->nv[i], 0, sizeof(struct rdnameval));
/* Duplicate the name */
if ( (c->sect[cs]->nv[i]->name = strdup(name)) == NULL) {
return -1;
}
/* Copy the value (theoretically can be any length
* but is limited to the size of the val buffer (256) above */
if ( (c->sect[cs]->nv[i]->value = strdup(val)) == NULL) {
return -1;
}
return 0;
}
/*int main(int argc, char *argv[])
{
Config c("dgs.conf");
if(c.read())
{
std::cout<<c.getInt("server","port");
}
}*/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?