sml.c

来自「ctags-5.5.4.tar.gz,一个很好的代码开发以及编辑源码」· C语言 代码 · 共 212 行

C
212
字号
/**   $Id: sml.c,v 1.6 2004/02/17 05:01:45 darren Exp $**   Copyright (c) 2002, Venkatesh Prasad Ranganath and 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 SML language files.*//* *   INCLUDE FILES */#include "general.h"	/* must always come first */#include <string.h>#include "entry.h"#include "parse.h"#include "read.h"#include "vstring.h"/* *   DATA DECLARATIONS */typedef enum {    K_AND = -2,    K_NONE = -1,    K_EXCEPTION,    K_FUNCTION,    K_FUNCTOR,    K_SIGNATURE,    K_STRUCTURE,    K_TYPE,    K_VAL} smlKind;/* *   DATA DEFINITIONS */static kindOption SmlKinds[] = {    { TRUE, 'e', "exception", "exception declarations" },    { TRUE, 'f', "function",  "function definitions" },    { TRUE, 'c', "functor",   "functor definitions" },    { TRUE, 's', "signature", "signature declarations" },    { TRUE, 'r', "structure", "structure declarations" },    { TRUE, 't', "type",      "type definitions" },    { TRUE, 'v', "value",     "value bindings" }};static struct {    const char *keyword;    smlKind kind;} SmlKeywordTypes [] = {    { "abstype",   K_TYPE      },    { "and",       K_AND       },    { "datatype",  K_TYPE      },    { "exception", K_EXCEPTION },    { "functor",   K_FUNCTOR   },    { "fun",       K_FUNCTION  },    { "signature", K_SIGNATURE },    { "structure", K_STRUCTURE },    { "type",      K_TYPE      },    { "val",       K_VAL       }};static unsigned int CommentLevel = 0;/* * FUNCTION DEFINITIONS */static void makeSmlTag (smlKind type, vString *name){    tagEntryInfo tag;    initTagEntry (&tag, vStringValue (name));    tag.kindName = SmlKinds [type].name;    tag.kind = SmlKinds [type].letter;    makeTagEntry (&tag);}static const unsigned char *skipSpace (const unsigned char *cp){    while (isspace ((int) *cp))	++cp;    return cp;}static boolean isIdentifier (int c){    boolean result = FALSE;    /* Consider '_' as an delimiter to aid user in tracking it's usage. */    const char *const alternateIdentifiers = "!%&$#+-<>=/?@\\~'^|*_";    if (isalnum (c))	result = TRUE;    else if (c != '\0'  &&  strchr (alternateIdentifiers, c) != NULL)	result = TRUE;    return result;}static const unsigned char *parseIdentifier (	const unsigned char *cp, vString *const identifier){    boolean stringLit = FALSE;    vStringClear (identifier);    while (*cp != '\0'  &&  (!isIdentifier ((int) *cp) || stringLit))    {	int oneback = *cp;	cp++;	if (oneback == '('  &&  *cp == '*'  &&  stringLit == FALSE)	{	    CommentLevel++;	    return ++cp;	}	if (*cp == '"' && oneback != '\\')	{	    stringLit = TRUE;	    continue;	}	if (stringLit && *cp == '"' && oneback != '\\')	    stringLit = FALSE;    }    if (strcmp ((const char *) cp, "") == 0 || cp == NULL)	return cp;    while (isIdentifier ((int) *cp))    {	vStringPut (identifier, (int) *cp);	cp++;    }    vStringTerminate (identifier);    return cp;}static smlKind findNextIdentifier (const unsigned char **cp){    smlKind result = K_NONE;    vString *const identifier = vStringNew ();    unsigned int count = sizeof (SmlKeywordTypes) / sizeof (SmlKeywordTypes [0]);    unsigned int i;    *cp = parseIdentifier (*cp, identifier);    for (i = 0  ;  i < count  &&  result == K_NONE ;  ++i)    {	const char *id = vStringValue (identifier);	if (strcmp (id, SmlKeywordTypes [i].keyword) == 0)	    result = SmlKeywordTypes [i].kind;    }    return result;}static void findSmlTags (void){    vString *const identifier = vStringNew ();    const unsigned char *line;    smlKind lastTag = K_NONE;    while ((line = fileReadLine ()) != NULL)    {	const unsigned char *cp = skipSpace (line);	do	{	    smlKind foundTag;	    if (CommentLevel != 0)	    {		cp = (const unsigned char *) strstr ((const char *) cp, "*)");		if (cp == NULL)		    continue;		else		{		    --CommentLevel;		    cp += 2;		}	    }	    foundTag = findNextIdentifier (&cp);	    if (foundTag != K_NONE)	    {		cp = skipSpace (cp);		cp = parseIdentifier (cp, identifier);		if (foundTag == K_AND)		    makeSmlTag (lastTag, identifier);		else		{		    makeSmlTag (foundTag, identifier);		    lastTag = foundTag;		}	    }	    if (strstr ((const char *) cp, "(*") != NULL)	    {		cp += 2;		cp = (const unsigned char *) strstr ((const char *) cp, "*)");		if (cp == NULL)		    ++CommentLevel;	    }	} while (cp != NULL  &&  strcmp ((const char *) cp, "") != 0);    }    vStringDelete (identifier);}extern parserDefinition *SmlParser (void){    static const char *const extensions[] = { "sml", "sig", NULL };    parserDefinition *def = parserNew ("SML");    def->kinds = SmlKinds;    def->kindCount = KIND_COUNT (SmlKinds);    def->extensions = extensions;    def->parser = findSmlTags;    return def;}/* vi:set tabstop=8 shiftwidth=4: */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?