Update all parsers and related files to ctags p6.1.20240421.0
[geany-mirror.git] / ctags / main / dependency.c
blobecb5a9e60c4addb7c8ab845036c0230ab6dc01cf
1 /*
3 * Copyright (c) 2016, Red Hat, Inc.
4 * Copyright (c) 2016, Masatake YAMATO
6 * Author: Masatake YAMATO <yamato@redhat.com>
8 * This source code is released for free distribution under the terms of the
9 * GNU General Public License version 2 or (at your option) any later version.
13 #include "general.h" /* must always come first */
15 #include "debug.h"
16 #include "dependency.h"
17 #include "options.h"
18 #include "parse_p.h"
19 #include "read.h"
20 #include "read_p.h"
21 #include "routines.h"
22 #include "subparser.h"
23 #include "subparser_p.h"
24 #include "xtag.h"
26 #include <string.h>
28 struct slaveControlBlock {
29 slaveParser *slaveParsers; /* The parsers on this list must be initialized when
30 this parser is initialized. */
31 subparser *subparsersDefault;
32 subparser *subparsersInUse;
33 langType owner;
36 extern void linkDependencyAtInitializeParsing (depType dtype,
37 parserDefinition *const master,
38 struct slaveControlBlock *masterSCB,
39 struct kindControlBlock *masterKCB,
40 parserDefinition *const slave,
41 struct kindControlBlock *slaveKCB,
42 void *data)
44 if (dtype == DEPTYPE_KIND_OWNER)
45 linkKindDependency (masterKCB, slaveKCB);
46 else if (dtype == DEPTYPE_SUBPARSER || dtype == DEPTYPE_FOREIGNER)
48 slaveParser *s = xMalloc (1, slaveParser);
50 s->type = dtype;
51 s->id = slave->id;
52 s->data = data;
54 s->next = masterSCB->slaveParsers;
55 masterSCB->slaveParsers = s;
59 static void attachSubparser (struct slaveControlBlock *base_sb, subparser *subparser)
61 subparser->next = base_sb->subparsersDefault;
62 base_sb->subparsersDefault = subparser;
66 extern struct slaveControlBlock *allocSlaveControlBlock (parserDefinition *parser)
68 struct slaveControlBlock *cb;
70 cb = xMalloc (1, struct slaveControlBlock);
71 cb->slaveParsers = NULL;
72 cb->subparsersDefault = NULL;
73 cb->subparsersInUse = NULL;
74 cb->owner = parser->id;
76 return cb;
79 extern void freeSlaveControlBlock (struct slaveControlBlock *cb)
81 eFree (cb);
84 extern void initializeDependencies (parserDefinition *parser,
85 struct slaveControlBlock *cb)
87 unsigned int i;
88 slaveParser *sp;
90 /* Initialize slaves */
91 sp = cb->slaveParsers;
92 while (sp != NULL)
94 if (sp->type == DEPTYPE_SUBPARSER)
96 subparser *sub;
98 sub = (subparser *)sp->data;
99 sub->slaveParser = sp;
102 if (sp->type == DEPTYPE_KIND_OWNER
103 || (sp->type == DEPTYPE_SUBPARSER &&
104 (((subparser *)sp->data)->direction & SUBPARSER_BASE_RUNS_SUB)))
106 initializeParser (sp->id);
107 if (sp->type == DEPTYPE_SUBPARSER
108 && isXtagEnabled (XTAG_SUBPARSER))
110 subparser *subparser = sp->data;
111 attachSubparser (cb, subparser);
114 sp = sp->next;
117 /* Initialize masters that act as base parsers. */
118 for (i = 0; i < parser->dependencyCount; i++)
120 parserDependency *d = parser->dependencies + i;
121 if ((d->type == DEPTYPE_SUBPARSER &&
122 ((subparser *)(d->data))->direction & SUBPARSER_SUB_RUNS_BASE)
123 || (d->type == DEPTYPE_FOREIGNER))
125 langType baseParser;
126 baseParser = getNamedLanguage (d->upperParser, 0);
127 Assert (baseParser != LANG_IGNORE);
128 initializeParser (baseParser);
133 extern void finalizeDependencies (parserDefinition *parser,
134 struct slaveControlBlock *cb)
136 while (cb->slaveParsers)
138 slaveParser *sp = cb->slaveParsers;
139 cb->slaveParsers = sp->next;
140 sp->next = NULL;
141 eFree (sp);
145 extern void notifyInputStart (void)
147 subparser *s;
149 /* for running prelude of optlib */
150 langType lang = getInputLanguage ();
151 notifyLanguageRegexInputStart (lang);
153 foreachSubparser(s, true)
155 enterSubparser(s);
156 if (s->inputStart)
157 s->inputStart (s);
158 /* propagate the event recursively */
159 notifyInputStart ();
160 leaveSubparser();
164 extern void notifyInputEnd (void)
166 subparser *s;
168 foreachSubparser(s, true)
170 enterSubparser(s);
171 /* propagate the event recursively */
172 notifyInputEnd ();
173 if (s->inputEnd)
174 s->inputEnd (s);
175 leaveSubparser();
178 /* for running sequel of optlib */
179 langType lang = getInputLanguage ();
180 notifyLanguageRegexInputEnd (lang);
183 extern void notifyMakeTagEntry (const tagEntryInfo *tag, int corkIndex)
185 subparser *s;
187 foreachSubparser(s, false)
189 if (s->makeTagEntryNotify)
191 enterSubparser(s);
192 s->makeTagEntryNotify (s, tag, corkIndex);
193 leaveSubparser();
198 extern langType getSubparserLanguage (subparser *s)
200 return s->slaveParser->id;
203 extern void chooseExclusiveSubparser (subparser *s, void *data)
205 if (s->exclusiveSubparserChosenNotify)
207 s->chosenAsExclusiveSubparser = true;
208 enterSubparser(s);
209 s->exclusiveSubparserChosenNotify (s, data);
210 verbose ("%s is chosen as exclusive subparser\n",
211 getLanguageName (getSubparserLanguage (s)));
212 leaveSubparser();
216 extern subparser *getFirstSubparser(struct slaveControlBlock *controlBlock)
218 if (controlBlock)
219 return controlBlock->subparsersInUse;
220 return NULL;
223 extern void useDefaultSubparsers (struct slaveControlBlock *controlBlock)
225 controlBlock->subparsersInUse = controlBlock->subparsersDefault;
228 extern void useSpecifiedSubparser (struct slaveControlBlock *controlBlock, subparser *s)
230 s->schedulingBaseparserExplicitly = true;
231 controlBlock->subparsersInUse = s;
234 extern void setupSubparsersInUse (struct slaveControlBlock *controlBlock)
236 if (!controlBlock->subparsersInUse)
237 useDefaultSubparsers(controlBlock);
240 extern subparser* teardownSubparsersInUse (struct slaveControlBlock *controlBlock)
242 subparser *tmp;
243 subparser *s = NULL;
245 tmp = controlBlock->subparsersInUse;
246 controlBlock->subparsersInUse = NULL;
248 if (tmp && tmp->schedulingBaseparserExplicitly)
250 tmp->schedulingBaseparserExplicitly = false;
251 s = tmp;
254 if (s)
255 return s;
257 while (tmp)
259 if (tmp->chosenAsExclusiveSubparser)
261 s = tmp;
263 tmp = tmp->next;
266 return s;
270 static int subparserDepth;
272 extern void enterSubparser(subparser *subparser)
274 subparserDepth++;
275 pushLanguage (getSubparserLanguage (subparser));
278 extern void leaveSubparser(void)
280 popLanguage ();
281 subparserDepth--;
284 extern bool doesSubparserRun (void)
286 if (getLanguageForBaseParser () == getInputLanguage())
287 return false;
288 return subparserDepth;
291 extern slaveParser *getFirstSlaveParser (struct slaveControlBlock *scb)
293 if (scb)
294 return scb->slaveParsers;
295 return NULL;
298 extern subparser *getLanguageSubparser (langType sublang,
299 bool including_none_crafted_parser)
301 subparser *s;
303 foreachSubparser (s, including_none_crafted_parser)
305 if (getSubparserLanguage (s) == sublang)
306 return s;
308 return NULL;
311 extern struct colprintTable * subparserColprintTableNew (void)
313 return colprintTableNew ("L:NAME", "L:BASEPARSER", "L:DIRECTIONS", NULL);
316 extern void subparserColprintAddSubparsers (struct colprintTable *table,
317 struct slaveControlBlock *scb)
319 slaveParser *tmp;
321 pushLanguage (scb->owner);
322 foreachSlaveParser(tmp)
324 if (tmp->type != DEPTYPE_SUBPARSER)
325 continue;
327 if (!isLanguageVisible (tmp->id))
328 continue;
330 struct colprintLine *line = colprintTableGetNewLine(table);
332 colprintLineAppendColumnCString (line, getLanguageName (tmp->id));
333 colprintLineAppendColumnCString (line, getLanguageName (scb->owner));
335 const char *direction;
336 switch (((subparser *)tmp->data)->direction)
338 case SUBPARSER_BASE_RUNS_SUB:
339 direction = "base => sub {shared}";
340 break;
341 case SUBPARSER_SUB_RUNS_BASE:
342 direction = "base <= sub {dedicated}";
343 break;
344 case SUBPARSER_BI_DIRECTION:
345 direction = "base <> sub {bidirectional}";
346 break;
347 default:
348 direction = "UNKNOWN(INTERNAL BUG)";
349 break;
351 colprintLineAppendColumnCString (line, direction);
353 popLanguage ();
356 static int subparserColprintCompareLines (struct colprintLine *a , struct colprintLine *b)
358 const char *a_name = colprintLineGetColumn (a, 0);
359 const char *b_name = colprintLineGetColumn (b, 0);
361 int r;
362 r = strcmp (a_name, b_name);
363 if (r != 0)
364 return r;
366 const char *a_baseparser = colprintLineGetColumn (a, 1);
367 const char *b_baseparser = colprintLineGetColumn (b, 1);
369 return strcmp(a_baseparser, b_baseparser);
372 extern void subparserColprintTablePrint (struct colprintTable *table,
373 bool withListHeader, bool machinable, FILE *fp)
375 colprintTableSort (table, subparserColprintCompareLines);
376 colprintTablePrint (table, 0, withListHeader, machinable, fp);
379 extern const char *dependencyTypeString(enum eDepType e)
380 { /* Generated by misc/enumstr.sh with cmdline:
381 misc/enumstr.sh main/dependency.h eDepType dependencyTypeString DEPTYPE_ */
382 switch (e)
384 case DEPTYPE_KIND_OWNER: return "KIND_OWNER";
385 case DEPTYPE_SUBPARSER: return "SUBPARSER";
386 case DEPTYPE_FOREIGNER: return "FOREIGNER";
387 case COUNT_DEPTYPES: return "COUNT_DEPTYPES";
388 default: return "UNKNOWN";