xref: /Universal-ctags/peg/peg_common.h (revision 697bbc6840a544c22083a0f9ae19869f1bbade8c)
1 /*
2  *   Copyright (c) 2021 Masatake YAMATO
3  *
4  *   This source code is released for free distribution under the terms of the
5  *   GNU General Public License version 2 or (at your option) any later version.
6  *
7  *   This module contains macros, data decls and prototypes to generate tags for Kotlin.
8  */
9 
10 #ifndef CTAGS_PEG_COMMON
11 #define CTAGS_PEG_COMMON
12 
13 #include "debug.h"
14 
15 #define PCC_GETCHAR(auxil) getcFromInputFile()
16 #define PCC_MALLCO(auxil,size) eMalloc(size)
17 #define PCC_REALLOC(auxil,ptr,size) eRealloc(ptr,size)
18 #define PCC_FREE(auxil,ptr) eFreeNoNullCheck((void *)ptr)
19 #define PCC_ERROR(auxil) baseReportError(BASE(auxil))
20 #ifdef DEBUG
21 #define PCC_DEBUG(auxil, event, rule, level, pos, buffer, length) baseDebug(BASE(auxil), event, rule, level, pos, buffer, length)
22 #endif
23 
24 #include "numarray.h"
25 #include "parse.h"
26 #include "entry.h"
27 #include "read.h"
28 #ifdef DEBUG
29 #include "htable.h"
30 #endif
31 
32 struct parserBaseCtx {
33 	intArray *kind_stack;
34 	int scope_cork_index;
35 	bool found_syntax_error;
36 #ifdef DEBUG
37 	hashTable *debug_rules;
38 #endif
39 };
40 
41 #define BASE_STRUCT parserBaseCtx
42 #define BASE(P) ((struct BASE_STRUCT*)(P))
43 #define BASE_ERROR(P) ((BASE(P))->found_syntax_error)
44 #define BASE_SCOPE(P) ((BASE(P))->scope_cork_index)
45 
46 #define SET_SCOPE(P,S) (BASE_SCOPE(P) = (S))
47 #define POP_SCOPE(P) (basePopScope(BASE(P)))
48 #define PUSH_KIND(P,K) (basePushKind(BASE(P),(K)))
49 #define POP_KIND(P,POP_SCOPE_TOO) (basePopKind(BASE(P),(POP_SCOPE_TOO)))
50 #define PEEK_KIND(P) (basePeekKind(BASE(P)))
51 
52 #define BASE_INIT(P,KIND) (baseInit((BASE(P)),KIND))
53 #define BASE_FINI(P) (baseFini(BASE(P)))
54 
55 #ifdef DEBUG
56 #define BASE_DEBUG_RULE(P, R) baseAddDebugRule(BASE(P), R)
57 #else
58 #define BASE_DEBUG_RULE(P, R)
59 #endif
60 
basePopScope(struct parserBaseCtx * auxil)61 static void basePopScope(struct parserBaseCtx *auxil)
62 {
63     tagEntryInfo *e = getEntryInCorkQueue (auxil->scope_cork_index);
64     if (e)
65         auxil->scope_cork_index = e->extensionFields.scopeIndex;
66 }
67 
basePushKind(struct parserBaseCtx * auxil,int kind)68 static void basePushKind (struct parserBaseCtx *auxil, int kind)
69 {
70 	intArrayAdd (auxil->kind_stack, kind);
71 }
72 
basePopKind(struct parserBaseCtx * auxil,bool popScopeToo)73 static void basePopKind (struct parserBaseCtx *auxil, bool popScopeToo)
74 {
75     intArrayRemoveLast (auxil->kind_stack);
76 
77     if (popScopeToo)
78     {
79         basePopScope(auxil);
80     }
81 }
82 
basePeekKind(struct parserBaseCtx * auxil)83 static int basePeekKind (struct parserBaseCtx *auxil)
84 {
85     return intArrayLast (auxil->kind_stack);
86 }
87 
baseReportError(struct parserBaseCtx * auxil)88 static void baseReportError (struct parserBaseCtx *auxil)
89 {
90     auxil->found_syntax_error = true;
91     fprintf(stderr, "%s: syntax error in \"%s\"\n",
92 			getLanguageName (getInputLanguage ()), getInputFileName());
93 }
94 
baseInit(struct parserBaseCtx * auxil,int initial_kind)95 static void baseInit(struct parserBaseCtx *auxil, int initial_kind)
96 {
97 	auxil->kind_stack = intArrayNew ();
98 	basePushKind (auxil, initial_kind);
99 	auxil->scope_cork_index = CORK_NIL;
100 	auxil->found_syntax_error = false;
101 #ifdef DEBUG
102 	auxil->debug_rules = hashTableNew (11,
103 									   hashCstrhash, hashCstreq,
104 									   NULL, NULL);
105 #endif
106 }
107 
baseFini(struct parserBaseCtx * auxil)108 static void baseFini(struct parserBaseCtx *auxil)
109 {
110 	basePopKind (auxil, false);
111 	intArrayDelete (auxil->kind_stack);
112 #ifdef DEBUG
113 	hashTableDelete (auxil->debug_rules);
114 #endif
115 }
116 
117 #ifdef DEBUG
baseAddDebugRule(struct parserBaseCtx * auxil,char * rule)118 static void baseAddDebugRule (struct parserBaseCtx *auxil, char *rule)
119 {
120 	hashTablePutItem (auxil->debug_rules, rule, HT_INT_TO_PTR(1));
121 }
122 
baseIsDebugRule(struct parserBaseCtx * auxil,const char * rule)123 static bool baseIsDebugRule (struct parserBaseCtx *auxil, const char *rule)
124 {
125 	return hashTableHasItem (auxil->debug_rules, rule);
126 }
127 
baseDebug(struct parserBaseCtx * auxil,int event,const char * rule,size_t level,size_t pos,const char * buffer,size_t len)128 static void baseDebug(struct parserBaseCtx *auxil, int event, const char *rule, size_t level, size_t pos, const char *buffer, size_t len)
129 {
130 	if (!baseIsDebugRule(auxil, rule))
131 		return;
132 
133 	fprintf(stderr, "<level:%2lu, len:%4lu>[%7s] %10s: ",
134 			level, len,
135 			event == 0 /*PCC_DBG_EVALUATE*/ ? "eval" :
136 			event == 1 /*PCC_DBG_MATCH*/    ? "match":
137 			event == 2 /*PCC_DBG_NOMATCH*/  ? "nomatch": "unknown",
138 			rule);
139 	for (size_t i = 0; i < len; i++)
140 	{
141 		if (buffer[i] == '\n')
142 			break;
143 		fputc(buffer[i], stderr);
144 	}
145 	fputc('\n', stderr);
146 }
147 #endif
148 
149 #endif	/* !CTAGS_PEG_COMMON */
150