/branches/opensp_1_4/sp/lib/MessageFormatter.cxx
# · C++ · 175 lines · 155 code · 17 blank · 3 comment · 34 complexity · 0143dfdadf6f9d75ff9dfd498b61f731 MD5 · raw file
- // Copyright (c) 1994, 1995, 1997 James Clark
- // See the file COPYING for copying permission.
- #ifdef __GNUG__
- #pragma implementation
- #endif
- #include "splib.h"
- #include "MessageFormatter.h"
- #include "OutputCharStream.h"
- #include "rtti.h"
- #include "MessageArg.h"
- #include "ErrnoMessageArg.h"
- #include "SearchResultMessageArg.h"
- #include "MessageFormatterMessages.h"
- #include <string.h>
- #include <errno.h>
- #ifdef DECLARE_STRERROR
- extern "C" {
- char *strerror(int);
- }
- #endif
- #ifdef SP_NAMESPACE
- namespace SP_NAMESPACE {
- #endif
- MessageFormatter::MessageFormatter()
- {
- }
- void MessageFormatter::formatOpenElements(const Vector<OpenElementInfo> &openElementInfo,
- OutputCharStream &os)
- {
- unsigned nOpenElements = openElementInfo.size();
- for (unsigned i = 0;; i++) {
- if (i > 0
- && (i == nOpenElements || openElementInfo[i].included)) {
- // describe last match in previous open element
- const OpenElementInfo &prevInfo = openElementInfo[i - 1];
- if (prevInfo.matchType.size() != 0) {
- os << " (" << prevInfo.matchType;
- if (prevInfo.matchIndex != 0)
- os << '[' << (unsigned long)prevInfo.matchIndex << ']';
- os << ')';
- }
- }
- if (i == nOpenElements)
- break;
- const OpenElementInfo &e = openElementInfo[i];
- os << ' ' << e.gi;
- if (i > 0 && !e.included) {
- unsigned long n = openElementInfo[i - 1].matchIndex;
- if (n != 0)
- os << '[' << n << ']';
- }
- }
- }
- void MessageFormatter::formatMessage(const MessageFragment &frag,
- const Vector<CopyOwner<MessageArg> > &args,
- OutputCharStream &os, bool noquote)
- {
- StringC text;
- if (!getMessageText(frag, text)) {
- formatFragment(MessageFormatterMessages::invalidMessage, os);
- return;
- }
- Builder builder(this, os, noquote || (text.size() == 2));
- size_t i = 0;
- while (i < text.size()) {
- if (text[i] == '%') {
- i++;
- if (i >= text.size())
- break;
- if (text[i] >= '1' && text[i] <= '9') {
- if (unsigned(text[i] - '1') < args.size())
- args[text[i] - '1']->append(builder);
- }
- else
- os.put(text[i]);
- i++;
- }
- else {
- os.put(text[i]);
- i++;
- }
- }
- }
- Boolean MessageFormatter::formatFragment(const MessageFragment &frag,
- OutputCharStream &os)
- {
- StringC text;
- if (!getMessageText(frag, text))
- return 0;
- os << text;
- return 1;
- }
- void MessageFormatter::Builder::appendNumber(unsigned long n)
- {
- os() << n;
- }
- void MessageFormatter::Builder::appendOrdinal(unsigned long n)
- {
- os() << n;
- switch (n % 10) {
- case 1:
- appendFragment(MessageFormatterMessages::ordinal1);
- break;
- case 2:
- appendFragment(MessageFormatterMessages::ordinal2);
- break;
- case 3:
- appendFragment(MessageFormatterMessages::ordinal3);
- break;
- default:
- appendFragment(MessageFormatterMessages::ordinaln);
- break;
- }
- }
- void MessageFormatter::Builder::appendChars(const Char *p, size_t n)
- {
- if (argIsCompleteMessage_)
- os().write(p, n);
- else
- os().put('"').write(p, n).put('"');
- }
- void MessageFormatter::Builder::appendOther(const OtherMessageArg *p)
- {
- const ErrnoMessageArg *ea = DYNAMIC_CAST_CONST_PTR(ErrnoMessageArg, p);
-
- if (ea) {
- os() << strerror(ea->errnum());
- return;
- }
- const SearchResultMessageArg *sr
- = DYNAMIC_CAST_CONST_PTR(SearchResultMessageArg, p);
- if (sr) {
- for (size_t i = 0; i < sr->nTried(); i++) {
- if (i > 0)
- os() << ", ";
- const StringC &f = sr->filename(i);
- appendChars(f.data(), f.size());
- switch (sr->errnum(i)) {
- default:
- os() << " (";
- os() << strerror(sr->errnum(i));
- os() << ")";
- #ifdef ENOENT
- case ENOENT:
- #endif
- break;
- }
- }
- return;
- }
- appendFragment(MessageFormatterMessages::invalidArgumentType);
- }
- void MessageFormatter::Builder::appendFragment(const MessageFragment &frag)
- {
- formatter_->formatFragment(frag, os());
- }
- #ifdef SP_NAMESPACE
- }
- #endif