1 // Copyright (c) 1994 James Clark
2 // See the file COPYING for copying permission.
3 #pragma ident "%Z%%M% %I% %E% SMI"
4
5 #ifdef __GNUG__
6 #pragma implementation
7 #endif
8 #include "splib.h"
9 #include "TokenMessageArg.h"
10 #include "MessageBuilder.h"
11 #include "token.h"
12 #include "ParserMessages.h"
13 #include "Mode.h"
14 #include "ModeInfo.h"
15 #include "macros.h"
16
17 #ifdef SP_NAMESPACE
18 namespace SP_NAMESPACE {
19 #endif
20
TokenMessageArg(Token token,Mode mode,const ConstPtr<Syntax> & syntax,const ConstPtr<Sd> & sd)21 TokenMessageArg::TokenMessageArg(Token token, Mode mode,
22 const ConstPtr<Syntax> &syntax,
23 const ConstPtr<Sd> &sd)
24 : token_(token), mode_(mode), syntax_(syntax), sd_(sd)
25 {
26 }
27
copy() const28 MessageArg *TokenMessageArg::copy() const
29 {
30 return new TokenMessageArg(*this);
31 }
32
append(MessageBuilder & builder) const33 void TokenMessageArg::append(MessageBuilder &builder) const
34 {
35 // FIXME translate function characters in delimiters into
36 // &#NAME; form.
37 if (token_ >= tokenFirstShortref) {
38 builder.appendFragment(ParserMessages::shortrefDelim);
39 return;
40 }
41 if (token_ == tokenEe) {
42 builder.appendFragment(ParserMessages::entityEnd);
43 return;
44 }
45 ModeInfo iter(mode_, *sd_);
46 TokenInfo info;
47 const MessageFragment *fragment = 0;
48 while (iter.nextToken(&info))
49 if (info.token == token_) {
50 switch (info.type) {
51 case TokenInfo::delimType:
52 case TokenInfo::delimDelimType:
53 case TokenInfo::delimSetType:
54 {
55 const StringC &delim = syntax_->delimGeneral(info.delim1);
56 builder.appendFragment(ParserMessages::delimStart);
57 builder.appendChars(delim.data(), delim.size());
58 fragment = &ParserMessages::delimEnd;
59 }
60 break;
61 case TokenInfo::setType:
62 switch (info.set) {
63 case Syntax::digit:
64 fragment = &ParserMessages::digit;
65 break;
66 case Syntax::nameStart:
67 fragment = &ParserMessages::nameStartCharacter;
68 break;
69 case Syntax::sepchar:
70 fragment = &ParserMessages::sepchar;
71 break;
72 case Syntax::s:
73 fragment = &ParserMessages::separator;
74 break;
75 case Syntax::nmchar:
76 fragment = &ParserMessages::nameCharacter;
77 break;
78 case Syntax::sgmlChar:
79 fragment = &ParserMessages::dataCharacter;
80 break;
81 case Syntax::minimumData:
82 fragment = &ParserMessages::minimumDataCharacter;
83 break;
84 case Syntax::significant:
85 fragment = &ParserMessages::significantCharacter;
86 break;
87 default:
88 CANNOT_HAPPEN();
89 }
90 break;
91 case TokenInfo::functionType:
92 switch (info.function) {
93 case Syntax::fRE:
94 fragment = &ParserMessages::recordEnd;
95 break;
96 case Syntax::fRS:
97 fragment = &ParserMessages::recordStart;
98 break;
99 case Syntax::fSPACE:
100 fragment = &ParserMessages::space;
101 break;
102 }
103 break;
104 }
105 break;
106 }
107 if (fragment)
108 builder.appendFragment(*fragment);
109 }
110
111 #ifdef SP_NAMESPACE
112 }
113 #endif
114