Commit 63235799 authored by jan.koester's avatar jan.koester
Browse files

test

parent f7f568ef
Loading
Loading
Loading
Loading
+64 −93
Original line number Diff line number Diff line
@@ -67,64 +67,54 @@ void confplus::Yaml::saveConfig(const char *path,const Config *conf){


void confplus::Yaml::loadConfig(const char *path,Config *conf){
    FILE* fh = nullptr;
    yaml_event_type_t type = YAML_NO_EVENT;
    FILE *fh = fopen(path,"rb");
    yaml_event_type_t type;
    yaml_parser_t parse;
    bool parser_initialized = false;
    std::string key, value;

    // FIX C2362: ystack muss vor dem ersten goto initialisiert werden.
    std::unique_ptr<YamlStack> ystack = nullptr;

     /* Initialize parser */

    if(fh == nullptr){
        throw "Failed to open file!";
    }

    if(!yaml_parser_initialize(&parse))
        throw "Failed to initialize parser!";
    parser_initialized = true;

    fh = fopen(path, "rb");
    if (fh == nullptr)
        goto cleanup; // Springt bei Fehler zum Cleanup

    /* Set input file */
    yaml_parser_set_input_file(&parse, fh);

    std::unique_ptr<YamlStack> ystack=nullptr;

    bool seq=false;
    std::string key,value;
    int pos = 0;
    do {
        yaml_event_t event;
        if (!yaml_parser_parse(&parse, &event))
            goto cleanup; // Springt bei Parser-Fehler zum Cleanup
            break;

        switch (event.type) {
            case YAML_MAPPING_START_EVENT: {
            std::unique_ptr<YamlStack> cystack = std::make_unique<YamlStack>();
                    std::unique_ptr<YamlStack> cystack(new YamlStack);
                    cystack->prevel=std::move(ystack);
                    ystack=std::move(cystack);
                    ystack->anchor=key;
                    key=value;
            value = ""; // FIX: Explizite Zuweisung
                    value.clear();
            }break;

            case YAML_MAPPING_END_EVENT:{
            if (ystack) {
                if(ystack->prevel){
                    ystack=std::move(ystack->prevel);
                }
            }break;


            case YAML_SCALAR_EVENT:{
            // FIX: Sichere String-Extraktion durch direkte Konstruktion.
            std::string temp_data(
                (const char*)event.data.scalar.value,
                event.data.scalar.length
            );

            if (key.empty()) {
                key = temp_data;
            }
            else {
                value = temp_data;
            }
                if(key.empty())
                    std::copy(event.data.scalar.value,event.data.scalar.value+event.data.scalar.length,std::inserter<std::string>(key,std::begin(key)));
                else
                    std::copy(event.data.scalar.value,event.data.scalar.value+event.data.scalar.length,std::inserter<std::string>(value,std::begin(value)));
            }break;

            case YAML_SEQUENCE_START_EVENT:{
@@ -135,7 +125,7 @@ void confplus::Yaml::loadConfig(const char* path, Config* conf) {
                seq=false;
                key=value;
                pos=0;
            value = ""; // FIX: Explizite Zuweisung
                value.clear();
            }break;

            default:
@@ -143,29 +133,21 @@ void confplus::Yaml::loadConfig(const char* path, Config* conf) {
        }

        if(!key.empty() && !value.empty()){
            std::vector<std::string> path_segments;
            for (YamlStack* curst = ystack.get(); curst; curst = curst->prevel.get()) {
                path_segments.push_back(curst->anchor);
            }

            // FIX: Korrekte Pfadkonstruktion (Root zu Leaf)
            std::string cname;
            for (auto it = path_segments.rbegin(); it != path_segments.rend(); ++it) {
                if (!it->empty()) {
                    cname += "/";
                    cname += *it;
                }
            for(YamlStack *curst=ystack.get(); curst; curst=curst->prevel.get()){
                std::string pp=curst->anchor; pp+='/';
                std::copy(pp.begin(),pp.end(),std::inserter<std::string>(cname,std::begin(cname)));
            }
            cname += "/";
            cname+=key;

            Config::ConfigData *ckey=conf->setKey(cname);

            std::cout << cname << "=" << value << std::endl;

            conf->setValue(ckey,pos,value);
            value = ""; // FIX: Explizite Zuweisung
            value.clear();
            if(!seq){
                key = ""; // FIX: Explizite Zuweisung
            }
            else {
                key.clear();
            }else{
                ++pos;
            }
        }
@@ -173,17 +155,6 @@ void confplus::Yaml::loadConfig(const char* path, Config* conf) {
        yaml_event_delete(&event);
    } while (type!= YAML_STREAM_END_EVENT);

cleanup:
    // Garantiertes Cleanup der C-Ressourcen
    if (parser_initialized) {
    yaml_parser_delete(&parse);
    }
    if (fh != nullptr) {
    fclose(fh);
}

    // Fehler werfen nur, wenn das ffnen der Datei nach der Parser-Initialisierung fehlschlug
    if (fh == nullptr && parser_initialized) {
        throw "Failed to open file!";
    }
}
 No newline at end of file
+9 −42
Original line number Diff line number Diff line
@@ -61,8 +61,7 @@ GETKEYSEARCH:
                          return cdat;
                    }
                    cdat=cdat->Child.get();
                    ++pos;
                    start=pos;
                    start=++pos;
                    match=true;
                    goto GETKEYSEARCH;
                }
@@ -73,27 +72,10 @@ GETKEYSEARCH:
        }
        ++pos;
    }
    ConfException exp;
    exp[ConfException::Error] << "Config: key not found";
    throw exp;
    return (confplus::Config::ConfigData*)nullptr;
}

confplus::Config::ConfigData *confplus::Config::setKey(const std::string &key){

    auto createdat = [] (std::unique_ptr<ConfigData> &root){
        std::unique_ptr<ConfigData> *current_ptr = &root;

        // Traverse the unique_ptr chain to find the last element
        while(current_ptr->get()){
            current_ptr = &current_ptr->get()->nextData;
        }

        // current_ptr now points to the unique_ptr at the end of the list (which is nullptr)
        *current_ptr = std::unique_ptr<ConfigData>(new ConfigData);

        return current_ptr->get();
    };

    auto existsdat = [] (ConfigData *search,const std::string ckey){
        while(search){
            if(search->Key==ckey){
@@ -119,8 +101,7 @@ confplus::Config::ConfigData *confplus::Config::setKey(const std::string &key){
    while(pos<=key.length()){
        if(key[pos]=='/' || key[pos]=='\0'){

            std::string childkey;
            std::copy(&key[start], &key[pos], std::back_inserter(childkey));
            std::string childkey = key.substr(start, pos - start);
            start=(pos+1);

            find = existsdat(root_ptr->get(), childkey);
@@ -132,10 +113,10 @@ confplus::Config::ConfigData *confplus::Config::setKey(const std::string &key){
                    current_ptr = &current_ptr->get()->nextData;
                }

                *current_ptr = std::unique_ptr<ConfigData>(new ConfigData); // Konstruktor mit Key/Daten
                *current_ptr = std::unique_ptr<ConfigData>(new ConfigData);

                find = current_ptr->get();

                find->Key = childkey;
            }
            root_ptr = &find->Child;
        }
@@ -340,41 +321,27 @@ int confplus::Config::getIntValue(confplus::Config::ConfigData* key, size_t pos)
}

void confplus::Config::setValue(confplus::Config::ConfigData *key, size_t pos, const std::string& value) {
    // 1. Prfen, ob es sich um einen Pfad handelt
    if (key->haveChild) {
        ConfException err;
        err[ConfException::Error] << "setValue it is a path not key";
        throw err;
    }

    // 2. Bestehenden Wert an 'pos' suchen und aktualisieren
    for (ConfigValue* cur = key->Value.get(); cur; cur = cur->_nextValue.get()) {
        if (cur->_Pos == pos) {
            cur->_Value = value;
            return; // Gefunden und aktualisiert
            return;
        }
    }

    // 3. Wenn der Wert nicht existiert, ihn am Ende anfgen.

    // Fall A: Die Liste ist leer (Kopf ist null).
    if (!key->Value) {
        // Setze den Kopfzeiger direkt
        key->Value = std::make_unique<ConfigValue>(value, pos);
    }
    else {
        // Fall B: Die Liste ist nicht leer. Finde das letzte Element.

        // Verwende einen Raw-Pointer zur Traversierung.
    } else {
        ConfigValue* last = key->Value.get();

        // Durchlaufe die Kette, solange _nextValue existiert.
        while (last->_nextValue) {
            last = last->_nextValue.get();
        }

        // Hnge das neue Objekt an den _nextValue-Smart Pointer des letzten Elements an.
        // Der Compiler verwendet hier std::move fr eine sichere Zuweisung.
        last->_nextValue = std::make_unique<ConfigValue>(value, pos);
    }
}