This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
#ifdef WINDOWSNT
# include <direct.h>
-# define MAXPATHLEN _MAX_PATH
# undef HAVE_NTGUI
# undef DOS_NT
# define DOS_NT
static const char Objc_help [] =
"In Objective C code, tags include Objective C definitions for classes,\n\
class categories, methods and protocols. Tags for variables and\n\
-functions in classes are named 'CLASS::VARIABLE' and 'CLASS::FUNCTION'.\n\
-(Use --help --lang=c --lang=objc --lang=java for full help.)";
+functions in classes are named 'CLASS::VARIABLE' and 'CLASS::FUNCTION'.\
+\n(Use --help --lang=c --lang=objc --lang=java for full help.)";
static const char *Pascal_suffixes [] =
{ "p", "pas", NULL };
in some languages.");
puts ("-Q, --class-qualify\n\
- Qualify tag names with their class name in C++, ObjC, and Java.\n\
+ Qualify tag names with their class name in C++, ObjC, Java, and Perl.\n\
This produces tag names of the form \"class::member\" for C++,\n\
\"class(category)\" for Objective C, and \"class.member\" for Java.\n\
For Objective C, this also produces class methods qualified with\n\
- their arguments, as in \"foo:bar:baz:more\".");
+ their arguments, as in \"foo:bar:baz:more\".\n\
+ For Perl, this produces \"package::member\".");
puts ("-r REGEXP, --regex=REGEXP or --regex=@regexfile\n\
Make a tag for each line matching a regular expression pattern\n\
in the following files. {LANGUAGE}REGEXP uses REGEXP for LANGUAGE\n\
{
char *cmd =
xmalloc (strlen (tagfile) + whatlen_max +
- sizeof "mv..OTAGS;fgrep -v '\t\t' OTAGS >;rm OTAGS");
+ sizeof "mv..OTAGS;grep -Fv '\t\t' OTAGS >;rm OTAGS");
for (i = 0; i < current_arg; ++i)
{
switch (argbuffer[i].arg_type)
}
char *z = stpcpy (cmd, "mv ");
z = stpcpy (z, tagfile);
- z = stpcpy (z, " OTAGS;fgrep -v '\t");
+ z = stpcpy (z, " OTAGS;grep -Fv '\t");
z = stpcpy (z, argbuffer[i].what);
z = stpcpy (z, "\t' OTAGS >");
z = stpcpy (z, tagfile);
((assert ("" kw), true) /* syntax error if not a literal string */ \
&& strneq ((cp), kw, sizeof (kw)-1) /* cp points at kw */ \
&& notinname ((cp)[sizeof (kw)-1]) /* end of kw */ \
- && ((cp) = skip_spaces ((cp)+sizeof (kw)-1))) /* skip spaces */
+ && ((cp) = skip_spaces ((cp) + sizeof (kw) - 1), true)) /* skip spaces */
/* Similar to LOOKING_AT but does not use notinname, does not skip */
#define LOOKING_AT_NOCASE(cp, kw) /* the keyword is a literal string */ \
((assert ("" kw), true) /* syntax error if not a literal string */ \
&& strncaseeq ((cp), kw, sizeof (kw)-1) /* cp points at kw */ \
- && ((cp) += sizeof (kw)-1)) /* skip spaces */
+ && ((cp) += sizeof (kw) - 1, true)) /* skip spaces */
/*
* Read a file, but do no processing. This is used to do regexp
continue; /* nothing found */
pos = strchr (sp, ':');
if (pos && pos < cp && pos[1] == ':')
- /* The name is already qualified. */
- make_tag (sp, cp - sp, true,
- lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
- else
+ {
+ /* The name is already qualified. */
+ if (!class_qualify)
+ {
+ char *q = pos + 2, *qpos;
+ while ((qpos = strchr (q, ':')) != NULL
+ && qpos < cp
+ && qpos[1] == ':')
+ q = qpos + 2;
+ sp = q;
+ }
+ make_tag (sp, cp - sp, true,
+ lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
+ }
+ else if (class_qualify)
/* Qualify it. */
{
char savechar, *name;
lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
free (name);
}
+ else
+ make_tag (sp, cp - sp, true,
+ lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
}
else if (LOOKING_AT (cp, "use constant")
|| LOOKING_AT (cp, "use constant::defer"))
Ruby_functions (FILE *inf)
{
char *cp = NULL;
+ bool reader = false, writer = false, alias = false, continuation = false;
LOOP_ON_INPUT_LINES (inf, lb, cp)
{
char *name;
cp = skip_spaces (cp);
- if (c_isalpha (*cp) && c_isupper (*cp)) /* constants */
+ if (!continuation
+ /* Constants. */
+ && c_isalpha (*cp) && c_isupper (*cp))
{
char *bp, *colon = NULL;
}
}
}
- else if ((is_method = LOOKING_AT (cp, "def")) /* module/class/method */
- || (is_class = LOOKING_AT (cp, "class"))
- || LOOKING_AT (cp, "module"))
+ else if (!continuation
+ /* Modules, classes, methods. */
+ && ((is_method = LOOKING_AT (cp, "def"))
+ || (is_class = LOOKING_AT (cp, "class"))
+ || LOOKING_AT (cp, "module")))
{
const char self_name[] = "self.";
const size_t self_size1 = sizeof (self_name) - 1;
else
{
/* Tag accessors and aliases. */
+
+ if (!continuation)
+ reader = writer = alias = false;
+
while (*cp && *cp != '#')
{
- bool reader = false, writer = false, alias = false;
-
- if (LOOKING_AT (cp, "attr_reader"))
- reader = true;
- else if (LOOKING_AT (cp, "attr_writer"))
- writer = true;
- else if (LOOKING_AT (cp, "attr_accessor"))
+ if (!continuation)
{
- reader = true;
- writer = true;
+ reader = writer = alias = false;
+ if (LOOKING_AT (cp, "attr_reader"))
+ reader = true;
+ else if (LOOKING_AT (cp, "attr_writer"))
+ writer = true;
+ else if (LOOKING_AT (cp, "attr_accessor"))
+ {
+ reader = true;
+ writer = true;
+ }
+ else if (LOOKING_AT (cp, "alias_method"))
+ alias = true;
}
- else if (LOOKING_AT (cp, "alias_method"))
- alias = true;
if (reader || writer || alias)
{
do {
- char *np = cp;
+ char *np;
- if (*np == ':')
- np++;
+ cp = skip_spaces (cp);
+ if (*cp == '(')
+ cp = skip_spaces (cp + 1);
+ np = cp;
cp = skip_name (cp);
+ if (*np != ':')
+ continue;
+ np++;
if (reader)
- make_tag (np, cp - np, true,
- lb.buffer, cp - lb.buffer + 1,
- lineno, linecharno);
+ {
+ make_tag (np, cp - np, true,
+ lb.buffer, cp - lb.buffer + 1,
+ lineno, linecharno);
+ continuation = false;
+ }
if (writer)
{
size_t name_len = cp - np + 1;
memcpy (wr_name + name_len - 1, "=", 2);
pfnote (wr_name, true, lb.buffer, cp - lb.buffer + 1,
lineno, linecharno);
+ continuation = false;
}
if (alias)
{
- make_tag (np, cp - np, true,
- lb.buffer, cp - lb.buffer + 1,
- lineno, linecharno);
+ if (!continuation)
+ make_tag (np, cp - np, true,
+ lb.buffer, cp - lb.buffer + 1,
+ lineno, linecharno);
+ continuation = false;
while (*cp && *cp != '#' && *cp != ';')
- cp++;
+ {
+ if (*cp == ',')
+ continuation = true;
+ else if (!c_isspace (*cp))
+ continuation = false;
+ cp++;
+ }
+ if (*cp == ';')
+ continuation = false;
}
- } while (*cp == ','
+ cp = skip_spaces (cp);
+ } while ((alias
+ ? (*cp == ',')
+ : (continuation = (*cp == ',')))
&& (cp = skip_spaces (cp + 1), *cp && *cp != '#'));
}
- cp = skip_name (cp);
+ if (*cp != '#')
+ cp = skip_name (cp);
while (*cp && *cp != '#' && notinname (*cp))
cp++;
}