Blame doxygen-1.8.10-SOURCE_DATE_EPOCH.patch

Than Ngo 5e50ad
diff --git a/qtools/qcstring.cpp b/qtools/qcstring.cpp
Than Ngo 5e50ad
index 45ccef9..35b9bb8 100644
Than Ngo 5e50ad
--- a/qtools/qcstring.cpp
Than Ngo 5e50ad
+++ b/qtools/qcstring.cpp
Than Ngo 5e50ad
@@ -460,6 +460,12 @@ ulong QCString::toULong(bool *ok) const
Than Ngo 5e50ad
   return s.toULong(ok);
Than Ngo 5e50ad
 }
Than Ngo 5e50ad
 
Than Ngo 5e50ad
+uint64 QCString::toUInt64(bool *ok) const
Than Ngo 5e50ad
+{
Than Ngo 5e50ad
+  QString s(data());
Than Ngo 5e50ad
+  return s.toUInt64(ok);
Than Ngo 5e50ad
+}
Than Ngo 5e50ad
+
Than Ngo 5e50ad
 QCString &QCString::setNum(short n)
Than Ngo 5e50ad
 {
Than Ngo 5e50ad
   return setNum((long)n);
Than Ngo 5e50ad
diff --git a/qtools/qcstring.h b/qtools/qcstring.h
Than Ngo 5e50ad
index d8ce074..4f15b18 100644
Than Ngo 5e50ad
--- a/qtools/qcstring.h
Than Ngo 5e50ad
+++ b/qtools/qcstring.h
Than Ngo 5e50ad
@@ -288,6 +288,7 @@ public:
Than Ngo 5e50ad
     uint toUInt( bool *ok=0 ) const;
Than Ngo 5e50ad
     long toLong( bool *ok=0 ) const;
Than Ngo 5e50ad
     ulong toULong( bool *ok=0 )	const;
Than Ngo 5e50ad
+    uint64 toUInt64( bool *ok=0 ) const;
Than Ngo 5e50ad
     QCString &setNum(short n);
Than Ngo 5e50ad
     QCString &setNum(ushort n);
Than Ngo 5e50ad
     QCString &setNum(int n);
Than Ngo 5e50ad
diff --git a/qtools/qstring.cpp b/qtools/qstring.cpp
Than Ngo 5e50ad
index f51c0d4..458fd53 100644
Than Ngo 5e50ad
--- a/qtools/qstring.cpp
Than Ngo 5e50ad
+++ b/qtools/qstring.cpp
Than Ngo 5e50ad
@@ -13935,6 +13935,60 @@ bye:
Than Ngo 5e50ad
 }
Than Ngo 5e50ad
 
Than Ngo 5e50ad
 /*!
Than Ngo 5e50ad
+  Returns the string converted to an unsigned long
Than Ngo 5e50ad
+  value.
Than Ngo 5e50ad
+
Than Ngo 5e50ad
+  If \a ok is non-null, \a *ok is set to TRUE if there are no
Than Ngo 5e50ad
+  conceivable errors, and FALSE if the string is not a number at all,
Than Ngo 5e50ad
+  or if it has trailing garbage.
Than Ngo 5e50ad
+*/
Than Ngo 5e50ad
+
Than Ngo 5e50ad
+uint64 QString::toUInt64( bool *ok, int base ) const
Than Ngo 5e50ad
+{
Than Ngo 5e50ad
+    const QChar *p = unicode();
Than Ngo 5e50ad
+    uint64 val=0;
Than Ngo 5e50ad
+    int l = length();
Than Ngo 5e50ad
+    const uint64 max_mult = 1844674407370955161ULL;  // ULLONG_MAX/10, rounded down
Than Ngo 5e50ad
+    bool is_ok = FALSE;
Than Ngo 5e50ad
+    if ( !p )
Than Ngo 5e50ad
+	goto bye;
Than Ngo 5e50ad
+    while ( l && p->isSpace() )			// skip leading space
Than Ngo 5e50ad
+	l--,p++;
Than Ngo 5e50ad
+    if ( *p == '+' )
Than Ngo 5e50ad
+	l--,p++;
Than Ngo 5e50ad
+
Than Ngo 5e50ad
+    // NOTE: toULong() code is similar
Than Ngo 5e50ad
+    if ( !l || !ok_in_base(*p,base) )
Than Ngo 5e50ad
+	goto bye;
Than Ngo 5e50ad
+    while ( l && ok_in_base(*p,base) ) {
Than Ngo 5e50ad
+	l--;
Than Ngo 5e50ad
+	uint dv;
Than Ngo 5e50ad
+	if ( p->isDigit() ) {
Than Ngo 5e50ad
+	    dv = p->digitValue();
Than Ngo 5e50ad
+	} else {
Than Ngo 5e50ad
+	    if ( *p >= 'a' && *p <= 'z' )
Than Ngo 5e50ad
+		dv = *p - 'a' + 10;
Than Ngo 5e50ad
+	    else
Than Ngo 5e50ad
+		dv = *p - 'A' + 10;
Than Ngo 5e50ad
+	}
Than Ngo 5e50ad
+	if ( val > max_mult || (val == max_mult && dv > (ULLONG_MAX%base)) )
Than Ngo 5e50ad
+	    goto bye;
Than Ngo 5e50ad
+	val = base*val + dv;
Than Ngo 5e50ad
+	p++;
Than Ngo 5e50ad
+    }
Than Ngo 5e50ad
+
Than Ngo 5e50ad
+    while ( l && p->isSpace() )			// skip trailing space
Than Ngo 5e50ad
+	l--,p++;
Than Ngo 5e50ad
+    if ( !l )
Than Ngo 5e50ad
+	is_ok = TRUE;
Than Ngo 5e50ad
+bye:
Than Ngo 5e50ad
+    if ( ok )
Than Ngo 5e50ad
+	*ok = is_ok;
Than Ngo 5e50ad
+    return is_ok ? val : 0;
Than Ngo 5e50ad
+}
Than Ngo 5e50ad
+
Than Ngo 5e50ad
+
Than Ngo 5e50ad
+/*!
Than Ngo 5e50ad
   Returns the string converted to a short value.
Than Ngo 5e50ad
 
Than Ngo 5e50ad
   If \a ok is non-null, \a *ok is set to TRUE if there are no
Than Ngo 5e50ad
diff --git a/qtools/qstring.h b/qtools/qstring.h
Than Ngo 5e50ad
index a64fabf..df3873d 100644
Than Ngo 5e50ad
--- a/qtools/qstring.h
Than Ngo 5e50ad
+++ b/qtools/qstring.h
Than Ngo 5e50ad
@@ -463,6 +463,7 @@ public:
Than Ngo 5e50ad
     uint	toUInt( bool *ok=0, int base=10 )	const;
Than Ngo 5e50ad
     long	toLong( bool *ok=0, int base=10 )	const;
Than Ngo 5e50ad
     ulong	toULong( bool *ok=0, int base=10 )	const;
Than Ngo 5e50ad
+    uint64	toUInt64( bool *ok=0, int base=10 )	const;
Than Ngo 5e50ad
     float	toFloat( bool *ok=0 )	const;
Than Ngo 5e50ad
     double	toDouble( bool *ok=0 )	const;
Than Ngo 5e50ad
 
Than Ngo 5e50ad
diff --git a/src/util.cpp b/src/util.cpp
Than Ngo 5e50ad
index d367c40..db6a19c 100644
Than Ngo 5e50ad
--- a/src/util.cpp
Than Ngo 5e50ad
+++ b/src/util.cpp
Than Ngo 5e50ad
@@ -18,6 +18,7 @@
Than Ngo 5e50ad
 #include <ctype.h>
Than Ngo 5e50ad
 #include <errno.h>
Than Ngo 5e50ad
 #include <math.h>
Than Ngo 5e50ad
+#include <limits.h>
Than Ngo 5e50ad
 
Than Ngo 5e50ad
 #include "md5.h"
Than Ngo 5e50ad
 
Than Ngo 5e50ad
@@ -2472,6 +2473,35 @@ QCString fileToString(const char *name,bool filter,bool isSourceCode)
Than Ngo 5e50ad
 QCString dateToString(bool includeTime)
Than Ngo 5e50ad
 {
Than Ngo 5e50ad
   QDateTime current = QDateTime::currentDateTime();
Than Ngo 5e50ad
+  QCString sourceDateEpoch = portable_getenv("SOURCE_DATE_EPOCH");
Than Ngo 5e50ad
+  if (!sourceDateEpoch.isEmpty())
Than Ngo 5e50ad
+  {
Than Ngo 5e50ad
+    bool ok;
Than Ngo 5e50ad
+    uint64 epoch = sourceDateEpoch.toUInt64(&ok;;
Than Ngo 5e50ad
+    if (!ok)
Than Ngo 5e50ad
+    {
Than Ngo 5e50ad
+      static bool warnedOnce=FALSE;
Than Ngo 5e50ad
+      if (!warnedOnce)
Than Ngo 5e50ad
+      {
Than Ngo 5e50ad
+        warn_uncond("Environment variable SOURCE_DATE_EPOCH does not contain a valid number; value is '%s'\n",
Than Ngo 5e50ad
+            sourceDateEpoch.data());
Than Ngo 5e50ad
+        warnedOnce=TRUE;
Than Ngo 5e50ad
+      }
Than Ngo 5e50ad
+    }
Than Ngo 5e50ad
+    else if (epoch>UINT_MAX)
Than Ngo 5e50ad
+    {
Than Ngo 5e50ad
+      static bool warnedOnce=FALSE;
Than Ngo 5e50ad
+      if (!warnedOnce)
Than Ngo 5e50ad
+      {
Than Ngo 5e50ad
+        warn_uncond("Environment variable SOURCE_DATA_EPOCH must have a value smaller than or equal to %llu; actual value %llu\n",UINT_MAX,epoch);
Than Ngo 5e50ad
+        warnedOnce=TRUE;
Than Ngo 5e50ad
+      }
Than Ngo 5e50ad
+    }
Than Ngo 5e50ad
+    else // all ok, replace current time with epoch value
Than Ngo 5e50ad
+    {
Than Ngo 5e50ad
+      current.setTime_t((ulong)epoch); // TODO: add support for 64bit epoch value
Than Ngo 5e50ad
+    }
Than Ngo 5e50ad
+  }
Than Ngo 5e50ad
   return theTranslator->trDateTime(current.date().year(),
Than Ngo 5e50ad
                                    current.date().month(),
Than Ngo 5e50ad
                                    current.date().day(),