2005-11-22 12:26:26 +00:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Copyright (c) 2000-2001, Darren Hiebert
|
|
|
|
*
|
|
|
|
* This source code is released for free distribution under the terms of the
|
|
|
|
* GNU General Public License.
|
|
|
|
*
|
|
|
|
* This module contains functions for generating tags for PERL language
|
|
|
|
* files.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* INCLUDE FILES
|
|
|
|
*/
|
|
|
|
#include "general.h" /* must always come first */
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "read.h"
|
|
|
|
#include "vstring.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* DATA DEFINITIONS
|
|
|
|
*/
|
|
|
|
typedef enum {
|
|
|
|
K_SUBROUTINE,
|
2006-05-10 22:35:55 +00:00
|
|
|
K_PACKAGE,
|
|
|
|
K_LOCAL,
|
|
|
|
K_MY,
|
|
|
|
K_OUR
|
2005-11-22 12:26:26 +00:00
|
|
|
} perlKind;
|
|
|
|
|
|
|
|
static kindOption PerlKinds [] = {
|
|
|
|
{ TRUE, 'f', "function", "functions" },
|
2006-05-10 22:35:55 +00:00
|
|
|
{ TRUE, 'c', "class", "packages" },
|
|
|
|
{ TRUE, 'l', "macro", "local variables" },
|
|
|
|
{ TRUE, 'm', "member", "my variables" },
|
|
|
|
{ TRUE, 'v', "variable", "our variables" }
|
2005-11-22 12:26:26 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* FUNCTION DEFINITIONS
|
|
|
|
*/
|
|
|
|
|
2006-05-12 16:24:09 +00:00
|
|
|
static const unsigned char *createTagString(const unsigned char *str, int type)
|
|
|
|
{
|
|
|
|
vString *n = vStringNew();
|
|
|
|
while (! isspace ((int) *str) && *str != '\0' && *str != '=' && *str != ';' &&
|
|
|
|
*str != ',' && *str != ')' && *str != '$')
|
|
|
|
{
|
|
|
|
vStringPut (n, (int) *str);
|
|
|
|
str++;
|
|
|
|
}
|
|
|
|
|
|
|
|
vStringTerminate (n);
|
|
|
|
if (vStringLength (n) > 0)
|
|
|
|
makeSimpleTag (n, PerlKinds, type);
|
|
|
|
vStringDelete (n);
|
|
|
|
|
|
|
|
/* if ((*(const char*)str) == ')')
|
|
|
|
return str-1;
|
|
|
|
else
|
|
|
|
*/ return str;
|
|
|
|
}
|
2006-05-10 22:35:55 +00:00
|
|
|
|
2005-11-22 12:26:26 +00:00
|
|
|
/* Algorithm adapted from from GNU etags.
|
|
|
|
* Perl support by Bart Robinson <lomew@cs.utah.edu>
|
|
|
|
* Perl sub names: look for /^ [ \t\n]sub [ \t\n]+ [^ \t\n{ (]+/
|
|
|
|
*/
|
|
|
|
static void findPerlTags (void)
|
|
|
|
{
|
|
|
|
vString *name = vStringNew ();
|
|
|
|
boolean skipPodDoc = FALSE;
|
|
|
|
const unsigned char *line;
|
|
|
|
perlKind kind;
|
|
|
|
|
|
|
|
while ((line = fileReadLine ()) != NULL)
|
|
|
|
{
|
|
|
|
const unsigned char *cp = line;
|
|
|
|
|
|
|
|
if (skipPodDoc)
|
|
|
|
{
|
|
|
|
if (strcmp ((const char*) line, "=cut") == 0)
|
|
|
|
skipPodDoc = FALSE;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else if (line [0] == '=')
|
|
|
|
{
|
|
|
|
skipPodDoc = (boolean) (strncmp (
|
|
|
|
(const char*) line + 1, "cut", (size_t) 3) != 0);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else if (strcmp ((const char*) line, "__DATA__") == 0)
|
|
|
|
break;
|
|
|
|
else if (strcmp ((const char*) line, "__END__") == 0)
|
|
|
|
break;
|
|
|
|
else if (line [0] == '#')
|
|
|
|
continue;
|
|
|
|
|
|
|
|
while (isspace (*cp))
|
|
|
|
cp++;
|
|
|
|
|
2006-05-10 22:35:55 +00:00
|
|
|
if (strncmp((const char*) cp, "my", (size_t) 2) == 0)
|
|
|
|
{
|
|
|
|
cp += 2;
|
|
|
|
while (isspace (*cp)) cp++;
|
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* parse something like my($bla) */
|
2006-05-12 16:24:09 +00:00
|
|
|
if (*(const char*) cp == '(')
|
2006-05-10 22:35:55 +00:00
|
|
|
{
|
2006-05-12 16:24:09 +00:00
|
|
|
cp++;
|
|
|
|
while (*(const char*) cp != ')')
|
|
|
|
{
|
|
|
|
while (isspace (*(const char*) cp)) cp++;
|
2008-02-27 13:17:29 +00:00
|
|
|
if (*(const char*) cp == ',') cp++; /* to skip ',' */
|
2006-05-12 16:24:09 +00:00
|
|
|
while (isspace (*(const char*) cp)) cp++;
|
2008-02-27 13:17:29 +00:00
|
|
|
cp++; /* to skip $ sign */
|
2006-05-12 16:24:09 +00:00
|
|
|
cp = createTagString(cp, K_MY);
|
|
|
|
while (isspace (*(const char*) cp)) cp++;
|
|
|
|
}
|
2006-05-10 22:35:55 +00:00
|
|
|
}
|
2008-02-27 13:17:29 +00:00
|
|
|
/* parse my $bla */
|
2006-05-12 16:24:09 +00:00
|
|
|
else
|
|
|
|
{
|
2008-02-27 13:17:29 +00:00
|
|
|
cp++; /* to skip the $ sign */
|
2006-05-10 22:35:55 +00:00
|
|
|
|
2006-05-12 16:24:09 +00:00
|
|
|
if (! isalpha (*(const char*) cp)) continue;
|
2006-05-10 22:35:55 +00:00
|
|
|
|
2006-05-12 16:24:09 +00:00
|
|
|
createTagString (cp, K_MY);
|
|
|
|
}
|
2006-05-10 22:35:55 +00:00
|
|
|
}
|
2006-05-10 23:00:22 +00:00
|
|
|
else if (strncmp((const char*) cp, "our", (size_t) 3) == 0)
|
2006-05-10 22:35:55 +00:00
|
|
|
{
|
|
|
|
cp += 3;
|
2006-05-10 23:00:22 +00:00
|
|
|
while (isspace (*cp)) cp++;
|
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* parse something like my($bla) */
|
2006-05-12 16:24:09 +00:00
|
|
|
if (*(const char*) cp == '(')
|
2006-05-10 22:35:55 +00:00
|
|
|
{
|
2006-05-12 16:24:09 +00:00
|
|
|
cp++;
|
|
|
|
while (*(const char*) cp != ')')
|
|
|
|
{
|
|
|
|
while (isspace (*(const char*) cp)) cp++;
|
2008-02-27 13:17:29 +00:00
|
|
|
if (*(const char*) cp == ',') cp++; /* to skip ',' */
|
2006-05-12 16:24:09 +00:00
|
|
|
while (isspace (*(const char*) cp)) cp++;
|
2008-02-27 13:17:29 +00:00
|
|
|
cp++; /* to skip $ sign */
|
2006-05-12 16:24:09 +00:00
|
|
|
cp = createTagString(cp, K_OUR);
|
|
|
|
while (isspace (*(const char*) cp)) cp++;
|
|
|
|
}
|
2006-05-10 22:35:55 +00:00
|
|
|
}
|
2008-02-27 13:17:29 +00:00
|
|
|
/* parse my $bla */
|
2006-05-12 16:24:09 +00:00
|
|
|
else
|
|
|
|
{
|
2008-02-27 13:17:29 +00:00
|
|
|
cp++; /* to skip the $ sign */
|
2006-05-12 16:24:09 +00:00
|
|
|
|
|
|
|
if (! isalpha (*(const char*) cp)) continue;
|
|
|
|
|
|
|
|
createTagString (cp, K_OUR);
|
|
|
|
}
|
2006-05-10 22:35:55 +00:00
|
|
|
}
|
2006-05-10 23:00:22 +00:00
|
|
|
else if (strncmp((const char*) cp, "local", (size_t) 5) == 0)
|
2006-05-10 22:35:55 +00:00
|
|
|
{
|
|
|
|
cp += 5;
|
2006-05-10 23:00:22 +00:00
|
|
|
while (isspace (*cp)) cp++;
|
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* parse something like my($bla) */
|
2006-05-12 16:24:09 +00:00
|
|
|
if (*(const char*) cp == '(')
|
2006-05-10 22:35:55 +00:00
|
|
|
{
|
2006-05-12 16:24:09 +00:00
|
|
|
cp++;
|
|
|
|
while (*(const char*) cp != ')')
|
|
|
|
{
|
|
|
|
while (isspace (*(const char*) cp)) cp++;
|
2008-02-27 13:17:29 +00:00
|
|
|
if (*(const char*) cp == ',') cp++; /* to skip ',' */
|
2006-05-12 16:24:09 +00:00
|
|
|
while (isspace (*(const char*) cp)) cp++;
|
2008-02-27 13:17:29 +00:00
|
|
|
cp++; /* to skip $ sign */
|
2006-05-12 16:24:09 +00:00
|
|
|
cp = createTagString(cp, K_LOCAL);
|
|
|
|
while (isspace (*(const char*) cp)) cp++;
|
|
|
|
}
|
2006-05-10 22:35:55 +00:00
|
|
|
}
|
2008-02-27 13:17:29 +00:00
|
|
|
/* parse my $bla */
|
2006-05-12 16:24:09 +00:00
|
|
|
else
|
|
|
|
{
|
2008-02-27 13:17:29 +00:00
|
|
|
cp++; /* to skip the $ sign */
|
2006-05-12 16:24:09 +00:00
|
|
|
|
|
|
|
if (! isalpha (*(const char*) cp)) continue;
|
|
|
|
|
|
|
|
createTagString (cp, K_LOCAL);
|
|
|
|
}
|
2006-05-10 22:35:55 +00:00
|
|
|
}
|
|
|
|
else if (strncmp((const char*) cp, "sub", (size_t) 3) == 0 ||
|
|
|
|
strncmp((const char*) cp, "package", (size_t) 7) == 0)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
|
|
|
if (strncmp((const char*) cp, "sub", (size_t) 3) == 0)
|
|
|
|
{
|
|
|
|
cp += 3;
|
|
|
|
kind = K_SUBROUTINE;
|
|
|
|
} else {
|
|
|
|
cp += 7;
|
|
|
|
kind = K_PACKAGE;
|
|
|
|
}
|
|
|
|
if (!isspace(*cp)) /* woops, not followed by a space */
|
|
|
|
continue;
|
|
|
|
|
|
|
|
while (isspace (*cp))
|
|
|
|
cp++;
|
2006-05-10 22:35:55 +00:00
|
|
|
while (! isspace ((int) *cp) && *cp != '\0' && *cp != '{' && *cp != '(' && *cp != ';')
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
|
|
|
vStringPut (name, (int) *cp);
|
|
|
|
cp++;
|
|
|
|
}
|
|
|
|
vStringTerminate (name);
|
|
|
|
if (vStringLength (name) > 0)
|
|
|
|
makeSimpleTag (name, PerlKinds, kind);
|
|
|
|
vStringClear (name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
vStringDelete (name);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern parserDefinition* PerlParser (void)
|
|
|
|
{
|
|
|
|
static const char *const extensions [] = { "pl", "pm", "perl", NULL };
|
|
|
|
parserDefinition* def = parserNew ("Perl");
|
|
|
|
def->kinds = PerlKinds;
|
|
|
|
def->kindCount = KIND_COUNT (PerlKinds);
|
|
|
|
def->extensions = extensions;
|
|
|
|
def->parser = findPerlTags;
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* vi:set tabstop=8 shiftwidth=4: */
|