d63ae51ba337165172a9b50fd5d84805ffe50044Tinderbox User// Automated Testing Framework (atf)
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews// Copyright (c) 2007 The NetBSD Foundation, Inc.
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews// All rights reserved.
819fe493f97078521bb6b9a7b97583bef89f5abcMark Andrews// Redistribution and use in source and binary forms, with or without
f5d30e2864e048a42c4dc1134993ae7efdb5d6c3Mark Andrews// modification, are permitted provided that the following conditions
33d96fbbc8aa221508f3c780539bf44810fd2c9cMark Andrews// 1. Redistributions of source code must retain the above copyright
33d96fbbc8aa221508f3c780539bf44810fd2c9cMark Andrews// notice, this list of conditions and the following disclaimer.
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// 2. Redistributions in binary form must reproduce the above copyright
33d96fbbc8aa221508f3c780539bf44810fd2c9cMark Andrews// notice, this list of conditions and the following disclaimer in the
33d96fbbc8aa221508f3c780539bf44810fd2c9cMark Andrews// documentation and/or other materials provided with the distribution.
33d96fbbc8aa221508f3c780539bf44810fd2c9cMark Andrews// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
33d96fbbc8aa221508f3c780539bf44810fd2c9cMark Andrews// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
33d96fbbc8aa221508f3c780539bf44810fd2c9cMark Andrews// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
33d96fbbc8aa221508f3c780539bf44810fd2c9cMark Andrews// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
33d96fbbc8aa221508f3c780539bf44810fd2c9cMark Andrews// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
bff64bf12b58a6f80e740e94f2e42a32df18113aEvan Hunt// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33d96fbbc8aa221508f3c780539bf44810fd2c9cMark Andrews// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
33d96fbbc8aa221508f3c780539bf44810fd2c9cMark Andrews// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
33d96fbbc8aa221508f3c780539bf44810fd2c9cMark Andrews// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
33d96fbbc8aa221508f3c780539bf44810fd2c9cMark Andrews// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
33d96fbbc8aa221508f3c780539bf44810fd2c9cMark Andrews// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt// ------------------------------------------------------------------------
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt// The "parse_error" class.
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt// ------------------------------------------------------------------------
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Huntimpl::parse_error::parse_error(size_t line, std::string msg) :
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein const throw()
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein oss << "LONELY PARSE ERROR: " << first << ": " << second;
c1a883f2e04d94e99c433b1f6cfd0c0338f4ed85Mark Andrews } catch (...) {
8077efca7d2ec3b9bf0428386a1ec2fcbcdf437bAutomatic Updater return "Could not format message for parsing error.";
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein return tools::text::to_string(first) + ": " + second;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// ------------------------------------------------------------------------
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt// The "parse_errors" class.
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// ------------------------------------------------------------------------
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein const throw()
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt } catch (...) {
30eec077db2bdcb6f2a0dc388a3cdde2ede75ec1Mark Andrews return "Could not format messages for parsing errors.";
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// ------------------------------------------------------------------------
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// The "format_error" class.
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// ------------------------------------------------------------------------
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinimpl::format_error::format_error(const std::string& w) :
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// ------------------------------------------------------------------------
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// The "token" class.
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// ------------------------------------------------------------------------
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// ------------------------------------------------------------------------
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// The "header_entry" class.
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// ------------------------------------------------------------------------
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinimpl::header_entry::header_entry(const std::string& n, const std::string& v,
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinimpl::header_entry::has_attr(const std::string& n) const
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinimpl::header_entry::get_attr(const std::string& n) const
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein attrs_map::const_iterator iter = m_attrs.find(n);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// ------------------------------------------------------------------------
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// The header tokenizer.
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// ------------------------------------------------------------------------
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinstatic const impl::token_type semicolon_type = 4;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinclass tokenizer : public impl::tokenizer< std::istream > {
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein (is, true, eof_type, nl_type, text_type, curline)
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinread(impl::parser< header::tokenizer >& p, impl::header_entry& he)
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein using namespace header;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein impl::token t = p.expect(text_type, nl_type, "a header name");
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein "eof, `;' or new line");
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein if (t.type() == eof_type || t.type() == nl_type)
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein t = p.expect(text_type, "word or quoted string");
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein he = impl::header_entry(hdr_name, hdr_value, attrs);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinwrite(std::ostream& os, const impl::header_entry& he)
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein std::string line = he.name() + ": " + he.value();
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein for (impl::attrs_map::const_iterator iter = as.begin(); iter != as.end();
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein assert((*iter).second.find('\"') == std::string::npos);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein line += "; " + (*iter).first + "=\"" + (*iter).second + "\"";
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein} // namespace header
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// ------------------------------------------------------------------------
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// Free functions.
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein// ------------------------------------------------------------------------
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinimpl::read_headers(std::istream& is, size_t curline)
3001a1b4e6298466882a4147307b4c28a3b08f91Mark Andrews // header = entry+ nl
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein // entry = line nl
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein // line = text colon text
561a29af8c54a216e7d30b5b4f6e0d21661654ecMark Andrews // (semicolon (text equal (text | dblquote string dblquote)))*
561a29af8c54a216e7d30b5b4f6e0d21661654ecMark Andrews // string = quoted_string
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein if (!header::read(p, he).good() || he.name().empty())
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein throw format_error("Could not determine content type");
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein return std::pair< size_t, headers_map >(tkz.lineno(), hm);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinimpl::write_headers(const impl::headers_map& hm, std::ostream& os)
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein headers_map::const_iterator ct = hm.find("Content-Type");
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein for (headers_map::const_iterator iter = hm.begin(); iter != hm.end();
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinimpl::validate_content_type(const impl::headers_map& hm, const std::string& fmt,
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein headers_map::const_iterator iter = hm.find("Content-Type");
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein throw format_error("Could not determine content type");
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein throw format_error("Mismatched content type: expected `" + fmt +
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein throw format_error("Could not determine version");
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein const std::string& vstr = tools::text::to_string(version);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein throw format_error("Mismatched version: expected `" +