ohcount
Data Structures | Macros | Typedefs | Functions | Variables
parser_macros.h File Reference
#include <stdio.h>
#include <stdlib.h>
#include "languages.h"

Go to the source code of this file.

Data Structures

struct  CallbackItem
 Holds a series of callbacks for in a queue (linked list). More...
 

Macros

#define dequeue
 
#define ls
 
#define code
 
#define comment
 
#define saw(lang)
 
#define std_internal_newline(lang)
 
#define emb_internal_newline(lang)
 
#define std_newline(lang)
 
#define emb_newline(lang)
 
#define process_last_line(lang)
 
#define check_blank_entry(lang)
 
#define NEWLINE   -1
 
#define INTERNAL_NL   -2
 
#define CHECK_BLANK_ENTRY   -3
 
#define cint(c)   ((int) (c - buffer_start))
 
#define init
 

Typedefs

typedef struct CallbackItem Callback
 

Functions

void enqueue (const char *lang, const char *entity, int s, int e, void *udata)
 
void free_queue ()
 
int is_blank_entry (char **p)
 

Variables

Callbackcallback_list_head = NULL
 
Callbackcallback_list_tail = NULL
 
int cs
 
int act
 
char * p
 
char * pe
 
char * eof
 
char * ts
 
char * te
 
int stack [5]
 
int top
 
char * buffer_start
 
int whole_line_comment
 
int line_contains_code
 
char * line_start
 
int entity
 
const char * seen
 
int inqueue
 
char * last_line_start
 
int last_line_contains_code
 
int last_whole_line_comment
 

Macro Definition Documentation

◆ check_blank_entry

#define check_blank_entry (   lang)
Value:
{ \
if (is_blank_entry(&p)) { \
te = p + 1; \
std_newline(lang) \
} \
}
int is_blank_entry(char **p)
Definition: parser_macros.h:270
char * p
Definition: parser_macros.h:330

If there is a transition into an embedded language and there is only parent language code on the line (the rest of the line is blank with no child code), count the line as a line of parent code. Moves p and te to the end of the newline and calls the std_newline macro. (p is inclusive, te is not.) This is typically used in the main action for the CHECK_BLANK_ENTRY entity.

Parameters
langThe language name string.
Note
Applies only to line counting parsers.

◆ CHECK_BLANK_ENTRY

#define CHECK_BLANK_ENTRY   -3

Check blank entry entity. Used for embedded language transitions. If a newline follows immediately after such a transition, the line should be counted as parent code, not child code.

Note
This is only used for line counting parsers.

◆ cint

#define cint (   c)    ((int) (c - buffer_start))

Returns the absolute location in memory for a position relative to the start of the buffer being parsed.

Parameters
cPosition relative to the start of the buffer.
Note
This is only used for line counting parsers.

◆ code

#define code
Value:
{ \
if (inqueue) { dequeue; } \
line_contains_code = 1; \
}
char * ts
Definition: parser_macros.h:339
int line_contains_code
Definition: parser_macros.h:371
#define dequeue
Definition: parser_macros.h:107
char * line_start
Definition: parser_macros.h:377
int inqueue
Definition: parser_macros.h:393

The C equivalent of the Ragel 'code' action. This is tyically used in the main action for entities where Ragel actions cannot, for one reason or another, be used.

Note
Applies only to line counting parsers.

◆ comment

#define comment
Value:
{ \
if (inqueue) { dequeue; } \
whole_line_comment = 1; \
} \
}

The C equivalent of the Ragel 'comment' action. This is typically unused, but here for consistency.

Note
Applies only to line counting parsers.

◆ dequeue

#define dequeue
Value:
{ \
inqueue = 0; \
line_start = last_line_start; \
line_contains_code = last_line_contains_code; \
whole_line_comment = last_whole_line_comment; \
}
int last_whole_line_comment
Definition: parser_macros.h:411
char * last_line_start
Definition: parser_macros.h:399
int last_line_contains_code
Definition: parser_macros.h:405

Restores settings for a failed enqueued entity. This is typically used in the ls, code, and comment macros.

Note
Applies only to line counting parsers.

◆ emb_internal_newline

#define emb_internal_newline (   lang)
Value:
{ \
if (seen && seen != lang) \
std_internal_newline(seen) \
seen = 0; \
}
const char * seen
Definition: parser_macros.h:386
#define std_internal_newline(lang)
Definition: parser_macros.h:169

Executes emebedded language line counting actions for INTERNAL_NL entities based on whether or not the embedded language's code has been seen in a parent line. This is typically used in the main action for the INTERNAL_NL entity.

Parameters
langThe language name string.
Note
Applies only to line counting parsers.

◆ emb_newline

#define emb_newline (   lang)
Value:
{ \
if (seen && seen != lang) \
std_newline(seen) \
std_newline(lang) \
seen = 0; \
}
#define std_newline(lang)
Definition: parser_macros.h:215

Executes embedded language line counting actions for NEWLINE entities based on whether or not the embedded language's code has been seen in a parent line. This is typically used in the main action for the NEWLINE entity.

Parameters
langThe language name string.
Note
Applies only to line counting parsers.

◆ init

#define init
Value:
{ \
p = buffer; \
pe = buffer + length; \
eof = pe; \
\
buffer_start = buffer; \
whole_line_comment = 0; \
line_contains_code = 0; \
line_start = 0; \
entity = 0; \
seen = 0; \
inqueue = 0; \
}
char * pe
Definition: parser_macros.h:333

Initializes variables for parsing a buffer. Required at the beginning of every parser function.

◆ INTERNAL_NL

#define INTERNAL_NL   -2

Internal newline entity. Used for newlines inside patterns like strings and comments that can have newlines in them.

Note
This is only used for line counting parsers.

◆ ls

#define ls
Value:
{ \
if (inqueue) { dequeue; } \
}

Sets the line_start variable to ts. This is typically used for the SPACE entity in the main action.

Note
Applies only to line counting parsers.

◆ NEWLINE

#define NEWLINE   -1

Newline entity.

Note
This is only used for line counting parsers.

◆ process_last_line

#define process_last_line (   lang)
Value:
{\
if ((whole_line_comment || line_contains_code) && callback) { \
callback(lang, "lcode", cint(line_start), cint(pe), userdata); \
else if (whole_line_comment) \
callback(lang, "lcomment", cint(line_start), cint(pe), userdata); \
} \
}
int whole_line_comment
Definition: parser_macros.h:365
#define cint(c)
Definition: parser_macros.h:359

Processes the last line for buffers that don't have a newline at EOF. This is typically used at the end of the parse_lang function after the Ragel parser has been executed.

Parameters
langThe language name string.
Note
Applies only to line counting parsers.

◆ saw

#define saw (   lang)
Value:
{ \
seen = lang; \
whole_line_comment = 0; \
line_contains_code = 0; \
}

Sets up for having seen an embedded language. This is typically used when entering an embedded language which usually does not span multiple lines (e.g. php for <?php echo 'blah' ?> on single lines) so the line is counted as embedded code or comment, not parent code.

Parameters
langThe language name string.
Note
Applies only to line counting parsers.

◆ std_internal_newline

#define std_internal_newline (   lang)
Value:
{ \
if (callback && p > line_start) { \
if (inqueue) \
enqueue(lang, "lcode", cint(line_start), cint(p), userdata); \
else \
callback(lang, "lcode", cint(line_start), cint(p), userdata); \
} else if (whole_line_comment) { \
if (inqueue) \
enqueue(lang, "lcomment", cint(line_start), cint(p), userdata); \
else \
callback(lang, "lcomment", cint(line_start), cint(p), userdata); \
} else { \
if (inqueue) \
enqueue(lang, "lblank", cint(line_start), cint(p), userdata); \
else \
callback(lang, "lblank", cint(line_start), cint(p), userdata); \
} \
} \
whole_line_comment = 0; \
line_contains_code = 0; \
line_start = p; \
}

Executes standard line counting actions for INTERNAL_NL entities. This is typically used in the main action for the INTERNAL_NL entity.

Parameters
langThe language name string.
Note
Applies only to line counting parsers.

◆ std_newline

#define std_newline (   lang)
Value:
{\
if (inqueue) { dequeue; } \
if (callback && te > line_start) { \
callback(lang, "lcode", cint(line_start), cint(te), userdata); \
else if (whole_line_comment) \
callback(lang, "lcomment", cint(line_start), cint(te), userdata); \
else \
callback(lang, "lblank", cint(ts), cint(te), userdata); \
} \
whole_line_comment = 0; \
line_contains_code = 0; \
line_start = 0; \
}
char * te
Definition: parser_macros.h:342

Executes standard line counting actions for NEWLINE entities. This is typically used in the main action for the NEWLINE entity.

Parameters
langThe language name string.
Note
Applies only to line counting parsers.

Typedef Documentation

◆ Callback

typedef struct CallbackItem Callback

Function Documentation

◆ enqueue()

void enqueue ( const char *  lang,
const char *  entity,
int  s,
int  e,
void *  udata 
)

Enqueues a callback for calling upon commit. This is only necessary for line counting machines. Ragel will execute actions in real-time rather than after a complete match. This is a problem for entities that contain internal newlines, since there is a callback for each internal newline whether or not the end of the entity matches. This means that if, for example, the beginning of a string entity is matched, the text following is treated as code until the ending delimiter. If there is no ending delimiter (it was not actually a string entity), Ragel will jump back to the beginning of the string and reparse the text again. This means all the callbacks called were probably not accurate. To remedy this, any entity which needs an ending delimiter that may not appear will have its callbacks enqueued and then committed when the ending delimitter is reached. If that delimitter is not reached, the callbacks are never called.

Parameters
langThe language name.
entityThe entity (lcode, lcomment, lblank).
sThe start position of the entity in the buffer.
eThe end position of the entity in the buffer.
udataUserdata.

◆ free_queue()

void free_queue ( )

Frees the memory used by a queue.

◆ is_blank_entry()

int is_blank_entry ( char **  p)

Determines whether or not the rest of the line is blank. This is typically used when entering an embedded language.

Parameters
pThe position of entry into the emebedded language.
Returns
0 if the rest of the line is not blank, the position at the end of the newline otherwise (inclusive).
Note
Applies only to line counting parsers.

Variable Documentation

◆ act

int act

Required by Ragel.

◆ buffer_start

char* buffer_start

The buffer currently being parsed.

◆ callback_list_head

Callback* callback_list_head = NULL

The head of the Callback queue.

◆ callback_list_tail

Callback* callback_list_tail = NULL

The tail of the Callback queue.

◆ cs

int cs

Required by Ragel.

◆ entity

int entity

State variable for the current entity being matched.

◆ eof

char* eof

Required by Ragel.

◆ inqueue

int inqueue

Flag indicating whether or not to enqueue callbacks instead of calling them in real time.

Note
This is only used for line counting parsers.

◆ last_line_contains_code

int last_line_contains_code

Backup variable for 'inqueue'ing.

Note
This is only used for line counting parsers.

◆ last_line_start

char* last_line_start

Backup variable for 'inqueue'ing.

Note
This is only used for line counting parsers.

◆ last_whole_line_comment

int last_whole_line_comment

Backup variable for 'inqueue'ing.

Note
This is only used for line counting parsers.

◆ line_contains_code

int line_contains_code

Flag indicating whether or not the current line contains any code.

Note
This is only used for line counting parsers.

◆ line_start

char* line_start

The beginning of the current line in the buffer being parsed.

Note
This is only used for line counting parsers.

◆ p

char* p

Required by Ragel.

◆ pe

char* pe

Required by Ragel.

◆ seen

const char* seen

Keeps track of an embedded language.

Note
This is only used for line counting parsers.

◆ stack

int stack[5]

Required by Ragel.

◆ te

char* te

Required by Ragel.

◆ top

int top

Required by Ragel.

◆ ts

char* ts

Required by Ragel.

◆ whole_line_comment

int whole_line_comment

Flag indicating whether or not the current line contains only a comment.

Note
This is only used for line counting parsers.