/* * C TemplateS Library 0.1 - * Forked from C Template Library 1.0 by Stephen C. Losen. * * Copyright 2017 Alexander M. Pickering Distributed under the terms * of the GNU General Public License (GPL) */ #ifndef _CTEMPLATE_H #define _CTEMPLATE_H #include "fbuf.h" #include "kmp.h" #include "hashmap.h" #define MAX_TEMPLATE_LENGTH 2147384647 /* typedef struct TMPL_varlist TMPL_varlist; typedef struct TMPL_loop TMPL_loop; typedef struct TMPL_fmtlist TMPL_fmtlist; typedef struct TMPL_fmtlists TMPL_fmtlists; */ #define TAG_NULL_TEXT "" #define TAG_TEXT_TEXT "" #define TAG_VAR_TEXT "TMPL_VAR" #define TAG_IF_TEXT "TMPL_IF" #define TAG_ELSEIF_TEXT "TMPL_ELSEIF" #define TAG_ELSE_TEXT "TMPL_ELSE" #define TAG_LOOP_TEXT "TMPL_LOOP" #define TAG_BREAK_TEXT "TMPL_BREAK" #define TAG_CONTINUE_TEXT "TMPL_CONTINUE" #define TAG_END_TEXT "TMPL_END" #define ATTRIBUTE_VARNAME "name=\"" #define ATTRIBUTE_DEFAULT "default=\"" #define ATTRIBUTE_VALUE "value=\"" #define ERRBUF_HINTLEN 50 #define SIZEOF(x) (sizeof(x) / sizeof(x[0])) #define TAG_NULL_LENGTH 0 #define TAG_TEXT_LENGTH 0 #define TAG_VAR_LENGTH SIZEOF(TAG_VAR_TEXT) #define TAG_IF_LENGTH SIZEOF(TAG_IF_TEXT) #define TAG_ELSEIF_LENGTH SIZEOF(TAG_ELSEIF_TEXT) #define TAG_ELSE_LENGTH SIZEOF(TAG_ELSE_TEXT) #define TAG_LOOP_LENGTH SIZEOF(TAG_LOOP_TEXT) #define TAG_BREAK_LENGTH SIZEOF(TAG_BREAK_TEXT) #define TAG_CONTINUE_LENGTH SIZEOF(TAG_CONTINUE_TEXT) #define TAG_END_LENGTH SIZEOF(TAG_END_TEXT) //I guess it counts the backslash? #define ATTRIBUTE_VARNAME_LENGTH SIZEOF(ATTRIBUTE_VARNAME) - 1 #define ATTRIBUTE_DEFAULT_LENGTH SIZEOF(ATTRIBUTE_DEFAULT) - 1 #define ATTRIBUTE_VALUE_LENGTH SIZEOF(ATTRIBUTE_VALUE) - 1 //Define to 0 for slight speedup improvements, no errors #define DEBUGGING 1 //Length of error messages #define ERR_MSG_LEN 500 /*The different kind of nodes we can have*/ enum TMPL_tagtype{ tag_null = 0,/*Should never show up*/ tag_text = 1,/*A text sequence*/ tag_var = 2,/*A variable to replace*/ tag_if = 3,/*If*/ tag_elseif = 4,/*Else if*/ tag_else = 5,/*Else*/ tag_end = 6,/*end if, end loop*/ tag_loop = 7,/*Loop*/ tag_break = 9,/*Break*/ tag_continue = 10,/*Skip the rest of the loop and go again*/ }; struct TMPL_light_string{ const char* start; size_t len; }; enum TMPL_vartype{ vartype_null = 0, vartype_loop, vartype_var }; struct TMPL_varlist{ map_t map; }TMPL_varlist; struct TMPL_loop{ struct TMPL_varlist* varlist; size_t loop_len; struct TMPL_loop* next; struct TMPL_loop* tail; }; struct TMPL_varitem{ enum TMPL_vartype type; union { struct TMPL_loop* l; char* s; }item; }; /*Holds all the data needed for a single node in a template*/ struct TMPL_tagnode{ enum TMPL_tagtype type; struct TMPL_tagnode* next; unsigned int line; unsigned int character; union{ /*Text*/ struct{ const char* start; size_t len; }text; /*Var*/ struct{ char* varname; size_t name_len; char* defaultval; size_t default_len; }var; /*If, elseif*/ struct{ char* varname; char* testval; struct TMPL_tagnode* tbranch; struct TMPL_tagnode* fbranch; }ifelse; /*Loop*/ struct{ char* loopname; struct TMPL_tagnode* body; }loop; /*Break and Continue*/ struct{ int level; }breakcont; }TMPL_tag; }TMPL_tagnode; //typedef void (*TMPL_fmtfuncs) (const char*, struct TMPL_buf*); /* * TMPL_fmtlist is a list of format functions, which are passed to * a template. A TMPL_VAR tag can specify a format function for * outputting the variable with the fmt="fmtname" attribute. */ struct TMPL_fmtlist{ struct TMPL_fmtlist* next; void* fmtfunc; char* name; } TMPL_fmtlist; /* Holdes all the data needed for a template*/ struct TMPL_templates{ struct TMPL_buf* out; struct TMPL_buf* errout; struct TMPL_tagnode* roottag; int linenum; int error; } TMPL_templates; struct TMPL_token{ char* start;//Start of token char* end;//End of token enum TMPL_tagtype type;//The type of token size_t length;//Length of token, should always be end-start struct TMPL_token* next;//The next token unsigned int line; unsigned int character; }TMPL_token; void TMPL_add_var_to_varlist(struct TMPL_varlist* vl, char* name, char* value); void TMPL_add_loop_to_varlist(struct TMPL_varlist* vl, char* name, struct TMPL_loop* loop); void TMPL_add_varlist_to_loop(struct TMPL_loop* l, struct TMPL_varlist* vl); struct TMPL_varlist* TMPL_alloc_varlist(void); void TMPL_free_varlist(struct TMPL_varlist* t); struct TMPL_varitem* TMPL_alloc_varitem(void); void TMPL_free_varitem(struct TMPL_varitem* vi); struct TMPL_templates* TMPL_alloc_template(char* t); void TMPL_free_template(struct TMPL_templates* t); struct TMPL_loop* TMPL_alloc_loop(void); void TMPL_free_loop(struct TMPL_loop* tl); char* TMPL_render(struct TMPL_templates* t, struct TMPL_varlist* varlist, size_t* size_p); struct TMPL_tagnode* TMPL_alloc_tagnode(enum TMPL_tagtype); void TMPL_free_tagnode(struct TMPL_tagnode* tn); /*A debug function*/ void print_varlist(struct TMPL_varlist* vl); #endif