1240116Smarcel// 2240116Smarcel// Automated Testing Framework (atf) 3240116Smarcel// 4240116Smarcel// Copyright (c) 2007 The NetBSD Foundation, Inc. 5240116Smarcel// All rights reserved. 6240116Smarcel// 7240116Smarcel// Redistribution and use in source and binary forms, with or without 8240116Smarcel// modification, are permitted provided that the following conditions 9240116Smarcel// are met: 10240116Smarcel// 1. Redistributions of source code must retain the above copyright 11240116Smarcel// notice, this list of conditions and the following disclaimer. 12240116Smarcel// 2. Redistributions in binary form must reproduce the above copyright 13240116Smarcel// notice, this list of conditions and the following disclaimer in the 14240116Smarcel// documentation and/or other materials provided with the distribution. 15240116Smarcel// 16240116Smarcel// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17240116Smarcel// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18240116Smarcel// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19240116Smarcel// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20240116Smarcel// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21240116Smarcel// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22240116Smarcel// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23240116Smarcel// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24240116Smarcel// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25240116Smarcel// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26240116Smarcel// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27240116Smarcel// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28240116Smarcel// 29240116Smarcel 30240116Smarcel#if !defined(_ATF_CXX_PARSER_HPP_) 31240116Smarcel#define _ATF_CXX_PARSER_HPP_ 32240116Smarcel 33240116Smarcel#include <istream> 34240116Smarcel#include <map> 35240116Smarcel#include <ostream> 36240116Smarcel#include <stdexcept> 37240116Smarcel#include <string> 38240116Smarcel#include <utility> 39240116Smarcel#include <vector> 40240116Smarcel 41240116Smarcelnamespace atf { 42240116Smarcelnamespace parser { 43240116Smarcel 44240116Smarcel// ------------------------------------------------------------------------ 45240116Smarcel// The "parse_error" class. 46240116Smarcel// ------------------------------------------------------------------------ 47240116Smarcel 48240116Smarcelclass parse_error : public std::runtime_error, 49240116Smarcel public std::pair< size_t, std::string > { 50240116Smarcel mutable std::string m_msg; 51240116Smarcel 52240116Smarcelpublic: 53240116Smarcel parse_error(size_t, std::string); 54240116Smarcel ~parse_error(void) throw(); 55240116Smarcel 56240116Smarcel const char* what(void) const throw(); 57240116Smarcel 58240116Smarcel operator std::string(void) const; 59240116Smarcel}; 60240116Smarcel 61240116Smarcel// ------------------------------------------------------------------------ 62240116Smarcel// The "parse_errors" class. 63240116Smarcel// ------------------------------------------------------------------------ 64240116Smarcel 65240116Smarcelclass parse_errors : public std::runtime_error, 66240116Smarcel public std::vector< parse_error > { 67240116Smarcel std::vector< parse_error > m_errors; 68240116Smarcel mutable std::string m_msg; 69240116Smarcel 70240116Smarcelpublic: 71240116Smarcel parse_errors(void); 72240116Smarcel ~parse_errors(void) throw(); 73240116Smarcel 74240116Smarcel const char* what(void) const throw(); 75240116Smarcel}; 76240116Smarcel 77240116Smarcel// ------------------------------------------------------------------------ 78240116Smarcel// The "format_error" class. 79240116Smarcel// ------------------------------------------------------------------------ 80240116Smarcel 81240116Smarcelclass format_error : public std::runtime_error { 82240116Smarcelpublic: 83240116Smarcel format_error(const std::string&); 84240116Smarcel}; 85240116Smarcel 86240116Smarcel// ------------------------------------------------------------------------ 87240116Smarcel// The "token" class. 88240116Smarcel// ------------------------------------------------------------------------ 89240116Smarcel 90240116Smarceltypedef int token_type; 91240116Smarcel 92240116Smarcel//! 93240116Smarcel//! \brief Representation of a read token. 94240116Smarcel//! 95240116Smarcel//! A pair that contains the information of a token read from a stream. 96240116Smarcel//! It contains the token's type and its associated data, if any. 97240116Smarcel//! 98240116Smarcelstruct token { 99240116Smarcel bool m_inited; 100240116Smarcel size_t m_line; 101240116Smarcel token_type m_type; 102240116Smarcel std::string m_text; 103240116Smarcel 104240116Smarcelpublic: 105240116Smarcel token(void); 106240116Smarcel token(size_t, const token_type&, const std::string& = ""); 107240116Smarcel 108240116Smarcel size_t lineno(void) const; 109240116Smarcel const token_type& type(void) const; 110240116Smarcel const std::string& text(void) const; 111240116Smarcel 112240116Smarcel operator bool(void) const; 113240116Smarcel bool operator!(void) const; 114240116Smarcel}; 115240116Smarcel 116240116Smarcel// ------------------------------------------------------------------------ 117240116Smarcel// The "tokenizer" class. 118240116Smarcel// ------------------------------------------------------------------------ 119240116Smarcel 120240116Smarcel//! 121240116Smarcel//! \brief A stream tokenizer. 122240116Smarcel//! 123240116Smarcel//! This template implements an extremely simple, line-oriented stream 124240116Smarcel//! tokenizer. It is only able to recognize one character-long delimiters, 125240116Smarcel//! random-length keywords, skip whitespace and, anything that does not 126240116Smarcel//! match these rules is supposed to be a word. 127240116Smarcel//! 128240116Smarcel//! Parameter IS: The input stream's type. 129240116Smarcel//! 130240116Smarceltemplate< class IS > 131240116Smarcelclass tokenizer { 132240116Smarcel IS& m_is; 133240116Smarcel size_t m_lineno; 134240116Smarcel token m_la; 135240116Smarcel 136240116Smarcel bool m_skipws; 137240116Smarcel token_type m_eof_type, m_nl_type, m_text_type; 138240116Smarcel 139240116Smarcel std::map< char, token_type > m_delims_map; 140240116Smarcel std::string m_delims_str; 141240116Smarcel 142240116Smarcel char m_quotech; 143240116Smarcel token_type m_quotetype; 144240116Smarcel 145240116Smarcel std::map< std::string, token_type > m_keywords_map; 146240116Smarcel 147240116Smarcel token_type alloc_type(void); 148240116Smarcel 149240116Smarcel template< class TKZ > 150240116Smarcel friend 151240116Smarcel class parser; 152240116Smarcel 153240116Smarcelpublic: 154240116Smarcel tokenizer(IS&, bool, const token_type&, const token_type&, 155240116Smarcel const token_type&, size_t = 1); 156240116Smarcel 157240116Smarcel size_t lineno(void) const; 158240116Smarcel 159240116Smarcel void add_delim(char, const token_type&); 160240116Smarcel void add_keyword(const std::string&, const token_type&); 161240116Smarcel void add_quote(char, const token_type&); 162240116Smarcel 163240116Smarcel token next(void); 164240116Smarcel std::string rest_of_line(void); 165240116Smarcel}; 166240116Smarcel 167240116Smarceltemplate< class IS > 168240116Smarceltokenizer< IS >::tokenizer(IS& p_is, 169240116Smarcel bool p_skipws, 170240116Smarcel const token_type& p_eof_type, 171240116Smarcel const token_type& p_nl_type, 172240116Smarcel const token_type& p_text_type, 173240116Smarcel size_t p_lineno) : 174240116Smarcel m_is(p_is), 175240116Smarcel m_lineno(p_lineno), 176240116Smarcel m_skipws(p_skipws), 177240116Smarcel m_eof_type(p_eof_type), 178240116Smarcel m_nl_type(p_nl_type), 179240116Smarcel m_text_type(p_text_type), 180240116Smarcel m_quotech(-1) 181240116Smarcel{ 182240116Smarcel} 183240116Smarcel 184240116Smarceltemplate< class IS > 185240116Smarcelsize_t 186240116Smarceltokenizer< IS >::lineno(void) 187240116Smarcel const 188240116Smarcel{ 189240116Smarcel return m_lineno; 190240116Smarcel} 191240116Smarcel 192240116Smarceltemplate< class IS > 193240116Smarcelvoid 194240116Smarceltokenizer< IS >::add_delim(char delim, const token_type& type) 195240116Smarcel{ 196240116Smarcel m_delims_map[delim] = type; 197240116Smarcel m_delims_str += delim; 198240116Smarcel} 199240116Smarcel 200240116Smarceltemplate< class IS > 201240116Smarcelvoid 202240116Smarceltokenizer< IS >::add_keyword(const std::string& keyword, 203240116Smarcel const token_type& type) 204240116Smarcel{ 205240116Smarcel m_keywords_map[keyword] = type; 206240116Smarcel} 207240116Smarcel 208240116Smarceltemplate< class IS > 209240116Smarcelvoid 210240116Smarceltokenizer< IS >::add_quote(char ch, const token_type& type) 211240116Smarcel{ 212240116Smarcel m_quotech = ch; 213240116Smarcel m_quotetype = type; 214240116Smarcel} 215240116Smarcel 216240116Smarceltemplate< class IS > 217240116Smarceltoken 218240116Smarceltokenizer< IS >::next(void) 219240116Smarcel{ 220240116Smarcel if (m_la) { 221240116Smarcel token t = m_la; 222240116Smarcel m_la = token(); 223240116Smarcel if (t.type() == m_nl_type) 224240116Smarcel m_lineno++; 225240116Smarcel return t; 226240116Smarcel } 227240116Smarcel 228240116Smarcel char ch; 229240116Smarcel std::string text; 230240116Smarcel 231240116Smarcel bool done = false, quoted = false; 232240116Smarcel token t(m_lineno, m_eof_type, "<<EOF>>"); 233240116Smarcel while (!done && m_is.get(ch).good()) { 234240116Smarcel if (ch == m_quotech) { 235240116Smarcel if (text.empty()) { 236240116Smarcel bool escaped = false; 237240116Smarcel while (!done && m_is.get(ch).good()) { 238240116Smarcel if (!escaped) { 239240116Smarcel if (ch == '\\') 240240116Smarcel escaped = true; 241240116Smarcel else if (ch == '\n') { 242240116Smarcel m_la = token(m_lineno, m_nl_type, "<<NEWLINE>>"); 243240116Smarcel throw parse_error(t.lineno(), 244240116Smarcel "Missing double quotes before " 245240116Smarcel "end of line"); 246240116Smarcel } else if (ch == m_quotech) 247240116Smarcel done = true; 248240116Smarcel else 249240116Smarcel text += ch; 250240116Smarcel } else { 251240116Smarcel text += ch; 252240116Smarcel escaped = false; 253240116Smarcel } 254240116Smarcel } 255240116Smarcel if (!m_is.good()) 256240116Smarcel throw parse_error(t.lineno(), 257240116Smarcel "Missing double quotes before " 258240116Smarcel "end of file"); 259240116Smarcel t = token(m_lineno, m_text_type, text); 260240116Smarcel quoted = true; 261240116Smarcel } else { 262240116Smarcel m_is.unget(); 263240116Smarcel done = true; 264240116Smarcel } 265240116Smarcel } else { 266240116Smarcel typename std::map< char, token_type >::const_iterator idelim; 267240116Smarcel idelim = m_delims_map.find(ch); 268240116Smarcel if (idelim != m_delims_map.end()) { 269240116Smarcel done = true; 270240116Smarcel if (text.empty()) 271240116Smarcel t = token(m_lineno, (*idelim).second, 272240116Smarcel std::string("") + ch); 273240116Smarcel else 274240116Smarcel m_is.unget(); 275240116Smarcel } else if (ch == '\n') { 276240116Smarcel done = true; 277240116Smarcel if (text.empty()) 278240116Smarcel t = token(m_lineno, m_nl_type, "<<NEWLINE>>"); 279240116Smarcel else 280240116Smarcel m_is.unget(); 281240116Smarcel } else if (m_skipws && (ch == ' ' || ch == '\t')) { 282240116Smarcel if (!text.empty()) 283240116Smarcel done = true; 284240116Smarcel } else 285240116Smarcel text += ch; 286240116Smarcel } 287240116Smarcel } 288240116Smarcel 289240116Smarcel if (!quoted && !text.empty()) { 290240116Smarcel typename std::map< std::string, token_type >::const_iterator ikw; 291240116Smarcel ikw = m_keywords_map.find(text); 292240116Smarcel if (ikw != m_keywords_map.end()) 293240116Smarcel t = token(m_lineno, (*ikw).second, text); 294240116Smarcel else 295240116Smarcel t = token(m_lineno, m_text_type, text); 296240116Smarcel } 297240116Smarcel 298240116Smarcel if (t.type() == m_nl_type) 299240116Smarcel m_lineno++; 300240116Smarcel 301240116Smarcel return t; 302240116Smarcel} 303240116Smarcel 304240116Smarceltemplate< class IS > 305240116Smarcelstd::string 306240116Smarceltokenizer< IS >::rest_of_line(void) 307240116Smarcel{ 308240116Smarcel std::string str; 309240116Smarcel while (m_is.good() && m_is.peek() != '\n') 310240116Smarcel str += m_is.get(); 311240116Smarcel return str; 312240116Smarcel} 313240116Smarcel 314240116Smarcel// ------------------------------------------------------------------------ 315240116Smarcel// The "parser" class. 316240116Smarcel// ------------------------------------------------------------------------ 317240116Smarcel 318240116Smarceltemplate< class TKZ > 319240116Smarcelclass parser { 320240116Smarcel TKZ& m_tkz; 321240116Smarcel token m_last; 322240116Smarcel parse_errors m_errors; 323240116Smarcel bool m_thrown; 324240116Smarcel 325240116Smarcelpublic: 326240116Smarcel parser(TKZ& tkz); 327240116Smarcel ~parser(void); 328240116Smarcel 329240116Smarcel bool good(void) const; 330240116Smarcel void add_error(const parse_error&); 331240116Smarcel bool has_errors(void) const; 332240116Smarcel 333240116Smarcel token next(void); 334240116Smarcel std::string rest_of_line(void); 335240116Smarcel token reset(const token_type&); 336240116Smarcel 337240116Smarcel token 338240116Smarcel expect(const token_type&, 339240116Smarcel const std::string&); 340240116Smarcel 341240116Smarcel token 342240116Smarcel expect(const token_type&, 343240116Smarcel const token_type&, 344240116Smarcel const std::string&); 345240116Smarcel 346240116Smarcel token 347240116Smarcel expect(const token_type&, 348240116Smarcel const token_type&, 349240116Smarcel const token_type&, 350240116Smarcel const std::string&); 351240116Smarcel 352240116Smarcel token 353240116Smarcel expect(const token_type&, 354240116Smarcel const token_type&, 355240116Smarcel const token_type&, 356240116Smarcel const token_type&, 357240116Smarcel const std::string&); 358240116Smarcel 359240116Smarcel token 360240116Smarcel expect(const token_type&, 361240116Smarcel const token_type&, 362240116Smarcel const token_type&, 363240116Smarcel const token_type&, 364240116Smarcel const token_type&, 365240116Smarcel const token_type&, 366240116Smarcel const token_type&, 367240116Smarcel const std::string&); 368240116Smarcel 369240116Smarcel token 370240116Smarcel expect(const token_type&, 371240116Smarcel const token_type&, 372240116Smarcel const token_type&, 373240116Smarcel const token_type&, 374240116Smarcel const token_type&, 375240116Smarcel const token_type&, 376240116Smarcel const token_type&, 377240116Smarcel const token_type&, 378240116Smarcel const std::string&); 379240116Smarcel}; 380240116Smarcel 381240116Smarceltemplate< class TKZ > 382240116Smarcelparser< TKZ >::parser(TKZ& tkz) : 383240116Smarcel m_tkz(tkz), 384240116Smarcel m_thrown(false) 385240116Smarcel{ 386240116Smarcel} 387240116Smarcel 388240116Smarceltemplate< class TKZ > 389240116Smarcelparser< TKZ >::~parser(void) 390240116Smarcel{ 391240116Smarcel if (!m_errors.empty() && !m_thrown) 392240116Smarcel throw m_errors; 393240116Smarcel} 394240116Smarcel 395240116Smarceltemplate< class TKZ > 396240116Smarcelbool 397240116Smarcelparser< TKZ >::good(void) 398240116Smarcel const 399240116Smarcel{ 400240116Smarcel return m_tkz.m_is.good(); 401240116Smarcel} 402240116Smarcel 403240116Smarceltemplate< class TKZ > 404240116Smarcelvoid 405240116Smarcelparser< TKZ >::add_error(const parse_error& pe) 406240116Smarcel{ 407240116Smarcel m_errors.push_back(pe); 408240116Smarcel} 409240116Smarcel 410240116Smarceltemplate< class TKZ > 411240116Smarcelbool 412240116Smarcelparser< TKZ >::has_errors(void) 413240116Smarcel const 414240116Smarcel{ 415240116Smarcel return !m_errors.empty(); 416240116Smarcel} 417240116Smarcel 418240116Smarceltemplate< class TKZ > 419240116Smarceltoken 420240116Smarcelparser< TKZ >::next(void) 421240116Smarcel{ 422240116Smarcel token t = m_tkz.next(); 423240116Smarcel 424240116Smarcel m_last = t; 425240116Smarcel 426240116Smarcel if (t.type() == m_tkz.m_eof_type) { 427240116Smarcel if (!m_errors.empty()) { 428240116Smarcel m_thrown = true; 429240116Smarcel throw m_errors; 430240116Smarcel } 431240116Smarcel } 432240116Smarcel 433240116Smarcel return t; 434240116Smarcel} 435240116Smarcel 436240116Smarceltemplate< class TKZ > 437240116Smarcelstd::string 438240116Smarcelparser< TKZ >::rest_of_line(void) 439240116Smarcel{ 440240116Smarcel return m_tkz.rest_of_line(); 441240116Smarcel} 442240116Smarcel 443240116Smarceltemplate< class TKZ > 444240116Smarceltoken 445240116Smarcelparser< TKZ >::reset(const token_type& stop) 446240116Smarcel{ 447240116Smarcel token t = m_last; 448240116Smarcel 449240116Smarcel while (t.type() != m_tkz.m_eof_type && t.type() != stop) 450240116Smarcel t = next(); 451240116Smarcel 452240116Smarcel return t; 453240116Smarcel} 454240116Smarcel 455240116Smarceltemplate< class TKZ > 456240116Smarceltoken 457240116Smarcelparser< TKZ >::expect(const token_type& t1, 458240116Smarcel const std::string& textual) 459240116Smarcel{ 460240116Smarcel token t = next(); 461240116Smarcel 462240116Smarcel if (t.type() != t1) 463240116Smarcel throw parse_error(t.lineno(), 464240116Smarcel "Unexpected token `" + t.text() + 465240116Smarcel "'; expected " + textual); 466240116Smarcel 467240116Smarcel return t; 468240116Smarcel} 469240116Smarcel 470240116Smarceltemplate< class TKZ > 471240116Smarceltoken 472240116Smarcelparser< TKZ >::expect(const token_type& t1, 473240116Smarcel const token_type& t2, 474240116Smarcel const std::string& textual) 475240116Smarcel{ 476240116Smarcel token t = next(); 477240116Smarcel 478240116Smarcel if (t.type() != t1 && t.type() != t2) 479240116Smarcel throw parse_error(t.lineno(), 480240116Smarcel "Unexpected token `" + t.text() + 481240116Smarcel "'; expected " + textual); 482240116Smarcel 483240116Smarcel return t; 484240116Smarcel} 485240116Smarcel 486240116Smarceltemplate< class TKZ > 487240116Smarceltoken 488240116Smarcelparser< TKZ >::expect(const token_type& t1, 489240116Smarcel const token_type& t2, 490240116Smarcel const token_type& t3, 491240116Smarcel const std::string& textual) 492240116Smarcel{ 493240116Smarcel token t = next(); 494240116Smarcel 495240116Smarcel if (t.type() != t1 && t.type() != t2 && t.type() != t3) 496240116Smarcel throw parse_error(t.lineno(), 497240116Smarcel "Unexpected token `" + t.text() + 498240116Smarcel "'; expected " + textual); 499240116Smarcel 500240116Smarcel return t; 501240116Smarcel} 502240116Smarcel 503240116Smarceltemplate< class TKZ > 504240116Smarceltoken 505240116Smarcelparser< TKZ >::expect(const token_type& t1, 506240116Smarcel const token_type& t2, 507240116Smarcel const token_type& t3, 508240116Smarcel const token_type& t4, 509240116Smarcel const std::string& textual) 510240116Smarcel{ 511240116Smarcel token t = next(); 512240116Smarcel 513240116Smarcel if (t.type() != t1 && t.type() != t2 && t.type() != t3 && 514240116Smarcel t.type() != t4) 515240116Smarcel throw parse_error(t.lineno(), 516240116Smarcel "Unexpected token `" + t.text() + 517240116Smarcel "'; expected " + textual); 518240116Smarcel 519240116Smarcel return t; 520240116Smarcel} 521240116Smarcel 522240116Smarceltemplate< class TKZ > 523240116Smarceltoken 524240116Smarcelparser< TKZ >::expect(const token_type& t1, 525240116Smarcel const token_type& t2, 526240116Smarcel const token_type& t3, 527240116Smarcel const token_type& t4, 528240116Smarcel const token_type& t5, 529240116Smarcel const token_type& t6, 530240116Smarcel const token_type& t7, 531240116Smarcel const std::string& textual) 532240116Smarcel{ 533240116Smarcel token t = next(); 534240116Smarcel 535240116Smarcel if (t.type() != t1 && t.type() != t2 && t.type() != t3 && 536240116Smarcel t.type() != t4 && t.type() != t5 && t.type() != t6 && 537240116Smarcel t.type() != t7) 538240116Smarcel throw parse_error(t.lineno(), 539240116Smarcel "Unexpected token `" + t.text() + 540240116Smarcel "'; expected " + textual); 541240116Smarcel 542240116Smarcel return t; 543240116Smarcel} 544240116Smarcel 545240116Smarceltemplate< class TKZ > 546240116Smarceltoken 547240116Smarcelparser< TKZ >::expect(const token_type& t1, 548240116Smarcel const token_type& t2, 549240116Smarcel const token_type& t3, 550240116Smarcel const token_type& t4, 551240116Smarcel const token_type& t5, 552240116Smarcel const token_type& t6, 553240116Smarcel const token_type& t7, 554240116Smarcel const token_type& t8, 555240116Smarcel const std::string& textual) 556240116Smarcel{ 557240116Smarcel token t = next(); 558240116Smarcel 559240116Smarcel if (t.type() != t1 && t.type() != t2 && t.type() != t3 && 560240116Smarcel t.type() != t4 && t.type() != t5 && t.type() != t6 && 561240116Smarcel t.type() != t7 && t.type() != t8) 562240116Smarcel throw parse_error(t.lineno(), 563240116Smarcel "Unexpected token `" + t.text() + 564240116Smarcel "'; expected " + textual); 565240116Smarcel 566240116Smarcel return t; 567240116Smarcel} 568240116Smarcel 569240116Smarcel#define ATF_PARSER_CALLBACK(parser, func) \ 570240116Smarcel do { \ 571240116Smarcel if (!(parser).has_errors()) \ 572240116Smarcel func; \ 573240116Smarcel } while (false) 574240116Smarcel 575240116Smarcel// ------------------------------------------------------------------------ 576240116Smarcel// Header parsing. 577240116Smarcel// ------------------------------------------------------------------------ 578240116Smarcel 579240116Smarceltypedef std::map< std::string, std::string > attrs_map; 580240116Smarcel 581240116Smarcelclass header_entry { 582240116Smarcel std::string m_name; 583240116Smarcel std::string m_value; 584240116Smarcel attrs_map m_attrs; 585240116Smarcel 586240116Smarcelpublic: 587240116Smarcel header_entry(void); 588240116Smarcel header_entry(const std::string&, const std::string&, 589240116Smarcel attrs_map = attrs_map()); 590240116Smarcel 591240116Smarcel const std::string& name(void) const; 592240116Smarcel const std::string& value(void) const; 593240116Smarcel const attrs_map& attrs(void) const; 594240116Smarcel bool has_attr(const std::string&) const; 595240116Smarcel const std::string& get_attr(const std::string&) const; 596240116Smarcel}; 597240116Smarcel 598240116Smarceltypedef std::map< std::string, header_entry > headers_map; 599240116Smarcel 600240116Smarcelstd::pair< size_t, headers_map > read_headers(std::istream&, size_t); 601240116Smarcelvoid write_headers(const headers_map&, std::ostream&); 602240116Smarcelvoid validate_content_type(const headers_map&, const std::string&, int); 603240116Smarcel 604240116Smarcel} // namespace parser 605240116Smarcel} // namespace atf 606240116Smarcel 607240116Smarcel#endif // !defined(_ATF_CXX_PARSER_HPP_) 608