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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
|
/*
* 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"
#include "ctemplates.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_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;
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
}TMPL_token;
typedef void (*TMPL_fmtfunc) (const char *, FILE *);
/*
TMPL_varlist *TMPL_add_var(TMPL_varlist *varlist,
const char *varname1, const char *value1, ... , 0);
*/
//TMPL_varlist *TMPL_add_var(TMPL_varlist *varlist, ...);
extern struct TMPL_varlist* TMPL_add_var(struct TMPL_varlist* varlist, ...);
/*TMPL_varlist *TMPL_add_loop(TMPL_varlist *varlist,
const char *name, TMPL_loop *loop);
*/
extern struct TMPL_varlist* TMPL_add_loop(struct TMPL_varlist* varlist,
const char* name, struct TMPL_loop* loop);
//TMPL_loop *TMPL_add_varlist(TMPL_loop *loop, TMPL_varlist *varlist);
struct TMPL_loop* TMPL_add_varlist(struct TMPL_loop* loop, struct TMPL_varlist* varlist);
//void TMPL_free_varlist(TMPL_varlist *varlist);
void TMPL_free_varlist(struct TMPL_varlist* varlist);
//TMPL_fmtlist *TMPL_add_fmt(TMPL_fmtlist *fmtlist,
//const char *name, TMPL_fmtfunc fmtfunc);
struct TMPL_fmtlist* TMPL_add_fmt(struct TMPL_fmtlist* fmtlist,
const char* name, void* fmtfunc);
void TMPL_free_fmtlist(struct TMPL_fmtlist* fmtlist);
/*int TMPL_write(const char *filename, const char *tmplstr,
const TMPL_fmtlist *fmtlist, const TMPL_varlist *varlist,
FILE *out, FILE *errout);
*/
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);
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);
/* TODO: Remove this after testing is done */
struct TMPL_token* TMPL_tokenize(char* tmplstr, size_t strlen);
#endif
|