Une MAJ de sécurité est nécessaire sur notre version actuelle. Elle sera effectuée lundi 02/08 entre 12h30 et 13h. L'interruption de service devrait durer quelques minutes (probablement moins de 5 minutes).

args.h 5.59 KB
Newer Older
1 2 3 4 5 6 7
#pragma once

#include <string>
#include <map>
#include <cstdlib>
#include <iostream>

Laurent Belcour's avatar
Laurent Belcour committed
8 9
#include "common.h"

10 11
/*! \brief A useful class for storing the high-level arguments of a program
 *  or a function.
12 13
 *  \ingroup core
 *  \internal
14 15 16 17 18
 *
 *  The set of parameters are parsed from the command line using the 
 *  constructor. They are stored as std::string in a std::map.
 *  \todo add functionalities to provide new parameters values.
 */
19 20 21 22 23
class arguments
{
	public: // functions

		// Constructor and destructor
Laurent Belcour's avatar
Laurent Belcour committed
24 25
		arguments()
		{
26
		}
27 28 29 30 31
		arguments(int argc, char** const argv)
		{
			for(int i=0; i<argc; ++i)
			{
				std::string temp(argv[i]) ;
32
				std::string key, data ;
33 34 35 36

				if(temp.compare(0, 2, "--") == 0)
				{
					key = temp.substr(2, temp.size()-2) ;
37 38 39 40 41
#ifdef DEBUG_ARGS
					std::cout << "<<DEBUG>> (" << i << ")" << key << " -> [ ";
#endif
					int k = i+1;
					int j = k;
42
					while(j < argc) 
43
					{
44

45
						std::string next(argv[j]) ;
46
						if(next[0] == '[' || next[next.size()-1] == ']' || next.compare(0, 2, "--") != 0)
47
						{
48 49 50 51 52 53 54 55 56 57 58
							if(j != k)
							{
								data.append(" ");
#ifdef DEBUG_ARGS
								std::cout << " ";
#endif
							}
							data.append(next);
#ifdef DEBUG_ARGS
							std::cout << "(" << j << ")" << next;
#endif
59
						}
60 61 62 63 64
						else
						{
							break ;
						}
						++j;
65
						++i;
66
					}
67 68 69
#ifdef DEBUG_ARGS
					std::cout << "]" << std::endl;
#endif
70 71 72
				}
				_map.insert(std::pair<std::string, std::string>(key, data)) ;
			}
73 74 75 76
		}
		~arguments()
		{
		}
77

78
		//! \brief is the elements in the command line ?
79 80 81 82 83 84 85 86 87 88
		bool is_defined(const std::string& key) const
		{
			if(_map.count(key) > 0)
			{
				return true ;
			}
			else
			{
				return false ;
			}
89
        }
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106

        //! \brief is the data at the given key in a vector format?
        //! No matter the type of the data, this function will test is the
        //! mapped string is of type "[ .... ]".
        //! It returns false if there is no associated entry.
        bool is_vec(const std::string& key) const
        {
            if(_map.count(key) > 0)
            {
                return _map.find(key)->second[0] == '[' ;
            }
            else
            {
                return false ;
            }
        }

107
		//! \brief access the element stored value
108 109 110 111 112 113 114 115
		std::string operator[](const std::string& key) const
		{
			if(_map.count(key) > 0)
			{
				return _map.find(key)->second ;
			}
			else
			{
116
                //std::cerr << "Underfined request to key : \"" << key << "\"" << std::endl ;
117 118
				return std::string() ;
			}
119
        }
120 121 122 123 124
		//! \brief acces to the float value associated with the parameter
		//! \a key.
		//!
		//! The \a default_value argument will be returned if the \a key
		//! has no associated value.
125
		float get_float(const std::string& key, float default_value = 0.0f) const
126
		{
127
			if(_map.count(key) > 0)
Laurent Belcour's avatar
Laurent Belcour committed
128
				return atof(_map.find(key)->second.c_str()) ;
129
			else
130
				return default_value ;
Laurent Belcour's avatar
Laurent Belcour committed
131
		}
132 133 134 135 136
		//! \brief acces to the integer value associated with the parameter
		//! \a key.
		//!
		//! The \a default_value argument will be returned if the \a key
		//! has no associated value.
137
		int get_int(const std::string& key, int default_value = 0) const
138
		{
139
			if(_map.count(key) > 0)
Laurent Belcour's avatar
Laurent Belcour committed
140
				return atoi(_map.find(key)->second.c_str()) ;
141
			else
142
				return default_value ;
Laurent Belcour's avatar
Laurent Belcour committed
143
		} 
144 145 146 147 148
		//! \brief acces to a vector of float of size \a size associated with
		//! the parameter \a key.
		//!
		//! The \a default_value argument will be returned if the \a key
		//! has no associated value.
149
		vec get_vec(const std::string& key, int size, float default_value = 0.0f) const
Laurent Belcour's avatar
Laurent Belcour committed
150
		{
151
			vec res(size);
152 153 154
            for(int i=0; i<size; ++i)
                res[i] = default_value;

Laurent Belcour's avatar
Laurent Belcour committed
155 156
			if(_map.count(key) > 0)
			{
Laurent Belcour's avatar
Laurent Belcour committed
157
				std::string s = _map.find(key)->second;
158
				if(s[0] == '[') // Is an array of type [a, b, c]
Laurent Belcour's avatar
Laurent Belcour committed
159 160
				{
					int i = 0;
161
					size_t pos = 1;
162
					while(pos != std::string::npos && i<size)
Laurent Belcour's avatar
Laurent Belcour committed
163
					{
164
						size_t ppos = s.find(',', pos);
Laurent Belcour's avatar
Laurent Belcour committed
165 166 167

						if(ppos != std::string::npos)
						{
168
                            res[i] = atof(s.substr(pos, ppos-pos).c_str());
Laurent Belcour's avatar
Laurent Belcour committed
169 170 171
							pos = ppos+1;
							++i;
						}
172 173
						else
						{
174 175
                            std::string temp = s.substr(pos, std::string::npos);
                            res[i] = atof(temp.substr(0, temp.size()-1).c_str());
176 177 178
							pos = ppos;
							++i;
						}
Laurent Belcour's avatar
Laurent Belcour committed
179 180 181 182 183 184
					}
					return res;
				}
			}

			float val = get_float(key, default_value);
185 186 187 188
			for(int i=0; i<size; ++i)
			{
				res[i] = val;
			}
Laurent Belcour's avatar
Laurent Belcour committed
189 190
			return res;
		}
191

192 193 194 195 196 197
        std::vector<std::string> get_vec(const std::string& key) const
        {
            std::vector<std::string> res;
            if(_map.count(key) > 0)
            {
                std::string s = _map.find(key)->second;
198

199 200 201 202 203 204 205 206 207
                if(s[0] == '[') // Is an array of type [a, b, c]
                {
                    size_t pos = 1;
                    while(pos != std::string::npos)
                    {
                        size_t ppos = s.find(',', pos);

                        if(ppos != std::string::npos)
                        {
208 209
                            std::string temp = s.substr(pos, ppos-pos);
                            res.push_back(temp);
210 211 212 213 214
                            pos = ppos+1;
                        }
                        else
                        {
                            std::string temp = s.substr(pos, std::string::npos);
215 216
                            temp = temp.substr(0, temp.size()-1);
                            res.push_back(temp);
217 218 219 220 221 222 223 224 225
                            pos = ppos;
                        }
                    }
                }
            }

            return res;
        }

226 227 228 229 230
	private: // data

		std::map<std::string, std::string> _map ;

} ;