cosmopolitan/third_party/ctags/lisp.c
2022-11-13 13:26:28 -08:00

141 lines
2.9 KiB
C

// clang-format off
/*
* $Id: lisp.c 717 2009-07-07 03:40:50Z dhiebert $
*
* Copyright (c) 2000-2002, 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 LISP files.
*/
/*
* INCLUDE FILES
*/
#include "third_party/ctags/general.h" /* must always come first */
#include "third_party/ctags/parse.h"
#include "third_party/ctags/read.h"
#include "third_party/ctags/vstring.h"
/*
* DATA DEFINITIONS
*/
typedef enum {
K_FUNCTION
} lispKind;
static kindOption LispKinds [] = {
{ TRUE, 'f', "function", "functions" }
};
/*
* FUNCTION DEFINITIONS
*/
/*
* lisp tag functions
* look for (def or (DEF, quote or QUOTE
*/
static int L_isdef (const unsigned char *strp)
{
return ( (strp [1] == 'd' || strp [1] == 'D')
&& (strp [2] == 'e' || strp [2] == 'E')
&& (strp [3] == 'f' || strp [3] == 'F'));
}
static int L_isquote (const unsigned char *strp)
{
return ( (*(++strp) == 'q' || *strp == 'Q')
&& (*(++strp) == 'u' || *strp == 'U')
&& (*(++strp) == 'o' || *strp == 'O')
&& (*(++strp) == 't' || *strp == 'T')
&& (*(++strp) == 'e' || *strp == 'E')
&& isspace (*(++strp)));
}
static void L_getit (vString *const name, const unsigned char *dbp)
{
const unsigned char *p;
if (*dbp == '\'') /* Skip prefix quote */
dbp++;
else if (*dbp == '(' && L_isquote (dbp)) /* Skip "(quote " */
{
dbp += 7;
while (isspace (*dbp))
dbp++;
}
for (p=dbp ; *p!='\0' && *p!='(' && !isspace ((int) *p) && *p!=')' ; p++)
vStringPut (name, *p);
vStringTerminate (name);
if (vStringLength (name) > 0)
makeSimpleTag (name, LispKinds, K_FUNCTION);
vStringClear (name);
}
/* Algorithm adapted from from GNU etags.
*/
static void findLispTags (void)
{
vString *name = vStringNew ();
const unsigned char* p;
while ((p = fileReadLine ()) != NULL)
{
if (*p == '(')
{
if (L_isdef (p))
{
while (*p != '\0' && !isspace ((int) *p))
p++;
while (isspace ((int) *p))
p++;
L_getit (name, p);
}
else
{
/* Check for (foo::defmumble name-defined ... */
do
p++;
while (*p != '\0' && !isspace ((int) *p)
&& *p != ':' && *p != '(' && *p != ')');
if (*p == ':')
{
do
p++;
while (*p == ':');
if (L_isdef (p - 1))
{
while (*p != '\0' && !isspace ((int) *p))
p++;
while (isspace (*p))
p++;
L_getit (name, p);
}
}
}
}
}
vStringDelete (name);
}
extern parserDefinition* LispParser (void)
{
static const char *const extensions [] = {
"cl", "clisp", "el", "l", "lisp", "lsp", NULL
};
parserDefinition* def = parserNew ("Lisp");
def->kinds = LispKinds;
def->kindCount = KIND_COUNT (LispKinds);
def->extensions = extensions;
def->parser = findLispTags;
return def;
}
/* vi:set tabstop=4 shiftwidth=4: */