2 * $Id: beta.c 536 2007-06-02 06:09:00Z elliotth $
4 * Copyright (c) 1999-2000, MjĂžlner Informatics
6 * Written by Erik Corry <corry@mjolner.dk>
8 * This source code is released for free distribution under the terms of the
9 * GNU General Public License.
11 * This module contains functions for generating tags for BETA language
18 #include "general.h" /* must always come first */
31 #define isbident(c) (identarray [(unsigned char) (c)])
37 K_FRAGMENT
, K_PATTERN
, K_SLOT
, K_VIRTUAL
40 static kindOption BetaKinds
[] = {
41 { TRUE
, 'f', "fragment", "fragment definitions"},
42 { FALSE
, 'p', "pattern", "all patterns"},
43 { TRUE
, 's', "slot", "slots (fragment uses)"},
44 { TRUE
, 'v', "virtual", "patterns (virtual or rebound)"}
48 static const char identarray
[256] = {
49 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0-15 */
50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16-31 */
51 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 32-47 !"#$%&'()*+'-./ */
52 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 48-63 0123456789:;<=>? */
53 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 64-79 @ABCDEFGHIJKLMNO */
54 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 80-95 PQRSTUVWXYZ [\]^_ */
55 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 96-111 `abcdefghijklmno */
56 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 112-127 pqrstuvwxyz{|}~ */
57 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128- */
58 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* -255 */
67 * FUNCTION DEFINITIONS
70 static void makeBetaTag (const char* const name
, const betaKind kind
)
72 if (BetaKinds
[kind
].enabled
)
75 initTagEntry (&e
, name
);
76 e
.kindName
= BetaKinds
[kind
].name
;
77 e
.kind
= BetaKinds
[kind
].letter
;
82 static void findBetaTags (void)
84 vString
*line
= vStringNew ();
85 boolean incomment
= FALSE
;
86 boolean inquote
= FALSE
;
87 boolean dovirtuals
= BetaKinds
[K_VIRTUAL
].enabled
;
88 boolean dopatterns
= BetaKinds
[K_PATTERN
].enabled
;
92 boolean foundfragmenthere
= FALSE
;
93 /* find fragment definition (line that starts and ends with --) */
100 while ((c
= fileGetc ()) != EOF
&& c
!= '\n' && c
!= '\r')
101 vStringPut (line
, c
);
103 vStringTerminate (line
);
105 last
= vStringLength (line
) - 1;
107 /* skip white space at start and end of line */
108 while (last
&& isspace ((int) vStringChar (line
, last
))) last
--;
109 while (first
< last
&& isspace ((int) vStringChar (line
, first
))) first
++;
110 /* if line still has a reasonable length and ... */
111 if (last
- first
> 4 &&
112 (vStringChar (line
, first
) == '-' &&
113 vStringChar (line
, first
+ 1) == '-' &&
114 vStringChar (line
, last
) == '-' &&
115 vStringChar (line
, last
- 1) == '-'))
117 if (!incomment
&& !inquote
)
119 foundfragmenthere
= TRUE
;
120 /* skip past -- and whitespace. Also skip back past 'dopart'
121 or 'attributes' to the :. We have to do this because there
122 is no sensible way to include whitespace in a ctags token
123 so the conventional space after the ':' would mess us up */
126 while (last
&& vStringChar (line
, last
) != ':') last
--;
127 while (last
&& (isspace ((int) vStringChar (line
, last
-1)))) last
--;
128 while (first
< last
&&
129 (isspace ((int) vStringChar (line
, first
)) ||
130 vStringChar (line
, first
) == '-'))
132 /* If there's anything left it is a fragment title */
133 if (first
< last
- 1)
135 vStringChar (line
, last
) = 0;
136 if (strcasecmp ("LIB", vStringValue (line
) + first
) &&
137 strcasecmp ("PROGRAM", vStringValue (line
) + first
))
139 makeBetaTag (vStringValue (line
) + first
, K_FRAGMENT
);
145 int len
= vStringLength (line
);
146 if (inquote
) goto stringtext
;
147 if (incomment
) goto commenttext
;
149 for ( ; pos
< len
; pos
++)
151 if (vStringChar (line
, pos
) == '\'')
157 if (vStringChar (line
, pos
) == '{')
163 if (vStringChar (line
, pos
) == '(' && pos
< len
- 1 &&
164 vStringChar (line
, pos
+1) == '*')
171 * SLOT definition looks like this:
172 * <<SLOT nameofslot: dopart>>
174 * <<SLOT nameofslot: descriptor>>
176 if (!foundfragmenthere
&&
177 vStringChar (line
, pos
) == '<' &&
179 vStringChar (line
, pos
+1) == '<' &&
180 strstr (vStringValue (line
) + pos
, ">>"))
182 /* Found slot name, get start and end */
185 pos
+= 2; /* skip past << */
186 /* skip past space before SLOT */
187 while (pos
< len
&& isspace ((int) vStringChar (line
, pos
)))
191 !strncasecmp (vStringValue(line
) + pos
, "SLOT", (size_t)4))
193 /* skip past space after SLOT */
194 while (pos
< len
&& isspace ((int) vStringChar (line
, pos
)))
197 /* skip to end of name */
198 while (eoname
< len
&&
199 (c2
= vStringChar (line
, eoname
)) != '>' &&
205 vStringChar (line
, eoname
) = 0;
206 if (strcasecmp ("LIB", vStringValue (line
) + pos
) &&
207 strcasecmp ("PROGRAM", vStringValue (line
) + pos
) &&
208 strcasecmp ("SLOT", vStringValue (line
) + pos
))
210 makeBetaTag (vStringValue (line
) + pos
, K_SLOT
);
213 if (eoname
+1 < len
) {
220 /* Only patterns that are virtual, extensions of virtuals or
221 * final bindings are normally included so as not to overload
223 * That means one of the forms name:: name:< or name::<
225 if (!foundfragmenthere
&&
226 vStringChar (line
, pos
) == ':' &&
229 (vStringChar (line
, pos
+1) == ':' ||
230 vStringChar (line
, pos
+1) == '<')
235 /* Found pattern name, get start and end */
238 while (eoname
&& isspace ((int) vStringChar (line
, eoname
-1)))
241 /* terminate right after name */
242 vStringChar (line
, eoname
) = 0;
245 isbident (vStringChar (line
, soname
-1)))
249 if (soname
!= eoname
)
251 makeBetaTag (vStringValue (line
) + soname
, K_PATTERN
);
252 /* scan back past white space */
254 isspace ((int) vStringChar (line
, soname
-1)))
256 if (soname
&& vStringChar (line
, soname
-1) == ',')
258 /* we found a new pattern name before comma */
260 goto foundanothername
;
267 for ( ; pos
< len
; pos
++)
269 if (vStringChar (line
, pos
) == '*' && pos
< len
- 1 &&
270 vStringChar (line
, pos
+1) == ')')
276 if (vStringChar (line
, pos
) == '}')
285 for ( ; pos
< len
; pos
++)
287 if (vStringChar (line
, pos
) == '\\')
289 if (pos
< len
- 1) pos
++;
291 else if (vStringChar (line
, pos
) == '\'')
294 /* support obsolete '' syntax */
295 if (pos
< len
&& vStringChar (line
, pos
) == '\'')
305 inquote
= FALSE
; /* This shouldn't really make a difference */
306 } while (!feof (File
.fp
));
307 vStringDelete (line
);
310 extern parserDefinition
* BetaParser (void)
312 static const char *const extensions
[] = { "bet", NULL
};
313 parserDefinition
* def
= parserNew ("BETA");
314 def
->kinds
= BetaKinds
;
315 def
->kindCount
= KIND_COUNT (BetaKinds
);
316 def
->extensions
= extensions
;
317 def
->parser
= findBetaTags
;
321 /* vi:set tabstop=4 shiftwidth=4: */