Orb/Doxygen/src/config.h
changeset 0 42188c7ea2d9
child 4 468f4c8d3d5b
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     1 /******************************************************************************
       
     2  *
       
     3  * 
       
     4  *
       
     5  *
       
     6  * Copyright (C) 1997-2008 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 CONFIG_H
       
    20 #define CONFIG_H
       
    21 
       
    22 #include "qtbc.h"
       
    23 #include <qstrlist.h>
       
    24 #include <qfile.h>
       
    25 #include <qdict.h>
       
    26 #include <qlist.h>
       
    27 #include <qtextstream.h>
       
    28 
       
    29 /*! \brief Abstract base class for any configuration option.
       
    30  *
       
    31  */
       
    32 class ConfigOption
       
    33 {
       
    34     friend class Config;
       
    35 
       
    36   public:
       
    37 
       
    38     /*! The type of option */
       
    39     enum OptionType 
       
    40     { 
       
    41       O_Info,      //<! A section header
       
    42       O_List,      //<! A list of items
       
    43       O_Enum,      //<! A fixed set of items
       
    44       O_String,    //<! A single item
       
    45       O_Int,       //<! An integer value
       
    46       O_Bool,      //<! A boolean value
       
    47       O_Obsolete   //<! An obsolete 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 
       
    73   protected:
       
    74     virtual void writeTemplate(QTextStream &t,bool sl,bool upd) = 0;
       
    75     virtual void convertStrToVal() {}
       
    76     virtual void substEnvVars() = 0;
       
    77     virtual void writeXML(QTextStream&) {}
       
    78     virtual void init() {}
       
    79 
       
    80     QCString convertToComment(const QCString &s);
       
    81     void writeBoolValue(QTextStream &t,bool v);
       
    82     void writeIntValue(QTextStream &t,int i);
       
    83     void writeStringValue(QTextStream &t,QCString &s);
       
    84     void writeStringList(QTextStream &t,QStrList &l);
       
    85 
       
    86     QCString m_spaces;
       
    87     QCString m_name;
       
    88     QCString m_doc;
       
    89     QCString m_dependency;
       
    90     QCString m_encoding;
       
    91     OptionType m_kind;
       
    92 };
       
    93 
       
    94 /*! \brief Section marker for grouping the configuration options
       
    95  *
       
    96  */
       
    97 class ConfigInfo : public ConfigOption
       
    98 {
       
    99   public:
       
   100     ConfigInfo(const char *name,const char *doc) 
       
   101       : ConfigOption(O_Info)
       
   102     {
       
   103       m_name = name;
       
   104       m_doc = doc;
       
   105     }
       
   106     void writeTemplate(QTextStream &t, bool sl,bool)
       
   107     {
       
   108       if (!sl)
       
   109       {
       
   110         t << "\n";
       
   111       }
       
   112       t << "#---------------------------------------------------------------------------\n";
       
   113       t << "# " << m_doc << endl;
       
   114       t << "#---------------------------------------------------------------------------\n";
       
   115     }
       
   116     void substEnvVars() {}
       
   117 };
       
   118 
       
   119 /*! \brief Option of the list type.
       
   120  *
       
   121  */
       
   122 class ConfigList : public ConfigOption
       
   123 {
       
   124   public:
       
   125     enum WidgetType { String, File, Dir, FileAndDir };
       
   126     ConfigList(const char *name,const char *doc) 
       
   127       : ConfigOption(O_List)
       
   128     {
       
   129       m_name = name;
       
   130       m_doc = doc;
       
   131       m_widgetType = String;
       
   132     }
       
   133     void addValue(const char *v) { m_value.append(v); }
       
   134     void setWidgetType(WidgetType w) { m_widgetType = w; }
       
   135     WidgetType widgetType() const { return m_widgetType; }
       
   136     QStrList *valueRef() { return &m_value; }
       
   137     void writeTemplate(QTextStream &t,bool sl,bool)
       
   138     {
       
   139       if (!sl)
       
   140       {
       
   141         t << endl;
       
   142         t << convertToComment(m_doc);
       
   143         t << endl;
       
   144       }
       
   145       t << m_name << m_spaces.left(MAX_OPTION_LENGTH-m_name.length()) << "=";
       
   146       writeStringList(t,m_value);
       
   147       t << "\n";
       
   148     }
       
   149     void substEnvVars();
       
   150     void writeXML(QTextStream&);
       
   151     void init() { m_value.clear(); }
       
   152   private:
       
   153     QStrList m_value;
       
   154     WidgetType m_widgetType;
       
   155 };
       
   156 
       
   157 /*! \brief Option of the enum type.
       
   158  *
       
   159  */
       
   160 class ConfigEnum : public ConfigOption
       
   161 {
       
   162   public:
       
   163     ConfigEnum(const char *name,const char *doc,const char *defVal) 
       
   164       : ConfigOption(O_Enum)
       
   165     {
       
   166       m_name = name;
       
   167       m_doc = doc;
       
   168       m_value = defVal;
       
   169       m_defValue = defVal;
       
   170     }
       
   171     void addValue(const char *v) { m_valueRange.append(v); }
       
   172     QStrListIterator iterator() 
       
   173     {
       
   174       return QStrListIterator(m_valueRange);
       
   175     }
       
   176     QCString *valueRef() { return &m_value; }
       
   177     void substEnvVars();
       
   178     void writeTemplate(QTextStream &t,bool sl,bool)
       
   179     {
       
   180       if (!sl)
       
   181       {
       
   182         t << endl;
       
   183         t << convertToComment(m_doc);
       
   184         t << endl;
       
   185       }
       
   186       t << m_name << m_spaces.left(MAX_OPTION_LENGTH-m_name.length()) << "=";
       
   187       writeStringValue(t,m_value);
       
   188       t << "\n";
       
   189     }
       
   190     void writeXML(QTextStream&);
       
   191     void init() { m_value = m_defValue.copy(); }
       
   192 
       
   193   private:
       
   194     QStrList m_valueRange;
       
   195     QCString m_value;
       
   196     QCString m_defValue;
       
   197 };
       
   198 
       
   199 /*! \brief Option of the string type.
       
   200  *
       
   201  */
       
   202 class ConfigString : public ConfigOption
       
   203 {
       
   204   public:
       
   205     enum WidgetType { String, File, Dir };
       
   206     ConfigString(const char *name,const char *doc) 
       
   207       : ConfigOption(O_String)
       
   208     {
       
   209       m_name = name;
       
   210       m_doc = doc;
       
   211       m_widgetType = String;
       
   212     }
       
   213    ~ConfigString()
       
   214     {
       
   215     }
       
   216     void setWidgetType(WidgetType w) { m_widgetType = w; }
       
   217     WidgetType widgetType() const { return m_widgetType; }
       
   218     void setDefaultValue(const char *v) { m_defValue = v; }
       
   219     QCString *valueRef() { return &m_value; }
       
   220     void writeTemplate(QTextStream &t,bool sl,bool)
       
   221     {
       
   222       if (!sl)
       
   223       {
       
   224         t << endl;
       
   225         t << convertToComment(m_doc);
       
   226         t << endl;
       
   227       }
       
   228       t << m_name << m_spaces.left(MAX_OPTION_LENGTH-m_name.length()) << "=";
       
   229       writeStringValue(t,m_value);
       
   230       t << "\n";
       
   231     }
       
   232     void substEnvVars();
       
   233     void writeXML(QTextStream&);
       
   234     void init() { m_value = m_defValue.copy(); }
       
   235   
       
   236   private:
       
   237     QCString m_value;
       
   238     QCString m_defValue;
       
   239     WidgetType m_widgetType;
       
   240 };
       
   241 
       
   242 /*! \brief Option of the integer type.
       
   243  *
       
   244  */
       
   245 class ConfigInt : public ConfigOption
       
   246 {
       
   247   public:
       
   248     ConfigInt(const char *name,const char *doc,int minVal,int maxVal,int defVal) 
       
   249       : ConfigOption(O_Int)
       
   250     {
       
   251       m_name = name;
       
   252       m_doc = doc;
       
   253       m_value = defVal;
       
   254       m_defValue = defVal;
       
   255       m_minVal = minVal;
       
   256       m_maxVal = maxVal;
       
   257     }
       
   258     QCString *valueStringRef() { return &m_valueString; }
       
   259     int *valueRef() { return &m_value; }
       
   260     int minVal() const { return m_minVal; }
       
   261     int maxVal() const { return m_maxVal; }
       
   262     void convertStrToVal();
       
   263     void substEnvVars();
       
   264     void writeTemplate(QTextStream &t,bool sl,bool upd)
       
   265     {
       
   266       if (!sl)
       
   267       {
       
   268         t << endl;
       
   269         t << convertToComment(m_doc);
       
   270         t << endl;
       
   271       }
       
   272       t << m_name << m_spaces.left(MAX_OPTION_LENGTH-m_name.length()) << "=";
       
   273       if (upd && !m_valueString.isEmpty())
       
   274       {
       
   275         writeStringValue(t,m_valueString);
       
   276       }
       
   277       else
       
   278       {
       
   279         writeIntValue(t,m_value);
       
   280       }
       
   281       t << "\n";
       
   282     }
       
   283     void writeXML(QTextStream&);
       
   284     void init() { m_value = m_defValue; }
       
   285   private:
       
   286     int m_value;
       
   287     int m_defValue;
       
   288     int m_minVal;
       
   289     int m_maxVal;
       
   290     QCString m_valueString;
       
   291 };
       
   292 
       
   293 /*! \brief Option of the boolean type.
       
   294  *
       
   295  */
       
   296 class ConfigBool : public ConfigOption
       
   297 {
       
   298   public:
       
   299     ConfigBool(const char *name,const char *doc,bool defVal) 
       
   300       : ConfigOption(O_Bool)
       
   301     {
       
   302       m_name = name;
       
   303       m_doc = doc;
       
   304       m_value = defVal;
       
   305       m_defValue = defVal;
       
   306     }
       
   307     QCString *valueStringRef() { return &m_valueString; }
       
   308     bool *valueRef() { return &m_value; }
       
   309     void convertStrToVal();
       
   310     void substEnvVars();
       
   311     void setValueString(const QCString &v) { m_valueString = v; }
       
   312     void writeTemplate(QTextStream &t,bool sl,bool upd)
       
   313     {
       
   314       if (!sl)
       
   315       {
       
   316         t << endl;
       
   317         t << convertToComment(m_doc);
       
   318         t << endl;
       
   319       }
       
   320       t << m_name << m_spaces.left(MAX_OPTION_LENGTH-m_name.length()) << "=";
       
   321       if (upd && !m_valueString.isEmpty())
       
   322       {
       
   323         writeStringValue(t,m_valueString);
       
   324       }
       
   325       else
       
   326       {
       
   327         writeBoolValue(t,m_value);
       
   328       }
       
   329       t << "\n";
       
   330     }
       
   331     void writeXML(QTextStream&);
       
   332     void init() { m_value = m_defValue; }
       
   333   private:
       
   334     bool m_value;
       
   335     bool m_defValue;
       
   336     QCString m_valueString;
       
   337 };
       
   338 
       
   339 /*! \brief Section marker for obsolete options
       
   340  *
       
   341  */
       
   342 class ConfigObsolete : public ConfigOption
       
   343 {
       
   344   public:
       
   345     ConfigObsolete(const char *name,OptionType t) : ConfigOption(t)  
       
   346     { m_name = name; }
       
   347     void writeTemplate(QTextStream &,bool,bool) {}
       
   348     void substEnvVars() {}
       
   349     void writeXML(QTextStream&);
       
   350 };
       
   351 
       
   352 
       
   353 // some convenience macros
       
   354 #define Config_getString(val)  Config::instance()->getString(__FILE__,__LINE__,val)
       
   355 #define Config_getInt(val)     Config::instance()->getInt(__FILE__,__LINE__,val)
       
   356 #define Config_getList(val)    Config::instance()->getList(__FILE__,__LINE__,val)
       
   357 #define Config_getEnum(val)    Config::instance()->getEnum(__FILE__,__LINE__,val)
       
   358 #define Config_getBool(val)    Config::instance()->getBool(__FILE__,__LINE__,val)
       
   359 
       
   360 /*! \brief Singleton for configuration variables.
       
   361  *
       
   362  *  This object holds the global static variables
       
   363  *  read from a user-supplied configuration file.
       
   364  *  The static member instance() can be used to get
       
   365  *  a pointer to the one and only instance.
       
   366  *  
       
   367  *  Set all variables to their default values by
       
   368  *  calling Config::instance()->init()
       
   369  *
       
   370  */
       
   371 class Config
       
   372 {
       
   373   public:
       
   374     /////////////////////////////
       
   375     // public API
       
   376     /////////////////////////////
       
   377 
       
   378     /*! Returns the one and only instance of this class */
       
   379     static Config *instance()
       
   380     {
       
   381       if (m_instance==0) m_instance = new Config;
       
   382       return m_instance;
       
   383     }
       
   384     /*! Delete the instance */
       
   385     static void deleteInstance()
       
   386     {
       
   387       delete m_instance;
       
   388       m_instance=0;
       
   389     }
       
   390     
       
   391     /*! Returns an iterator that can by used to iterate over the 
       
   392      *  configuration options.
       
   393      */
       
   394     QListIterator<ConfigOption> iterator()
       
   395     {
       
   396       return QListIterator<ConfigOption>(*m_options);
       
   397     }
       
   398 
       
   399     /*! 
       
   400      *  @name Getting configuration values.
       
   401      *  @{
       
   402      */
       
   403 
       
   404     /*! Returns the value of the string option with name \a fileName. 
       
   405      *  The arguments \a num and \a name are for debugging purposes only.
       
   406      *  There is a convenience function Config_getString() for this.
       
   407      */
       
   408     QCString &getString(const char *fileName,int num,const char *name) const;
       
   409 
       
   410     /*! Returns the value of the list option with name \a fileName. 
       
   411      *  The arguments \a num and \a name are for debugging purposes only.
       
   412      *  There is a convenience function Config_getList() for this.
       
   413      */
       
   414     QStrList &getList(const char *fileName,int num,const char *name) const;
       
   415 
       
   416     /*! Returns the value of the enum option with name \a fileName. 
       
   417      *  The arguments \a num and \a name are for debugging purposes only.
       
   418      *  There is a convenience function Config_getEnum() for this.
       
   419      */
       
   420     QCString &getEnum(const char *fileName,int num,const char *name) const;
       
   421 
       
   422     /*! Returns the value of the integer option with name \a fileName. 
       
   423      *  The arguments \a num and \a name are for debugging purposes only.
       
   424      *  There is a convenience function Config_getInt() for this.
       
   425      */
       
   426     int      &getInt(const char *fileName,int num,const char *name) const;
       
   427 
       
   428     /*! Returns the value of the boolean option with name \a fileName. 
       
   429      *  The arguments \a num and \a name are for debugging purposes only.
       
   430      *  There is a convenience function Config_getBool() for this.
       
   431      */
       
   432     bool     &getBool(const char *fileName,int num,const char *name) const;
       
   433 
       
   434     /*! Returns the ConfigOption corresponding with \a name or 0 if
       
   435      *  the option is not supported.
       
   436      */
       
   437     ConfigOption *get(const char *name) const
       
   438     {
       
   439       return m_dict->find(name); 
       
   440     }
       
   441     /* @} */
       
   442 
       
   443     /*! 
       
   444      *  @name Adding configuration options. 
       
   445      *  @{
       
   446      */
       
   447 
       
   448     /*! Starts a new configuration section with \a name and description \a doc.
       
   449      *  \returns An object representing the option.
       
   450      */
       
   451     ConfigInfo   *addInfo(const char *name,const char *doc)
       
   452     {
       
   453       ConfigInfo *result = new ConfigInfo(name,doc);
       
   454       m_options->append(result);
       
   455       return result;
       
   456     }
       
   457 
       
   458     /*! Adds a new string option with \a name and documentation \a doc.
       
   459      *  \returns An object representing the option.
       
   460      */
       
   461     ConfigString *addString(const char *name,
       
   462                             const char *doc)
       
   463     {
       
   464       ConfigString *result = new ConfigString(name,doc);
       
   465       m_options->append(result);
       
   466       m_dict->insert(name,result);
       
   467       return result;
       
   468     }
       
   469 
       
   470     /*! Adds a new enumeration option with \a name and documentation \a doc
       
   471      *  and initial value \a defVal. 
       
   472      *  \returns An object representing the option.
       
   473      */
       
   474     ConfigEnum   *addEnum(const char *name,
       
   475                           const char *doc,
       
   476                           const char *defVal)
       
   477     {
       
   478       ConfigEnum *result = new ConfigEnum(name,doc,defVal);
       
   479       m_options->append(result);
       
   480       m_dict->insert(name,result);
       
   481       return result;
       
   482     }
       
   483 
       
   484     /*! Adds a new string option with \a name and documentation \a doc.
       
   485      *  \returns An object representing the option.
       
   486      */
       
   487     ConfigList   *addList(const char *name,
       
   488                           const char *doc)
       
   489     {
       
   490       ConfigList *result = new ConfigList(name,doc);
       
   491       m_options->append(result);
       
   492       m_dict->insert(name,result);
       
   493       return result;
       
   494     }
       
   495 
       
   496     /*! Adds a new integer option with \a name and documentation \a doc.
       
   497      *  The integer has a range between \a minVal and \a maxVal and a
       
   498      *  default value of \a defVal.
       
   499      *  \returns An object representing the option.
       
   500      */
       
   501     ConfigInt    *addInt(const char *name,
       
   502                          const char *doc,
       
   503                          int minVal,int maxVal,int defVal)
       
   504     {
       
   505       ConfigInt *result = new ConfigInt(name,doc,minVal,maxVal,defVal);
       
   506       m_options->append(result);
       
   507       m_dict->insert(name,result);
       
   508       return result;
       
   509     }
       
   510 
       
   511     /*! Adds a new boolean option with \a name and documentation \a doc.
       
   512      *  The boolean has a default value of \a defVal.
       
   513      *  \returns An object representing the option.
       
   514      */
       
   515     ConfigBool   *addBool(const char *name,
       
   516                           const char *doc,
       
   517                           bool defVal)
       
   518     {
       
   519       ConfigBool *result = new ConfigBool(name,doc,defVal);
       
   520       m_options->append(result);
       
   521       m_dict->insert(name,result);
       
   522       return result;
       
   523     }
       
   524     /*! Adds an option that has become obsolete. */
       
   525     ConfigOption *addObsolete(const char *name)
       
   526     {
       
   527       ConfigObsolete *option = new ConfigObsolete(name,ConfigOption::O_Obsolete);
       
   528       m_dict->insert(name,option);
       
   529       m_obsolete->append(option);
       
   530       return option;
       
   531     }
       
   532     /*! @} */
       
   533 
       
   534     /*! Writes a template configuration to stream \a t. If \a shortIndex
       
   535      *  is \c TRUE the description of each configuration option will
       
   536      *  be omitted.
       
   537      */
       
   538     void writeTemplate(QTextStream &t,bool shortIndex,bool updateOnly);
       
   539 
       
   540     /** Write XML representation of the config file */
       
   541     void writeXML(QTextStream &t);
       
   542 
       
   543     /////////////////////////////
       
   544     // internal API
       
   545     /////////////////////////////
       
   546 
       
   547     /*! Converts the string values read from the configuration file
       
   548      *  to real values for non-string type options (like int, and bools)
       
   549      */
       
   550     void convertStrToVal();
       
   551 
       
   552     /*! Replaces references to environment variable by the actual value
       
   553      *  of the environment variable.
       
   554      */
       
   555     void substituteEnvironmentVars();
       
   556 
       
   557     /*! Checks if the values of the variable are correct, adjusts them
       
   558      *  if needed, and report any errors.
       
   559      */
       
   560     void check();
       
   561 
       
   562     /*! Initialize config variables to their default value */
       
   563     void init();
       
   564 
       
   565     /*! Parse a configuration data in string \a str.
       
   566      *  \returns TRUE if successful, or FALSE if the string could not be
       
   567      *  parsed.
       
   568      */ 
       
   569     bool parseString(const char *fn,const char *str);
       
   570 
       
   571     /*! Parse a configuration file with name \a fn.
       
   572      *  \returns TRUE if successful, FALSE if the file could not be 
       
   573      *  opened or read.
       
   574      */ 
       
   575     bool parse(const char *fn);
       
   576 
       
   577     /*! Called from the constructor, will add doxygen's default options
       
   578      *  to the configuration object 
       
   579      */
       
   580     void create();
       
   581 
       
   582   protected:
       
   583 
       
   584     Config()
       
   585     { 
       
   586       m_options  = new QList<ConfigOption>;
       
   587       m_obsolete = new QList<ConfigOption>;
       
   588       m_dict     = new QDict<ConfigOption>(257);
       
   589       m_options->setAutoDelete(TRUE);
       
   590       m_obsolete->setAutoDelete(TRUE);
       
   591       m_initialized = FALSE;
       
   592       create();
       
   593     }
       
   594    ~Config()
       
   595     {
       
   596       delete m_options;
       
   597       delete m_obsolete;
       
   598       delete m_dict;
       
   599     }
       
   600 
       
   601   private:
       
   602     QList<ConfigOption> *m_options;
       
   603     QList<ConfigOption> *m_obsolete;
       
   604     QDict<ConfigOption> *m_dict;
       
   605     static Config *m_instance;
       
   606     bool m_initialized;
       
   607 };
       
   608 
       
   609 #endif