1 /*
2 * Copyright (c) 2016, Masatake YAMATO <yamato@redhat.com>
3 * Copyright (c) 2016, Red Hat, Inc.
4 *
5 * This source code is released for free distribution under the terms of the
6 * GNU General Public License version 2 or (at your option) any later version.
7 *
8 * This module contains functions for generating tags for Python language
9 * files.
10 */
11
12 #include "general.h"
13 #include "tokeninfo.h"
14
15 #include "entry.h"
16 #include "read.h"
17 #include "routines.h"
18
createToken(void * createArg)19 static void* createToken (void *createArg)
20 {
21 struct tokenInfoClass *klass = createArg;
22 tokenInfo *token;
23
24 token = eCalloc (1, sizeof (*token) + klass->extraSpace);
25 token->klass = klass;
26 token->string = vStringNew ();
27
28 return token;
29 }
30
clearToken(void * data)31 static void clearToken (void *data)
32 {
33 tokenInfo *token = data;
34
35 if (token->klass->clear)
36 token->klass->clear (token);
37
38 token->type = token->klass->typeForUndefined;
39 token->keyword = token->klass->keywordNone;
40 vStringClear (token->string);
41 token->lineNumber = getInputLineNumber ();
42 token->filePosition = getInputFilePosition ();
43 }
44
deleteToken(void * data)45 static void deleteToken (void *data)
46 {
47 tokenInfo *token = data;
48
49 if (token->klass->delete)
50 token->klass->delete (token);
51
52 vStringDelete (token->string);
53 eFree (token);
54 }
55
newToken(struct tokenInfoClass * klass)56 void *newToken (struct tokenInfoClass *klass)
57 {
58 return newTokenFull (klass, NULL);
59 }
60
newTokenFull(struct tokenInfoClass * klass,void * data)61 void *newTokenFull (struct tokenInfoClass *klass, void *data)
62 {
63 tokenInfo *token = NULL;
64
65 if (klass->nPreAlloc == 0)
66 klass->nPreAlloc = 16;
67
68 retry:
69 if (klass->pool)
70 token = objPoolGet (klass->pool);
71 else
72 {
73 klass->pool = objPoolNew (klass->nPreAlloc,
74 createToken,
75 deleteToken,
76 clearToken,
77 klass);
78 goto retry;
79 }
80
81 if (klass->init)
82 klass->init (token, data);
83 return token;
84 }
85
flashTokenBacklog(struct tokenInfoClass * klass)86 void flashTokenBacklog (struct tokenInfoClass *klass)
87 {
88 if (klass->backlog)
89 ptrArrayClear (klass->backlog);
90 }
91
tokenDelete(tokenInfo * token)92 void tokenDelete (tokenInfo *token)
93 {
94 objPoolPut (token->klass->pool, token);
95 }
96
97
tokenReadFull(tokenInfo * token,void * data)98 void tokenReadFull (tokenInfo *token, void *data)
99 {
100 if (!token->klass->backlog)
101 token->klass->backlog = ptrArrayNew ((ptrArrayDeleteFunc)tokenDelete);
102
103 if (ptrArrayCount (token->klass->backlog) > 0)
104 {
105 tokenInfo *backlog = ptrArrayLast (token->klass->backlog);
106 tokenCopyFull (token, backlog, data);
107 ptrArrayRemoveLast (token->klass->backlog);
108 tokenDelete (backlog);
109 }
110 else
111 {
112 token->klass->read (token, data);
113 if (!tokenIsEOF (token))
114 token->klass->read_counter++;
115 }
116 }
117
tokenRead(tokenInfo * token)118 void tokenRead (tokenInfo *token)
119 {
120 tokenReadFull (token, NULL);
121 }
122
tokenCopyFull(tokenInfo * dest,tokenInfo * src,void * data)123 void tokenCopyFull (tokenInfo *dest, tokenInfo *src, void *data)
124 {
125 dest->lineNumber = src->lineNumber;
126 dest->filePosition = src->filePosition;
127 dest->type = src->type;
128 dest->keyword = src->keyword;
129 /* klass */
130 vStringCopy(dest->string, src->string);
131 if (src->klass->copy)
132 src->klass->copy (dest, src, data);
133 }
134
tokenCopy(tokenInfo * dest,tokenInfo * src)135 void tokenCopy (tokenInfo *dest, tokenInfo *src)
136 {
137 tokenCopyFull (dest, src, NULL);
138 }
139
newTokenByCopying(tokenInfo * src)140 void *newTokenByCopying (tokenInfo *src)
141 {
142 return newTokenByCopyingFull (src, NULL);
143 }
144
newTokenByCopyingFull(tokenInfo * src,void * data)145 void *newTokenByCopyingFull (tokenInfo *src, void *data)
146 {
147 void * dest = newToken (src->klass);
148 tokenCopyFull (dest, src, data);
149 return dest;
150 }
151
tokenSkipToTypeFull(tokenInfo * token,tokenType t,void * data)152 bool tokenSkipToTypeFull (tokenInfo *token, tokenType t, void *data)
153 {
154 while (! (tokenIsEOF (token)
155 || token->type == t))
156 tokenReadFull (token, data);
157
158 return (token->type == t)? true: false;
159 }
160
tokenSkipToType(tokenInfo * token,tokenType t)161 bool tokenSkipToType (tokenInfo *token, tokenType t)
162 {
163 return tokenSkipToTypeFull (token, t, NULL);
164 }
165
tokenUnreadFull(tokenInfo * token,void * data)166 void tokenUnreadFull (tokenInfo *token, void *data)
167 {
168 tokenInfo *backlog;
169
170 if (!token->klass->backlog)
171 token->klass->backlog = ptrArrayNew ((ptrArrayDeleteFunc)tokenDelete);
172
173 backlog = newToken (token->klass);
174 tokenCopyFull (backlog, token, data);
175 ptrArrayAdd (token->klass->backlog, backlog);
176 }
177
tokenUnread(tokenInfo * token)178 void tokenUnread (tokenInfo *token)
179 {
180 tokenUnreadFull (token, NULL);
181 }
182
tokenSkipOverPair(tokenInfo * token)183 bool tokenSkipOverPair (tokenInfo *token)
184 {
185 return tokenSkipOverPairFull(token, NULL);
186 }
187
tokenSkipOverPairFull(tokenInfo * token,void * data)188 bool tokenSkipOverPairFull (tokenInfo *token, void *data)
189 {
190 int start = token->type;
191 int end = token->klass->typeForUndefined;
192 unsigned int i;
193
194 for (i = 0; i < token->klass->pairCount; i++)
195 if (start == token->klass->pairs[i].start)
196 end = token->klass->pairs[i].end;
197
198 if (end == token->klass->typeForUndefined)
199 return false;
200
201 int depth = 1;
202 do {
203 tokenReadFull (token, data);
204 if (token->type == start)
205 depth ++;
206 else if (token->type == end)
207 depth--;
208 } while ((!tokenIsEOF(token)) && (depth > 0));
209
210 return (depth == 0)? true: false;
211 }
212