📄 dotconfpp.cpp
字号:
DOTCONFDocumentNode * tagNode = NULL; int vi = 0; for(std::list<DOTCONFDocumentNode*>::iterator i = from; i != nodeTree.end(); i++){ tagNode = *i; 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){ break; } } vi++; } if(ret == -1){ break; } } return ret;}int DOTCONFDocument::setContent(const char * _fileName){ int ret = 0; char realpathBuf[PATH_MAX]; if (!_fileName || strlen(_fileName) == 0) _fileName = ACE_EXT_CONF_FILE; if(realpath(_fileName, realpathBuf) == NULL){ error(0, NULL, "realpath(%s) failed: %s", _fileName, strerror(errno)); return -1; } fileName = strdup(realpathBuf); processedFiles.push_back(strdup(realpathBuf)); if(( file = fopen(fileName, "r")) == NULL){ error(0, NULL, "failed to open file '%s': %s", fileName, strerror(errno)); return -1; } ret = parseFile(); (void) fclose(file); if(!ret){ if( (ret = checkConfig(nodeTree.begin())) == -1){ return -1; } std::list<DOTCONFDocumentNode*>::iterator from; DOTCONFDocumentNode * tagNode = NULL; int vi = 0; for(std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i!=nodeTree.end(); i++){ tagNode = *i; if(!cmp_func("DOTCONFPPIncludeFile", tagNode->name)){ vi = 0; 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)); return -1; } bool processed = false; for(std::list<char*>::const_iterator itInode = processedFiles.begin(); itInode != processedFiles.end(); itInode++){ if(!strcmp(*itInode, realpathBuf)){ processed = true; break; } } if(processed){ break; } processedFiles.push_back(strdup(realpathBuf)); file = fopen(tagNode->values[vi], "r"); 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--; ret = parseFile(); (void) fclose(file); if(ret == -1) return -1; if(checkConfig(++from) == -1){ return -1; } vi++; } } } if(!requiredOptions.empty()) ret = checkRequiredOptions(); } return ret;}int DOTCONFDocument::checkRequiredOptions(){ for(std::list<char*>::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)){ matched = true; break; } } 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, ...){ va_list args; va_start(args, fmt); 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); else (void) snprintf(buf, len, "DOTCONF++: %s\n", fmt); (void) vfprintf(stderr, buf, args); va_end(args);}char * DOTCONFDocument::getSubstitution(char * macro, int lineNum){ char * buf = NULL; char * variable = macro+2; char * endBr = strchr(macro, '}'); if(!endBr){ error(lineNum, fileName, "unterminated '{'"); return NULL; } *endBr = 0; char * defaultValue = strchr(variable, ':'); if(defaultValue){ *defaultValue++ = 0; 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++){ tagNode = *i; 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 { error(lineNum, fileName, "substitution not found and default value not given"); return NULL; } } } return buf;}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; while(*macro){ if(*macro == '$' && *(macro+1) == '{'){ char * m = strchr(macro, '}'); subs = getSubstitution(macro, tagNode->lineNum); if(subs == NULL){ ret = -1; break; } macro = m + 1; *v = 0; 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]); tagNode->values[valueIndex] = strdup(value); return ret;}const DOTCONFDocumentNode * DOTCONFDocument::getFirstNode() const{ if ( !nodeTree.empty() ) { return *nodeTree.begin(); } else { return NULL; }}const DOTCONFDocumentNode * DOTCONFDocument::findNode(const char * nodeName, const DOTCONFDocumentNode * parentNode, const DOTCONFDocumentNode * startNode) const{ std::list<DOTCONFDocumentNode*>::const_iterator i = nodeTree.begin(); if(startNode == NULL) startNode = parentNode; if(startNode != NULL){ while( i != nodeTree.end() && (*i) != startNode ){ i++; } if( i != nodeTree.end() ) i++; } for(; i!=nodeTree.end(); i++){ if((*i)->parentNode != parentNode){ continue; } if(!cmp_func(nodeName, (*i)->name)){ return *i; } } return NULL;}void DOTCONFDocument::setRequiredOptionNames(const char ** requiredOptionNames){ while(*requiredOptionNames){ requiredOptions.push_back(strdup( *requiredOptionNames )); requiredOptionNames++; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -