/** Разбор URL-строки */ void UrlParser::parse() { port = 80; mainParse(url_); // Ищем первый вопросительный знак std::string::size_type pos = url_.find_first_of('?'); if (pos == std::string::npos) pos = -1; while (pos < url_.size() || pos == (std::string::size_type)-1) { // Выделяем название параметра std::string::size_type end = url_.find_first_of('=', ++pos); if (end == std::string::npos) return; std::string param_name = url_.substr(pos, end - pos); pos = end; // Выделяем значение параметра end = url_.find_first_of('&', ++pos); if (end == std::string::npos) end = url_.size(); std::string param_value = url_.substr(pos, end - pos); pos = end; params_[param_name] = percent_decode(param_value); } }
NPtr parseNode(I& be, I& en, Pos& pos) { eat(be, '<', pos); eatWhitespaceComment(be, en, pos); auto beCopy = be; for(; beCopy != en && std::isalnum(*beCopy); increment(beCopy, pos)) {} auto type = std::string(be, beCopy); be = beCopy; std::string classLit; // . std::string idLit; // # std::string attributes; // ( **** ) while(*be == '.' || *be == '#') { beCopy = be; increment(beCopy, pos); // eat the . or '#' assert(beCopy != en); bool tickEnclosed = false; if(*beCopy == '"') { tickEnclosed = true; increment(beCopy, pos); // eat the " while(beCopy != en && *beCopy != '"') { increment(beCopy, pos); } assert(*beCopy == '"'); increment(beCopy, pos); // eat the " } else { while(beCopy != en && (std::isalnum(*beCopy) || *beCopy == '-')) { increment(beCopy, pos); } } if(*be == '.') { classLit.insert(classLit.begin(), tickEnclosed ? be+2 : be+1, tickEnclosed ? beCopy-1 : beCopy); } else if(*be == '#') { idLit.insert(idLit.begin(), tickEnclosed ? be+2 : be+1, tickEnclosed ? beCopy-1 : beCopy); } be = beCopy; } if(*be == '(') { beCopy = be + 1; for(; *beCopy != ')'; increment(beCopy, pos)) {} attributes.insert(attributes.begin(), be+1, beCopy); be = beCopy; eat(be, ')', pos); } eatWhitespaceComment(be, en, pos); if(test(be, en, "/>")) { eat(be, "/>", pos); return std::make_unique<Node>(std::move(type), std::move(classLit), std::move(idLit), std::move(attributes), pos); } else { auto children = mainParse(be, en, pos); return std::make_unique<Node>(std::move(type), std::move(classLit), std::move(idLit), std::move(attributes), std::move(children), pos); } }
int main(int argc, char** argv) { const CmdOptions opt = parseOptions(argc, argv); if(!opt.allOk) { return 1; } std::ifstream in(opt.input, std::ios_base::in); if(!in) { std::cerr << "Error: Could not open input file: \'" << opt.input << "\'" << std::endl; return 1; } std::ostream* output = &std::cout; std::ofstream oFile; if(!opt.output.empty()) { oFile.open(opt.output, std::ofstream::out); output = &oFile; } std::string storage; // We will read the contents here. in.unsetf(std::ios::skipws); // No white space skipping! std::copy( std::istream_iterator<char>(in), std::istream_iterator<char>(), std::back_inserter(storage)); Pos pos; auto b = storage.begin(); auto e = storage.end(); *output<<"//This file is autogenerated from file: "<<opt.input<<"\n"; *output<<"#pragma once\n"; *output<<"\n#include <ostream>\n"; auto header = parseHeader(b, e, pos); header->gen(*output, 0); *output<<"template<typename O, typename P>\n"; *output<<"void "<<opt.functionName<<"(O& out, P& params) {\n"; if(!opt.noDocType && opt.docType.empty()) { *output<<"\tout<<\"<!DOCTYPE html>\\n\";"<<std::endl; } else if(!opt.noDocType) { *output<<"\tout<<\"<!DOCTYPE "<<opt.docType<<">\\n\";"; } auto rslt = mainParse(b, e, pos); for(auto& it : rslt) { it->gen(*output, 0); } *output<<"}\n"; return 0; }