cosmopolitan/third_party/ctags/lisp.c

111 lines
2.9 KiB
C

/*
* $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 "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: */