2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: Syntax.C /main/2 1996/08/12 13:22:19 mgreess $ */
24 // Copyright (c) 1994 James Clark
25 // See the file COPYING for copying permission.
28 #pragma implementation
33 #include "CharsetInfo.h"
36 #include "MarkupScan.h"
40 namespace SP_NAMESPACE {
43 const int Syntax::referenceQuantity_[] = {
61 Syntax::Syntax(const Sd &sd)
64 categoryTable_(otherCategory),
67 markupScanTable_(MarkupScan::normal),
68 namecaseGeneral_(false),
69 namecaseEntity_(false)
71 static const char lcletter[] = "abcdefghijklmnopqrstuvwxyz";
72 static const char ucletter[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
74 for (i = 0; i < 26; i++) {
75 Char lc = sd.execToDoc(lcletter[i]);
76 Char uc = sd.execToDoc(ucletter[i]);
77 set_[nameStart] += lc;
78 set_[nameStart] += uc;
79 set_[minimumData] += lc;
80 set_[minimumData] += uc;
81 set_[significant] += lc;
82 set_[significant] += uc;
83 categoryTable_.setChar(lc, nameStartCategory);
84 categoryTable_.setChar(uc, nameStartCategory);
87 static const char digits[] = "0123456789";
88 for (i = 0; i < 10; i++) {
89 Char c = sd.execToDoc(digits[i]);
91 set_[minimumData] += c;
92 set_[significant] += c;
93 categoryTable_.setChar(c, digitCategory);
95 static const char special[] = "'()+,-./:=?";
96 for (i = 0; special[i] != '\0'; i++) {
97 Char c = sd.execToDoc(special[i]);
98 set_[minimumData] += c;
99 set_[significant] += c;
101 for (i = 0; i < nQuantity; i++)
102 quantity_[i] = referenceQuantity_[i];
103 for (i = 0; i < 3; i++)
104 standardFunctionValid_[i] = 0;
108 Syntax::Syntax(const Syntax & syn)
109 : generalSubst_(syn.generalSubst_),
110 entitySubst_(syn.entitySubst_),
111 shunchar_(syn.shunchar_),
112 shuncharControls_(syn.shuncharControls_),
113 namecaseGeneral_(syn.namecaseGeneral_),
114 namecaseEntity_(syn.namecaseEntity_),
115 delimShortrefComplex_(syn.delimShortrefComplex_),
116 delimShortrefSimple_(syn.delimShortrefSimple_),
117 nameTable_(syn.nameTable_),
118 functionTable_(syn.functionTable_),
119 upperSubst_(syn.upperSubst_),
120 identitySubst_(syn.identitySubst_),
121 categoryTable_(syn.categoryTable_),
122 multicode_(syn.multicode_),
123 markupScanTable_(syn.markupScanTable_)
127 for (i = 0; i < nSet; i++)
128 set_[i] = syn.set_[i];
130 for (i = 0; i < 3; i++) {
131 standardFunction_[i] = syn.standardFunction_[i];
132 standardFunctionValid_[i] = syn.standardFunctionValid_[i];
135 for (i = 0; i < nDelimGeneral; i++)
136 delimGeneral_[i] = syn.delimGeneral_[i];
138 for (i = 0; i < nNames; i++)
139 names_[i] = syn.names_[i];
141 for (i = 0; i < nQuantity; i++)
142 quantity_[i] = syn.quantity_[i];
145 void Syntax::addNameCharacters(const ISet<Char> &set)
147 ISetIter<Char> iter(set);
149 while (iter.next(min, max)) {
150 set_[nmchar].addRange(min, max);
151 set_[significant].addRange(min, max);
152 categoryTable_.setRange(min, max, otherNameCategory);
156 void Syntax::addNameStartCharacters(const ISet<Char> &set)
158 ISetIter<Char> iter(set);
160 while (iter.next(min, max)) {
161 set_[nameStart].addRange(min, max);
162 set_[significant].addRange(min, max);
163 categoryTable_.setRange(min, max, nameStartCategory);
167 void Syntax::addSubst(Char lc, Char uc)
172 void Syntax::setStandardFunction(StandardFunction f, Char c)
174 standardFunction_[f] = c;
175 standardFunctionValid_[f] = 1;
176 set_[minimumData] += c;
178 categoryTable_.setChar(c, sCategory);
179 set_[functionChar] += c;
180 set_[significant] += c;
191 void Syntax::enterStandardFunctionNames()
193 static ReservedName name[3] = {
196 for (int i = 0; i < 3; i++)
197 if (standardFunctionValid_[i])
198 functionTable_.insert(reservedName(name[i]), standardFunction_[i]);
201 void Syntax::setDelimGeneral(int i, const StringC &str)
203 delimGeneral_[i] = str;
204 for (size_t j = 0; j < str.size(); j++)
205 set_[significant] += str[j];
208 void Syntax::addDelimShortref(const StringC &str, const CharsetInfo &charset)
210 if (str.size() == 1 && str[0] != charset.execToDesc('B') && !isB(str[0]))
211 delimShortrefSimple_.add(str[0]);
213 delimShortrefComplex_.push_back(str);
214 for (size_t i = 0; i < str.size(); i++)
215 set_[significant] += str[i];
218 void Syntax::addDelimShortrefs(const ISet<Char> &shortrefChars,
219 const CharsetInfo &charset)
221 ISetIter<Char> blankIter(set_[blank]);
223 StringC specialChars;
224 while (blankIter.next(min, max)) {
227 } while (min++ != max);
229 specialChars += charset.execToDesc('B');
230 const ISet<Char> *simpleCharsPtr = &shortrefChars;
231 ISet<Char> simpleChars;
232 for (size_t i = 0; i < specialChars.size(); i++)
233 if (shortrefChars.contains(specialChars[i])) {
234 if (simpleCharsPtr != &simpleChars) {
235 simpleChars = shortrefChars;
236 simpleCharsPtr = &simpleChars;
238 simpleChars.remove(specialChars[i]);
240 ISetIter<Char> iter(*simpleCharsPtr);
241 while (iter.next(min, max)) {
242 delimShortrefSimple_.addRange(min, max);
243 set_[significant].addRange(min, max);
247 void Syntax::addFunctionChar(const StringC &str, FunctionClass fun, Char c)
254 categoryTable_.setChar(c, sCategory);
260 markupScanTable_.setChar(c, MarkupScan::out);
263 // don't need to do anything special if we just have MSICHARs
264 markupScanTable_.setChar(c, MarkupScan::in);
268 markupScanTable_.setChar(c, MarkupScan::suppress);
271 set_[functionChar] += c;
272 set_[significant] += c;
273 functionTable_.insert(str, c);
276 void Syntax::setName(int i, const StringC &str)
279 nameTable_.insert(str, i);
282 void Syntax::setNamecaseGeneral(Boolean b)
284 namecaseGeneral_ = b;
285 generalSubst_ = b ? &upperSubst_ : &identitySubst_;
288 void Syntax::setNamecaseEntity(Boolean b)
291 entitySubst_ = b ? &upperSubst_ : &identitySubst_;
294 void Syntax::subst(Char from, Char to)
296 upperSubst_.addSubst(from, to);
299 void Syntax::addShunchar(Char c)
304 Boolean Syntax::lookupReservedName(const StringC &str,
305 ReservedName *result) const
307 const int *tem = nameTable_.lookup(str);
309 *result = ReservedName(*tem);
316 Boolean Syntax::lookupFunctionChar(const StringC &name, Char *result) const
318 const Char *p = functionTable_.lookup(name);
328 typedef HashTableIter<StringC,Char> Dummy_HashTableIter_StringC_Char;
331 Boolean Syntax::charFunctionName(Char c, const StringC *&name) const
333 HashTableIter<StringC,Char> iter(functionTable_);
335 while (iter.next(name, cp))
341 Boolean Syntax::isValidShortref(const StringC &str) const
343 if (str.size() == 1 && delimShortrefSimple_.contains(str[0]))
345 for (size_t i = 0; i < delimShortrefComplex_.size(); i++)
346 if (str == delimShortrefComplex_[i])
351 void Syntax::implySgmlChar(const CharsetInfo &docCharset)
353 docCharset.getDescSet(set_[sgmlChar]);
354 ISet<WideChar> invalid;
355 checkSgmlChar(docCharset, 0, invalid);
356 ISetIter<WideChar> iter(invalid);
358 while (iter.next(min, max)) {
361 set_[sgmlChar].remove(Char(min));
362 } while (min++ != max);
366 void Syntax::checkSgmlChar(const CharsetInfo &docCharset,
367 const ::SP_NAMESPACE_SCOPE Syntax *otherSyntax,
368 ISet<WideChar> &invalid) const
370 ISetIter<Char> iter(shunchar_);
372 while (iter.next(min, max)) {
375 if (!set_[significant].contains(min)
376 && (!otherSyntax || !otherSyntax->set_[significant].contains(min))
377 && set_[sgmlChar].contains(min))
379 } while (min++ != max);
382 if (shuncharControls_) {
384 for (i = 0; i < 32; i++)
385 checkUnivControlChar(i, docCharset, otherSyntax, invalid);
386 for (i = 127; i < 160; i++)
387 checkUnivControlChar(i, docCharset, otherSyntax, invalid);
391 void Syntax::checkUnivControlChar(UnivChar univChar,
392 const CharsetInfo &docCharset,
393 const ::SP_NAMESPACE_SCOPE Syntax *otherSyntax,
394 ISet<WideChar> &invalid) const
398 switch (docCharset.univToDesc(univChar, c, set)) {
406 ISetIter<WideChar> iter(set);
408 while (iter.next(min, max)) {
413 if (!set_[significant].contains(ch)
415 || !otherSyntax->set_[significant].contains(ch))
416 && set_[sgmlChar].contains(ch))
418 } while (min++ != max);
424 StringC Syntax::rniReservedName(ReservedName i) const
426 StringC result = delimGeneral(dRNI);
427 result += reservedName(i);
431 const SubstTable<Char> &Syntax::upperSubstTable() const
436 const StringC &Syntax::peroDelim() const
438 return delimGeneral(dPERO);