Switch to unified view

a/src/conftree.cpp b/src/conftree.cpp
...
...
12
 *   You should have received a copy of the GNU General Public License
12
 *   You should have received a copy of the GNU General Public License
13
 *   along with this program; if not, write to the
13
 *   along with this program; if not, write to the
14
 *   Free Software Foundation, Inc.,
14
 *   Free Software Foundation, Inc.,
15
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
15
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
16
 */
16
 */
17
#ifndef TEST_CONFTREE
18
19
#ifdef BUILDING_RECOLL
17
#ifdef BUILDING_RECOLL
20
#include "autoconfig.h"
18
#include "autoconfig.h"
21
#else
19
#else
22
#include "config.h"
20
#include "config.h"
23
#endif
21
#endif
...
...
669
                break;
667
                break;
670
        }
668
        }
671
    }
669
    }
672
    return 0;
670
    return 0;
673
}
671
}
674
675
#else // TEST_CONFTREE
676
677
#include <stdio.h>
678
#include <unistd.h>
679
#include <fcntl.h>
680
#include <errno.h>
681
#include <string.h>
682
#include <sstream>
683
#include <iostream>
684
#include <vector>
685
686
#include <sys/types.h>
687
#include <sys/stat.h>
688
#include <unistd.h>
689
690
#include "conftree.h"
691
#include "smallut.h"
692
#include "readfile.h"
693
694
using namespace std;
695
696
static char *thisprog;
697
698
bool complex_updates(const string& fn)
699
{
700
    int fd;
701
    if ((fd = open(fn.c_str(), O_RDWR | O_TRUNC | O_CREAT, 0666)) < 0) {
702
        perror("open/create");
703
        return false;
704
    }
705
    close(fd);
706
707
    ConfTree conf(fn.c_str());
708
    if (!conf.ok()) {
709
        cerr << "Config init failed" << endl;
710
        return false;
711
    }
712
713
    conf.set("nm-1", "val-1", "");
714
    conf.set("nm-2", "val-2", "");
715
716
    conf.set("nm-1", "val1-1", "/dir1");
717
    conf.set("nm-2", "val1-2", "/dir1");
718
719
    conf.set("nm-1", "val2-1", "/dir2");
720
    conf.set("nm-2", "val2-2", "/dir2");
721
722
    conf.set("nm-1", "val11-1", "/dir1/dir1");
723
    conf.set("nm-2", "val11-2", "/dir1/dir1");
724
725
    conf.eraseKey("/dir2");
726
    conf.set("nm-1", "val2-1", "/dir2");
727
    conf.set("nm-2", "val2-2", "/dir2");
728
729
    conf.erase("nm-1", "");
730
    conf.erase("nm-2", "");
731
    conf.eraseKey("/dir1");
732
    conf.eraseKey("/dir2");
733
    conf.eraseKey("/dir1/dir1");
734
735
    conf.set("nm-1", "val1-1", "/dir1");
736
    conf.set("nm-2", "val1-2", "/dir1");
737
    conf.set("nm-1", "val-1", "");
738
739
    conf.set("nm-1", "val2-1", "/dir2");
740
    conf.set("nm-2", "val2-2", "/dir2");
741
742
    conf.set("nm-1", "val11-1", "/dir1/dir1");
743
    conf.set("nm-2", "val11-2", "/dir1/dir1");
744
745
    conf.erase("nm-1", "/dir2");
746
    conf.erase("nm-2", "/dir2");
747
    conf.erase("nm-1", "/dir1/dir1");
748
    conf.erase("nm-2", "/dir1/dir1");
749
750
    string data;
751
    file_to_string(fn, data, 0);
752
    const string ref =
753
        "nm-1 = val-1\n"
754
        "[/dir1]\n"
755
        "nm-1 = val1-1\n"
756
        "nm-2 = val1-2\n"
757
        ;
758
    if (data.compare(ref)) {
759
        cerr << "Final file:" << endl << data << endl << "Differs from ref:" <<
760
             endl << ref << endl;
761
        return false;
762
    } else {
763
        cout << "Updates test Ok" << endl;
764
    }
765
    return true;
766
}
767
768
ConfSimple::WalkerCode mywalker(void *, const string& nm, const string& value)
769
{
770
    if (nm.empty()) {
771
        printf("\n[%s]\n", value.c_str());
772
    } else {
773
        printf("'%s' -> '%s'\n", nm.c_str(), value.c_str());
774
    }
775
    return ConfSimple::WALK_CONTINUE;
776
}
777
778
const char *longvalue =
779
    "Donnees012345678901234567890123456789012345678901234567890123456789AA"
780
    "0123456789012345678901234567890123456789012345678901234567890123456789FIN"
781
    ;
782
783
void memtest(ConfSimple& c)
784
{
785
    cout << "Initial:" << endl;
786
    c.showall();
787
    if (c.set("nom", "avec nl \n 2eme ligne", "")) {
788
        fprintf(stderr, "set with embedded nl succeeded !\n");
789
        exit(1);
790
    }
791
    if (!c.set(string("parm1"), string("1"), string("subkey1"))) {
792
        fprintf(stderr, "Set error");
793
        exit(1);
794
    }
795
    if (!c.set("sparm", "Parametre \"string\" bla", "s2")) {
796
        fprintf(stderr, "Set error");
797
        exit(1);
798
    }
799
    if (!c.set("long", longvalue, "")) {
800
        fprintf(stderr, "Set error");
801
        exit(1);
802
    }
803
804
    cout << "Final:" << endl;
805
    c.showall();
806
}
807
808
bool readwrite(ConfNull *conf)
809
{
810
    if (conf->ok()) {
811
        // It's ok for the file to not exist here
812
        string value;
813
814
        if (conf->get("mypid", value)) {
815
            cout << "Value for mypid is [" << value << "]" << endl;
816
        } else {
817
            cout << "mypid not set" << endl;
818
        }
819
820
        if (conf->get("unstring", value)) {
821
            cout << "Value for unstring is [" << value << "]" << endl;
822
        } else {
823
            cout << "unstring not set" << endl;
824
        }
825
    }
826
    char spid[100];
827
    sprintf(spid, "%d", getpid());
828
    if (!conf->set("mypid", spid)) {
829
        cerr << "Set mypid failed" << endl;
830
    }
831
832
    ostringstream ost;
833
    ost << "mypid" << getpid();
834
    if (!conf->set(ost.str(), spid, "")) {
835
        cerr << "Set mypid failed (2)" << endl;
836
    }
837
    if (!conf->set("unstring", "Une jolie phrase pour essayer")) {
838
        cerr << "Set unstring failed" << endl;
839
    }
840
    return true;
841
}
842
843
bool query(ConfNull *conf, const string& nm, const string& sub)
844
{
845
    if (!conf->ok()) {
846
        cerr <<  "Error opening or parsing file\n" << endl;
847
        return false;
848
    }
849
    string value;
850
    if (!conf->get(nm, value, sub)) {
851
        cerr << "name [" << nm << "] not found in [" << sub << "]" << endl;
852
        return false;
853
    }
854
    cout << "[" << sub << "] " << nm << " " << value << endl;
855
    return true;
856
}
857
858
bool erase(ConfNull *conf, const string& nm, const string& sub)
859
{
860
    if (!conf->ok()) {
861
        cerr <<  "Error opening or parsing file\n" << endl;
862
        return false;
863
    }
864
865
    if (!conf->erase(nm, sub)) {
866
        cerr <<  "delete name [" << nm <<  "] in [" << sub << "] failed" << endl;
867
        return false;
868
    }
869
    return true;
870
}
871
872
bool eraseKey(ConfNull *conf, const string& sub)
873
{
874
    if (!conf->ok()) {
875
        cerr <<  "Error opening or parsing file\n" << endl;
876
        return false;
877
    }
878
879
    if (!conf->eraseKey(sub)) {
880
        cerr <<  "delete key [" << sub <<  "] failed" << endl;
881
        return false;
882
    }
883
    return true;
884
}
885
886
bool setvar(ConfNull *conf, const string& nm, const string& value,
887
            const string& sub)
888
{
889
    if (!conf->ok()) {
890
        cerr <<  "Error opening or parsing file\n" << endl;
891
        return false;
892
    }
893
    if (!conf->set(nm, value, sub)) {
894
        cerr <<  "Set error\n" << endl;
895
        return false;
896
    }
897
    return true;
898
}
899
900
static char usage [] =
901
    "testconftree [opts] filename\n"
902
    "[-w]  : read/write test.\n"
903
    "[-s]  : string parsing test. Filename must hold parm 'strings'\n"
904
    "-a nm value sect : add/set nm,value in 'sect' which can be ''\n"
905
    "-q nm sect : subsection test: look for nm in 'sect' which can be ''\n"
906
    "-d nm sect : delete nm in 'sect' which can be ''\n"
907
    "-E sect : erase key (and all its names)\n"
908
    "-S : string io test. No filename in this case\n"
909
    "-V : volatile config test. No filename in this case\n"
910
    "-U : complex update test. Will erase the named file parameter\n"
911
    ;
912
913
void Usage()
914
{
915
    fprintf(stderr, "%s:%s\n", thisprog, usage);
916
    exit(1);
917
}
918
static int     op_flags;
919
#define OPT_MOINS 0x1
920
#define OPT_w     0x2
921
#define OPT_q     0x4
922
#define OPT_s     0x8
923
#define OPT_S     0x10
924
#define OPT_d     0x20
925
#define OPT_V     0x40
926
#define OPT_a     0x80
927
#define OPT_k     0x100
928
#define OPT_E     0x200
929
#define OPT_U      0x400
930
931
int main(int argc, char **argv)
932
{
933
    const char *nm = 0;
934
    const char *sub = 0;
935
    const char *value = 0;
936
937
    thisprog = argv[0];
938
    argc--;
939
    argv++;
940
941
    while (argc > 0 && **argv == '-') {
942
        (*argv)++;
943
        if (!(**argv))
944
            /* Cas du "adb - core" */
945
        {
946
            Usage();
947
        }
948
        while (**argv)
949
            switch (*(*argv)++) {
950
            case 'a':
951
                op_flags |= OPT_a;
952
                if (argc < 4) {
953
                    Usage();
954
                }
955
                nm = *(++argv);
956
                argc--;
957
                value = *(++argv);
958
                argc--;
959
                sub = *(++argv);
960
                argc--;
961
                goto b1;
962
            case 'd':
963
                op_flags |= OPT_d;
964
                if (argc < 3) {
965
                    Usage();
966
                }
967
                nm = *(++argv);
968
                argc--;
969
                sub = *(++argv);
970
                argc--;
971
                goto b1;
972
            case 'E':
973
                op_flags |= OPT_E;
974
                if (argc < 2) {
975
                    Usage();
976
                }
977
                sub = *(++argv);
978
                argc--;
979
                goto b1;
980
            case 'k':
981
                op_flags |= OPT_k;
982
                break;
983
            case 'q':
984
                op_flags |= OPT_q;
985
                if (argc < 3) {
986
                    Usage();
987
                }
988
                nm = *(++argv);
989
                argc--;
990
                sub = *(++argv);
991
                argc--;
992
                goto b1;
993
            case 's':
994
                op_flags |= OPT_s;
995
                break;
996
            case 'S':
997
                op_flags |= OPT_S;
998
                break;
999
            case 'V':
1000
                op_flags |= OPT_V;
1001
                break;
1002
            case 'U':
1003
                op_flags |= OPT_U;
1004
                break;
1005
            case 'w':
1006
                op_flags |= OPT_w;
1007
                break;
1008
1009
            default:
1010
                Usage();
1011
                break;
1012
            }
1013
b1:
1014
        argc--;
1015
        argv++;
1016
    }
1017
1018
    if ((op_flags & OPT_S)) {
1019
        // String storage test
1020
        if (argc != 0) {
1021
            Usage();
1022
        }
1023
        string s;
1024
        ConfSimple c(s);
1025
        memtest(c);
1026
        exit(0);
1027
    } else if ((op_flags & OPT_V)) {
1028
        // No storage test
1029
        if (argc != 0) {
1030
            Usage();
1031
        }
1032
        ConfSimple c;
1033
        memtest(c);
1034
        exit(0);
1035
    }
1036
1037
    // Other tests use file(s) as backing store
1038
    if (argc < 1) {
1039
        Usage();
1040
    }
1041
1042
    if (op_flags & OPT_U) {
1043
        exit(!complex_updates(argv[0]));
1044
    }
1045
    vector<string> flist;
1046
    while (argc--) {
1047
        flist.push_back(*argv++);
1048
    }
1049
    bool ro = !(op_flags & (OPT_w | OPT_a | OPT_d | OPT_E));
1050
    ConfNull *conf = 0;
1051
    switch (flist.size()) {
1052
    case 0:
1053
        Usage();
1054
        break;
1055
    case 1:
1056
        conf = new ConfTree(flist.front().c_str(), ro);
1057
        break;
1058
    default:
1059
        conf = new ConfStack<ConfTree>(flist, ro);
1060
        break;
1061
    }
1062
1063
    if (op_flags & OPT_w) {
1064
        exit(!readwrite(conf));
1065
    } else if (op_flags & OPT_q) {
1066
        exit(!query(conf, nm, sub));
1067
    } else if (op_flags & OPT_k) {
1068
        if (!conf->ok()) {
1069
            cerr << "conf init error" << endl;
1070
            exit(1);
1071
        }
1072
        vector<string>lst = conf->getSubKeys();
1073
        for (vector<string>::const_iterator it = lst.begin();
1074
                it != lst.end(); it++) {
1075
            cout << *it << endl;
1076
        }
1077
        exit(0);
1078
    } else if (op_flags & OPT_a) {
1079
        exit(!setvar(conf, nm, value, sub));
1080
    } else if (op_flags & OPT_d) {
1081
        exit(!erase(conf, nm, sub));
1082
    } else if (op_flags & OPT_E) {
1083
        exit(!eraseKey(conf, sub));
1084
    } else if (op_flags & OPT_s) {
1085
        if (!conf->ok()) {
1086
            cerr << "Cant open /parse conf file " << endl;
1087
            exit(1);
1088
        }
1089
1090
        string source;
1091
        if (!conf->get(string("strings"), source, "")) {
1092
            cerr << "Cant get param 'strings'" << endl;
1093
            exit(1);
1094
        }
1095
        cout << "source: [" << source << "]" << endl;
1096
        vector<string> strings;
1097
        if (!stringToStrings(source, strings)) {
1098
            cerr << "parse failed" << endl;
1099
            exit(1);
1100
        }
1101
1102
        for (vector<string>::iterator it = strings.begin();
1103
                it != strings.end(); it++) {
1104
            cout << "[" << *it << "]" << endl;
1105
        }
1106
1107
    } else {
1108
        if (!conf->ok()) {
1109
            fprintf(stderr, "Open failed\n");
1110
            exit(1);
1111
        }
1112
        printf("LIST\n");
1113
        conf->showall();
1114
        //printf("WALK\n");conf->sortwalk(mywalker, 0);
1115
        printf("\nNAMES in global space:\n");
1116
        vector<string> names = conf->getNames("");
1117
        for (vector<string>::iterator it = names.begin();
1118
                it != names.end(); it++) {
1119
            cout << *it << " ";
1120
        }
1121
        cout << endl;
1122
        printf("\nNAMES in global space matching t* \n");
1123
        names = conf->getNames("", "t*");
1124
        for (vector<string>::iterator it = names.begin();
1125
                it != names.end(); it++) {
1126
            cout << *it << " ";
1127
        }
1128
        cout << endl;
1129
    }
1130
}
1131
1132
#endif