OSDN Git Service

Import from darcs trunk
[coolrain/CoolRain.git] / src / builtin_tag.c
index 5facb43..f50bf50 100644 (file)
@@ -72,9 +72,8 @@ int coolrain_builtin_tag_handler_let(struct coolrain_eval_context const *cntx)
        r = coolrain_template_eval_content(cntx);
 
        coolrain_stash_restore(cntx->stash, vl, count);
+       coolrain_stash_value_list_unset(vl, count);
 
-       for (i = 0; i < count; i++)
-               coolrain_variant_destroy(&vl[i].value);
        coolrain_free(vl);
 
        return r;
@@ -149,8 +148,111 @@ int coolrain_builtin_tag_handler_loop(struct coolrain_eval_context const *cntx)
                }
        }
        coolrain_stash_restore(cntx->stash, vlist, 1);
+       coolrain_stash_value_list_unset(vlist, 1);
 
        return COOLRAIN_SUCCESS;
 }
 
 
+
+
+
+
+int coolrain_builtin_tag_handler_include_param(struct coolrain_eval_context const *cntx G_GNUC_UNUSED)
+{
+       return COOLRAIN_SUCCESS;
+}
+
+
+
+
+/**
+ *
+ */
+int coolrain_builtin_tag_handler_include(struct coolrain_eval_context const *cntx)
+{
+       char *href_cstr;
+       int r;
+       int param_count = 0;
+       struct coolrain_stash_value_list *vlist = NULL;
+       char* tagname;
+
+       if (cntx->tmpl->loader == NULL) {
+               coolrain_template_raise_error(cntx->tmpl, "Template %s has no loader.\n", cntx->tmpl->name);
+               return COOLRAIN_ERROR_NO_LOADER;
+       }
+
+
+       /* */
+       {
+               coolrain_refstring_t const* href = coolrain_fragment_find_attribute(cntx->fragment, "href");
+               if (href == NULL) {
+                       tagname = coolrain_refstring_dup(&cntx->fragment->data.tag.tagdesc->name);
+                       coolrain_template_raise_error(cntx->tmpl, "No 'href' attribute on %s tag\n", tagname);
+                       coolrain_free(tagname);
+                       return COOLRAIN_ERROR_NO_ATTRIBUTE;
+               }
+               href_cstr = coolrain_refstring_dup(href);
+       }
+
+
+       /* Bind all parameters */
+       {
+               struct coolrain_fragment *child;
+               coolrain_refstring_t const* name;
+               int n;
+
+               for (child = cntx->fragment->data.tag.content; child != NULL; child = child->next) {
+                       if (child->type != COOLRAIN_FRAGMENT_TYPE_TAG ||
+                           child->data.tag.tagdesc->handler != coolrain_builtin_tag_handler_include_param)
+                               continue;
+                       param_count++;
+               }
+
+               if (param_count > 0) {
+                       vlist = coolrain_malloc(sizeof(struct coolrain_stash_value_list) * param_count);
+
+                       n = 0;
+                       for (child = cntx->fragment->data.tag.content; n < param_count && child != NULL; child = child->next) {
+                               if (child->type != COOLRAIN_FRAGMENT_TYPE_TAG ||
+                                   child->data.tag.tagdesc->handler != coolrain_builtin_tag_handler_include_param)
+                                       continue;
+
+                               name = coolrain_fragment_find_attribute(child, "name");
+                               if (name == NULL) continue;
+
+                               vlist[n].name = *name;
+                               coolrain_variant_initialize(&vlist[n].value);
+                               coolrain_variant_set_dynamic_context(&vlist[n].value, cntx);
+                               vlist[n].value.data.v_cntx->fragment = child;
+                               vlist[n].old_value = NULL;
+                               n++;
+                       }
+
+                       param_count = n;
+                       coolrain_stash_set_values(cntx->stash, vlist, param_count);
+               }
+       }
+
+
+       /* Process included template */
+       r = coolrain_loader_process_template(cntx->tmpl->loader, href_cstr, cntx->stash, cntx->writer);
+       coolrain_free(href_cstr);
+       if (r != 0) {
+               coolrain_template_raise_error(cntx->tmpl, "  include from %s\n", cntx->tmpl->name);
+       }
+
+
+       /* Reelase memories */
+       if (vlist != NULL) {
+               if (param_count > 0)
+                       coolrain_stash_restore(cntx->stash, vlist, param_count);
+               coolrain_stash_value_list_unset(vlist, param_count);
+
+               coolrain_free(vlist);
+       }
+
+       return r;
+}
+
+