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 CALLOC(state->error, 1);
84 state->error->lens = ref(lens);
85 state->error->pos = -1;
86 if (strlen(state->path) == 0) {
87 state->error->path = strdup("");
89 state->error->path = strdup(state->path);
93 r = vasprintf(&state->error->message, format, ap);
96 state->error->message = NULL;
100 static int enclen(const char *key, const char *value) {
101 return ENCLEN(key) + strlen(ENC_EQ) + ENCLEN(value)
105 static char *encpcpy(char *e, const char *key, const char *value) {
106 e = stpcpy(e, ENCSTR(key));
107 e = stpcpy(e, ENC_EQ);
108 e = stpcpy(e, ENCSTR(value));
109 e = stpcpy(e, ENC_SLASH);
113 static void regexp_match_error(struct state *state, struct lens *lens,
114 int count, struct split *split) {
118 lns_format_atype(lens, &pat);
119 text = enc_format_indent(split->enc + split->start,
120 split->end - split->start,
124 put_error(state, lens,
125 "Failed to match tree under %s\n\n%s\n with pattern\n %s\n",
126 state->path, text, pat);
127 } else if (count == -2) {
128 put_error(state, lens,
129 "Internal error matching\n %s\n with tree\n %s\n",
131 } else if (count == -3) {
132 /* Should have been caught by the typechecker */
133 put_error(state, lens, "Syntax error in tree schema\n %s\n", pat);
139 static void free_split(struct split *split) {
147 /* Encode the list of TREE's children as a string.
149 static struct split *make_split(struct tree *tree) {
152 if (ALLOC(split) < 0)
156 list_for_each(t, tree) {
157 split->end += enclen(t->label, t->value);
160 if (ALLOC_N(split->enc, split->end + 1) < 0)
163 char *enc = split->enc;
164 list_for_each(t, tree) {
165 enc = encpcpy(enc, t->label, t->value);
173 static struct split *split_append(struct split **split, struct split *tail,
174 struct tree *tree, struct tree *follow,
175 char *enc, size_t start, size_t end) {
183 list_tail_cons(*split, tail, sp);
187 static struct split *next_split(struct state *state) {
188 if (state->split != NULL) {
189 state->split = state->split->next;
190 if (state->split != NULL)
191 state->pos = state->split->end;
196 static struct split *set_split(struct state *state, struct split *split) {
197 state->split = split;
199 state->pos = split->end;
203 /* Refine a tree split OUTER according to the L_CONCAT lens LENS */
204 static struct split *split_concat(struct state *state, struct lens *lens) {
205 assert(lens->tag == L_CONCAT);
208 struct split *outer = state->split;
209 struct re_registers regs;
210 struct split *split = NULL, *tail = NULL;
211 struct regexp *atype = lens->atype;
213 /* Fast path for leaf nodes, which will always lead to an empty split */
214 // FIXME: This doesn't match the empty encoding
215 if (outer->tree == NULL && strlen(outer->enc) == 0
216 && regexp_is_empty_pattern(atype)) {
217 for (int i=0; i < lens->nchildren; i++) {
218 tail = split_append(&split, tail, NULL, NULL,
225 count = regexp_match(atype, outer->enc, outer->end,
226 outer->start, ®s);
227 if (count >= 0 && count != outer->end - outer->start)
230 regexp_match_error(state, lens, count, outer);
234 struct tree *cur = outer->tree;
236 for (int i=0; i < lens->nchildren; i++) {
237 assert(reg < regs.num_regs);
238 assert(regs.start[reg] != -1);
239 struct tree *follow = cur;
240 for (int j = regs.start[reg]; j < regs.end[reg]; j++) {
241 if (outer->enc[j] == ENC_SLASH_CH)
242 follow = follow->next;
244 tail = split_append(&split, tail, cur, follow,
245 outer->enc, regs.start[reg], regs.end[reg]);
247 reg += 1 + regexp_nsub(lens->children[i]->atype);
249 assert(reg < regs.num_regs);
260 static struct split *split_iter(struct state *state, struct lens *lens) {
261 assert(lens->tag == L_STAR);
264 struct split *outer = state->split;
265 struct split *split = NULL;
266 struct regexp *atype = lens->child->atype;
268 struct tree *cur = outer->tree;
269 int pos = outer->start;
270 struct split *tail = NULL;
271 while (pos < outer->end) {
272 count = regexp_match(atype, outer->enc, outer->end, pos, NULL);
275 } else if (count < -1) {
276 regexp_match_error(state, lens->child, count, outer);
280 struct tree *follow = cur;
281 for (int j = pos; j < pos + count; j++) {
282 if (outer->enc[j] == ENC_SLASH_CH)
283 follow = follow->next;
285 tail = split_append(&split, tail, cur, follow,
286 outer->enc, pos, pos + count);
296 /* Check if LENS applies to the current split in STATE */
297 static int applies(struct lens *lens, struct state *state) {
299 struct split *split = state->split;
301 count = regexp_match(lens->atype, split->enc, split->end,
304 regexp_match_error(state, lens, count, split);
308 if (count != split->end - split->start)
310 if (count == 0 && lens->value)
311 return state->tree->value != NULL;
316 * Check whether SKEL has the skeleton type required by LENS
319 static int skel_instance_of(struct lens *lens, struct skel *skel) {
326 if (skel->tag != L_DEL)
328 count = regexp_match(lens->regexp, skel->text, strlen(skel->text),
330 return count == strlen(skel->text);
333 return skel->tag == L_STORE;
335 return skel->tag == L_KEY;
337 return skel->tag == L_LABEL;
339 return skel->tag == L_VALUE;
341 return skel->tag == L_SEQ;
343 return skel->tag == L_COUNTER;
346 if (skel->tag != L_CONCAT)
348 struct skel *s = skel->skels;
349 for (int i=0; i < lens->nchildren; i++) {
350 if (! skel_instance_of(lens->children[i], s))
359 for (int i=0; i < lens->nchildren; i++) {
360 if (skel_instance_of(lens->children[i], skel))
367 return skel->tag == L_SUBTREE;
369 return skel->tag == L_MAYBE || skel_instance_of(lens->child, skel);
371 if (skel->tag != L_STAR)
373 list_for_each(s, skel->skels) {
374 if (! skel_instance_of(lens->child, s))
379 return skel_instance_of(lens->body, skel);
381 return skel->tag == L_SQUARE
382 && skel_instance_of(lens->child, skel->skels);
384 BUG_ON(true, lens->info, "illegal lens tag %d", lens->tag);
391 enum span_kind { S_NONE, S_LABEL, S_VALUE };
393 static void emit(struct state *state, const char *text, enum span_kind kind) {
394 struct span* span = state->tree->span;
397 long start = ftell(state->out);
398 if (kind == S_LABEL) {
399 span->label_start = start;
400 } else if (kind == S_VALUE) {
401 span->value_start = start;
404 fprintf(state->out, "%s", text);
406 long end = ftell(state->out);
407 if (kind == S_LABEL) {
408 span->label_end = end;
409 } else if (kind == S_VALUE) {
410 span->value_end = end;
418 static void put_subtree(struct lens *lens, struct state *state) {
419 assert(lens->tag == L_SUBTREE);
420 struct state oldstate = *state;
421 struct split oldsplit = *state->split;
422 char * oldpath = state->path;
424 struct tree *tree = state->split->tree;
425 struct split *split = NULL;
428 state->path = path_of_tree(tree);
430 split = make_split(tree->children);
431 set_split(state, split);
433 dict_lookup(tree->label, state->dict, &state->skel, &state->dict);
434 if (state->with_span) {
435 if (tree->span == NULL) {
436 tree->span = make_span(state->info);
438 tree->span->span_start = ftell(state->out);
440 if (state->skel == NULL || ! skel_instance_of(lens->child, state->skel)) {
441 create_lens(lens->child, state);
443 put_lens(lens->child, state);
445 assert(state->error != NULL || state->split->next == NULL);
446 if (tree->span != NULL) {
447 tree->span->span_end = ftell(state->out);
450 oldstate.error = state->error;
451 oldstate.path = state->path;
453 *state->split= oldsplit;
456 state->path = oldpath;
459 static void put_del(ATTRIBUTE_UNUSED struct lens *lens, struct state *state) {
460 assert(lens->tag == L_DEL);
461 assert(state->skel != NULL);
462 assert(state->skel->tag == L_DEL);
463 if (state->override != NULL) {
464 emit(state, state->override, S_NONE);
466 emit(state, state->skel->text, S_NONE);
470 static void put_union(struct lens *lens, struct state *state) {
471 assert(lens->tag == L_UNION);
473 for (int i=0; i < lens->nchildren; i++) {
474 struct lens *l = lens->children[i];
475 if (applies(l, state)) {
476 if (skel_instance_of(l, state->skel))
479 create_lens(l, state);
483 put_error(state, lens, "None of the alternatives in the union match");
486 static void put_concat(struct lens *lens, struct state *state) {
487 assert(lens->tag == L_CONCAT);
488 struct split *oldsplit = state->split;
489 struct skel *oldskel = state->skel;
491 struct split *split = split_concat(state, lens);
493 state->skel = state->skel->skels;
494 set_split(state, split);
495 for (int i=0; i < lens->nchildren; i++) {
496 if (state->split == NULL) {
497 put_error(state, lens,
498 "Not enough components in concat");
502 put_lens(lens->children[i], state);
503 state->skel = state->skel->next;
507 set_split(state, oldsplit);
508 state->skel = oldskel;
511 static void error_quant_star(struct split *last_split, struct lens *lens,
512 struct state *state, const char *enc) {
513 struct tree *child = NULL;
514 if (last_split != NULL) {
515 if (last_split->follow != NULL) {
516 child = last_split->follow;
518 for (child = last_split->tree;
519 child != NULL && child->next != NULL;
520 child = child->next);
526 lns_format_atype(lens, &pat);
527 text = enc_format_indent(enc, strlen(enc), 4);
530 put_error(state, lens,
531 "Missing a node: can not match tree\n\n%s\n with pattern\n %s\n",
534 char *s = path_of_tree(child);
535 put_error(state, lens,
536 "Unexpected node '%s': can not match tree\n\n%s\n with pattern\n %s\n",
544 static void put_quant_star(struct lens *lens, struct state *state) {
545 assert(lens->tag == L_STAR);
546 struct split *oldsplit = state->split;
547 struct skel *oldskel = state->skel;
548 struct split *last_split = NULL;
550 struct split *split = split_iter(state, lens);
552 state->skel = state->skel->skels;
553 set_split(state, split);
554 last_split = state->split;
555 while (state->split != NULL && state->skel != NULL) {
556 put_lens(lens->child, state);
557 state->skel = state->skel->next;
558 last_split = state->split;
561 while (state->split != NULL) {
562 create_lens(lens->child, state);
563 last_split = state->split;
566 if (state->pos != oldsplit->end)
567 error_quant_star(last_split, lens, state, oldsplit->enc + state->pos);
569 set_split(state, oldsplit);
570 state->skel = oldskel;
573 static void put_quant_maybe(struct lens *lens, struct state *state) {
574 assert(lens->tag == L_MAYBE);
575 struct lens *child = lens->child;
577 if (applies(child, state)) {
578 if (skel_instance_of(child, state->skel))
579 put_lens(child, state);
581 create_lens(child, state);
585 static void put_store(struct lens *lens, struct state *state) {
586 const char *value = state->tree->value;
589 put_error(state, lens,
590 "Can not store a nonexistent (NULL) value");
591 } else if (regexp_match(lens->regexp, value, strlen(value),
592 0, NULL) != strlen(value)) {
593 char *pat = regexp_escape(lens->regexp);
594 put_error(state, lens,
595 "Value '%s' does not match regexp /%s/ in store lens",
599 emit(state, value, S_VALUE);
603 static void put_rec(struct lens *lens, struct state *state) {
604 put_lens(lens->body, state);
607 static void put_square(struct lens *lens, struct state *state) {
608 assert(lens->tag == L_SQUARE);
609 struct skel *oldskel = state->skel;
610 struct split *oldsplit = state->split;
611 struct lens *concat = lens->child;
612 struct lens *left = concat->children[0];
613 struct split *split = split_concat(state, concat);
615 /* skels of concat is one depth more */
616 state->skel = state->skel->skels->skels;
617 set_split(state, split);
618 for (int i=0; i < concat->nchildren; i++) {
619 if (state->split == NULL) {
620 put_error(state, concat, "Not enough components in square");
624 struct lens *curr = concat->children[i];
625 if (i == (concat->nchildren - 1) && left->tag == L_KEY)
626 state->override = state->tree->label;
627 put_lens(curr, state);
628 state->override = NULL;
629 state->skel = state->skel->next;
633 set_split(state, oldsplit);
634 state->skel = oldskel;
637 static void put_lens(struct lens *lens, struct state *state) {
638 if (state->error != NULL)
643 put_del(lens, state);
646 put_store(lens, state);
649 emit(state, state->tree->label, S_LABEL);
662 put_concat(lens, state);
665 put_union(lens, state);
668 put_subtree(lens, state);
671 put_quant_star(lens, state);
674 put_quant_maybe(lens, state);
677 put_rec(lens, state);
680 put_square(lens, state);
688 static void create_subtree(struct lens *lens, struct state *state) {
689 put_subtree(lens, state);
692 static void create_del(struct lens *lens, struct state *state) {
693 assert(lens->tag == L_DEL);
694 if (state->override != NULL) {
695 emit(state, state->override, S_NONE);
697 emit(state, lens->string->str, S_NONE);
701 static void create_union(struct lens *lens, struct state *state) {
702 assert(lens->tag == L_UNION);
704 for (int i=0; i < lens->nchildren; i++) {
705 if (applies(lens->children[i], state)) {
706 create_lens(lens->children[i], state);
710 put_error(state, lens, "None of the alternatives in the union match");
713 static void create_concat(struct lens *lens, struct state *state) {
714 assert(lens->tag == L_CONCAT);
715 struct split *oldsplit = state->split;
717 struct split *split = split_concat(state, lens);
719 set_split(state, split);
720 for (int i=0; i < lens->nchildren; i++) {
721 if (state->split == NULL) {
722 put_error(state, lens,
723 "Not enough components in concat");
727 create_lens(lens->children[i], state);
731 set_split(state, oldsplit);
734 static void create_square(struct lens *lens, struct state *state) {
735 assert(lens->tag == L_SQUARE);
736 struct lens *concat = lens->child;
738 struct split *oldsplit = state->split;
739 struct split *split = split_concat(state, concat);
740 struct lens *left = concat->children[0];
742 set_split(state, split);
743 for (int i=0; i < concat->nchildren; i++) {
744 if (state->split == NULL) {
745 put_error(state, concat, "Not enough components in square");
749 struct lens *curr = concat->children[i];
750 if (i == (concat->nchildren - 1) && left->tag == L_KEY)
751 state->override = state->tree->label;
752 create_lens(curr, state);
753 state->override = NULL;
757 set_split(state, oldsplit);
760 static void create_quant_star(struct lens *lens, struct state *state) {
761 assert(lens->tag == L_STAR);
762 struct split *oldsplit = state->split;
763 struct split *last_split = NULL;
765 struct split *split = split_iter(state, lens);
767 set_split(state, split);
768 last_split = state->split;
769 while (state->split != NULL) {
770 create_lens(lens->child, state);
771 last_split = state->split;
774 if (state->pos != oldsplit->end)
775 error_quant_star(last_split, lens, state, oldsplit->enc + state->pos);
777 set_split(state, oldsplit);
780 static void create_quant_maybe(struct lens *lens, struct state *state) {
781 assert(lens->tag == L_MAYBE);
783 if (applies(lens->child, state)) {
784 create_lens(lens->child, state);
788 static void create_rec(struct lens *lens, struct state *state) {
789 create_lens(lens->body, state);
792 static void create_lens(struct lens *lens, struct state *state) {
793 if (state->error != NULL)
797 create_del(lens, state);
800 put_store(lens, state);
803 emit(state, state->tree->label, S_LABEL);
816 create_concat(lens, state);
819 create_union(lens, state);
822 create_subtree(lens, state);
825 create_quant_star(lens, state);
828 create_quant_maybe(lens, state);
831 create_rec(lens, state);
834 create_square(lens, state);
842 void lns_put(struct info *info, FILE *out, struct lens *lens, struct tree *tree,
843 const char *text, int enable_span, struct lns_error **err) {
845 struct lns_error *err1;
853 state.path = strdup("/");
854 state.skel = lns_parse(lens, text, &state.dict, &err1);
860 free_lns_error(err1);
864 state.split = make_split(tree);
865 state.with_span = enable_span;
868 if (state.with_span) {
869 if (tree->span == NULL) {
870 tree->span = make_span(info);
872 tree->span->span_start = ftell(out);
874 put_lens(lens, &state);
875 if (state.with_span) {
876 tree->span->span_end = ftell(out);
881 free_lns_error(state.error);
886 free_split(state.split);
887 free_skel(state.skel);
888 free_dict(state.dict);
893 * indent-tabs-mode: nil