xref: /Universal-ctags/parsers/perl-function-parameters.c (revision 00f9a206b087545f05909e61ef605cf354678961)
1*00f9a206SMasatake YAMATO /*
2*00f9a206SMasatake YAMATO  *   Copyright (c) 2021, Masatake YAMATO
3*00f9a206SMasatake YAMATO  *   Copyright (c) 2021, Red Hat, Inc.
4*00f9a206SMasatake YAMATO  *
5*00f9a206SMasatake YAMATO  *   This source code is released for free distribution under the terms of the
6*00f9a206SMasatake YAMATO  *   GNU General Public License version 2 or (at your option) any later version.
7*00f9a206SMasatake YAMATO  *
8*00f9a206SMasatake YAMATO  *   This module contains functions for generating tags for Function::Parameters perl extension.
9*00f9a206SMasatake YAMATO  *   https://metacpan.org/pod/Function::Parameters
10*00f9a206SMasatake YAMATO  *
11*00f9a206SMasatake YAMATO  *   This parser is inspired by the pull request submitted by Jim Butler (@jimmygoogle).
12*00f9a206SMasatake YAMATO  */
13*00f9a206SMasatake YAMATO 
14*00f9a206SMasatake YAMATO /*
15*00f9a206SMasatake YAMATO  *   INCLUDE FILES
16*00f9a206SMasatake YAMATO  */
17*00f9a206SMasatake YAMATO #include "general.h"  /* must always come first */
18*00f9a206SMasatake YAMATO 
19*00f9a206SMasatake YAMATO #include "entry.h"
20*00f9a206SMasatake YAMATO #include "kind.h"
21*00f9a206SMasatake YAMATO #include "parse.h"
22*00f9a206SMasatake YAMATO #include "perl.h"
23*00f9a206SMasatake YAMATO 
24*00f9a206SMasatake YAMATO #include <string.h>
25*00f9a206SMasatake YAMATO 
26*00f9a206SMasatake YAMATO /*
27*00f9a206SMasatake YAMATO  *   DATA DECLARATIONS
28*00f9a206SMasatake YAMATO  */
29*00f9a206SMasatake YAMATO 
30*00f9a206SMasatake YAMATO enum FParamsKind {
31*00f9a206SMasatake YAMATO 	K_METHOD,
32*00f9a206SMasatake YAMATO 	K_FUN,
33*00f9a206SMasatake YAMATO };
34*00f9a206SMasatake YAMATO 
35*00f9a206SMasatake YAMATO static kindDefinition FParamsKinds[] = {
36*00f9a206SMasatake YAMATO 	{ true, 'm', "method", "methods" },
37*00f9a206SMasatake YAMATO 	{ true, 'f', "fun",    "functions" },
38*00f9a206SMasatake YAMATO };
39*00f9a206SMasatake YAMATO 
40*00f9a206SMasatake YAMATO struct FParamsSubparser {
41*00f9a206SMasatake YAMATO 	perlSubparser perl;
42*00f9a206SMasatake YAMATO 	bool notInFParams;
43*00f9a206SMasatake YAMATO 	bool inPod;
44*00f9a206SMasatake YAMATO };
45*00f9a206SMasatake YAMATO 
46*00f9a206SMasatake YAMATO /*
47*00f9a206SMasatake YAMATO  *   FUNCTION PROTOTYPES
48*00f9a206SMasatake YAMATO  */
49*00f9a206SMasatake YAMATO 
50*00f9a206SMasatake YAMATO static void inputStart (subparser *s);
51*00f9a206SMasatake YAMATO static void makeTagEntryNotify (subparser *s, const tagEntryInfo *tag, int corkIndex);
52*00f9a206SMasatake YAMATO static void enterFParams (struct FParamsSubparser *fparms);
53*00f9a206SMasatake YAMATO static void leaveFParams (struct FParamsSubparser *fparams);
54*00f9a206SMasatake YAMATO static void enteringPodNotify (perlSubparser *perl);
55*00f9a206SMasatake YAMATO static void leavingPodNotify  (perlSubparser *perl);
56*00f9a206SMasatake YAMATO 
57*00f9a206SMasatake YAMATO /*
58*00f9a206SMasatake YAMATO  *   DATA DEFINITIONS
59*00f9a206SMasatake YAMATO  */
60*00f9a206SMasatake YAMATO 
61*00f9a206SMasatake YAMATO static struct FParamsSubparser fparamsSubparser = {
62*00f9a206SMasatake YAMATO 	.perl = {
63*00f9a206SMasatake YAMATO 		.subparser = {
64*00f9a206SMasatake YAMATO 			.direction  = SUBPARSER_BI_DIRECTION,
65*00f9a206SMasatake YAMATO 			.inputStart = inputStart,
66*00f9a206SMasatake YAMATO 			.makeTagEntryNotify = makeTagEntryNotify,
67*00f9a206SMasatake YAMATO 		},
68*00f9a206SMasatake YAMATO 		.enteringPodNotify = enteringPodNotify,
69*00f9a206SMasatake YAMATO 		.leavingPodNotify  = leavingPodNotify,
70*00f9a206SMasatake YAMATO 	}
71*00f9a206SMasatake YAMATO };
72*00f9a206SMasatake YAMATO 
73*00f9a206SMasatake YAMATO /*
74*00f9a206SMasatake YAMATO  *   FUNCTION DEFINITIONS
75*00f9a206SMasatake YAMATO  */
76*00f9a206SMasatake YAMATO 
inputStart(subparser * s)77*00f9a206SMasatake YAMATO static void inputStart (subparser *s)
78*00f9a206SMasatake YAMATO {
79*00f9a206SMasatake YAMATO 	struct FParamsSubparser *fparams = (struct FParamsSubparser *)s;
80*00f9a206SMasatake YAMATO 
81*00f9a206SMasatake YAMATO 	fparams->notInFParams = true;
82*00f9a206SMasatake YAMATO 	fparams->inPod = false;
83*00f9a206SMasatake YAMATO }
84*00f9a206SMasatake YAMATO 
makeTagEntryNotify(subparser * s,const tagEntryInfo * tag,int corkIndex)85*00f9a206SMasatake YAMATO static void makeTagEntryNotify (subparser *s, const tagEntryInfo *tag, int corkIndex)
86*00f9a206SMasatake YAMATO {
87*00f9a206SMasatake YAMATO 	perlSubparser *perl = (perlSubparser *)s;
88*00f9a206SMasatake YAMATO 	struct FParamsSubparser *fparams = (struct FParamsSubparser *)perl;
89*00f9a206SMasatake YAMATO 
90*00f9a206SMasatake YAMATO 	if (isTagExtraBitMarked(tag, XTAG_QUALIFIED_TAGS))
91*00f9a206SMasatake YAMATO 		return;
92*00f9a206SMasatake YAMATO 
93*00f9a206SMasatake YAMATO 	if (tag->kindIndex == KIND_PERL_MODULE)
94*00f9a206SMasatake YAMATO 	{
95*00f9a206SMasatake YAMATO 		if (isRoleAssigned(tag, ROLE_PERL_MODULE_USED)
96*00f9a206SMasatake YAMATO 			&& strcmp (tag->name, "Function::Parameters") == 0)
97*00f9a206SMasatake YAMATO 			enterFParams (fparams);
98*00f9a206SMasatake YAMATO 		else if (isRoleAssigned(tag, ROLE_PERL_MODULE_UNUSED)
99*00f9a206SMasatake YAMATO 				 && strcmp (tag->name, "Function::Parameters") == 0)
100*00f9a206SMasatake YAMATO 			leaveFParams (fparams);
101*00f9a206SMasatake YAMATO 	}
102*00f9a206SMasatake YAMATO }
103*00f9a206SMasatake YAMATO 
enterFParams(struct FParamsSubparser * fparams)104*00f9a206SMasatake YAMATO static void enterFParams (struct FParamsSubparser *fparams)
105*00f9a206SMasatake YAMATO {
106*00f9a206SMasatake YAMATO 	fparams->notInFParams = false;
107*00f9a206SMasatake YAMATO }
108*00f9a206SMasatake YAMATO 
leaveFParams(struct FParamsSubparser * fparams)109*00f9a206SMasatake YAMATO static void leaveFParams (struct FParamsSubparser *fparams)
110*00f9a206SMasatake YAMATO {
111*00f9a206SMasatake YAMATO 	fparams->notInFParams = true;
112*00f9a206SMasatake YAMATO }
113*00f9a206SMasatake YAMATO 
enteringPodNotify(perlSubparser * perl)114*00f9a206SMasatake YAMATO static void enteringPodNotify (perlSubparser *perl)
115*00f9a206SMasatake YAMATO {
116*00f9a206SMasatake YAMATO 	struct FParamsSubparser *fparams = (struct FParamsSubparser *)perl;
117*00f9a206SMasatake YAMATO 	fparams->inPod = true;
118*00f9a206SMasatake YAMATO }
119*00f9a206SMasatake YAMATO 
leavingPodNotify(perlSubparser * perl)120*00f9a206SMasatake YAMATO static void leavingPodNotify  (perlSubparser *perl)
121*00f9a206SMasatake YAMATO {
122*00f9a206SMasatake YAMATO 	struct FParamsSubparser *fparams = (struct FParamsSubparser *)perl;
123*00f9a206SMasatake YAMATO 	fparams->inPod = false;
124*00f9a206SMasatake YAMATO }
125*00f9a206SMasatake YAMATO 
findFParamsObject(const char * line,const regexMatch * matches,unsigned int count,void * userData)126*00f9a206SMasatake YAMATO static bool findFParamsObject (const char * line, const regexMatch *matches, unsigned int count,
127*00f9a206SMasatake YAMATO 							   void *userData)
128*00f9a206SMasatake YAMATO {
129*00f9a206SMasatake YAMATO 	struct FParamsSubparser *fparams = (struct FParamsSubparser *)userData;
130*00f9a206SMasatake YAMATO 
131*00f9a206SMasatake YAMATO 	if (fparams->inPod)
132*00f9a206SMasatake YAMATO 		return false;
133*00f9a206SMasatake YAMATO 
134*00f9a206SMasatake YAMATO 
135*00f9a206SMasatake YAMATO 	const char *kindHint = line + matches[1].start;
136*00f9a206SMasatake YAMATO 	int kind = kindHint [0] == 'm'? K_METHOD: K_FUN;
137*00f9a206SMasatake YAMATO 
138*00f9a206SMasatake YAMATO 	char *name = eStrndup (line + matches[2].start, matches[2].length);
139*00f9a206SMasatake YAMATO 	tagEntryInfo e;
140*00f9a206SMasatake YAMATO 	initTagEntry (&e, name, kind);
141*00f9a206SMasatake YAMATO 
142*00f9a206SMasatake YAMATO 	makeTagEntry (&e);
143*00f9a206SMasatake YAMATO 	eFree (name);
144*00f9a206SMasatake YAMATO 	return true;
145*00f9a206SMasatake YAMATO }
146*00f9a206SMasatake YAMATO 
findFParamsTags(void)147*00f9a206SMasatake YAMATO static void findFParamsTags (void)
148*00f9a206SMasatake YAMATO {
149*00f9a206SMasatake YAMATO 	scheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);
150*00f9a206SMasatake YAMATO }
151*00f9a206SMasatake YAMATO 
initializeFParamsParser(langType language)152*00f9a206SMasatake YAMATO static void initializeFParamsParser (langType language)
153*00f9a206SMasatake YAMATO {
154*00f9a206SMasatake YAMATO 	addLanguageCallbackRegex (language, "^[ \t]*(method|fun)[ \t]+([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*\\(",
155*00f9a206SMasatake YAMATO 							  NULL,
156*00f9a206SMasatake YAMATO 							  findFParamsObject, &fparamsSubparser.notInFParams,
157*00f9a206SMasatake YAMATO 							  &fparamsSubparser);
158*00f9a206SMasatake YAMATO }
159*00f9a206SMasatake YAMATO 
FunctionParametersParser(void)160*00f9a206SMasatake YAMATO extern parserDefinition* FunctionParametersParser (void)
161*00f9a206SMasatake YAMATO {
162*00f9a206SMasatake YAMATO 	parserDefinition* const def = parserNew("FunctionParameters");
163*00f9a206SMasatake YAMATO 
164*00f9a206SMasatake YAMATO 	static parserDependency dependencies [] = {
165*00f9a206SMasatake YAMATO 		[0] = { DEPTYPE_SUBPARSER, "Perl", &fparamsSubparser },
166*00f9a206SMasatake YAMATO 	};
167*00f9a206SMasatake YAMATO 
168*00f9a206SMasatake YAMATO 	def->dependencies = dependencies;
169*00f9a206SMasatake YAMATO 	def->dependencyCount = ARRAY_SIZE (dependencies);
170*00f9a206SMasatake YAMATO 
171*00f9a206SMasatake YAMATO 	def->kindTable = FParamsKinds;
172*00f9a206SMasatake YAMATO 	def->kindCount = ARRAY_SIZE(FParamsKinds);
173*00f9a206SMasatake YAMATO 
174*00f9a206SMasatake YAMATO 	def->initialize = initializeFParamsParser;
175*00f9a206SMasatake YAMATO 	def->parser = findFParamsTags;
176*00f9a206SMasatake YAMATO 
177*00f9a206SMasatake YAMATO 	return def;
178*00f9a206SMasatake YAMATO }
179