test_ncbiargs.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:18k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: test_ncbiargs.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:09:55  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R6.22
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: test_ncbiargs.cpp,v 1000.1 2004/06/01 19:09:55 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Authors:  Anton Butanayev, Denis Vakatov
  35.  *
  36.  * File Description:
  37.  *   Test for the command-line arguments' processing ("ncbiargs.[ch]pp"):
  38.  *
  39.  */
  40. #include <ncbi_pch.hpp>
  41. #include <corelib/ncbiapp.hpp>
  42. #include <corelib/ncbienv.hpp>
  43. #include <corelib/ncbiargs.hpp>
  44. #include <test/test_assert.h>  /* This header must go last */
  45. USING_NCBI_SCOPE;
  46. // Extended test for all different types of arguments  [default test]
  47. static void s_InitTest0(CArgDescriptions& arg_desc)
  48. {
  49.     // Describe the expected command-line arguments
  50.     arg_desc.AddOptionalPositional
  51.         ("logfile",
  52.          "This is an optional named positional argument without default value",
  53.          CArgDescriptions::eOutputFile,
  54.          CArgDescriptions::fPreOpen | CArgDescriptions::fBinary);
  55.     arg_desc.AddFlag
  56.         ("f2",
  57.          "This is another flag argument:  FALSE if set, TRUE if not set",
  58.          false);
  59.     arg_desc.AddPositional
  60.         ("barfooetc",
  61.          "This is a mandatory plain (named positional) argument",
  62.          CArgDescriptions::eString);
  63.     arg_desc.SetConstraint
  64.         ("barfooetc", &(*new CArgAllow_Strings, "foo", "bar", "etc"));
  65.     arg_desc.AddDefaultKey
  66.         ("kd", "DefaultKey",
  67.          "This is an optional integer key argument, with default value",
  68.          CArgDescriptions::eInteger, "123");
  69.     arg_desc.SetConstraint
  70.         ("kd", new CArgAllow_Integers(0, 200));
  71.     arg_desc.AddExtra
  72.         (0,  // no mandatory extra args
  73.          3,  // up to 3 optional extra args
  74.          "These are the optional extra (unnamed positional) arguments. "
  75.          "They will be printed out to the file specified by the "
  76.          "2nd positional argument,n"logfile"",
  77.          CArgDescriptions::eBoolean);
  78.     arg_desc.AddKey
  79.         ("k", "MandatoryKey",
  80.          "This is a mandatory alpha-num key argument",
  81.          CArgDescriptions::eString);
  82.     arg_desc.SetConstraint
  83.         ("k", new CArgAllow_String(CArgAllow_Symbols::eAlnum));
  84.     arg_desc.AddOptionalKey
  85.         ("ko", "OptionalKey",
  86.          "This is another optional key argument, without default value",
  87.          CArgDescriptions::eBoolean);
  88.     arg_desc.AddFlag
  89.         ("f1",
  90.          "This is a flag argument:  TRUE if set, FALSE if not set");
  91.     arg_desc.AddDefaultPositional
  92.         ("one_symbol",
  93.          "This is an optional named positional argument with default value",
  94.          CArgDescriptions::eString, "a");
  95.     arg_desc.SetConstraint
  96.         ("one_symbol", new CArgAllow_Symbols(" aBtCd"));
  97. }
  98. static void s_RunTest0(const CArgs& args, ostream& os)
  99. {
  100.     assert(!args.Exist(kEmptyStr));  // never exists;  use #1, #2, ... instead
  101.     assert(args.Exist("f1"));
  102.     assert(args.Exist("logfile"));
  103.     assert(args["barfooetc"]);
  104.     if ( !args["logfile"] )
  105.         return;
  106.     // Printout argument values
  107.     os << "Printing arguments to file `"
  108.        << args["logfile"].AsString() << "'..." << endl;
  109.     ostream& lg = args["logfile"].AsOutputFile();
  110.     lg << "k:         " << args["k"].AsString() << endl;
  111.     lg << "barfooetc: " << args["barfooetc"].AsString() << endl;
  112.     lg << "logfile:   " << args["logfile"].AsString() << endl;
  113.     if ( args["ko"] ) {
  114.         lg << "ko:        " << NStr::BoolToString(args["ko"].AsBoolean())
  115.            << endl;
  116.     } else {
  117.         lg << "ko:        not provided" << endl;
  118.         bool is_thrown = false;
  119.         try {
  120.             (void) args["ko"].AsString();
  121.         } catch (CArgException& e) {
  122.             is_thrown = true;
  123.             NCBI_REPORT_EXCEPTION("CArgException is thrown:",e);
  124.         }
  125.         assert(is_thrown);
  126.     }
  127.     if ( args["f1"] ) {
  128.         assert(args["f1"].AsBoolean());
  129.     }
  130.     if ( args["f2"] ) {
  131.         assert(args["f2"].AsBoolean());
  132.     }
  133.     // Extra (unnamed positional) arguments
  134.     if ( args.GetNExtra() ) {
  135.         for (size_t extra = 1;  extra <= args.GetNExtra();  extra++) {
  136.             lg << "#" << extra << ":        "
  137.                << NStr::BoolToString(args[extra].AsBoolean())
  138.                << "   (passed as `" << args[extra].AsString() << "')"
  139.                << endl;
  140.         }
  141.     } else {
  142.         lg << "(no unnamed positional arguments passed in the cmd-line)"
  143.            << endl;
  144.     }
  145.     // Separator
  146.     lg << string(44, '-') << endl;
  147. }
  148. // Allowing
  149. static void s_InitTest9(CArgDescriptions& arg_desc)
  150. {
  151.     arg_desc.AddKey("a",
  152.                     "alphaNumericKey",
  153.                     "This is a test alpha-num argument",
  154.                     CArgDescriptions::eString);
  155.     arg_desc.AddKey("i",
  156.                     "integerKey",
  157.                     "This is a test integer argument",
  158.                     CArgDescriptions::eInteger);
  159.     arg_desc.SetConstraint("a", &(*new CArgAllow_Strings, "foo", "bar", "qq"));
  160.     arg_desc.SetConstraint("i", new CArgAllow_Integers(-3, 34));
  161. }
  162. static void s_RunTest9(const CArgs& args, ostream& os)
  163. {
  164.     os << "a=" << args["a"].AsString()  << endl;
  165.     os << "i=" << args["i"].AsInteger() << endl;
  166. }
  167. // Argument with default walue
  168. static void s_InitTest8(CArgDescriptions& arg_desc)
  169. {
  170.     arg_desc.AddDefaultKey
  171.         ("k", "alphaNumericKey",
  172.          "This is an optional argument with default value",
  173.          CArgDescriptions::eString, "CORELIB");
  174. }
  175. static void s_RunTest8(const CArgs& args, ostream& os)
  176. {
  177.     os << "k=" << args["k"].AsString()  << endl;
  178. }
  179. // Position arguments - advanced
  180. static void s_InitTest7(CArgDescriptions& arg_desc)
  181. {
  182.     arg_desc.AddPositional
  183.         ("p2",
  184.          "This is a plain argument",  CArgDescriptions::eString);
  185.     arg_desc.AddExtra
  186.         (1, 3,
  187.          "These are extra arguments", CArgDescriptions::eInteger);
  188.     arg_desc.AddPositional
  189.         ("p1",
  190.          "This is a plain argument",  CArgDescriptions::eBoolean);
  191. }
  192. static void s_RunTest7(const CArgs& args, ostream& os)
  193. {
  194.     os << "p1=" << args["p1"].AsString()  << endl;
  195.     os << "p2=" << args["p2"].AsString()  << endl;
  196.     os << "#1=" << args["#1"].AsInteger() << endl;
  197.     if ( args["#2"] ) {
  198.         os << "#2=" << args["#2"].AsInteger() << endl;
  199.     }
  200.     if ( args["#3"] ) {
  201.         os << "#3=" << args["#3"].AsInteger() << endl;
  202.     }
  203. }
  204. // Position arguments
  205. static void s_InitTest6(CArgDescriptions& arg_desc)
  206. {
  207.     arg_desc.AddDefaultPositional
  208.         ("p1", "This is a positional argument with default value",
  209.          CArgDescriptions::eDouble, "1.23");
  210.     arg_desc.AddPositional
  211.         ("p2", "This is a mandatory positional argument",
  212.          CArgDescriptions::eBoolean);
  213. }
  214. static void s_RunTest6(const CArgs& args, ostream& os)
  215. {
  216.     os << "p1=" << args["p1"].AsString() << endl;
  217.     os << "p2=" << args["p2"].AsString() << endl;
  218. }
  219. // Files - advanced
  220. static void s_InitTest5(CArgDescriptions& arg_desc)
  221. {
  222.     arg_desc.AddKey("if",
  223.                     "inputFile", "This is an input file argument",
  224.                     CArgDescriptions::eInputFile, CArgDescriptions::fPreOpen);
  225.     arg_desc.AddKey("of",
  226.                     "outputFile", "This is an output file argument",
  227.                     CArgDescriptions::eOutputFile, CArgDescriptions::fAppend);
  228. }
  229. static void s_RunTest5(const CArgs& args, ostream& /*os*/)
  230. {
  231.     // Close
  232.     args["if"].CloseFile();
  233.     (void) args["of"].AsOutputFile();
  234.     args["of"].CloseFile();
  235.     // Auto-reopen (first time only)
  236.     while ( !args["if"].AsInputFile().eof() ) {
  237.         string tmp;
  238.         args["if"].AsInputFile () >> tmp;
  239.         args["of"].AsOutputFile() << tmp << endl;
  240.     }
  241. }
  242. // Files
  243. static void s_InitTest4(CArgDescriptions& arg_desc)
  244. {
  245.     arg_desc.AddKey("if",
  246.                     "inputFile", "This is an input file argument",
  247.                     CArgDescriptions::eInputFile);
  248.     arg_desc.AddKey("of",
  249.                     "outputFile", "This is an output file argument",
  250.                     CArgDescriptions::eOutputFile);
  251. }
  252. static void s_RunTest4(const CArgs& args, ostream& /*os*/)
  253. {
  254.     while ( !args["if"].AsInputFile().eof() ) {
  255.         string tmp;
  256.         args["if"].AsInputFile () >> tmp;
  257.         args["of"].AsOutputFile() << tmp << endl;
  258.     }
  259. }
  260. // Optional
  261. static void s_InitTest3(CArgDescriptions& arg_desc)
  262. {
  263.     arg_desc.AddOptionalKey("k1",
  264.                             "fistOptionalKey",
  265.                             "This is an optional argument",
  266.                             CArgDescriptions::eString);
  267.     arg_desc.AddOptionalKey("k2",
  268.                             "secondOptionalKey",
  269.                             "This is an optional argument",
  270.                             CArgDescriptions::eString);
  271.     arg_desc.AddFlag("f1", "Flag 1");
  272.     arg_desc.AddFlag("f2", "Flag 2");
  273. }
  274. static void s_RunTest3(const CArgs& args, ostream& os)
  275. {
  276.     if (args["k1"])
  277.         os << "k1=" << args["k1"].AsString() << endl;
  278.     if (args["k2"])
  279.         os << "k2=" << args["k2"].AsString() << endl;
  280. }
  281. // Data types
  282. static void s_InitTest2(CArgDescriptions& arg_desc)
  283. {
  284.     arg_desc.AddKey("ka",
  285.                     "alphaNumericKey", "This is a test alpha-num key argument",
  286.                     CArgDescriptions::eString);
  287.     arg_desc.AddKey("kb",
  288.                     "booleanKey", "This is a test boolean key argument",
  289.                     CArgDescriptions::eBoolean);
  290.     arg_desc.AddKey("ki",
  291.                     "integerKey", "This is a test integer key argument",
  292.                     CArgDescriptions::eInteger);
  293.     arg_desc.AddKey("kd",
  294.                     "doubleKey", "This is a test double key argument",
  295.                     CArgDescriptions::eDouble);
  296. }
  297. static void s_RunTest2(const CArgs& args, ostream& os)
  298. {
  299.     os << "ka=" << args["ka"].AsString() << endl;
  300.     os << "kb=" << NStr::BoolToString( args["kb"].AsBoolean() ) << endl;
  301.     os << "ki=" << args["ki"].AsInteger() << endl;
  302.     os << "kd=" << args["kd"].AsDouble() << endl;
  303. }
  304. // The simplest test
  305. static void s_InitTest1(CArgDescriptions& arg_desc)
  306. {
  307.     arg_desc.AddKey("k",
  308.                     "key", "This is a key argument",
  309.                     CArgDescriptions::eString);
  310. }
  311. static void s_RunTest1(const CArgs& args, ostream& os)
  312. {
  313.     os << "k=" << args["k"].AsString() << endl;
  314. }
  315. /////////////////////////////////////////////////////////////////////////////
  316. //  Tests' array
  317. struct STest {
  318.     void (*init)(CArgDescriptions& arg_desc);
  319.     void (*run)(const CArgs& args, ostream& os);
  320. };
  321. static STest s_Test[] =
  322. {
  323.     {s_InitTest0, s_RunTest0},  // default
  324.     {s_InitTest1, s_RunTest1},
  325.     {s_InitTest2, s_RunTest2},
  326.     {s_InitTest3, s_RunTest3},
  327.     {s_InitTest4, s_RunTest4},
  328.     {s_InitTest5, s_RunTest5},
  329.     {s_InitTest6, s_RunTest6},
  330.     {s_InitTest7, s_RunTest7},
  331.     {s_InitTest8, s_RunTest8},
  332.     {s_InitTest9, s_RunTest9},
  333.     {s_InitTest0, s_RunTest0},
  334.     {0,           0}
  335. };
  336. /////////////////////////////////////////////////////////////////////////////
  337. //  CArgTestApplication::
  338. class CArgTestApplication : public CNcbiApplication
  339. {
  340. public:
  341.     CArgTestApplication();
  342. private:
  343.     virtual void Init(void);
  344.     virtual int  Run(void);
  345.     virtual void Exit(void);
  346.     size_t m_TestNo;
  347. };
  348. // Constructor -- setting version test
  349. CArgTestApplication::CArgTestApplication()
  350. {
  351.     SetVersion(CVersionInfo(1,2,3,"NcbiArgTest"));
  352. // Choose the test to run, and
  353. // Setup arg.descriptions accordingly
  354. void CArgTestApplication::Init(void)
  355. {
  356.     // Set err.-posting and tracing on maximum
  357.     SetDiagTrace(eDT_Enable);
  358.     SetDiagPostFlag(eDPF_All);
  359.     SetDiagPostLevel(eDiag_Info);
  360.     // Get test # from env.variable $TEST_NO
  361.     m_TestNo = 0;
  362.     size_t max_test = sizeof(s_Test) / sizeof(s_Test[0]) - 2;
  363.     const string& test_str = GetEnvironment().Get("TEST_NO");
  364.     if ( !test_str.empty() ) {
  365.         try {
  366.             m_TestNo = NStr::StringToULong(test_str);
  367.         } catch (...) {
  368.             m_TestNo = 0;
  369.         }
  370.         if (m_TestNo > max_test) {
  371.             m_TestNo = 0;
  372.         }
  373.     }
  374.     // The "no-test" case
  375.     if ( !s_Test[m_TestNo].init )
  376.         return;
  377.     // Create cmd-line argument descriptions class
  378.     auto_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);
  379.     // Specify USAGE context
  380.     string prog_description =
  381.         "This is a test program for command-line argument processing.n"
  382.         "TEST #" + NStr::UIntToString(m_TestNo) +
  383.         "    (To run another test, set env.variable $TEST_NO to 0.." +
  384.         NStr::UIntToString(max_test) + ")";
  385.     bool usage_sort_args = (m_TestNo == 10);
  386.     arg_desc->SetUsageContext(GetArguments().GetProgramBasename(),
  387.                               prog_description, usage_sort_args);
  388.     // Describe cmd-line arguments according to the chosen test #
  389.     s_Test[m_TestNo].init(*arg_desc);
  390.     // Setup arg.descriptions for this application
  391.     SetupArgDescriptions(arg_desc.release());
  392. }
  393. // Printout arguments obtained from cmd.-line
  394. int CArgTestApplication::Run(void)
  395. {
  396.     cout << string(72, '=') << endl;
  397.     // The "no-test" case
  398.     if ( !s_Test[m_TestNo].run ) {
  399.         cout << "No arguments described." << endl;
  400.         return 0;
  401.     }
  402.     // Do run
  403.     s_Test[m_TestNo].run(GetArgs(), cout);
  404.     // Printout obtained argument values
  405.     string str;
  406.     cout << GetArgs().Print(str) << endl;
  407.     return 0;
  408. }
  409. // Cleanup
  410. void CArgTestApplication::Exit(void)
  411. {
  412.     SetDiagStream(0);
  413. }
  414. /////////////////////////////////////////////////////////////////////////////
  415. //  MAIN
  416. int main(int argc, const char* argv[])
  417. {
  418.     // Execute main application function
  419.     return CArgTestApplication().AppMain(argc, argv, 0, eDS_Default, 0);
  420. }
  421. /*
  422.  * ===========================================================================
  423.  * $Log: test_ncbiargs.cpp,v $
  424.  * Revision 1000.1  2004/06/01 19:09:55  gouriano
  425.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R6.22
  426.  *
  427.  * Revision 6.22  2004/05/14 13:59:51  gorelenk
  428.  * Added include of ncbi_pch.hpp
  429.  *
  430.  * Revision 6.21  2002/12/26 17:13:28  ivanov
  431.  * Added version info test
  432.  *
  433.  * Revision 6.20  2002/07/15 18:17:25  gouriano
  434.  * renamed CNcbiException and its descendents
  435.  *
  436.  * Revision 6.19  2002/07/11 14:18:29  gouriano
  437.  * exceptions replaced by CNcbiException-type ones
  438.  *
  439.  * Revision 6.18  2002/04/16 18:49:07  ivanov
  440.  * Centralize threatment of assert() in tests.
  441.  * Added #include <test/test_assert.h>. CVS log moved to end of file.
  442.  *
  443.  * Revision 6.17  2001/03/26 16:52:19  vakatov
  444.  * Fixed a minor warning
  445.  *
  446.  * Revision 6.16  2000/12/24 00:13:00  vakatov
  447.  * Radically revamped NCBIARGS.
  448.  * Introduced optional key and posit. args without default value.
  449.  * Added new arg.value constraint classes.
  450.  * Passed flags to be detected by HasValue() rather than AsBoolean.
  451.  * Simplified constraints on the number of mandatory and optional extra args.
  452.  * Improved USAGE info and diagnostic messages. Etc...
  453.  *
  454.  * Revision 6.15  2000/11/29 00:09:19  vakatov
  455.  * Added test #10 -- to auto-sort flag and key args alphabetically
  456.  *
  457.  * Revision 6.14  2000/11/24 23:37:46  vakatov
  458.  * The test is now "CNcbiApplication" based (rather than "bare main()")
  459.  * -- to use and to test standard processing of cmd.-line arguments implemented
  460.  * in "CNcbiApplication".
  461.  * Also, test for CArgValue::CloseFile().
  462.  *
  463.  * Revision 6.13  2000/11/22 22:04:32  vakatov
  464.  * Added special flag "-h" and special exception CArgHelpException to
  465.  * force USAGE printout in a standard manner
  466.  *
  467.  * Revision 6.12  2000/11/22 19:40:51  vakatov
  468.  * s_Test3() -- fixed:  Exist() --> IsProvided()
  469.  *
  470.  * Revision 6.11  2000/11/20 19:49:40  vakatov
  471.  * Test0::  printout all arg values
  472.  *
  473.  * Revision 6.10  2000/11/17 22:04:31  vakatov
  474.  * CArgDescriptions::  Switch the order of optional args in methods
  475.  * AddOptionalKey() and AddPlain(). Also, enforce the default value to
  476.  * match arg. description (and constraints, if any) at all times.
  477.  *
  478.  * Revision 6.9  2000/11/13 20:31:09  vakatov
  479.  * Wrote new test, fixed multiple bugs, ugly "features", and the USAGE.
  480.  *
  481.  * Revision 6.8  2000/10/20 20:26:11  butanaev
  482.  * Modified example #9.
  483.  *
  484.  * Revision 6.7  2000/10/11 21:03:50  vakatov
  485.  * Cleanup to avoid 64-bit to 32-bit values truncation, etc.
  486.  * (reported by Forte6 Patch 109490-01)
  487.  *
  488.  * Revision 6.6  2000/10/06 21:57:07  butanaev
  489.  * Added Allow() function. Added classes CArgAllowValue, CArgAllowIntInterval.
  490.  *
  491.  * Revision 6.5  2000/09/29 17:11:01  butanaev
  492.  * Got rid of IsDefaultValue(), added IsProvided().
  493.  *
  494.  * Revision 6.4  2000/09/28 21:00:21  butanaev
  495.  * fPreOpen with opposite meaning took over fDelayOpen.
  496.  * IsDefaultValue() added which returns true if no
  497.  * value for an optional argument was provided in cmd. line.
  498.  *
  499.  * Revision 6.3  2000/09/22 21:26:28  butanaev
  500.  * Added example with default arg values.
  501.  *
  502.  * Revision 6.2  2000/09/12 15:01:30  butanaev
  503.  * Examples now switching by environment variable EXAMPLE_NUM.
  504.  *
  505.  * Revision 6.1  2000/08/31 23:55:35  vakatov
  506.  * Initial revision
  507.  *
  508.  * ===========================================================================
  509.  */