diff options
| -rw-r--r-- | Makefile | 9 | ||||
| -rw-r--r-- | build/.gitignore | 1 | ||||
| -rw-r--r-- | src/ctemplates.c | 44 | ||||
| -rw-r--r-- | t/test_3.c | 72 |
4 files changed, 112 insertions, 14 deletions
@@ -15,6 +15,7 @@ objfiles = $(objs:%=build/%.o) TEST_1_NAME = t/test_1$(BIN_POSTFIX) TEST_2_NAME = t/test_2$(BIN_POSTFIX) +TEST_3_NAME = t/test_3$(BIN_POSTFIX) examples=hello variable example_bins=$(examples:%=examples/%$(BIN_POSTFIX)) @@ -36,9 +37,13 @@ $(TEST_1_NAME): t/test_1.c $(LIBNAME) $(TEST_2_NAME): t/test_2.c $(LIBNAME) $(CC) $(CFLAGS) -o $@ $< -lctemplates -test: $(TEST_1_NAME) $(TEST_2_NAME) +$(TEST_3_NAME): t/test_3.c $(LIBNAME) + $(CC) $(CFLAGS) -o $@ $< -lctemplates + +test: $(TEST_1_NAME) $(TEST_2_NAME) $(TEST_3_NAME) #$(TEST_1_NAME) - $(TEST_2_NAME) + #$(TEST_2_NAME) + $(TEST_3_NAME) examples: $(example_bins) $(example_bins) diff --git a/build/.gitignore b/build/.gitignore index e69de29..5761abc 100644 --- a/build/.gitignore +++ b/build/.gitignore @@ -0,0 +1 @@ +*.o diff --git a/src/ctemplates.c b/src/ctemplates.c index 559733f..ae2ed2a 100644 --- a/src/ctemplates.c +++ b/src/ctemplates.c @@ -139,7 +139,7 @@ int render_any( struct TMPL_templates* t, struct TMPL_varlist* varlist ); -void TMPL_render_helper( +int TMPL_render_helper( struct TMPL_templates* t, struct TMPL_varlist* varlist ); @@ -1065,7 +1065,8 @@ render_if(struct TMPL_templates* t, struct TMPL_varlist* varlist){ char* varname = t->cursor->TMPL_tag.ifelse.varname; char* testval = t->cursor->TMPL_tag.ifelse.testval; struct TMPL_varitem* vi; - int err = hashmap_get(varlist->map,varname,(void**)&vi); + int err; + err = hashmap_get(varlist->map,varname,(void**)&vi); struct TMPL_templates* nt = (struct TMPL_templates*)malloc(sizeof(struct TMPL_templates)); nt->out = t->out; nt->errout = t->errout; @@ -1078,7 +1079,7 @@ render_if(struct TMPL_templates* t, struct TMPL_varlist* varlist){ if(testval == NULL || strcmp(vi->item.s, testval) == 0){ nt->roottag = t->cursor->TMPL_tag.ifelse.tbranch; nt->cursor = nt->roottag; - TMPL_render_helper(nt,varlist); + err = TMPL_render_helper(nt,varlist); if(nt->jumping) t->cursor = nt->cursor; t->breaks += nt->breaks; @@ -1091,7 +1092,7 @@ render_if(struct TMPL_templates* t, struct TMPL_varlist* varlist){ }else if(t->cursor->TMPL_tag.ifelse.fbranch != NULL){ nt->roottag = t->cursor->TMPL_tag.ifelse.fbranch; nt->cursor = nt->roottag; - TMPL_render_helper(nt,varlist); + err = TMPL_render_helper(nt,varlist); if(nt->jumping) t->cursor = nt->cursor; t->breaks += nt->breaks; @@ -1101,7 +1102,7 @@ render_if(struct TMPL_templates* t, struct TMPL_varlist* varlist){ } free(nt); advance_cursor(t); - return 0; + return err; } /*Exactly the same thing as if*/ @@ -1150,8 +1151,15 @@ render_loop(struct TMPL_templates* t, struct TMPL_varlist* varlist){ char* loopname = t->cursor->TMPL_tag.loop.loopname; struct TMPL_tagnode* loopnode = t->cursor; struct TMPL_varitem* loop; - int err = resolve_name(varlist,loopname,&loop); + int err; + err = resolve_name(varlist,loopname,&loop); + printf("When resolving name, err is %d\n",err); + /*What should happen when we get to a loop that does not have a name? + We follow the precident set for variables, and throw an error.*/ if(err != MAP_OK){ + bputs(t->errout,"Render error: Variable \""); + bputs(t->errout,loopname); + bputs(t->errout,"\" was not bound to a value\n"); return -1; } struct TMPL_templates* nt = (struct TMPL_templates*)malloc(sizeof(struct TMPL_templates)); @@ -1183,7 +1191,7 @@ render_loop(struct TMPL_templates* t, struct TMPL_varlist* varlist){ } } }else{ - TMPL_render_helper(nt,cursor->varlist); + err = TMPL_render_helper(nt,cursor->varlist); t->breaks += nt->breaks; t->continues += nt->continues; t->jumping += nt->jumping; @@ -1204,7 +1212,7 @@ render_loop(struct TMPL_templates* t, struct TMPL_varlist* varlist){ if(t->cursor == loopnode) advance_cursor(t); free(nt); - return 0; + return err; } int @@ -1248,21 +1256,33 @@ render_any(struct TMPL_templates* t, struct TMPL_varlist* varlist){ return err; } -void +int TMPL_render_helper(struct TMPL_templates* t, struct TMPL_varlist* varlist){ - while(t->cursor != NULL && t->jumping == 0){ - render_any(t,varlist); + int err; + while(t->cursor != NULL && t->jumping == 0 && err == 0){ + err = render_any(t,varlist); } + return err; } char* TMPL_render(struct TMPL_templates* t, struct TMPL_varlist* varlist, size_t* size_p){ + int err; + /*Reset the output buffer*/ if(t->out != NULL){ free_tmpl_buf(t->out); } + /*Reset the error buffer, if needed*/ + if(t->errout != NULL && t->errout->total_len > 0){ + free_tmpl_buf(t->errout); + t->errout = alloc_tmpl_buf(); + } t->out = alloc_tmpl_buf(); t->cursor = t->roottag; - TMPL_render_helper(t,varlist); + err = TMPL_render_helper(t,varlist); + if(err){ + return NULL; + } char* ret = bstringify(t->out,size_p); return ret; } diff --git a/t/test_3.c b/t/test_3.c new file mode 100644 index 0000000..dc55aa6 --- /dev/null +++ b/t/test_3.c @@ -0,0 +1,72 @@ +#include <stdio.h> + +#include <ctemplates.h> + +//Nested loops w/ break +char t_1[] = "What is a loop with no items?<TMPL_LOOP name=\"loop1\">Something<TMPL_END>\nA sad little pile of bits!"; +char c_1_1[] = "What is a loop with no items?\nA sad little pile of bits!"; +char c_1_2[] = "What is a loop with no items?\nA sad little pile of bits!"; + +#define log(x) printf(x) + +#define check(n,n2,a,b)\ + if(strcmp(a,b) != 0){\ + fprintf(stderr, "Error in test 3.%d.%d\n",n,n2);\ + printf("Result should have been '%s'\n was '%s'\n", b, a);\ + if(t->error)\ + printf(TMPL_err(t, NULL));\ + return -1;\ + }else{\ + printf("\n\n##########\n##Test %d.%d passed\n##########\n\n\n",n,n2);\ + } + +#define check_isnull(n,n2,a)\ + if(a != NULL){\ + fprintf(stderr, "Error in test 3.%d.%d\n",n,n2);\ + printf("Result should have been NULL\n was '%s'\n", a);\ + if(t->error)\ + printf(TMPL_err(t, NULL));\ + return -1;\ + }else{\ + printf("\n\n##########\n##Test %d.%d passed\n##########\n\n\n",n,n2);\ + } + +#define template(x,y) \ + err = TMPL_alloc_template(x,&y);\ + if(err != 0){\ + printf("Error: %s\n",TMPL_err(y,&dummy));\ + return -1;\ + } + +int main(){ + log("Running tests2\n"); + struct TMPL_templates* t; + struct TMPL_varlist *vl,*vl1,*vl2; + struct TMPL_loop *l1,*l2; + char* ret; + size_t dummy; + int err; + + /*Test 1: Variable*/ + template(t_1,t); + vl = TMPL_alloc_varlist(); + l1 = TMPL_alloc_loop(); + TMPL_add_loop_to_varlist(vl,"loop1",l1); + ret = TMPL_render(t,vl,&dummy); + check(1,1,ret,c_1_1); + TMPL_free_template(t); + TMPL_free_varlist(vl); + log("Test 1 complete\n"); + + template(t_1,t); + vl = TMPL_alloc_varlist(); + l1 = TMPL_alloc_loop(); + TMPL_add_loop_to_varlist(vl,"notaloop",l1); + ret = TMPL_render(t,vl,&dummy); + check_isnull(1,2,ret); + TMPL_free_template(t); + TMPL_free_varlist(vl); + log("Test 2 complete\n"); + + return 0; +} |
