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
|
#include "lexer.h"
struct TMPL_token* TMPL_alloc_token(void);
void TMPL_free_token(struct TMPL_token* token);
enum TMPL_tagtype starts_with_token(const char* str, size_t strlen);
size_t tagtype_len(enum TMPL_tagtype t);
struct TMPL_token* scan_text(
const char* start,
size_t strlen,
size_t* consumed
);
struct TMPL_token* scan_tag(
const char* start,
size_t strlen,
size_t* consumed
);
void print_tokens(struct TMPL_token* head);
/*Allocates a token*/
struct TMPL_token*
TMPL_alloc_token(){
struct TMPL_token* ret = (struct TMPL_token*)malloc(sizeof(struct TMPL_token));
ret->next = NULL;
return ret;
}
/*Frees an allocated token*/
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(const char* str, size_t strlen){
/*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) != '_'){
return tag_null;
}
if(strlen > TAG_VAR_LENGTH
&& *(str + 5) == 'V'
&& *(str + 6) == 'A'
&& *(str + 7) == 'R'
&& *(str + 8) == ' '){
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'){
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'){
return tag_continue;
}else{
return tag_null;
}
}
/*Find the lenth of a tag*/
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(const char* start, size_t strlen, size_t* consumed){
struct TMPL_token* t = TMPL_alloc_token();
t->start = start;
enum TMPL_tagtype type = tag_null;
const char* cursor = start;
while(type == tag_null){
int left = strlen - (cursor - start);
cursor = (const char*)memchr(cursor,'<',left);
if(cursor == NULL){
cursor = start + (strlen > 0 ? strlen : 1);
break;
}
type = starts_with_token(cursor+1,strlen);
if(type == tag_null){
cursor++;
}
}
t->end = cursor;
t->length = t->end - t->start;
*consumed = t->length;
return t;
}
struct TMPL_token*
scan_tag(const char* start, size_t strlen, size_t* consumed){
struct TMPL_token* t = TMPL_alloc_token();
t->start = start;
char* cursor = (char*)memchr(start,'>',strlen);
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);
const char* i;
for(i = cursor->start; i != cursor->end; i++){
printf("%c",*i);
}
printf("\n----\n");
cursor = cursor->next;
}
printf("Finished printing tokens\n");
}
|