1 /*-
2  * Copyright (c) 2004 Jacques A. Vidrine
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  */
27 #include <sys/param.h>
28 
29 #include <functional>
30 #include <algorithm>
31 #include <cctype>
32 #include <functional>
33 #include <iostream>
34 #include <map>
35 #include <string>
36 #include <vector>
37 
38 #include <vuxml/vuxml.hh>
39 
40 using namespace vuxml;
41 
42 
43 namespace {
44 const char *predefined_[] =
45 #if defined(XMLESCAPE_ALL_PREDEFINED)
46 { "<", "&lt;", ">", "&gt;", "&", "&amp;", "'", "&apos;", "\"", "&quot;", 0 }
47 #else
48 { "<", "&lt;", "&", "&amp;", "\"", "&quot;", 0 }
49 #endif
50 	;
51 
52 static std::map<char, std::string> predefined;
53 
54 struct PredefinedInitializer {
PredefinedInitializer__anon71d9eda30111::PredefinedInitializer55   PredefinedInitializer() {
56 	  const char **p;
57 	  for (p = predefined_; *p != 0 && *(p+1) != 0; p += 2)
58 		  predefined[**p] = *(p+1);
59   }
60 };
61 static PredefinedInitializer predefinedInitializer;
62 
63 struct isPredefinedCharacter : public std::unary_function<bool, char> {
64   std::string &esc_;
65   std::map<char, std::string>::const_iterator end_;
isPredefinedCharacter__anon71d9eda30111::isPredefinedCharacter66   isPredefinedCharacter(std::string &esc) :
67       esc_(esc), end_(predefined.end()) {}
operator ()__anon71d9eda30111::isPredefinedCharacter68   bool operator()(char c) {
69 	  std::map<char, std::string>::const_iterator p =
70 	      predefined.find(c);
71 	  if (p != end_)
72 		  esc_ = p->second;
73 	  return (p != end_);
74   }
75 };
76 }
77 
78 
79 std::string
xmlescape(const std::string & s)80 vuxml::xmlescape(const std::string &s)
81 {
82 	std::string out;
83 	std::string esc;
84 	isPredefinedCharacter pred(esc);
85 
86 	std::string::const_iterator q,  p;
87 	std::string::const_iterator end = s.end();
88 
89 	for (q = s.begin(); (p = std::find_if(q, end, pred)) != end; q = p+1) {
90 		if (q != p)
91 			out.append(q, p);
92 		out.append(esc);
93 	}
94 	out.append(q, end);
95 	return out;
96 }
97 
98 
99 #if defined(TEST)
100 #include <iostream>
101 int
main(int ac,char * av[])102 main(int ac, char *av[])
103 {
104 	std::cout << vuxml::xmlescape(av[1]) << '\n';
105 	return 0;
106 }
107 #endif
108 
109 
110 namespace {
111 class Killspace : public std::unary_function<void,char> {
112 public:
Killspace(std::string & result)113   Killspace(std::string &result) : space_(true), result_(result) {}
operator ()(char c)114   void operator()(char c) {
115 	if (!isspace(c)) {
116 		space_   = false;
117 		result_ += c;
118 	} else if (!space_) {
119 		space_   = true;
120 		result_ += ' ';
121 	}
122   }
123 private:
124   bool		 space_;
125   std::string	&result_;
126 };
127 }
128 
129 
130 std::string
killspace(const std::string & s)131 vuxml::killspace(const std::string &s)
132 {
133     std::string x;
134     std::for_each(s.begin(), s.end(), Killspace(x));
135     return x;
136 }
137 
138 
139 std::ostream &
log()140 vuxml::Logger::log()
141 {
142 	return std::cerr;
143 }
144 
145 
146 const char VersionRange::infinity[] = "-Infinity-";
147 const char VersionRange::zero[] = "-Zero-";
148 
149 
150 bool
contains(const std::string & version) const151 VersionRange::contains(const std::string &version) const
152 {
153 	int cmp;
154 	if (lo != VersionRange::zero) {
155 		cmp = version_cmp(version.c_str(), lo.c_str());
156 		if (!(cmp > 0 || (lo_closed && cmp == 0)))
157 			return false;
158 	}
159 	if (hi != VersionRange::infinity) {
160 		cmp = version_cmp(version.c_str(), hi.c_str());
161 		if (!(cmp < 0 || (hi_closed && cmp == 0)))
162 			return false;
163 	}
164 	return true;
165 }
166 
167 
Entry()168 Entry::Entry()  {}
~Entry()169 Entry::~Entry() {}
170 
171 
vid() const172 const std::string &Entry::vid() const { return vid_; }
setVid(const std::string & vid)173 void Entry::setVid(const std::string &vid) { vid_ = vid; }
174 
175 
topic() const176 const std::string &Entry::topic() const { return topic_; }
setTopic(const std::string & text)177 void Entry::setTopic(const std::string &text) { topic_ = text; }
178 
179 
description() const180 const std::string &Entry::description() const { return description_; }
setDescription(const std::string & text)181 void Entry::setDescription(const std::string &text) { description_ = text; }
182 
183 
appendDescription(const std::string & text)184 void Entry::appendDescription(const std::string &text)
185 {
186 	description_ += text;
187 }
188 
189 
discoveryDate() const190 const std::string &Entry::discoveryDate() const { return discovery_; }
setDiscoveryDate(const std::string & date)191 void Entry::setDiscoveryDate(const std::string &date) { discovery_ = date; }
192 
193 
entryDate() const194 const std::string &Entry::entryDate() const { return entry_; }
setEntryDate(const std::string & date)195 void Entry::setEntryDate(const std::string &date) { entry_ = date; }
196 
197 
modifiedDate() const198 const std::string &Entry::modifiedDate() const { return modified_; }
setModifiedDate(const std::string & date)199 void Entry::setModifiedDate(const std::string &date) { modified_ = date; }
200 
201 
references() const202 const std::vector<Reference> &Entry::references() const { return references_; }
203 
204 
205 void
addReference(const Reference & reference)206 Entry::addReference(const Reference &reference)
207 {
208 	references_.push_back(reference);
209 }
210 
211 
212 void
addReference(const std::string & type,const std::string & text)213 Entry::addReference(const std::string &type, const std::string &text)
214 {
215 	references_.push_back(Reference(type, text));
216 }
217 
218 
affected() const219 const std::vector<AffectedSet> &Entry::affected() const { return affected_; }
220 
221 
222 void
addAffectedSet()223 Entry::addAffectedSet()
224 {
225 	affected_.resize(affected_.size()+1);
226 }
227 
228 
229 void
addAffectedName(const std::string & name)230 Entry::addAffectedName(const std::string &name)
231 {
232 	AffectedSet &as = affected_.back();
233 	as.names.push_back(name);
234 }
235 
236 
237 void
addAffectedRange(const VersionRange & range)238 Entry::addAffectedRange(const VersionRange &range)
239 {
240 	AffectedSet &as = affected_.back();
241 	as.ranges.push_back(range);
242 }
243 
244 
EntryProcessor()245 EntryProcessor::EntryProcessor() {}
~EntryProcessor()246 EntryProcessor::~EntryProcessor() {}
start()247 void EntryProcessor::start() {}
end()248 void EntryProcessor::end() {}
249