ohcount
parser_macros.h
Go to the documentation of this file.
1// parser_macros.h written by Mitchell Foral. mitchell<att>caladbolg.net.
2// See COPYING for license information.
3
4#ifndef OHCOUNT_PARSER_MACROS_H
5#define OHCOUNT_PARSER_MACROS_H
6
7#include <stdio.h>
8#include <stdlib.h>
9
10#include "languages.h"
11
16typedef struct CallbackItem {
21 const char *lang;
22
27 const char *entity;
28
30 int s;
31
33 int e;
34
36 void *udata;
37
40
42
45
48
70void enqueue(const char *lang, const char *entity, int s, int e, void *udata) {
71 Callback *item = (Callback *) malloc(sizeof(Callback));
72 if (!item) printf("Failed to allocate memory for enqueued callback.\n");
73
74 item->lang = lang;
75 item->entity = entity;
76 item->s = s;
77 item->e = e;
78 item->udata = udata;
79 item->next = NULL;
80
81 if (!callback_list_head) {
82 callback_list_head = item;
83 callback_list_tail = item;
84 } else {
86 callback_list_tail = item;
87 }
88}
89
91void free_queue() {
93 while (item) {
94 Callback *next = item->next;
95 free(item);
96 item = next;
97 }
98 callback_list_head = NULL;
99 callback_list_tail = NULL;
100}
101
107#define dequeue { \
108 inqueue = 0; \
109 line_start = last_line_start; \
110 line_contains_code = last_line_contains_code; \
111 whole_line_comment = last_whole_line_comment; \
112}
113
119#define ls { \
120 if (inqueue) { dequeue; } \
121 if (!line_start) line_start = ts; \
122}
123
130#define code { \
131 if (inqueue) { dequeue; } \
132 if (!line_contains_code && !line_start) line_start = ts; \
133 line_contains_code = 1; \
134}
135
141#define comment { \
142 if (inqueue) { dequeue; } \
143 if (!line_contains_code) { \
144 whole_line_comment = 1; \
145 if (!line_start) line_start = ts; \
146 } \
147}
148
157#define saw(lang) { \
158 seen = lang; \
159 whole_line_comment = 0; \
160 line_contains_code = 0; \
161}
162
169#define std_internal_newline(lang) { \
170 if (callback && p > line_start) { \
171 if (line_contains_code) { \
172 if (inqueue) \
173 enqueue(lang, "lcode", cint(line_start), cint(p), userdata); \
174 else \
175 callback(lang, "lcode", cint(line_start), cint(p), userdata); \
176 } else if (whole_line_comment) { \
177 if (inqueue) \
178 enqueue(lang, "lcomment", cint(line_start), cint(p), userdata); \
179 else \
180 callback(lang, "lcomment", cint(line_start), cint(p), userdata); \
181 } else { \
182 if (inqueue) \
183 enqueue(lang, "lblank", cint(line_start), cint(p), userdata); \
184 else \
185 callback(lang, "lblank", cint(line_start), cint(p), userdata); \
186 } \
187 } \
188 whole_line_comment = 0; \
189 line_contains_code = 0; \
190 line_start = p; \
191}
192
201#define emb_internal_newline(lang) { \
202 if (seen && seen != lang) \
203 std_internal_newline(seen) \
204 else \
205 std_internal_newline(lang) \
206 seen = 0; \
207}
208
215#define std_newline(lang) {\
216 if (inqueue) { dequeue; } \
217 if (callback && te > line_start) { \
218 if (line_contains_code) \
219 callback(lang, "lcode", cint(line_start), cint(te), userdata); \
220 else if (whole_line_comment) \
221 callback(lang, "lcomment", cint(line_start), cint(te), userdata); \
222 else \
223 callback(lang, "lblank", cint(ts), cint(te), userdata); \
224 } \
225 whole_line_comment = 0; \
226 line_contains_code = 0; \
227 line_start = 0; \
228}
229
238#define emb_newline(lang) { \
239 if (seen && seen != lang) \
240 std_newline(seen) \
241 else \
242 std_newline(lang) \
243 seen = 0; \
244}
245
253#define process_last_line(lang) {\
254 if ((whole_line_comment || line_contains_code) && callback) { \
255 if (line_contains_code) \
256 callback(lang, "lcode", cint(line_start), cint(pe), userdata); \
257 else if (whole_line_comment) \
258 callback(lang, "lcomment", cint(line_start), cint(pe), userdata); \
259 } \
260}
261
270int is_blank_entry(char **p) {
271 char *pos = *p+1;
272 while (*pos != '\n' && *pos != '\r' && *pos != '\f') {
273 if (*pos != '\t' && *pos != ' ') return 0;
274 pos++;
275 }
276 if (*pos == '\r' && *(pos+1) == '\n') pos++;
277 *p = pos;
278 return 1;
279}
280
291#define check_blank_entry(lang) { \
292 if (is_blank_entry(&p)) { \
293 te = p + 1; \
294 std_newline(lang) \
295 } \
296}
297
298// Variables used by all parsers. Do not modify.
299
304#define NEWLINE -1
305
312#define INTERNAL_NL -2
313
321#define CHECK_BLANK_ENTRY -3
322
324int cs;
325
327int act;
328
330char *p;
331
333char *pe;
334
336char *eof;
337
339char *ts;
340
342char *te;
343
345int stack[5];
346
348int top;
349
352
359#define cint(c) ((int) (c - buffer_start))
360
366
372
378
381
386const char *seen;
387
394
400
406
412
417#define init { \
418 p = buffer; \
419 pe = buffer + length; \
420 eof = pe; \
421 \
422 buffer_start = buffer; \
423 whole_line_comment = 0; \
424 line_contains_code = 0; \
425 line_start = 0; \
426 entity = 0; \
427 seen = 0; \
428 inqueue = 0; \
429}
430
431#endif
int last_whole_line_comment
Definition: parser_macros.h:411
char * eof
Definition: parser_macros.h:336
int stack[5]
Definition: parser_macros.h:345
char * last_line_start
Definition: parser_macros.h:399
const char * seen
Definition: parser_macros.h:386
int is_blank_entry(char **p)
Definition: parser_macros.h:270
char * ts
Definition: parser_macros.h:339
char * pe
Definition: parser_macros.h:333
char * te
Definition: parser_macros.h:342
int act
Definition: parser_macros.h:327
Callback * callback_list_head
Definition: parser_macros.h:44
struct CallbackItem Callback
int whole_line_comment
Definition: parser_macros.h:365
void free_queue()
Definition: parser_macros.h:91
int line_contains_code
Definition: parser_macros.h:371
char * line_start
Definition: parser_macros.h:377
Callback * callback_list_tail
Definition: parser_macros.h:47
int inqueue
Definition: parser_macros.h:393
char * p
Definition: parser_macros.h:330
int last_line_contains_code
Definition: parser_macros.h:405
void enqueue(const char *lang, const char *entity, int s, int e, void *udata)
Definition: parser_macros.h:70
int cs
Definition: parser_macros.h:324
int entity
Definition: parser_macros.h:380
char * buffer_start
Definition: parser_macros.h:351
int top
Definition: parser_macros.h:348
Holds a series of callbacks for in a queue (linked list).
Definition: parser_macros.h:16
const char * entity
Definition: parser_macros.h:27
const char * lang
Definition: parser_macros.h:21
int s
Definition: parser_macros.h:30
void * udata
Definition: parser_macros.h:36
int e
Definition: parser_macros.h:33
struct CallbackItem * next
Definition: parser_macros.h:39