ohcount

/build/buildd/ohcount-3.0.0/src/parser_macros.h

Go to the documentation of this file.
00001 // parser_macros.h written by Mitchell Foral. mitchell<att>caladbolg.net.
00002 // See COPYING for license information.
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 // Variables used by all parsers. Do not modify.
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