xref: /Universal-ctags/main/tokeninfo.c (revision 982cab14ce439abc13f338f873b0a4989e514d8c)
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