Mercurial > illumos > onarm
annotate usr/src/cmd/man/src/util/nsgmls.src/lib/MessageFormatter.cxx @ 4:1a15d5aaf794
synchronized with onnv_86 (6202) in onnv-gate
author | Koji Uno <koji.uno@sun.com> |
---|---|
date | Mon, 31 Aug 2009 14:38:03 +0900 |
parents | c9caec207d52 |
children |
rev | line source |
---|---|
0 | 1 // Copyright (c) 1994, 1995, 1997 James Clark |
2 // See the file COPYING for copying permission. | |
4
1a15d5aaf794
synchronized with onnv_86 (6202) in onnv-gate
Koji Uno <koji.uno@sun.com>
parents:
0
diff
changeset
|
3 #pragma ident "%Z%%M% %I% %E% SMI" |
0 | 4 |
5 #ifdef __GNUG__ | |
6 #pragma implementation | |
7 #endif | |
8 | |
9 #include "splib.h" | |
10 #include "MessageFormatter.h" | |
11 #include "OutputCharStream.h" | |
12 #include "rtti.h" | |
13 #include "MessageArg.h" | |
14 #include "ErrnoMessageArg.h" | |
15 #include "SearchResultMessageArg.h" | |
16 #include "MessageFormatterMessages.h" | |
17 | |
18 #include <string.h> | |
19 #include <errno.h> | |
20 | |
21 #ifdef DECLARE_STRERROR | |
22 extern "C" { | |
23 char *strerror(int); | |
24 } | |
25 #endif | |
26 | |
27 #ifdef SP_NAMESPACE | |
28 namespace SP_NAMESPACE { | |
29 #endif | |
30 | |
31 MessageFormatter::MessageFormatter() | |
32 { | |
33 } | |
34 | |
35 void MessageFormatter::formatOpenElements(const Vector<OpenElementInfo> &openElementInfo, | |
36 OutputCharStream &os) | |
37 { | |
38 unsigned nOpenElements = openElementInfo.size(); | |
39 for (unsigned i = 0;; i++) { | |
40 if (i > 0 | |
41 && (i == nOpenElements || openElementInfo[i].included)) { | |
42 // describe last match in previous open element | |
43 const OpenElementInfo &prevInfo = openElementInfo[i - 1]; | |
44 if (prevInfo.matchType.size() != 0) { | |
45 os << " (" << prevInfo.matchType; | |
46 if (prevInfo.matchIndex != 0) | |
47 os << '[' << (unsigned long)prevInfo.matchIndex << ']'; | |
48 os << ')'; | |
49 } | |
50 } | |
51 if (i == nOpenElements) | |
52 break; | |
53 const OpenElementInfo &e = openElementInfo[i]; | |
54 os << ' ' << e.gi; | |
55 if (i > 0 && !e.included) { | |
56 unsigned long n = openElementInfo[i - 1].matchIndex; | |
57 if (n != 0) | |
58 os << '[' << n << ']'; | |
59 } | |
60 } | |
61 } | |
62 | |
63 void MessageFormatter::formatMessage(const MessageFragment &frag, | |
64 const Vector<CopyOwner<MessageArg> > &args, | |
65 OutputCharStream &os) | |
66 { | |
67 StringC text; | |
68 if (!getMessageText(frag, text)) { | |
69 formatFragment(MessageFormatterMessages::invalidMessage, os); | |
70 return; | |
71 } | |
72 Builder builder(this, os, text.size() == 2); | |
73 size_t i = 0; | |
74 while (i < text.size()) { | |
75 if (text[i] == '%') { | |
76 i++; | |
77 if (i >= text.size()) | |
78 break; | |
79 if (text[i] >= '1' && text[i] <= '9') { | |
80 if (unsigned(text[i] - '1') < args.size()) | |
81 args[text[i] - '1']->append(builder); | |
82 } | |
83 else | |
84 os.put(text[i]); | |
85 i++; | |
86 } | |
87 else { | |
88 os.put(text[i]); | |
89 i++; | |
90 } | |
91 } | |
92 } | |
93 | |
94 Boolean MessageFormatter::formatFragment(const MessageFragment &frag, | |
95 OutputCharStream &os) | |
96 { | |
97 StringC text; | |
98 if (!getMessageText(frag, text)) | |
99 return 0; | |
100 os << text; | |
101 return 1; | |
102 } | |
103 | |
104 void MessageFormatter::Builder::appendNumber(unsigned long n) | |
105 { | |
106 os() << n; | |
107 } | |
108 | |
109 void MessageFormatter::Builder::appendOrdinal(unsigned long n) | |
110 { | |
111 os() << n; | |
112 switch (n % 10) { | |
113 case 1: | |
114 appendFragment(MessageFormatterMessages::ordinal1); | |
115 break; | |
116 case 2: | |
117 appendFragment(MessageFormatterMessages::ordinal2); | |
118 break; | |
119 case 3: | |
120 appendFragment(MessageFormatterMessages::ordinal3); | |
121 break; | |
122 default: | |
123 appendFragment(MessageFormatterMessages::ordinaln); | |
124 break; | |
125 } | |
126 } | |
127 | |
128 void MessageFormatter::Builder::appendChars(const Char *p, size_t n) | |
129 { | |
130 if (argIsCompleteMessage_) | |
131 os().write(p, n); | |
132 else | |
133 os().put('"').write(p, n).put('"'); | |
134 } | |
135 | |
136 void MessageFormatter::Builder::appendOther(const OtherMessageArg *p) | |
137 { | |
138 const ErrnoMessageArg *ea = DYNAMIC_CAST_CONST_PTR(ErrnoMessageArg, p); | |
139 | |
140 if (ea) { | |
141 os() << strerror(ea->errnum()); | |
142 return; | |
143 } | |
144 | |
145 const SearchResultMessageArg *sr | |
146 = DYNAMIC_CAST_CONST_PTR(SearchResultMessageArg, p); | |
147 if (sr) { | |
148 for (size_t i = 0; i < sr->nTried(); i++) { | |
149 if (i > 0) | |
150 os() << ", "; | |
151 const StringC &f = sr->filename(i); | |
152 appendChars(f.data(), f.size()); | |
153 switch (sr->errnum(i)) { | |
154 default: | |
155 os() << " ("; | |
156 os() << strerror(sr->errnum(i)); | |
157 os() << ")"; | |
158 #ifdef ENOENT | |
159 case ENOENT: | |
160 #endif | |
161 break; | |
162 } | |
163 } | |
164 return; | |
165 } | |
166 appendFragment(MessageFormatterMessages::invalidArgumentType); | |
167 } | |
168 | |
169 void MessageFormatter::Builder::appendFragment(const MessageFragment &frag) | |
170 { | |
171 formatter_->formatFragment(frag, os()); | |
172 } | |
173 | |
174 #ifdef SP_NAMESPACE | |
175 } | |
176 #endif |