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

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

00001 /* cxxtools/arg.h
00002  *
00003  * cxxtools - general purpose C++-toolbox
00004  * Copyright (C) 2003,2004 Tommi Maekitalo
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00019  *
00020  */
00021 
00022 #ifndef CXXTOOLS_ARG_H
00023 #define CXXTOOLS_ARG_H
00024 
00025 #include <sstream>
00026 #include <string.h>
00027 
00028 namespace cxxtools
00029 {
00030 
00032 
00055 template <typename T>
00056 class Arg
00057 {
00058   public:
00064     Arg(const T& def = T())
00065       : m_value(def),
00066         m_isset(false)
00067       { }
00068 
00083     Arg(int& argc, char* argv[], char ch, const T& def = T())
00084       : m_value(def),
00085         m_isset(false)
00086     {
00087       set(argc, argv, ch);
00088     }
00089 
00101     Arg(int& argc, char* argv[], const char* str, const T& def = T())
00102       : m_value(def),
00103         m_isset(false)
00104     {
00105       m_isset = set(argc, argv, str);
00106     }
00107 
00108     Arg(int& argc, char* argv[])
00109       : m_isset(false)
00110     {
00111       m_isset = set(argc, argv);
00112     }
00113 
00128     bool set(int& argc, char* argv[], char ch)
00129     {
00130       // don't extract value, when already found
00131       if (m_isset)
00132         return false;
00133 
00134       for (int i = 1; i < argc - 1; ++i)
00135         if (argv[i][0] == '-' && argv[i][1] == ch && argv[i][2] == '\0')
00136         {
00137           std::istringstream s(argv[i + 1]);
00138           s >> m_value;
00139           if (!s.fail())
00140           {
00141             m_isset = true;
00142             for ( ; i < argc - 2; ++i)
00143               argv[i] = argv[i + 2];
00144             argc -= 2;
00145             argv[argc] = 0;
00146             return true;
00147           }
00148         }
00149       
00150       return false;
00151     }
00152 
00165     bool set(int& argc, char* argv[], const char* str)
00166     {
00167       // don't extract value, when already found
00168       if (m_isset)
00169         return false;
00170 
00171       for (int i = 1; i < argc - 1; ++i)
00172         if (strcmp(argv[i], str) == 0)
00173         {
00174           std::istringstream s(argv[i + 1]);
00175           s >> m_value;
00176           if (!s.fail())
00177           {
00178             m_isset = true;
00179             for ( ; i < argc - 2; ++i)
00180               argv[i] = argv[i + 2];
00181             argc -= 2;
00182             argv[argc] = 0;
00183             return true;
00184           }
00185         }
00186 
00187       return false;
00188     }
00189 
00193     bool set(int& argc, char* argv[])
00194     {
00195       // don't extract value, when already found
00196       if (m_isset)
00197         return false;
00198 
00199       if (argc > 1)
00200       {
00201         std::istringstream s(argv[1]);
00202         s >> m_value;
00203         if (!s.fail())
00204         {
00205           m_isset = true;
00206           for (int i = 1; i < argc - 1; ++i)
00207             argv[i] = argv[i + 1];
00208           argc -= 1;
00209           argv[argc] = 0;
00210         }
00211         else
00212           m_isset = false;
00213       }
00214       else
00215         m_isset = false;
00216 
00217       return m_isset;
00218     }
00219 
00223     const T& getValue() const   { return m_value; }
00224 
00244     operator T() const   { return m_value; }
00245 
00250     bool isSet() const   { return m_isset; }
00251 
00252   private:
00253     T    m_value;
00254     bool m_isset;
00255 };
00256 
00258 
00271 template <>
00272 class Arg<bool>
00273 {
00274   public:
00280     Arg(bool def = false)
00281       : m_value(def),
00282         m_isset(false)
00283         { }
00284 
00299     Arg(int& argc, char* argv[], char ch, bool def = false)
00300       : m_value(def),
00301         m_isset(false)
00302     {
00303       m_isset = set(argc, argv, ch);
00304     }
00305 
00306     Arg(int& argc, char* argv[], const char* str, bool def = false)
00307       : m_value(def),
00308         m_isset(false)
00309     {
00310       m_isset = set(argc, argv, str);
00311     }
00312 
00356     bool set(int& argc, char* argv[], char ch)
00357     {
00358       // don't extract value, when already found
00359       if (m_isset)
00360         return false;
00361 
00362       for (int i = 1; i < argc; ++i)
00363         if (argv[i][0] == '-' && argv[i][1] != '-')
00364         {
00365           // starts with a '-', but not with "--"
00366           if (argv[i][1] == ch && argv[i][2] == '\0')
00367           {
00368             // single option found
00369             m_value = true;
00370             m_isset = true;
00371             for ( ; i < argc - 1; ++i)
00372               argv[i] = argv[i + 1];
00373             argc -= 1;
00374             argv[argc] = 0;
00375             return true;
00376           }
00377           else if (argv[i][1] == ch && argv[i][2] == '-' && argv[i][3] == '\0')
00378           {
00379             // Option was explicitly disabled with -x-
00380             m_value = false;
00381             m_isset = true;
00382             for ( ; i < argc - 1; ++i)
00383               argv[i] = argv[i + 1];
00384             argc -= 1;
00385             argv[argc] = 0;
00386             return true;
00387           }
00388           else
00389           {
00390             // look, if we find the option in a optiongroup
00391             for (char* p = argv[i] + 1; *p != '\0'; ++p)
00392               if (*p == ch)
00393               {
00394                 // her it is - extract it
00395                 m_value = true;
00396                 m_isset = true;
00397                 do
00398                 {
00399                   *p = *(p + 1);
00400                 } while (*p++ != '\0');
00401 
00402                 return true;
00403               }
00404           }
00405         }
00406 
00407       return false;
00408     }
00409 
00425     bool set(int& argc, char* argv[], const char* str)
00426     {
00427       // don't extract value, when already found
00428       if (m_isset)
00429         return false;
00430 
00431       for (int i = 1; i < argc; ++i)
00432         if (strcmp(argv[i], str) == 0)
00433         {
00434           m_value = true;
00435           m_isset = true;
00436           for ( ; i < argc - 1; ++i)
00437             argv[i] = argv[i + 1];
00438           argc -= 1;
00439           argv[argc] = 0;
00440           return true;
00441         }
00442 
00443       return false;
00444     }
00445 
00449     bool isTrue() const   { return m_value; }
00450 
00454     bool isFalse() const  { return !m_value; }
00455 
00459     operator bool() const  { return m_value; }
00460 
00464     bool isSet() const             { return m_isset; }
00465 
00466   private:
00467     bool m_value;
00468     bool m_isset;
00469 };
00470 
00472 
00478 template <>
00479 class Arg<const char*>
00480 {
00481   public:
00482     Arg(const char* def = 0)
00483       : m_value(def),
00484         m_isset(false)
00485     { }
00486 
00487     Arg(int& argc, char* argv[], char ch, const char* def = 0)
00488       : m_value(def),
00489         m_isset(false)
00490     {
00491       m_isset = set(argc, argv, ch);
00492     }
00493 
00494     Arg(int& argc, char* argv[], const char* str, const char* def = 0)
00495       : m_value(def),
00496         m_isset(false)
00497     {
00498       m_isset = set(argc, argv, str);
00499     }
00500 
00501     Arg(int& argc, char* argv[])
00502       : m_value(0),
00503         m_isset(false)
00504     { 
00505       m_isset = set(argc, argv);
00506     }
00507 
00511     bool set(int& argc, char* argv[], char ch)
00512     {
00513       // don't extract value, when already found
00514       if (m_isset)
00515         return false;
00516 
00517       for (int i = 1; i < argc - 1; ++i)
00518         if (argv[i][0] == '-' && argv[i][1] == ch && argv[i][2] == '\0')
00519         {
00520           m_value = argv[i + 1];
00521           m_isset = true;
00522           for ( ; i < argc - 2; ++i)
00523             argv[i] = argv[i + 2];
00524           argc -= 2;
00525           argv[argc] = 0;
00526           return true;
00527         }
00528 
00529       return false;
00530     }
00531 
00535     bool set(int& argc, char* argv[], const char* str, const char* def = 0)
00536     {
00537       // don't extract value, when already found
00538       if (m_isset)
00539         return false;
00540 
00541       for (int i = 1; i < argc - 1; ++i)
00542         if (strcmp(argv[i], str) == 0)
00543         {
00544           m_value = argv[i + 1];
00545           m_isset = true;
00546           for ( ; i < argc - 2; ++i)
00547             argv[i] = argv[i + 2];
00548           argc -= 2;
00549           argv[argc] = 0;
00550           return true;
00551         }
00552 
00553       return false;
00554     }
00555 
00559     bool set(int& argc, char* argv[])
00560     {
00561       // don't extract value, when already found
00562       if (m_isset)
00563         return false;
00564 
00565       if (argc > 1)
00566       {
00567         m_value = argv[1];
00568         m_isset = true;
00569         for (int i = 1; i < argc - 1; ++i)
00570           argv[i] = argv[i + 1];
00571         argc -= 1;
00572         argv[argc] = 0;
00573         return true;
00574       }
00575       else
00576         return false;
00577     }
00578 
00582     const char* getValue() const   { return m_value; }
00583 
00587     operator const char*() const   { return m_value; }
00588 
00592     bool isSet() const             { return m_isset; }
00593 
00594   private:
00595     const char* m_value;
00596     bool        m_isset;
00597 };
00598 
00600 
00606 template <>
00607 class Arg<std::string>
00608 {
00609   public:
00610     Arg(const std::string& def = std::string())
00611       : m_value(def),
00612         m_isset(false)
00613     { }
00614 
00618     Arg(int& argc, char* argv[], char ch, const std::string& def = std::string())
00619       : m_value(def),
00620         m_isset(false)
00621     {
00622       m_isset = set(argc, argv, ch);
00623     }
00624 
00628     Arg(int& argc, char* argv[], const char* str, const std::string& def = std::string())
00629       : m_value(def),
00630         m_isset(false)
00631     {
00632       m_isset = set(argc, argv, str);
00633     }
00634 
00638     Arg(int& argc, char* argv[])
00639       : m_value(std::string()),
00640         m_isset(false)
00641     {
00642       m_isset = set(argc, argv);
00643     }
00644 
00648     bool set(int& argc, char* argv[], char ch)
00649     {
00650       // don't extract value, when already found
00651       if (m_isset)
00652         return false;
00653 
00654       for (int i = 1; i < argc - 1; ++i)
00655         if (argv[i][0] == '-' && argv[i][1] == ch && argv[i][2] == '\0')
00656         {
00657           m_value = argv[i + 1];
00658           m_isset = true;
00659           for ( ; i < argc - 2; ++i)
00660             argv[i] = argv[i + 2];
00661           argc -= 2;
00662           argv[argc] = 0;
00663           return true;
00664         }
00665 
00666       return false;
00667     }
00668 
00672     bool set(int& argc, char* argv[], const char* str)
00673     {
00674       // don't extract value, when already found
00675       if (m_isset)
00676         return false;
00677 
00678       for (int i = 1; i < argc - 1; ++i)
00679         if (strcmp(argv[i], str) == 0)
00680         {
00681           m_value = argv[i + 1];
00682           m_isset = true;
00683           for ( ; i < argc - 2; ++i)
00684             argv[i] = argv[i + 2];
00685           argc -= 2;
00686           argv[argc] = 0;
00687           return true;
00688         }
00689 
00690       return false;
00691     }
00692 
00696     bool set(int& argc, char* argv[])
00697     {
00698       // don't extract value, when already found
00699       if (m_isset)
00700         return false;
00701 
00702       if (argc > 1)
00703       {
00704         m_value = argv[1];
00705         m_isset = true;
00706         for (int i = 1; i < argc - 1; ++i)
00707           argv[i] = argv[i + 1];
00708         argc -= 1;
00709         argv[argc] = 0;
00710         return true;
00711       }
00712       else
00713         return false;
00714     }
00715 
00719     bool setNoOpt(int& argc, char* argv[])
00720     {
00721       // don't extract value, when already found
00722       if (m_isset)
00723         return false;
00724 
00725       for (int i = 1; i < argc; ++i)
00726         if (argv[i][0] != '-')
00727         {
00728           m_isset = true;
00729           m_value = argv[i];
00730           for ( ; i < argc - 1; ++i)
00731             argv[i] = argv[i + 1];
00732           --argc;
00733           argv[argc] = 0;
00734           return true;
00735         }
00736 
00737       return false;
00738     }
00739 
00743     const std::string& getValue() const   { return m_value; }
00744 
00748     operator const std::string&() const   { return m_value; }
00749 
00753     bool isSet() const             { return m_isset; }
00754 
00755   private:
00756     std::string m_value;
00757     bool        m_isset;
00758 };
00759 
00760 }
00761 
00762 #endif // CXXTOOLS_ARG_H
Copyright © 2008 The Tntnet Development Team
Tntnet 1.6