// Iffy // // Douglas Thrift // // $Id$ #include "Tag.hpp" #include "Matcher.hpp" #include #include #include #include struct IffyCommand : public app::Application { virtual int Run(const app::ArgumentList& args) { Iffy::program = api::GetExecutablePath().GetName(); ext::String in("-"), out("-"); for (size_t index(0); index < args.GetSize(); ++index) { Matcher matcher; if (args[index] == "-D") { if (!Iffy::debug) Iffy::debug = true; } else if (args[index] == matcher("^-in=(.+)$")) { in = matcher[1]; } else if (args[index] == matcher("^-out=(.+)$")) { out = matcher[1]; } else { api::Cout << "Usage: " << Iffy::program << " [-in=in] [-out=out] [-D]\n"; return 1; } } Iffy(in, out); return 0; } } iffy; Iffy::Iffy(const ext::String& in, const ext::String& out) { if (in == "-" && out == "-") { iffy(api::Cin, api::Cout); } else if (in == "-") { api::FileWriter fout(out); iffy(api::Cin, fout); } else if (out == "-") { api::FileReader fin(in); iffy(fin, api::Cout); } else { api::FileReader fin(in); api::FileWriter fout(out); iffy(fin, fout); } } ext::String Iffy::program; bool Iffy::debug(false); void Iffy::iffy(ios::Reader& in, ios::Writer& out) { ext::String segment; bool text(true); ios::FormatWriter fout(out); ext::Stack opens; while (read(in, segment, text)) if (text) { fout << segment; text = false; } else { Tag tag(segment); if (tag == "br") tag = STANDALONE; switch (tag) { case OPEN: opens.Push(tag); break; case CLOSE: if (tag != opens.Top()) tag = opens.Top(); opens.Pop(); break; default: break; } fout << tag; text = true; } } bool Iffy::read(ios::Reader& in, ext::String& segment, bool text) { segment.Clear(); byte_t atom; while (in.Get(atom)) { if (atom == (text ? '<' : '>')) return true; segment.InsertLast(atom); } return !segment.IsEmpty(); }