Imported Upstream version 1.5.0
[platform/upstream/augeas.git] / src / builtin.c
index 4964405..44d61cc 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * builtin.c: builtin primitives
  *
- * Copyright (C) 2007-2011 David Lutterkort
+ * Copyright (C) 2007-2015 David Lutterkort
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -86,14 +86,25 @@ static struct value *lns_counter(struct info *info, struct value *str) {
     return lns_make_prim(L_COUNTER, ref(info), NULL, ref(str->string));
 }
 
-/* V_REGEXP -> V_LENS -> V_LENS */
-static struct value *lns_square(struct info *info, struct value *rxp,
-                                struct value *lns) {
-    assert(rxp->tag == V_REGEXP);
-    assert(lns->tag == V_LENS);
+/* V_LENS -> V_LENS -> V_LENS -> V_LENS */
+static struct value *lns_square(struct info *info, struct value *l1,
+                                struct value *l2, struct value *l3) {
+    assert(l1->tag == V_LENS);
+    assert(l2->tag == V_LENS);
+    assert(l3->tag == V_LENS);
     int check = info->error->aug->flags & AUG_TYPE_CHECK;
 
-    return lns_make_square(ref(info), ref(rxp->regexp), ref(lns->lens), check);
+    return lns_make_square(ref(info), ref(l1->lens), ref(l2->lens), ref(l3->lens), check);
+}
+
+static void exn_lns_error_detail(struct value *exn, const char *label,
+                                 struct lens *lens) {
+    if (lens == NULL)
+        return;
+
+    char *s = format_info(lens->info);
+    exn_printf_line(exn, "%s: %s", label, s);
+    free(s);
 }
 
 static struct value *make_exn_lns_error(struct info *info,
@@ -102,14 +113,12 @@ static struct value *make_exn_lns_error(struct info *info,
     struct value *v;
 
     if (HAS_ERR(info))
-        return exn_error();
+        return info->error->exn;
 
     v = make_exn_value(ref(info), "%s", err->message);
-    if (err->lens != NULL) {
-        char *s = format_info(err->lens->info);
-        exn_printf_line(v, "Lens: %s", s);
-        free(s);
-    }
+    exn_lns_error_detail(v, "Lens", err->lens);
+    exn_lns_error_detail(v, "  Last match", err->last);
+    exn_lns_error_detail(v, "  Not matching", err->next);
     if (err->pos >= 0) {
         char *pos = format_pos(text, err->pos);
         size_t line, ofs;
@@ -486,6 +495,13 @@ static struct value *pr_endline(struct info *info, struct value *s) {
     return make_unit(ref(info));
 }
 
+/* V_TREE -> V_TREE */
+static struct value *pr_tree(ATTRIBUTE_UNUSED struct info *info,
+                             struct value *t) {
+    print_tree_braces(stdout, 0, t->origin);
+    return ref(t);
+}
+
 /*
  * Lens inspection
  */
@@ -527,7 +543,7 @@ static struct value *lns_fmt_atype(struct info *info, struct value *l) {
 
     r = lns_format_atype(l->lens, &s);
     if (r < 0)
-        return exn_error();
+        return info->error->exn;
     result = make_value(V_STRING, ref(info));
     result->string = make_string(s);
     return result;
@@ -555,7 +571,7 @@ static struct value *rx_match(struct info *info,
             match = strndup(str + regs.start[0], regs.end[0] - regs.start[0]);
         }
         if (match == NULL) {
-            result = exn_error();
+            result = info->error->exn;
         } else {
             result = make_value(V_STRING, ref(info));
             result->string = make_string(match);
@@ -582,7 +598,7 @@ struct module *builtin_init(struct error *error) {
     DEFINE_NATIVE(modl, "label",   1, lns_label, T_STRING, T_LENS);
     DEFINE_NATIVE(modl, "seq",     1, lns_seq, T_STRING, T_LENS);
     DEFINE_NATIVE(modl, "counter", 1, lns_counter, T_STRING, T_LENS);
-    DEFINE_NATIVE(modl, "square",  2, lns_square, T_REGEXP, T_LENS, T_LENS);
+    DEFINE_NATIVE(modl, "square",  3, lns_square, T_LENS, T_LENS, T_LENS, T_LENS);
     /* Applying lenses (mostly for tests) */
     DEFINE_NATIVE(modl, "get",     2, lens_get, T_LENS, T_STRING, T_TREE);
     DEFINE_NATIVE(modl, "put",     3, lens_put, T_LENS, T_TREE, T_STRING,
@@ -608,6 +624,7 @@ struct module *builtin_init(struct error *error) {
     DEFINE_NATIVE(modl, "print_string", 1, pr_string, T_STRING, T_UNIT);
     DEFINE_NATIVE(modl, "print_regexp", 1, pr_regexp, T_REGEXP, T_UNIT);
     DEFINE_NATIVE(modl, "print_endline", 1, pr_endline, T_STRING, T_UNIT);
+    DEFINE_NATIVE(modl, "print_tree", 1, pr_tree, T_TREE, T_TREE);
 
     /* Lens inspection */
     DEFINE_NATIVE(modl, "lens_ctype", 1, lns_ctype, T_LENS, T_REGEXP);