c901198d2aab259bf89e53ad97f92ea68c1d9be7
[platform/upstream/doxygen.git] / src / configimpl.h
1 /******************************************************************************
2  *
3  * 
4  *
5  *
6  * Copyright (C) 1997-2015 by Dimitri van Heesch.
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation under the terms of the GNU General Public License is hereby 
10  * granted. No representations are made about the suitability of this software 
11  * for any purpose. It is provided "as is" without express or implied warranty.
12  * See the GNU General Public License for more details.
13  *
14  * Documents produced by Doxygen are derivative works derived from the
15  * input used in their production; they are not affected by this license.
16  *
17  */
18
19 #ifndef CONFIGIMPL_H
20 #define CONFIGIMPL_H
21
22 #include <qstrlist.h>
23 #include <qdict.h>
24 #include <qlist.h>
25 #include <qregexp.h>
26 #include "ftextstream.h"
27
28
29 /** Abstract base class for any configuration option.
30  */
31 class ConfigOption
32 {
33     friend class ConfigImpl;
34
35   public:
36
37     /*! The type of option */
38     enum OptionType 
39     { 
40       O_Info,      //<! A section header
41       O_List,      //<! A list of items
42       O_Enum,      //<! A fixed set of items
43       O_String,    //<! A single item
44       O_Int,       //<! An integer value
45       O_Bool,      //<! A boolean value
46       O_Obsolete,  //<! An obsolete option
47       O_Disabled   //<! Disabled compile time option
48     };
49     enum 
50     { 
51      /*! Maximum length of an option in the config file. Used for 
52       *  alignment purposes.
53       */
54       MAX_OPTION_LENGTH = 23  
55     };
56     ConfigOption(OptionType t) : m_kind(t) 
57     {
58       m_spaces.fill(' ',40);
59     }
60     virtual ~ConfigOption()
61     {
62     }
63
64     /*! returns the kind of option this is. */
65     OptionType kind() const { return m_kind; }
66     QCString name() const { return m_name; }
67     QCString docs() const { return m_doc; }
68
69     QCString dependsOn() const { return m_dependency; }
70     void addDependency(const char *dep) { m_dependency = dep; }
71     void setEncoding(const QCString &e) { m_encoding = e; }
72     void setUserComment(const QCString &u) { m_userComment += u; }
73
74   protected:
75     virtual void writeTemplate(FTextStream &t,bool sl,bool upd) = 0;
76     virtual void convertStrToVal() {}
77     virtual void substEnvVars() = 0;
78     virtual void init() {}
79
80     void writeBoolValue(FTextStream &t,bool v);
81     void writeIntValue(FTextStream &t,int i);
82     void writeStringValue(FTextStream &t,QCString &s);
83     void writeStringList(FTextStream &t,QStrList &l);
84
85     QCString m_spaces;
86     QCString m_name;
87     QCString m_doc;
88     QCString m_dependency;
89     QCString m_encoding;
90     QCString m_userComment;
91     OptionType m_kind;
92 };
93
94 /** Section marker for grouping the configuration options.
95  */
96 class ConfigInfo : public ConfigOption
97 {
98   public:
99     ConfigInfo(const char *name,const char *doc) 
100       : ConfigOption(O_Info)
101     {
102       m_name = name;
103       m_doc = doc;
104     }
105     void writeTemplate(FTextStream &t, bool sl,bool);
106     void substEnvVars() {}
107 };
108
109 /** Class respresenting a list type option.
110  */
111 class ConfigList : public ConfigOption
112 {
113   public:
114     enum WidgetType { String, File, Dir, FileAndDir };
115     ConfigList(const char *name,const char *doc) 
116       : ConfigOption(O_List)
117     {
118       m_name = name;
119       m_doc = doc;
120       m_widgetType = String;
121     }
122     void addValue(const char *v) { m_defaultValue.append(v); }
123     void setWidgetType(WidgetType w) { m_widgetType = w; }
124     WidgetType widgetType() const { return m_widgetType; }
125     QStrList *valueRef() { return &m_value; }
126     void writeTemplate(FTextStream &t,bool sl,bool);
127     void substEnvVars();
128     void init() { m_value = m_defaultValue; }
129   private:
130     QStrList m_value;
131     QStrList m_defaultValue;
132     WidgetType m_widgetType;
133 };
134
135 /** Class representing an enum type option.
136  */
137 class ConfigEnum : public ConfigOption
138 {
139   public:
140     ConfigEnum(const char *name,const char *doc,const char *defVal) 
141       : ConfigOption(O_Enum)
142     {
143       m_name = name;
144       m_doc = doc;
145       m_value = defVal;
146       m_defValue = defVal;
147     }
148     void addValue(const char *v) { m_valueRange.append(v); }
149     QStrListIterator iterator() 
150     {
151       return QStrListIterator(m_valueRange);
152     }
153     QCString *valueRef() { return &m_value; }
154     void substEnvVars();
155     void writeTemplate(FTextStream &t,bool sl,bool);
156     void init() { m_value = m_defValue.copy(); }
157
158   private:
159     QStrList m_valueRange;
160     QCString m_value;
161     QCString m_defValue;
162 };
163
164 /** Class representing a string type option.
165  */
166 class ConfigString : public ConfigOption
167 {
168   public:
169     enum WidgetType { String, File, Dir, Image };
170     ConfigString(const char *name,const char *doc) 
171       : ConfigOption(O_String)
172     {
173       m_name = name;
174       m_doc = doc;
175       m_widgetType = String;
176     }
177    ~ConfigString()
178     {
179     }
180     void setWidgetType(WidgetType w) { m_widgetType = w; }
181     WidgetType widgetType() const { return m_widgetType; }
182     void setDefaultValue(const char *v) { m_defValue = v; }
183     QCString *valueRef() { return &m_value; }
184     void writeTemplate(FTextStream &t,bool sl,bool);
185     void substEnvVars();
186     void init() { m_value = m_defValue.copy(); }
187   
188   private:
189     QCString m_value;
190     QCString m_defValue;
191     WidgetType m_widgetType;
192 };
193
194 /** Class representing an integer type option.
195  */
196 class ConfigInt : public ConfigOption
197 {
198   public:
199     ConfigInt(const char *name,const char *doc,int minVal,int maxVal,int defVal) 
200       : ConfigOption(O_Int)
201     {
202       m_name = name;
203       m_doc = doc;
204       m_value = defVal;
205       m_defValue = defVal;
206       m_minVal = minVal;
207       m_maxVal = maxVal;
208     }
209     QCString *valueStringRef() { return &m_valueString; }
210     int *valueRef() { return &m_value; }
211     int minVal() const { return m_minVal; }
212     int maxVal() const { return m_maxVal; }
213     void convertStrToVal();
214     void substEnvVars();
215     void writeTemplate(FTextStream &t,bool sl,bool upd);
216     void init() { m_value = m_defValue; }
217   private:
218     int m_value;
219     int m_defValue;
220     int m_minVal;
221     int m_maxVal;
222     QCString m_valueString;
223 };
224
225 /** Class representing a Boolean type option.
226  */
227 class ConfigBool : public ConfigOption
228 {
229   public:
230     ConfigBool(const char *name,const char *doc,bool defVal) 
231       : ConfigOption(O_Bool)
232     {
233       m_name = name;
234       m_doc = doc;
235       m_value = defVal;
236       m_defValue = defVal;
237     }
238     QCString *valueStringRef() { return &m_valueString; }
239     bool *valueRef() { return &m_value; }
240     void convertStrToVal();
241     void substEnvVars();
242     void setValueString(const QCString &v) { m_valueString = v; }
243     void writeTemplate(FTextStream &t,bool sl,bool upd);
244     void init() { m_value = m_defValue; }
245   private:
246     bool m_value;
247     bool m_defValue;
248     QCString m_valueString;
249 };
250
251 /** Section marker for obsolete options
252  */
253 class ConfigObsolete : public ConfigOption
254 {
255   public:
256     ConfigObsolete(const char *name) : ConfigOption(O_Obsolete)  
257     { m_name = name; }
258     void writeTemplate(FTextStream &,bool,bool);
259     void substEnvVars() {}
260 };
261
262 /** Section marker for compile time optional options
263  */
264 class ConfigDisabled : public ConfigOption
265 {
266   public:
267     ConfigDisabled(const char *name) : ConfigOption(O_Disabled)  
268     { m_name = name; }
269     void writeTemplate(FTextStream &,bool,bool);
270     void substEnvVars() {}
271 };
272
273 // some convenience macros for access the config options
274 #define ConfigImpl_getString(val)  ConfigImpl::instance()->getString(__FILE__,__LINE__,val)
275 #define ConfigImpl_getInt(val)     ConfigImpl::instance()->getInt(__FILE__,__LINE__,val)
276 #define ConfigImpl_getList(val)    ConfigImpl::instance()->getList(__FILE__,__LINE__,val)
277 #define ConfigImpl_getEnum(val)    ConfigImpl::instance()->getEnum(__FILE__,__LINE__,val)
278 #define ConfigImpl_getBool(val)    ConfigImpl::instance()->getBool(__FILE__,__LINE__,val)
279
280
281 /** Singleton for configuration variables.
282  *
283  *  This object holds the global static variables
284  *  read from a user-supplied configuration file.
285  *  The static member instance() can be used to get
286  *  a pointer to the one and only instance.
287  *  
288  *  Set all variables to their default values by
289  *  calling Config::instance()->init()
290  *
291  */
292 class ConfigImpl
293 {
294   public:
295     /////////////////////////////
296     // public API
297     /////////////////////////////
298
299     /*! Returns the one and only instance of this class */
300     static ConfigImpl *instance()
301     {
302       if (m_instance==0) m_instance = new ConfigImpl;
303       return m_instance;
304     }
305     /*! Delete the instance */
306     static void deleteInstance()
307     {
308       delete m_instance;
309       m_instance=0;
310     }
311     
312     /*! Returns an iterator that can by used to iterate over the 
313      *  configuration options.
314      */
315     QListIterator<ConfigOption> iterator()
316     {
317       return QListIterator<ConfigOption>(*m_options);
318     }
319
320     /*! 
321      *  @name Getting configuration values.
322      *  @{
323      */
324
325     /*! Returns the value of the string option with name \a fileName. 
326      *  The arguments \a num and \a name are for debugging purposes only.
327      *  There is a convenience function Config_getString() for this.
328      */
329     QCString &getString(const char *fileName,int num,const char *name) const;
330
331     /*! Returns the value of the list option with name \a fileName. 
332      *  The arguments \a num and \a name are for debugging purposes only.
333      *  There is a convenience function Config_getList() for this.
334      */
335     QStrList &getList(const char *fileName,int num,const char *name) const;
336
337     /*! Returns the value of the enum option with name \a fileName. 
338      *  The arguments \a num and \a name are for debugging purposes only.
339      *  There is a convenience function Config_getEnum() for this.
340      */
341     QCString &getEnum(const char *fileName,int num,const char *name) const;
342
343     /*! Returns the value of the integer option with name \a fileName. 
344      *  The arguments \a num and \a name are for debugging purposes only.
345      *  There is a convenience function Config_getInt() for this.
346      */
347     int      &getInt(const char *fileName,int num,const char *name) const;
348
349     /*! Returns the value of the boolean option with name \a fileName. 
350      *  The arguments \a num and \a name are for debugging purposes only.
351      *  There is a convenience function Config_getBool() for this.
352      */
353     bool     &getBool(const char *fileName,int num,const char *name) const;
354
355     /*! Returns the ConfigOption corresponding with \a name or 0 if
356      *  the option is not supported.
357      */
358     ConfigOption *get(const char *name) const
359     {
360       return m_dict->find(name); 
361     }
362     /* @} */
363
364     /*! 
365      *  @name Adding configuration options. 
366      *  @{
367      */
368
369     /*! Starts a new configuration section with \a name and description \a doc.
370      *  \returns An object representing the option.
371      */
372     ConfigInfo   *addInfo(const char *name,const char *doc)
373     {
374       ConfigInfo *result = new ConfigInfo(name,doc);
375       m_options->append(result);
376       return result;
377     }
378
379     /*! Adds a new string option with \a name and documentation \a doc.
380      *  \returns An object representing the option.
381      */
382     ConfigString *addString(const char *name,
383                             const char *doc)
384     {
385       ConfigString *result = new ConfigString(name,doc);
386       m_options->append(result);
387       m_dict->insert(name,result);
388       return result;
389     }
390
391     /*! Adds a new enumeration option with \a name and documentation \a doc
392      *  and initial value \a defVal. 
393      *  \returns An object representing the option.
394      */
395     ConfigEnum   *addEnum(const char *name,
396                           const char *doc,
397                           const char *defVal)
398     {
399       ConfigEnum *result = new ConfigEnum(name,doc,defVal);
400       m_options->append(result);
401       m_dict->insert(name,result);
402       return result;
403     }
404
405     /*! Adds a new string option with \a name and documentation \a doc.
406      *  \returns An object representing the option.
407      */
408     ConfigList   *addList(const char *name,
409                           const char *doc)
410     {
411       ConfigList *result = new ConfigList(name,doc);
412       m_options->append(result);
413       m_dict->insert(name,result);
414       return result;
415     }
416
417     /*! Adds a new integer option with \a name and documentation \a doc.
418      *  The integer has a range between \a minVal and \a maxVal and a
419      *  default value of \a defVal.
420      *  \returns An object representing the option.
421      */
422     ConfigInt    *addInt(const char *name,
423                          const char *doc,
424                          int minVal,int maxVal,int defVal)
425     {
426       ConfigInt *result = new ConfigInt(name,doc,minVal,maxVal,defVal);
427       m_options->append(result);
428       m_dict->insert(name,result);
429       return result;
430     }
431
432     /*! Adds a new boolean option with \a name and documentation \a doc.
433      *  The boolean has a default value of \a defVal.
434      *  \returns An object representing the option.
435      */
436     ConfigBool   *addBool(const char *name,
437                           const char *doc,
438                           bool defVal)
439     {
440       ConfigBool *result = new ConfigBool(name,doc,defVal);
441       m_options->append(result);
442       m_dict->insert(name,result);
443       return result;
444     }
445     /*! Adds an option that has become obsolete. */
446     ConfigOption *addObsolete(const char *name)
447     {
448       ConfigObsolete *option = new ConfigObsolete(name);
449       m_dict->insert(name,option);
450       m_obsolete->append(option);
451       return option;
452     }
453     /*! Adds an option that has been disabled at compile time. */
454     ConfigOption *addDisabled(const char *name)
455     {
456       ConfigDisabled *option = new ConfigDisabled(name);
457       m_dict->insert(name,option);
458       m_disabled->append(option);
459       return option;
460     }
461     /*! @} */
462
463     /*! Writes a template configuration to stream \a t. If \a shortIndex
464      *  is \c TRUE the description of each configuration option will
465      *  be omitted.
466      */
467     void writeTemplate(FTextStream &t,bool shortIndex,bool updateOnly);
468
469     void setHeader(const char *header) { m_header = header; }
470
471     /////////////////////////////
472     // internal API
473     /////////////////////////////
474
475     /*! Converts the string values read from the configuration file
476      *  to real values for non-string type options (like int, and bools)
477      */
478     void convertStrToVal();
479
480     /*! Replaces references to environment variable by the actual value
481      *  of the environment variable.
482      */
483     void substituteEnvironmentVars();
484
485     /*! Initialize config variables to their default value */
486     void init();
487
488     /*! Parse a configuration data in string \a str.
489      *  \returns TRUE if successful, or FALSE if the string could not be
490      *  parsed.
491      */ 
492     //bool parseString(const char *fn,const char *str);
493     bool parseString(const char *fn,const char *str,bool upd = FALSE);
494
495     /*! Parse a configuration file with name \a fn.
496      *  \returns TRUE if successful, FALSE if the file could not be 
497      *  opened or read.
498      */ 
499     bool parse(const char *fn,bool upd = FALSE);
500
501     /*! Called from the constructor, will add doxygen's default options
502      *  to the configuration object 
503      */
504     void create();
505
506     /*! Append user start comment
507      */
508     void appendStartComment(const QCString &u)
509     {
510       m_startComment += u;
511     }
512     /*! Append user comment
513      */
514     void appendUserComment(const QCString &u)
515     {
516       m_userComment += u;
517     }
518     /*! Take the user start comment and reset it internally
519      *  \returns user start comment
520      */
521     QCString takeStartComment()
522     {
523       QCString result=m_startComment;
524       m_startComment.resize(0);
525       return result.replace(QRegExp("\r"),"");
526     }
527     /*! Take the user comment and reset it internally
528      *  \returns user comment
529      */
530     QCString takeUserComment()
531     {
532       QCString result=m_userComment;
533       m_userComment.resize(0);
534       return result.replace(QRegExp("\r"),"");
535     }
536
537   protected:
538
539     ConfigImpl()
540     {
541       m_options  = new QList<ConfigOption>;
542       m_obsolete = new QList<ConfigOption>;
543       m_disabled = new QList<ConfigOption>;
544       m_dict     = new QDict<ConfigOption>(257);
545       m_options->setAutoDelete(TRUE);
546       m_obsolete->setAutoDelete(TRUE);
547       m_disabled->setAutoDelete(TRUE);
548       m_initialized = FALSE;
549       create();
550     }
551    ~ConfigImpl()
552     {
553       delete m_options;
554       delete m_obsolete;
555       delete m_disabled;
556       delete m_dict;
557     }
558
559   private:
560     QList<ConfigOption> *m_options;
561     QList<ConfigOption> *m_obsolete;
562     QList<ConfigOption> *m_disabled;
563     QDict<ConfigOption> *m_dict;
564     static ConfigImpl *m_instance;
565     QCString m_startComment;
566     QCString m_userComment;
567     bool m_initialized;
568     QCString m_header;
569 };
570
571 #endif