1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
/*
* 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
|