Switch to unified view

a/src/conftree.cpp b/src/conftree.cpp
...
...
40
#include <sstream>
40
#include <sstream>
41
#include <utility>
41
#include <utility>
42
42
43
#include "pathut.h"
43
#include "pathut.h"
44
#include "smallut.h"
44
#include "smallut.h"
45
#include "log.h"
45
46
46
using namespace std;
47
using namespace std;
47
48
48
#undef DEBUG
49
#undef DEBUG_CONFTREE
49
#ifdef DEBUG
50
#ifdef DEBUG_CONFTREE
50
#define LOGDEB(X) fprintf X
51
#define CONFDEB LOGDEB
51
#else
52
#else
52
#define LOGDEB(X)
53
#define CONFDEB LOGDEB2
53
#endif
54
#endif
54
55
55
static const SimpleRegexp varcomment_rx("[ \t]*#[ \t]*([a-zA-Z0-9]+)[ \t]*=",
56
static const SimpleRegexp varcomment_rx("[ \t]*#[ \t]*([a-zA-Z0-9]+)[ \t]*=",
56
                                        0, 1);
57
                                        0, 1);
57
58
...
...
64
    bool eof = false;
65
    bool eof = false;
65
66
66
    for (;;) {
67
    for (;;) {
67
        cline.clear();
68
        cline.clear();
68
        std::getline(input, cline);
69
        std::getline(input, cline);
69
        LOGDEB((stderr, "Parse:line: [%s] status %d\n",
70
        CONFDEB("Parse:line: ["  << cline << "] status "  << status << "\n");
70
                cline.c_str(), int(status)));
71
        if (!input.good()) {
71
        if (!input.good()) {
72
            if (input.bad()) {
72
            if (input.bad()) {
73
                LOGDEB((stderr, "Parse: input.bad()\n"));
73
                CONFDEB("Parse: input.bad()\n");
74
                status = STATUS_ERROR;
74
                status = STATUS_ERROR;
75
                return;
75
                return;
76
            }
76
            }
77
            LOGDEB((stderr, "Parse: eof\n"));
77
            CONFDEB("Parse: eof\n");
78
            // Must be eof ? But maybe we have a partial line which
78
            // Must be eof ? But maybe we have a partial line which
79
            // must be processed. This happens if the last line before
79
            // must be processed. This happens if the last line before
80
            // eof ends with a backslash, or there is no final \n
80
            // eof ends with a backslash, or there is no final \n
81
            eof = true;
81
            eof = true;
82
        }
82
        }
...
...
336
                    const string& sk)
336
                    const string& sk)
337
{
337
{
338
    if (status  != STATUS_RW) {
338
    if (status  != STATUS_RW) {
339
        return 0;
339
        return 0;
340
    }
340
    }
341
    LOGDEB((stderr, "ConfSimple::set [%s]:[%s] -> [%s]\n", sk.c_str(),
341
    CONFDEB("ConfSimple::set ["<<sk<< "]:[" << nm << "] -> [" << value << "]\n");
342
            nm.c_str(), value.c_str()));
343
    if (!i_set(nm, value, sk)) {
342
    if (!i_set(nm, value, sk)) {
344
        return 0;
343
        return 0;
345
    }
344
    }
346
    return write();
345
    return write();
347
}
346
}
...
...
356
// set, we're doing initial parsing, else we are changing a parsed
355
// set, we're doing initial parsing, else we are changing a parsed
357
// tree (changes the way we update the order data)
356
// tree (changes the way we update the order data)
358
int ConfSimple::i_set(const std::string& nm, const std::string& value,
357
int ConfSimple::i_set(const std::string& nm, const std::string& value,
359
                      const string& sk, bool init)
358
                      const string& sk, bool init)
360
{
359
{
361
    LOGDEB((stderr, "ConfSimple::i_set: nm[%s] val[%s] key[%s], init %d\n",
360
    CONFDEB("ConfSimple::i_set: nm[" << nm << "] val[" << value <<
362
            nm.c_str(), value.c_str(), sk.c_str(), init));
361
            "] key[" << sk << "], init " << init << "\n");
363
    // Values must not have embedded newlines
362
    // Values must not have embedded newlines
364
    if (value.find_first_of("\n\r") != string::npos) {
363
    if (value.find_first_of("\n\r") != string::npos) {
365
        LOGDEB((stderr, "ConfSimple::i_set: LF in value\n"));
364
        CONFDEB("ConfSimple::i_set: LF in value\n");
366
        return 0;
365
        return 0;
367
    }
366
    }
368
    bool existing = false;
367
    bool existing = false;
369
    map<string, map<string, string> >::iterator ss;
368
    map<string, map<string, string> >::iterator ss;
370
    // Test if submap already exists, else create it, and insert variable:
369
    // Test if submap already exists, else create it, and insert variable:
371
    if ((ss = m_submaps.find(sk)) == m_submaps.end()) {
370
    if ((ss = m_submaps.find(sk)) == m_submaps.end()) {
372
        LOGDEB((stderr, "ConfSimple::i_set: new submap\n"));
371
        CONFDEB("ConfSimple::i_set: new submap\n");
373
        map<string, string> submap;
372
        map<string, string> submap;
374
        submap[nm] = value;
373
        submap[nm] = value;
375
        m_submaps[sk] = submap;
374
        m_submaps[sk] = submap;
376
375
377
        // Maybe add sk entry to m_order data, if not already there.
376
        // Maybe add sk entry to m_order data, if not already there.
...
...
396
        }
395
        }
397
    }
396
    }
398
397
399
    // If the variable already existed, no need to change the m_order data
398
    // If the variable already existed, no need to change the m_order data
400
    if (existing) {
399
    if (existing) {
401
        LOGDEB((stderr, "ConfSimple::i_set: existing var: no order update\n"));
400
        CONFDEB("ConfSimple::i_set: existing var: no order update\n");
402
        return 1;
401
        return 1;
403
    }
402
    }
404
403
405
    // Add the new variable at the end of its submap in the order data.
404
    // Add the new variable at the end of its submap in the order data.
406
405
407
    if (init) {
406
    if (init) {
408
        // During the initial construction, just append:
407
        // During the initial construction, just append:
409
        LOGDEB((stderr, "ConfSimple::i_set: init true: append\n"));
408
        CONFDEB("ConfSimple::i_set: init true: append\n");
410
        m_order.push_back(ConfLine(ConfLine::CFL_VAR, nm));
409
        m_order.push_back(ConfLine(ConfLine::CFL_VAR, nm));
411
        return 1;
410
        return 1;
412
    }
411
    }
413
412
414
    // Look for the start and end of the subkey zone. Start is either
413
    // Look for the start and end of the subkey zone. Start is either
...
...
416
    // entry. End is either the next subkey entry, or the end of
415
    // entry. End is either the next subkey entry, or the end of
417
    // list. We insert the new entry just before end.
416
    // list. We insert the new entry just before end.
418
    vector<ConfLine>::iterator start, fin;
417
    vector<ConfLine>::iterator start, fin;
419
    if (sk.empty()) {
418
    if (sk.empty()) {
420
        start = m_order.begin();
419
        start = m_order.begin();
421
        LOGDEB((stderr, "ConfSimple::i_set: null sk, start at top of order\n"));
420
        CONFDEB("ConfSimple::i_set: null sk, start at top of order\n");
422
    } else {
421
    } else {
423
        start = find(m_order.begin(), m_order.end(),
422
        start = find(m_order.begin(), m_order.end(),
424
                     ConfLine(ConfLine::CFL_SK, sk));
423
                     ConfLine(ConfLine::CFL_SK, sk));
425
        if (start == m_order.end()) {
424
        if (start == m_order.end()) {
426
            // This is not logically possible. The subkey must
425
            // This is not logically possible. The subkey must
...
...
570
                return false;
569
                return false;
571
            }
570
            }
572
            break;
571
            break;
573
        case ConfLine::CFL_SK:
572
        case ConfLine::CFL_SK:
574
            sk = it->m_data;
573
            sk = it->m_data;
575
            LOGDEB((stderr, "ConfSimple::write: SK [%s]\n", sk.c_str()));
574
            CONFDEB("ConfSimple::write: SK ["  << sk << "]\n");
576
            // Check that the submap still exists, and only output it if it
575
            // Check that the submap still exists, and only output it if it
577
            // does
576
            // does
578
            if (m_submaps.find(sk) != m_submaps.end()) {
577
            if (m_submaps.find(sk) != m_submaps.end()) {
579
                out << "[" << it->m_data << "]" << endl;
578
                out << "[" << it->m_data << "]" << endl;
580
                if (!out.good()) {
579
                if (!out.good()) {
...
...
582
                }
581
                }
583
            }
582
            }
584
            break;
583
            break;
585
        case ConfLine::CFL_VAR:
584
        case ConfLine::CFL_VAR:
586
            string nm = it->m_data;
585
            string nm = it->m_data;
587
            LOGDEB((stderr, "ConfSimple::write: VAR [%s], sk [%s]\n",
586
            CONFDEB("ConfSimple::write: VAR [" << nm << "], sk [" <<sk<< "]\n");
588
                    nm.c_str(), sk.c_str()));
589
            // As erase() doesnt update m_order we can find unexisting
587
            // As erase() doesnt update m_order we can find unexisting
590
            // variables, and must not output anything for them. Have
588
            // variables, and must not output anything for them. Have
591
            // to use a ConfSimple::get() to check here, because
589
            // to use a ConfSimple::get() to check here, because
592
            // ConfTree's could retrieve from an ancestor even if the
590
            // ConfTree's could retrieve from an ancestor even if the
593
            // local var is gone.
591
            // local var is gone.
...
...
597
                if (!out.good()) {
595
                if (!out.good()) {
598
                    return false;
596
                    return false;
599
                }
597
                }
600
                break;
598
                break;
601
            }
599
            }
602
            LOGDEB((stderr, "ConfSimple::write: no value: nm[%s] sk[%s]\n",
600
            CONFDEB("ConfSimple::write: no value: nm["<<nm<<"] sk["<<sk<< "]\n");
603
                    nm.c_str(), sk.c_str()));
604
            break;
601
            break;
605
        }
602
        }
606
    }
603
    }
607
    return true;
604
    return true;
608
}
605
}
...
...
698
695
699
int ConfTree::get(const std::string& name, string& value, const string& sk)
696
int ConfTree::get(const std::string& name, string& value, const string& sk)
700
const
697
const
701
{
698
{
702
    if (sk.empty() || !path_isabsolute(sk)) {
699
    if (sk.empty() || !path_isabsolute(sk)) {
703
        // LOGDEB((stderr, "ConfTree::get: looking in global space for [%s]\n",
700
        LOGDEB2("ConfTree::get: looking in global space for ["  <<
704
        // sk.c_str()));
701
                sk << "]\n");
705
        return ConfSimple::get(name, value, sk);
702
        return ConfSimple::get(name, value, sk);
706
    }
703
    }
707
704
708
    // Get writable copy of subkey path
705
    // Get writable copy of subkey path
709
    string msk = sk;
706
    string msk = sk;
...
...
712
    // the input sk
709
    // the input sk
713
    path_catslash(msk);
710
    path_catslash(msk);
714
711
715
    // Look in subkey and up its parents until root ('')
712
    // Look in subkey and up its parents until root ('')
716
    for (;;) {
713
    for (;;) {
717
        // LOGDEB((stderr,"ConfTree::get: looking for '%s' in '%s'\n",
714
        LOGDEB2("ConfTree::get: looking for ["  << name << "] in ["  <<
718
        // name.c_str(), msk.c_str()));
715
                msk << "]\n");
719
        if (ConfSimple::get(name, value, msk)) {
716
        if (ConfSimple::get(name, value, msk)) {
720
            return 1;
717
            return 1;
721
        }
718
        }
722
        string::size_type pos = msk.rfind("/");
719
        string::size_type pos = msk.rfind("/");
723
        if (pos != string::npos) {
720
        if (pos != string::npos) {
...
...
731
                break;
728
                break;
732
        }
729
        }
733
    }
730
    }
734
    return 0;
731
    return 0;
735
}
732
}
733