4 * Copyright (c) 2000-2003, Darren Hiebert
6 * This source code is released for free distribution under the terms of the
7 * GNU General Public License.
9 * This module contains functions for generating tags for PERL language
16 #include "general.h" /* must always come first */
35 static kindOption PerlKinds
[] = {
36 { TRUE
, 'c', "constant", "constants" },
37 { TRUE
, 'l', "label", "labels" },
38 { TRUE
, 's', "subroutine", "subroutines" }
42 * FUNCTION DEFINITIONS
45 static boolean
isIdentifier1 (int c
)
47 return (boolean
) (isalpha (c
) || c
== '_');
50 static boolean
isIdentifier (int c
)
52 return (boolean
) (isalnum (c
) || c
== '_');
55 static boolean
isPodWord (const char *word
)
57 boolean result
= FALSE
;
60 const char *const pods
[] = {
61 "head1", "head2", "head3", "head4", "over", "item", "back",
62 "pod", "begin", "end", "for"
64 const size_t count
= sizeof (pods
) / sizeof (pods
[0]);
65 const char *white
= strpbrk (word
, " \t");
66 const size_t len
= (white
!=NULL
) ? (size_t)(white
-word
) : strlen (word
);
67 char *const id
= (char*) eMalloc (len
+ 1);
69 strncpy (id
, word
, len
);
71 for (i
= 0 ; i
< count
&& ! result
; ++i
)
73 if (strcmp (id
, pods
[i
]) == 0)
81 /* Algorithm adapted from from GNU etags.
82 * Perl support by Bart Robinson <lomew@cs.utah.edu>
83 * Perl sub names: look for /^ [ \t\n]sub [ \t\n]+ [^ \t\n{ (]+/
85 static void findPerlTags (void)
87 vString
*name
= vStringNew ();
88 vString
*package
= NULL
;
89 boolean skipPodDoc
= FALSE
;
90 const unsigned char *line
;
92 while ((line
= fileReadLine ()) != NULL
)
94 boolean spaceRequired
= FALSE
;
95 boolean qualified
= FALSE
;
96 const unsigned char *cp
= line
;
97 perlKind kind
= K_NONE
;
101 if (strncmp ((const char*) line
, "=cut", (size_t) 4) == 0)
105 else if (line
[0] == '=')
107 skipPodDoc
= isPodWord ((const char*)line
+ 1);
110 else if (strcmp ((const char*) line
, "__DATA__") == 0)
112 else if (strcmp ((const char*) line
, "__END__") == 0)
114 else if (line
[0] == '#')
117 while (isspace (*cp
))
120 if (strncmp((const char*) cp
, "sub", (size_t) 3) == 0)
124 spaceRequired
= TRUE
;
127 else if (strncmp((const char*) cp
, "use", (size_t) 3) == 0)
132 while (*cp
&& isspace (*cp
))
134 if (strncmp((const char*) cp
, "constant", (size_t) 8) != 0)
138 spaceRequired
= TRUE
;
141 else if (strncmp((const char*) cp
, "package", (size_t) 7) == 0)
145 package
= vStringNew ();
147 vStringClear (package
);
148 while (isspace (*cp
))
150 while ((int) *cp
!= ';' && !isspace ((int) *cp
))
152 vStringPut (package
, (int) *cp
);
155 vStringCatS (package
, "::");
159 if (isIdentifier1 (*cp
))
161 const unsigned char *p
= cp
;
162 while (isIdentifier (*p
))
170 if (spaceRequired
&& !isspace (*cp
))
173 while (isspace (*cp
))
175 while (isIdentifier (*cp
))
177 vStringPut (name
, (int) *cp
);
180 vStringTerminate (name
);
181 if (vStringLength (name
) > 0)
183 makeSimpleTag (name
, PerlKinds
, kind
);
184 if (Option
.include
.qualifiedTags
&& qualified
&&
185 package
!= NULL
&& vStringLength (package
) > 0)
187 vString
*const qualifiedName
= vStringNew ();
188 vStringCopy (qualifiedName
, package
);
189 vStringCat (qualifiedName
, name
);
190 makeSimpleTag (qualifiedName
, PerlKinds
, kind
);
191 vStringDelete (qualifiedName
);
197 vStringDelete (name
);
199 vStringDelete (package
);
202 extern parserDefinition
* PerlParser (void)
204 static const char *const extensions
[] = { "pl", "pm", "plx", "perl", NULL
};
205 parserDefinition
* def
= parserNew ("Perl");
206 def
->kinds
= PerlKinds
;
207 def
->kindCount
= KIND_COUNT (PerlKinds
);
208 def
->extensions
= extensions
;
209 def
->parser
= findPerlTags
;
213 /* vi:set tabstop=4 shiftwidth=4: */