00001
00002
00003
00004 #ifndef OHCOUNT_PARSER_MACROS_H
00005 #define OHCOUNT_PARSER_MACROS_H
00006
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009
00010 #include "languages.h"
00011
00016 typedef struct CallbackItem {
00021 const char *lang;
00022
00027 const char *entity;
00028
00030 int s;
00031
00033 int e;
00034
00036 void *udata;
00037
00039 struct CallbackItem *next;
00040
00041 } Callback;
00042
00044 Callback *callback_list_head = NULL;
00045
00047 Callback *callback_list_tail = NULL;
00048
00070 void enqueue(const char *lang, const char *entity, int s, int e, void *udata) {
00071 Callback *item = (Callback *) malloc(sizeof(Callback));
00072 if (!item) printf("Failed to allocate memory for enqueued callback.\n");
00073
00074 item->lang = lang;
00075 item->entity = entity;
00076 item->s = s;
00077 item->e = e;
00078 item->udata = udata;
00079 item->next = NULL;
00080
00081 if (!callback_list_head) {
00082 callback_list_head = item;
00083 callback_list_tail = item;
00084 } else {
00085 callback_list_tail->next = item;
00086 callback_list_tail = item;
00087 }
00088 }
00089
00091 void free_queue() {
00092 Callback *item = callback_list_head;
00093 while (item) {
00094 Callback *next = item->next;
00095 free(item);
00096 item = next;
00097 }
00098 callback_list_head = NULL;
00099 callback_list_tail = NULL;
00100 }
00101
00107 #define dequeue { \
00108 inqueue = 0; \
00109 line_start = last_line_start; \
00110 line_contains_code = last_line_contains_code; \
00111 whole_line_comment = last_whole_line_comment; \
00112 }
00113
00119 #define ls { \
00120 if (inqueue) { dequeue; } \
00121 if (!line_start) line_start = ts; \
00122 }
00123
00130 #define code { \
00131 if (inqueue) { dequeue; } \
00132 if (!line_contains_code && !line_start) line_start = ts; \
00133 line_contains_code = 1; \
00134 }
00135
00141 #define comment { \
00142 if (inqueue) { dequeue; } \
00143 if (!line_contains_code) { \
00144 whole_line_comment = 1; \
00145 if (!line_start) line_start = ts; \
00146 } \
00147 }
00148
00157 #define saw(lang) { \
00158 seen = lang; \
00159 whole_line_comment = 0; \
00160 line_contains_code = 0; \
00161 }
00162
00169 #define std_internal_newline(lang) { \
00170 if (callback && p > line_start) { \
00171 if (line_contains_code) { \
00172 if (inqueue) \
00173 enqueue(lang, "lcode", cint(line_start), cint(p), userdata); \
00174 else \
00175 callback(lang, "lcode", cint(line_start), cint(p), userdata); \
00176 } else if (whole_line_comment) { \
00177 if (inqueue) \
00178 enqueue(lang, "lcomment", cint(line_start), cint(p), userdata); \
00179 else \
00180 callback(lang, "lcomment", cint(line_start), cint(p), userdata); \
00181 } else { \
00182 if (inqueue) \
00183 enqueue(lang, "lblank", cint(line_start), cint(p), userdata); \
00184 else \
00185 callback(lang, "lblank", cint(line_start), cint(p), userdata); \
00186 } \
00187 } \
00188 whole_line_comment = 0; \
00189 line_contains_code = 0; \
00190 line_start = p; \
00191 }
00192
00201 #define emb_internal_newline(lang) { \
00202 if (seen && seen != lang) \
00203 std_internal_newline(seen) \
00204 else \
00205 std_internal_newline(lang) \
00206 seen = 0; \
00207 }
00208
00215 #define std_newline(lang) {\
00216 if (inqueue) { dequeue; } \
00217 if (callback && te > line_start) { \
00218 if (line_contains_code) \
00219 callback(lang, "lcode", cint(line_start), cint(te), userdata); \
00220 else if (whole_line_comment) \
00221 callback(lang, "lcomment", cint(line_start), cint(te), userdata); \
00222 else \
00223 callback(lang, "lblank", cint(ts), cint(te), userdata); \
00224 } \
00225 whole_line_comment = 0; \
00226 line_contains_code = 0; \
00227 line_start = 0; \
00228 }
00229
00238 #define emb_newline(lang) { \
00239 if (seen && seen != lang) \
00240 std_newline(seen) \
00241 else \
00242 std_newline(lang) \
00243 seen = 0; \
00244 }
00245
00253 #define process_last_line(lang) {\
00254 if ((whole_line_comment || line_contains_code) && callback) { \
00255 if (line_contains_code) \
00256 callback(lang, "lcode", cint(line_start), cint(pe), userdata); \
00257 else if (whole_line_comment) \
00258 callback(lang, "lcomment", cint(line_start), cint(pe), userdata); \
00259 } \
00260 }
00261
00270 int is_blank_entry(char **p) {
00271 char *pos = *p+1;
00272 while (*pos != '\n' && *pos != '\r' && *pos != '\f') {
00273 if (*pos != '\t' && *pos != ' ') return 0;
00274 pos++;
00275 }
00276 if (*pos == '\r' && *(pos+1) == '\n') pos++;
00277 *p = pos;
00278 return 1;
00279 }
00280
00291 #define check_blank_entry(lang) { \
00292 if (is_blank_entry(&p)) { \
00293 te = p + 1; \
00294 std_newline(lang) \
00295 } \
00296 }
00297
00298
00299
00304 #define NEWLINE -1
00305
00312 #define INTERNAL_NL -2
00313
00321 #define CHECK_BLANK_ENTRY -3
00322
00324 int cs;
00325
00327 int act;
00328
00330 char *p;
00331
00333 char *pe;
00334
00336 char *eof;
00337
00339 char *ts;
00340
00342 char *te;
00343
00345 int stack[5];
00346
00348 int top;
00349
00351 char *buffer_start;
00352
00359 #define cint(c) ((int) (c - buffer_start))
00360
00365 int whole_line_comment;
00366
00371 int line_contains_code;
00372
00377 char *line_start;
00378
00380 int entity;
00381
00386 const char *seen;
00387
00393 int inqueue;
00394
00399 char *last_line_start;
00400
00405 int last_line_contains_code;
00406
00411 int last_whole_line_comment;
00412
00417 #define init { \
00418 p = buffer; \
00419 pe = buffer + length; \
00420 eof = pe; \
00421 \
00422 buffer_start = buffer; \
00423 whole_line_comment = 0; \
00424 line_contains_code = 0; \
00425 line_start = 0; \
00426 entity = 0; \
00427 seen = 0; \
00428 inqueue = 0; \
00429 }
00430
00431 #endif