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