1 // Copyright (c) 1995, 1996 James Clark
2 // See the file COPYING for copying permission.
3
4 // FIXME usage message for bad -m option.
5
6 #include "config.h"
7 #include "SgmlParser.h"
8 #include "Event.h"
9 #include "OutputCharStream.h"
10 #include "ParserApp.h"
11 #include "Boolean.h"
12 #include "macros.h"
13 #include "SpamMessages.h"
14 #include "CopyEventHandler.h"
15 #include "InputSource.h"
16
17 #include "sptchar.h"
18
19 #include <stdlib.h>
20
21 #ifdef SP_NAMESPACE
22 using namespace SP_NAMESPACE;
23 #endif
24
25 class XCopyEventHandler : public CopyEventHandler {
26 public:
27 XCopyEventHandler(OutputCharStream *os, unsigned normalizeFlags,
28 const StringC &outputEntity, Messenger *);
29 void message(MessageEvent *);
30 private:
31 void reportTagInSpecialMarkedSection(const Location &);
32 Messenger *messenger_;
33 OutputCharStream *os_;
34 };
35
36 static
37 struct {
38 const ParserApp::AppChar *name;
39 unsigned flag;
40 } normalizeTable[] = {
41 { SP_T("omittag"), CopyEventHandler::normalizeOmittag },
42 { SP_T("shortref"), CopyEventHandler::normalizeShortref },
43 { SP_T("net"), CopyEventHandler::normalizeNet },
44 { SP_T("emptytag"), CopyEventHandler::normalizeEmptytag },
45 { SP_T("unclosed"), CopyEventHandler::normalizeUnclosed },
46 { SP_T("attname"), CopyEventHandler::normalizeAttname },
47 { SP_T("attvalue"), CopyEventHandler::normalizeAttvalue },
48 { SP_T("attspec"), CopyEventHandler::normalizeAttspec },
49 { SP_T("current"), CopyEventHandler::normalizeCurrent },
50 { SP_T("shorttag"), CopyEventHandler::normalizeShorttag },
51 { SP_T("rank"), CopyEventHandler::normalizeRank },
52 { SP_T("reserved"), CopyEventHandler::normalizeReserved },
53 { SP_T("ms"), CopyEventHandler::normalizeMarkedSection },
54 };
55
56 class SpamApp : public ParserApp {
57 public:
58 SpamApp();
59 ErrorCountEventHandler *makeEventHandler();
60 void processOption(AppChar opt, const AppChar *arg);
61 private:
62 unsigned normalizeFlags_;
63 StringC outputEntity_;
64 Boolean rawOutput_;
65 };
66
SP_DEFINE_APP(SpamApp)67 SP_DEFINE_APP(SpamApp)
68
69 SpamApp::SpamApp()
70 : rawOutput_(0), normalizeFlags_(0)
71 {
72 options_.eventsWanted.addInstanceMarkup();
73 options_.eventsWanted.addPrologMarkup();
74 changeOptionRegistration('h', AppChar(255));
75 registerOption('h', SP_T("hoist-omitted-tags"), SpamMessages::hHelp);
76 registerOption('l', SP_T("lowercase"), SpamMessages::lHelp);
77 registerOption('m', SP_T("markup-option"), SpamMessages::option,
78 SpamMessages::mHelp);
79 registerOption('o', SP_T("output-entity"), SpamMessages::name,
80 SpamMessages::oHelp);
81 registerOption('p', SP_T("output-prolog"), SpamMessages::pHelp);
82 registerOption('r', SP_T("raw"), SpamMessages::rHelp);
83 registerOption('x', SP_T("expand-references"), SpamMessages::xHelp);
84 registerInfo(SpamMessages::info1);
85 registerInfo(SpamMessages::info2);
86 registerInfo(SpamMessages::info3);
87 }
88
processOption(AppChar opt,const AppChar * arg)89 void SpamApp::processOption(AppChar opt, const AppChar *arg)
90 {
91 switch (opt) {
92 case AppChar(255):
93 ParserApp::processOption('h', arg);
94 break;
95 case 'h':
96 // hoist omitted tags out of entities
97 normalizeFlags_ |= CopyEventHandler::normalizeOmittagHoist;
98 break;
99 case 'l': // prefer lowercase
100 normalizeFlags_ |= CopyEventHandler::normalizeLower;
101 break;
102 case 'm':
103 {
104 Boolean found = 0;
105 for (size_t i = 0; i < SIZEOF(normalizeTable); i++)
106 if (tcscmp(normalizeTable[i].name, arg) == 0) {
107 found = 1;
108 normalizeFlags_ |= normalizeTable[i].flag;
109 break;
110 }
111 if (!found) {
112 message(SpamMessages::invalidMarkupArgument,
113 StringMessageArg(convertInput(arg)));
114 // usage(kit);
115 }
116 }
117 break;
118 case 'o':
119 outputEntity_ = convertInput(arg);
120 break;
121 case 'p':
122 if (normalizeFlags_ & CopyEventHandler::normalizeIncludeProlog)
123 normalizeFlags_ |= CopyEventHandler::normalizeExpandProlog;
124 else
125 normalizeFlags_ |= CopyEventHandler::normalizeIncludeProlog;
126 break;
127 case 'r':
128 rawOutput_ = 1;
129 break;
130 case 'x':
131 if (normalizeFlags_ & CopyEventHandler::normalizeExpand)
132 normalizeFlags_ |= CopyEventHandler::normalizeExpandAll;
133 else
134 normalizeFlags_ |= CopyEventHandler::normalizeExpand;
135 break;
136 default:
137 ParserApp::processOption(opt, arg);
138 break;
139 }
140 }
141
makeEventHandler()142 ErrorCountEventHandler *SpamApp::makeEventHandler()
143 {
144 OutputCharStream *os = makeStdOut();
145 if (!rawOutput_)
146 os = new RecordOutputCharStream(os);
147 return new XCopyEventHandler(os, normalizeFlags_, outputEntity_, this);
148 }
149
XCopyEventHandler(OutputCharStream * os,unsigned normalizeFlags,const StringC & outputEntity,Messenger * messenger)150 XCopyEventHandler::XCopyEventHandler(OutputCharStream *os,
151 unsigned normalizeFlags,
152 const StringC &outputEntity,
153 Messenger *messenger)
154 : messenger_(messenger), os_(os),
155 CopyEventHandler(os, normalizeFlags, outputEntity)
156 {
157 }
158
message(MessageEvent * event)159 void XCopyEventHandler::message(MessageEvent *event)
160 {
161 messenger_->dispatchMessage(event->message());
162 CopyEventHandler::message(event);
163 }
164
reportTagInSpecialMarkedSection(const Location & loc)165 void XCopyEventHandler::reportTagInSpecialMarkedSection(const Location &loc)
166 {
167 messenger_->setNextLocation(loc);
168 messenger_->message(SpamMessages::tagInSpecialMarkedSection);
169 }
170