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