File: ecl_argp.hh

package info (click to toggle)
enigma 1.20-dfsg.1-2.2
  • links: PTS
  • area: main
  • in suites: bookworm, bullseye
  • size: 64,696 kB
  • sloc: xml: 153,614; cpp: 63,581; ansic: 31,088; sh: 4,825; makefile: 1,858; yacc: 288; perl: 84; sed: 16
file content (120 lines) | stat: -rw-r--r-- 3,769 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
 * Copyright (C) 2000,2003 Daniel Heck
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *  
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */
#ifndef ECL_ARGP_HH
#define ECL_ARGP_HH

#include "ecl_util.hh"
#include <list>
#include <algorithm>

namespace ecl 
{ 
    class ArgParser : public ecl::Nocopy {
    public:
        // Constructors.
        ArgParser ();

        template <class Iter>
        ArgParser(Iter beg, Iter end) {
            feed (beg, end);
        }

        // Destructor.
        virtual ~ArgParser();

        // Types.
        enum ErrorType {
            UnknownOpt,         // Unkown option found
            AmbiguousOpt,       // Abbreviation matches two options
            MissingParam,       // Expected parameter is missing
            InvalidParam        // Option does not take parameter
        };

        //
        // Public interface.
        //
        
        virtual void on_error (ErrorType t, const std::string &arg);
        virtual void on_argument (const std::string &arg);
        virtual void on_option (int id, const std::string &param);

        //
        // Functions.
        //

        /* Feed new arguments into the parser. */
        template <class ForwardIterator>
        void feed (ForwardIterator begin, ForwardIterator end) {
            std::copy(begin, end, std::back_inserter(m_arglist));
        }
    
        /* Define a new option. */
        void def (int id, const std::string &name, char abbr = 0, bool param = false);
	void def (bool *boolvar, const std::string &name, char abbr = 0);

        /* Parse all command line arguments, calling the appropriate
           handlers at the right time. */
        void parse();

        std::string errormsg(ErrorType t, const std::string &arg) const;

    private:
        struct Option {
            Option (int id_, char s='\0', const std::string& l="", bool param=false)
                : id(id_), shortopt(s), longopt(l), takesparam(param), boolvar(0)
            {}
		
            int         id;
            char        shortopt;
            std::string longopt;
            bool        takesparam;
	    bool	*boolvar;
        };


        // Private Variables.
        typedef std::list<Option>::iterator option_iterator;
    
        std::list<Option>      m_opts;
        std::list<std::string> m_arglist;
        std::string            m_lastopt; // Last option seen

        // Private functions.
	void process_option(Option &opt, const std::string &param);

        void getlongopt (const std::string& arg);
        void getshortopt (const std::string& arg);

        template <class Iter>
        static Iter
        find_prefix(Iter beg, Iter end, const std::string& val) {
            typename std::string::size_type s = val.size();
            for (; beg != end; ++beg) {
                // This is the way the comparison should be done,
                // but gcc doesn't like it yet...
                //   if ((beg->longopt).compare(0, s, val) == 0)
                if ((beg->longopt).substr(0, s) == val)
                    break;
            }
            return beg;
        }
    };
}

#endif