1 /* MicroConf - minimal configuration framework
2  * Copyright (C) 2010 Stefan Westerfeld
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General
15  * Public License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 
20 #ifndef SPECTMORPH_MICRO_CONF_HH
21 #define SPECTMORPH_MICRO_CONF_HH
22 
23 #include <string>
24 #include <vector>
25 
26 #include <stdio.h>
27 
28 namespace SpectMorph
29 {
30 
31 class MicroConf
32 {
33 public:
34   enum NumberFormat {
35     I18N,
36     NO_I18N
37   };
38 private:
39   FILE                    *cfg_file;
40   std::string              current_line;
41   int                      current_no;
42   std::string              current_file;
43   std::vector<std::string> tokens;
44   bool                     tokenizer_error;
45   NumberFormat             m_number_format;
46 
47   bool convert (const std::string& token, int& arg);
48   bool convert (const std::string& token, double& arg);
49   bool convert (const std::string& token, std::string& arg);
50 
51   bool tokenize();
52 public:
53   MicroConf (const std::string& filename);
54   ~MicroConf();
55 
56   NumberFormat number_format();
57   void set_number_format (NumberFormat new_number_format);
58 
59   bool open_ok();
60   bool next();
61   std::string line();
62   void die_if_unknown();
63 
64   template<class T1>
command(const std::string & cmd,T1 & arg1)65   bool command (const std::string& cmd, T1& arg1)
66   {
67     if (tokenizer_error || tokens.size() != 2 || cmd != tokens[0])
68       return false;
69     return convert (tokens[1], arg1);
70   }
71   template<class T1, class T2>
command(const std::string & cmd,T1 & arg1,T2 & arg2)72   bool command (const std::string& cmd, T1& arg1, T2& arg2)
73   {
74     if (tokenizer_error || tokens.size() != 3 || cmd != tokens[0])
75       return false;
76     return convert (tokens[1], arg1) && convert (tokens[2], arg2);
77   }
78   template<class T1, class T2, class T3>
command(const std::string & cmd,T1 & arg1,T2 & arg2,T3 & arg3)79   bool command (const std::string& cmd, T1& arg1, T2& arg2, T3& arg3)
80   {
81     if (tokenizer_error || tokens.size() != 4 || cmd != tokens[0])
82       return false;
83     return convert (tokens[1], arg1) && convert (tokens[2], arg2) && convert (tokens[3], arg3);
84   }
85   template<class T1, class T2, class T3, class T4>
command(const std::string & cmd,T1 & arg1,T2 & arg2,T3 & arg3,T4 & arg4)86   bool command (const std::string& cmd, T1& arg1, T2& arg2, T3& arg3, T4& arg4)
87   {
88     if (tokenizer_error || tokens.size() != 5 || cmd != tokens[0])
89       return false;
90     return convert (tokens[1], arg1) && convert (tokens[2], arg2) && convert (tokens[3], arg3)
91       &&   convert (tokens[4], arg4);
92   }
93   template<class T1, class T2, class T3, class T4, class T5>
command(const std::string & cmd,T1 & arg1,T2 & arg2,T3 & arg3,T4 & arg4,T5 & arg5)94   bool command (const std::string& cmd, T1& arg1, T2& arg2, T3& arg3, T4& arg4, T5& arg5)
95   {
96     if (tokenizer_error || tokens.size() != 6 || cmd != tokens[0])
97       return false;
98     return convert (tokens[1], arg1) && convert (tokens[2], arg2) && convert (tokens[3], arg3)
99       &&   convert (tokens[4], arg4) && convert (tokens[5], arg5);
100   }
101   template<class T1, class T2, class T3, class T4, class T5, class T6>
command(const std::string & cmd,T1 & arg1,T2 & arg2,T3 & arg3,T4 & arg4,T5 & arg5,T6 & arg6)102   bool command (const std::string& cmd, T1& arg1, T2& arg2, T3& arg3, T4& arg4, T5& arg5, T6& arg6)
103   {
104     if (tokenizer_error || tokens.size() != 7 || cmd != tokens[0])
105       return false;
106     return convert (tokens[1], arg1) && convert (tokens[2], arg2) && convert (tokens[3], arg3)
107       &&   convert (tokens[4], arg4) && convert (tokens[5], arg5) && convert (tokens[6], arg6);
108   }
109 };
110 
111 }
112 
113 #endif
114