aboutsummaryrefslogtreecommitdiff
path: root/ctemplate.c
diff options
context:
space:
mode:
authorAlexander Pickering <alexandermpickering@gmail.com>2017-12-22 23:03:44 -0500
committerAlexander Pickering <alexandermpickering@gmail.com>2017-12-22 23:03:44 -0500
commit3e4c76bf41011d8f40136a4010e9ff331b00b4ea (patch)
tree82349a7c9f95b6c95c68daa8176cb42f75f182a9 /ctemplate.c
parent5926e6122a8eaf70aac25fa7b2c3bf12c7025978 (diff)
downloadlibctemplates-3e4c76bf41011d8f40136a4010e9ff331b00b4ea.tar.gz
libctemplates-3e4c76bf41011d8f40136a4010e9ff331b00b4ea.tar.bz2
libctemplates-3e4c76bf41011d8f40136a4010e9ff331b00b4ea.zip
Renamed files
Renamed everything that needed to be rename from libctemplate to libctemplates
Diffstat (limited to 'ctemplate.c')
-rw-r--r--ctemplate.c1063
1 files changed, 0 insertions, 1063 deletions
diff --git a/ctemplate.c b/ctemplate.c
deleted file mode 100644
index 291c6f9..0000000
--- a/ctemplate.c
+++ /dev/null
@@ -1,1063 +0,0 @@
-/*
- * C TemplateS : template expander
- * Based on the original libctemplate by Stephen C. Losen
- *
- * Version 0.1
- *
- * Copyright (c) 2017 Alexander M. Pickering (alexandermpickering@gmail.com)
- *
- * Distributed under the terms of the GNU General Public Liscense
- * (GPL). See COPYING for more information.
- *
- */
-
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <sys/stat.h>
-#include <stdarg.h>
-#include <ctemplate_i.h>
-void TMPL_free_loop(struct TMPL_loop* tl);
-
-struct TMPL_token* TMPL_alloc_token(){
- struct TMPL_token* ret = (struct TMPL_token*)malloc(sizeof(struct TMPL_token));
- ret->next = NULL;
- return ret;
-}
-
-void TMPL_free_token(struct TMPL_token* token){
- struct TMPL_token* cursor = token;
- while(cursor != NULL){
- struct TMPL_token* this = cursor;
- cursor = cursor->next;
- free(this);
- }
-}
-
-/*Check if it starts with the names of any of our tokens*/
-enum TMPL_tagtype starts_with_token(char* str, size_t strlen){
- //printf("hit starts_with_token, \"%s\"\n",str);
- //Make sure we get TMPL_ first
- if(strlen < 5){
- return tag_null;
- }
- if(*str != 'T'
- || *(str + 1) != 'M'
- || *(str + 2) != 'P'
- || *(str + 3) != 'L'
- || *(str + 4) != '_'){
- //printf("Didn't even start with tmpl_\n");
- return tag_null;
- }
- //printf("Did start with tmpl\n");
- if(strlen > TAG_VAR_LENGTH
- && *(str + 5) == 'V'
- && *(str + 6) == 'A'
- && *(str + 7) == 'R'
- && *(str + 8) == ' '){
- //printf("Hit var\n");
- return tag_var;
- }else if(strlen > TAG_IF_LENGTH
- && *(str + 5) == 'I'
- && *(str + 6) == 'F'
- && *(str + 7) == ' '){
- return tag_if;
- }else if(strlen > TAG_END_LENGTH
- && *(str + 5) == 'E'
- && *(str + 6) == 'N'
- && *(str + 7) == 'D'){
- return tag_end;
- }else if(strlen > TAG_ELSE_LENGTH
- && *(str + 5) == 'E'//Check for both else and elseif
- && *(str + 6) == 'L'
- && *(str + 7) == 'S'
- && *(str + 8) == 'E'){
- if(*(str + 9) != 'I'){
- return tag_else;
- }else if(strlen > TAG_ELSEIF_LENGTH
- && *(str + 9) == 'I'
- && *(str + 10) == 'F'
- && *(str + 11) == ' '){
- return tag_elseif;
- }else{
- return tag_null;
- }
- }else if(strlen > TAG_LOOP_LENGTH
- && *(str + 5) == 'L'
- && *(str + 6) == 'O'
- && *(str + 7) == 'O'
- && *(str + 8) == 'P'
- && *(str + 9) == ' '){
- return tag_loop;
- }else if(strlen > TAG_BREAK_LENGTH
- && *(str + 5) == 'B'
- && *(str + 6) == 'R'
- && *(str + 7) == 'E'
- && *(str + 8) == 'A'
- && *(str + 9) == 'K'
- && *(str + 10) == ' '){
- return tag_break;
- }else if(strlen > TAG_CONTINUE_LENGTH
- && *(str + 5) == 'C'
- && *(str + 6) == 'O'
- && *(str + 7) == 'N'
- && *(str + 8) == 'T'
- && *(str + 9) == 'I'
- && *(str + 10) == 'N'
- && *(str + 11) == 'U'
- && *(str + 12) == 'E'
- && *(str + 13) == ' '){
- return tag_continue;
- }else{
- return tag_null;
- }
-}
-
-size_t tagtype_len(enum TMPL_tagtype t){
- switch(t){
- case tag_null:
- return TAG_NULL_LENGTH;
- case tag_text:
- return TAG_TEXT_LENGTH;
- case tag_var:
- return TAG_VAR_LENGTH;
- case tag_if:
- return TAG_IF_LENGTH;
- case tag_end:
- return TAG_END_LENGTH;
- case tag_elseif:
- return TAG_ELSEIF_LENGTH;
- case tag_else:
- return TAG_ELSE_LENGTH;
- case tag_loop:
- return TAG_LOOP_LENGTH;
- case tag_break:
- return TAG_BREAK_LENGTH;
- case tag_continue:
- return TAG_CONTINUE_LENGTH;
- }
- return 0;
-}
-
-/*Quickly find the token*/
-struct TMPL_token* scan_text(char* start, size_t strlen, size_t* consumed){
- //printf("Scan starting at %p\n",start);
- //printf("Size of string was %d \"%s\"\n",(int)strlen,start);
- struct TMPL_token* t = TMPL_alloc_token();
- t->start = start;
- enum TMPL_tagtype type = tag_null;
- char* cursor = start;
- while(type == tag_null){
- cursor = (char*)memchr(cursor,'<',strlen);
- if(cursor == NULL){
- //printf("Cursor was null\n");
- cursor = start + (strlen > 0 ? strlen : 1);
- break;
- }
- //printf("Return of memchr was %s\n",cursor);
- type = starts_with_token(cursor+1,strlen);
- if(type == tag_null){
- cursor++;
- }
- }
- t->end = cursor;
- t->length = t->end - t->start;
- *consumed = t->length;
- //printf("Consumed length is %d\n",(int)*consumed);
- //printf("Scan_text is returning token:\n");
- char* c;
- for(c = start; c < cursor; c++){
- //printf("%c",*c);
- }
- //printf("\n");
- return t;
-}
-
-struct TMPL_token* scan_tag(char* start, size_t strlen, size_t* consumed){
- //printf("Scanning tag\n");
- struct TMPL_token* t = TMPL_alloc_token();
- t->start = start;
- char* cursor = (char*)memchr(start,'>',strlen);
- //printf("Managed to get through memchr, cursor is now %s\n",cursor);
- t->end = cursor+1;//Include the '>'
- t->length = t->end - t->start;
- *consumed = t->length;
- return t;
-}
-
-void print_tokens(struct TMPL_token* head){
- struct TMPL_token* cursor = head;
- while(cursor != NULL){
- printf("char start is %p char end is %p cursor is %p type is %d\n",cursor->start, cursor->end,(void*)cursor,(int)cursor->type);
- char* i;
- for(i = cursor->start; i != cursor->end; i++){
- printf("%c",*i);
- }
- printf("\n----\n");
- cursor = cursor->next;
- }
- printf("Finished printing tokens\n");
-}
-
-struct TMPL_varitem* TMPL_alloc_varitem(){
- struct TMPL_varitem* ret = (struct TMPL_varitem*)malloc(sizeof(struct TMPL_varitem));
- return ret;
-}
-
-void TMPL_free_varitem(struct TMPL_varitem* vi){
- //printf("Freeing varitem\n");
- if(vi->type == vartype_var){
- ////printf("Freeing string at %p(%s)\n",vi->item.s,vi->item.s);
- //free(vi->item.s);
- }else{
- //printf("Freeing loop\n");
- TMPL_free_loop(vi->item.l);
- }
- free(vi);
-}
-
-void TMPL_add_var_to_varlist(struct TMPL_varlist* t, char* varname, char* var){
- //printf("Adding \"%s\" to varlist under \"%s\"(%p)\n",var,varname,(void*)varname);
- struct TMPL_varitem* vi = TMPL_alloc_varitem();
- vi->type = vartype_var;
- size_t slen = strlen(var);
- vi->item.s = (char*)malloc(sizeof(char)*slen);
- memcpy(vi->item.s,var,slen);
- int succ = hashmap_put(t->map,varname,vi);
- if(succ != MAP_OK){
- //printf("FAiled to put item in %d\n",succ);
- exit(-1);
- }
- //printf("Done\n");
-}
-
-void print_ast_helper(struct TMPL_tagnode* cursor, int level){
- int i;
- for(i = 0; i < level; i++){
- printf("|");
- }
- printf("} %d ->",(int)cursor->type);
- switch(cursor->type){
- case tag_null:
- printf("TAG NULL");
- break;
- case tag_text:
- printf("TAG Text %d\n", (int)cursor->TMPL_tag.text.len);
- break;
- case tag_var:
- printf("TAG var(%s)",cursor->TMPL_tag.var.varname);
- if(cursor->TMPL_tag.var.default_len > 0){
- printf(" +default:%d",(int)cursor->TMPL_tag.var.default_len);
- }
- printf("\n");
- break;
- case tag_if:
- case tag_elseif:
- printf("TAG If/elseif,(%s) == (%s)\n",cursor->TMPL_tag.ifelse.varname,cursor->TMPL_tag.ifelse.testval);
- level++;
- for(i=0;i<level;i++){
- printf("|");
- }
- printf("True:\n");
- print_ast_helper(cursor->TMPL_tag.ifelse.tbranch,level);
- if(cursor->TMPL_tag.ifelse.fbranch != NULL){
- for(i=0;i<level;i++){
- printf("|");
- }
- printf("False:\n");
- print_ast_helper(cursor->TMPL_tag.ifelse.fbranch,level);
- }
- level--;
- break;
- case tag_else:
- printf("TAG Else\n");
- break;
- case tag_end:
- printf("TAG End\n");
- break;
- case tag_loop:
- printf("TAG Loop (%s), body:\n",cursor->TMPL_tag.loop.loopname);
- print_ast_helper(cursor->TMPL_tag.loop.body,level+1);
- break;
- case tag_break:
- printf("TAG Break\n");
- break;
- case tag_continue:
- printf("TAG Continue\n");
- break;
- }
- if(cursor->next != NULL){
- print_ast_helper(cursor->next,level);
- }
-}
-void print_ast(struct TMPL_tagnode* root){
- print_ast_helper(root,0);
-}
-
-struct TMPL_token* TMPL_tokenize(char* tmplstr, size_t strlen){
- if(strlen == 0) return NULL;
- struct TMPL_token* first;
- char* textcursor = tmplstr;
- size_t newlength;
- enum TMPL_tagtype ttype;
- ttype = starts_with_token(tmplstr+1,strlen);
- //printf("First ttype is %d\n",(int)ttype);
- if(ttype == tag_null){
- first = scan_text(textcursor,strlen,&newlength);
- first->type = tag_text;
- }else{
- first = scan_tag(textcursor,strlen,&newlength);
- first->type = ttype;
- }
- //printf("I got a first consumed length of %d\n",(int)newlength);
- textcursor += newlength;
- first->end = textcursor;
- first->length = newlength;
- strlen -= newlength;
- struct TMPL_token* tokencursor = first;
- struct TMPL_token* newnode;
- //print_tokens(first);
- while(*textcursor != '\0'){
- //printf("Getting a new token... size was %d textcursor is %d\n", (int)newlength, (int)*textcursor);
- ttype = starts_with_token(textcursor+1,strlen);
- //printf("Loop ttype is %d\n",(int)ttype);
- if(ttype == tag_null){
- newnode = scan_text(textcursor,strlen,&newlength);
- newnode->type = tag_text;
- }else{
- newnode = scan_tag(textcursor,strlen,&newlength);
- newnode->type = ttype;
- }
- tokencursor->next = newnode;
- textcursor += newlength;
- strlen -= newlength;
- tokencursor = newnode;
- }
- //printf("Returning from tokenize\n");
- return first;
-}
-void print_varlist_helper(struct TMPL_varlist* vl, int indent);
-void print_varlist(struct TMPL_varlist* vl);
-
-struct TMPL_tagnode* parse(struct TMPL_token* head, struct TMPL_buf* errbuf);
-
-struct TMPL_tagnode* alloc_tagnode(){
- struct TMPL_tagnode* t = malloc(sizeof(struct TMPL_tagnode));
- return t;
-}
-
-//Finds a quoted string, allows for \"
-size_t get_quoted_string(char* start, size_t len){
- size_t i;
- int setup;
- for(i = 0; i < len; i++){
- if(*(start+i) == '\\'){
- setup = 1;
- }else if(*(start+i) == '"'){
- if( setup == 1){
- //Do nothing, this is \"
- }else{
- return i;
- }
- }else{
- setup = 0;
- }
- }
- return i;
-}
-
-struct TMPL_tagnode* parse_text(struct TMPL_token* head, struct TMPL_buf* errbuf){
- //printf("Parsing text node\n");
- struct TMPL_tagnode* t = alloc_tagnode();
- t->TMPL_tag.text.start = head->start;
- t->TMPL_tag.text.len = head->length;
- t->type = head->type;
- //printf("About to call parse again\n");
- struct TMPL_tagnode* n = parse(head->next, errbuf);
- //printf("Parsed next\n");
- t->next = n;
- return t;
-}
-
-struct TMPL_tagnode* parse_else(struct TMPL_token* head, struct TMPL_buf* errbuf){
- struct TMPL_tagnode* branch = parse(head->next,errbuf);
- return branch;
-}
-
-struct TMPL_tagnode* parse_elseif(struct TMPL_token* head, struct TMPL_buf* errbuf){
- struct TMPL_tagnode* t = alloc_tagnode();
- //printf("Parsing elseif..., token was %s\n",head->start);
- char* start_of_attribs = head->start + TAG_ELSEIF_LENGTH;
- //printf("Start of attribs was %s\n",start_of_attribs);
- int name_offset = kmp(start_of_attribs,head->length, ATTRIBUTE_VARNAME,ATTRIBUTE_VARNAME_LENGTH);
- //printf("Found an elseif statement, offset is %d\n",name_offset);
- char* start_of_name = start_of_attribs + name_offset + ATTRIBUTE_VARNAME_LENGTH;
- //printf("Looking for name starting from %s\n",start_of_name);
- size_t name_length = get_quoted_string(start_of_name,head->length);
- //printf("Length of name was %d\n",(int)name_length);
- char* name = (char*)malloc(sizeof(char)*name_length);
- memcpy(name,start_of_name,name_length);
- name[name_length] = '\0';
- //printf("Makeing elseif with name: %s\n",name);
- t->TMPL_tag.ifelse.varname = name;
-
- int testval_offset = kmp(start_of_attribs,head->length, ATTRIBUTE_VALUE,ATTRIBUTE_VALUE_LENGTH);
- char* start_of_value = start_of_attribs + testval_offset + ATTRIBUTE_VALUE_LENGTH;
- size_t value_length = get_quoted_string(start_of_value,head->length);
- char* value = (char*)malloc(sizeof(char)*value_length);
- memcpy(value,start_of_value,value_length);
- value[value_length] = '\0';
- t->TMPL_tag.ifelse.testval = value;
- struct TMPL_token* cursor = head->next;
- int nest_level = 0;
- struct TMPL_token* fstart = NULL;
- while(nest_level > 0 || cursor->type != tag_end){
- if(nest_level == 0 && fstart == NULL){
- if(cursor->type == tag_elseif){
- fstart = cursor;
- }else if(cursor->type == tag_else){
- fstart = cursor;
- }
- }
- if(cursor->type == tag_if || cursor->type == tag_loop){
- nest_level++;
- }else if(cursor->type == tag_end){
- nest_level--;
- }
- cursor = cursor->next;
- }
- if(fstart != NULL){
- //printf("Found the fstart token to be %s\n",fstart->start);
- if(fstart->type == tag_elseif){
- t->TMPL_tag.ifelse.fbranch = parse_elseif(fstart,errbuf);
- }else if(fstart->type == tag_else){
- t->TMPL_tag.ifelse.fbranch = parse_else(fstart,errbuf);
- }else{
- t->TMPL_tag.ifelse.fbranch = parse(fstart,errbuf);
- }
- }else{
- //printf("Did not find an fstart token\n");
- t->TMPL_tag.ifelse.fbranch = NULL;
- }
-
- t->TMPL_tag.ifelse.tbranch = parse(head->next,errbuf);
- t->next = NULL;//parse(cursor->next,errbuf);
-
- t->type = tag_elseif;
- //printf("Parsed elseif statement:\n");
- //print_ast(t);
- return t;
-
-}
-
-struct TMPL_tagnode* parse_if(struct TMPL_token* head, struct TMPL_buf* errbuf){
- //printf("Parsing if...\n");
- struct TMPL_tagnode* t = alloc_tagnode();
- char* start_of_attribs = head->start + TAG_IF_LENGTH;
- /*Find the name of the varialbe*/
- int name_offset = kmp(start_of_attribs,head->length,ATTRIBUTE_VARNAME,ATTRIBUTE_VARNAME_LENGTH);
- //printf("Found an if statement, name offset is %d\n",name_offset);
- char* start_of_name = start_of_attribs + name_offset + ATTRIBUTE_VARNAME_LENGTH;
- size_t name_length = get_quoted_string(start_of_name,head->length);
- char* name = (char*)malloc(sizeof(char)*name_length);
- memcpy(name,start_of_name,name_length);
- name[name_length] = '\0';
- //printf("Found if name:\"%s\"\n",name);
- t->TMPL_tag.ifelse.varname = name;
- /*Find the name to check against*/
- int testval_offset = kmp(start_of_attribs,head->length, ATTRIBUTE_VALUE,ATTRIBUTE_VALUE_LENGTH);
- char* start_of_value = start_of_attribs + testval_offset + ATTRIBUTE_VALUE_LENGTH;
- size_t value_length = get_quoted_string(start_of_value,head->length);
- char* value = (char*)malloc(sizeof(char)*value_length);
- memcpy(value,start_of_value,value_length);
- value[value_length] = '\0';
- //printf("Found if value:\"%s\"\n",value);
- t->TMPL_tag.ifelse.testval = value;
- /*Find the true branch*/
- struct TMPL_token* cursor = head->next;
- int nest_level = 0;
- struct TMPL_token* fstart = NULL;
- while(nest_level > 0 || cursor->type != tag_end){
- if(fstart == NULL){
- if(cursor->type == tag_elseif){
- fstart = cursor;
- }else if(cursor->type == tag_else){
- fstart = cursor;
- }
- }
- if(cursor->type == tag_if || cursor->type == tag_loop){
- nest_level++;
- }else if(cursor->type == tag_end){
- nest_level--;
- }
- cursor = cursor->next;
- }
- if(fstart != NULL){
- //printf("Found the fstart token to be %s\n",fstart->start);
- if(fstart->type == tag_elseif){
- t->TMPL_tag.ifelse.fbranch = parse_elseif(fstart,errbuf);
- }else if(fstart->type == tag_else){
- //printf("Type was else, parsing...\n");
- //printf("Tokens were:\n");
- //print_tokens(fstart);
- //struct TMPL_tagnode* tn = parse_else(fstart,errbuf);
- //printf("Got tagnode back:\n");
- //print_ast(tn);
- t->TMPL_tag.ifelse.fbranch = parse_else(fstart,errbuf);
- }else{
- t->TMPL_tag.ifelse.fbranch = parse(fstart,errbuf);
- }
- }else{
- //printf("Did not find an fstart token\n");
- t->TMPL_tag.ifelse.fbranch = NULL;
- }
-
- t->TMPL_tag.ifelse.tbranch = parse(head->next,errbuf);
- //Walk the tbranch and try to find if we have elseifs
- t->next = parse(cursor->next,errbuf);
-
- t->type = tag_if;
- //printf("Parsed if statement:\n");
- //print_ast(t);
- return t;
-}
-
-
-struct TMPL_tagnode* parse_loop(struct TMPL_token* head, struct TMPL_buf* errbuf){
- //printf("Parsing loop that starts at %s\n",head->start);
- struct TMPL_tagnode* t = alloc_tagnode();
- char* loop_start = head->start + TAG_LOOP_LENGTH;
- int loop_length = head->length - TAG_LOOP_LENGTH;
- int name_offset = kmp(loop_start,loop_length, ATTRIBUTE_VARNAME, ATTRIBUTE_VARNAME_LENGTH);
- //printf("In parse loop, name offset was %d\n",name_offset);
- if(name_offset == -1 && DEBUGGING){
- bputs(errbuf,"Parsing error: Could not find name attribute for loop near\n");
- bputsn(errbuf,head->start, ERRBUF_HINTLEN);
- return NULL;
- }
- if(name_offset >= 0){
- char* start_of_name = loop_start + name_offset + ATTRIBUTE_VARNAME_LENGTH;
- //printf("Start of name is at %s\n",start_of_name);
- size_t name_size = get_quoted_string(start_of_name,head->length);
- char* loopname = (char*)malloc(sizeof(char)*name_size);
- loopname[name_size] = '\0';
- //printf("Loop name size is %d\n", (int)name_size);
- memcpy(loopname,start_of_name,name_size);
- //printf("Got loop name %s\n",loopname);
- t->TMPL_tag.loop.loopname = loopname;
-
- }
- t->type = tag_loop;
- int nest_level = 0;
- struct TMPL_token* cursor = head->next;
- while(cursor != NULL && (nest_level > 0 || cursor->type != tag_end)){
- //printf("Trying to find end of loop, cursor is");
- //print_tokens(cursor);
- if(cursor == NULL){
- bputs(errbuf,"Parse error : tried parsing loop and hit end of stream near\n");
- bputsn(errbuf,head->start,ERRBUF_HINTLEN);
- return NULL;
- }
- if(cursor->type == tag_if ||
- cursor->type == tag_loop){
- nest_level++;
- }else if(cursor->type == tag_end){
- nest_level--;
- }
- cursor = cursor->next;
- }
- if(cursor == NULL){
- bputs(errbuf,"Parse error: Tried parsing loop and hit end of stream near\n");
- bputsn(errbuf,head->start,ERRBUF_HINTLEN);
- return NULL;
- }
- //printf("Found end of loop near %20s\n",cursor->start);
- t->TMPL_tag.loop.body = parse(head->next,errbuf);
- t->next = parse(cursor->next,errbuf);
- return t;
-}
-
-struct TMPL_tagnode* parse_variable(struct TMPL_token* head, struct TMPL_buf* errbuf){
- //printf("Parsing variable\n");
- struct TMPL_tagnode* t = alloc_tagnode();
- char* start_of_attribs = head->start + TAG_VAR_LENGTH;
- int attribs_length = head->length - TAG_VAR_LENGTH;
- int in_name = kmp(start_of_attribs,attribs_length,ATTRIBUTE_VARNAME,ATTRIBUTE_VARNAME_LENGTH);
- int in_default = kmp(start_of_attribs,attribs_length,ATTRIBUTE_DEFAULT,ATTRIBUTE_DEFAULT_LENGTH);
- //printf("parse: start of attribs is %s\n",start_of_attribs);
- //printf("parse: length of 1 was %d, length of 2 was %d\n",(int)attribs_length,(int)ATTRIBUTE_VARNAME_LENGTH);
- //printf("While parseing variable, kmp search gave %d\n",in_name);
- if(in_name == -1 && DEBUGGING){
- char buf[ERR_MSG_LEN];
- snprintf(buf,ERR_MSG_LEN,"Parsing error: Could not find name=\"name\" near %s\n",head->start);
- bputs(errbuf,buf);
- }
- if(in_name >= 0){
- char* start_of_name = start_of_attribs + in_name + ATTRIBUTE_VARNAME_LENGTH;
- size_t name_size = get_quoted_string(start_of_name,head->length);
- char* name = (char*)malloc(sizeof(char)*name_size);
- memcpy(name,start_of_name,name_size);
- name[name_size] = '\0';
- t->TMPL_tag.var.varname = name;
- t->TMPL_tag.var.name_len = name_size;
- //printf("Found a varname\n");
- }
- if(in_default >= 0){
- char* start_of_default = start_of_attribs + in_default + ATTRIBUTE_DEFAULT_LENGTH;
- size_t default_size = get_quoted_string(start_of_default,head->length);
- char* def = (char*) malloc(sizeof(char)*default_size);
- def[default_size] = '\0';
- memcpy(def,start_of_default,default_size);
- t->TMPL_tag.var.defaultval = def;
- t->TMPL_tag.var.default_len = default_size;
- //printf("Found a default\n");
- }else{
- t->TMPL_tag.var.default_len = 0;
- }
- t->type = tag_var;
- t->next = parse(head->next,errbuf);
- //printf("Returning %p From parse_variable\n",(void*)t);
- //t->TMPL_tag.var.varname
- return t;
-}
-
-struct TMPL_varlist* TMPL_alloc_varlist(){
- struct TMPL_varlist* ret = (struct TMPL_varlist*)malloc(sizeof(struct TMPL_varlist));
- ret->map = hashmap_new();
- return ret;
-}
-
-
-int TMPL_free_hashmapitems(any_t a, any_t b){
- //printf("Freeing hashmap item at %p\n",(void*)b);
- struct TMPL_varitem* vi = (struct TMPL_varitem*)b;
- TMPL_free_varitem(vi);
- return MAP_OK;
-}
-
-void TMPL_free_varlist(struct TMPL_varlist* vl){
- //printf("Freeing varlist:\n");
- //print_varlist(vl);
- hashmap_iterate(vl->map,TMPL_free_hashmapitems,NULL);
- //printf("done interatively freeing\n");
- hashmap_free(vl->map);
- free(vl);
-}
-
-struct TMPL_loop* TMPL_alloc_loop(){
- struct TMPL_loop* ret = (struct TMPL_loop*)malloc(sizeof(struct TMPL_loop));
- ret->loop_len = 0;
- ret->varlist = NULL;
- ret->next = NULL;
- ret->tail = NULL;
- return ret;
-}
-
-void TMPL_free_loop(struct TMPL_loop* tl){
- //printf("Freeing loop\n");
- if(tl->next != NULL){
- TMPL_free_loop(tl->next);
- }
- TMPL_free_varlist(tl->varlist);
- free(tl);
-}
-
-void TMPL_add_varlist_to_loop(struct TMPL_loop* tl,struct TMPL_varlist* vl){
- //printf("Adding varlist to loop\n");
- //print_varlist(vl);
- if(tl->loop_len == 0){// Add the first node
- tl->varlist = vl;
- tl->tail = tl;
- tl->loop_len++;
- }else{
- struct TMPL_loop* new = TMPL_alloc_loop();
- new->varlist = vl;
- tl->tail->next = new;
- tl->tail = new;
- }
-}
-
-void TMPL_add_loop_to_varlist(struct TMPL_varlist* vl, char* name, struct TMPL_loop* l){
- //printf("Adding loop to varlist under \"%s\"\n",name);
- struct TMPL_varitem* vi = TMPL_alloc_varitem();
- vi->type = vartype_loop;
- vi->item.l = l;
- int err = hashmap_put(vl->map,name,vi);
- if(err != MAP_OK){
- //printf("Failed to add loop to varlist:%d\n",err);
- }
- struct TMPL_varitem* back;
- hashmap_get(vl->map,name,(void**)&back);
- //printf("Trying to get %s back out: %p\n",name,(void*)back);
- //printf("Varlist is now:\n");
- //print_varlist(vl);
-}
-
-
-
-//Parses tokens into a syntax tree
-struct TMPL_tagnode* parse(struct TMPL_token* head, struct TMPL_buf* errbuf){
- struct TMPL_tagnode* root;
- if(head == NULL){
- //printf("Asked to parse null");
- return NULL;
- }
- //printf("In parse, type is %d\n",(int)head->type);
- switch(head->type){
- case tag_text:
- root = parse_text(head,errbuf);
- break;
- case tag_var:
- root = parse_variable(head,errbuf);
- break;
- case tag_loop:
- root = parse_loop(head,errbuf);
- break;
- case tag_end:
- root = NULL;
- //root = prase(head->next, errbuf);
- break;
- case tag_if:
- root = parse_if(head,errbuf);
- //printf("Returned from parsing if\n");
- break;
- case tag_elseif:
- root = NULL;
- //root = parse_elseif(head,errbuf);
- //printf("Returned from parsing elseif\n");
- break;
- case tag_else:
- root = NULL;
- //root = parse_else(head,errbuf);
- break;
- default:
- //printf("Exiting parse early\n");
- exit(-1);
- break;
- }
- //size_t dummy;
- //printf("Errbuf was %s\n",bstringify(errbuf,&dummy));
- if(errbuf->total_len > 0){
- //printf("FAiled to parse\n");
- return NULL;
- }
- return root;
-}
-
-struct TMPL_templates* alloc_templates(){
- struct TMPL_templates* t = malloc(sizeof(struct TMPL_templates));
- return t;
-}
-
-struct TMPL_templates* compile(char* tmplstr){
- size_t slen = strlen(tmplstr);
- struct TMPL_templates* ret = alloc_templates();
- ret->out = alloc_tmpl_buf();
- ret->errout = alloc_tmpl_buf();
- struct TMPL_token* tokens = TMPL_tokenize(tmplstr,slen);
- //printf("Tokenized %p\n",(void*)tokens);
- //print_tokens(tokens);
- struct TMPL_tagnode* ast = parse(tokens,ret->errout);
- //printf("Ast was:\n");
- //print_ast(ast);
- if(ast == NULL){
- //printf("ast was null");
- }else{
- ret->roottag = ast;
- }
- //printf("ret roottag is %p\n",(void*)ret->roottag);
- return ret;
-}
-
-int render_any(struct TMPL_templates* t, struct TMPL_tagnode* node, struct TMPL_varlist* varlist);
-
-int render_variable(struct TMPL_templates* t, struct TMPL_tagnode* node, struct TMPL_varlist* varlist){
- //printf("Rendering variable...\n");
- struct TMPL_varitem* vi;
- char* varname = node->TMPL_tag.var.varname;
- //printf("Looking for var name %s in\n",varname);
- //print_varlist(varlist);
- int err = hashmap_get(varlist->map,varname,(void**)&vi);
- //printf("Err is %d\n",err);
- if(err == MAP_OK){
- //printf("Rendering val: %s\n", vi->item.s);
- bputs(t->out,vi->item.s);
- }else if(err == MAP_MISSING){
- //printf("Missing var named %s\n",varname);
- size_t has_default = node->TMPL_tag.var.default_len;
- if(has_default){
- bputs(t->out,node->TMPL_tag.var.defaultval);
- }else{
- /*Error, not bound and no default*/
- return -1;
- }
- }else{
- //printf("Failed to put in var\n");
- return -1;
- }
- return 0;
-}
-
-int render_text(struct TMPL_templates* t, struct TMPL_tagnode* node, struct TMPL_varlist* varlist){
- struct TMPL_buf* buf = t->out;
- char* text = (char*)node->TMPL_tag.text.start;
- size_t length = node->TMPL_tag.text.len;
- bputsn(buf,text,length);
- return 0;
-}
-
-int print_pair(any_t indent, any_t b){
- struct TMPL_varitem* vi = (struct TMPL_varitem*)b;
- int* ip = (int*)indent;
- int ind = *ip;
- if(vi->type == vartype_var){
- int i;
- for(i = 0; i < ind; i++)
- printf("\t");
- printf("%s\n",vi->item.s);
- }else{
- struct TMPL_loop* cursor;
- printf("{\n");
- ind++;
- for(cursor = vi->item.l; cursor != NULL; cursor = cursor->next){
- print_varlist_helper(cursor->varlist,ind);
- }
- printf("}\n");
- }
- return MAP_OK;
-}
-
-void print_varlist_helper(struct TMPL_varlist* vl, int indent){
- hashmap_iterate(vl->map, print_pair,&indent);
-}
-
-
-void print_varlist(struct TMPL_varlist* vl){
- print_varlist_helper(vl,0);
-}
-
-int render_if(struct TMPL_templates* t, struct TMPL_tagnode* node, struct TMPL_varlist* varlist){
- //printf("Rendering if...\n");
- //printf("Node %p tag %p\n",(void*)node,(void*)node->TMPL_tag.ifelse.varname);
- char* varname = node->TMPL_tag.ifelse.varname;
- //printf("Got varname: %s\n",varname);
- char* testval = node->TMPL_tag.ifelse.testval;
- //printf("Got varname %s and testval %s\n",varname,testval);
- struct TMPL_varitem* vi;
- //printf("About to hashmap get\n");
- int err = hashmap_get(varlist->map,varname,(void**)&vi);
- //printf("Found variable with key \"%s\" : \"%s\"\n",varname,vi->item.s);
- struct TMPL_tagnode* cursor;
- if(err == MAP_OK && strcmp(vi->item.s,testval) == 0){
- //printf("Rendering true branch\n");
- cursor = node->TMPL_tag.ifelse.tbranch;
- while(cursor != NULL){
- render_any(t,cursor,varlist);
- cursor = cursor->next;
- }
- }else if(node->TMPL_tag.ifelse.fbranch != NULL){
- //printf("Rendering false branch\n");
- //render_any(t,node->TMPL_tag.ifelse.fbranch,varlist);
- cursor = node->TMPL_tag.ifelse.fbranch;
- while(cursor != NULL){
- render_any(t,cursor,varlist);
- cursor = cursor->next;
- }
- }
- return 0;
-}
-
-int render_elseif(struct TMPL_templates* t, struct TMPL_tagnode* node, struct TMPL_varlist* varlist){
- char* varname = node->TMPL_tag.ifelse.varname;
- char* testval = node->TMPL_tag.ifelse.testval;
- struct TMPL_varitem* vi;
- int err = hashmap_get(varlist->map,varname,(void**)&vi);
- //printf("Rendering elseif ast:\n");
- //print_ast(node);
- struct TMPL_tagnode* cursor;
- if(err == MAP_OK && strcmp(vi->item.s, testval) == 0){
- //printf("Rendering true branch\n");
- cursor = node->TMPL_tag.ifelse.tbranch;
- while(cursor != NULL){
- render_any(t,cursor,varlist);
- cursor = cursor->next;
- }
- }else if(node->TMPL_tag.ifelse.fbranch != NULL){
- //printf("Rendering false branch\n");
- cursor = node->TMPL_tag.ifelse.fbranch;
- while(cursor != NULL){
- render_any(t,cursor,varlist);
- cursor = cursor->next;
- }
- }
- return 0;
-}
-void TMPL_render_helper(struct TMPL_templates* t, struct TMPL_varlist* varlist);
-
-int render_loop(struct TMPL_templates* t, struct TMPL_tagnode* node, struct TMPL_varlist* varlist){
- char* loopname = node->TMPL_tag.loop.loopname;
- struct TMPL_varitem* loop;
- //printf("Attempting to render loop:\n");
- //print_ast(node);
- //printf("With varlist:\n");
- //print_varlist(varlist);
- //printf("Looking for loop name %s\n", loopname);
- int err = hashmap_get(varlist->map,loopname,(void*)&loop);
- if(err != MAP_OK){
- //printf("Failed to get loop struct, %d\n",err);
- return -1;
- }
- //printf("Got loop struct %p\n",(void*)loop);
- //printf("First varlist is\n");
- //print_varlist(loop->item.l->varlist);
- struct TMPL_templates* nt = (struct TMPL_templates*)malloc(sizeof(struct TMPL_templates));
- nt->out = t->out;
- nt->errout = t->errout;
- nt->roottag = node->TMPL_tag.loop.body;
- struct TMPL_loop* cursor;
- for(cursor = loop->item.l; cursor != NULL; cursor = cursor->next){
- //printf("Rendering loop.This varlist is\n");
- //print_varlist(cursor->varlist);
- //int err = render_any(t,node->TMPL_tag.loop.body,cursor->varlist);
- if(err != 0){
- //printf("Failed to render loop\n");
- }
- TMPL_render_helper(nt,cursor->varlist);
- }
- //struct TMPL_buf* buf = t->out;
- //printf("Done rendering loop\n");
- free(nt);
- return 0;
-}
-
-int render_any(struct TMPL_templates* t, struct TMPL_tagnode* node, struct TMPL_varlist* varlist){
- /*Interpret the template*/
- int err;
- switch(node->type){
- case tag_text:
- //printf("Rendering text\n");
- err = render_text(t,node,varlist);
- if(err < 0){
- //printf("Failed to render text\n");
- }
- //printf("Done rendering text\n");
- break;
- case tag_var:
- //printf("Rendering var\n");
- err = render_variable(t,node,varlist);
- if(err < 0){
- //printf("Failed to render variable\n");
- }
- break;
- case tag_loop:
- //printf("Rendering loop\n");
- err = render_loop(t,node,varlist);
- if(err < 0){
- //printf("Failed to render loop\n");
- }
- break;
- case tag_if:
- //printf("Rendering if\n");
- err = render_if(t,node,varlist);
- if(err < 0){
- //printf("Failed to render if\n");
- }
- break;
- case tag_elseif:
- //printf("Rendering elseif\n");
- err = render_elseif(t,node,varlist);
- if(err < 0){
- //printf("Failed to render elseif\n");
- }
- break;
- default:
- //printf("Rendering default %d\n",(int)node->type);
- exit(-1);
- break;
- }
- return err;
-}
-
-void TMPL_render_helper(struct TMPL_templates* t, struct TMPL_varlist* varlist){
- struct TMPL_tagnode* cursor = t->roottag;
- while(cursor != NULL){
- render_any(t,cursor,varlist);
- cursor = cursor->next;
- }
-
-}
-
-char* TMPL_render(struct TMPL_templates* t, struct TMPL_varlist* varlist){
- if(t->out != NULL){
- free_tmpl_buf(t->out);
- }
- t->out = alloc_tmpl_buf();
- TMPL_render_helper(t,varlist);
- size_t dummy;
- char* ret = bstringify(t->out,&dummy);
- return ret;
-}
-
-struct TMPL_templates* TMPL_alloc_template(char* tmplstr){
- struct TMPL_templates* n = compile(tmplstr);
- ////printf("After returning from compile, rottag is %p\n",(void*)n->roottag);
-
- if(n != NULL){
- return n;
- }else{
- TMPL_free_template(n);
- return NULL;
- }
-}
-
-void TMPL_free_template(struct TMPL_templates* t){
- free_tmpl_buf(t->out);
- free_tmpl_buf(t->errout);
- TMPL_free_tagnode(t->roottag);
- free(t);
- ////printf("Freed tagnodes\n");
-}
-
-void TMPL_free_tagnode(struct TMPL_tagnode* tn){
- //printf("Freeing tagnode:\n");
- //print_ast(tn);
- switch(tn->type){
- case tag_text:
- break;
- case tag_var:
- free(tn->TMPL_tag.var.varname);
- if(tn->TMPL_tag.var.default_len > 0){
- free(tn->TMPL_tag.var.defaultval);
- }
- break;
- case tag_if:
- case tag_elseif:
- case tag_else:
- free(tn->TMPL_tag.ifelse.varname);
- free(tn->TMPL_tag.ifelse.testval);
- TMPL_free_tagnode(tn->TMPL_tag.ifelse.tbranch);
- if(tn->TMPL_tag.ifelse.fbranch){
- TMPL_free_tagnode(tn->TMPL_tag.ifelse.fbranch);
- }
- break;
- case tag_loop:
- free(tn->TMPL_tag.loop.loopname);
- TMPL_free_tagnode(tn->TMPL_tag.loop.body);
- break;
- case tag_null:
- case tag_break:
- case tag_continue:
- case tag_end:
- break;
- }
- if(tn->next != NULL)
- TMPL_free_tagnode(tn->next);
- free(tn);
-}
-
-char* TMPL_get_error(struct TMPL_templates* t){
- size_t dummy;
- return bstringify(t->errout,&dummy);
-}