/* * C TemplateS : template expander * Based on the original libctemplate by Stephen C. Losen * * Version 0.1 * * Copyright (c) 2017-2019 Alexander M. Pickering (alex@cogarr.net) * * Distributed under GPL V3, see COPYING for more information. * 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" #include "lexer.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 ERRBUF_HINTLEN 50 //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 ATTRIBUTE_LEVEL_LENGTH SIZEOF(ATTRIBUTE_LEVEL) - 1 //Define to 0 for slight speedup improvements, no errors #define DEBUGGING 1 //Length of error messages #define ERR_MSG_LEN 500 struct TMPL_light_string{ const char* start; size_t len; }; enum TMPL_vartype{ vartype_null = 0, vartype_loop, vartype_var }; struct TMPL_varlist TMPL_varlist; struct TMPL_loop TMPL_loop; struct TMPL_varlist{ map_t map; struct TMPL_loop* parent; }TMPL_varlist; struct TMPL_loop{ struct TMPL_varlist* varlist; struct TMPL_varlist* parent; size_t loop_len; struct TMPL_loop* next; struct TMPL_loop* tail; }TMPL_loop; 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; struct TMPL_tagnode* parent; 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;//Just use next as the next value struct TMPL_tagnode* into; }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; struct TMPL_tagnode* cursor; int jumping; //tells other functions that they should not change //the cursor, set after a break or continue. int breaks; int continues; int linenum; int error; } TMPL_templates; int TMPL_add_var_to_varlist(struct TMPL_varlist* vl, const char* name, const char* value); int TMPL_add_loop_to_varlist(struct TMPL_varlist* vl, const char* name, struct TMPL_loop* loop); int 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); int TMPL_alloc_template(const char* tmplstr, struct TMPL_templates **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); const char* TMPL_err(struct TMPL_templates* t, size_t* size); 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); void print_ast(struct TMPL_templates* root); #endif