// file : cli/runtime-source.cxx // author : Boris Kolpackov // copyright : Copyright (c) 2009 Code Synthesis Tools CC // license : MIT; see accompanying LICENSE file #include "runtime-source.hxx" using namespace std; void generate_runtime_source (context& ctx) { ostream& os (ctx.os); os << "#include " << endl << "#include " << endl << "#include " << endl << "#include " << endl << "#include " << endl << "#include " << endl << endl; os << "namespace cli" << "{"; // unknown_option // os << "// unknown_option" << endl << "//" << endl << "unknown_option::" << endl << "~unknown_option () throw ()" << "{" << "}" << "void unknown_option::" << endl << "print (std::ostream& os) const" << "{" << "os << \"unknown option '\" << option () << \"'\";" << "}" << "const char* unknown_option::" << endl << "what () const throw ()" << "{" << "return \"unknown option\";" << "}"; // unknown_argument // os << "// unknown_argument" << endl << "//" << endl << "unknown_argument::" << endl << "~unknown_argument () throw ()" << "{" << "}" << "void unknown_argument::" << endl << "print (std::ostream& os) const" << "{" << "os << \"unknown argument '\" << argument () << \"'\";" << "}" << "const char* unknown_argument::" << endl << "what () const throw ()" << "{" << "return \"unknown argument\";" << "}"; // missing_value // os << "// missing_value" << endl << "//" << endl << "missing_value::" << endl << "~missing_value () throw ()" << "{" << "}" << "void missing_value::" << endl << "print (std::ostream& os) const" << "{" << "os << \"missing value for option '\" << option () << \"'\";" << "}" << "const char* missing_value::" << endl << "what () const throw ()" << "{" << "return \"missing option value\";" << "}"; // invalid_value // os << "// invalid_value" << endl << "//" << endl << "invalid_value::" << endl << "~invalid_value () throw ()" << "{" << "}" << "void invalid_value::" << endl << "print (std::ostream& os) const" << "{" << "os << \"invalid value '\" << value () << \"' for option '\"" << endl << " << option () << \"'\";" << "}" << "const char* invalid_value::" << endl << "what () const throw ()" << "{" << "return \"invalid option value\";" << "}"; // parser class template & its specializations // os << "template " << endl << "struct parser" << "{" << "static int" << endl << "parse (X& x, char** argv, int n)" << "{" << "if (n > 1)" << "{" << "std::istringstream is (argv[1]);" << "if (!(is >> x && is.eof ()))" << endl << "throw invalid_value (argv[0], argv[1]);" << "return 2;" << "}" << "else" << endl << "throw missing_value (argv[0]);" << "}" << "};"; // parser // os << "template <>" << endl << "struct parser" << "{" << "static int" << endl << "parse (bool& x, char**, int)" << "{" << "x = true;" << "return 1;" << "}" << "};"; // parser // os << "template <>" << endl << "struct parser" << "{" << "static int" << endl << "parse (std::string& x, char** argv, int n)" << "{" << "if (n > 1)" << "{" << "x = argv[1];" << "return 2;" << "}" << "else" << endl << "throw missing_value (argv[0]);" << "}" << "};"; // parser> // os << "template " << endl << "struct parser >" << "{" << "static int" << endl << "parse (std::vector& v, char** argv, int n)" << "{" << "X x;" << "int i = parser::parse (x, argv, n);" << "v.push_back (x);" << "return i;" << "}" << "};"; // parser> // os << "template " << endl << "struct parser >" << "{" << "static int" << endl << "parse (std::set& s, char** argv, int n)" << "{" << "X x;" << "int i = parser::parse (x, argv, n);" << "s.insert (x);" << "return i;" << "}" << "};"; // parser> // os << "template " << endl << "struct parser >" << "{" << "static int" << endl << "parse (std::map& m, char** argv, int n)" << "{" << "if (n > 1)" << "{" << "std::string s (argv[1]);" << "std::string::size_type p = s.find ('=');" << endl << "if (p == std::string::npos)" << "{" << "K k = K ();" << endl << "if (!s.empty ())" << "{" << "std::istringstream ks (s);" << endl << "if (!(ks >> k && ks.eof ()))" << endl << "throw invalid_value (argv[0], argv[1]);" << "}" << "m[k] = V ();" << "}" << "else" << "{" << "K k = K ();" << "V v = V ();" << "std::string kstr (s, 0, p);" << "std::string vstr (s, p + 1);" << endl << "if (!kstr.empty ())" << "{" << "std::istringstream ks (kstr);" << endl << "if (!(ks >> k && ks.eof ()))" << endl << "throw invalid_value (argv[0], argv[1]);" << "}" << "if (!vstr.empty ())" << "{" << "std::istringstream vs (vstr);" << endl << "if (!(vs >> v && vs.eof ()))" << endl << "throw invalid_value (argv[0], argv[1]);" << "}" << "m[k] = v;" << "}" << "return 2;" << "}" << "else" << endl << "throw missing_value (argv[0]);" << "}" << "};"; // Parser thunk. // os << "template " << endl << "int" << endl << "thunk (X& x, char** argv, int n)" << "{" << "return parser::parse (x.*P, argv, n);" << "}"; os << "}"; // namespace cli }