📄 dotconfpp.cpp
字号:
#include "ace_ext_export.h"#include "dotconfpp.h"#if !defined(R_OK)#define R_OK 04#endifDOTCONFDocumentNode::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++){ free(values[i]); } free(values); }}void DOTCONFDocumentNode::pushValue(char * _value){ valuesCount++; values = (char**)realloc(values, valuesCount*sizeof(char*)); values[valuesCount-1] = strdup(_value);}const char* DOTCONFDocumentNode::getValue(int index) const{ 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){ if(caseSensitivity == CASESENSETIVE){ cmp_func = strcmp; } else { cmp_func = strcasecmp; } mempool = new AsyncDNSMemPool(1024); mempool->initialize();}DOTCONFDocument::~DOTCONFDocument(){ for(std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i != nodeTree.end(); i++){ delete(*i); } for(std::list<char*>::iterator i = requiredOptions.begin(); i != requiredOptions.end(); i++){ free(*i); } for(std::list<char*>::iterator i = processedFiles.begin(); i != processedFiles.end(); i++){ free(*i); } free(fileName); delete mempool;}int DOTCONFDocument::cleanupLine(char * line){ char * start = line; char * bg = line; bool multiline = false; bool concat = false; char * word = NULL; if(!words.empty() && quoted) concat = true; while(*line){ if((*line == '#' || *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); } words.push_back(word); } break; } 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) == '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); } words.push_back(word); } multiline = true; break; } if(*line == '"' || *line == '\''){ quoted = !quoted; line++; continue; } if(isspace(*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); } words.push_back(word); } start = bg; while(isspace(*++line)); continue; } *bg++ = *line++; } if(quoted && !multiline){ error(curLine, fileName, "unterminated quote"); return -1; } return multiline?1:0;}int DOTCONFDocument::parseLine(){ 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++) { word = *i; if(*word == '<'){ newNode = true; } if(newNode){ nodeValue = NULL; nodeName = NULL; newNode = false; } size_t wordLen = strlen(word); if(word[wordLen-1] == '>'){ word[wordLen-1] = 0; newNode = true; } if(nodeName == NULL){ nodeName = word; bool closed = true; 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){ (*itr)->closed = true; curParent = (*itr)->parentNode; curPrev = *itr; break; } } 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){ curPrev->nextNode = tagNode; tagNode->previousNode = curPrev; tagNode->parentNode = curParent; } else { prev->childNode = tagNode; tagNode->parentNode = prev; curParent = prev; } } nodeTree.push_back(tagNode); curPrev = tagNode; } else { nodeValue = word; tagNode->pushValue(nodeValue); } } return 0;}int DOTCONFDocument::parseFile(DOTCONFDocumentNode * _parent){ char str[512]; int ret = 0; curLine = 0; curParent = _parent; quoted = false; size_t slen = 0; while(fgets(str, 511, file)){ curLine++; 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((ret = cleanupLine(str)) == -1){ break; } if(ret == 0){ if(!words.empty()){ ret = parseLine(); mempool->free(); words.clear(); if(ret == -1){ break; } } } } return ret;}int DOTCONFDocument::checkConfig(const std::list<DOTCONFDocumentNode*>::iterator & from){ int ret = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -