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 
16 typedef struct CallbackItem {
21  const char *lang;
22 
27  const char *entity;
28 
30  int s;
31 
33  int e;
34 
36  void *udata;
37 
39  struct CallbackItem *next;
40 
41 } Callback;
42 
45 
48 
70 void 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 {
85  callback_list_tail->next = item;
86  callback_list_tail = item;
87  }
88 }
89 
91 void 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 
270 int 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 
324 int cs;
325 
327 int act;
328 
330 char *p;
331 
333 char *pe;
334 
336 char *eof;
337 
339 char *ts;
340 
342 char *te;
343 
345 int stack[5];
346 
348 int top;
349 
352 
359 #define cint(c) ((int) (c - buffer_start))
360 
366 
372 
378 
380 int entity;
381 
386 const 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