4 * Copyright (C) 2007-2016 David Lutterkort
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.
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.
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
20 * Author: David Lutterkort <dlutter@redhat.com>
31 /* Data structure to keep track of where we are in the tree. The split
32 * describes a sublist of the list of siblings in the current tree. The
33 * put_* functions don't operate on the tree directly, instead they operate
36 * The TREE field points to the first tree node for the current invocation
37 * of put_*, FOLLOW points to the first sibling following TREE that is not
38 * part of the split anymore (NULL if we are talking about all the siblings
41 * ENC is a string containing the encoding of the current position in the
42 * tree. The encoding is
43 * <label>=<value>/<label>=<value>/.../<label>=<value>/
44 * where the label/value pairs come from TREE and its
45 * siblings. The encoding uses ENC_EQ instead of the '=' above to avoid
46 * clashes with legitimate values, and encodes NULL values as ENC_NULL.
60 const struct tree *tree;
64 char *path; /* Position in the tree, for errors */
68 struct lns_error *error;
71 static void create_lens(struct lens *lens, struct state *state);
72 static void put_lens(struct lens *lens, struct state *state);
74 static void put_error(struct state *state, struct lens *lens,
75 const char *format, ...)
80 if (state->error != NULL)
83 if (ALLOC(state->error) < 0)
85 state->error->lens = ref(lens);
86 state->error->pos = -1;
87 if (strlen(state->path) == 0) {
88 state->error->path = strdup("");
90 state->error->path = strdup(state->path);
94 r = vasprintf(&state->error->message, format, ap);
97 state->error->message = NULL;
101 static int enclen(const char *key, const char *value) {
102 return ENCLEN(key) + strlen(ENC_EQ) + ENCLEN(value)
106 static char *encpcpy(char *e, const char *key, const char *value) {
107 e = stpcpy(e, ENCSTR(key));
108 e = stpcpy(e, ENC_EQ);
109 e = stpcpy(e, ENCSTR(value));
110 e = stpcpy(e, ENC_SLASH);
114 static void regexp_match_error(struct state *state, struct lens *lens,
115 int count, struct split *split) {
119 lns_format_atype(lens, &pat);
120 text = enc_format_indent(split->enc + split->start,
121 split->end - split->start,
125 put_error(state, lens,
126 "Failed to match tree under %s\n\n%s\n with pattern\n %s\n",
127 state->path, text, pat);
128 } else if (count == -2) {
129 put_error(state, lens,
130 "Internal error matching\n %s\n with tree\n %s\n",
132 } else if (count == -3) {
133 /* Should have been caught by the typechecker */
134 put_error(state, lens, "Syntax error in tree schema\n %s\n", pat);
140 static void free_split(struct split *split) {
148 /* Encode the list of TREE's children as a string.
150 static struct split *make_split(struct tree *tree) {
153 if (ALLOC(split) < 0)
157 list_for_each(t, tree) {
158 split->end += enclen(t->label, t->value);
161 if (ALLOC_N(split->enc, split->end + 1) < 0)
164 char *enc = split->enc;
165 list_for_each(t, tree) {
166 enc = encpcpy(enc, t->label, t->value);
174 static struct split *split_append(struct split **split, struct split *tail,
175 struct tree *tree, struct tree *follow,
176 char *enc, size_t start, size_t end) {
185 list_tail_cons(*split, tail, sp);
189 static struct split *next_split(struct state *state) {
190 if (state->split != NULL) {
191 state->split = state->split->next;
192 if (state->split != NULL)
193 state->pos = state->split->end;
198 static struct split *set_split(struct state *state, struct split *split) {
199 state->split = split;
201 state->pos = split->end;
205 /* Refine a tree split OUTER according to the L_CONCAT lens LENS */
206 static struct split *split_concat(struct state *state, struct lens *lens) {
207 assert(lens->tag == L_CONCAT);
210 struct split *outer = state->split;
211 struct re_registers regs;
212 struct split *split = NULL, *tail = NULL;
213 struct regexp *atype = lens->atype;
215 /* Fast path for leaf nodes, which will always lead to an empty split */
216 // FIXME: This doesn't match the empty encoding
217 if (outer->tree == NULL && strlen(outer->enc) == 0
218 && regexp_is_empty_pattern(atype)) {
219 for (int i=0; i < lens->nchildren; i++) {
220 tail = split_append(&split, tail, NULL, NULL,
229 count = regexp_match(atype, outer->enc, outer->end,
230 outer->start, ®s);
231 if (count >= 0 && count != outer->end - outer->start)
234 regexp_match_error(state, lens, count, outer);
238 struct tree *cur = outer->tree;
240 for (int i=0; i < lens->nchildren; i++) {
241 assert(reg < regs.num_regs);
242 assert(regs.start[reg] != -1);
243 struct tree *follow = cur;
244 for (int j = regs.start[reg]; j < regs.end[reg]; j++) {
245 if (outer->enc[j] == ENC_SLASH_CH)
246 follow = follow->next;
248 tail = split_append(&split, tail, cur, follow,
249 outer->enc, regs.start[reg], regs.end[reg]);
251 reg += 1 + regexp_nsub(lens->children[i]->atype);
253 assert(reg < regs.num_regs);
264 static struct split *split_iter(struct state *state, struct lens *lens) {
265 assert(lens->tag == L_STAR);
268 struct split *outer = state->split;
269 struct split *split = NULL;
270 struct regexp *atype = lens->child->atype;
272 struct tree *cur = outer->tree;
273 int pos = outer->start;
274 struct split *tail = NULL;
275 while (pos < outer->end) {
276 count = regexp_match(atype, outer->enc, outer->end, pos, NULL);
279 } else if (count < -1) {
280 regexp_match_error(state, lens->child, count, outer);
284 struct tree *follow = cur;
285 for (int j = pos; j < pos + count; j++) {
286 if (outer->enc[j] == ENC_SLASH_CH)
287 follow = follow->next;
289 tail = split_append(&split, tail, cur, follow,
290 outer->enc, pos, pos + count);
300 /* Check if LENS applies to the current split in STATE */
301 static int applies(struct lens *lens, struct state *state) {
303 struct split *split = state->split;
305 count = regexp_match(lens->atype, split->enc, split->end,
308 regexp_match_error(state, lens, count, split);
312 if (count != split->end - split->start)
314 if (count == 0 && lens->value)
315 return state->tree->value != NULL;
320 * Check whether SKEL has the skeleton type required by LENS
323 static int skel_instance_of(struct lens *lens, struct skel *skel) {
330 if (skel->tag != L_DEL)
332 count = regexp_match(lens->regexp, skel->text, strlen(skel->text),
334 return count == strlen(skel->text);
337 return skel->tag == L_STORE;
339 return skel->tag == L_KEY;
341 return skel->tag == L_LABEL;
343 return skel->tag == L_VALUE;
345 return skel->tag == L_SEQ;
347 return skel->tag == L_COUNTER;
350 if (skel->tag != L_CONCAT)
352 struct skel *s = skel->skels;
353 for (int i=0; i < lens->nchildren; i++) {
354 if (! skel_instance_of(lens->children[i], s))
363 for (int i=0; i < lens->nchildren; i++) {
364 if (skel_instance_of(lens->children[i], skel))
371 return skel->tag == L_SUBTREE;
373 return skel->tag == L_MAYBE || skel_instance_of(lens->child, skel);
375 if (skel->tag != L_STAR)
377 list_for_each(s, skel->skels) {
378 if (! skel_instance_of(lens->child, s))
383 return skel_instance_of(lens->body, skel);
385 return skel->tag == L_SQUARE
386 && skel_instance_of(lens->child, skel->skels);
388 BUG_ON(true, lens->info, "illegal lens tag %d", lens->tag);
395 enum span_kind { S_NONE, S_LABEL, S_VALUE };
397 static void emit(struct state *state, const char *text, enum span_kind kind) {
398 struct span* span = state->tree->span;
401 long start = ftell(state->out);
402 if (kind == S_LABEL) {
403 span->label_start = start;
404 } else if (kind == S_VALUE) {
405 span->value_start = start;
408 fprintf(state->out, "%s", text);
410 long end = ftell(state->out);
411 if (kind == S_LABEL) {
412 span->label_end = end;
413 } else if (kind == S_VALUE) {
414 span->value_end = end;
422 static void put_subtree(struct lens *lens, struct state *state) {
423 assert(lens->tag == L_SUBTREE);
424 struct state oldstate = *state;
425 struct split oldsplit = *state->split;
426 char * oldpath = state->path;
428 struct tree *tree = state->split->tree;
429 struct split *split = NULL;
432 state->path = path_of_tree(tree);
434 split = make_split(tree->children);
435 set_split(state, split);
437 dict_lookup(tree->label, state->dict, &state->skel, &state->dict);
438 if (state->with_span) {
439 if (tree->span == NULL) {
440 tree->span = make_span(state->info);
442 tree->span->span_start = ftell(state->out);
444 if (state->skel == NULL || ! skel_instance_of(lens->child, state->skel)) {
445 create_lens(lens->child, state);
447 put_lens(lens->child, state);
449 assert(state->error != NULL || state->split->next == NULL);
450 if (tree->span != NULL) {
451 tree->span->span_end = ftell(state->out);
454 oldstate.error = state->error;
455 oldstate.path = state->path;
457 *state->split= oldsplit;
460 state->path = oldpath;
463 static void put_del(ATTRIBUTE_UNUSED struct lens *lens, struct state *state) {
464 assert(lens->tag == L_DEL);
465 assert(state->skel != NULL);
466 assert(state->skel->tag == L_DEL);
467 if (state->override != NULL) {
468 emit(state, state->override, S_NONE);
470 emit(state, state->skel->text, S_NONE);
474 static void put_union(struct lens *lens, struct state *state) {
475 assert(lens->tag == L_UNION);
477 for (int i=0; i < lens->nchildren; i++) {
478 struct lens *l = lens->children[i];
479 if (applies(l, state)) {
480 if (skel_instance_of(l, state->skel))
483 create_lens(l, state);
487 put_error(state, lens, "None of the alternatives in the union match");
490 static void put_concat(struct lens *lens, struct state *state) {
491 assert(lens->tag == L_CONCAT);
492 struct split *oldsplit = state->split;
493 struct skel *oldskel = state->skel;
495 struct split *split = split_concat(state, lens);
497 state->skel = state->skel->skels;
498 set_split(state, split);
499 for (int i=0; i < lens->nchildren; i++) {
500 if (state->split == NULL) {
501 put_error(state, lens,
502 "Not enough components in concat");
506 put_lens(lens->children[i], state);
507 state->skel = state->skel->next;
511 set_split(state, oldsplit);
512 state->skel = oldskel;
515 static void error_quant_star(struct split *last_split, struct lens *lens,
516 struct state *state, const char *enc) {
517 struct tree *child = NULL;
518 if (last_split != NULL) {
519 if (last_split->follow != NULL) {
520 child = last_split->follow;
522 for (child = last_split->tree;
523 child != NULL && child->next != NULL;
524 child = child->next);
530 lns_format_atype(lens, &pat);
531 text = enc_format_indent(enc, strlen(enc), 4);
534 put_error(state, lens,
535 "Missing a node: can not match tree\n\n%s\n with pattern\n %s\n",
538 char *s = path_of_tree(child);
539 put_error(state, lens,
540 "Unexpected node '%s': can not match tree\n\n%s\n with pattern\n %s\n",
548 static void put_quant_star(struct lens *lens, struct state *state) {
549 assert(lens->tag == L_STAR);
550 struct split *oldsplit = state->split;
551 struct skel *oldskel = state->skel;
552 struct split *last_split = NULL;
554 struct split *split = split_iter(state, lens);
556 state->skel = state->skel->skels;
557 set_split(state, split);
558 last_split = state->split;
559 while (state->split != NULL && state->skel != NULL) {
560 put_lens(lens->child, state);
561 state->skel = state->skel->next;
562 last_split = state->split;
565 while (state->split != NULL) {
566 create_lens(lens->child, state);
567 last_split = state->split;
570 if (state->pos != oldsplit->end)
571 error_quant_star(last_split, lens, state, oldsplit->enc + state->pos);
573 set_split(state, oldsplit);
574 state->skel = oldskel;
577 static void put_quant_maybe(struct lens *lens, struct state *state) {
578 assert(lens->tag == L_MAYBE);
579 struct lens *child = lens->child;
581 if (applies(child, state)) {
582 if (skel_instance_of(child, state->skel))
583 put_lens(child, state);
585 create_lens(child, state);
589 static void put_store(struct lens *lens, struct state *state) {
590 const char *value = state->tree->value;
593 put_error(state, lens,
594 "Can not store a nonexistent (NULL) value");
595 } else if (regexp_match(lens->regexp, value, strlen(value),
596 0, NULL) != strlen(value)) {
597 char *pat = regexp_escape(lens->regexp);
598 put_error(state, lens,
599 "Value '%s' does not match regexp /%s/ in store lens",
603 emit(state, value, S_VALUE);
607 static void put_rec(struct lens *lens, struct state *state) {
608 put_lens(lens->body, state);
611 static void put_square(struct lens *lens, struct state *state) {
612 assert(lens->tag == L_SQUARE);
613 struct skel *oldskel = state->skel;
614 struct split *oldsplit = state->split;
615 struct lens *concat = lens->child;
616 struct lens *left = concat->children[0];
617 struct split *split = split_concat(state, concat);
619 /* skels of concat is one depth more */
620 state->skel = state->skel->skels->skels;
621 set_split(state, split);
622 for (int i=0; i < concat->nchildren; i++) {
623 if (state->split == NULL) {
624 put_error(state, concat, "Not enough components in square");
628 struct lens *curr = concat->children[i];
629 if (i == (concat->nchildren - 1) && left->tag == L_KEY)
630 state->override = state->tree->label;
631 put_lens(curr, state);
632 state->override = NULL;
633 state->skel = state->skel->next;
637 set_split(state, oldsplit);
638 state->skel = oldskel;
641 static void put_lens(struct lens *lens, struct state *state) {
642 if (state->error != NULL)
647 put_del(lens, state);
650 put_store(lens, state);
653 emit(state, state->tree->label, S_LABEL);
666 put_concat(lens, state);
669 put_union(lens, state);
672 put_subtree(lens, state);
675 put_quant_star(lens, state);
678 put_quant_maybe(lens, state);
681 put_rec(lens, state);
684 put_square(lens, state);
692 static void create_subtree(struct lens *lens, struct state *state) {
693 put_subtree(lens, state);
696 static void create_del(struct lens *lens, struct state *state) {
697 assert(lens->tag == L_DEL);
698 if (state->override != NULL) {
699 emit(state, state->override, S_NONE);
701 emit(state, lens->string->str, S_NONE);
705 static void create_union(struct lens *lens, struct state *state) {
706 assert(lens->tag == L_UNION);
708 for (int i=0; i < lens->nchildren; i++) {
709 if (applies(lens->children[i], state)) {
710 create_lens(lens->children[i], state);
714 put_error(state, lens, "None of the alternatives in the union match");
717 static void create_concat(struct lens *lens, struct state *state) {
718 assert(lens->tag == L_CONCAT);
719 struct split *oldsplit = state->split;
721 struct split *split = split_concat(state, lens);
723 set_split(state, split);
724 for (int i=0; i < lens->nchildren; i++) {
725 if (state->split == NULL) {
726 put_error(state, lens,
727 "Not enough components in concat");
731 create_lens(lens->children[i], state);
735 set_split(state, oldsplit);
738 static void create_square(struct lens *lens, struct state *state) {
739 assert(lens->tag == L_SQUARE);
740 struct lens *concat = lens->child;
742 struct split *oldsplit = state->split;
743 struct split *split = split_concat(state, concat);
744 struct lens *left = concat->children[0];
746 set_split(state, split);
747 for (int i=0; i < concat->nchildren; i++) {
748 if (state->split == NULL) {
749 put_error(state, concat, "Not enough components in square");
753 struct lens *curr = concat->children[i];
754 if (i == (concat->nchildren - 1) && left->tag == L_KEY)
755 state->override = state->tree->label;
756 create_lens(curr, state);
757 state->override = NULL;
761 set_split(state, oldsplit);
764 static void create_quant_star(struct lens *lens, struct state *state) {
765 assert(lens->tag == L_STAR);
766 struct split *oldsplit = state->split;
767 struct split *last_split = NULL;
769 struct split *split = split_iter(state, lens);
771 set_split(state, split);
772 last_split = state->split;
773 while (state->split != NULL) {
774 create_lens(lens->child, state);
775 last_split = state->split;
778 if (state->pos != oldsplit->end)
779 error_quant_star(last_split, lens, state, oldsplit->enc + state->pos);
781 set_split(state, oldsplit);
784 static void create_quant_maybe(struct lens *lens, struct state *state) {
785 assert(lens->tag == L_MAYBE);
787 if (applies(lens->child, state)) {
788 create_lens(lens->child, state);
792 static void create_rec(struct lens *lens, struct state *state) {
793 create_lens(lens->body, state);
796 static void create_lens(struct lens *lens, struct state *state) {
797 if (state->error != NULL)
801 create_del(lens, state);
804 put_store(lens, state);
807 emit(state, state->tree->label, S_LABEL);
820 create_concat(lens, state);
823 create_union(lens, state);
826 create_subtree(lens, state);
829 create_quant_star(lens, state);
832 create_quant_maybe(lens, state);
835 create_rec(lens, state);
838 create_square(lens, state);
846 void lns_put(struct info *info, FILE *out, struct lens *lens, struct tree *tree,
847 const char *text, int enable_span, struct lns_error **err) {
849 struct lns_error *err1;
857 state.path = strdup("/");
858 state.skel = lns_parse(lens, text, &state.dict, &err1);
864 free_lns_error(err1);
868 state.split = make_split(tree);
869 state.with_span = enable_span;
872 if (state.with_span) {
873 if (tree->span == NULL) {
874 tree->span = make_span(info);
876 tree->span->span_start = ftell(out);
878 put_lens(lens, &state);
879 if (state.with_span) {
880 tree->span->span_end = ftell(out);
885 free_lns_error(state.error);
890 free_split(state.split);
891 free_skel(state.skel);
892 free_dict(state.dict);
897 * indent-tabs-mode: nil