mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16:37:01 +00:00
[8645] Cleanup code for config loading/store/access.
Signed-off-by: VladimirMangos <vladimir@getmangos.com>
This commit is contained in:
parent
4d3e43e814
commit
aff1a3e59f
9 changed files with 532 additions and 474 deletions
|
|
@ -398,8 +398,8 @@ int Master::Run()
|
|||
bool Master::_StartDB()
|
||||
{
|
||||
///- Get world database info from configuration file
|
||||
std::string dbstring;
|
||||
if(!sConfig.GetString("WorldDatabaseInfo", &dbstring))
|
||||
std::string dbstring = sConfig.GetStringDefault("WorldDatabaseInfo", "");
|
||||
if(dbstring.empty())
|
||||
{
|
||||
sLog.outError("Database not specified in configuration file");
|
||||
return false;
|
||||
|
|
@ -416,7 +416,8 @@ bool Master::_StartDB()
|
|||
if(!WorldDatabase.CheckRequiredField("db_version",REVISION_DB_MANGOS))
|
||||
return false;
|
||||
|
||||
if(!sConfig.GetString("CharacterDatabaseInfo", &dbstring))
|
||||
dbstring = sConfig.GetStringDefault("CharacterDatabaseInfo", "");
|
||||
if(dbstring.empty())
|
||||
{
|
||||
sLog.outError("Character Database not specified in configuration file");
|
||||
return false;
|
||||
|
|
@ -434,7 +435,8 @@ bool Master::_StartDB()
|
|||
return false;
|
||||
|
||||
///- Get login database info from configuration file
|
||||
if(!sConfig.GetString("LoginDatabaseInfo", &dbstring))
|
||||
dbstring = sConfig.GetStringDefault("LoginDatabaseInfo", "");
|
||||
if(dbstring.empty())
|
||||
{
|
||||
sLog.outError("Login database not specified in configuration file");
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ char serviceDescription[] = "Massive Network Game Object Server";
|
|||
int m_ServiceStatus = -1;
|
||||
#endif
|
||||
|
||||
bool StartDB(std::string &dbstring);
|
||||
bool StartDB();
|
||||
void UnhookSignals();
|
||||
void HookSignals();
|
||||
|
||||
|
|
@ -187,8 +187,7 @@ extern int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
///- Initialize the database connection
|
||||
std::string dbstring;
|
||||
if(!StartDB(dbstring))
|
||||
if(!StartDB())
|
||||
return 1;
|
||||
|
||||
///- Get the list of realms for the server
|
||||
|
|
@ -312,9 +311,10 @@ void OnSignal(int s)
|
|||
}
|
||||
|
||||
/// Initialize connection to the database
|
||||
bool StartDB(std::string &dbstring)
|
||||
bool StartDB()
|
||||
{
|
||||
if(!sConfig.GetString("LoginDatabaseInfo", &dbstring))
|
||||
std::string dbstring = sConfig.GetStringDefault("LoginDatabaseInfo", "");
|
||||
if(dbstring.empty())
|
||||
{
|
||||
sLog.outError("Database not specified");
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -21,17 +21,16 @@
|
|||
|
||||
INSTANTIATE_SINGLETON_1(Config);
|
||||
|
||||
Config::Config() : mIgnoreCase(true), mConf(NULL)
|
||||
Config::Config()
|
||||
: mIgnoreCase(true), mConf(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Config::~Config()
|
||||
{
|
||||
delete mConf;
|
||||
}
|
||||
|
||||
|
||||
bool Config::SetSource(const char *file, bool ignorecase)
|
||||
{
|
||||
mIgnoreCase = ignorecase;
|
||||
|
|
@ -46,7 +45,7 @@ bool Config::Reload()
|
|||
|
||||
mConf = new DOTCONFDocument(mIgnoreCase ?
|
||||
DOTCONFDocument::CASEINSENSETIVE :
|
||||
DOTCONFDocument::CASESENSETIVE);
|
||||
DOTCONFDocument::CASESENSITIVE);
|
||||
|
||||
if (mConf->setContent(mFilename.c_str()) == -1)
|
||||
{
|
||||
|
|
@ -58,117 +57,58 @@ bool Config::Reload()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Config::GetString(const char* name, std::string *value)
|
||||
{
|
||||
if(!mConf)
|
||||
return false;
|
||||
|
||||
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
||||
if(!node || !node->getValue())
|
||||
return false;
|
||||
|
||||
*value = node->getValue();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Config::GetString(const char* name, char const **value)
|
||||
{
|
||||
if(!mConf)
|
||||
return false;
|
||||
|
||||
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
||||
if(!node || !node->getValue())
|
||||
return false;
|
||||
|
||||
*value = node->getValue();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::string Config::GetStringDefault(const char* name, const char* def)
|
||||
{
|
||||
if(!mConf)
|
||||
if (!mConf)
|
||||
return std::string(def);
|
||||
|
||||
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
||||
if(!node || !node->getValue())
|
||||
if (!node || !node->getValue())
|
||||
return std::string(def);
|
||||
|
||||
return std::string(node->getValue());
|
||||
}
|
||||
|
||||
|
||||
bool Config::GetBool(const char* name, bool *value)
|
||||
bool Config::GetBoolDefault(const char* name, bool def)
|
||||
{
|
||||
if(!mConf)
|
||||
return false;
|
||||
if (!mConf)
|
||||
return def;
|
||||
|
||||
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
||||
if(!node || !node->getValue())
|
||||
return false;
|
||||
if (!node || !node->getValue())
|
||||
return def;
|
||||
|
||||
const char* str = node->getValue();
|
||||
if(strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0 ||
|
||||
if (strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0 ||
|
||||
strcmp(str, "yes") == 0 || strcmp(str, "YES") == 0 ||
|
||||
strcmp(str, "1") == 0)
|
||||
{
|
||||
*value = true;
|
||||
}
|
||||
return true;
|
||||
else
|
||||
*value = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Config::GetBoolDefault(const char* name, const bool def)
|
||||
{
|
||||
bool val;
|
||||
return GetBool(name, &val) ? val : def;
|
||||
}
|
||||
|
||||
|
||||
bool Config::GetInt(const char* name, int *value)
|
||||
{
|
||||
if(!mConf)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int32 Config::GetIntDefault(const char* name, int32 def)
|
||||
{
|
||||
if (!mConf)
|
||||
return def;
|
||||
|
||||
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
||||
if(!node || !node->getValue())
|
||||
return false;
|
||||
if (!node || !node->getValue())
|
||||
return def;
|
||||
|
||||
*value = atoi(node->getValue());
|
||||
|
||||
return true;
|
||||
return atoi(node->getValue());
|
||||
}
|
||||
|
||||
|
||||
bool Config::GetFloat(const char* name, float *value)
|
||||
float Config::GetFloatDefault(const char* name, float def)
|
||||
{
|
||||
if(!mConf)
|
||||
return false;
|
||||
if (!mConf)
|
||||
return def;
|
||||
|
||||
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
||||
if(!node || !node->getValue())
|
||||
return false;
|
||||
if (!node || !node->getValue())
|
||||
return def;
|
||||
|
||||
*value = atof(node->getValue());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int Config::GetIntDefault(const char* name, const int def)
|
||||
{
|
||||
int val;
|
||||
return GetInt(name, &val) ? val : def;
|
||||
}
|
||||
|
||||
|
||||
float Config::GetFloatDefault(const char* name, const float def)
|
||||
{
|
||||
float val;
|
||||
return (GetFloat(name, &val) ? val : def);
|
||||
return atof(node->getValue());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,27 +27,22 @@ class DOTCONFDocument;
|
|||
class MANGOS_DLL_SPEC Config
|
||||
{
|
||||
public:
|
||||
|
||||
Config();
|
||||
~Config();
|
||||
|
||||
bool SetSource(const char *file, bool ignorecase = true);
|
||||
bool Reload();
|
||||
|
||||
bool GetString(const char* name, std::string *value);
|
||||
bool GetString(const char* name, char const **value);
|
||||
std::string GetStringDefault(const char* name, const char* def);
|
||||
|
||||
bool GetBool(const char* name, bool *value);
|
||||
bool GetBoolDefault(const char* name, const bool def = false);
|
||||
|
||||
bool GetInt(const char* name, int *value);
|
||||
int GetIntDefault(const char* name, const int def);
|
||||
|
||||
bool GetFloat(const char* name, float *value);
|
||||
int32 GetIntDefault(const char* name, const int32 def);
|
||||
float GetFloatDefault(const char* name, const float def);
|
||||
|
||||
std::string GetFilename() const { return mFilename; }
|
||||
|
||||
private:
|
||||
|
||||
std::string mFilename;
|
||||
bool mIgnoreCase;
|
||||
DOTCONFDocument *mConf;
|
||||
|
|
|
|||
|
|
@ -1,64 +1,68 @@
|
|||
|
||||
#include "Common.h"
|
||||
|
||||
#include "dotconfpp.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#define PATH_MAX _MAX_PATH
|
||||
#define strcasecmp stricmp
|
||||
#define realpath(path,resolved_path) _fullpath(resolved_path, path, _MAX_PATH)
|
||||
#include <io.h>
|
||||
# define PATH_MAX _MAX_PATH
|
||||
# define strcasecmp stricmp
|
||||
# define realpath(path,resolved_path) _fullpath(resolved_path, path, _MAX_PATH)
|
||||
# include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <strings.h>
|
||||
# include <unistd.h>
|
||||
# include <limits.h>
|
||||
# include <stdint.h>
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#if !defined(R_OK)
|
||||
#define R_OK 04
|
||||
# define R_OK 04
|
||||
#endif
|
||||
|
||||
DOTCONFDocumentNode::DOTCONFDocumentNode():previousNode(NULL), nextNode(NULL), parentNode(NULL), childNode(NULL),
|
||||
values(NULL), valuesCount(0),
|
||||
name(NULL), lineNum(0), fileName(NULL), closed(true)
|
||||
DOTCONFDocumentNode::DOTCONFDocumentNode()
|
||||
: previousNode(NULL), nextNode(NULL), parentNode(NULL), childNode(NULL),
|
||||
values(NULL), valuesCount(0), name(NULL), lineNum(0),
|
||||
fileName(NULL), closed(true)
|
||||
{
|
||||
}
|
||||
|
||||
DOTCONFDocumentNode::~DOTCONFDocumentNode()
|
||||
{
|
||||
free(name);
|
||||
if(values != NULL){
|
||||
for(int i = 0 ; i < valuesCount; i++){
|
||||
|
||||
if (values != NULL)
|
||||
{
|
||||
for (int i = 0; i < valuesCount; ++i)
|
||||
free(values[i]);
|
||||
}
|
||||
|
||||
free(values);
|
||||
}
|
||||
}
|
||||
|
||||
void DOTCONFDocumentNode::pushValue(char * _value)
|
||||
void DOTCONFDocumentNode::pushValue(char* _value)
|
||||
{
|
||||
++valuesCount;
|
||||
values = (char**)realloc(values, valuesCount*sizeof(char*));
|
||||
values[valuesCount-1] = strdup(_value);
|
||||
values = (char**)realloc(values, valuesCount * sizeof(char*));
|
||||
values[valuesCount - 1] = strdup(_value);
|
||||
}
|
||||
|
||||
const char* DOTCONFDocumentNode::getValue(int index) const
|
||||
{
|
||||
if(index >= valuesCount){
|
||||
if (index >= valuesCount)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return values[index];
|
||||
}
|
||||
|
||||
DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity):
|
||||
mempool(NULL),
|
||||
curParent(NULL), curPrev(NULL), curLine(0), file(NULL), fileName(NULL)
|
||||
DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity)
|
||||
: mempool(NULL), curParent(NULL), curPrev(NULL), curLine(0), file(NULL), fileName(NULL)
|
||||
{
|
||||
if(caseSensitivity == CASESENSETIVE){
|
||||
cmp_func = strcmp;
|
||||
} else {
|
||||
cmp_func = strcasecmp;
|
||||
switch (caseSensitivity)
|
||||
{
|
||||
case CASESENSITIVE:
|
||||
cmp_func = strcmp;
|
||||
break;
|
||||
case CASEINSENSETIVE:
|
||||
cmp_func = strcasecmp;
|
||||
break;
|
||||
}
|
||||
|
||||
mempool = new AsyncDNSMemPool(1024);
|
||||
|
|
@ -67,195 +71,247 @@ DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity)
|
|||
|
||||
DOTCONFDocument::~DOTCONFDocument()
|
||||
{
|
||||
for(std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i != nodeTree.end(); i++){
|
||||
for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i)
|
||||
delete(*i);
|
||||
}
|
||||
for(std::list<char*>::iterator i = requiredOptions.begin(); i != requiredOptions.end(); i++){
|
||||
|
||||
for (CharList::iterator i = requiredOptions.begin(); i != requiredOptions.end(); ++i)
|
||||
free(*i);
|
||||
}
|
||||
for(std::list<char*>::iterator i = processedFiles.begin(); i != processedFiles.end(); i++){
|
||||
|
||||
for (CharList::iterator i = processedFiles.begin(); i != processedFiles.end(); ++i)
|
||||
free(*i);
|
||||
}
|
||||
|
||||
free(fileName);
|
||||
delete mempool;
|
||||
}
|
||||
|
||||
int DOTCONFDocument::cleanupLine(char * line)
|
||||
int DOTCONFDocument::cleanupLine(char* line)
|
||||
{
|
||||
char * start = line;
|
||||
char * bg = line;
|
||||
char* start = line;
|
||||
char* bg = line;
|
||||
bool multiline = false;
|
||||
bool concat = false;
|
||||
char * word = NULL;
|
||||
char* word = NULL;
|
||||
|
||||
if(!words.empty() && quoted)
|
||||
if (!words.empty() && quoted)
|
||||
concat = true;
|
||||
|
||||
while(*line){
|
||||
if((*line == '#' || *line == ';') && !quoted){
|
||||
while (*line)
|
||||
{
|
||||
if ((*line == '#' || *line == ';') && !quoted)
|
||||
{
|
||||
*bg = 0;
|
||||
if(strlen(start)){
|
||||
|
||||
if(concat){
|
||||
word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1);
|
||||
if (strlen(start))
|
||||
{
|
||||
if (concat)
|
||||
{
|
||||
word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1);
|
||||
strcpy(word, words.back());
|
||||
strcat(word, start);
|
||||
words.pop_back();
|
||||
concat = false;
|
||||
} else {
|
||||
word = mempool->strdup(start);
|
||||
}
|
||||
else
|
||||
word = mempool->Strdup(start);
|
||||
|
||||
words.push_back(word);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if(*line == '=' && !quoted){
|
||||
*line = ' ';continue;
|
||||
|
||||
if (*line == '=' && !quoted)
|
||||
{
|
||||
*line = ' ';
|
||||
continue;
|
||||
}
|
||||
|
||||
// Allowing \" in there causes problems with directory paths
|
||||
// like "C:\MaNGOS\"
|
||||
//if(*line == '\\' && (*(line+1) == '"' || *(line+1) == '\'')){
|
||||
if(*line == '\\' && (*(line+1) == '\'')) {
|
||||
*bg++ = *(line+1);
|
||||
line+=2; continue;
|
||||
if (*line == '\\' && (*(line + 1) == '\''))
|
||||
{
|
||||
*bg++ = *(line + 1);
|
||||
line += 2;
|
||||
continue;
|
||||
}
|
||||
if(*line == '\\' && *(line+1) == 'n'){
|
||||
*bg++ = '\n';
|
||||
line+=2; continue;
|
||||
}
|
||||
if(*line == '\\' && *(line+1) == 'r'){
|
||||
*bg++ = '\r';
|
||||
line+=2; continue;
|
||||
}
|
||||
if(*line == '\\' && (*(line+1) == '\n' || *(line+1) == '\r')){
|
||||
*bg = 0;
|
||||
if(strlen(start)){
|
||||
|
||||
if(concat){
|
||||
word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1);
|
||||
if (*line == '\\' && *(line + 1) == 'n')
|
||||
{
|
||||
*bg++ = '\n';
|
||||
line += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*line == '\\' && *(line + 1) == 'r')
|
||||
{
|
||||
*bg++ = '\r';
|
||||
line += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*line == '\\' && (*(line + 1) == '\n' || *(line + 1) == '\r'))
|
||||
{
|
||||
*bg = 0;
|
||||
if (strlen(start))
|
||||
{
|
||||
if (concat)
|
||||
{
|
||||
word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1);
|
||||
strcpy(word, words.back());
|
||||
strcat(word, start);
|
||||
words.pop_back();
|
||||
concat = false;
|
||||
} else {
|
||||
word = mempool->strdup(start);
|
||||
}
|
||||
else
|
||||
word = mempool->Strdup(start);
|
||||
|
||||
words.push_back(word);
|
||||
}
|
||||
|
||||
multiline = true;
|
||||
break;
|
||||
}
|
||||
if(*line == '"' || *line == '\''){
|
||||
quoted = !quoted;
|
||||
++line; continue;
|
||||
}
|
||||
if(isspace((unsigned char)*line) && !quoted){
|
||||
*bg++ = 0;
|
||||
if(strlen(start)){
|
||||
|
||||
if(concat){
|
||||
word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1);
|
||||
if (*line == '"' || *line == '\'')
|
||||
{
|
||||
quoted = !quoted;
|
||||
++line;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isspace((unsigned char)*line) && !quoted)
|
||||
{
|
||||
*bg++ = 0;
|
||||
if (strlen(start))
|
||||
{
|
||||
if (concat)
|
||||
{
|
||||
word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1);
|
||||
strcpy(word, words.back());
|
||||
strcat(word, start);
|
||||
words.pop_back();
|
||||
concat = false;
|
||||
} else {
|
||||
word = mempool->strdup(start);
|
||||
}
|
||||
else
|
||||
word = mempool->Strdup(start);
|
||||
|
||||
words.push_back(word);
|
||||
}
|
||||
|
||||
start = bg;
|
||||
while(isspace((unsigned char)*++line)) {}
|
||||
while (isspace((unsigned char)*++line))
|
||||
{
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
*bg++ = *line++;
|
||||
}
|
||||
|
||||
if(quoted && !multiline){
|
||||
if (quoted && !multiline)
|
||||
{
|
||||
error(curLine, fileName, "unterminated quote");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return multiline?1:0;
|
||||
return multiline ? 1 : 0;
|
||||
}
|
||||
|
||||
int DOTCONFDocument::parseLine()
|
||||
{
|
||||
char * word = NULL;
|
||||
char * nodeName = NULL;
|
||||
char * nodeValue = NULL;
|
||||
DOTCONFDocumentNode * tagNode = NULL;
|
||||
char* word = NULL;
|
||||
char* nodeName = NULL;
|
||||
char* nodeValue = NULL;
|
||||
DOTCONFDocumentNode* tagNode = NULL;
|
||||
bool newNode = false;
|
||||
|
||||
for(std::list<char*>::iterator i = words.begin(); i != words.end(); i++) {
|
||||
for (CharList::iterator i = words.begin(); i != words.end(); ++i)
|
||||
{
|
||||
word = *i;
|
||||
|
||||
if(*word == '<'){
|
||||
if (*word == '<')
|
||||
newNode = true;
|
||||
}
|
||||
|
||||
if(newNode){
|
||||
if (newNode)
|
||||
{
|
||||
nodeValue = NULL;
|
||||
nodeName = NULL;
|
||||
newNode = false;
|
||||
}
|
||||
|
||||
size_t wordLen = strlen(word);
|
||||
if(word[wordLen-1] == '>'){
|
||||
word[wordLen-1] = 0;
|
||||
if (word[wordLen - 1] == '>')
|
||||
{
|
||||
word[wordLen - 1] = 0;
|
||||
newNode = true;
|
||||
}
|
||||
|
||||
if(nodeName == NULL){
|
||||
if (nodeName == NULL)
|
||||
{
|
||||
nodeName = word;
|
||||
bool closed = true;
|
||||
if(*nodeName == '<'){
|
||||
if(*(nodeName+1) != '/'){
|
||||
if (*nodeName == '<')
|
||||
{
|
||||
if (*(nodeName + 1) != '/')
|
||||
{
|
||||
++nodeName;
|
||||
closed = false;
|
||||
} else {
|
||||
nodeName+=2;
|
||||
std::list<DOTCONFDocumentNode*>::reverse_iterator itr=nodeTree.rbegin();
|
||||
for(; itr!=nodeTree.rend(); ++itr){
|
||||
if(!cmp_func(nodeName, (*itr)->name) && !(*itr)->closed){
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeList::reverse_iterator itr = nodeTree.rbegin();
|
||||
nodeName += 2;
|
||||
for (; itr != nodeTree.rend(); ++itr)
|
||||
{
|
||||
if (!cmp_func(nodeName, (*itr)->name) && !(*itr)->closed)
|
||||
{
|
||||
(*itr)->closed = true;
|
||||
curParent = (*itr)->parentNode;
|
||||
curPrev = *itr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(itr==nodeTree.rend()){
|
||||
|
||||
if(itr == nodeTree.rend())
|
||||
{
|
||||
error(curLine, fileName, "not matched closing tag </%s>", nodeName);
|
||||
return -1;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
tagNode = new DOTCONFDocumentNode;
|
||||
tagNode->name = strdup(nodeName);
|
||||
tagNode->document = this;
|
||||
tagNode->fileName = processedFiles.back();
|
||||
tagNode->lineNum = curLine;
|
||||
tagNode->closed = closed;
|
||||
if(!nodeTree.empty()){
|
||||
DOTCONFDocumentNode * prev = nodeTree.back();
|
||||
if(prev->closed){
|
||||
|
||||
if(!nodeTree.empty())
|
||||
{
|
||||
DOTCONFDocumentNode* prev = nodeTree.back();
|
||||
if (prev->closed)
|
||||
{
|
||||
curPrev->nextNode = tagNode;
|
||||
tagNode->previousNode = curPrev;
|
||||
tagNode->parentNode = curParent;
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
prev->childNode = tagNode;
|
||||
tagNode->parentNode = prev;
|
||||
curParent = prev;
|
||||
}
|
||||
}
|
||||
|
||||
nodeTree.push_back(tagNode);
|
||||
curPrev = tagNode;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeValue = word;
|
||||
tagNode->pushValue(nodeValue);
|
||||
}
|
||||
|
|
@ -263,7 +319,8 @@ int DOTCONFDocument::parseLine()
|
|||
|
||||
return 0;
|
||||
}
|
||||
int DOTCONFDocument::parseFile(DOTCONFDocumentNode * _parent)
|
||||
|
||||
int DOTCONFDocument::parseFile(DOTCONFDocumentNode* _parent)
|
||||
{
|
||||
char str[512];
|
||||
int ret = 0;
|
||||
|
|
@ -273,27 +330,32 @@ int DOTCONFDocument::parseFile(DOTCONFDocumentNode * _parent)
|
|||
quoted = false;
|
||||
size_t slen = 0;
|
||||
|
||||
while(fgets(str, 511, file)){
|
||||
while (fgets(str, 511, file))
|
||||
{
|
||||
++curLine;
|
||||
slen = strlen(str);
|
||||
if( slen >= 510 ){
|
||||
slen = strlen(str);
|
||||
if (slen >= 510)
|
||||
error(curLine, fileName, "warning: line too long");
|
||||
|
||||
if (str[slen - 1] != '\n')
|
||||
{
|
||||
str[slen] = '\n';
|
||||
str[slen + 1] = 0;
|
||||
}
|
||||
if(str[slen-1] != '\n'){
|
||||
str[slen] = '\n';
|
||||
str[slen+1] = 0;
|
||||
}
|
||||
if((ret = cleanupLine(str)) == -1){
|
||||
|
||||
if ((ret = cleanupLine(str)) == -1)
|
||||
break;
|
||||
}
|
||||
if(ret == 0){
|
||||
if(!words.empty()){
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
if (!words.empty())
|
||||
{
|
||||
ret = parseLine();
|
||||
mempool->free();
|
||||
mempool->Free();
|
||||
words.clear();
|
||||
if(ret == -1){
|
||||
|
||||
if(ret == -1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -301,46 +363,51 @@ int DOTCONFDocument::parseFile(DOTCONFDocumentNode * _parent)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int DOTCONFDocument::checkConfig(const std::list<DOTCONFDocumentNode*>::iterator & from)
|
||||
int DOTCONFDocument::checkConfig(const NodeList::iterator& from)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
DOTCONFDocumentNode * tagNode = NULL;
|
||||
DOTCONFDocumentNode* tagNode = NULL;
|
||||
int vi = 0;
|
||||
for(std::list<DOTCONFDocumentNode*>::iterator i = from; i != nodeTree.end(); i++){
|
||||
for (NodeList::iterator i = from; i != nodeTree.end(); ++i)
|
||||
{
|
||||
tagNode = *i;
|
||||
if(!tagNode->closed){
|
||||
if (!tagNode->closed)
|
||||
{
|
||||
error(tagNode->lineNum, tagNode->fileName, "unclosed tag %s", tagNode->name);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
vi = 0;
|
||||
while( vi < tagNode->valuesCount ){
|
||||
|
||||
if(strstr(tagNode->values[vi], "${") && strchr(tagNode->values[vi], '}') ){
|
||||
ret = macroSubstitute(tagNode, vi );
|
||||
mempool->free();
|
||||
if(ret == -1){
|
||||
vi = 0;
|
||||
while (vi < tagNode->valuesCount)
|
||||
{
|
||||
if (strstr(tagNode->values[vi], "${") && strchr(tagNode->values[vi], '}'))
|
||||
{
|
||||
ret = macroSubstitute(tagNode, vi);
|
||||
mempool->Free();
|
||||
if (ret == -1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
++vi;
|
||||
}
|
||||
if(ret == -1){
|
||||
|
||||
if (ret == -1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DOTCONFDocument::setContent(const char * _fileName)
|
||||
int DOTCONFDocument::setContent(const char* _fileName)
|
||||
{
|
||||
int ret = 0;
|
||||
char realpathBuf[PATH_MAX];
|
||||
|
||||
if(realpath(_fileName, realpathBuf) == NULL){
|
||||
error(0, NULL, "realpath(%s) failed: %s", _fileName, strerror(errno));
|
||||
if (realpath(_fileName, realpathBuf) == NULL)
|
||||
{
|
||||
error(0, NULL, "realpath (%s) failed: %s", _fileName, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -348,79 +415,90 @@ int DOTCONFDocument::setContent(const char * _fileName)
|
|||
|
||||
processedFiles.push_back(strdup(realpathBuf));
|
||||
|
||||
if(( file = fopen(fileName, "r")) == NULL){
|
||||
if ((file = fopen(fileName, "r")) == NULL)
|
||||
{
|
||||
error(0, NULL, "failed to open file '%s': %s", fileName, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Try read utf8 header and skip it if exist
|
||||
uint32 utf8header = 0;
|
||||
unsigned int utf8header = 0;
|
||||
fgets((char*)&utf8header, 4, file); // Try read header
|
||||
if (utf8header!=0x00BFBBEF) // If not exist
|
||||
if (utf8header != 0x00BFBBEF) // If not exist
|
||||
fseek(file, 0, SEEK_SET); // Reset read position
|
||||
|
||||
ret = parseFile();
|
||||
|
||||
(void) fclose(file);
|
||||
fclose(file);
|
||||
|
||||
if(!ret){
|
||||
|
||||
if( (ret = checkConfig(nodeTree.begin())) == -1){
|
||||
if (!ret)
|
||||
{
|
||||
if ((ret = checkConfig(nodeTree.begin())) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::list<DOTCONFDocumentNode*>::iterator from;
|
||||
DOTCONFDocumentNode * tagNode = NULL;
|
||||
NodeList::iterator from;
|
||||
DOTCONFDocumentNode* tagNode = NULL;
|
||||
int vi = 0;
|
||||
for(std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i!=nodeTree.end(); i++){
|
||||
for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i)
|
||||
{
|
||||
tagNode = *i;
|
||||
if(!cmp_func("DOTCONFPPIncludeFile", tagNode->name)){
|
||||
if (!cmp_func("DOTCONFPPIncludeFile", tagNode->name))
|
||||
{
|
||||
vi = 0;
|
||||
while( vi < tagNode->valuesCount ){
|
||||
if(access(tagNode->values[vi], R_OK) == -1){
|
||||
while (vi < tagNode->valuesCount)
|
||||
{
|
||||
if (access(tagNode->values[vi], R_OK) == -1)
|
||||
{
|
||||
error(tagNode->lineNum, tagNode->fileName, "%s: %s", tagNode->values[vi], strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if(realpath(tagNode->values[vi], realpathBuf) == NULL){
|
||||
error(tagNode->lineNum, tagNode->fileName, "realpath(%s) failed: %s", tagNode->values[vi], strerror(errno));
|
||||
|
||||
if (realpath(tagNode->values[vi], realpathBuf) == NULL)
|
||||
{
|
||||
error(tagNode->lineNum, tagNode->fileName, "realpath (%s) failed: %s", tagNode->values[vi], strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool processed = false;
|
||||
for(std::list<char*>::const_iterator itInode = processedFiles.begin(); itInode != processedFiles.end(); itInode++){
|
||||
if(!strcmp(*itInode, realpathBuf)){
|
||||
for (CharList::const_iterator itInode = processedFiles.begin(); itInode != processedFiles.end(); ++itInode)
|
||||
{
|
||||
if (!strcmp(*itInode, realpathBuf))
|
||||
{
|
||||
processed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(processed){
|
||||
|
||||
if(processed)
|
||||
break;
|
||||
}
|
||||
|
||||
processedFiles.push_back(strdup(realpathBuf));
|
||||
|
||||
file = fopen(tagNode->values[vi], "r");
|
||||
if(file == NULL){
|
||||
if(file == NULL)
|
||||
{
|
||||
error(tagNode->lineNum, fileName, "failed to open file '%s': %s", tagNode->values[vi], strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
fileName = strdup(realpathBuf);
|
||||
from = nodeTree.end(); --from;
|
||||
from = nodeTree.end();
|
||||
--from;
|
||||
|
||||
ret = parseFile();
|
||||
(void) fclose(file);
|
||||
if(ret == -1)
|
||||
fclose(file);
|
||||
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
if(checkConfig(++from) == -1){
|
||||
if (checkConfig(++from) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
++vi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!requiredOptions.empty())
|
||||
if (!requiredOptions.empty())
|
||||
ret = checkRequiredOptions();
|
||||
}
|
||||
|
||||
|
|
@ -429,124 +507,150 @@ int DOTCONFDocument::setContent(const char * _fileName)
|
|||
|
||||
int DOTCONFDocument::checkRequiredOptions()
|
||||
{
|
||||
for(std::list<char*>::const_iterator ci = requiredOptions.begin(); ci != requiredOptions.end(); ci++){
|
||||
for (CharList::const_iterator ci = requiredOptions.begin(); ci != requiredOptions.end(); ++ci)
|
||||
{
|
||||
bool matched = false;
|
||||
for(std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i!=nodeTree.end(); i++){
|
||||
if(!cmp_func((*i)->name, *ci)){
|
||||
for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i)
|
||||
{
|
||||
if (!cmp_func((*i)->name, *ci))
|
||||
{
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!matched){
|
||||
|
||||
if(!matched)
|
||||
{
|
||||
error(0, NULL, "required option '%s' not specified", *ci);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DOTCONFDocument::error(int lineNum, const char * fileName_, const char * fmt, ...)
|
||||
void DOTCONFDocument::error(int lineNum, const char* fileName_, const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
size_t len = (lineNum!=0?strlen(fileName_):0) + strlen(fmt) + 50;
|
||||
char * buf = (char*)mempool->alloc(len);
|
||||
size_t len = (lineNum != 0 ? strlen(fileName_) : 0) + strlen(fmt) + 50;
|
||||
char* buf = (char*)mempool->Alloc(len);
|
||||
|
||||
if(lineNum)
|
||||
(void) snprintf(buf, len, "DOTCONF++: file '%s', line %d: %s\n", fileName_, lineNum, fmt);
|
||||
if (lineNum)
|
||||
snprintf(buf, len, "DOTCONF++: file '%s', line %d: %s\n", fileName_, lineNum, fmt);
|
||||
else
|
||||
(void) snprintf(buf, len, "DOTCONF++: %s\n", fmt);
|
||||
snprintf(buf, len, "DOTCONF++: %s\n", fmt);
|
||||
|
||||
(void) vfprintf(stderr, buf, args);
|
||||
vfprintf(stderr, buf, args);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
char * DOTCONFDocument::getSubstitution(char * macro, int lineNum)
|
||||
char* DOTCONFDocument::getSubstitution(char* macro, int lineNum)
|
||||
{
|
||||
char * buf = NULL;
|
||||
char * variable = macro+2;
|
||||
char* buf = NULL;
|
||||
char* variable = macro + 2;
|
||||
|
||||
char * endBr = strchr(macro, '}');
|
||||
char* endBr = strchr(macro, '}');
|
||||
|
||||
if(!endBr){
|
||||
if (!endBr)
|
||||
{
|
||||
error(lineNum, fileName, "unterminated '{'");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*endBr = 0;
|
||||
|
||||
char * defaultValue = strchr(variable, ':');
|
||||
char* defaultValue = strchr(variable, ':');
|
||||
|
||||
if(defaultValue){
|
||||
if (defaultValue)
|
||||
{
|
||||
*defaultValue++ = 0;
|
||||
if(*defaultValue != '-'){
|
||||
if (*defaultValue != '-')
|
||||
{
|
||||
error(lineNum, fileName, "incorrect macro substitution syntax");
|
||||
return NULL;
|
||||
}
|
||||
++defaultValue;
|
||||
if(*defaultValue == '"' || *defaultValue == '\''){
|
||||
++defaultValue;
|
||||
defaultValue[strlen(defaultValue)-1] = 0;
|
||||
}
|
||||
} else {
|
||||
defaultValue = NULL;
|
||||
}
|
||||
|
||||
char * subs = getenv(variable);
|
||||
if( subs ){
|
||||
buf = mempool->strdup(subs);
|
||||
} else {
|
||||
std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin();
|
||||
DOTCONFDocumentNode * tagNode = NULL;
|
||||
for(; i!=nodeTree.end(); i++){
|
||||
++defaultValue;
|
||||
if (*defaultValue == '"' || *defaultValue == '\'')
|
||||
{
|
||||
++defaultValue;
|
||||
defaultValue[strlen(defaultValue) - 1] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
defaultValue = NULL;
|
||||
|
||||
char* subs = getenv(variable);
|
||||
if (subs)
|
||||
buf = mempool->Strdup(subs);
|
||||
else
|
||||
{
|
||||
NodeList::iterator i = nodeTree.begin();
|
||||
DOTCONFDocumentNode* tagNode = NULL;
|
||||
for (; i != nodeTree.end(); ++i)
|
||||
{
|
||||
tagNode = *i;
|
||||
if(!cmp_func(tagNode->name, variable)){
|
||||
if(tagNode->valuesCount != 0){
|
||||
buf = mempool->strdup(tagNode->values[0]);
|
||||
if (!cmp_func(tagNode->name, variable))
|
||||
{
|
||||
if (tagNode->valuesCount != 0)
|
||||
{
|
||||
buf = mempool->Strdup(tagNode->values[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( i == nodeTree.end() ){
|
||||
if( defaultValue ){
|
||||
buf = mempool->strdup(defaultValue);
|
||||
} else {
|
||||
|
||||
if (i == nodeTree.end())
|
||||
{
|
||||
if (defaultValue)
|
||||
buf = mempool->Strdup(defaultValue);
|
||||
else
|
||||
{
|
||||
error(lineNum, fileName, "substitution not found and default value not given");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode * tagNode, int valueIndex)
|
||||
int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode* tagNode, int valueIndex)
|
||||
{
|
||||
int ret = 0;
|
||||
char * macro = tagNode->values[valueIndex];
|
||||
size_t valueLen = strlen(tagNode->values[valueIndex])+1;
|
||||
char * value = (char*)mempool->alloc(valueLen);
|
||||
char * v = value;
|
||||
char * subs = NULL;
|
||||
char* macro = tagNode->values[valueIndex];
|
||||
size_t valueLen = strlen(tagNode->values[valueIndex]) + 1;
|
||||
char* value = (char*)mempool->Alloc(valueLen);
|
||||
char* v = value;
|
||||
char* subs = NULL;
|
||||
|
||||
while(*macro){
|
||||
if(*macro == '$' && *(macro+1) == '{'){
|
||||
char * m = strchr(macro, '}');
|
||||
while (*macro)
|
||||
{
|
||||
if (*macro == '$' && *(macro + 1) == '{')
|
||||
{
|
||||
char* m = strchr(macro, '}');
|
||||
subs = getSubstitution(macro, tagNode->lineNum);
|
||||
if(subs == NULL){
|
||||
if(subs == NULL)
|
||||
{
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
macro = m + 1;
|
||||
*v = 0;
|
||||
v = (char*)mempool->alloc(strlen(value)+strlen(subs)+valueLen);
|
||||
v = (char*)mempool->Alloc(strlen(value) + strlen(subs) + valueLen);
|
||||
strcpy(v, value);
|
||||
value = strcat(v, subs);
|
||||
v = value + strlen(value);
|
||||
continue;
|
||||
}
|
||||
|
||||
*v++ = *macro++;
|
||||
}
|
||||
|
||||
*v = 0;
|
||||
|
||||
free(tagNode->values[valueIndex]);
|
||||
|
|
@ -554,47 +658,47 @@ int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode * tagNode, int valueInd
|
|||
return ret;
|
||||
}
|
||||
|
||||
const DOTCONFDocumentNode * DOTCONFDocument::getFirstNode() const
|
||||
const DOTCONFDocumentNode* DOTCONFDocument::getFirstNode() const
|
||||
{
|
||||
if ( !nodeTree.empty() ) {
|
||||
if (!nodeTree.empty())
|
||||
return *nodeTree.begin();
|
||||
} else {
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const DOTCONFDocumentNode * DOTCONFDocument::findNode(const char * nodeName, const DOTCONFDocumentNode * parentNode, const DOTCONFDocumentNode * startNode) const
|
||||
const DOTCONFDocumentNode* DOTCONFDocument::findNode(const char* nodeName, const DOTCONFDocumentNode* parentNode, const DOTCONFDocumentNode* startNode) const
|
||||
{
|
||||
NodeList::const_iterator i = nodeTree.begin();
|
||||
|
||||
|
||||
std::list<DOTCONFDocumentNode*>::const_iterator i = nodeTree.begin();
|
||||
|
||||
if(startNode == NULL)
|
||||
if (startNode == NULL)
|
||||
startNode = parentNode;
|
||||
|
||||
if(startNode != NULL){
|
||||
while( i != nodeTree.end() && (*i) != startNode ){
|
||||
if (startNode != NULL)
|
||||
{
|
||||
while (i != nodeTree.end() && (*i) != startNode)
|
||||
++i;
|
||||
|
||||
if (i != nodeTree.end())
|
||||
++i;
|
||||
}
|
||||
if( i != nodeTree.end() ) ++i;
|
||||
}
|
||||
|
||||
for(; i!=nodeTree.end(); i++){
|
||||
|
||||
if((*i)->parentNode != parentNode){
|
||||
for (; i != nodeTree.end(); ++i)
|
||||
{
|
||||
if ((*i)->parentNode != parentNode)
|
||||
continue;
|
||||
}
|
||||
if(!cmp_func(nodeName, (*i)->name)){
|
||||
|
||||
if (!cmp_func(nodeName, (*i)->name))
|
||||
return *i;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DOTCONFDocument::setRequiredOptionNames(const char ** requiredOptionNames)
|
||||
void DOTCONFDocument::setRequiredOptionNames(const char** requiredOptionNames)
|
||||
{
|
||||
while(*requiredOptionNames){
|
||||
requiredOptions.push_back(strdup( *requiredOptionNames ));
|
||||
while (*requiredOptionNames)
|
||||
{
|
||||
requiredOptions.push_back(strdup(*requiredOptionNames));
|
||||
++requiredOptionNames;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
|
||||
|
||||
#ifndef DOTCONFPP_H
|
||||
#define DOTCONFPP_H
|
||||
|
||||
|
|
@ -21,77 +18,94 @@ class DOTCONFDocument;
|
|||
|
||||
class DOTCONFDocumentNode
|
||||
{
|
||||
friend class DOTCONFDocument;
|
||||
private:
|
||||
DOTCONFDocumentNode * previousNode;
|
||||
DOTCONFDocumentNode * nextNode;
|
||||
DOTCONFDocumentNode * parentNode;
|
||||
DOTCONFDocumentNode * childNode;
|
||||
char ** values;
|
||||
int valuesCount;
|
||||
char * name;
|
||||
const DOTCONFDocument * document;
|
||||
int lineNum;
|
||||
char * fileName;
|
||||
bool closed;
|
||||
friend class DOTCONFDocument;
|
||||
|
||||
void pushValue(char * _value);
|
||||
private:
|
||||
|
||||
public:
|
||||
DOTCONFDocumentNode();
|
||||
~DOTCONFDocumentNode();
|
||||
DOTCONFDocumentNode* previousNode;
|
||||
DOTCONFDocumentNode* nextNode;
|
||||
DOTCONFDocumentNode* parentNode;
|
||||
DOTCONFDocumentNode* childNode;
|
||||
char** values;
|
||||
int valuesCount;
|
||||
char* name;
|
||||
const DOTCONFDocument* document;
|
||||
int lineNum;
|
||||
char* fileName;
|
||||
bool closed;
|
||||
|
||||
const char * getConfigurationFileName()const { return fileName; }
|
||||
int getConfigurationLineNumber() const { return lineNum; }
|
||||
void pushValue(char* _value);
|
||||
|
||||
const DOTCONFDocumentNode * getNextNode() const { return nextNode; }
|
||||
const DOTCONFDocumentNode * getPreviuosNode() const { return previousNode; }
|
||||
const DOTCONFDocumentNode * getParentNode() const { return parentNode; }
|
||||
const DOTCONFDocumentNode * getChildNode() const { return childNode; }
|
||||
const char* getValue(int index = 0) const;
|
||||
const char * getName() const { return name; }
|
||||
const DOTCONFDocument * getDocument() const { return document; }
|
||||
public:
|
||||
|
||||
DOTCONFDocumentNode();
|
||||
~DOTCONFDocumentNode();
|
||||
|
||||
const char* getConfigurationFileName() const { return fileName; }
|
||||
int getConfigurationLineNumber() const { return lineNum; }
|
||||
|
||||
const DOTCONFDocumentNode* getNextNode() const { return nextNode; }
|
||||
const DOTCONFDocumentNode* getPreviuosNode() const { return previousNode; }
|
||||
const DOTCONFDocumentNode* getParentNode() const { return parentNode; }
|
||||
const DOTCONFDocumentNode* getChildNode() const { return childNode; }
|
||||
const char* getValue(int index = 0) const;
|
||||
const char* getName() const { return name; }
|
||||
const DOTCONFDocument * getDocument() const { return document; }
|
||||
};
|
||||
|
||||
class DOTCONFDocument
|
||||
{
|
||||
public:
|
||||
enum CaseSensitive { CASESENSETIVE, CASEINSENSETIVE };
|
||||
protected:
|
||||
AsyncDNSMemPool * mempool;
|
||||
private:
|
||||
DOTCONFDocumentNode * curParent;
|
||||
DOTCONFDocumentNode * curPrev;
|
||||
int curLine;
|
||||
bool quoted;
|
||||
std::list<DOTCONFDocumentNode*> nodeTree;
|
||||
std::list<char*> requiredOptions;
|
||||
std::list<char*> processedFiles;
|
||||
FILE * file;
|
||||
char * fileName;
|
||||
std::list<char*> words;
|
||||
int (*cmp_func)(const char *, const char *);
|
||||
public:
|
||||
|
||||
int checkRequiredOptions();
|
||||
int parseLine();
|
||||
int parseFile(DOTCONFDocumentNode * _parent = NULL);
|
||||
int checkConfig(const std::list<DOTCONFDocumentNode*>::iterator & from);
|
||||
int cleanupLine(char * line);
|
||||
char * getSubstitution(char * macro, int lineNum);
|
||||
int macroSubstitute(DOTCONFDocumentNode * tagNode, int valueIndex);
|
||||
enum CaseSensitive
|
||||
{
|
||||
CASESENSITIVE,
|
||||
CASEINSENSETIVE
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual void error(int lineNum, const char * fileName, const char * fmt, ...) ATTR_PRINTF(4,5);
|
||||
protected:
|
||||
|
||||
public:
|
||||
DOTCONFDocument(CaseSensitive caseSensitivity = CASESENSETIVE);
|
||||
virtual ~DOTCONFDocument();
|
||||
AsyncDNSMemPool* mempool;
|
||||
|
||||
int setContent(const char * _fileName);
|
||||
private:
|
||||
|
||||
void setRequiredOptionNames(const char ** requiredOptionNames);
|
||||
const DOTCONFDocumentNode * getFirstNode() const;
|
||||
const DOTCONFDocumentNode * findNode(const char * nodeName, const DOTCONFDocumentNode * parentNode = NULL, const DOTCONFDocumentNode * startNode = NULL) const;
|
||||
typedef std::list<char*> CharList;
|
||||
typedef std::list<DOTCONFDocumentNode*> NodeList;
|
||||
|
||||
DOTCONFDocumentNode* curParent;
|
||||
DOTCONFDocumentNode* curPrev;
|
||||
int curLine;
|
||||
bool quoted;
|
||||
NodeList nodeTree;
|
||||
CharList requiredOptions;
|
||||
CharList processedFiles;
|
||||
FILE* file;
|
||||
char* fileName;
|
||||
CharList words;
|
||||
int (*cmp_func)(const char*, const char*);
|
||||
|
||||
int checkRequiredOptions();
|
||||
int parseLine();
|
||||
int parseFile(DOTCONFDocumentNode* _parent = NULL);
|
||||
int checkConfig(const NodeList::iterator& from);
|
||||
int cleanupLine(char* line);
|
||||
char* getSubstitution(char* macro, int lineNum);
|
||||
int macroSubstitute(DOTCONFDocumentNode* tagNode, int valueIndex);
|
||||
|
||||
protected:
|
||||
|
||||
virtual void error(int lineNum, const char* fileName, const char* fmt, ...) ATTR_PRINTF(4,5);
|
||||
|
||||
public:
|
||||
|
||||
DOTCONFDocument(CaseSensitive caseSensitivity = CASESENSITIVE);
|
||||
virtual ~DOTCONFDocument();
|
||||
|
||||
int setContent(const char* _fileName);
|
||||
|
||||
void setRequiredOptionNames(const char** requiredOptionNames);
|
||||
const DOTCONFDocumentNode * getFirstNode() const;
|
||||
const DOTCONFDocumentNode * findNode(const char* nodeName, const DOTCONFDocumentNode* parentNode = NULL, const DOTCONFDocumentNode* startNode = NULL) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
|
||||
|
||||
|
||||
#include "mempool.h"
|
||||
|
||||
AsyncDNSMemPool::PoolChunk::PoolChunk(size_t _size):
|
||||
pool(NULL), pos(0), size(_size)
|
||||
AsyncDNSMemPool::PoolChunk::PoolChunk(size_t _size)
|
||||
: pool(NULL), pos(0), size(_size)
|
||||
{
|
||||
pool = ::malloc(size);
|
||||
pool = malloc(size);
|
||||
}
|
||||
|
||||
AsyncDNSMemPool::PoolChunk::~PoolChunk()
|
||||
|
|
@ -14,87 +11,96 @@ AsyncDNSMemPool::PoolChunk::~PoolChunk()
|
|||
::free(pool);
|
||||
}
|
||||
|
||||
AsyncDNSMemPool::AsyncDNSMemPool(size_t _defaultSize):
|
||||
chunks(NULL), chunksCount(0), defaultSize(_defaultSize),
|
||||
poolUsage(0), poolUsageCounter(0)
|
||||
AsyncDNSMemPool::AsyncDNSMemPool(size_t _defaultSize)
|
||||
: chunks(NULL), chunksCount(0), defaultSize(_defaultSize),
|
||||
poolUsage(0), poolUsageCounter(0)
|
||||
{
|
||||
}
|
||||
|
||||
AsyncDNSMemPool::~AsyncDNSMemPool()
|
||||
{
|
||||
for(size_t i = 0; i<chunksCount; i++){
|
||||
for (size_t i = 0; i < chunksCount; ++i)
|
||||
delete chunks[i];
|
||||
}
|
||||
|
||||
::free(chunks);
|
||||
}
|
||||
|
||||
int AsyncDNSMemPool::initialize()
|
||||
bool AsyncDNSMemPool::initialize()
|
||||
{
|
||||
chunksCount = 1;
|
||||
chunks = (PoolChunk**)::malloc(sizeof(PoolChunk*));
|
||||
if(chunks == NULL)
|
||||
return -1;
|
||||
chunks = (PoolChunk**)malloc(sizeof(PoolChunk*));
|
||||
if (chunks == NULL)
|
||||
return false;
|
||||
|
||||
chunks[chunksCount-1] = new PoolChunk(defaultSize);
|
||||
chunks[chunksCount - 1] = new PoolChunk(defaultSize);
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void AsyncDNSMemPool::addNewChunk(size_t size)
|
||||
{
|
||||
++chunksCount;
|
||||
chunks = (PoolChunk**)::realloc(chunks, chunksCount*sizeof(PoolChunk*));
|
||||
if(size <= defaultSize)
|
||||
chunks[chunksCount-1] = new PoolChunk(defaultSize);
|
||||
|
||||
chunks = (PoolChunk**)realloc(chunks, chunksCount * sizeof(PoolChunk*));
|
||||
if (size <= defaultSize)
|
||||
chunks[chunksCount - 1] = new PoolChunk(defaultSize);
|
||||
else
|
||||
chunks[chunksCount-1] = new PoolChunk(size);
|
||||
chunks[chunksCount - 1] = new PoolChunk(size);
|
||||
}
|
||||
|
||||
void * AsyncDNSMemPool::alloc(size_t size)
|
||||
void* AsyncDNSMemPool::Alloc(size_t size)
|
||||
{
|
||||
PoolChunk * chunk = NULL;
|
||||
for(size_t i = 0; i<chunksCount; i++){
|
||||
PoolChunk* chunk = NULL;
|
||||
for (size_t i = 0; i < chunksCount; ++i)
|
||||
{
|
||||
chunk = chunks[i];
|
||||
if((chunk->size - chunk->pos) >= size){
|
||||
if ((chunk->size - chunk->pos) >= size)
|
||||
{
|
||||
chunk->pos += size;
|
||||
return ((char*)chunk->pool) + chunk->pos - size;
|
||||
}
|
||||
}
|
||||
|
||||
addNewChunk(size);
|
||||
chunks[chunksCount-1]->pos = size;
|
||||
return chunks[chunksCount-1]->pool;
|
||||
chunks[chunksCount - 1]->pos = size;
|
||||
return chunks[chunksCount - 1]->pool;
|
||||
}
|
||||
|
||||
void AsyncDNSMemPool::free()
|
||||
void AsyncDNSMemPool::Free()
|
||||
{
|
||||
size_t pu = 0;
|
||||
size_t psz = 0;
|
||||
++poolUsageCounter;
|
||||
|
||||
for(size_t i = 0; i<chunksCount; i++){
|
||||
for (size_t i = 0; i < chunksCount; ++i)
|
||||
{
|
||||
pu += chunks[i]->pos;
|
||||
psz += chunks[i]->size;
|
||||
chunks[i]->pos = 0;
|
||||
}
|
||||
poolUsage=(poolUsage>pu)?poolUsage:pu;
|
||||
|
||||
if(poolUsageCounter >= 10 && chunksCount > 1){
|
||||
psz -= chunks[chunksCount-1]->size;
|
||||
if(poolUsage < psz){
|
||||
poolUsage = poolUsage > pu ? poolUsage : pu;
|
||||
|
||||
if (poolUsageCounter >= 10 && chunksCount > 1)
|
||||
{
|
||||
psz -= chunks[chunksCount - 1]->size;
|
||||
if (poolUsage < psz)
|
||||
{
|
||||
--chunksCount;
|
||||
delete chunks[chunksCount];
|
||||
}
|
||||
|
||||
poolUsage = 0;
|
||||
poolUsageCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void * AsyncDNSMemPool::calloc(size_t size)
|
||||
void* AsyncDNSMemPool::Calloc(size_t size)
|
||||
{
|
||||
return ::memset(this->alloc(size), 0, size);
|
||||
return ::memset(Alloc(size), 0, size);
|
||||
}
|
||||
|
||||
char * AsyncDNSMemPool::strdup(const char *str)
|
||||
char* AsyncDNSMemPool::Strdup(const char *str)
|
||||
{
|
||||
return ::strcpy((char*)this->alloc(strlen(str)+1), str);
|
||||
return ::strcpy((char*)Alloc(strlen(str) + 1), str);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
|
||||
|
||||
#ifndef ASYNC_DNS_MEMPOOL_H
|
||||
#define ASYNC_DNS_MEMPOOL_H
|
||||
|
||||
|
|
@ -8,39 +5,39 @@
|
|||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#undef free
|
||||
#undef calloc
|
||||
#undef strdup
|
||||
|
||||
class AsyncDNSMemPool
|
||||
{
|
||||
private:
|
||||
struct PoolChunk {
|
||||
void * pool;
|
||||
size_t pos;
|
||||
size_t size;
|
||||
private:
|
||||
|
||||
PoolChunk(size_t _size);
|
||||
~PoolChunk();
|
||||
};
|
||||
PoolChunk ** chunks;
|
||||
size_t chunksCount;
|
||||
size_t defaultSize;
|
||||
struct PoolChunk
|
||||
{
|
||||
void* pool;
|
||||
size_t pos;
|
||||
size_t size;
|
||||
|
||||
size_t poolUsage;
|
||||
size_t poolUsageCounter;
|
||||
PoolChunk(size_t _size);
|
||||
~PoolChunk();
|
||||
};
|
||||
|
||||
void addNewChunk(size_t size);
|
||||
PoolChunk** chunks;
|
||||
size_t chunksCount;
|
||||
size_t defaultSize;
|
||||
|
||||
public:
|
||||
AsyncDNSMemPool(size_t _defaultSize = 4096);
|
||||
virtual ~AsyncDNSMemPool();
|
||||
size_t poolUsage;
|
||||
size_t poolUsageCounter;
|
||||
|
||||
int initialize();
|
||||
void free();
|
||||
void * alloc(size_t size);
|
||||
void * calloc(size_t size);
|
||||
char * strdup(const char *str);
|
||||
void addNewChunk(size_t size);
|
||||
|
||||
public:
|
||||
|
||||
AsyncDNSMemPool(size_t _defaultSize = 4096);
|
||||
virtual ~AsyncDNSMemPool();
|
||||
|
||||
bool initialize();
|
||||
void Free();
|
||||
void* Alloc(size_t size);
|
||||
void* Calloc(size_t size);
|
||||
char* Strdup(const char *str);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "8644"
|
||||
#define REVISION_NR "8645"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue