Coverage Report

Created: 2023-09-23 07:09

/src/augeas/src/get.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * parser.c: parse a configuration file according to a grammar
3
 *
4
 * Copyright (C) 2007-2016 David Lutterkort
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
19
 *
20
 * Author: David Lutterkort <dlutter@redhat.com>
21
 */
22
23
#include <config.h>
24
25
#include <regex.h>
26
#include <stdarg.h>
27
28
#include "regexp.h"
29
#include "list.h"
30
#include "internal.h"
31
#include "memory.h"
32
#include "info.h"
33
#include "lens.h"
34
#include "errcode.h"
35
36
/* Our favorite error message */
37
static const char *const short_iteration =
38
    "Iterated lens matched less than it should";
39
40
struct seq {
41
    struct seq *next;
42
    const char *name;
43
    int value;
44
};
45
46
struct state {
47
    struct info      *info;
48
    struct span      *span;
49
    const char       *text;
50
    struct seq       *seqs;
51
    char             *key;
52
    char             *value;     /* GET_STORE leaves a value here */
53
    struct lns_error *error;
54
    int               enable_span;
55
    /* We use the registers from a regular expression match to keep track
56
     * of the substring we are currently looking at. REGS are the registers
57
     * from the last regexp match; NREG is the number of the register
58
     * in REGS that describes the substring we are currently looking at.
59
     *
60
     * We adjust NREG as we traverse lenses either because we know the
61
     * grouping structure of lenses (for L_STAR, the child lens is always
62
     * in NREG + 1) or by looking at the number of groups in a sublens (as
63
     * we move from one child of L_CONCAT to the next, we need to add 1 +
64
     * number of groups of that child to NREG) How NREG is adjusted is
65
     * closely related to how the REGEXP_* routines build up bigger regexps
66
     * from smaller ones.
67
     */
68
    struct re_registers *regs;
69
    uint                 nreg;
70
};
71
72
/* Used by recursive lenses to stack intermediate results
73
   Frames are used for a few different purposes:
74
75
   (1) to save results from individual lenses that are later gathered and
76
       combined by combinators like L_STAR and L_CONCAT
77
   (2) to preserve parse state when descending into a L_SUBTREE
78
   (3) as a marker to determine if a L_MAYBE had a match or not
79
 */
80
struct frame {
81
    struct lens     *lens;
82
    char            *key;
83
    struct span     *span;
84
    union {
85
        struct { /* MGET */
86
            char        *value;
87
            struct tree *tree;
88
        };
89
        struct { /* M_PARSE */
90
            struct skel *skel;
91
            struct dict *dict;
92
        };
93
    };
94
};
95
96
/* Used by recursive lenses in get_rec and parse_rec */
97
enum mode_t { M_GET, M_PARSE };
98
99
/* Abstract Syntax Tree for recursive parse */
100
struct ast {
101
    struct ast         *parent;
102
    struct ast        **children;
103
    uint                nchildren;
104
    uint                capacity;
105
    struct lens        *lens;
106
    uint                start;
107
    uint                end;
108
};
109
110
struct rec_state {
111
    enum mode_t          mode;
112
    struct state        *state;
113
    uint                 fsize;
114
    uint                 fused;
115
    struct frame        *frames;
116
    size_t               start;
117
    uint                 lvl;  /* Debug only */
118
    struct ast          *ast;
119
    /* Will either be get_combine or parse_combine, depending on MODE, for
120
       the duration of the whole recursive parse */
121
    void (*combine)(struct rec_state *, struct lens *, uint);
122
};
123
124
0
#define REG_START(state) ((state)->regs->start[(state)->nreg])
125
0
#define REG_END(state)   ((state)->regs->end[(state)->nreg])
126
0
#define REG_SIZE(state) (REG_END(state) - REG_START(state))
127
0
#define REG_POS(state) ((state)->text + REG_START(state))
128
0
#define REG_VALID(state) ((state)->regs != NULL &&                      \
129
0
                          (state)->nreg < (state)->regs->num_regs)
130
0
#define REG_MATCHED(state) (REG_VALID(state)                            \
131
0
                            && (state)->regs->start[(state)->nreg] >= 0)
132
133
/* The macros SAVE_REGS and RESTORE_REGS are used to remember and restore
134
 * where our caller was in processing their regexp match before we do
135
 * matching ourselves (and would therefore clobber the caller's state)
136
 *
137
 * These two macros are admittedly horrible in that they declare local
138
 * variables called OLD_REGS and OLD_NREG. The alternative to avoiding that
139
 * would be to manually manage a stack of regs/nreg in STATE.
140
 */
141
#define SAVE_REGS(state)                                                \
142
0
    struct re_registers *old_regs = state->regs;                        \
143
0
    uint old_nreg = state->nreg;                                        \
144
0
    state->regs = NULL;                                                 \
145
0
    state->nreg = 0
146
147
#define RESTORE_REGS(state)                                             \
148
0
    free_regs(state);                                                   \
149
0
    state->regs = old_regs;                                             \
150
0
    state->nreg = old_nreg;
151
152
/*
153
 * AST utils
154
 */
155
0
static struct ast *make_ast(struct lens *lens) {
156
0
    struct ast *ast = NULL;
157
158
0
    if (ALLOC(ast) < 0)
159
0
        return NULL;
160
0
    ast->lens = lens;
161
0
    ast->capacity = 4;
162
0
    if (ALLOC_N(ast->children, ast->capacity) < 0) {
163
0
        FREE(ast);
164
0
        return NULL;
165
0
    }
166
0
    return ast;
167
0
}
168
169
/* recursively free the node and all it's descendants */
170
0
static void free_ast(struct ast *ast) {
171
0
    int i;
172
0
    if (ast == NULL)
173
0
        return;
174
0
    for (i = 0; i < ast->nchildren; i++) {
175
0
        free_ast(ast->children[i]);
176
0
    }
177
0
    if (ast->children != NULL)
178
0
        FREE(ast->children);
179
0
    FREE(ast);
180
0
}
181
182
0
static struct ast *ast_root(struct ast *ast) {
183
0
    struct ast *root = ast;
184
0
    while(root != NULL && root->parent != NULL)
185
0
        root = root->parent;
186
0
    return root;
187
0
}
188
189
0
static void ast_set(struct ast *ast, uint start, uint end) {
190
0
    if (ast == NULL)
191
0
        return;
192
0
    ast->start = start;
193
0
    ast->end = end;
194
0
}
195
196
/* append a child to the parent ast */
197
static struct ast *ast_append(struct rec_state *rec_state, struct lens *lens,
198
0
                           uint start, uint end) {
199
0
    int ret;
200
0
    struct ast *child, *parent;
201
0
    struct state *state = rec_state->state;
202
203
0
    parent = rec_state->ast;
204
0
    if (parent == NULL)
205
0
       return NULL;
206
207
0
    child = make_ast(lens);
208
0
    ERR_NOMEM(child == NULL, state->info);
209
210
0
    ast_set(child, start, end);
211
0
    if (parent->nchildren >= parent->capacity) {
212
0
       ret = REALLOC_N(parent->children, parent->capacity * 2);
213
0
       ERR_NOMEM(ret < 0, state->info);
214
0
       parent->capacity = parent->capacity * 2;
215
0
    }
216
0
    parent->children[parent->nchildren++] = child;
217
0
    child->parent = parent;
218
219
0
    return child;
220
0
 error:
221
0
    free_ast(child);
222
0
    return NULL;
223
0
}
224
225
/* pop the ast from one level, fail the parent is NULL */
226
0
static void ast_pop(struct rec_state *rec_state) {
227
0
    ensure(rec_state->ast != NULL && rec_state->ast->parent != NULL, rec_state->state->info);
228
0
    rec_state->ast = rec_state->ast->parent;
229
0
 error:
230
0
    return;
231
0
}
232
233
0
static void print_ast(const struct ast *ast, int lvl) {
234
0
    int i;
235
0
    char *lns;
236
0
    if (ast == NULL)
237
0
        return;
238
0
    for (i = 0; i < lvl; i++) fputs(" ", stdout);
239
0
    lns = format_lens(ast->lens);
240
0
    printf("%d..%d %s\n", ast->start, ast->end, lns);
241
0
    free(lns);
242
0
    for (i = 0; i < ast->nchildren; i++) {
243
0
        print_ast(ast->children[i], lvl + 1);
244
0
    }
245
0
}
246
247
static void get_error(struct state *state, struct lens *lens,
248
                      const char *format, ...)
249
    ATTRIBUTE_FORMAT(printf, 3, 4);
250
251
11
void free_lns_error(struct lns_error *err) {
252
11
    if (err == NULL)
253
11
        return;
254
0
    free(err->message);
255
0
    free(err->path);
256
0
    unref(err->lens, lens);
257
0
    free(err);
258
0
}
259
260
static void vget_error(struct state *state, struct lens *lens,
261
0
                       const char *format, va_list ap) {
262
0
    int r;
263
264
0
    if (state->error != NULL)
265
0
        return;
266
0
    if (ALLOC(state->error) < 0)
267
0
        return;
268
0
    state->error->lens = ref(lens);
269
0
    if (REG_MATCHED(state))
270
0
        state->error->pos  = REG_END(state);
271
0
    else
272
0
        state->error->pos = 0;
273
0
    r = vasprintf(&state->error->message, format, ap);
274
0
    if (r == -1)
275
0
        state->error->message = NULL;
276
0
}
277
278
static void get_error(struct state *state, struct lens *lens,
279
                      const char *format, ...)
280
0
{
281
0
    va_list ap;
282
283
0
    va_start(ap, format);
284
0
    vget_error(state, lens, format, ap);
285
0
    va_end(ap);
286
0
}
287
288
0
static struct skel *make_skel(struct lens *lens) {
289
0
    struct skel *skel;
290
0
    enum lens_tag tag = lens->tag;
291
0
    if (ALLOC(skel) < 0)
292
0
        return NULL;
293
0
    skel->tag = tag;
294
0
    return skel;
295
0
}
296
297
0
void free_skel(struct skel *skel) {
298
0
    if (skel == NULL)
299
0
        return;
300
0
    if (skel->tag == L_CONCAT || skel->tag == L_STAR || skel->tag == L_MAYBE ||
301
0
        skel->tag == L_SQUARE) {
302
0
        while (skel->skels != NULL) {
303
0
            struct skel *del = skel->skels;
304
0
            skel->skels = del->next;
305
0
            free_skel(del);
306
0
        }
307
0
    } else if (skel->tag == L_DEL) {
308
0
        free(skel->text);
309
0
    }
310
0
    free(skel);
311
0
}
312
313
static void print_skel(struct skel *skel);
314
static void print_skel_list(struct skel *skels, const char *beg,
315
0
                            const char *sep, const char *end) {
316
0
    printf("%s", beg);
317
0
    list_for_each(s, skels) {
318
0
        print_skel(s);
319
0
        if (s->next != NULL)
320
0
            printf("%s", sep);
321
0
    }
322
0
    printf("%s", end);
323
0
}
324
325
0
static void print_skel(struct skel *skel) {
326
0
    switch(skel->tag) {
327
0
    case L_DEL:
328
0
        if (skel->text == NULL) {
329
0
            printf("<>");
330
0
        } else {
331
0
            fputc('\'', stdout);
332
0
            print_chars(stdout, skel->text, -1);
333
0
            fputc('\'', stdout);
334
0
        }
335
0
        break;
336
0
    case L_CONCAT:
337
0
        print_skel_list(skel->skels, "", " . ", "");
338
0
        break;
339
0
    case L_STAR:
340
0
        print_skel_list(skel->skels, "(", " ", ")*");
341
0
        break;
342
0
    case L_MAYBE:
343
0
        print_skel_list(skel->skels, "(", " ", ")?");
344
0
        break;
345
0
    case L_SUBTREE:
346
0
        print_skel_list(skel->skels, "[", " ", "]");
347
0
        break;
348
0
    default:
349
0
        printf("??");
350
0
        break;
351
0
    }
352
0
}
353
354
// DICT_DUMP is only used for debugging
355
#ifdef DICT_DUMP
356
static void print_dict(struct dict *dict, int indent) {
357
    list_for_each(d, dict) {
358
        printf("%*s%s:\n", indent, "", d->key);
359
        list_for_each(e, d->entry) {
360
            printf("%*s", indent+2, "");
361
            print_skel(e->skel);
362
            printf("\n");
363
            print_dict(e->dict, indent+2);
364
        }
365
    }
366
}
367
#endif
368
369
0
static void get_expected_error(struct state *state, struct lens *l) {
370
    /* Size of the excerpt of the input text we'll show */
371
0
    static const int wordlen = 10;
372
0
    char word[wordlen+1];
373
0
    char *p, *pat;
374
375
0
    if (REG_MATCHED(state))
376
0
        strncpy(word, REG_POS(state), wordlen);
377
0
    else
378
0
        strncpy(word, state->text, wordlen);
379
0
    word[wordlen] = '\0';
380
0
    for (p = word; *p != '\0' && *p != '\n'; p++);
381
0
    *p = '\0';
382
383
0
    pat = escape(l->ctype->pattern->str, -1, NULL);
384
0
    get_error(state, l, "expected %s at '%s'", pat, word);
385
0
    free(pat);
386
0
}
387
388
/*
389
 * Splitting of the input text
390
 */
391
392
0
static char *token(struct state *state) {
393
0
    ensure0(REG_MATCHED(state), state->info);
394
0
    return strndup(REG_POS(state), REG_SIZE(state));
395
0
}
396
397
0
static char *token_range(const char *text, uint start, uint end) {
398
0
    return strndup(text + start, end - start);
399
0
}
400
401
static void regexp_match_error(struct state *state, struct lens *lens,
402
0
                               int count, struct regexp *r) {
403
0
    char *text = NULL;
404
0
    char *pat = regexp_escape(r);
405
406
0
    if (state->regs != NULL)
407
0
        text = strndup(REG_POS(state), REG_SIZE(state));
408
0
    else
409
0
        text = strdup("(unknown)");
410
411
0
    if (count == -1) {
412
0
        get_error(state, lens, "Failed to match /%s/ with %s", pat, text);
413
0
    } else if (count == -2) {
414
0
        get_error(state, lens, "Internal error matching /%s/ with %s",
415
0
                  pat, text);
416
0
    } else if (count == -3) {
417
        /* Should have been caught by the typechecker */
418
0
        get_error(state, lens, "Syntax error in regexp /%s/", pat);
419
0
    }
420
0
    free(pat);
421
0
    free(text);
422
0
}
423
424
0
static void no_match_error(struct state *state, struct lens *lens) {
425
0
    ensure(lens->tag == L_KEY || lens->tag == L_DEL
426
0
           || lens->tag == L_STORE, state->info);
427
0
    char *pat = regexp_escape(lens->ctype);
428
0
    const char *lname = "(lname)";
429
0
    if (lens->tag == L_KEY)
430
0
        lname = "key";
431
0
    else if (lens->tag == L_DEL)
432
0
        lname = "del";
433
0
    else if (lens->tag == L_STORE)
434
0
        lname = "store";
435
0
    get_error(state, lens, "no match for %s /%s/", lname, pat);
436
0
    free(pat);
437
0
 error:
438
0
    return;
439
0
}
440
441
/* Modifies STATE->REGS and STATE->NREG. The caller must save these
442
 * if they are still needed
443
 *
444
 * Return the number of characters matched
445
 */
446
static int match(struct state *state, struct lens *lens,
447
0
                 struct regexp *re, uint size, uint start) {
448
0
    struct re_registers *regs;
449
0
    int count;
450
451
0
    if (ALLOC(regs) < 0)
452
0
        return -1;
453
454
0
    count = regexp_match(re, state->text, size, start, regs);
455
0
    if (count < -1) {
456
0
        regexp_match_error(state, lens, count, re);
457
0
        FREE(regs);
458
0
        return -1;
459
0
    }
460
0
    state->regs = regs;
461
0
    state->nreg = 0;
462
0
    return count;
463
0
}
464
465
0
static void free_regs(struct state *state) {
466
0
    if (state->regs != NULL) {
467
0
        free(state->regs->start);
468
0
        free(state->regs->end);
469
0
        FREE(state->regs);
470
0
    }
471
0
}
472
473
static struct tree *get_lens(struct lens *lens, struct state *state);
474
static struct skel *parse_lens(struct lens *lens, struct state *state,
475
                               struct dict **dict);
476
477
0
static void free_seqs(struct seq *seqs) {
478
    /* Do not free seq->name; it's not owned by the seq, but by some lens */
479
0
    list_free(seqs);
480
0
}
481
482
0
static struct seq *find_seq(const char *name, struct state *state) {
483
0
    ensure0(name != NULL, state->info);
484
0
    struct seq *seq;
485
486
0
    for (seq=state->seqs;
487
0
         seq != NULL && STRNEQ(seq->name, name);
488
0
         seq = seq->next);
489
490
0
    if (seq == NULL) {
491
0
        if (ALLOC(seq) < 0)
492
0
            return NULL;
493
0
        seq->name = name;
494
0
        seq->value = 1;
495
0
        list_append(state->seqs, seq);
496
0
    }
497
498
0
    return seq;
499
0
}
500
501
0
static struct tree *get_seq(struct lens *lens, struct state *state) {
502
0
    ensure0(lens->tag == L_SEQ, state->info);
503
0
    struct seq *seq = find_seq(lens->string->str, state);
504
0
    int r;
505
506
0
    r = asprintf((char **) &(state->key), "%d", seq->value);
507
0
    ERR_NOMEM(r < 0, state->info);
508
509
0
    seq->value += 1;
510
0
 error:
511
0
    return NULL;
512
0
}
513
514
0
static struct skel *parse_seq(struct lens *lens, struct state *state) {
515
0
    get_seq(lens, state);
516
0
    return make_skel(lens);
517
0
}
518
519
0
static struct tree *get_counter(struct lens *lens, struct state *state) {
520
0
    ensure0(lens->tag == L_COUNTER, state->info);
521
0
    struct seq *seq = find_seq(lens->string->str, state);
522
0
    seq->value = 1;
523
0
    return NULL;
524
0
}
525
526
0
static struct skel *parse_counter(struct lens *lens, struct state *state) {
527
0
    get_counter(lens, state);
528
0
    return make_skel(lens);
529
0
}
530
531
0
static struct tree *get_del(struct lens *lens, struct state *state) {
532
0
    ensure0(lens->tag == L_DEL, state->info);
533
0
    if (! REG_MATCHED(state)) {
534
0
        char *pat = regexp_escape(lens->ctype);
535
0
        get_error(state, lens, "no match for del /%s/", pat);
536
0
        free(pat);
537
0
    }
538
0
    update_span(state->span, REG_START(state), REG_END(state));
539
0
    return NULL;
540
0
}
541
542
0
static struct skel *parse_del(struct lens *lens, struct state *state) {
543
0
    ensure0(lens->tag == L_DEL, state->info);
544
0
    struct skel *skel = NULL;
545
546
0
    skel = make_skel(lens);
547
0
    if (! REG_MATCHED(state))
548
0
        no_match_error(state, lens);
549
0
    else
550
0
        skel->text = token(state);
551
0
    return skel;
552
0
}
553
554
0
static struct tree *get_store(struct lens *lens, struct state *state) {
555
0
    ensure0(lens->tag == L_STORE, state->info);
556
0
    ensure0(state->value == NULL, state->info);
557
558
0
    struct tree *tree = NULL;
559
560
0
    if (state->value != NULL)
561
0
        get_error(state, lens, "More than one store in a subtree");
562
0
    else if (! REG_MATCHED(state))
563
0
        no_match_error(state, lens);
564
0
    else {
565
0
        state->value = token(state);
566
0
        if (state->span) {
567
0
            state->span->value_start = REG_START(state);
568
0
            state->span->value_end = REG_END(state);
569
0
            update_span(state->span, REG_START(state), REG_END(state));
570
0
        }
571
0
    }
572
0
    return tree;
573
0
}
574
575
static struct skel *parse_store(struct lens *lens,
576
0
                                ATTRIBUTE_UNUSED struct state *state) {
577
0
    ensure0(lens->tag == L_STORE, state->info);
578
0
    return make_skel(lens);
579
0
}
580
581
0
static struct tree *get_value(struct lens *lens, struct state *state) {
582
0
    ensure0(lens->tag == L_VALUE, state->info);
583
0
    state->value = strdup(lens->string->str);
584
0
    return NULL;
585
0
}
586
587
static struct skel *parse_value(struct lens *lens,
588
0
                                ATTRIBUTE_UNUSED struct state *state) {
589
0
    ensure0(lens->tag == L_VALUE, state->info);
590
0
    return make_skel(lens);
591
0
}
592
593
0
static struct tree *get_key(struct lens *lens, struct state *state) {
594
0
    ensure0(lens->tag == L_KEY, state->info);
595
0
    if (! REG_MATCHED(state))
596
0
        no_match_error(state, lens);
597
0
    else {
598
0
        state->key = token(state);
599
0
        if (state->span) {
600
0
            state->span->label_start = REG_START(state);
601
0
            state->span->label_end = REG_END(state);
602
0
            update_span(state->span, REG_START(state), REG_END(state));
603
0
        }
604
0
    }
605
0
    return NULL;
606
0
}
607
608
0
static struct skel *parse_key(struct lens *lens, struct state *state) {
609
0
    get_key(lens, state);
610
0
    return make_skel(lens);
611
0
}
612
613
0
static struct tree *get_label(struct lens *lens, struct state *state) {
614
0
    ensure0(lens->tag == L_LABEL, state->info);
615
0
    state->key = strdup(lens->string->str);
616
0
    return NULL;
617
0
}
618
619
0
static struct skel *parse_label(struct lens *lens, struct state *state) {
620
0
    get_label(lens, state);
621
0
    return make_skel(lens);
622
0
}
623
624
0
static struct tree *get_union(struct lens *lens, struct state *state) {
625
0
    ensure0(lens->tag == L_UNION, state->info);
626
627
0
    struct tree *tree = NULL;
628
0
    int applied = 0;
629
0
    uint old_nreg = state->nreg;
630
631
0
    state->nreg += 1;
632
0
    for (int i=0; i < lens->nchildren; i++) {
633
0
        if (REG_MATCHED(state)) {
634
0
            tree = get_lens(lens->children[i], state);
635
0
            applied = 1;
636
0
            break;
637
0
        }
638
0
        state->nreg += 1 + regexp_nsub(lens->children[i]->ctype);
639
0
    }
640
0
    state->nreg = old_nreg;
641
0
    if (!applied)
642
0
        get_expected_error(state, lens);
643
0
    return tree;
644
0
}
645
646
static struct skel *parse_union(struct lens *lens, struct state *state,
647
0
                                struct dict **dict) {
648
0
    ensure0(lens->tag == L_UNION, state->info);
649
650
0
    struct skel *skel = NULL;
651
0
    int applied = 0;
652
0
    uint old_nreg = state->nreg;
653
654
0
    state->nreg += 1;
655
0
    for (int i=0; i < lens->nchildren; i++) {
656
0
        struct lens *l = lens->children[i];
657
0
        if (REG_MATCHED(state)) {
658
0
            skel = parse_lens(l, state, dict);
659
0
            applied = 1;
660
0
            break;
661
0
        }
662
0
        state->nreg += 1 + regexp_nsub(lens->children[i]->ctype);
663
0
    }
664
0
    state->nreg = old_nreg;
665
0
    if (! applied)
666
0
        get_expected_error(state, lens);
667
668
0
    return skel;
669
0
}
670
671
0
static struct tree *get_concat(struct lens *lens, struct state *state) {
672
0
    ensure0(lens->tag == L_CONCAT, state->info);
673
674
0
    struct tree *tree = NULL;
675
0
    uint old_nreg = state->nreg;
676
677
0
    state->nreg += 1;
678
0
    for (int i=0; i < lens->nchildren; i++) {
679
0
        struct tree *t = NULL;
680
0
        if (! REG_VALID(state)) {
681
0
            get_error(state, lens->children[i],
682
0
                      "Not enough components in concat");
683
0
            free_tree(tree);
684
0
            state->nreg = old_nreg;
685
0
            return NULL;
686
0
        }
687
688
0
        t = get_lens(lens->children[i], state);
689
0
        list_append(tree, t);
690
0
        state->nreg += 1 + regexp_nsub(lens->children[i]->ctype);
691
0
    }
692
0
    state->nreg = old_nreg;
693
694
0
    return tree;
695
0
}
696
697
static struct skel *parse_concat(struct lens *lens, struct state *state,
698
0
                                 struct dict **dict) {
699
0
    ensure0(lens->tag == L_CONCAT, state->info);
700
0
    struct skel *skel = make_skel(lens);
701
0
    uint old_nreg = state->nreg;
702
703
0
    state->nreg += 1;
704
0
    for (int i=0; i < lens->nchildren; i++) {
705
0
        struct skel *sk = NULL;
706
0
        struct dict *di = NULL;
707
0
        if (! REG_VALID(state)) {
708
0
            get_error(state, lens->children[i],
709
0
                      "Not enough components in concat");
710
0
            free_skel(skel);
711
0
            return NULL;
712
0
        }
713
714
0
        sk = parse_lens(lens->children[i], state, &di);
715
0
        list_append(skel->skels, sk);
716
0
        dict_append(dict, di);
717
0
        state->nreg += 1 + regexp_nsub(lens->children[i]->ctype);
718
0
    }
719
0
    state->nreg = old_nreg;
720
721
0
    return skel;
722
0
}
723
724
/* Given a lens that does not match at the current position, try to find
725
 * the left-most child LAST that does match and the lens next to it NEXT
726
 * that does not match. Return the length of the match.
727
 *
728
 * If no such child exists, return 0
729
 */
730
static int try_match(struct lens *lens, struct state *state,
731
                     uint start, uint end,
732
0
                     struct lens **last, struct lens **next) {
733
0
    int result = 0, r;
734
735
0
    switch(lens->tag) {
736
0
    case L_VALUE:
737
0
    case L_LABEL:
738
0
    case L_SEQ:
739
0
    case L_COUNTER:
740
0
        *last = lens;
741
0
        return result;
742
0
        break;
743
0
    case L_DEL:
744
0
    case L_KEY:
745
0
    case L_STORE:
746
0
        result = regexp_match(lens->ctype, state->text, end, start, NULL);
747
0
        if (result >= 0)
748
0
            *last = lens;
749
0
        return result;
750
0
    case L_CONCAT:
751
0
        for (int i=0; i < lens->nchildren; i++) {
752
0
            struct lens *child = lens->children[i];
753
0
            struct lens *next_child  =
754
0
                (i < lens->nchildren - 1) ? lens->children[i+1] : NULL;
755
756
0
            r = regexp_match(child->ctype, state->text, end, start, NULL);
757
0
            if (r >= 0) {
758
0
                result += r;
759
0
                start += r;
760
0
                *last = child;
761
0
            } else if (result > 0) {
762
0
                if (*next == NULL)
763
0
                    *next = child;
764
0
                return result;
765
0
            } else {
766
0
                result = try_match(child, state, start, end, last, next);
767
0
                if (result > 0 && *next == NULL)
768
0
                    *next = next_child;
769
0
                return result;
770
0
            }
771
0
        }
772
0
        return result;
773
0
        break;
774
0
    case L_UNION:
775
0
        for (int i=0; i < lens->nchildren; i++) {
776
0
            struct lens *child = lens->children[i];
777
0
            result = try_match(child, state, start, end, last, next);
778
0
            if (result > 0)
779
0
                return result;
780
0
        }
781
0
        return 0;
782
0
        break;
783
0
    case L_SUBTREE:
784
0
    case L_STAR:
785
0
    case L_MAYBE:
786
0
    case L_SQUARE:
787
0
        return try_match(lens->child, state, start, end, last, next);
788
0
        break;
789
0
    default:
790
0
        BUG_ON(true, state->info, "illegal lens tag %d", lens->tag);
791
0
        break;
792
0
    }
793
0
 error:
794
0
    return 0;
795
0
}
796
797
static void short_iteration_error(struct lens *lens, struct state *state,
798
0
                                    uint start, uint end) {
799
0
    int match_count;
800
801
0
    get_error(state, lens, "%s", short_iteration);
802
803
0
    match_count = try_match(lens->child, state, start, end,
804
0
                            &state->error->last, &state->error->next);
805
0
    state->error->pos = start + match_count;
806
0
}
807
808
0
static struct tree *get_quant_star(struct lens *lens, struct state *state) {
809
0
    ensure0(lens->tag == L_STAR, state->info);
810
0
    struct lens *child = lens->child;
811
0
    struct tree *tree = NULL, *tail = NULL;
812
0
    uint end = REG_END(state);
813
0
    uint start = REG_START(state);
814
0
    uint size = end - start;
815
816
0
    SAVE_REGS(state);
817
0
    while (size > 0 && match(state, child, child->ctype, end, start) > 0) {
818
0
        struct tree *t = NULL;
819
820
0
        t = get_lens(lens->child, state);
821
0
        list_tail_cons(tree, tail, t);
822
823
0
        start += REG_SIZE(state);
824
0
        size -= REG_SIZE(state);
825
0
        free_regs(state);
826
0
    }
827
0
    RESTORE_REGS(state);
828
0
    if (size != 0) {
829
0
        short_iteration_error(lens, state, start, end);
830
0
    }
831
0
    return tree;
832
0
}
833
834
static struct skel *parse_quant_star(struct lens *lens, struct state *state,
835
0
                                     struct dict **dict) {
836
0
    ensure0(lens->tag == L_STAR, state->info);
837
0
    struct lens *child = lens->child;
838
0
    struct skel *skel = make_skel(lens), *tail = NULL;
839
0
    uint end = REG_END(state);
840
0
    uint start = REG_START(state);
841
0
    uint size = end - start;
842
843
0
    *dict = NULL;
844
0
    SAVE_REGS(state);
845
0
    while (size > 0 && match(state, child, child->ctype, end, start) > 0) {
846
0
        struct skel *sk;
847
0
        struct dict *di = NULL;
848
849
0
        sk = parse_lens(lens->child, state, &di);
850
0
        list_tail_cons(skel->skels, tail, sk);
851
0
        dict_append(dict, di);
852
853
0
        start += REG_SIZE(state);
854
0
        size -= REG_SIZE(state);
855
0
        free_regs(state);
856
0
    }
857
0
    RESTORE_REGS(state);
858
0
    if (size != 0) {
859
0
        get_error(state, lens, "%s", short_iteration);
860
0
    }
861
0
    return skel;
862
0
}
863
864
0
static struct tree *get_quant_maybe(struct lens *lens, struct state *state) {
865
0
    ensure0(lens->tag == L_MAYBE, state->info);
866
0
    struct tree *tree = NULL;
867
868
    /* Check that our child matched. For a construct like (r)?, the
869
     * matcher will report a zero length match for group 0, even if r
870
     * does not match at all
871
     */
872
0
    state->nreg += 1;
873
0
    if (REG_MATCHED(state)) {
874
0
        tree = get_lens(lens->child, state);
875
0
    }
876
0
    state->nreg -= 1;
877
0
    return tree;
878
0
}
879
880
static struct skel *parse_quant_maybe(struct lens *lens, struct state *state,
881
0
                                      struct dict **dict) {
882
0
    ensure0(lens->tag == L_MAYBE, state->info);
883
884
0
    struct skel *skel = NULL;
885
886
0
    state->nreg += 1;
887
0
    if (REG_MATCHED(state)) {
888
0
        skel = parse_lens(lens->child, state, dict);
889
0
    }
890
0
    state->nreg -= 1;
891
0
    if (skel == NULL)
892
0
        skel = make_skel(lens);
893
0
    return skel;
894
0
}
895
896
0
static struct tree *get_subtree(struct lens *lens, struct state *state) {
897
0
    char *key = state->key;
898
0
    char *value = state->value;
899
0
    struct span *span = move(state->span);
900
901
0
    struct tree *tree = NULL, *children;
902
903
0
    state->key = NULL;
904
0
    state->value = NULL;
905
0
    if (state->enable_span) {
906
0
        state->span = make_span(state->info);
907
0
        ERR_NOMEM(state->span == NULL, state->info);
908
0
    }
909
910
0
    children = get_lens(lens->child, state);
911
912
0
    tree = make_tree(state->key, state->value, NULL, children);
913
0
    ERR_NOMEM(tree == NULL, state->info);
914
0
    tree->span = move(state->span);
915
916
0
    if (tree->span != NULL) {
917
0
        update_span(span, tree->span->span_start, tree->span->span_end);
918
0
    }
919
920
0
    state->key = key;
921
0
    state->value = value;
922
0
    state->span = span;
923
0
    return tree;
924
0
 error:
925
0
    free_span(state->span);
926
0
    state->span = span;
927
0
    return NULL;
928
0
}
929
930
static struct skel *parse_subtree(struct lens *lens, struct state *state,
931
0
                                  struct dict **dict) {
932
0
    char *key = state->key;
933
0
    struct skel *skel;
934
0
    struct dict *di = NULL;
935
936
0
    state->key = NULL;
937
0
    skel = parse_lens(lens->child, state, &di);
938
0
    *dict = make_dict(state->key, skel, di);
939
0
    state->key = key;
940
0
    return make_skel(lens);
941
0
}
942
943
/* Check if left and right strings matches according to the square lens
944
 * definition.
945
 *
946
 * Returns 1 if strings matches, 0 otherwise
947
 */
948
0
static int square_match(struct lens *lens, char *left, char *right) {
949
0
    int cmp = 0;
950
0
    struct lens *concat = NULL;
951
952
    // if one of the argument is NULL, returns no match
953
0
    if (left == NULL || right == NULL || lens == NULL)
954
0
        return cmp;
955
956
0
    concat = lens->child;
957
    /* If either right or left lens is nocase, then ignore case */
958
0
    if (child_first(concat)->ctype->nocase ||
959
0
            child_last(concat)->ctype->nocase) {
960
0
        cmp = STRCASEEQ(left, right);
961
0
    } else {
962
0
        cmp = STREQ(left, right);
963
0
    }
964
0
    return cmp;
965
0
}
966
967
/*
968
 * This function applies only for non-recursive lens, handling of recursive
969
 * square is done in visit_exit().
970
 */
971
0
static struct tree *get_square(struct lens *lens, struct state *state) {
972
0
    ensure0(lens->tag == L_SQUARE, state->info);
973
974
0
    struct lens *concat = lens->child;
975
0
    struct tree *tree = NULL;
976
0
    uint end = REG_END(state);
977
0
    uint start = REG_START(state);
978
0
    char *rsqr = NULL, *lsqr = NULL;
979
0
    int r;
980
981
0
    SAVE_REGS(state);
982
0
    r = match(state, lens->child, lens->child->ctype, end, start);
983
0
    ERR_NOMEM(r < 0, state->info);
984
985
0
    tree = get_lens(lens->child, state);
986
987
    /* retrieve left component */
988
0
    state->nreg = 1;
989
0
    start = REG_START(state);
990
0
    end = REG_END(state);
991
0
    lsqr = token_range(state->text, start, end);
992
993
    /* retrieve right component */
994
    /* compute nreg for the last children */
995
0
    for (int i = 0; i < concat->nchildren - 1; i++)
996
0
        state->nreg += 1 + regexp_nsub(concat->children[i]->ctype);
997
998
0
    start = REG_START(state);
999
0
    end = REG_END(state);
1000
0
    rsqr = token_range(state->text, start, end);
1001
1002
0
    if (!square_match(lens, lsqr, rsqr)) {
1003
0
        get_error(state, lens, "%s \"%s\" %s \"%s\"",
1004
0
            "Parse error: mismatched in square lens, expecting", lsqr,
1005
0
            "but got", rsqr);
1006
0
        goto error;
1007
0
    }
1008
1009
0
 done:
1010
0
    RESTORE_REGS(state);
1011
0
    FREE(lsqr);
1012
0
    FREE(rsqr);
1013
0
    return tree;
1014
1015
0
 error:
1016
0
    free_tree(tree);
1017
0
    tree = NULL;
1018
0
    goto done;
1019
0
}
1020
1021
static struct skel *parse_square(struct lens *lens, struct state *state,
1022
0
                                 struct dict **dict) {
1023
0
    ensure0(lens->tag == L_SQUARE, state->info);
1024
0
    uint end = REG_END(state);
1025
0
    uint start = REG_START(state);
1026
0
    struct skel *skel = NULL, *sk = NULL;
1027
0
    int r;
1028
1029
0
    SAVE_REGS(state);
1030
0
    r = match(state, lens->child, lens->child->ctype, end, start);
1031
0
    ERR_NOMEM(r < 0, state->info);
1032
1033
0
    skel = parse_lens(lens->child, state, dict);
1034
0
    if (skel == NULL)
1035
0
        return NULL;
1036
0
    sk = make_skel(lens);
1037
0
    sk->skels = skel;
1038
1039
0
 error:
1040
0
    RESTORE_REGS(state);
1041
0
    return sk;
1042
0
}
1043
1044
/*
1045
 * Helpers for recursive lenses
1046
 */
1047
1048
ATTRIBUTE_UNUSED
1049
0
static void print_frames(struct rec_state *state) {
1050
0
    for (int j = state->fused - 1; j >=0; j--) {
1051
0
        struct frame *f = state->frames + j;
1052
0
        for (int i=0; i < state->lvl; i++) fputc(' ', stderr);
1053
0
        fprintf(stderr, "%2d %s %s", j, f->key, f->value);
1054
0
        if (f->tree == NULL) {
1055
0
            fprintf(stderr, " - ");
1056
0
        } else {
1057
0
            fprintf(stderr, " { %s = %s } ", f->tree->label, f->tree->value);
1058
0
        }
1059
0
        char *s = format_lens(f->lens);
1060
0
        if (s != NULL) {
1061
0
            fprintf(stderr, "%s\n", s);
1062
0
            free(s);
1063
0
        }
1064
0
    }
1065
0
}
1066
1067
ATTRIBUTE_PURE
1068
0
static struct frame *top_frame(struct rec_state *state) {
1069
0
    ensure0(state->fsize > 0, state->state->info);
1070
0
    return state->frames + state->fused - 1;
1071
0
}
1072
1073
/* The nth frame from the top of the stack, where 0th frame is the top */
1074
ATTRIBUTE_PURE
1075
0
static struct frame *nth_frame(struct rec_state *state, uint n) {
1076
0
    ensure0(state->fsize > n, state->state->info);
1077
0
    return state->frames + state->fused - (n+1);
1078
0
}
1079
1080
0
static struct frame *push_frame(struct rec_state *state, struct lens *lens) {
1081
0
    int r;
1082
1083
0
    if (state->fused >= state->fsize) {
1084
0
        uint expand = state->fsize;
1085
0
        if (expand < 8)
1086
0
            expand = 8;
1087
0
        r = REALLOC_N(state->frames, state->fsize + expand);
1088
0
        ERR_NOMEM(r < 0, state->state->info);
1089
0
        state->fsize += expand;
1090
0
    }
1091
1092
0
    state->fused += 1;
1093
1094
0
    struct frame *top = top_frame(state);
1095
0
    MEMZERO(top, 1);
1096
0
    top->lens = lens;
1097
0
    return top;
1098
0
 error:
1099
0
    return NULL;
1100
0
}
1101
1102
0
static struct frame *pop_frame(struct rec_state *state) {
1103
0
    ensure0(state->fused > 0, state->state->info);
1104
1105
0
    struct frame *result = top_frame(state);
1106
0
    state->fused -= 1;
1107
0
    return result;
1108
0
}
1109
1110
static void dbg_visit(struct lens *lens, char action, size_t start, size_t end,
1111
0
                      int fused, int lvl) {
1112
0
    char *lns;
1113
0
    for (int i=0; i < lvl; i++)
1114
0
        fputc(' ', stderr);
1115
0
    lns = format_lens(lens);
1116
0
    fprintf(stderr, "%c %zd..%zd %d %s\n", action, start, end,
1117
0
            fused, lns);
1118
0
    free(lns);
1119
0
}
1120
1121
static void get_terminal(struct frame *top, struct lens *lens,
1122
0
                         struct state *state) {
1123
0
    top->tree = get_lens(lens, state);
1124
0
    top->key = state->key;
1125
0
    top->value = state->value;
1126
0
    state->key = NULL;
1127
0
    state->value = NULL;
1128
0
}
1129
1130
static void parse_terminal(struct frame *top, struct lens *lens,
1131
0
                           struct state *state) {
1132
0
    top->dict = NULL;
1133
0
    top->skel = parse_lens(lens, state, &top->dict);
1134
0
    top->key = state->key;
1135
0
    state->key = NULL;
1136
0
}
1137
1138
static void visit_terminal(struct lens *lens, size_t start, size_t end,
1139
0
                           void *data) {
1140
0
    struct rec_state *rec_state = data;
1141
0
    struct state *state = rec_state->state;
1142
0
    struct ast *child;
1143
1144
0
    if (state->error != NULL)
1145
0
        return;
1146
1147
0
    SAVE_REGS(state);
1148
0
    if (debugging("cf.get"))
1149
0
        dbg_visit(lens, 'T', start, end, rec_state->fused, rec_state->lvl);
1150
0
    match(state, lens, lens->ctype, end, start);
1151
0
    struct frame *top = push_frame(rec_state, lens);
1152
0
    ERR_BAIL(state->info);
1153
0
    if (rec_state->mode == M_GET)
1154
0
        get_terminal(top, lens, state);
1155
0
    else
1156
0
        parse_terminal(top, lens, state);
1157
0
    child = ast_append(rec_state, lens, start, end);
1158
0
    ERR_NOMEM(child == NULL, state->info);
1159
0
 error:
1160
0
    RESTORE_REGS(state);
1161
0
}
1162
1163
0
static bool rec_gen_span(struct rec_state *rec_state) {
1164
0
    return ((rec_state->mode == M_GET) && (rec_state->state->enable_span));
1165
0
}
1166
1167
static void visit_enter(struct lens *lens,
1168
                        ATTRIBUTE_UNUSED size_t start,
1169
                        ATTRIBUTE_UNUSED size_t end,
1170
0
                        void *data) {
1171
0
    struct rec_state *rec_state = data;
1172
0
    struct state *state = rec_state->state;
1173
0
    struct ast *child;
1174
1175
0
    if (state->error != NULL)
1176
0
        return;
1177
1178
0
    if (debugging("cf.get"))
1179
0
        dbg_visit(lens, '{', start, end, rec_state->fused, rec_state->lvl);
1180
0
    rec_state->lvl += 1;
1181
0
    if (lens->tag == L_SUBTREE) {
1182
        /* Same for parse and get */
1183
        /* Use this frame to preserve the current state before we process
1184
           the contents of the subtree, i.e., lens->child */
1185
0
        struct frame *f = push_frame(rec_state, lens);
1186
0
        ERR_BAIL(state->info);
1187
0
        f->key = state->key;
1188
0
        f->value = state->value;
1189
0
        state->key = NULL;
1190
0
        state->value = NULL;
1191
0
        if (rec_gen_span(rec_state)) {
1192
0
            f->span = state->span;
1193
0
            state->span = make_span(state->info);
1194
0
            ERR_NOMEM(state->span == NULL, state->info);
1195
0
        }
1196
0
    } else if (lens->tag == L_MAYBE) {
1197
        /* Push a frame as a marker so we can tell whether lens->child
1198
           actually had a match or not */
1199
0
        push_frame(rec_state, lens);
1200
0
        ERR_BAIL(state->info);
1201
0
    }
1202
0
    child = ast_append(rec_state, lens, start, end);
1203
0
    if (child != NULL)
1204
0
        rec_state->ast = child;
1205
0
 error:
1206
0
    return;
1207
0
}
1208
1209
/* Combine n frames from the stack into one new frame for M_GET */
1210
static void get_combine(struct rec_state *rec_state,
1211
0
                        struct lens *lens, uint n) {
1212
0
    struct tree *tree = NULL, *tail = NULL;
1213
0
    char *key = NULL, *value = NULL;
1214
0
    struct frame *top = NULL;
1215
1216
0
    for (int i=0; i < n; i++) {
1217
0
        top = pop_frame(rec_state);
1218
0
        ERR_BAIL(lens->info);
1219
0
        list_tail_cons(tree, tail, top->tree);
1220
        /* top->tree might have more than one node, update tail */
1221
0
        if (tail != NULL)
1222
0
            while (tail->next != NULL) tail = tail->next;
1223
1224
0
        if (top->key != NULL) {
1225
0
            ensure(key == NULL, rec_state->state->info);
1226
0
            key = top->key;
1227
0
        }
1228
0
        if (top->value != NULL) {
1229
0
            ensure(value == NULL, rec_state->state->info);
1230
0
            value = top->value;
1231
0
        }
1232
0
    }
1233
0
    top = push_frame(rec_state, lens);
1234
0
    ERR_BAIL(lens->info);
1235
0
    top->tree = tree;
1236
0
    top->key = key;
1237
0
    top->value = value;
1238
0
 error:
1239
0
    return;
1240
0
}
1241
1242
/* Combine n frames from the stack into one new frame for M_PUT */
1243
static void parse_combine(struct rec_state *rec_state,
1244
0
                          struct lens *lens, uint n) {
1245
0
    struct skel *skel = make_skel(lens), *tail = NULL;
1246
0
    struct dict *dict = NULL;
1247
0
    char *key = NULL;
1248
0
    struct frame *top = NULL;
1249
1250
0
    for (int i=0; i < n; i++) {
1251
0
        top = pop_frame(rec_state);
1252
0
        ERR_BAIL(lens->info);
1253
0
        list_tail_cons(skel->skels, tail, top->skel);
1254
        /* top->skel might have more than one node, update skel */
1255
0
        if (tail != NULL)
1256
0
            while (tail->next != NULL) tail = tail->next;
1257
0
        dict_append(&dict, top->dict);
1258
0
        if (top->key != NULL) {
1259
0
            ensure(key == NULL, rec_state->state->info);
1260
0
            key = top->key;
1261
0
        }
1262
0
    }
1263
0
    top = push_frame(rec_state, lens);
1264
0
    ERR_BAIL(lens->info);
1265
0
    top->skel = move(skel);
1266
0
    top->dict = move(dict);
1267
0
    top->key = key;
1268
0
 error:
1269
0
    free_skel(skel);
1270
0
    free_dict(dict);
1271
0
    return;
1272
0
}
1273
1274
static void visit_exit_put_subtree(struct lens *lens,
1275
                                   struct rec_state *rec_state,
1276
0
                                   struct frame *top) {
1277
0
    struct state *state = rec_state->state;
1278
0
    struct skel *skel = NULL;
1279
0
    struct dict *dict = NULL;
1280
1281
0
    skel = make_skel(lens);
1282
0
    ERR_NOMEM(skel == NULL, lens->info);
1283
0
    dict = make_dict(top->key, top->skel, top->dict);
1284
0
    ERR_NOMEM(dict == NULL, lens->info);
1285
1286
0
    top = pop_frame(rec_state);
1287
0
    ERR_BAIL(state->info);
1288
0
    ensure(lens == top->lens, state->info);
1289
0
    state->key = top->key;
1290
0
    top = push_frame(rec_state, lens);
1291
0
    ERR_BAIL(state->info);
1292
0
    top->skel = move(skel);
1293
0
    top->dict = move(dict);
1294
0
 error:
1295
0
    free_skel(skel);
1296
0
    free_dict(dict);
1297
0
}
1298
1299
static void visit_exit(struct lens *lens,
1300
                       ATTRIBUTE_UNUSED size_t start,
1301
                       ATTRIBUTE_UNUSED size_t end,
1302
0
                       void *data) {
1303
0
    struct rec_state *rec_state = data;
1304
0
    struct state *state = rec_state->state;
1305
0
    struct tree *tree = NULL;
1306
1307
0
    if (state->error != NULL)
1308
0
        return;
1309
1310
0
    rec_state->lvl -= 1;
1311
0
    if (debugging("cf.get"))
1312
0
        dbg_visit(lens, '}', start, end, rec_state->fused, rec_state->lvl);
1313
1314
0
    ERR_BAIL(lens->info);
1315
1316
0
    if (lens->tag == L_SUBTREE) {
1317
        /* Get the result of parsing lens->child */
1318
0
        struct frame *top = pop_frame(rec_state);
1319
0
        ERR_BAIL(state->info);
1320
0
        if (rec_state->mode == M_GET) {
1321
0
            tree = make_tree(top->key, top->value, NULL, top->tree);
1322
0
            ERR_NOMEM(tree == NULL, lens->info);
1323
0
            tree->span = state->span;
1324
            /* Restore the parse state from before entering this subtree */
1325
0
            top = pop_frame(rec_state);
1326
0
            ERR_BAIL(state->info);
1327
0
            ensure(lens == top->lens, state->info);
1328
0
            state->key = top->key;
1329
0
            state->value = top->value;
1330
0
            state->span = top->span;
1331
            /* Push the result of parsing this subtree */
1332
0
            top = push_frame(rec_state, lens);
1333
0
            ERR_BAIL(state->info);
1334
0
            top->tree = move(tree);
1335
0
        } else {
1336
0
            visit_exit_put_subtree(lens, rec_state, top);
1337
0
        }
1338
0
    } else if (lens->tag == L_CONCAT) {
1339
0
        ensure(rec_state->fused >= lens->nchildren, state->info);
1340
0
        for (int i = 0; i < lens->nchildren; i++) {
1341
0
            struct frame *fr = nth_frame(rec_state, i);
1342
0
            ERR_BAIL(state->info);
1343
0
            BUG_ON(lens->children[i] != fr->lens,
1344
0
                    lens->info,
1345
0
             "Unexpected lens in concat %zd..%zd\n  Expected: %s\n  Actual: %s",
1346
0
                    start, end,
1347
0
                    format_lens(lens->children[i]),
1348
0
                    format_lens(fr->lens));
1349
0
        }
1350
0
        rec_state->combine(rec_state, lens, lens->nchildren);
1351
0
    } else if (lens->tag == L_STAR) {
1352
0
        uint n = 0;
1353
0
        while (n < rec_state->fused &&
1354
0
               nth_frame(rec_state, n)->lens == lens->child)
1355
0
            n++;
1356
0
        ERR_BAIL(state->info);
1357
0
        rec_state->combine(rec_state, lens, n);
1358
0
    } else if (lens->tag == L_MAYBE) {
1359
0
        uint n = 1;
1360
0
        if (rec_state->fused > 0
1361
0
            && top_frame(rec_state)->lens == lens->child) {
1362
0
            n = 2;
1363
0
        }
1364
0
        ERR_BAIL(state->info);
1365
        /* If n = 2, the top of the stack is our child's result, and the
1366
           frame underneath it is the marker frame we pushed during
1367
           visit_enter. Combine these two frames into one, which represents
1368
           the result of parsing the whole L_MAYBE. */
1369
0
        rec_state->combine(rec_state, lens, n);
1370
0
    } else if (lens->tag == L_SQUARE) {
1371
0
        if (rec_state->mode == M_GET) {
1372
0
            struct ast *square, *concat, *right, *left;
1373
0
            char *rsqr, *lsqr;
1374
0
            int ret;
1375
1376
0
            square = rec_state->ast;
1377
0
            concat = child_first(square);
1378
0
            right = child_first(concat);
1379
0
            left = child_last(concat);
1380
0
            lsqr = token_range(state->text, left->start, left->end);
1381
0
            rsqr = token_range(state->text, right->start, right->end);
1382
0
            ret = square_match(lens, lsqr, rsqr);
1383
0
            if (! ret) {
1384
0
                get_error(state, lens, "%s \"%s\" %s \"%s\"",
1385
0
                        "Parse error: mismatched in square lens, expecting", lsqr,
1386
0
                        "but got", rsqr);
1387
0
            }
1388
0
            FREE(lsqr);
1389
0
            FREE(rsqr);
1390
0
            if (! ret)
1391
0
                goto error;
1392
0
        }
1393
0
        rec_state->combine(rec_state, lens, 1);
1394
0
    } else {
1395
        /* Turn the top frame from having the result of one of our children
1396
           to being our result */
1397
0
        top_frame(rec_state)->lens = lens;
1398
0
        ERR_BAIL(state->info);
1399
0
    }
1400
0
    ast_pop(rec_state);
1401
0
 error:
1402
0
    free_tree(tree);
1403
0
    return;
1404
0
}
1405
1406
static void visit_error(struct lens *lens, void *data, size_t pos,
1407
0
                        const char *format, ...) {
1408
0
    struct rec_state *rec_state = data;
1409
0
    va_list ap;
1410
1411
0
    va_start(ap, format);
1412
0
    vget_error(rec_state->state, lens, format, ap);
1413
0
    va_end(ap);
1414
0
    rec_state->state->error->pos = rec_state->start + pos;
1415
0
}
1416
1417
static struct frame *rec_process(enum mode_t mode, struct lens *lens,
1418
0
                                 struct state *state) {
1419
0
    uint end = REG_END(state);
1420
0
    uint start = REG_START(state);
1421
0
    size_t len = 0;
1422
0
    int r;
1423
0
    struct jmt_visitor visitor;
1424
0
    struct rec_state rec_state;
1425
0
    int i;
1426
0
    struct frame *f = NULL;
1427
1428
0
    MEMZERO(&rec_state, 1);
1429
0
    MEMZERO(&visitor, 1);
1430
0
    SAVE_REGS(state);
1431
1432
0
    if (lens->jmt == NULL) {
1433
0
        lens->jmt = jmt_build(lens);
1434
0
        ERR_BAIL(lens->info);
1435
0
    }
1436
1437
0
    rec_state.mode  = mode;
1438
0
    rec_state.state = state;
1439
0
    rec_state.fused = 0;
1440
0
    rec_state.lvl   = 0;
1441
0
    rec_state.start = start;
1442
0
    rec_state.ast = make_ast(lens);
1443
0
    rec_state.combine = (mode == M_GET) ? get_combine : parse_combine;
1444
0
    ERR_NOMEM(rec_state.ast == NULL, state->info);
1445
1446
0
    visitor.parse = jmt_parse(lens->jmt, state->text + start, end - start);
1447
0
    ERR_BAIL(lens->info);
1448
0
    visitor.terminal = visit_terminal;
1449
0
    visitor.enter = visit_enter;
1450
0
    visitor.exit = visit_exit;
1451
0
    visitor.error = visit_error;
1452
0
    visitor.data = &rec_state;
1453
0
    r = jmt_visit(&visitor, &len);
1454
0
    ERR_BAIL(lens->info);
1455
0
    if (r != 1) {
1456
0
        get_error(state, lens, "Syntax error");
1457
0
        state->error->pos = start + len;
1458
0
    }
1459
0
    if (rec_state.fused == 0) {
1460
0
        get_error(state, lens,
1461
0
                  "Parse did not leave a result on the stack");
1462
0
        goto error;
1463
0
    } else if (rec_state.fused > 1) {
1464
0
        get_error(state, lens,
1465
0
                  "Parse left additional garbage on the stack");
1466
0
        goto error;
1467
0
    }
1468
1469
0
    rec_state.ast = ast_root(rec_state.ast);
1470
0
    ensure(rec_state.ast->parent == NULL, state->info);
1471
0
 done:
1472
0
    if (debugging("cf.get.ast"))
1473
0
        print_ast(ast_root(rec_state.ast), 0);
1474
0
    RESTORE_REGS(state);
1475
0
    jmt_free_parse(visitor.parse);
1476
0
    free_ast(ast_root(rec_state.ast));
1477
0
    return rec_state.frames;
1478
0
 error:
1479
1480
0
    for(i = 0; i < rec_state.fused; i++) {
1481
0
        f = nth_frame(&rec_state, i);
1482
0
        FREE(f->key);
1483
0
        free_span(f->span);
1484
0
        if (mode == M_GET) {
1485
0
            FREE(f->value);
1486
0
            free_tree(f->tree);
1487
0
        } else if (mode == M_PARSE) {
1488
0
            free_skel(f->skel);
1489
0
            free_dict(f->dict);
1490
0
        }
1491
0
    }
1492
0
    FREE(rec_state.frames);
1493
0
    goto done;
1494
0
}
1495
1496
0
static struct tree *get_rec(struct lens *lens, struct state *state) {
1497
0
    struct frame *fr;
1498
0
    struct tree *tree = NULL;
1499
1500
0
    fr = rec_process(M_GET, lens, state);
1501
0
    if (fr != NULL) {
1502
0
        tree = fr->tree;
1503
0
        state->key = fr->key;
1504
0
        state->value = fr->value;
1505
0
        FREE(fr);
1506
0
    }
1507
0
    return tree;
1508
0
}
1509
1510
static struct skel *parse_rec(struct lens *lens, struct state *state,
1511
0
                              struct dict **dict) {
1512
0
    struct skel *skel = NULL;
1513
0
    struct frame *fr;
1514
1515
0
    fr = rec_process(M_PARSE, lens, state);
1516
0
    if (fr != NULL) {
1517
0
        skel = fr->skel;
1518
0
        *dict = fr->dict;
1519
0
        state->key = fr->key;
1520
0
        FREE(fr);
1521
0
    }
1522
0
    return skel;
1523
0
}
1524
1525
0
static struct tree *get_lens(struct lens *lens, struct state *state) {
1526
0
    struct tree *tree = NULL;
1527
1528
0
    switch(lens->tag) {
1529
0
    case L_DEL:
1530
0
        tree = get_del(lens, state);
1531
0
        break;
1532
0
    case L_STORE:
1533
0
        tree = get_store(lens, state);
1534
0
        break;
1535
0
    case L_VALUE:
1536
0
        tree = get_value(lens, state);
1537
0
        break;
1538
0
    case L_KEY:
1539
0
        tree = get_key(lens, state);
1540
0
        break;
1541
0
    case L_LABEL:
1542
0
        tree = get_label(lens, state);
1543
0
        break;
1544
0
    case L_SEQ:
1545
0
        tree = get_seq(lens, state);
1546
0
        break;
1547
0
    case L_COUNTER:
1548
0
        tree = get_counter(lens, state);
1549
0
        break;
1550
0
    case L_CONCAT:
1551
0
        tree = get_concat(lens, state);
1552
0
        break;
1553
0
    case L_UNION:
1554
0
        tree = get_union(lens, state);
1555
0
        break;
1556
0
    case L_SUBTREE:
1557
0
        tree = get_subtree(lens, state);
1558
0
        break;
1559
0
    case L_STAR:
1560
0
        tree = get_quant_star(lens, state);
1561
0
        break;
1562
0
    case L_MAYBE:
1563
0
        tree = get_quant_maybe(lens, state);
1564
0
        break;
1565
0
    case L_SQUARE:
1566
0
        tree = get_square(lens, state);
1567
0
        break;
1568
0
    default:
1569
0
        BUG_ON(true, state->info, "illegal lens tag %d", lens->tag);
1570
0
        break;
1571
0
    }
1572
0
 error:
1573
0
    return tree;
1574
0
}
1575
1576
/* Initialize registers. Return 0 if the lens matches the entire text, 1 if
1577
 * it does not and -1 on error.
1578
 */
1579
0
static int init_regs(struct state *state, struct lens *lens, uint size) {
1580
0
    int r;
1581
1582
0
    if (lens->tag != L_STAR && ! lens->recursive) {
1583
0
        r = match(state, lens, lens->ctype, size, 0);
1584
0
        if (r == -1)
1585
0
            get_error(state, lens, "Input string does not match at all");
1586
0
        if (r <= -1)
1587
0
            return -1;
1588
0
        return r != size;
1589
0
    }
1590
    /* Special case the very common situation that the lens is (l)*
1591
     * We can avoid matching the entire text in that case - that
1592
     * match can be very expensive
1593
     */
1594
0
    if (ALLOC(state->regs) < 0)
1595
0
        return -1;
1596
0
    state->regs->num_regs = 1;
1597
0
    if (ALLOC(state->regs->start) < 0 || ALLOC(state->regs->end) < 0)
1598
0
        return -1;
1599
0
    state->regs->start[0] = 0;
1600
0
    state->regs->end[0] = size;
1601
0
    return 0;
1602
0
}
1603
1604
struct tree *lns_get(struct info *info, struct lens *lens, const char *text,
1605
0
                     int enable_span, struct lns_error **err) {
1606
0
    struct state state;
1607
0
    struct tree *tree = NULL;
1608
0
    uint size = strlen(text);
1609
0
    int partial, r;
1610
1611
0
    MEMZERO(&state, 1);
1612
0
    r = ALLOC(state.info);
1613
0
    ERR_NOMEM(r < 0, info);
1614
1615
0
    *state.info = *info;
1616
0
    state.info->ref = UINT_MAX;
1617
1618
0
    state.text = text;
1619
1620
0
    state.enable_span = enable_span;
1621
1622
    /* We are probably being overly cautious here: if the lens can't process
1623
     * all of TEXT, we should really fail somewhere in one of the sublenses.
1624
     * But to be safe, we check that we can process everything anyway, then
1625
     * try to process, hoping we'll get a more specific error, and if that
1626
     * fails, we throw our arms in the air and say 'something went wrong'
1627
     */
1628
0
    partial = init_regs(&state, lens, size);
1629
0
    if (partial >= 0) {
1630
0
        if (lens->recursive)
1631
0
            tree = get_rec(lens, &state);
1632
0
        else
1633
0
            tree = get_lens(lens, &state);
1634
0
    }
1635
1636
0
    free_seqs(state.seqs);
1637
0
    if (state.key != NULL) {
1638
0
        get_error(&state, lens, "get left unused key %s", state.key);
1639
0
        free(state.key);
1640
0
    }
1641
0
    if (state.value != NULL) {
1642
0
        get_error(&state, lens, "get left unused value %s", state.value);
1643
0
        free(state.value);
1644
0
    }
1645
0
    if (partial && state.error == NULL) {
1646
0
        get_error(&state, lens, "Get did not match entire input");
1647
0
    }
1648
1649
0
 error:
1650
0
    free_regs(&state);
1651
0
    FREE(state.info);
1652
1653
0
    if (err != NULL) {
1654
0
        *err = state.error;
1655
0
    } else {
1656
0
        if (state.error != NULL) {
1657
0
            free_tree(tree);
1658
0
            tree = NULL;
1659
0
        }
1660
0
        free_lns_error(state.error);
1661
0
    }
1662
0
    return tree;
1663
0
}
1664
1665
static struct skel *parse_lens(struct lens *lens, struct state *state,
1666
0
                               struct dict **dict) {
1667
0
    struct skel *skel = NULL;
1668
1669
0
    switch(lens->tag) {
1670
0
    case L_DEL:
1671
0
        skel = parse_del(lens, state);
1672
0
        break;
1673
0
    case L_STORE:
1674
0
        skel = parse_store(lens, state);
1675
0
        break;
1676
0
    case L_VALUE:
1677
0
        skel = parse_value(lens, state);
1678
0
        break;
1679
0
    case L_KEY:
1680
0
        skel = parse_key(lens, state);
1681
0
        break;
1682
0
    case L_LABEL:
1683
0
        skel = parse_label(lens, state);
1684
0
        break;
1685
0
    case L_SEQ:
1686
0
        skel = parse_seq(lens, state);
1687
0
        break;
1688
0
    case L_COUNTER:
1689
0
        skel = parse_counter(lens, state);
1690
0
        break;
1691
0
    case L_CONCAT:
1692
0
        skel = parse_concat(lens, state, dict);
1693
0
        break;
1694
0
    case L_UNION:
1695
0
        skel = parse_union(lens, state, dict);
1696
0
        break;
1697
0
    case L_SUBTREE:
1698
0
        skel = parse_subtree(lens, state, dict);
1699
0
        break;
1700
0
    case L_STAR:
1701
0
        skel = parse_quant_star(lens, state, dict);
1702
0
        break;
1703
0
    case L_MAYBE:
1704
0
        skel = parse_quant_maybe(lens, state, dict);
1705
0
        break;
1706
0
    case L_SQUARE:
1707
0
        skel = parse_square(lens, state, dict);
1708
0
        break;
1709
0
    default:
1710
0
        BUG_ON(true, state->info, "illegal lens tag %d", lens->tag);
1711
0
        break;
1712
0
    }
1713
0
 error:
1714
0
    return skel;
1715
0
}
1716
1717
struct skel *lns_parse(struct lens *lens, const char *text, struct dict **dict,
1718
0
                       struct lns_error **err) {
1719
0
    struct state state;
1720
0
    struct skel *skel = NULL;
1721
0
    uint size = strlen(text);
1722
0
    int partial, r;
1723
1724
0
    MEMZERO(&state, 1);
1725
0
    r = ALLOC(state.info);
1726
0
    ERR_NOMEM(r< 0, lens->info);
1727
0
    state.info->ref = UINT_MAX;
1728
0
    state.info->error = lens->info->error;
1729
0
    state.text = text;
1730
1731
0
    state.text = text;
1732
1733
0
    partial = init_regs(&state, lens, size);
1734
0
    if (! partial) {
1735
0
        *dict = NULL;
1736
0
        if (lens->recursive)
1737
0
            skel = parse_rec(lens, &state, dict);
1738
0
        else
1739
0
            skel = parse_lens(lens, &state, dict);
1740
1741
0
        free_seqs(state.seqs);
1742
0
        if (state.error != NULL) {
1743
0
            free_skel(skel);
1744
0
            skel = NULL;
1745
0
            free_dict(*dict);
1746
0
            *dict = NULL;
1747
0
        }
1748
0
        if (state.key != NULL) {
1749
0
            get_error(&state, lens, "parse left unused key %s", state.key);
1750
0
            free(state.key);
1751
0
        }
1752
0
        if (state.value != NULL) {
1753
0
            get_error(&state, lens, "parse left unused value %s", state.value);
1754
0
            free(state.value);
1755
0
        }
1756
0
    } else {
1757
        // This should never happen during lns_parse
1758
0
        get_error(&state, lens, "parse can not process entire input");
1759
0
    }
1760
1761
0
 error:
1762
0
    free_regs(&state);
1763
0
    FREE(state.info);
1764
0
    if (err != NULL) {
1765
0
        *err = state.error;
1766
0
    } else {
1767
0
        free_lns_error(state.error);
1768
0
    }
1769
0
    return skel;
1770
0
}
1771
1772
/*
1773
 * Local variables:
1774
 *  indent-tabs-mode: nil
1775
 *  c-indent-level: 4
1776
 *  c-basic-offset: 4
1777
 *  tab-width: 4
1778
 * End:
1779
 */