1ebdab5e8SMasatake YAMATO /*
2ebdab5e8SMasatake YAMATO * Copyright (c) 2016, Masatake YAMATO
3ebdab5e8SMasatake YAMATO * Copyright (c) 2016, Red Hat, Inc.
4ebdab5e8SMasatake YAMATO *
5ebdab5e8SMasatake YAMATO * This source code is released for free distribution under the terms of the
6ebdab5e8SMasatake YAMATO * GNU General Public License version 2 or (at your option) any later version.
7ebdab5e8SMasatake YAMATO *
8ebdab5e8SMasatake YAMATO * This module contains functions for generating tags for DTD, data type
9ebdab5e8SMasatake YAMATO * definition explained in https://www.w3.org/TR/REC-xml/#sec-physical-struct
10ebdab5e8SMasatake YAMATO *
11ebdab5e8SMasatake YAMATO */
12ebdab5e8SMasatake YAMATO
13ebdab5e8SMasatake YAMATO #include "general.h"
14ebdab5e8SMasatake YAMATO #include "tokeninfo.h"
15ebdab5e8SMasatake YAMATO
16*3afb5475SMasatake YAMATO #include "debug.h"
17ebdab5e8SMasatake YAMATO #include "entry.h"
18ebdab5e8SMasatake YAMATO #include "keyword.h"
190d502ef0SMasatake YAMATO #include "parse.h"
20ebdab5e8SMasatake YAMATO #include "read.h"
21ebdab5e8SMasatake YAMATO #include "xtag.h"
22ebdab5e8SMasatake YAMATO
23ebdab5e8SMasatake YAMATO
24ebdab5e8SMasatake YAMATO static scopeSeparator DtdParameterEntrySeparators [] = {
25f92e6bf2SMasatake YAMATO { KIND_WILDCARD_INDEX, "/%" },
26ebdab5e8SMasatake YAMATO };
27ebdab5e8SMasatake YAMATO
28ebdab5e8SMasatake YAMATO static scopeSeparator DtdAttSeparators [] = {
29f92e6bf2SMasatake YAMATO { KIND_WILDCARD_INDEX, "/@" },
30ebdab5e8SMasatake YAMATO };
31ebdab5e8SMasatake YAMATO
32ebdab5e8SMasatake YAMATO typedef enum {
33ebdab5e8SMasatake YAMATO DTD_PARAMETER_ENTITY_ELEMENT_NAME,
34ebdab5e8SMasatake YAMATO DTD_PARAMETER_ENTITY_CONDITION,
35ebdab5e8SMasatake YAMATO DTD_PARAMETER_ENTITY_PART_OF_ATT_DEF,
36ebdab5e8SMasatake YAMATO } dtdEntityRole;
37ebdab5e8SMasatake YAMATO
3813457258SMasatake YAMATO static roleDefinition DtdEntityRoles [] = {
39ebdab5e8SMasatake YAMATO { true, "elementName", "element names" },
4026c671b5SMasatake YAMATO { true, "condition", "conditions" },
41ebdab5e8SMasatake YAMATO { true, "partOfAttDef", "part of attribute definition" },
42ebdab5e8SMasatake YAMATO };
43ebdab5e8SMasatake YAMATO
44ebdab5e8SMasatake YAMATO typedef enum {
45ebdab5e8SMasatake YAMATO DTD_ELEMENT_ATT_OWNER,
46ebdab5e8SMasatake YAMATO } dtdElementRole;
47ebdab5e8SMasatake YAMATO
4813457258SMasatake YAMATO static roleDefinition DtdElementRoles [] = {
49ebdab5e8SMasatake YAMATO { true, "attOwner", "attributes owner" },
50ebdab5e8SMasatake YAMATO };
51ebdab5e8SMasatake YAMATO
52ebdab5e8SMasatake YAMATO typedef enum {
53ebdab5e8SMasatake YAMATO K_ENTITY,
54ebdab5e8SMasatake YAMATO K_PARAMETER_ENTITY,
55ebdab5e8SMasatake YAMATO // K_EXTERNAL_ENTITY,
56ebdab5e8SMasatake YAMATO // K_UNPARSED_ENTITY,
57ebdab5e8SMasatake YAMATO K_ELEMENT,
58ebdab5e8SMasatake YAMATO K_ATTRIBUTE,
59ebdab5e8SMasatake YAMATO K_NOTATION,
60ebdab5e8SMasatake YAMATO } dtdKind;
61ebdab5e8SMasatake YAMATO
62e112e8abSMasatake YAMATO static kindDefinition DtdKinds [] = {
63ebdab5e8SMasatake YAMATO { true, 'E', "entity", "entities" },
64ebdab5e8SMasatake YAMATO { true, 'p', "parameterEntity", "parameter entities",
65ebdab5e8SMasatake YAMATO .referenceOnly = false, ATTACH_ROLES(DtdEntityRoles),
66ebdab5e8SMasatake YAMATO ATTACH_SEPARATORS(DtdParameterEntrySeparators),
67ebdab5e8SMasatake YAMATO },
68ebdab5e8SMasatake YAMATO // { true, 'X', "externalEntity", "external entities" },
69ebdab5e8SMasatake YAMATO // { true, 'U', "unparsedEntity", "unparsed entities" },
70ebdab5e8SMasatake YAMATO { true, 'e', "element", "elements",
71ebdab5e8SMasatake YAMATO .referenceOnly = false, ATTACH_ROLES(DtdElementRoles) },
72ebdab5e8SMasatake YAMATO { true, 'a', "attribute", "attributes",
73ebdab5e8SMasatake YAMATO ATTACH_SEPARATORS(DtdAttSeparators), },
74ebdab5e8SMasatake YAMATO { true, 'n', "notation", "notations" },
75ebdab5e8SMasatake YAMATO
76ebdab5e8SMasatake YAMATO };
77ebdab5e8SMasatake YAMATO
78ebdab5e8SMasatake YAMATO enum {
79ebdab5e8SMasatake YAMATO KEYWORD_ENTITY,
80ebdab5e8SMasatake YAMATO KEYWORD_ELEMENT,
81ebdab5e8SMasatake YAMATO KEYWORD_ATTLIST,
82ebdab5e8SMasatake YAMATO KEYWORD_INCLUDE,
83ebdab5e8SMasatake YAMATO KEYWORD_IGNORE,
84ebdab5e8SMasatake YAMATO // KEYWORD_PUBLIC,
85ebdab5e8SMasatake YAMATO // KEYWORD_SYSTEM,
86ebdab5e8SMasatake YAMATO KEYWORD_NOTATION,
87ebdab5e8SMasatake YAMATO KEYWORD_FIXED,
88ebdab5e8SMasatake YAMATO KEYWORD_ATTR_TYPES,
89ebdab5e8SMasatake YAMATO KEYWORD_ATTR_DEFAULT_DECLS,
90ebdab5e8SMasatake YAMATO };
91ebdab5e8SMasatake YAMATO
92ebdab5e8SMasatake YAMATO typedef int keywordId;
93ebdab5e8SMasatake YAMATO
94ebdab5e8SMasatake YAMATO static const keywordTable DtdKeywordTable[] = {
95ebdab5e8SMasatake YAMATO { "ENTITY", KEYWORD_ENTITY },
96ebdab5e8SMasatake YAMATO { "ELEMENT", KEYWORD_ELEMENT },
97ebdab5e8SMasatake YAMATO { "ATTLIST", KEYWORD_ATTLIST },
98ebdab5e8SMasatake YAMATO { "INCLUDE", KEYWORD_INCLUDE },
99ebdab5e8SMasatake YAMATO { "IGNORE", KEYWORD_IGNORE },
100ebdab5e8SMasatake YAMATO // { "PUBLIC", KEYWORD_PUBLIC },
101ebdab5e8SMasatake YAMATO // { "SYSTEM", KEYWORD_SYSTEM },
102ebdab5e8SMasatake YAMATO { "NOTATION", KEYWORD_NOTATION },
103ebdab5e8SMasatake YAMATO { "FIXED", KEYWORD_FIXED },
104ebdab5e8SMasatake YAMATO { "CDATA", KEYWORD_ATTR_TYPES },
105ebdab5e8SMasatake YAMATO { "ID", KEYWORD_ATTR_TYPES },
106ebdab5e8SMasatake YAMATO { "IDREF", KEYWORD_ATTR_TYPES },
107ebdab5e8SMasatake YAMATO { "IDREFS", KEYWORD_ATTR_TYPES },
108ebdab5e8SMasatake YAMATO { "ENTITIES", KEYWORD_ATTR_TYPES },
109ebdab5e8SMasatake YAMATO { "NMTOKEN", KEYWORD_ATTR_TYPES },
110ebdab5e8SMasatake YAMATO { "NMTOKENS", KEYWORD_ATTR_TYPES },
111ebdab5e8SMasatake YAMATO { "REQUIRED", KEYWORD_ATTR_DEFAULT_DECLS },
112ebdab5e8SMasatake YAMATO { "IMPLIED", KEYWORD_ATTR_DEFAULT_DECLS },
113ebdab5e8SMasatake YAMATO };
114ebdab5e8SMasatake YAMATO
115ebdab5e8SMasatake YAMATO enum eTokenType {
116ebdab5e8SMasatake YAMATO /* 0..255 are the byte's value */
117ebdab5e8SMasatake YAMATO TOKEN_CLOSE = '>',
118ebdab5e8SMasatake YAMATO TOKEN_EOF = 256,
119ebdab5e8SMasatake YAMATO TOKEN_UNDEFINED,
120ebdab5e8SMasatake YAMATO TOKEN_KEYWORD,
121ebdab5e8SMasatake YAMATO TOKEN_IDENTIFIER,
122ebdab5e8SMasatake YAMATO TOKEN_OPEN, /* <! */
123ebdab5e8SMasatake YAMATO TOKEN_STRING,
124ebdab5e8SMasatake YAMATO };
125ebdab5e8SMasatake YAMATO
126ebdab5e8SMasatake YAMATO static void readToken (tokenInfo *const token, void *data CTAGS_ATTR_UNUSED);
127ebdab5e8SMasatake YAMATO static void clearToken (tokenInfo *token);
128ebdab5e8SMasatake YAMATO static void copyToken (tokenInfo *dest, tokenInfo *src, void *data CTAGS_ATTR_UNUSED);
129ebdab5e8SMasatake YAMATO
130002dd246SMasatake YAMATO typedef struct sDtdToken {
131002dd246SMasatake YAMATO tokenInfo base;
132ebdab5e8SMasatake YAMATO int scopeIndex;
133002dd246SMasatake YAMATO } dtdToken;
134002dd246SMasatake YAMATO
135002dd246SMasatake YAMATO #define DTD(TOKEN) ((dtdToken *)TOKEN)
136ebdab5e8SMasatake YAMATO
137ebdab5e8SMasatake YAMATO static struct tokenInfoClass dtdTokenInfoClass = {
138ebdab5e8SMasatake YAMATO .nPreAlloc = 16,
139ebdab5e8SMasatake YAMATO .typeForUndefined = TOKEN_UNDEFINED,
140ebdab5e8SMasatake YAMATO .keywordNone = KEYWORD_NONE,
141ebdab5e8SMasatake YAMATO .typeForKeyword = TOKEN_KEYWORD,
142ebdab5e8SMasatake YAMATO .typeForEOF = TOKEN_EOF,
143002dd246SMasatake YAMATO .extraSpace = sizeof (dtdToken) - sizeof (tokenInfo),
144ebdab5e8SMasatake YAMATO .read = readToken,
145ebdab5e8SMasatake YAMATO .clear = clearToken,
146ebdab5e8SMasatake YAMATO .copy = copyToken,
147ebdab5e8SMasatake YAMATO };
148ebdab5e8SMasatake YAMATO
149ebdab5e8SMasatake YAMATO static langType Lang_dtd;
150ebdab5e8SMasatake YAMATO
151ebdab5e8SMasatake YAMATO #define isIdentifierChar(c) (isalnum (c) || c == '-' || c == '_' || c == '.' \
152ebdab5e8SMasatake YAMATO || c == ':')
153ebdab5e8SMasatake YAMATO
newDtdToken(void)154ebdab5e8SMasatake YAMATO static tokenInfo *newDtdToken (void)
155ebdab5e8SMasatake YAMATO {
156ebdab5e8SMasatake YAMATO return newToken (&dtdTokenInfoClass);
157ebdab5e8SMasatake YAMATO }
158ebdab5e8SMasatake YAMATO
clearToken(tokenInfo * token)159ebdab5e8SMasatake YAMATO static void clearToken (tokenInfo *token)
160ebdab5e8SMasatake YAMATO {
161002dd246SMasatake YAMATO DTD (token)->scopeIndex = CORK_NIL;
162ebdab5e8SMasatake YAMATO }
163ebdab5e8SMasatake YAMATO
copyToken(tokenInfo * dest,tokenInfo * src,void * data CTAGS_ATTR_UNUSED)164ebdab5e8SMasatake YAMATO static void copyToken (tokenInfo *dest, tokenInfo *src, void *data CTAGS_ATTR_UNUSED)
165ebdab5e8SMasatake YAMATO {
166002dd246SMasatake YAMATO DTD (dest)->scopeIndex = DTD (src)->scopeIndex;
167ebdab5e8SMasatake YAMATO }
168ebdab5e8SMasatake YAMATO
readToken(tokenInfo * const token,void * data CTAGS_ATTR_UNUSED)169ebdab5e8SMasatake YAMATO static void readToken (tokenInfo *const token, void *data CTAGS_ATTR_UNUSED)
170ebdab5e8SMasatake YAMATO {
171ebdab5e8SMasatake YAMATO int c, c0;
172ebdab5e8SMasatake YAMATO
173ebdab5e8SMasatake YAMATO token->type = TOKEN_UNDEFINED;
174ebdab5e8SMasatake YAMATO token->keyword = KEYWORD_NONE;
175ebdab5e8SMasatake YAMATO vStringClear (token->string);
176ebdab5e8SMasatake YAMATO
177ebdab5e8SMasatake YAMATO retry:
178ebdab5e8SMasatake YAMATO do {
179ebdab5e8SMasatake YAMATO c = getcFromInputFile ();
180ebdab5e8SMasatake YAMATO } while (c == ' ' || c == '\t' || c == '\f' || c == '\n');
181ebdab5e8SMasatake YAMATO
182ebdab5e8SMasatake YAMATO token->lineNumber = getInputLineNumber ();
183ebdab5e8SMasatake YAMATO token->filePosition = getInputFilePosition ();
184ebdab5e8SMasatake YAMATO
185ebdab5e8SMasatake YAMATO switch (c)
186ebdab5e8SMasatake YAMATO {
187ebdab5e8SMasatake YAMATO case EOF:
188ebdab5e8SMasatake YAMATO token->type = TOKEN_EOF;
189ebdab5e8SMasatake YAMATO break;
190ebdab5e8SMasatake YAMATO case ';':
191ebdab5e8SMasatake YAMATO case '&':
192ebdab5e8SMasatake YAMATO case '%':
193ebdab5e8SMasatake YAMATO case '>':
194ebdab5e8SMasatake YAMATO case '#':
195ebdab5e8SMasatake YAMATO case '?':
196ebdab5e8SMasatake YAMATO case '[':
197ebdab5e8SMasatake YAMATO case ']':
198ebdab5e8SMasatake YAMATO case '|':
199ebdab5e8SMasatake YAMATO case ',':
200ebdab5e8SMasatake YAMATO case '(':
201ebdab5e8SMasatake YAMATO case ')':
202ebdab5e8SMasatake YAMATO case '+':
203ebdab5e8SMasatake YAMATO token->type = c;
204ebdab5e8SMasatake YAMATO break;
205ebdab5e8SMasatake YAMATO case '<':
206ebdab5e8SMasatake YAMATO c0 = getcFromInputFile();
207ebdab5e8SMasatake YAMATO if (c0 == '!')
208ebdab5e8SMasatake YAMATO {
209ebdab5e8SMasatake YAMATO token->type = TOKEN_OPEN;
210ebdab5e8SMasatake YAMATO break;
211ebdab5e8SMasatake YAMATO }
212ebdab5e8SMasatake YAMATO else
213ebdab5e8SMasatake YAMATO {
214ebdab5e8SMasatake YAMATO ungetcToInputFile (c0);
215ebdab5e8SMasatake YAMATO token->type = c;
216ebdab5e8SMasatake YAMATO break;
217ebdab5e8SMasatake YAMATO }
218ebdab5e8SMasatake YAMATO case '-':
219ebdab5e8SMasatake YAMATO c0 = getcFromInputFile();
220ebdab5e8SMasatake YAMATO if (c0 == '-')
221ebdab5e8SMasatake YAMATO {
222ebdab5e8SMasatake YAMATO int c1, c2;
223ebdab5e8SMasatake YAMATO
224ebdab5e8SMasatake YAMATO while ( (c1 = getcFromInputFile()) != EOF )
225ebdab5e8SMasatake YAMATO {
226ebdab5e8SMasatake YAMATO if (c1 == '-')
227ebdab5e8SMasatake YAMATO {
228ebdab5e8SMasatake YAMATO c2 = getcFromInputFile();
229ebdab5e8SMasatake YAMATO if (c2 == '-' || c2 == EOF)
230ebdab5e8SMasatake YAMATO goto retry;
231ebdab5e8SMasatake YAMATO }
232ebdab5e8SMasatake YAMATO }
233ebdab5e8SMasatake YAMATO }
234ebdab5e8SMasatake YAMATO else
235ebdab5e8SMasatake YAMATO {
236ebdab5e8SMasatake YAMATO ungetcToInputFile (c0);
237ebdab5e8SMasatake YAMATO token->type = c;
238ebdab5e8SMasatake YAMATO }
239ebdab5e8SMasatake YAMATO break;
240ebdab5e8SMasatake YAMATO case '"':
241ebdab5e8SMasatake YAMATO case '\'':
242ebdab5e8SMasatake YAMATO token->type = TOKEN_STRING;
243ebdab5e8SMasatake YAMATO while ((c0 = getcFromInputFile ()))
244ebdab5e8SMasatake YAMATO {
245ebdab5e8SMasatake YAMATO if (c0 == EOF || c0 == c)
246ebdab5e8SMasatake YAMATO break;
247ebdab5e8SMasatake YAMATO else
248ebdab5e8SMasatake YAMATO tokenPutc(token, c0);
249ebdab5e8SMasatake YAMATO }
250ebdab5e8SMasatake YAMATO break;
251ebdab5e8SMasatake YAMATO default:
252ebdab5e8SMasatake YAMATO if (isIdentifierChar(c))
253ebdab5e8SMasatake YAMATO {
254ebdab5e8SMasatake YAMATO tokenPutc(token, c);
255ebdab5e8SMasatake YAMATO while ((c = getcFromInputFile ()))
256ebdab5e8SMasatake YAMATO {
257ebdab5e8SMasatake YAMATO if (isIdentifierChar(c))
258ebdab5e8SMasatake YAMATO tokenPutc(token, c);
259ebdab5e8SMasatake YAMATO else
260ebdab5e8SMasatake YAMATO {
261ebdab5e8SMasatake YAMATO ungetcToInputFile (c);
262ebdab5e8SMasatake YAMATO break;
263ebdab5e8SMasatake YAMATO }
264ebdab5e8SMasatake YAMATO }
265ebdab5e8SMasatake YAMATO token->keyword = lookupKeyword (vStringValue (token->string),
266ebdab5e8SMasatake YAMATO Lang_dtd);
267ebdab5e8SMasatake YAMATO if (token->keyword == KEYWORD_NONE)
268ebdab5e8SMasatake YAMATO token->type = TOKEN_IDENTIFIER;
269ebdab5e8SMasatake YAMATO else
270ebdab5e8SMasatake YAMATO token->type = TOKEN_KEYWORD;
271ebdab5e8SMasatake YAMATO
272ebdab5e8SMasatake YAMATO }
273ebdab5e8SMasatake YAMATO else
274ebdab5e8SMasatake YAMATO token->type = c;
275ebdab5e8SMasatake YAMATO break;
276ebdab5e8SMasatake YAMATO }
277ebdab5e8SMasatake YAMATO }
278ebdab5e8SMasatake YAMATO
makeDtdTagMaybe(tagEntryInfo * const e,tokenInfo * const token,int kind,int role)279ebdab5e8SMasatake YAMATO static int makeDtdTagMaybe (tagEntryInfo *const e, tokenInfo *const token,
280ebdab5e8SMasatake YAMATO int kind, int role)
281ebdab5e8SMasatake YAMATO {
28224b256e3SMasatake YAMATO if (role == ROLE_DEFINITION_INDEX)
283ebdab5e8SMasatake YAMATO {
284ebdab5e8SMasatake YAMATO if (! DtdKinds[kind].enabled)
285ebdab5e8SMasatake YAMATO return CORK_NIL;
286ebdab5e8SMasatake YAMATO }
287ebdab5e8SMasatake YAMATO else if (! (isXtagEnabled (XTAG_REFERENCE_TAGS)
288ebdab5e8SMasatake YAMATO && DtdKinds[kind].roles[role].enabled))
289ebdab5e8SMasatake YAMATO return CORK_NIL;
290ebdab5e8SMasatake YAMATO
291ebdab5e8SMasatake YAMATO initRefTagEntry (e, tokenString (token),
29216a2541cSMasatake YAMATO kind,
293ebdab5e8SMasatake YAMATO role);
294ebdab5e8SMasatake YAMATO e->lineNumber = token->lineNumber;
295ebdab5e8SMasatake YAMATO e->filePosition = token->filePosition;
296002dd246SMasatake YAMATO e->extensionFields.scopeIndex = DTD (token)->scopeIndex;
297ebdab5e8SMasatake YAMATO
298ebdab5e8SMasatake YAMATO return makeTagEntry (e);
299ebdab5e8SMasatake YAMATO }
300ebdab5e8SMasatake YAMATO
backpatchEndField(int index,unsigned long lineNumber)301*3afb5475SMasatake YAMATO static void backpatchEndField (int index, unsigned long lineNumber)
302ebdab5e8SMasatake YAMATO {
303ebdab5e8SMasatake YAMATO tagEntryInfo *ep = getEntryInCorkQueue (index);
304ebdab5e8SMasatake YAMATO
305ebdab5e8SMasatake YAMATO if (ep)
306ebdab5e8SMasatake YAMATO ep->extensionFields.endLine = lineNumber;
307ebdab5e8SMasatake YAMATO }
308ebdab5e8SMasatake YAMATO
parseEntity(tokenInfo * const token)309ebdab5e8SMasatake YAMATO static void parseEntity (tokenInfo *const token)
310ebdab5e8SMasatake YAMATO {
311ebdab5e8SMasatake YAMATO tagEntryInfo e;
312*3afb5475SMasatake YAMATO int index = CORK_NIL;
313ebdab5e8SMasatake YAMATO
314ebdab5e8SMasatake YAMATO tokenRead (token);
315ebdab5e8SMasatake YAMATO if (token->type == '%')
316ebdab5e8SMasatake YAMATO {
317ebdab5e8SMasatake YAMATO tokenRead (token);
318ebdab5e8SMasatake YAMATO if (tokenIsType(token, IDENTIFIER))
319ebdab5e8SMasatake YAMATO index = makeDtdTagMaybe (&e, token,
32024b256e3SMasatake YAMATO K_PARAMETER_ENTITY, ROLE_DEFINITION_INDEX);
321ebdab5e8SMasatake YAMATO }
322ebdab5e8SMasatake YAMATO else if (tokenIsType(token, IDENTIFIER))
323ebdab5e8SMasatake YAMATO index = makeDtdTagMaybe (&e, token,
32424b256e3SMasatake YAMATO K_ENTITY, ROLE_DEFINITION_INDEX);
325ebdab5e8SMasatake YAMATO
326ebdab5e8SMasatake YAMATO if (tokenSkipToType (token, TOKEN_CLOSE) && (index != CORK_NIL))
327ebdab5e8SMasatake YAMATO backpatchEndField (index, token->lineNumber);
328ebdab5e8SMasatake YAMATO }
329ebdab5e8SMasatake YAMATO
parserParameterEntityRef(tokenInfo * const token)330fa4d090aSMasatake YAMATO static tokenInfo *parserParameterEntityRef (tokenInfo *const token)
331ebdab5e8SMasatake YAMATO {
332ebdab5e8SMasatake YAMATO tokenRead (token);
333ebdab5e8SMasatake YAMATO if (tokenIsType(token, IDENTIFIER))
334ebdab5e8SMasatake YAMATO {
335ebdab5e8SMasatake YAMATO tokenInfo * identifier = newTokenByCopying (token);
336ebdab5e8SMasatake YAMATO
337ebdab5e8SMasatake YAMATO tokenRead (token);
338ebdab5e8SMasatake YAMATO
339ebdab5e8SMasatake YAMATO if (token->type == ';')
340ebdab5e8SMasatake YAMATO return identifier;
341ebdab5e8SMasatake YAMATO else
342ebdab5e8SMasatake YAMATO {
343a203ce0eSMasatake YAMATO tokenDelete (identifier);
344ebdab5e8SMasatake YAMATO return NULL;
345ebdab5e8SMasatake YAMATO }
346ebdab5e8SMasatake YAMATO }
347ebdab5e8SMasatake YAMATO return NULL;
348ebdab5e8SMasatake YAMATO }
349ebdab5e8SMasatake YAMATO
parseElement(tokenInfo * const token,bool skipToClose)350ebdab5e8SMasatake YAMATO static void parseElement (tokenInfo *const token, bool skipToClose)
351ebdab5e8SMasatake YAMATO {
352ebdab5e8SMasatake YAMATO tagEntryInfo e;
353*3afb5475SMasatake YAMATO int original_index;
354ebdab5e8SMasatake YAMATO
355ebdab5e8SMasatake YAMATO if (skipToClose)
356*3afb5475SMasatake YAMATO original_index = (int)countEntryInCorkQueue ();
357ebdab5e8SMasatake YAMATO
358ebdab5e8SMasatake YAMATO tokenRead (token);
359ebdab5e8SMasatake YAMATO if (token->type == '%')
360ebdab5e8SMasatake YAMATO {
361ebdab5e8SMasatake YAMATO tokenInfo * identifier = parserParameterEntityRef (token);
362ebdab5e8SMasatake YAMATO if (identifier)
363ebdab5e8SMasatake YAMATO {
364ebdab5e8SMasatake YAMATO makeDtdTagMaybe (&e, identifier,
365ebdab5e8SMasatake YAMATO K_PARAMETER_ENTITY,
366ebdab5e8SMasatake YAMATO DTD_PARAMETER_ENTITY_ELEMENT_NAME);
367a203ce0eSMasatake YAMATO tokenDelete (identifier);
368ebdab5e8SMasatake YAMATO }
369ebdab5e8SMasatake YAMATO }
370ebdab5e8SMasatake YAMATO else if (tokenIsType(token, IDENTIFIER))
37124b256e3SMasatake YAMATO makeDtdTagMaybe (&e, token, K_ELEMENT, ROLE_DEFINITION_INDEX);
37269d5e9d9SMasatake YAMATO else if (token->type == '(')
373ebdab5e8SMasatake YAMATO {
374ebdab5e8SMasatake YAMATO do {
375ebdab5e8SMasatake YAMATO parseElement (token, false);
376ebdab5e8SMasatake YAMATO } while ((!tokenIsEOF (token))
377ebdab5e8SMasatake YAMATO && (token->type != ')'));
378ebdab5e8SMasatake YAMATO }
379ebdab5e8SMasatake YAMATO
380ebdab5e8SMasatake YAMATO if (skipToClose)
381ebdab5e8SMasatake YAMATO {
382*3afb5475SMasatake YAMATO int current_index = (int)countEntryInCorkQueue ();
383ebdab5e8SMasatake YAMATO if (tokenSkipToType (token, TOKEN_CLOSE)
384ebdab5e8SMasatake YAMATO && (current_index > original_index))
385ebdab5e8SMasatake YAMATO {
386*3afb5475SMasatake YAMATO for (int index = original_index; index < current_index; index++)
387ebdab5e8SMasatake YAMATO backpatchEndField (index, token->lineNumber);
388ebdab5e8SMasatake YAMATO }
389ebdab5e8SMasatake YAMATO }
390ebdab5e8SMasatake YAMATO }
391ebdab5e8SMasatake YAMATO
parseAttDefs(tokenInfo * const token)392ebdab5e8SMasatake YAMATO static void parseAttDefs (tokenInfo *const token)
393ebdab5e8SMasatake YAMATO {
394ebdab5e8SMasatake YAMATO /* [53] AttDef ::= S Name S AttType S DefaultDecl */
395ebdab5e8SMasatake YAMATO
396ebdab5e8SMasatake YAMATO do {
397ebdab5e8SMasatake YAMATO tokenRead (token);
398ebdab5e8SMasatake YAMATO
399ebdab5e8SMasatake YAMATO /* Name */
400ebdab5e8SMasatake YAMATO if (tokenIsType(token, IDENTIFIER))
401ebdab5e8SMasatake YAMATO {
40286d17f9cSColomban Wendling tagEntryInfo e;
403ebdab5e8SMasatake YAMATO makeDtdTagMaybe (&e, token,
40424b256e3SMasatake YAMATO K_ATTRIBUTE, ROLE_DEFINITION_INDEX);
405ebdab5e8SMasatake YAMATO }
406ebdab5e8SMasatake YAMATO else if (tokenIsKeyword(token, ATTR_TYPES)
407ebdab5e8SMasatake YAMATO || tokenIsKeyword(token, ENTITY))
408ebdab5e8SMasatake YAMATO /* AttType -> just consuming */
409ebdab5e8SMasatake YAMATO ;
410ebdab5e8SMasatake YAMATO else if (tokenIsKeyword(token, NOTATION))
411ebdab5e8SMasatake YAMATO {
412ebdab5e8SMasatake YAMATO /* AttType -> just consuming */
413ebdab5e8SMasatake YAMATO tokenRead (token);
414ebdab5e8SMasatake YAMATO if (token->type == '(')
415ebdab5e8SMasatake YAMATO tokenSkipToType (token, ')');
416ebdab5e8SMasatake YAMATO }
417ebdab5e8SMasatake YAMATO else if (token->type == '(')
418ebdab5e8SMasatake YAMATO {
419ebdab5e8SMasatake YAMATO /* AttType, TODO: Enumerated members can be tagged. */
420ebdab5e8SMasatake YAMATO tokenSkipToType (token, ')');
421ebdab5e8SMasatake YAMATO }
422ebdab5e8SMasatake YAMATO else if (token->type == '#')
423ebdab5e8SMasatake YAMATO {
424ebdab5e8SMasatake YAMATO /* DefaultDecl */
425ebdab5e8SMasatake YAMATO tokenRead (token);
426ebdab5e8SMasatake YAMATO if (tokenIsKeyword(token, FIXED))
427ebdab5e8SMasatake YAMATO tokenRead (token);
428ebdab5e8SMasatake YAMATO else if (tokenIsKeyword(token, ATTR_DEFAULT_DECLS))
42954ca6868SMasatake YAMATO {
43054ca6868SMasatake YAMATO /* Just consuming */
43154ca6868SMasatake YAMATO }
432ebdab5e8SMasatake YAMATO }
433ebdab5e8SMasatake YAMATO else if (tokenIsType (token, STRING))
434ebdab5e8SMasatake YAMATO ; /* DefaultDecl -> Just consuming */
435ebdab5e8SMasatake YAMATO else if (token->type == '%')
436ebdab5e8SMasatake YAMATO {
437ebdab5e8SMasatake YAMATO tokenInfo * identifier = parserParameterEntityRef (token);
438ebdab5e8SMasatake YAMATO if (identifier)
439ebdab5e8SMasatake YAMATO {
44086d17f9cSColomban Wendling tagEntryInfo e;
441ebdab5e8SMasatake YAMATO makeDtdTagMaybe (&e, identifier,
442ebdab5e8SMasatake YAMATO K_PARAMETER_ENTITY,
443ebdab5e8SMasatake YAMATO DTD_PARAMETER_ENTITY_PART_OF_ATT_DEF);
444a203ce0eSMasatake YAMATO tokenDelete (identifier);
445ebdab5e8SMasatake YAMATO }
446ebdab5e8SMasatake YAMATO }
447ebdab5e8SMasatake YAMATO else if (tokenIsType(token, CLOSE))
448ebdab5e8SMasatake YAMATO {
449002dd246SMasatake YAMATO DTD (token)->scopeIndex = CORK_NIL;
450ebdab5e8SMasatake YAMATO tokenUnread (token);
451ebdab5e8SMasatake YAMATO break;
452ebdab5e8SMasatake YAMATO }
453ebdab5e8SMasatake YAMATO } while (!tokenIsEOF (token));
454ebdab5e8SMasatake YAMATO }
455ebdab5e8SMasatake YAMATO
parseAttlist(tokenInfo * const token)456ebdab5e8SMasatake YAMATO static void parseAttlist (tokenInfo *const token)
457ebdab5e8SMasatake YAMATO {
458ebdab5e8SMasatake YAMATO tagEntryInfo e;
459*3afb5475SMasatake YAMATO int index = CORK_NIL;
460ebdab5e8SMasatake YAMATO
461ebdab5e8SMasatake YAMATO tokenRead (token);
462ebdab5e8SMasatake YAMATO if (token->type == '%')
463ebdab5e8SMasatake YAMATO {
464ebdab5e8SMasatake YAMATO tokenRead (token);
465ebdab5e8SMasatake YAMATO if (tokenIsType(token, IDENTIFIER))
466ebdab5e8SMasatake YAMATO {
467ebdab5e8SMasatake YAMATO tokenInfo * identifier = parserParameterEntityRef (token);
468ebdab5e8SMasatake YAMATO if (identifier)
469ebdab5e8SMasatake YAMATO {
470ebdab5e8SMasatake YAMATO index = makeDtdTagMaybe (&e, identifier,
471ebdab5e8SMasatake YAMATO K_ENTITY,
472ebdab5e8SMasatake YAMATO DTD_PARAMETER_ENTITY_ELEMENT_NAME);
473a203ce0eSMasatake YAMATO tokenDelete (identifier);
474ebdab5e8SMasatake YAMATO
475002dd246SMasatake YAMATO DTD (token)->scopeIndex = index;
476ebdab5e8SMasatake YAMATO parseAttDefs (token);
477002dd246SMasatake YAMATO DTD (token)->scopeIndex = CORK_NIL;
478ebdab5e8SMasatake YAMATO }
479ebdab5e8SMasatake YAMATO }
480ebdab5e8SMasatake YAMATO }
481ebdab5e8SMasatake YAMATO else if (tokenIsType(token, IDENTIFIER))
482ebdab5e8SMasatake YAMATO {
483ebdab5e8SMasatake YAMATO tokenInfo * element = newTokenByCopying (token);
484ebdab5e8SMasatake YAMATO
485ebdab5e8SMasatake YAMATO index = makeDtdTagMaybe (&e, element,
486ebdab5e8SMasatake YAMATO K_ELEMENT, DTD_ELEMENT_ATT_OWNER);
487a203ce0eSMasatake YAMATO tokenDelete (element);
488ebdab5e8SMasatake YAMATO
489002dd246SMasatake YAMATO DTD (token)->scopeIndex = index;
490ebdab5e8SMasatake YAMATO parseAttDefs (token);
491002dd246SMasatake YAMATO DTD (token)->scopeIndex = CORK_NIL;
492ebdab5e8SMasatake YAMATO }
493ebdab5e8SMasatake YAMATO
494ebdab5e8SMasatake YAMATO tokenSkipToType (token, TOKEN_CLOSE);
495ebdab5e8SMasatake YAMATO backpatchEndField (index, token->lineNumber);
496ebdab5e8SMasatake YAMATO }
497ebdab5e8SMasatake YAMATO
parseNotation(tokenInfo * const token)498ebdab5e8SMasatake YAMATO static void parseNotation (tokenInfo *const token)
499ebdab5e8SMasatake YAMATO {
500*3afb5475SMasatake YAMATO int index = CORK_NIL;
501ebdab5e8SMasatake YAMATO tagEntryInfo e;
502ebdab5e8SMasatake YAMATO
503ebdab5e8SMasatake YAMATO tokenRead (token);
504ebdab5e8SMasatake YAMATO if (tokenIsType(token, IDENTIFIER))
505ebdab5e8SMasatake YAMATO index = makeDtdTagMaybe (&e, token,
50624b256e3SMasatake YAMATO K_NOTATION, ROLE_DEFINITION_INDEX);
507ebdab5e8SMasatake YAMATO
508ebdab5e8SMasatake YAMATO tokenSkipToType (token, TOKEN_CLOSE);
509ebdab5e8SMasatake YAMATO backpatchEndField (index, token->lineNumber);
510ebdab5e8SMasatake YAMATO }
511ebdab5e8SMasatake YAMATO
512ebdab5e8SMasatake YAMATO
513ebdab5e8SMasatake YAMATO static void parseSection (tokenInfo *const token);
514ebdab5e8SMasatake YAMATO
parseDtdTag1(tokenInfo * const token)515ebdab5e8SMasatake YAMATO static void parseDtdTag1 (tokenInfo *const token)
516ebdab5e8SMasatake YAMATO {
517ebdab5e8SMasatake YAMATO if (tokenIsType(token, OPEN))
518ebdab5e8SMasatake YAMATO {
519ebdab5e8SMasatake YAMATO tokenRead (token);
520ebdab5e8SMasatake YAMATO if (tokenIsKeyword (token, ELEMENT))
521ebdab5e8SMasatake YAMATO parseElement(token, true);
522ebdab5e8SMasatake YAMATO else if (tokenIsKeyword (token, ATTLIST))
523ebdab5e8SMasatake YAMATO parseAttlist(token);
524ebdab5e8SMasatake YAMATO else if (tokenIsKeyword (token, ENTITY))
525ebdab5e8SMasatake YAMATO parseEntity(token);
526ebdab5e8SMasatake YAMATO else if (tokenIsKeyword (token, NOTATION))
527ebdab5e8SMasatake YAMATO parseNotation(token);
528ebdab5e8SMasatake YAMATO else if (token->type == '[')
529ebdab5e8SMasatake YAMATO {
530ebdab5e8SMasatake YAMATO tokenRead (token);
531ebdab5e8SMasatake YAMATO parseSection (token);
532ebdab5e8SMasatake YAMATO tokenSkipToType (token, ']');
533ebdab5e8SMasatake YAMATO }
534ebdab5e8SMasatake YAMATO else if (!tokenIsType(token, CLOSE))
535ebdab5e8SMasatake YAMATO tokenSkipToType (token, TOKEN_CLOSE);
536ebdab5e8SMasatake YAMATO }
537ebdab5e8SMasatake YAMATO }
538ebdab5e8SMasatake YAMATO
parseSection(tokenInfo * const token)539ebdab5e8SMasatake YAMATO static void parseSection (tokenInfo *const token)
540ebdab5e8SMasatake YAMATO {
541ebdab5e8SMasatake YAMATO if (tokenIsKeyword(token, IGNORE))
542ebdab5e8SMasatake YAMATO tokenSkipToType (token, ']');
543ebdab5e8SMasatake YAMATO else
544ebdab5e8SMasatake YAMATO {
545ebdab5e8SMasatake YAMATO if (tokenIsKeyword (token, INCLUDE))
546ebdab5e8SMasatake YAMATO {
547ebdab5e8SMasatake YAMATO tokenRead (token);
548ebdab5e8SMasatake YAMATO if (token->type == '[')
549ebdab5e8SMasatake YAMATO {
550ebdab5e8SMasatake YAMATO do {
551ebdab5e8SMasatake YAMATO tokenRead (token);
552ebdab5e8SMasatake YAMATO } while ((!tokenIsEOF (token))
553ebdab5e8SMasatake YAMATO && (token->type != ']'));
554ebdab5e8SMasatake YAMATO }
555ebdab5e8SMasatake YAMATO }
556ebdab5e8SMasatake YAMATO else if (token->type == '%')
557ebdab5e8SMasatake YAMATO {
558ebdab5e8SMasatake YAMATO tokenInfo *const condition = parserParameterEntityRef (token);
559ebdab5e8SMasatake YAMATO if (condition)
560ebdab5e8SMasatake YAMATO {
561ebdab5e8SMasatake YAMATO tagEntryInfo e;
562*3afb5475SMasatake YAMATO int index = makeDtdTagMaybe (&e, condition,
563ebdab5e8SMasatake YAMATO K_PARAMETER_ENTITY,
564ebdab5e8SMasatake YAMATO DTD_PARAMETER_ENTITY_CONDITION);
565a203ce0eSMasatake YAMATO tokenDelete (condition);
566ebdab5e8SMasatake YAMATO tokenRead (token);
567ebdab5e8SMasatake YAMATO if (token->type == '[')
568ebdab5e8SMasatake YAMATO {
569ebdab5e8SMasatake YAMATO do {
570ebdab5e8SMasatake YAMATO tokenRead (token);
571ebdab5e8SMasatake YAMATO parseDtdTag1 (token);
572ebdab5e8SMasatake YAMATO } while ((!tokenIsEOF (token))
573ebdab5e8SMasatake YAMATO && (token->type != ']'));
574ebdab5e8SMasatake YAMATO if (token->type== ']')
575ebdab5e8SMasatake YAMATO backpatchEndField (index, token->lineNumber);
576ebdab5e8SMasatake YAMATO }
577ebdab5e8SMasatake YAMATO }
578ebdab5e8SMasatake YAMATO }
579ebdab5e8SMasatake YAMATO }
580ebdab5e8SMasatake YAMATO }
581ebdab5e8SMasatake YAMATO
findDtdTags(void)582ebdab5e8SMasatake YAMATO static void findDtdTags (void)
583ebdab5e8SMasatake YAMATO {
584ebdab5e8SMasatake YAMATO tokenInfo *const token = newDtdToken ();
585ebdab5e8SMasatake YAMATO
586ebdab5e8SMasatake YAMATO do {
587ebdab5e8SMasatake YAMATO tokenRead (token);
588ebdab5e8SMasatake YAMATO parseDtdTag1 (token);
589ebdab5e8SMasatake YAMATO } while (!tokenIsEOF (token));
590ebdab5e8SMasatake YAMATO
591a203ce0eSMasatake YAMATO tokenDelete (token);
592ebdab5e8SMasatake YAMATO
593ebdab5e8SMasatake YAMATO flashTokenBacklog (&dtdTokenInfoClass);
594ebdab5e8SMasatake YAMATO }
595ebdab5e8SMasatake YAMATO
initialize(const langType language)596ebdab5e8SMasatake YAMATO static void initialize (const langType language)
597ebdab5e8SMasatake YAMATO {
598ebdab5e8SMasatake YAMATO Lang_dtd = language;
599ebdab5e8SMasatake YAMATO }
600ebdab5e8SMasatake YAMATO
DtdParser(void)601ebdab5e8SMasatake YAMATO extern parserDefinition* DtdParser (void)
602ebdab5e8SMasatake YAMATO {
603ebdab5e8SMasatake YAMATO parserDefinition* def = parserNew ("DTD");
604ebdab5e8SMasatake YAMATO
605ebdab5e8SMasatake YAMATO /* File name patters are picked from Linux kernel. */
606ebdab5e8SMasatake YAMATO static const char *const extensions [] = {
607ebdab5e8SMasatake YAMATO "dtd",
608ebdab5e8SMasatake YAMATO "mod",
609ebdab5e8SMasatake YAMATO NULL
610ebdab5e8SMasatake YAMATO };
611ebdab5e8SMasatake YAMATO
612ebdab5e8SMasatake YAMATO def->initialize = initialize;
613ebdab5e8SMasatake YAMATO def->parser = findDtdTags;
614ebdab5e8SMasatake YAMATO
61509ae690fSMasatake YAMATO def->kindTable = DtdKinds;
616ebdab5e8SMasatake YAMATO def->kindCount = ARRAY_SIZE (DtdKinds);
617ebdab5e8SMasatake YAMATO def->extensions = extensions;
618ebdab5e8SMasatake YAMATO
619ebdab5e8SMasatake YAMATO def->keywordTable = DtdKeywordTable;
620ebdab5e8SMasatake YAMATO def->keywordCount = ARRAY_SIZE (DtdKeywordTable);
621ebdab5e8SMasatake YAMATO
6226b1a862eSMasatake YAMATO def->useCork = CORK_QUEUE;
623ebdab5e8SMasatake YAMATO def->requestAutomaticFQTag = true;
624ebdab5e8SMasatake YAMATO
625ebdab5e8SMasatake YAMATO return def;
626ebdab5e8SMasatake YAMATO }
627