~ubuntu-branches/ubuntu/natty/augeas/natty

« back to all changes in this revision

Viewing changes to src/get.c

  • Committer: Bazaar Package Importer
  • Author(s): Raphaël Pinson
  • Date: 2011-02-24 09:32:22 UTC
  • mfrom: (1.2.15 upstream)
  • Revision ID: james.westby@ubuntu.com-20110224093222-bfd4fkm6envek6ys
Tags: 0.8.0-0ubuntu1
* New upstream release.
* Remove obsolete ruby Build-Depend.
* Build PDF docs and add them to augeas-doc.
* Build-Depend on texlive-latex-base to build PDF docs.
* Install txt doc files in augeas-doc.

Show diffs side-by-side

added added

removed removed

Lines of Context:
45
45
 
46
46
struct state {
47
47
    struct info      *info;
 
48
    struct span      *span;
48
49
    const char       *text;
49
50
    struct seq       *seqs;
50
51
    char             *key;
51
52
    char             *value;     /* GET_STORE leaves a value here */
 
53
    char             *square;    /* last L_DEL from L_SQUARE */
52
54
    struct lns_error *error;
53
55
    /* We use the registers from a regular expression match to keep track
54
56
     * of the substring we are currently looking at. REGS are the registers
71
73
struct frame {
72
74
    struct lens     *lens;
73
75
    char            *key;
 
76
    char            *square;
 
77
    struct span     *span;
74
78
    union {
75
 
        struct {
 
79
        struct { /* MGET */
76
80
            char        *value;
77
81
            struct tree *tree;
78
82
        };
79
 
        struct {
 
83
        struct { /* M_PARSE */
80
84
            struct skel *skel;
81
85
            struct dict *dict;
82
86
        };
156
160
void free_skel(struct skel *skel) {
157
161
    if (skel == NULL)
158
162
        return;
159
 
    if (skel->tag == L_CONCAT || skel->tag == L_STAR || skel->tag == L_MAYBE) {
 
163
    if (skel->tag == L_CONCAT || skel->tag == L_STAR || skel->tag == L_MAYBE ||
 
164
        skel->tag == L_SQUARE) {
160
165
        while (skel->skels != NULL) {
161
166
            struct skel *del = skel->skels;
162
167
            skel->skels = del->next;
383
388
        get_error(state, lens, "no match for del /%s/", pat);
384
389
        free(pat);
385
390
    }
 
391
    if (lens->string == NULL) {
 
392
        state->square = token(state);
 
393
    }
 
394
    update_span(state->span, REG_START(state), REG_END(state));
386
395
    return NULL;
387
396
}
388
397
 
408
417
        get_error(state, lens, "More than one store in a subtree");
409
418
    else if (! REG_MATCHED(state))
410
419
        no_match_error(state, lens);
411
 
    else
 
420
    else {
412
421
        state->value = token(state);
 
422
        if (state->span) {
 
423
            state->span->value_start = REG_START(state);
 
424
            state->span->value_end = REG_END(state);
 
425
            update_span(state->span, REG_START(state), REG_END(state));
 
426
        }
 
427
    }
413
428
    return tree;
414
429
}
415
430
 
435
450
    ensure0(lens->tag == L_KEY, state->info);
436
451
    if (! REG_MATCHED(state))
437
452
        no_match_error(state, lens);
438
 
    else
 
453
    else {
439
454
        state->key = token(state);
 
455
        if (state->span) {
 
456
            state->span->label_start = REG_START(state);
 
457
            state->span->label_end = REG_END(state);
 
458
            update_span(state->span, REG_START(state), REG_END(state));
 
459
        }
 
460
    }
440
461
    return NULL;
441
462
}
442
463
 
656
677
static struct tree *get_subtree(struct lens *lens, struct state *state) {
657
678
    char *key = state->key;
658
679
    char *value = state->value;
 
680
    struct span *span = state->span;
 
681
 
659
682
    struct tree *tree = NULL, *children;
660
683
 
661
684
    state->key = NULL;
662
685
    state->value = NULL;
 
686
    if (state->info->flags & AUG_ENABLE_SPAN) {
 
687
        state->span = make_span(state->info);
 
688
        ERR_NOMEM(state->span == NULL, state->info);
 
689
    }
 
690
 
663
691
    children = get_lens(lens->child, state);
664
692
 
665
693
    tree = make_tree(state->key, state->value, NULL, children);
 
694
    tree->span = state->span;
 
695
 
 
696
    if (state->span != NULL) {
 
697
        update_span(span, state->span->span_start, state->span->span_end);
 
698
    }
666
699
 
667
700
    state->key = key;
668
701
    state->value = value;
 
702
    state->span = span;
669
703
    return tree;
 
704
 error:
 
705
    return NULL;
670
706
}
671
707
 
672
708
static struct skel *parse_subtree(struct lens *lens, struct state *state,
682
718
    return make_skel(lens);
683
719
}
684
720
 
 
721
static struct tree *get_square(struct lens *lens, struct state *state) {
 
722
    ensure0(lens->tag == L_SQUARE, state->info);
 
723
 
 
724
    struct tree *tree = NULL;
 
725
    char *key = NULL, *square = NULL;
 
726
 
 
727
    // get the child lens
 
728
    tree = get_concat(lens->child, state);
 
729
 
 
730
    key = state->key;
 
731
    square = state->square;
 
732
    ensure0(key != NULL, state->info);
 
733
    ensure0(square != NULL, state->info);
 
734
 
 
735
    if (strcmp(key, square) != 0) {
 
736
        get_error(state, lens, "%s \"%s\" %s \"%s\"",
 
737
                "Parse error: mismatched key in square lens, expecting", key,
 
738
                "but got", square);
 
739
    }
 
740
 
 
741
    FREE(state->square);
 
742
    return tree;
 
743
}
 
744
 
 
745
static struct skel *parse_square(struct lens *lens, struct state *state,
 
746
                                 struct dict **dict) {
 
747
    ensure0(lens->tag == L_SQUARE, state->info);
 
748
    struct skel *skel, *sk;
 
749
 
 
750
    skel = parse_concat(lens->child, state, dict);
 
751
    sk = make_skel(lens);
 
752
    sk->skels = skel;
 
753
 
 
754
    return sk;
 
755
}
 
756
 
685
757
/*
686
758
 * Helpers for recursive lenses
687
759
 */
691
763
    for (int j = state->fused - 1; j >=0; j--) {
692
764
        struct frame *f = state->frames + j;
693
765
        for (int i=0; i < state->lvl; i++) fputc(' ', stderr);
694
 
        fprintf(stderr, "%2d %s %s", j, f->key, f->value);
 
766
        fprintf(stderr, "%2d %s %s %s", j, f->key, f->value, f->square);
695
767
        if (f->tree == NULL) {
696
768
            fprintf(stderr, " - ");
697
769
        } else {
760
832
    top->tree = get_lens(lens, state);
761
833
    top->key = state->key;
762
834
    top->value = state->value;
 
835
    top->square = state->square;
763
836
    state->key = NULL;
764
837
    state->value = NULL;
 
838
    state->square = NULL;
765
839
}
766
840
 
767
841
static void parse_terminal(struct frame *top, struct lens *lens,
813
887
        struct frame *f = push_frame(rec_state, lens);
814
888
        f->key = state->key;
815
889
        f->value = state->value;
 
890
        f->span = state->span;
816
891
        state->key = NULL;
817
892
        state->value = NULL;
 
893
    } else if (lens->tag == L_MAYBE) {
 
894
        push_frame(rec_state, lens);
 
895
        if (state->info->flags & AUG_ENABLE_SPAN) {
 
896
            state->span = make_span(state->info);
 
897
            ERR_NOMEM(state->span == NULL, state->info);
 
898
        }
818
899
    }
 
900
 error:
 
901
    return;
819
902
}
820
903
 
821
904
static void get_combine(struct rec_state *rec_state,
822
905
                        struct lens *lens, uint n) {
823
906
    struct tree *tree = NULL, *tail = NULL;
824
 
    char *key = NULL, *value = NULL;
 
907
    char *key = NULL, *value = NULL, *square = NULL;
825
908
    struct frame *top = NULL;
826
909
 
827
910
    if (n > 0)
841
924
            ensure(value == NULL, rec_state->state->info);
842
925
            value = top->value;
843
926
        }
 
927
        if (top->square != NULL) {
 
928
            ensure(square == NULL, rec_state->state->info);
 
929
            square = top->square;
 
930
        }
844
931
    }
845
932
    top = push_frame(rec_state, lens);
846
933
    top->tree = tree;
847
934
    top->key = key;
848
935
    top->value = value;
 
936
    top->square = square;
849
937
 error:
850
938
    return;
851
939
}
899
987
        struct frame *top = top_frame(rec_state);
900
988
        if (rec_state->mode == M_GET) {
901
989
            struct tree *tree;
 
990
            // FIXME: tree may leak if pop_frame ensure0 fail
902
991
            tree = make_tree(top->key, top->value, NULL, top->tree);
 
992
            tree->span = state->span;
903
993
            ERR_NOMEM(tree == NULL, lens->info);
904
994
            top = pop_frame(rec_state);
905
995
            ensure(lens == top->lens, state->info);
906
996
            state->key = top->key;
907
997
            state->value = top->value;
 
998
            state->span = top->span;
908
999
            pop_frame(rec_state);
909
1000
            top = push_frame(rec_state, lens);
910
1001
            top->tree = tree;
948
1039
        else
949
1040
            parse_combine(rec_state, lens, n);
950
1041
    } else if (lens->tag == L_MAYBE) {
951
 
        uint n = 0;
 
1042
        uint n = 1;
952
1043
        if (rec_state->fused > 0
953
1044
            && top_frame(rec_state)->lens == lens->child) {
954
 
            n = 1;
 
1045
            n = 2;
955
1046
        }
956
1047
        if (rec_state->mode == M_GET)
957
1048
            get_combine(rec_state, lens, n);
958
1049
        else
959
1050
            parse_combine(rec_state, lens, n);
 
1051
    } else if (lens->tag == L_SQUARE) {
 
1052
        if (rec_state->mode == M_GET) {
 
1053
            char *key, *square;
 
1054
 
 
1055
            key = top_frame(rec_state)->key;
 
1056
            square = top_frame(rec_state)->square;
 
1057
 
 
1058
            ensure(key != NULL, state->info);
 
1059
            ensure(square != NULL, state->info);
 
1060
 
 
1061
            // raise syntax error if they are not equals
 
1062
            if (strcmp(key, square) != 0){
 
1063
                get_error(state, lens, "%s \"%s\" %s \"%s\"",
 
1064
                        "Parse error: mismatched key in square lens, expecting",
 
1065
                        key, "but got", square);
 
1066
                state->error->pos = end - strlen(square);
 
1067
                goto error;
 
1068
            }
 
1069
 
 
1070
            FREE(square);
 
1071
            get_combine(rec_state, lens, 1);
 
1072
        } else {
 
1073
            parse_combine(rec_state, lens, 1);
 
1074
        }
960
1075
    } else {
961
1076
        top_frame(rec_state)->lens = lens;
962
1077
    }
985
1100
    int r;
986
1101
    struct jmt_visitor visitor;
987
1102
    struct rec_state rec_state;
 
1103
    int i;
 
1104
    struct frame *f = NULL;
988
1105
 
989
1106
    MEMZERO(&rec_state, 1);
990
1107
    MEMZERO(&visitor, 1);
1032
1149
    jmt_free_parse(visitor.parse);
1033
1150
    return rec_state.frames;
1034
1151
 error:
 
1152
 
 
1153
    for(i = 0; i < rec_state.fused; i++) {
 
1154
        f = nth_frame(&rec_state, i);
 
1155
        FREE(f->key);
 
1156
        FREE(f->square);
 
1157
        if (mode == M_GET) {
 
1158
            FREE(f->value);
 
1159
            free_tree(f->tree);
 
1160
        } else if (mode == M_PARSE) {
 
1161
            free_skel(f->skel);
 
1162
            free_dict(f->dict);
 
1163
        }
 
1164
    }
1035
1165
    FREE(rec_state.frames);
1036
1166
    goto done;
1037
1167
}
1105
1235
    case L_MAYBE:
1106
1236
        tree = get_quant_maybe(lens, state);
1107
1237
        break;
 
1238
    case L_SQUARE:
 
1239
        tree = get_square(lens, state);
 
1240
        break;
1108
1241
    default:
1109
1242
        BUG_ON(true, state->info, "illegal lens tag %d", lens->tag);
1110
1243
        break;
1180
1313
        get_error(&state, lens, "get left unused value %s", state.value);
1181
1314
        free(state.value);
1182
1315
    }
 
1316
    if (state.square != NULL) {
 
1317
        get_error(&state, lens, "get left unused square %s", state.square);
 
1318
        free(state.square);
 
1319
    }
1183
1320
    if (partial && state.error == NULL) {
1184
1321
        get_error(&state, lens, "Get did not match entire input");
1185
1322
    }
1241
1378
    case L_MAYBE:
1242
1379
        skel = parse_quant_maybe(lens, state, dict);
1243
1380
        break;
 
1381
    case L_SQUARE:
 
1382
        skel = parse_square(lens, state, dict);
 
1383
        break;
1244
1384
    default:
1245
1385
        BUG_ON(true, state->info, "illegal lens tag %d", lens->tag);
1246
1386
        break;