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 */
16 #include "dependency.h"
22 #include "subparser.h"
23 #include "subparser_p.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
;
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
,
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
);
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
;
79 extern void freeSlaveControlBlock (struct slaveControlBlock
*cb
)
84 extern void initializeDependencies (parserDefinition
*parser
,
85 struct slaveControlBlock
*cb
)
90 /* Initialize slaves */
91 sp
= cb
->slaveParsers
;
94 if (sp
->type
== DEPTYPE_SUBPARSER
)
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
);
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
))
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
;
145 extern void notifyInputStart (void)
149 /* for running prelude of optlib */
150 langType lang
= getInputLanguage ();
151 notifyLanguageRegexInputStart (lang
);
153 foreachSubparser(s
, true)
158 /* propagate the event recursively */
164 extern void notifyInputEnd (void)
168 foreachSubparser(s
, true)
171 /* propagate the event recursively */
178 /* for running sequel of optlib */
179 langType lang
= getInputLanguage ();
180 notifyLanguageRegexInputEnd (lang
);
183 extern void notifyMakeTagEntry (const tagEntryInfo
*tag
, int corkIndex
)
187 foreachSubparser(s
, false)
189 if (s
->makeTagEntryNotify
)
192 s
->makeTagEntryNotify (s
, tag
, corkIndex
);
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;
209 s
->exclusiveSubparserChosenNotify (s
, data
);
210 verbose ("%s is chosen as exclusive subparser\n",
211 getLanguageName (getSubparserLanguage (s
)));
216 extern subparser
*getFirstSubparser(struct slaveControlBlock
*controlBlock
)
219 return controlBlock
->subparsersInUse
;
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
)
245 tmp
= controlBlock
->subparsersInUse
;
246 controlBlock
->subparsersInUse
= NULL
;
248 if (tmp
&& tmp
->schedulingBaseparserExplicitly
)
250 tmp
->schedulingBaseparserExplicitly
= false;
259 if (tmp
->chosenAsExclusiveSubparser
)
270 static int subparserDepth
;
272 extern void enterSubparser(subparser
*subparser
)
275 pushLanguage (getSubparserLanguage (subparser
));
278 extern void leaveSubparser(void)
284 extern bool doesSubparserRun (void)
286 if (getLanguageForBaseParser () == getInputLanguage())
288 return subparserDepth
;
291 extern slaveParser
*getFirstSlaveParser (struct slaveControlBlock
*scb
)
294 return scb
->slaveParsers
;
298 extern subparser
*getLanguageSubparser (langType sublang
,
299 bool including_none_crafted_parser
)
303 foreachSubparser (s
, including_none_crafted_parser
)
305 if (getSubparserLanguage (s
) == sublang
)
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
)
321 pushLanguage (scb
->owner
);
322 foreachSlaveParser(tmp
)
324 if (tmp
->type
!= DEPTYPE_SUBPARSER
)
327 if (!isLanguageVisible (tmp
->id
))
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}";
341 case SUBPARSER_SUB_RUNS_BASE
:
342 direction
= "base <= sub {dedicated}";
344 case SUBPARSER_BI_DIRECTION
:
345 direction
= "base <> sub {bidirectional}";
348 direction
= "UNKNOWN(INTERNAL BUG)";
351 colprintLineAppendColumnCString (line
, direction
);
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);
362 r
= strcmp (a_name
, b_name
);
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_ */
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";