]> git.stg.codes - stg.git/blobdiff - stglibs/dotconfpp.lib/dotconfpp.cpp
Port to CMake, get rid of os_int.h.
[stg.git] / stglibs / dotconfpp.lib / dotconfpp.cpp
diff --git a/stglibs/dotconfpp.lib/dotconfpp.cpp b/stglibs/dotconfpp.lib/dotconfpp.cpp
deleted file mode 100644 (file)
index 8f766f0..0000000
+++ /dev/null
@@ -1,664 +0,0 @@
-/*  Copyright (C) 2003 Aleksey Krivoshey <krivoshey@users.sourceforge.net>
-*
-*   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 <libgen.h> // dirname
-#include <glob.h> // glob
-#include <string>
-
-#include "stg/dotconfpp.h"
-#include "mempool.h"
-
-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++){
-            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), errorCallback(NULL), errorCallbackData(NULL),
-    curLine(0), file(NULL), fileName(NULL)
-{
-    if(caseSensitivity == CASESENSITIVE){
-        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)){
-                //printf("2start='%s'\n", 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){ // 'parameter = value' is the same as 'parameter value' but do not replace with ' ' when used in quoted value
-            *line = ' ';continue;
-        }
-        if(*line == '\\' && (*(line+1) == '"' || *(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')){ //multiline
-            *bg = 0;
-            if(strlen(start)){
-                //printf("3start='%s'\n", 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 == '\''){ //need to handle quotes because of spaces or = that may be between
-            quoted = !quoted;
-            line++; continue;
-        }
-        if(isspace(*line) && !quoted){
-            *bg++ = 0;
-            if(strlen(start)){
-                //printf("start='%s'\n", 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 this not <> node then it is closed by default
-            if(*nodeName == '<'){
-                if(*(nodeName+1) != '/'){ //opening tag
-                    nodeName++;
-                    closed = false;
-                } else { //closing tag
-                    nodeName+=2;
-                    std::list<DOTCONFDocumentNode*>::reverse_iterator i=nodeTree.rbegin();
-                    for(; i!=nodeTree.rend(); ++i){
-                        if(!cmp_func(nodeName, (*i)->name) && !(*i)->closed){
-                            (*i)->closed = true;
-                            curParent = (*i)->parentNode;
-                            curPrev = *i;
-                            break;
-                        }
-                    }
-                    if(i==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;
-
-    while(fgets(str, 511, file)){
-        curLine++;
-       size_t 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;
-
-    for(std::list<DOTCONFDocumentNode*>::iterator i = from; i != nodeTree.end(); ++i){
-        DOTCONFDocumentNode * tagNode = *i;
-        if(!tagNode->closed){
-            error(tagNode->lineNum, tagNode->fileName, "unclosed tag %s", tagNode->name);
-            ret = -1;
-            break;
-        }
-        int vi = 0;
-        while( vi < tagNode->valuesCount ){
-            //if((tagNode->values[vi])[0] == '$' && (tagNode->values[vi])[1] == '{' && strchr(tagNode->values[vi], '}') ){
-            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(realpath(_fileName, realpathBuf) == NULL){
-        error(0, _fileName, "%s", strerror(errno));
-        return -1;
-    }
-
-    fileName = strdup(realpathBuf);
-
-    char * forPathName = strdup(realpathBuf);
-
-    if (forPathName == NULL) {
-        error(0, NULL, "Not enought memory to duplicate realpath");
-        return -1;
-    }
-
-    char * _pathName = dirname(forPathName);
-
-    std::string pathName(_pathName);
-
-    free(forPathName); // From strdup
-
-    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("IncludeFile", tagNode->name)){
-                vi = 0;
-                while( vi < tagNode->valuesCount ){
-                    glob_t globBuf;
-                    std::string nodeFilePath;
-                    if (*tagNode->values[vi] != '/') {
-                        // Relative path
-                        nodeFilePath = pathName + "/" + tagNode->values[vi];
-                    } else {
-                        // Absolute path
-                       nodeFilePath = tagNode->values[vi];
-                    }
-                    int res = glob(nodeFilePath.c_str(), 0, NULL, &globBuf);
-                    if (res) {
-                        switch (res) {
-                            case GLOB_NOSPACE:
-                                error(tagNode->lineNum, tagNode->fileName, "glob call failed for '%s': no free space", nodeFilePath.c_str());
-                                return -1;
-#ifndef FREE_BSD
-                            case GLOB_ABORTED:
-                                // printf("Read error\n");
-                                // Ignore that error
-                                break;
-                            case GLOB_NOMATCH:
-                                // printf("No match\n");
-                                // Ignore that error
-                                break;
-#endif
-                            default:
-                                error(tagNode->lineNum, tagNode->fileName, "glob call failed for '%s': unknown error", nodeFilePath.c_str());
-                                return -1;
-                        }
-                    }
-                    if (!res) {
-                        for (size_t i = 0; i < globBuf.gl_pathc; ++i) {
-                            std::string nodeFilePath(globBuf.gl_pathv[i]);
-                            if(access(nodeFilePath.c_str(), R_OK) == -1){
-                                error(tagNode->lineNum, tagNode->fileName, "%s: %s", nodeFilePath.c_str(), strerror(errno));
-                                continue;
-                            }
-                            if(realpath(nodeFilePath.c_str(), realpathBuf) == NULL){
-                                error(tagNode->lineNum, tagNode->fileName, "realpath(%s) failed: %s", nodeFilePath.c_str(), strerror(errno));
-                                continue;
-                            }
-
-                            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(nodeFilePath.c_str(), "r");
-                            if(file == NULL){
-                                error(tagNode->lineNum, fileName, "failed to open file '%s': %s", nodeFilePath.c_str(), strerror(errno));
-                                continue;
-                            }
-                            //free(fileName);
-                            fileName = strdup(realpathBuf);
-                            from = nodeTree.end(); --from;
-                            
-                            if(tagNode->parentNode){
-                                DOTCONFDocumentNode * nd = tagNode->parentNode->childNode;
-                                while(nd){
-                                    if(!nd->nextNode)
-                                        break;
-                                    nd = nd->nextNode;
-                                }
-
-                                curPrev = nd;
-                            }
-                            ret = parseFile(tagNode->parentNode);
-                            
-                            //ret = parseFile(tagNode->parentNode);
-                            (void) fclose(file);
-                            if(ret == -1)
-                                continue;
-                            if(checkConfig(++from) == -1){
-                                continue;
-                            }
-                        }
-                    }
-                    globfree(&globBuf);
-                    vi++;
-                }
-            }
-        }
-        /*
-        if( (ret = checkConfig(nodeTree.begin())) == -1){
-            return -1;
-        }
-        */
-
-        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);
-
-    char msg[256];
-
-    vsnprintf(msg, 256, fmt, args);
-
-    size_t len = (lineNum!=0?strlen(fileName):0) + strlen(msg) + 50;
-    char * buf = (char*)mempool->alloc(len);
-
-    if(lineNum)
-        (void) snprintf(buf, len, "File '%s', line %d: %s\n", fileName, lineNum, msg);
-    else
-        (void) snprintf(buf, len, "File '%s':  %s\n", fileName, msg);
-
-    if (errorCallback) {
-        errorCallback(errorCallbackData, buf);
-    } else {
-        (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();
-        for(; i!=nodeTree.end(); ++i){            
-            DOTCONFDocumentNode * 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
-{
-    //printf("nodeName=%s, cont=%s, start=%s\n", nodeName, containingNode!=NULL?containingNode->name:"NULL", startNode!=NULL?startNode->name:"NULL");
-    
-    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(parentNode != NULL && (*i)->parentNode != parentNode){
-       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++;
-    }
-}
-