Updated Spanish translation
[anjuta-git-plugin.git] / tagmanager / sml.c
blob90ef40832197c2f6900636ea4c04b5fef98ffc52
1 /*
2 * $Id$
4 * Copyright (c) 2002, Venkatesh Prasad Ranganath and Darren Hiebert
6 * This source code is released for free distribution under the terms of the
7 * GNU General Public License.
9 * This module contains functions for generating tags for SML language files.
13 * INCLUDE FILES
15 #include "general.h" /* must always come first */
17 #include <string.h>
19 #include "entry.h"
20 #include "parse.h"
21 #include "read.h"
22 #include "vstring.h"
25 * DATA DECLARATIONS
27 typedef enum {
28 K_AND = -2,
29 K_NONE = -1,
30 K_EXCEPTION,
31 K_FUNCTION,
32 K_FUNCTOR,
33 K_SIGNATURE,
34 K_STRUCTURE,
35 K_TYPE,
36 K_VAL
37 } smlKind;
40 * DATA DEFINITIONS
42 static kindOption SmlKinds[] = {
43 { TRUE, 'e', "exception", "exception declarations" },
44 { TRUE, 'f', "function", "function definitions" },
45 { TRUE, 'c', "functor", "functor definitions" },
46 { TRUE, 's', "signature", "signature declarations" },
47 { TRUE, 'r', "structure", "structure declarations" },
48 { TRUE, 't', "type", "type definitions" },
49 { TRUE, 'v', "value", "value bindings" }
52 static struct {
53 const char *keyword;
54 smlKind kind;
55 } SmlKeywordTypes [] = {
56 { "abstype", K_TYPE },
57 { "and", K_AND },
58 { "datatype", K_TYPE },
59 { "exception", K_EXCEPTION },
60 { "functor", K_FUNCTOR },
61 { "fun", K_FUNCTION },
62 { "signature", K_SIGNATURE },
63 { "structure", K_STRUCTURE },
64 { "type", K_TYPE },
65 { "val", K_VAL }
68 static unsigned int CommentLevel = 0;
71 * FUNCTION DEFINITIONS
74 static void makeSmlTag (smlKind type, vString *name)
76 tagEntryInfo tag;
77 initTagEntry (&tag, vStringValue (name));
78 tag.kindName = SmlKinds [type].name;
79 tag.kind = SmlKinds [type].letter;
80 makeTagEntry (&tag);
83 static const unsigned char *skipSpace (const unsigned char *cp)
85 while (isspace ((int) *cp))
86 ++cp;
87 return cp;
90 static boolean isIdentifier (int c)
92 boolean result = FALSE;
93 /* Consider '_' as an delimiter to aid user in tracking it's usage. */
94 const char *const alternateIdentifiers = "!%&$#+-<>=/?@\\~'^|*_";
95 if (isalnum (c))
96 result = TRUE;
97 else if (c != '\0' && strchr (alternateIdentifiers, c) != NULL)
98 result = TRUE;
99 return result;
102 static const unsigned char *parseIdentifier (
103 const unsigned char *cp, vString *const identifier)
105 boolean stringLit = FALSE;
106 vStringClear (identifier);
107 while (*cp != '\0' && (!isIdentifier ((int) *cp) || stringLit))
109 int oneback = *cp;
110 cp++;
111 if (oneback == '(' && *cp == '*' && stringLit == FALSE)
113 CommentLevel++;
114 return ++cp;
116 if (*cp == '"' && oneback != '\\')
118 stringLit = TRUE;
119 continue;
121 if (stringLit && *cp == '"' && oneback != '\\')
122 stringLit = FALSE;
124 if (strcmp ((const char *) cp, "") == 0 || cp == NULL)
125 return cp;
127 while (isIdentifier ((int) *cp))
129 vStringPut (identifier, (int) *cp);
130 cp++;
132 vStringTerminate (identifier);
133 return cp;
136 static smlKind findNextIdentifier (const unsigned char **cp)
138 smlKind result = K_NONE;
139 vString *const identifier = vStringNew ();
140 unsigned int count = sizeof (SmlKeywordTypes) / sizeof (SmlKeywordTypes [0]);
141 unsigned int i;
142 *cp = parseIdentifier (*cp, identifier);
143 for (i = 0 ; i < count && result == K_NONE ; ++i)
145 const char *id = vStringValue (identifier);
146 if (strcmp (id, SmlKeywordTypes [i].keyword) == 0)
147 result = SmlKeywordTypes [i].kind;
149 return result;
152 static void findSmlTags (void)
154 vString *const identifier = vStringNew ();
155 const unsigned char *line;
156 smlKind lastTag = K_NONE;
158 while ((line = fileReadLine ()) != NULL)
160 const unsigned char *cp = skipSpace (line);
163 smlKind foundTag;
164 if (CommentLevel != 0)
166 cp = (const unsigned char *) strstr ((const char *) cp, "*)");
167 if (cp == NULL)
168 continue;
169 else
171 --CommentLevel;
172 cp += 2;
175 foundTag = findNextIdentifier (&cp);
176 if (foundTag != K_NONE)
178 cp = skipSpace (cp);
179 cp = parseIdentifier (cp, identifier);
180 if (foundTag == K_AND)
181 makeSmlTag (lastTag, identifier);
182 else
184 makeSmlTag (foundTag, identifier);
185 lastTag = foundTag;
188 if (strstr ((const char *) cp, "(*") != NULL)
190 cp += 2;
191 cp = (const unsigned char *) strstr ((const char *) cp, "*)");
192 if (cp == NULL)
193 ++CommentLevel;
195 } while (cp != NULL && strcmp ((const char *) cp, "") != 0);
197 vStringDelete (identifier);
200 extern parserDefinition *SmlParser (void)
202 static const char *const extensions[] = { "sml", "sig", NULL };
203 parserDefinition *def = parserNew ("SML");
204 def->kinds = SmlKinds;
205 def->kindCount = KIND_COUNT (SmlKinds);
206 def->extensions = extensions;
207 def->parser = findSmlTags;
208 return def;
211 /* vi:set tabstop=4 shiftwidth=4: */