4 * Copyright (C) 2007-2015 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.
65 char *path; /* Position in the tree, for errors */
67 struct lns_error *error;
70 static void create_lens(struct lens *lens, struct state *state);
71 static void put_lens(struct lens *lens, struct state *state);
73 static void put_error(struct state *state, struct lens *lens,
74 const char *format, ...)
79 if (state->error != NULL)
82 CALLOC(state->error, 1);
83 state->error->lens = ref(lens);
84 state->error->pos = -1;
85 if (strlen(state->path) == 0) {
86 state->error->path = strdup("");
88 state->error->path = strdup(state->path);
92 r = vasprintf(&state->error->message, format, ap);
95 state->error->message = NULL;
99 static int enclen(const char *key, const char *value) {
100 return ENCLEN(key) + strlen(ENC_EQ) + ENCLEN(value)
104 static char *encpcpy(char *e, const char *key, const char *value) {
105 e = stpcpy(e, ENCSTR(key));
106 e = stpcpy(e, ENC_EQ);
107 e = stpcpy(e, ENCSTR(value));
108 e = stpcpy(e, ENC_SLASH);
112 static void regexp_match_error(struct state *state, struct lens *lens,
113 int count, struct split *split) {
117 lns_format_atype(lens, &pat);
118 text = enc_format_indent(split->enc + split->start,
119 split->end - split->start,
123 put_error(state, lens,
124 "Failed to match tree\n\n%s\n with pattern\n %s",
126 } else if (count == -2) {
127 put_error(state, lens,
128 "Internal error matching\n %s\n with tree\n %s",
130 } else if (count == -3) {
131 /* Should have been caught by the typechecker */
132 put_error(state, lens, "Syntax error in tree schema\n %s", pat);
138 static void free_split(struct split *split) {
146 /* Encode the list of TREE's children as a string.
148 static struct split *make_split(struct tree *tree) {
151 if (ALLOC(split) < 0)
155 list_for_each(t, tree) {
156 split->end += enclen(t->label, t->value);
159 if (ALLOC_N(split->enc, split->end + 1) < 0)
162 char *enc = split->enc;
163 list_for_each(t, tree) {
164 enc = encpcpy(enc, t->label, t->value);
172 static struct split *split_append(struct split **split, struct split *tail,
173 struct tree *tree, struct tree *follow,
174 char *enc, size_t start, size_t end) {
182 list_tail_cons(*split, tail, sp);
186 static struct split *next_split(struct state *state) {
187 if (state->split != NULL) {
188 state->split = state->split->next;
189 if (state->split != NULL)
190 state->pos = state->split->end;
195 static struct split *set_split(struct state *state, struct split *split) {
196 state->split = split;
198 state->pos = split->end;
202 /* Refine a tree split OUTER according to the L_CONCAT lens LENS */
203 static struct split *split_concat(struct state *state, struct lens *lens) {
204 assert(lens->tag == L_CONCAT);
207 struct split *outer = state->split;
208 struct re_registers regs;
209 struct split *split = NULL, *tail = NULL;
210 struct regexp *atype = lens->atype;
212 /* Fast path for leaf nodes, which will always lead to an empty split */
213 // FIXME: This doesn't match the empty encoding
214 if (outer->tree == NULL && strlen(outer->enc) == 0
215 && regexp_is_empty_pattern(atype)) {
216 for (int i=0; i < lens->nchildren; i++) {
217 tail = split_append(&split, tail, NULL, NULL,
224 count = regexp_match(atype, outer->enc, outer->end,
225 outer->start, ®s);
226 if (count >= 0 && count != outer->end - outer->start)
229 regexp_match_error(state, lens, count, outer);
233 struct tree *cur = outer->tree;
235 for (int i=0; i < lens->nchildren; i++) {
236 assert(reg < regs.num_regs);
237 assert(regs.start[reg] != -1);
238 struct tree *follow = cur;
239 for (int j = regs.start[reg]; j < regs.end[reg]; j++) {
240 if (outer->enc[j] == ENC_SLASH_CH)
241 follow = follow->next;
243 tail = split_append(&split, tail, cur, follow,
244 outer->enc, regs.start[reg], regs.end[reg]);
246 reg += 1 + regexp_nsub(lens->children[i]->atype);
248 assert(reg < regs.num_regs);
259 static struct split *split_iter(struct state *state, struct lens *lens) {
260 assert(lens->tag == L_STAR);
263 struct split *outer = state->split;
264 struct split *split = NULL;
265 struct regexp *atype = lens->child->atype;
267 struct tree *cur = outer->tree;
268 int pos = outer->start;
269 struct split *tail = NULL;
270 while (pos < outer->end) {
271 count = regexp_match(atype, outer->enc, outer->end, pos, NULL);
274 } else if (count < -1) {
275 regexp_match_error(state, lens->child, count, outer);
279 struct tree *follow = cur;
280 for (int j = pos; j < pos + count; j++) {
281 if (outer->enc[j] == ENC_SLASH_CH)
282 follow = follow->next;
284 tail = split_append(&split, tail, cur, follow,
285 outer->enc, pos, pos + count);
295 /* Check if LENS applies to the current split in STATE */
296 static int applies(struct lens *lens, struct state *state) {
298 struct split *split = state->split;
300 count = regexp_match(lens->atype, split->enc, split->end,
303 regexp_match_error(state, lens, count, split);
307 if (count != split->end - split->start)
309 if (count == 0 && lens->value)
310 return state->value != NULL;
314 /* Print TEXT to OUT, translating common escapes like \n */
315 static void print_escaped_chars(FILE *out, const char *text) {
316 for (const char *c = text; *c != '\0'; c++) {
358 * Check whether SKEL has the skeleton type required by LENS
361 static int skel_instance_of(struct lens *lens, struct skel *skel) {
368 if (skel->tag != L_DEL)
370 count = regexp_match(lens->regexp, skel->text, strlen(skel->text),
372 return count == strlen(skel->text);
375 return skel->tag == L_STORE;
377 return skel->tag == L_KEY;
379 return skel->tag == L_LABEL;
381 return skel->tag == L_VALUE;
383 return skel->tag == L_SEQ;
385 return skel->tag == L_COUNTER;
388 struct skel *s = skel->skels;
389 for (int i=0; i < lens->nchildren; i++) {
390 if (! skel_instance_of(lens->children[i], s))
399 for (int i=0; i < lens->nchildren; i++) {
400 if (skel_instance_of(lens->children[i], skel))
407 return skel->tag == L_SUBTREE;
409 return skel->tag == L_MAYBE || skel_instance_of(lens->child, skel);
411 if (skel->tag != lens->tag)
413 if (lens->tag == L_MAYBE &&
414 skel->skels != NULL && skel->skels->next != NULL)
416 list_for_each(s, skel->skels) {
417 if (! skel_instance_of(lens->child, s))
422 return skel_instance_of(lens->body, skel);
424 return skel->tag == L_SQUARE
425 && skel_instance_of(lens->child, skel->skels);
427 BUG_ON(true, lens->info, "illegal lens tag %d", lens->tag);
437 static void put_subtree(struct lens *lens, struct state *state) {
438 assert(lens->tag == L_SUBTREE);
439 struct state oldstate = *state;
440 struct split oldsplit = *state->split;
441 size_t oldpathlen = strlen(state->path);
443 struct tree *tree = state->split->tree;
444 struct split *split = NULL;
446 state->key = tree->label;
447 state->value = tree->value;
448 pathjoin(&state->path, 1, state->key);
450 split = make_split(tree->children);
451 set_split(state, split);
453 dict_lookup(tree->label, state->dict, &state->skel, &state->dict);
454 if (state->skel == NULL || ! skel_instance_of(lens->child, state->skel)) {
455 create_lens(lens->child, state);
457 put_lens(lens->child, state);
459 assert(state->error != NULL || state->split->next == NULL);
461 oldstate.error = state->error;
462 oldstate.path = state->path;
464 *state->split= oldsplit;
466 state->path[oldpathlen] = '\0';
469 static void put_del(ATTRIBUTE_UNUSED struct lens *lens, struct state *state) {
470 assert(lens->tag == L_DEL);
471 assert(state->skel != NULL);
472 assert(state->skel->tag == L_DEL);
473 if (state->override != NULL) {
474 fprintf(state->out, "%s", state->override);
476 fprintf(state->out, "%s", state->skel->text);
480 static void put_union(struct lens *lens, struct state *state) {
481 assert(lens->tag == L_UNION);
483 for (int i=0; i < lens->nchildren; i++) {
484 struct lens *l = lens->children[i];
485 if (applies(l, state)) {
486 if (skel_instance_of(l, state->skel))
489 create_lens(l, state);
493 put_error(state, lens, "None of the alternatives in the union match");
496 static void put_concat(struct lens *lens, struct state *state) {
497 assert(lens->tag == L_CONCAT);
498 struct split *oldsplit = state->split;
499 struct skel *oldskel = state->skel;
501 struct split *split = split_concat(state, lens);
503 state->skel = state->skel->skels;
504 set_split(state, split);
505 for (int i=0; i < lens->nchildren; i++) {
506 if (state->split == NULL) {
507 put_error(state, lens,
508 "Not enough components in concat");
512 put_lens(lens->children[i], state);
513 state->skel = state->skel->next;
517 set_split(state, oldsplit);
518 state->skel = oldskel;
521 static void error_quant_star(struct split *last_split, struct lens *lens,
522 struct state *state) {
523 struct tree *child = NULL;
524 if (last_split != NULL) {
525 if (last_split->follow != NULL) {
526 child = last_split->follow;
528 for (child = last_split->tree;
529 child != NULL && child->next != NULL;
530 child = child->next);
534 put_error(state, lens, "Malformed child node");
536 put_error(state, lens, "Malformed child node '%s'", child->label);
540 static void put_quant_star(struct lens *lens, struct state *state) {
541 assert(lens->tag == L_STAR);
542 struct split *oldsplit = state->split;
543 struct skel *oldskel = state->skel;
544 struct split *last_split = NULL;
546 struct split *split = split_iter(state, lens);
548 state->skel = state->skel->skels;
549 set_split(state, split);
550 last_split = state->split;
551 while (state->split != NULL && state->skel != NULL) {
552 put_lens(lens->child, state);
553 state->skel = state->skel->next;
554 last_split = state->split;
557 while (state->split != NULL) {
558 create_lens(lens->child, state);
559 last_split = state->split;
562 if (state->pos != oldsplit->end)
563 error_quant_star(last_split, lens, state);
565 set_split(state, oldsplit);
566 state->skel = oldskel;
569 static void put_quant_maybe(struct lens *lens, struct state *state) {
570 assert(lens->tag == L_MAYBE);
571 struct lens *child = lens->child;
573 if (applies(child, state)) {
574 if (skel_instance_of(child, state->skel))
575 put_lens(child, state);
577 create_lens(child, state);
581 static void put_store(struct lens *lens, struct state *state) {
582 if (state->value == NULL) {
583 put_error(state, lens,
584 "Can not store a nonexistent (NULL) value");
585 } else if (regexp_match(lens->regexp, state->value, strlen(state->value),
586 0, NULL) != strlen(state->value)) {
587 char *pat = regexp_escape(lens->regexp);
588 put_error(state, lens,
589 "Value '%s' does not match regexp /%s/ in store lens",
593 fprintf(state->out, "%s", state->value);
597 static void put_rec(struct lens *lens, struct state *state) {
598 put_lens(lens->body, state);
601 static void put_square(struct lens *lens, struct state *state) {
602 assert(lens->tag == L_SQUARE);
603 struct skel *oldskel = state->skel;
604 struct split *oldsplit = state->split;
605 struct lens *concat = lens->child;
606 struct lens *left = concat->children[0];
607 struct split *split = split_concat(state, concat);
609 /* skels of concat is one depth more */
610 state->skel = state->skel->skels->skels;
611 set_split(state, split);
612 for (int i=0; i < concat->nchildren; i++) {
613 if (state->split == NULL) {
614 put_error(state, concat, "Not enough components in square");
618 struct lens *curr = concat->children[i];
619 if (i == (concat->nchildren - 1) && left->tag == L_KEY)
620 state->override = state->key;
621 put_lens(curr, state);
622 state->override = NULL;
623 state->skel = state->skel->next;
627 set_split(state, oldsplit);
628 state->skel = oldskel;
631 static void put_lens(struct lens *lens, struct state *state) {
632 if (state->error != NULL)
637 put_del(lens, state);
640 put_store(lens, state);
643 fprintf(state->out, "%s", state->key);
656 put_concat(lens, state);
659 put_union(lens, state);
662 put_subtree(lens, state);
665 put_quant_star(lens, state);
668 put_quant_maybe(lens, state);
671 put_rec(lens, state);
674 put_square(lens, state);
682 static void create_subtree(struct lens *lens, struct state *state) {
683 put_subtree(lens, state);
686 static void create_del(struct lens *lens, struct state *state) {
687 assert(lens->tag == L_DEL);
688 if (state->override != NULL) {
689 print_escaped_chars(state->out, state->override);
691 print_escaped_chars(state->out, lens->string->str);
695 static void create_union(struct lens *lens, struct state *state) {
696 assert(lens->tag == L_UNION);
698 for (int i=0; i < lens->nchildren; i++) {
699 if (applies(lens->children[i], state)) {
700 create_lens(lens->children[i], state);
704 put_error(state, lens, "None of the alternatives in the union match");
707 static void create_concat(struct lens *lens, struct state *state) {
708 assert(lens->tag == L_CONCAT);
709 struct split *oldsplit = state->split;
711 struct split *split = split_concat(state, lens);
713 set_split(state, split);
714 for (int i=0; i < lens->nchildren; i++) {
715 if (state->split == NULL) {
716 put_error(state, lens,
717 "Not enough components in concat");
721 create_lens(lens->children[i], state);
725 set_split(state, oldsplit);
728 static void create_square(struct lens *lens, struct state *state) {
729 assert(lens->tag == L_SQUARE);
730 struct lens *concat = lens->child;
732 struct split *oldsplit = state->split;
733 struct split *split = split_concat(state, concat);
734 struct lens *left = concat->children[0];
736 set_split(state, split);
737 for (int i=0; i < concat->nchildren; i++) {
738 if (state->split == NULL) {
739 put_error(state, concat, "Not enough components in square");
743 struct lens *curr = concat->children[i];
744 if (i == (concat->nchildren - 1) && left->tag == L_KEY)
745 state->override = state->key;
746 create_lens(curr, state);
747 state->override = NULL;
751 set_split(state, oldsplit);
754 static void create_quant_star(struct lens *lens, struct state *state) {
755 assert(lens->tag == L_STAR);
756 struct split *oldsplit = state->split;
757 struct split *last_split = NULL;
759 struct split *split = split_iter(state, lens);
761 set_split(state, split);
762 last_split = state->split;
763 while (state->split != NULL) {
764 create_lens(lens->child, state);
765 last_split = state->split;
768 if (state->pos != oldsplit->end)
769 error_quant_star(last_split, lens, state);
771 set_split(state, oldsplit);
774 static void create_quant_maybe(struct lens *lens, struct state *state) {
775 assert(lens->tag == L_MAYBE);
777 if (applies(lens->child, state)) {
778 create_lens(lens->child, state);
782 static void create_rec(struct lens *lens, struct state *state) {
783 create_lens(lens->body, state);
786 static void create_lens(struct lens *lens, struct state *state) {
787 if (state->error != NULL)
791 create_del(lens, state);
794 put_store(lens, state);
797 fprintf(state->out, "%s", state->key);
810 create_concat(lens, state);
813 create_union(lens, state);
816 create_subtree(lens, state);
819 create_quant_star(lens, state);
822 create_quant_maybe(lens, state);
825 create_rec(lens, state);
828 create_square(lens, state);
836 void lns_put(FILE *out, struct lens *lens, struct tree *tree,
837 const char *text, struct lns_error **err) {
839 struct lns_error *err1;
847 state.path = strdup("");
848 state.skel = lns_parse(lens, text, &state.dict, &err1);
854 free_lns_error(err1);
858 state.split = make_split(tree);
859 state.key = tree->label;
860 put_lens(lens, &state);
863 free_split(state.split);
864 free_skel(state.skel);
865 free_dict(state.dict);
869 free_lns_error(state.error);
875 * indent-tabs-mode: nil