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.
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 if (skel->tag != L_CONCAT)
390 struct skel *s = skel->skels;
391 for (int i=0; i < lens->nchildren; i++) {
392 if (! skel_instance_of(lens->children[i], s))
401 for (int i=0; i < lens->nchildren; i++) {
402 if (skel_instance_of(lens->children[i], skel))
409 return skel->tag == L_SUBTREE;
411 return skel->tag == L_MAYBE || skel_instance_of(lens->child, skel);
413 if (skel->tag != L_STAR)
415 list_for_each(s, skel->skels) {
416 if (! skel_instance_of(lens->child, s))
421 return skel_instance_of(lens->body, skel);
423 return skel->tag == L_SQUARE
424 && skel_instance_of(lens->child, skel->skels);
426 BUG_ON(true, lens->info, "illegal lens tag %d", lens->tag);
436 static void put_subtree(struct lens *lens, struct state *state) {
437 assert(lens->tag == L_SUBTREE);
438 struct state oldstate = *state;
439 struct split oldsplit = *state->split;
440 size_t oldpathlen = strlen(state->path);
442 struct tree *tree = state->split->tree;
443 struct split *split = NULL;
445 state->key = tree->label;
446 state->value = tree->value;
447 pathjoin(&state->path, 1, state->key);
449 split = make_split(tree->children);
450 set_split(state, split);
452 dict_lookup(tree->label, state->dict, &state->skel, &state->dict);
453 if (state->skel == NULL || ! skel_instance_of(lens->child, state->skel)) {
454 create_lens(lens->child, state);
456 put_lens(lens->child, state);
458 assert(state->error != NULL || state->split->next == NULL);
460 oldstate.error = state->error;
461 oldstate.path = state->path;
463 *state->split= oldsplit;
465 state->path[oldpathlen] = '\0';
468 static void put_del(ATTRIBUTE_UNUSED struct lens *lens, struct state *state) {
469 assert(lens->tag == L_DEL);
470 assert(state->skel != NULL);
471 assert(state->skel->tag == L_DEL);
472 if (state->override != NULL) {
473 fprintf(state->out, "%s", state->override);
475 fprintf(state->out, "%s", state->skel->text);
479 static void put_union(struct lens *lens, struct state *state) {
480 assert(lens->tag == L_UNION);
482 for (int i=0; i < lens->nchildren; i++) {
483 struct lens *l = lens->children[i];
484 if (applies(l, state)) {
485 if (skel_instance_of(l, state->skel))
488 create_lens(l, state);
492 put_error(state, lens, "None of the alternatives in the union match");
495 static void put_concat(struct lens *lens, struct state *state) {
496 assert(lens->tag == L_CONCAT);
497 struct split *oldsplit = state->split;
498 struct skel *oldskel = state->skel;
500 struct split *split = split_concat(state, lens);
502 state->skel = state->skel->skels;
503 set_split(state, split);
504 for (int i=0; i < lens->nchildren; i++) {
505 if (state->split == NULL) {
506 put_error(state, lens,
507 "Not enough components in concat");
511 put_lens(lens->children[i], state);
512 state->skel = state->skel->next;
516 set_split(state, oldsplit);
517 state->skel = oldskel;
520 static void error_quant_star(struct split *last_split, struct lens *lens,
521 struct state *state) {
522 struct tree *child = NULL;
523 if (last_split != NULL) {
524 if (last_split->follow != NULL) {
525 child = last_split->follow;
527 for (child = last_split->tree;
528 child != NULL && child->next != NULL;
529 child = child->next);
533 put_error(state, lens, "Malformed child node");
535 put_error(state, lens, "Malformed child node '%s'", child->label);
539 static void put_quant_star(struct lens *lens, struct state *state) {
540 assert(lens->tag == L_STAR);
541 struct split *oldsplit = state->split;
542 struct skel *oldskel = state->skel;
543 struct split *last_split = NULL;
545 struct split *split = split_iter(state, lens);
547 state->skel = state->skel->skels;
548 set_split(state, split);
549 last_split = state->split;
550 while (state->split != NULL && state->skel != NULL) {
551 put_lens(lens->child, state);
552 state->skel = state->skel->next;
553 last_split = state->split;
556 while (state->split != NULL) {
557 create_lens(lens->child, state);
558 last_split = state->split;
561 if (state->pos != oldsplit->end)
562 error_quant_star(last_split, lens, state);
564 set_split(state, oldsplit);
565 state->skel = oldskel;
568 static void put_quant_maybe(struct lens *lens, struct state *state) {
569 assert(lens->tag == L_MAYBE);
570 struct lens *child = lens->child;
572 if (applies(child, state)) {
573 if (skel_instance_of(child, state->skel))
574 put_lens(child, state);
576 create_lens(child, state);
580 static void put_store(struct lens *lens, struct state *state) {
581 if (state->value == NULL) {
582 put_error(state, lens,
583 "Can not store a nonexistent (NULL) value");
584 } else if (regexp_match(lens->regexp, state->value, strlen(state->value),
585 0, NULL) != strlen(state->value)) {
586 char *pat = regexp_escape(lens->regexp);
587 put_error(state, lens,
588 "Value '%s' does not match regexp /%s/ in store lens",
592 fprintf(state->out, "%s", state->value);
596 static void put_rec(struct lens *lens, struct state *state) {
597 put_lens(lens->body, state);
600 static void put_square(struct lens *lens, struct state *state) {
601 assert(lens->tag == L_SQUARE);
602 struct skel *oldskel = state->skel;
603 struct split *oldsplit = state->split;
604 struct lens *concat = lens->child;
605 struct lens *left = concat->children[0];
606 struct split *split = split_concat(state, concat);
608 /* skels of concat is one depth more */
609 state->skel = state->skel->skels->skels;
610 set_split(state, split);
611 for (int i=0; i < concat->nchildren; i++) {
612 if (state->split == NULL) {
613 put_error(state, concat, "Not enough components in square");
617 struct lens *curr = concat->children[i];
618 if (i == (concat->nchildren - 1) && left->tag == L_KEY)
619 state->override = state->key;
620 put_lens(curr, state);
621 state->override = NULL;
622 state->skel = state->skel->next;
626 set_split(state, oldsplit);
627 state->skel = oldskel;
630 static void put_lens(struct lens *lens, struct state *state) {
631 if (state->error != NULL)
636 put_del(lens, state);
639 put_store(lens, state);
642 fprintf(state->out, "%s", state->key);
655 put_concat(lens, state);
658 put_union(lens, state);
661 put_subtree(lens, state);
664 put_quant_star(lens, state);
667 put_quant_maybe(lens, state);
670 put_rec(lens, state);
673 put_square(lens, state);
681 static void create_subtree(struct lens *lens, struct state *state) {
682 put_subtree(lens, state);
685 static void create_del(struct lens *lens, struct state *state) {
686 assert(lens->tag == L_DEL);
687 if (state->override != NULL) {
688 print_escaped_chars(state->out, state->override);
690 print_escaped_chars(state->out, lens->string->str);
694 static void create_union(struct lens *lens, struct state *state) {
695 assert(lens->tag == L_UNION);
697 for (int i=0; i < lens->nchildren; i++) {
698 if (applies(lens->children[i], state)) {
699 create_lens(lens->children[i], state);
703 put_error(state, lens, "None of the alternatives in the union match");
706 static void create_concat(struct lens *lens, struct state *state) {
707 assert(lens->tag == L_CONCAT);
708 struct split *oldsplit = state->split;
710 struct split *split = split_concat(state, lens);
712 set_split(state, split);
713 for (int i=0; i < lens->nchildren; i++) {
714 if (state->split == NULL) {
715 put_error(state, lens,
716 "Not enough components in concat");
720 create_lens(lens->children[i], state);
724 set_split(state, oldsplit);
727 static void create_square(struct lens *lens, struct state *state) {
728 assert(lens->tag == L_SQUARE);
729 struct lens *concat = lens->child;
731 struct split *oldsplit = state->split;
732 struct split *split = split_concat(state, concat);
733 struct lens *left = concat->children[0];
735 set_split(state, split);
736 for (int i=0; i < concat->nchildren; i++) {
737 if (state->split == NULL) {
738 put_error(state, concat, "Not enough components in square");
742 struct lens *curr = concat->children[i];
743 if (i == (concat->nchildren - 1) && left->tag == L_KEY)
744 state->override = state->key;
745 create_lens(curr, state);
746 state->override = NULL;
750 set_split(state, oldsplit);
753 static void create_quant_star(struct lens *lens, struct state *state) {
754 assert(lens->tag == L_STAR);
755 struct split *oldsplit = state->split;
756 struct split *last_split = NULL;
758 struct split *split = split_iter(state, lens);
760 set_split(state, split);
761 last_split = state->split;
762 while (state->split != NULL) {
763 create_lens(lens->child, state);
764 last_split = state->split;
767 if (state->pos != oldsplit->end)
768 error_quant_star(last_split, lens, state);
770 set_split(state, oldsplit);
773 static void create_quant_maybe(struct lens *lens, struct state *state) {
774 assert(lens->tag == L_MAYBE);
776 if (applies(lens->child, state)) {
777 create_lens(lens->child, state);
781 static void create_rec(struct lens *lens, struct state *state) {
782 create_lens(lens->body, state);
785 static void create_lens(struct lens *lens, struct state *state) {
786 if (state->error != NULL)
790 create_del(lens, state);
793 put_store(lens, state);
796 fprintf(state->out, "%s", state->key);
809 create_concat(lens, state);
812 create_union(lens, state);
815 create_subtree(lens, state);
818 create_quant_star(lens, state);
821 create_quant_maybe(lens, state);
824 create_rec(lens, state);
827 create_square(lens, state);
835 void lns_put(FILE *out, struct lens *lens, struct tree *tree,
836 const char *text, struct lns_error **err) {
838 struct lns_error *err1;
846 state.path = strdup("");
847 state.skel = lns_parse(lens, text, &state.dict, &err1);
853 free_lns_error(err1);
857 state.split = make_split(tree);
858 state.key = tree->label;
859 put_lens(lens, &state);
863 free_lns_error(state.error);
868 free_split(state.split);
869 free_skel(state.skel);
870 free_dict(state.dict);
875 * indent-tabs-mode: nil