13bae5023SMasatake YAMATO /*
23bae5023SMasatake YAMATO * Copyright (c) 2017, Masatake YAMATO
33bae5023SMasatake YAMATO *
43bae5023SMasatake YAMATO * This source code is released for free distribution under the terms of the
53bae5023SMasatake YAMATO * GNU General Public License version 2 or (at your option) any later version.
63bae5023SMasatake YAMATO *
73bae5023SMasatake YAMATO */
83bae5023SMasatake YAMATO
93bae5023SMasatake YAMATO #include "general.h" /* must always come first */
103bae5023SMasatake YAMATO #include "tcl.h"
11*0d958412SMasatake YAMATO #include "param.h"
123bae5023SMasatake YAMATO #include "parse.h"
133bae5023SMasatake YAMATO #include "entry.h"
143bae5023SMasatake YAMATO #include "tokeninfo.h"
153bae5023SMasatake YAMATO
163bae5023SMasatake YAMATO #include <string.h>
173bae5023SMasatake YAMATO
183bae5023SMasatake YAMATO
193bae5023SMasatake YAMATO struct tclooSubparser {
203bae5023SMasatake YAMATO tclSubparser tcl;
213bae5023SMasatake YAMATO bool foundTclOONamespaceImported;
223bae5023SMasatake YAMATO };
233bae5023SMasatake YAMATO
243bae5023SMasatake YAMATO static scopeSeparator TclOOGenericSeparators [] = {
25f92e6bf2SMasatake YAMATO { KIND_WILDCARD_INDEX, "::" },
263bae5023SMasatake YAMATO };
273bae5023SMasatake YAMATO
283bae5023SMasatake YAMATO enum TclOOKind {
293bae5023SMasatake YAMATO K_CLASS,
303bae5023SMasatake YAMATO K_METHOD,
313bae5023SMasatake YAMATO };
323bae5023SMasatake YAMATO
333bae5023SMasatake YAMATO static kindDefinition TclOOKinds[] = {
343bae5023SMasatake YAMATO { true, 'c', "class", "classes" },
353bae5023SMasatake YAMATO { true, 'm', "method", "methods",
363bae5023SMasatake YAMATO ATTACH_SEPARATORS(TclOOGenericSeparators) },
373bae5023SMasatake YAMATO };
383bae5023SMasatake YAMATO
39*0d958412SMasatake YAMATO static bool tclooForceUse;
40*0d958412SMasatake YAMATO
parseMethod(tokenInfo * token,int owner)41ac2f8a0bSMasatake YAMATO static void parseMethod (tokenInfo *token, int owner)
423bae5023SMasatake YAMATO {
433bae5023SMasatake YAMATO tokenRead (token);
443bae5023SMasatake YAMATO if (tokenIsType (token, TCL_IDENTIFIER))
453bae5023SMasatake YAMATO {
463bae5023SMasatake YAMATO tagEntryInfo e;
473bae5023SMasatake YAMATO
485c2563d5SMasatake YAMATO initTagEntry(&e, tokenString (token), K_METHOD);
49ac2f8a0bSMasatake YAMATO e.extensionFields.scopeIndex = owner;
503bae5023SMasatake YAMATO makeTagEntry (&e);
513bae5023SMasatake YAMATO }
523bae5023SMasatake YAMATO skipToEndOfTclCmdline (token);
533bae5023SMasatake YAMATO }
543bae5023SMasatake YAMATO
parseSuperclass(tokenInfo * token,int this_class)55ac2f8a0bSMasatake YAMATO static void parseSuperclass (tokenInfo *token, int this_class)
563bae5023SMasatake YAMATO {
573bae5023SMasatake YAMATO tokenRead (token);
583bae5023SMasatake YAMATO if (tokenIsType (token, TCL_IDENTIFIER))
593bae5023SMasatake YAMATO {
60ac2f8a0bSMasatake YAMATO tagEntryInfo *e = getEntryInCorkQueue(this_class);
613bae5023SMasatake YAMATO
620a8850f8SMasatake YAMATO if (e)
630a8850f8SMasatake YAMATO {
643bae5023SMasatake YAMATO if (e->extensionFields.inheritance)
653bae5023SMasatake YAMATO { /* superclass is used twice in a class. */
663bae5023SMasatake YAMATO eFree ((void *)e->extensionFields.inheritance);
673bae5023SMasatake YAMATO }
683bae5023SMasatake YAMATO e->extensionFields.inheritance = eStrdup(tokenString(token));
693bae5023SMasatake YAMATO }
700a8850f8SMasatake YAMATO }
713bae5023SMasatake YAMATO skipToEndOfTclCmdline (token);
723bae5023SMasatake YAMATO }
733bae5023SMasatake YAMATO
parseClass(tclSubparser * s CTAGS_ATTR_UNUSED,int parentIndex,void * pstate)745d9d66cfSMasatake YAMATO static int parseClass (tclSubparser *s CTAGS_ATTR_UNUSED, int parentIndex,
755d9d66cfSMasatake YAMATO void *pstate)
763bae5023SMasatake YAMATO {
775d9d66cfSMasatake YAMATO tokenInfo *token = newTclToken (pstate);
783bae5023SMasatake YAMATO int r = CORK_NIL;
793bae5023SMasatake YAMATO
803bae5023SMasatake YAMATO tokenRead (token);
813bae5023SMasatake YAMATO if (tokenIsType (token, TCL_IDENTIFIER)
823bae5023SMasatake YAMATO && (strcmp(tokenString(token), "create") == 0))
833bae5023SMasatake YAMATO {
843bae5023SMasatake YAMATO tokenRead (token);
853bae5023SMasatake YAMATO if (tokenIsType (token, TCL_IDENTIFIER))
863bae5023SMasatake YAMATO {
873bae5023SMasatake YAMATO tagEntryInfo e;
883bae5023SMasatake YAMATO
895c2563d5SMasatake YAMATO initTagEntry(&e, tokenString (token), K_CLASS);
903bae5023SMasatake YAMATO e.extensionFields.scopeIndex = parentIndex;
913bae5023SMasatake YAMATO r = makeTagEntry (&e);
923bae5023SMasatake YAMATO }
933bae5023SMasatake YAMATO
943bae5023SMasatake YAMATO if (tokenSkipToType (token, '{'))
953bae5023SMasatake YAMATO {
963bae5023SMasatake YAMATO do {
973bae5023SMasatake YAMATO tokenRead (token);
983bae5023SMasatake YAMATO if (tokenIsType (token, TCL_IDENTIFIER)
993bae5023SMasatake YAMATO || tokenIsType (token, TCL_KEYWORD))
1003bae5023SMasatake YAMATO {
1013bae5023SMasatake YAMATO if (strcmp(tokenString(token), "method") == 0)
1023bae5023SMasatake YAMATO parseMethod(token, r);
1033bae5023SMasatake YAMATO else if (strcmp(tokenString(token), "superclass") == 0)
1043bae5023SMasatake YAMATO parseSuperclass(token, r);
1053bae5023SMasatake YAMATO else
1063bae5023SMasatake YAMATO skipToEndOfTclCmdline (token);
1073bae5023SMasatake YAMATO }
1083bae5023SMasatake YAMATO else if (token->type == '}')
1093bae5023SMasatake YAMATO break;
1103bae5023SMasatake YAMATO } while (!tokenIsEOF(token));
1113bae5023SMasatake YAMATO }
1123bae5023SMasatake YAMATO }
1133bae5023SMasatake YAMATO
1143bae5023SMasatake YAMATO skipToEndOfTclCmdline (token);
115a203ce0eSMasatake YAMATO tokenDelete(token);
1163bae5023SMasatake YAMATO return r;
1173bae5023SMasatake YAMATO }
1183bae5023SMasatake YAMATO
commandNotify(tclSubparser * s,char * command,int parentIndex,void * pstate)1193bae5023SMasatake YAMATO static int commandNotify (tclSubparser *s, char *command,
1205d9d66cfSMasatake YAMATO int parentIndex, void *pstate)
1213bae5023SMasatake YAMATO {
1223bae5023SMasatake YAMATO struct tclooSubparser *tcloo = (struct tclooSubparser *)s;
1233bae5023SMasatake YAMATO int r = CORK_NIL;
1243bae5023SMasatake YAMATO
1253bae5023SMasatake YAMATO if ((tcloo->foundTclOONamespaceImported
1263bae5023SMasatake YAMATO && (strcmp (command, "class") == 0))
1273bae5023SMasatake YAMATO || (strcmp (command, "oo::class") == 0))
1285d9d66cfSMasatake YAMATO r = parseClass (s, parentIndex, pstate);
1293bae5023SMasatake YAMATO
1303bae5023SMasatake YAMATO return r;
1313bae5023SMasatake YAMATO }
1323bae5023SMasatake YAMATO
namespaceImportNotify(tclSubparser * s,char * namespace,void * pstate CTAGS_ATTR_UNUSED)1335d9d66cfSMasatake YAMATO static void namespaceImportNotify (tclSubparser *s, char *namespace,
1345d9d66cfSMasatake YAMATO void *pstate CTAGS_ATTR_UNUSED)
1353bae5023SMasatake YAMATO {
1363bae5023SMasatake YAMATO struct tclooSubparser *tcloo = (struct tclooSubparser *)s;
1373bae5023SMasatake YAMATO
1383bae5023SMasatake YAMATO if (strcmp(namespace, "oo::*") == 0
1393bae5023SMasatake YAMATO || strcmp(namespace, "oo::class") == 0)
1403bae5023SMasatake YAMATO tcloo->foundTclOONamespaceImported = true;
1413bae5023SMasatake YAMATO }
1423bae5023SMasatake YAMATO
inputStart(subparser * s)1433bae5023SMasatake YAMATO static void inputStart (subparser *s)
1443bae5023SMasatake YAMATO {
1453bae5023SMasatake YAMATO struct tclooSubparser *tcloo = (struct tclooSubparser *)s;
1463bae5023SMasatake YAMATO
147*0d958412SMasatake YAMATO tcloo->foundTclOONamespaceImported = tclooForceUse;
1483bae5023SMasatake YAMATO }
1493bae5023SMasatake YAMATO
150e3ee5398SMasatake YAMATO static struct tclooSubparser tclooSubparser = {
1513bae5023SMasatake YAMATO .tcl = {
1523bae5023SMasatake YAMATO .subparser = {
1533bae5023SMasatake YAMATO .direction = SUBPARSER_BI_DIRECTION,
1543bae5023SMasatake YAMATO .inputStart = inputStart,
1553bae5023SMasatake YAMATO },
1563bae5023SMasatake YAMATO .commandNotify = commandNotify,
1573bae5023SMasatake YAMATO .namespaceImportNotify = namespaceImportNotify,
1583bae5023SMasatake YAMATO },
1593bae5023SMasatake YAMATO };
1603bae5023SMasatake YAMATO
findTclOOTags(void)1613bae5023SMasatake YAMATO static void findTclOOTags(void)
1623bae5023SMasatake YAMATO {
1633bae5023SMasatake YAMATO scheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);
1643bae5023SMasatake YAMATO }
1653bae5023SMasatake YAMATO
tclooForceUseParamHandler(const langType language CTAGS_ATTR_UNUSED,const char * name,const char * arg)166*0d958412SMasatake YAMATO static void tclooForceUseParamHandler (const langType language CTAGS_ATTR_UNUSED,
167*0d958412SMasatake YAMATO const char *name, const char *arg)
168*0d958412SMasatake YAMATO {
169*0d958412SMasatake YAMATO tclooForceUse = paramParserBool (arg, tclooForceUse, name, "parameter");
170*0d958412SMasatake YAMATO }
171*0d958412SMasatake YAMATO
172*0d958412SMasatake YAMATO static parameterHandlerTable TclOOParameterHandlerTable [] = {
173*0d958412SMasatake YAMATO { .name = "forceUse",
174*0d958412SMasatake YAMATO .desc = "enable the parser even when `oo' namespace is not specified in the input (true or [false])" ,
175*0d958412SMasatake YAMATO .handleParameter = tclooForceUseParamHandler,
176*0d958412SMasatake YAMATO },
177*0d958412SMasatake YAMATO };
178*0d958412SMasatake YAMATO
TclOOParser(void)1793bae5023SMasatake YAMATO extern parserDefinition* TclOOParser (void)
1803bae5023SMasatake YAMATO {
1813bae5023SMasatake YAMATO parserDefinition* const def = parserNew("TclOO");
1823bae5023SMasatake YAMATO
1833bae5023SMasatake YAMATO static parserDependency dependencies [] = {
1843bae5023SMasatake YAMATO [0] = { DEPTYPE_SUBPARSER, "Tcl", &tclooSubparser },
1853bae5023SMasatake YAMATO };
1863bae5023SMasatake YAMATO
1873bae5023SMasatake YAMATO def->dependencies = dependencies;
1883bae5023SMasatake YAMATO def->dependencyCount = ARRAY_SIZE (dependencies);
1893bae5023SMasatake YAMATO
1903bae5023SMasatake YAMATO def->kindTable = TclOOKinds;
1913bae5023SMasatake YAMATO def->kindCount = ARRAY_SIZE(TclOOKinds);
1923bae5023SMasatake YAMATO
1933bae5023SMasatake YAMATO def->parser = findTclOOTags;
1946b1a862eSMasatake YAMATO def->useCork = CORK_QUEUE;
1953bae5023SMasatake YAMATO def->requestAutomaticFQTag = true;
1963bae5023SMasatake YAMATO
197*0d958412SMasatake YAMATO def->parameterHandlerTable = TclOOParameterHandlerTable;
198*0d958412SMasatake YAMATO def->parameterHandlerCount = ARRAY_SIZE(TclOOParameterHandlerTable);
199*0d958412SMasatake YAMATO
2003bae5023SMasatake YAMATO return def;
2013bae5023SMasatake YAMATO }
202