Webmaster  |  Imprint 
C++ Server Pages
Main  |  License  |  Documentation  |  Download 

/home/tommi/cxxtools/include/cxxtools/arg.h

00001 /*
00002  * Copyright (C) 2003,2004 Tommi Maekitalo
00003  * 
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  * 
00009  * As a special exception, you may use this file as part of a free
00010  * software library without restriction. Specifically, if other files
00011  * instantiate templates or use macros or inline functions from this
00012  * file, or you compile this file and link it with other files to
00013  * produce an executable, this file does not by itself cause the
00014  * resulting executable to be covered by the GNU General Public
00015  * License. This exception does not however invalidate any other
00016  * reasons why the executable file might be covered by the GNU Library
00017  * General Public License.
00018  * 
00019  * This library is distributed in the hope that it will be useful,
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00022  * Lesser General Public License for more details.
00023  * 
00024  * You should have received a copy of the GNU Lesser General Public
00025  * License along with this library; if not, write to the Free Software
00026  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00027  */
00028 
00029 #ifndef CXXTOOLS_ARG_H
00030 #define CXXTOOLS_ARG_H
00031 
00032 #include <sstream>
00033 #include <string.h>
00034 
00035 namespace cxxtools
00036 {
00037 
00039 
00062 template <typename T>
00063 class Arg
00064 {
00065   public:
00071     Arg(const T& def = T())
00072       : m_value(def),
00073         m_isset(false)
00074       { }
00075 
00090     Arg(int& argc, char* argv[], char ch, const T& def = T())
00091       : m_value(def),
00092         m_isset(false)
00093     {
00094       set(argc, argv, ch);
00095     }
00096 
00108     Arg(int& argc, char* argv[], const char* str, const T& def = T())
00109       : m_value(def),
00110         m_isset(false)
00111     {
00112       m_isset = set(argc, argv, str);
00113     }
00114 
00115     Arg(int& argc, char* argv[])
00116       : m_isset(false)
00117     {
00118       m_isset = set(argc, argv);
00119     }
00120 
00135     bool set(int& argc, char* argv[], char ch)
00136     {
00137       // don't extract value, when already found
00138       if (m_isset)
00139         return false;
00140 
00141       for (int i = 1; i < argc - 1; ++i)
00142         if (argv[i][0] == '-' && argv[i][1] == ch && argv[i][2] == '\0')
00143         {
00144           std::istringstream s(argv[i + 1]);
00145           s >> m_value;
00146           if (!s.fail())
00147           {
00148             m_isset = true;
00149             for ( ; i < argc - 2; ++i)
00150               argv[i] = argv[i + 2];
00151             argc -= 2;
00152             argv[argc] = 0;
00153             return true;
00154           }
00155         }
00156       
00157       return false;
00158     }
00159 
00172     bool set(int& argc, char* argv[], const char* str)
00173     {
00174       // don't extract value, when already found
00175       if (m_isset)
00176         return false;
00177 
00178       for (int i = 1; i < argc - 1; ++i)
00179         if (strcmp(argv[i], str) == 0)
00180         {
00181           std::istringstream s(argv[i + 1]);
00182           s >> m_value;
00183           if (!s.fail())
00184           {
00185             m_isset = true;
00186             for ( ; i < argc - 2; ++i)
00187               argv[i] = argv[i + 2];
00188             argc -= 2;
00189             argv[argc] = 0;
00190             return true;
00191           }
00192         }
00193 
00194       return false;
00195     }
00196 
00200     bool set(int& argc, char* argv[])
00201     {
00202       // don't extract value, when already found
00203       if (m_isset)
00204         return false;
00205 
00206       if (argc > 1)
00207       {
00208         std::istringstream s(argv[1]);
00209         s >> m_value;
00210         if (!s.fail())
00211         {
00212           m_isset = true;
00213           for (int i = 1; i < argc - 1; ++i)
00214             argv[i] = argv[i + 1];
00215           argc -= 1;
00216           argv[argc] = 0;
00217         }
00218         else
00219           m_isset = false;
00220       }
00221       else
00222         m_isset = false;
00223 
00224       return m_isset;
00225     }
00226 
00230     const T& getValue() const   { return m_value; }
00231 
00251     operator T() const   { return m_value; }
00252 
00257     bool isSet() const   { return m_isset; }
00258 
00259   private:
00260     T    m_value;
00261     bool m_isset;
00262 };
00263 
00265 
00278 template <>
00279 class Arg<bool>
00280 {
00281   public:
00287     Arg(bool def = false)
00288       : m_value(def),
00289         m_isset(false)
00290         { }
00291 
00306     Arg(int& argc, char* argv[], char ch, bool def = false)
00307       : m_value(def),
00308         m_isset(false)
00309     {
00310       m_isset = set(argc, argv, ch);
00311     }
00312 
00313     Arg(int& argc, char* argv[], const char* str, bool def = false)
00314       : m_value(def),
00315         m_isset(false)
00316     {
00317       m_isset = set(argc, argv, str);
00318     }
00319 
00363     bool set(int& argc, char* argv[], char ch)
00364     {
00365       // don't extract value, when already found
00366       if (m_isset)
00367         return false;
00368 
00369       for (int i = 1; i < argc; ++i)
00370         if (argv[i][0] == '-' && argv[i][1] != '-')
00371         {
00372           // starts with a '-', but not with "--"
00373           if (argv[i][1] == ch && argv[i][2] == '\0')
00374           {
00375             // single option found
00376             m_value = true;
00377             m_isset = true;
00378             for ( ; i < argc - 1; ++i)
00379               argv[i] = argv[i + 1];
00380             argc -= 1;
00381             argv[argc] = 0;
00382             return true;
00383           }
00384           else if (argv[i][1] == ch && argv[i][2] == '-' && argv[i][3] == '\0')
00385           {
00386             // Option was explicitly disabled with -x-
00387             m_value = false;
00388             m_isset = true;
00389             for ( ; i < argc - 1; ++i)
00390               argv[i] = argv[i + 1];
00391             argc -= 1;
00392             argv[argc] = 0;
00393             return true;
00394           }
00395           else
00396           {
00397             // look, if we find the option in a optiongroup
00398             for (char* p = argv[i] + 1; *p != '\0'; ++p)
00399               if (*p == ch)
00400               {
00401                 // her it is - extract it
00402                 m_value = true;
00403                 m_isset = true;
00404                 do
00405                 {
00406                   *p = *(p + 1);
00407                 } while (*p++ != '\0');
00408 
00409                 return true;
00410               }
00411           }
00412         }
00413 
00414       return false;
00415     }
00416 
00432     bool set(int& argc, char* argv[], const char* str)
00433     {
00434       // don't extract value, when already found
00435       if (m_isset)
00436         return false;
00437 
00438       for (int i = 1; i < argc; ++i)
00439         if (strcmp(argv[i], str) == 0)
00440         {
00441           m_value = true;
00442           m_isset = true;
00443           for ( ; i < argc - 1; ++i)
00444             argv[i] = argv[i + 1];
00445           argc -= 1;
00446           argv[argc] = 0;
00447           return true;
00448         }
00449 
00450       return false;
00451     }
00452 
00456     bool isTrue() const   { return m_value; }
00457 
00461     bool isFalse() const  { return !m_value; }
00462 
00466     operator bool() const  { return m_value; }
00467 
00471     bool isSet() const             { return m_isset; }
00472 
00473   private:
00474     bool m_value;
00475     bool m_isset;
00476 };
00477 
00479 
00485 template <>
00486 class Arg<const char*>
00487 {
00488   public:
00489     Arg(const char* def = 0)
00490       : m_value(def),
00491         m_isset(false)
00492     { }
00493 
00494     Arg(int& argc, char* argv[], char ch, const char* def = 0)
00495       : m_value(def),
00496         m_isset(false)
00497     {
00498       m_isset = set(argc, argv, ch);
00499     }
00500 
00501     Arg(int& argc, char* argv[], const char* str, const char* def = 0)
00502       : m_value(def),
00503         m_isset(false)
00504     {
00505       m_isset = set(argc, argv, str);
00506     }
00507 
00508     Arg(int& argc, char* argv[])
00509       : m_value(0),
00510         m_isset(false)
00511     { 
00512       m_isset = set(argc, argv);
00513     }
00514 
00518     bool set(int& argc, char* argv[], char ch)
00519     {
00520       // don't extract value, when already found
00521       if (m_isset)
00522         return false;
00523 
00524       for (int i = 1; i < argc - 1; ++i)
00525         if (argv[i][0] == '-' && argv[i][1] == ch && argv[i][2] == '\0')
00526         {
00527           m_value = argv[i + 1];
00528           m_isset = true;
00529           for ( ; i < argc - 2; ++i)
00530             argv[i] = argv[i + 2];
00531           argc -= 2;
00532           argv[argc] = 0;
00533           return true;
00534         }
00535 
00536       return false;
00537     }
00538 
00542     bool set(int& argc, char* argv[], const char* str, const char* def = 0)
00543     {
00544       // don't extract value, when already found
00545       if (m_isset)
00546         return false;
00547 
00548       for (int i = 1; i < argc - 1; ++i)
00549         if (strcmp(argv[i], str) == 0)
00550         {
00551           m_value = argv[i + 1];
00552           m_isset = true;
00553           for ( ; i < argc - 2; ++i)
00554             argv[i] = argv[i + 2];
00555           argc -= 2;
00556           argv[argc] = 0;
00557           return true;
00558         }
00559 
00560       return false;
00561     }
00562 
00566     bool set(int& argc, char* argv[])
00567     {
00568       // don't extract value, when already found
00569       if (m_isset)
00570         return false;
00571 
00572       if (argc > 1)
00573       {
00574         m_value = argv[1];
00575         m_isset = true;
00576         for (int i = 1; i < argc - 1; ++i)
00577           argv[i] = argv[i + 1];
00578         argc -= 1;
00579         argv[argc] = 0;
00580         return true;
00581       }
00582       else
00583         return false;
00584     }
00585 
00589     const char* getValue() const   { return m_value; }
00590 
00594     operator const char*() const   { return m_value; }
00595 
00599     bool isSet() const             { return m_isset; }
00600 
00601   private:
00602     const char* m_value;
00603     bool        m_isset;
00604 };
00605 
00607 
00613 template <>
00614 class Arg<std::string>
00615 {
00616   public:
00617     Arg(const std::string& def = std::string())
00618       : m_value(def),
00619         m_isset(false)
00620     { }
00621 
00625     Arg(int& argc, char* argv[], char ch, const std::string& def = std::string())
00626       : m_value(def),
00627         m_isset(false)
00628     {
00629       m_isset = set(argc, argv, ch);
00630     }
00631 
00635     Arg(int& argc, char* argv[], const char* str, const std::string& def = std::string())
00636       : m_value(def),
00637         m_isset(false)
00638     {
00639       m_isset = set(argc, argv, str);
00640     }
00641 
00645     Arg(int& argc, char* argv[])
00646       : m_value(std::string()),
00647         m_isset(false)
00648     {
00649       m_isset = set(argc, argv);
00650     }
00651 
00655     bool set(int& argc, char* argv[], char ch)
00656     {
00657       // don't extract value, when already found
00658       if (m_isset)
00659         return false;
00660 
00661       for (int i = 1; i < argc - 1; ++i)
00662         if (argv[i][0] == '-' && argv[i][1] == ch && argv[i][2] == '\0')
00663         {
00664           m_value = argv[i + 1];
00665           m_isset = true;
00666           for ( ; i < argc - 2; ++i)
00667             argv[i] = argv[i + 2];
00668           argc -= 2;
00669           argv[argc] = 0;
00670           return true;
00671         }
00672 
00673       return false;
00674     }
00675 
00679     bool set(int& argc, char* argv[], const char* str)
00680     {
00681       // don't extract value, when already found
00682       if (m_isset)
00683         return false;
00684 
00685       for (int i = 1; i < argc - 1; ++i)
00686         if (strcmp(argv[i], str) == 0)
00687         {
00688           m_value = argv[i + 1];
00689           m_isset = true;
00690           for ( ; i < argc - 2; ++i)
00691             argv[i] = argv[i + 2];
00692           argc -= 2;
00693           argv[argc] = 0;
00694           return true;
00695         }
00696 
00697       return false;
00698     }
00699 
00703     bool set(int& argc, char* argv[])
00704     {
00705       // don't extract value, when already found
00706       if (m_isset)
00707         return false;
00708 
00709       if (argc > 1)
00710       {
00711         m_value = argv[1];
00712         m_isset = true;
00713         for (int i = 1; i < argc - 1; ++i)
00714           argv[i] = argv[i + 1];
00715         argc -= 1;
00716         argv[argc] = 0;
00717         return true;
00718       }
00719       else
00720         return false;
00721     }
00722 
00726     bool setNoOpt(int& argc, char* argv[])
00727     {
00728       // don't extract value, when already found
00729       if (m_isset)
00730         return false;
00731 
00732       for (int i = 1; i < argc; ++i)
00733         if (argv[i][0] != '-')
00734         {
00735           m_isset = true;
00736           m_value = argv[i];
00737           for ( ; i < argc - 1; ++i)
00738             argv[i] = argv[i + 1];
00739           --argc;
00740           argv[argc] = 0;
00741           return true;
00742         }
00743 
00744       return false;
00745     }
00746 
00750     const std::string& getValue() const   { return m_value; }
00751 
00755     operator const std::string&() const   { return m_value; }
00756 
00760     bool isSet() const             { return m_isset; }
00761 
00762   private:
00763     std::string m_value;
00764     bool        m_isset;
00765 };
00766 
00767 }
00768 
00769 #endif // CXXTOOLS_ARG_H
Copyright © 2008 The Tntnet Development Team
Tntnet 1.6