From ed1fb80b55bab16443b211ebeb1cd45bb630b08b Mon Sep 17 00:00:00 2001
From: albert-github <albert.tests@gmail.com>
Date: Sat, 15 Sep 2018 11:40:02 +0200
Subject: Difference between standard and used Doxyfile

Writes a the differences between the current configuration and the template configuration.

Useful when communicating e.g. in forums.
---
 doc/arch.doc     | 16 ++++++++++++++-
 doc/doxygen.1    |  4 ++++
 src/config.h     |  5 +++++
 src/configimpl.h | 14 +++++++++++++
 src/configimpl.l | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/doxygen.cpp  | 33 ++++++++++++++++++++++++++++++-
 6 files changed, 130 insertions(+), 2 deletions(-)

diff --git a/doc/arch.doc b/doc/arch.doc
index ed9d579..bd51a1b 100644
--- a/doc/arch.doc
+++ b/doc/arch.doc
@@ -248,7 +248,21 @@ Note that by running doxygen with `-d lex` you get information about which
 <h3>Testing</h3>
 
 Doxygen has a small set of tests available to test, some, code integrity.
-The tests can be run by means of the command `make tests`. When only one or a few tests are required one can set the variable \c TEST_FLAGS when running the test e.g. `make TEST_FLAGS="--id 5" tests` or for multiple tests `make TEST_FLAGS="--id 5 --id 7" tests`.
+The tests can be run by means of the command `make tests`. When only one or a
+few tests are required one can set the variable \c TEST_FLAGS when running the
+test e.g. `make TEST_FLAGS="--id 5" tests` or for multiple tests
+`make TEST_FLAGS="--id 5 --id 7" tests`. For a full set of possibilities give the
+command `make TEST_FLAGS="--help" tests`. It is also possible to specify the
+`TEST_FLAGS` as an environment variable (works also for testing through Visual
+Studio projects), e.g. `setenv TEST_FLAGS "--id 5 --id 7"` and `make tests`.
+
+<h3>Doxyfile differences</h3>
+
+In case one has to communicate through e.g. a forum the configuration settings that 
+are different from the standard doxygen configuration file settings one can run the
+doxygen command: with the `-x` option and the name of the configuration file (default
+is `Doxyfile`). The output will be a list of the not default settings (in `Doxyfile`
+format).
 
 \htmlonly
 Return to the <a href="index.html">index</a>.
diff --git a/doc/doxygen.1 b/doc/doxygen.1
index 5ac287e..a9c6b38 100644
--- a/doc/doxygen.1
+++ b/doc/doxygen.1
@@ -41,6 +41,10 @@ LaTeX: doxygen \fB\-w\fR latex headerFile footerFile styleSheetFile [configFile]
 .TP
 RTF:
 doxygen \fB\-e\fR rtf extensionsFile
+.TP
+7) Use doxygen to compare the used configuration file with the template configuration file
+.TP
+doxygen \fB\-x\fR [configFile]
 .PP
 If \fB\-s\fR is specified the comments in the config file will be omitted.
 If configName is omitted `Doxyfile' will be used as a default.
diff --git a/src/config.h b/src/config.h
index e86e950..98f5a92 100644
--- a/src/config.h
+++ b/src/config.h
@@ -51,6 +51,11 @@ namespace Config
    */
   void writeTemplate(FTextStream &t,bool shortList,bool updateOnly=FALSE);
 
+  /*! Writes a the differences between the current configuration and the
+   *  template configuration to stream \a t.
+   */
+  void compareDoxyfile(FTextStream &t);
+
   /*! Parses a configuration file with name \a fn.
    *  \returns TRUE if successful, FALSE if the file could not be
    *  opened or read.
diff --git a/src/configimpl.h b/src/configimpl.h
index c901198..ef8bb21 100644
--- a/src/configimpl.h
+++ b/src/configimpl.h
@@ -73,6 +73,7 @@ class ConfigOption
 
   protected:
     virtual void writeTemplate(FTextStream &t,bool sl,bool upd) = 0;
+    virtual void compareDoxyfile(FTextStream &t) = 0;
     virtual void convertStrToVal() {}
     virtual void substEnvVars() = 0;
     virtual void init() {}
@@ -103,6 +104,7 @@ class ConfigInfo : public ConfigOption
       m_doc = doc;
     }
     void writeTemplate(FTextStream &t, bool sl,bool);
+    void compareDoxyfile(FTextStream &){};
     void substEnvVars() {}
 };
 
@@ -124,6 +126,7 @@ class ConfigList : public ConfigOption
     WidgetType widgetType() const { return m_widgetType; }
     QStrList *valueRef() { return &m_value; }
     void writeTemplate(FTextStream &t,bool sl,bool);
+    void compareDoxyfile(FTextStream &t);
     void substEnvVars();
     void init() { m_value = m_defaultValue; }
   private:
@@ -153,6 +156,7 @@ class ConfigEnum : public ConfigOption
     QCString *valueRef() { return &m_value; }
     void substEnvVars();
     void writeTemplate(FTextStream &t,bool sl,bool);
+    void compareDoxyfile(FTextStream &t);
     void init() { m_value = m_defValue.copy(); }
 
   private:
@@ -182,6 +186,7 @@ class ConfigString : public ConfigOption
     void setDefaultValue(const char *v) { m_defValue = v; }
     QCString *valueRef() { return &m_value; }
     void writeTemplate(FTextStream &t,bool sl,bool);
+    void compareDoxyfile(FTextStream &t);
     void substEnvVars();
     void init() { m_value = m_defValue.copy(); }
   
@@ -213,6 +218,7 @@ class ConfigInt : public ConfigOption
     void convertStrToVal();
     void substEnvVars();
     void writeTemplate(FTextStream &t,bool sl,bool upd);
+    void compareDoxyfile(FTextStream &t);
     void init() { m_value = m_defValue; }
   private:
     int m_value;
@@ -241,6 +247,7 @@ class ConfigBool : public ConfigOption
     void substEnvVars();
     void setValueString(const QCString &v) { m_valueString = v; }
     void writeTemplate(FTextStream &t,bool sl,bool upd);
+    void compareDoxyfile(FTextStream &t);
     void init() { m_value = m_defValue; }
   private:
     bool m_value;
@@ -256,6 +263,7 @@ class ConfigObsolete : public ConfigOption
     ConfigObsolete(const char *name) : ConfigOption(O_Obsolete)  
     { m_name = name; }
     void writeTemplate(FTextStream &,bool,bool);
+    void compareDoxyfile(FTextStream &) {}
     void substEnvVars() {}
 };
 
@@ -267,6 +275,7 @@ class ConfigDisabled : public ConfigOption
     ConfigDisabled(const char *name) : ConfigOption(O_Disabled)  
     { m_name = name; }
     void writeTemplate(FTextStream &,bool,bool);
+    void compareDoxyfile(FTextStream &) {}
     void substEnvVars() {}
 };
 
@@ -466,6 +475,11 @@ class ConfigImpl
      */
     void writeTemplate(FTextStream &t,bool shortIndex,bool updateOnly);
 
+    /*! Writes a the differences between the current configuration and the
+     *  template configuration to stream \a t.
+     */
+    void compareDoxyfile(FTextStream &t);
+
     void setHeader(const char *header) { m_header = header; }
 
     /////////////////////////////
diff --git a/src/configimpl.l b/src/configimpl.l
index df032a6..72584d7 100644
--- a/src/configimpl.l
+++ b/src/configimpl.l
@@ -315,6 +315,28 @@ void ConfigList::writeTemplate(FTextStream &t,bool sl,bool)
   t << "\n";
 }
 
+void ConfigList::compareDoxyfile(FTextStream &t)
+{
+  if ( m_value.count() != m_defaultValue.count())
+  {
+    writeTemplate(t,TRUE,TRUE);
+    return;
+  }
+
+  const char *p = m_value.first();
+  const char *q = m_defaultValue.first();
+  while (p)
+  {
+    p = m_value.next();
+    q = m_defaultValue.next();
+    if (QCString(p).stripWhiteSpace() != QCString(q).stripWhiteSpace())
+    {
+      writeTemplate(t,TRUE,TRUE);
+      return;
+    }
+  }
+}
+
 void ConfigEnum::writeTemplate(FTextStream &t,bool sl,bool)
 {
   if (!sl)
@@ -332,6 +354,11 @@ void ConfigEnum::writeTemplate(FTextStream &t,bool sl,bool)
   t << "\n";
 }
 
+void ConfigEnum::compareDoxyfile(FTextStream &t)
+{
+  if (m_value != m_defValue) writeTemplate(t,TRUE,TRUE);
+}
+
 void ConfigString::writeTemplate(FTextStream &t,bool sl,bool)
 {
   if (!sl)
@@ -349,6 +376,11 @@ void ConfigString::writeTemplate(FTextStream &t,bool sl,bool)
   t << "\n";
 }
 
+void ConfigString::compareDoxyfile(FTextStream &t)
+{
+  if (m_value.stripWhiteSpace() != m_defValue.stripWhiteSpace()) writeTemplate(t,TRUE,TRUE);
+}
+
 void ConfigInt::writeTemplate(FTextStream &t,bool sl,bool upd)
 {
   if (!sl)
@@ -373,6 +405,11 @@ void ConfigInt::writeTemplate(FTextStream &t,bool sl,bool upd)
   t << "\n";
 }
 
+void ConfigInt::compareDoxyfile(FTextStream &t)
+{
+  if (m_value != m_defValue) writeTemplate(t,TRUE,TRUE);
+}
+
 void ConfigBool::writeTemplate(FTextStream &t,bool sl,bool upd)
 {
   if (!sl)
@@ -397,6 +434,11 @@ void ConfigBool::writeTemplate(FTextStream &t,bool sl,bool upd)
   t << "\n";
 }
 
+void ConfigBool::compareDoxyfile(FTextStream &t)
+{
+  if (m_value != m_defValue) writeTemplate(t,TRUE,TRUE);
+}
+
 void ConfigObsolete::writeTemplate(FTextStream &,bool,bool) {}
 void ConfigDisabled::writeTemplate(FTextStream &,bool,bool) {}
 
@@ -871,6 +913,18 @@ void ConfigImpl::writeTemplate(FTextStream &t,bool sl,bool upd)
   }
 }
 
+void ConfigImpl::compareDoxyfile(FTextStream &t)
+{
+  t << "# Difference with default Doxyfile " << versionString << endl;
+  QListIterator<ConfigOption> it = iterator();
+  ConfigOption *option;
+  for (;(option=it.current());++it)
+  {
+    option->m_userComment = "";
+    option->compareDoxyfile(t);
+  }
+}
+
 void ConfigImpl::convertStrToVal()
 {
   QListIterator<ConfigOption> it = iterator();
@@ -1749,6 +1803,12 @@ void Config::writeTemplate(FTextStream &t,bool shortList,bool update)
   ConfigImpl::instance()->writeTemplate(t,shortList,update);
 }
 
+void Config::compareDoxyfile(FTextStream &t)
+{
+  postProcess(FALSE);
+  ConfigImpl::instance()->compareDoxyfile(t);
+}
+
 bool Config::parse(const char *fileName,bool update)
 {
   return ConfigImpl::instance()->parse(fileName,update);
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index bf93a9b..f0fc650 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -9151,7 +9151,24 @@ static void generateConfigFile(const char *configFile,bool shortList,
     exit(1);
   }
 }
-
+static void compareDoxyfile()
+{
+  QFile f;
+  char configFile[2];
+  configFile[0] = '-';
+  configFile[1] = '\0';
+  bool fileOpened=openOutputFile(configFile,f);
+  if (fileOpened)
+  {
+    FTextStream t(&f);
+    Config::compareDoxyfile(t);
+  }
+  else
+  {
+    err("Cannot open file %s for writing\n",configFile);
+    exit(1);
+  }
+}
 //----------------------------------------------------------------------------
 // read and parse a tag file
 
@@ -10009,6 +10026,8 @@ static void usage(const char *name)
   msg("    LaTeX:      %s -w latex headerFile footerFile styleSheetFile [configFile]\n\n",name);
   msg("6) Use doxygen to generate a rtf extensions file\n");
   msg("    RTF:   %s -e rtf extensionsFile\n\n",name);
+  msg("7) Use doxygen to compare the used configuration file with the template configuration file\n");
+  msg("    %s -x [configFile]\n\n",name);
   msg("If -s is specified the comments of the configuration items in the config file will be omitted.\n");
   msg("If configName is omitted `Doxyfile' will be used as a default.\n\n");
   msg("-v print version string\n");
@@ -10211,6 +10230,7 @@ void readConfiguration(int argc, char **argv)
   const char *formatName;
   bool genConfig=FALSE;
   bool shortList=FALSE;
+  bool diffList=FALSE;
   bool updateConfig=FALSE;
   int retVal;
   while (optind<argc && argv[optind][0]=='-' &&
@@ -10248,6 +10268,9 @@ void readConfiguration(int argc, char **argv)
           exit(1);
         }
         break;
+      case 'x':
+        diffList=TRUE;
+        break;
       case 's':
         shortList=TRUE;
         break;
@@ -10498,6 +10521,7 @@ void readConfiguration(int argc, char **argv)
       exit(1);
     }
   }
+
   if (genConfig && g_useOutputTemplate)
   {
     generateTemplateFiles("templates");
@@ -10519,6 +10543,13 @@ void readConfiguration(int argc, char **argv)
     exit(1);
   }
 
+  if (diffList)
+  {
+    compareDoxyfile();
+    cleanUpDoxygen();
+    exit(0);
+  }
+
   if (updateConfig)
   {
     generateConfigFile(configName,shortList,TRUE);
-- 
cgit v0.12

