From f4451ff57d569ae64ca92c7733c2160cc1344d0c Mon Sep 17 00:00:00 2001 From: John Ralls Date: Mon, 4 May 2015 10:52:07 -0700 Subject: [PATCH 1/7] Remove gnc_gdate_range_check. Since GncDate and GncDateTime will have the same limits it's not necessary. --- src/libqof/qof/gnc-date.cpp | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp index 5db07db148..07d0310853 100644 --- a/src/libqof/qof/gnc-date.cpp +++ b/src/libqof/qof/gnc-date.cpp @@ -479,22 +479,7 @@ int gnc_date_get_last_mday (int month, int year) return last_day_of_month[0][month]; } -/* Safety function */ -static void -gnc_gdate_range_check (GDate *gd) -{ - int year; - if (!g_date_valid (gd)) - { - g_date_set_dmy (gd, 1, G_DATE_JANUARY, 1970); - return; - } - year = g_date_get_year (gd); - // Adjust the GDate to fit in the range of GDateTime. - year = (year < 1 ? 1 : year > 9999 ? 9999 : year); - g_date_set_year (gd, year); - return; -} + /* Return the set dateFormat. return QofDateFormat: enumeration indicating preferred format @@ -725,7 +710,6 @@ qof_print_gdate( char *buf, size_t len, const GDate *gd ) GDate date; g_date_clear (&date, 1); date = *gd; - gnc_gdate_range_check (&date); return qof_print_date_dmy_buff( buf, len, g_date_get_day(&date), g_date_get_month(&date), @@ -1411,7 +1395,6 @@ GDate* gnc_g_date_new_today () Timespec gdate_to_timespec (GDate d) { - gnc_gdate_range_check (&d); return gnc_dmy2timespec(g_date_get_day(&d), g_date_get_month(&d), g_date_get_year(&d)); From e1e4391b03b6a7c3ddd5f2a6d36d0497e0f17db6 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Mon, 4 May 2015 11:57:17 -0700 Subject: [PATCH 2/7] Remove unused gnc_timezone function. --- src/libqof/qof/gnc-date.cpp | 27 --------------------------- src/libqof/qof/gnc-date.h | 13 ------------- 2 files changed, 40 deletions(-) diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp index 07d0310853..dff25dee28 100644 --- a/src/libqof/qof/gnc-date.cpp +++ b/src/libqof/qof/gnc-date.cpp @@ -1316,33 +1316,6 @@ gnc_dmy2timespec_end (int day, int month, int year) /********************************************************************\ \********************************************************************/ - -long int -gnc_timezone (const struct tm *tm) -{ - g_return_val_if_fail (tm != NULL, 0); - -#ifdef HAVE_STRUCT_TM_GMTOFF - /* tm_gmtoff is seconds *east* of UTC and is - * already adjusted for daylight savings time. */ - return -(tm->tm_gmtoff); -#else - { - long tz_seconds; - /* timezone is seconds *west* of UTC and is - * not adjusted for daylight savings time. - * In Spring, we spring forward, wheee! */ -# if COMPILER(MSVC) - _get_timezone(&tz_seconds); -# else - tz_seconds = timezone; -# endif - return (long int)(tz_seconds - (tm->tm_isdst > 0 ? 3600 : 0)); - } -#endif -} - - void timespecFromTime64 ( Timespec *ts, time64 t ) { diff --git a/src/libqof/qof/gnc-date.h b/src/libqof/qof/gnc-date.h index 6c7537280d..a67639794d 100644 --- a/src/libqof/qof/gnc-date.h +++ b/src/libqof/qof/gnc-date.h @@ -385,19 +385,6 @@ gchar * gnc_timespec_to_iso8601_buff (Timespec ts, gchar * buff); */ void gnc_timespec2dmy (Timespec ts, gint *day, gint *month, gint *year); -/** The gnc_timezone function returns the number of seconds *west* - * of UTC represented by the tm argument, adjusted for daylight - * savings time. - * - * This function requires a tm argument returned by localtime or set - * by mktime. This is a strange function! It requires that localtime - * or mktime be called before use. Subsequent calls to localtime or - * mktime *may* invalidate the result! The actual contents of tm *may* - * be used for both timezone offset and daylight savings time, or only - * daylight savings time! Timezone stuff under unix is not - * standardized and is a big mess. - */ -glong gnc_timezone (const struct tm *tm); // @} /* ------------------------------------------------------------------------ */ From 2b84dfae8d74371e300bfdcd0fab5f2633dc732d Mon Sep 17 00:00:00 2001 From: John Ralls Date: Mon, 4 May 2015 14:57:02 -0700 Subject: [PATCH 3/7] Remove some noisy comments. That duplicate the Doxygen comments in the header. --- src/libqof/qof/gnc-date.cpp | 42 ------------------------------------- 1 file changed, 42 deletions(-) diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp index dff25dee28..3880adc8fd 100644 --- a/src/libqof/qof/gnc-date.cpp +++ b/src/libqof/qof/gnc-date.cpp @@ -479,29 +479,11 @@ int gnc_date_get_last_mday (int month, int year) return last_day_of_month[0][month]; } - -/* Return the set dateFormat. - -return QofDateFormat: enumeration indicating preferred format - -Global: dateFormat -*/ QofDateFormat qof_date_format_get (void) { return dateFormat; } -/* set date format - -set date format to one of US, UK, CE, ISO OR UTC -checks to make sure it's a legal value - -param QofDateFormat: enumeration indicating preferred format - -return void - -Globals: dateFormat -*/ void qof_date_format_set(QofDateFormat df) { if (df >= DATE_FORMAT_FIRST && df <= DATE_FORMAT_LAST) @@ -590,15 +572,6 @@ const gchar *qof_date_format_get_string(QofDateFormat df) return GNC_D_FMT; } -/* get the date format string for the current format - -get the date format string for the current format - -param df Required date format. -return string - -Globals: dateFormat -*/ const gchar *qof_date_text_format_get_string(QofDateFormat df) { switch (df) @@ -619,21 +592,6 @@ const gchar *qof_date_text_format_get_string(QofDateFormat df) return GNC_D_FMT; } -/* Convert day, month and year values to a date string - - Convert a date as day / month / year integers into a localized string - representation - -param buff - pointer to previously allocated character array; its size - must be at lease MAX_DATE_LENTH bytes. -param day - value to be set with the day of the month as 1 ... 31 -param month - value to be set with the month of the year as 1 ... 12 -param year - value to be set with the year (4-digit) - -return length of string created in buff. - -Globals: global dateFormat value -*/ size_t qof_print_date_dmy_buff (char * buff, size_t len, int day, int month, int year) { From 269bb510fbd322cf8be2775f94f8c0f1f8c83495 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Mon, 4 May 2015 15:03:54 -0700 Subject: [PATCH 4/7] Implement GncDate::format() Analog of GncDateTime::format(). --- src/libqof/qof/gnc-datetime.cpp | 22 ++++++++++++++++++++++ src/libqof/qof/gnc-datetime.hpp | 22 ++++++++++++++++------ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/libqof/qof/gnc-datetime.cpp b/src/libqof/qof/gnc-datetime.cpp index 7f8a6d4f03..db8215a9ae 100644 --- a/src/libqof/qof/gnc-datetime.cpp +++ b/src/libqof/qof/gnc-datetime.cpp @@ -65,6 +65,7 @@ public: void today() { m_greg = boost::gregorian::day_clock::local_day(); } ymd year_month_day() const; + std::string format(const char* format) const; private: Date m_greg; }; @@ -76,6 +77,18 @@ GncDateImpl::year_month_day() const return {boost_ymd.year, boost_ymd.month.as_number(), boost_ymd.day}; } +std::string +GncDateImpl::format(const char* format) const +{ + using Facet = boost::gregorian::date_facet; + std::stringstream ss; + //The stream destructor frees the facet, so it must be heap-allocated. + auto output_facet(new Facet(format)); + ss.imbue(std::locale(std::locale(), output_facet)); + ss << m_greg; + return ss.str(); +} + /** Private implementation of GncDateTime. See the documentation for that class. */ static LDT @@ -211,6 +224,7 @@ GncDateTimeImpl::format(const char* format) const } /* =================== Presentation-class Implementations ====================*/ +/* GncDate */ GncDate::GncDate() : m_impl{new GncDateImpl} {} GncDate::GncDate(int year, int month, int day) : m_impl(new GncDateImpl(year, month, day)) {} @@ -228,12 +242,20 @@ GncDate::today() m_impl->today(); } +std::string +GncDate::format(const char* format) +{ + return m_impl->format(format); +} + ymd GncDate::year_month_day() const { return m_impl->year_month_day(); } +/* GncDateTime */ + GncDateTime::GncDateTime() : m_impl(new GncDateTimeImpl) {} GncDateTime::GncDateTime(const time64 time) : m_impl(new GncDateTimeImpl(time)) {} diff --git a/src/libqof/qof/gnc-datetime.hpp b/src/libqof/qof/gnc-datetime.hpp index 04d48b5f34..e24796daae 100644 --- a/src/libqof/qof/gnc-datetime.hpp +++ b/src/libqof/qof/gnc-datetime.hpp @@ -69,6 +69,15 @@ public:/** Construct a GncDate representing the current day. @return ymd struct */ ymd year_month_day() const; +/** Format the GncDate into a std::string + * @param format: A cstr describing the way the date and time are + * presented. Code letters preceded with % stand in for arguments; + * most are the same as described in strftime(3), but there are a few + * differences. Consult the boost::date_time documentation. + * @return a std::string containing a representation of the date + * according to the format. + */ + std::string format(const char* format); /** Test that the Date has an implementation. */ bool isnull (void) { return m_impl == nullptr; } @@ -83,7 +92,7 @@ private: * between 1400 and 9999 CE. * * Be careful when using times: A particular time is represented - * differently depending on the timezone, which can shif the displayed + * differently depending on the timezone, which can shift the displayed * date. Accounting is generally not sensitive to the time of day, but * is sensitive to the recorded day. Since GncDates are not timezone * dependent they should be preferred for accounting entries. @@ -110,7 +119,7 @@ public: * @exception std::invalid_argument if the year is outside the constraints. */ GncDateTime(const struct tm tm); -/** Construct a GncDateTime +/** Construct a GncDateTime * @param str: A string representing the date and time in some * recognizable format. Note that if a timezone is not specified the * default is UTC, not the local one. @@ -142,11 +151,12 @@ public: /** Test if the GncDateTime has a member pointer. Testing only. */ bool isnull (void) { return m_impl == nullptr; } /** Format the GncDateTime into a std::string - + * @param format: A cstr describing the way the date and time are + * presented. Code letters preceded with % stand in for arguments; + * most are the same as described in strftime(3), but there are a few + * differences. Consult the boost::date_time documentation. * @return a std::string containing a representation of the date - * according to the format. Consult the boost::date_time - * documentation for format characters; while they mostly compy with - * POSIX there are a few differences. + * according to the format. */ std::string format(const char* format) const; From ccbfeb3799ea0b52b9f1749e3fdeaf955d2a081e Mon Sep 17 00:00:00 2001 From: John Ralls Date: Mon, 4 May 2015 15:04:31 -0700 Subject: [PATCH 5/7] Reimplement qof_date print functions with GncDate::format() --- src/libqof/qof/gnc-date.cpp | 80 +++++++++---------------------------- 1 file changed, 18 insertions(+), 62 deletions(-) diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp index 3880adc8fd..90b6c9f7fd 100644 --- a/src/libqof/qof/gnc-date.cpp +++ b/src/libqof/qof/gnc-date.cpp @@ -556,11 +556,11 @@ const gchar *qof_date_format_get_string(QofDateFormat df) switch (df) { case QOF_DATE_FORMAT_US: - return "%m/%d/%y"; + return "%m/%d/%Y"; case QOF_DATE_FORMAT_UK: - return "%d/%m/%y"; + return "%d/%m/%Y"; case QOF_DATE_FORMAT_CE: - return "%d.%m.%y"; + return "%d.%m.%Y"; case QOF_DATE_FORMAT_UTC: return "%Y-%m-%dT%H:%M:%SZ"; case QOF_DATE_FORMAT_ISO: @@ -577,10 +577,10 @@ const gchar *qof_date_text_format_get_string(QofDateFormat df) switch (df) { case QOF_DATE_FORMAT_US: - return "%b %d, %y"; + return "%b %d, %Y"; case QOF_DATE_FORMAT_UK: case QOF_DATE_FORMAT_CE: - return "%d %b, %y"; + return "%d %b %Y"; case QOF_DATE_FORMAT_UTC: return "%Y-%m-%dT%H:%M:%SZ"; case QOF_DATE_FORMAT_ISO: @@ -595,71 +595,27 @@ const gchar *qof_date_text_format_get_string(QofDateFormat df) size_t qof_print_date_dmy_buff (char * buff, size_t len, int day, int month, int year) { - int flen; if (!buff) return 0; - /* Note that when printing year, we use %-4d in format string; - * this causes a one, two or three-digit year to be left-adjusted - * when printed (i.e. padded with blanks on the right). This is - * important while the user is editing the year, since erasing a - * digit can temporarily cause a three-digit year, and having the - * blank on the left is a real pain for the user. So pad on the - * right. - */ - switch (dateFormat) - { - case QOF_DATE_FORMAT_UK: - flen = g_snprintf (buff, len, "%02d/%02d/%-4d", day, month, year); - break; - case QOF_DATE_FORMAT_CE: - flen = g_snprintf (buff, len, "%02d.%02d.%-4d", day, month, year); - break; - case QOF_DATE_FORMAT_LOCALE: - { - struct tm tm_str; - time64 t; - - tm_str.tm_mday = day; - tm_str.tm_mon = month - 1; /* tm_mon = 0 through 11 */ - tm_str.tm_year = year - 1900; /* this is what the standard - says, it's not a Y2K thing */ - - gnc_tm_set_day_start (&tm_str); - t = gnc_mktime (&tm_str); - gnc_localtime_r (&t, &tm_str); - flen = qof_strftime (buff, len, GNC_D_FMT, &tm_str); - if (flen != 0) - break; - } - /* FALL THROUGH */ - case QOF_DATE_FORMAT_ISO: - case QOF_DATE_FORMAT_UTC: - flen = g_snprintf (buff, len, "%04d-%02d-%02d", year, month, day); - break; - case QOF_DATE_FORMAT_US: - default: - flen = g_snprintf (buff, len, "%02d/%02d/%-4d", month, day, year); - break; - } - - return flen; + GncDate date(year, month, day); + std::string str = date.format(qof_date_format_get_string(dateFormat)); + strncpy(buff, str.c_str(), len); + if (str.length() >= len) + buff[len - 1] = '\0'; + return strlen(buff); } size_t qof_print_date_buff (char * buff, size_t len, time64 t) { - struct tm theTime; - time64 bt = t; - size_t actual; - if (!buff) return 0 ; - if (!gnc_localtime_r(&bt, &theTime)) - return 0; + if (!buff) return 0; - actual = qof_print_date_dmy_buff (buff, len, - theTime.tm_mday, - theTime.tm_mon + 1, - theTime.tm_year + 1900); - return actual; + GncDateTime gncdt(t); + std::string str = gncdt.format(qof_date_format_get_string(dateFormat)); + strncpy(buff, str.c_str(), len); + if (str.length() >= len) + buff[len - 1] = '\0'; + return strlen(buff); } size_t From 725622f61326030ae0695a97e1d85d7abd005731 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Thu, 30 Apr 2015 13:21:29 -0700 Subject: [PATCH 6/7] Ensure we compile C for at least C99. --- configure.ac | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure.ac b/configure.ac index a98d21071c..493e94af2c 100644 --- a/configure.ac +++ b/configure.ac @@ -71,6 +71,8 @@ AC_GNU_SOURCE AC_PROG_INTLTOOL # Ensure the compiler supports C++ 11: AX_CXX_COMPILE_STDCXX_11(ext) +# We require C99 for the C parts: +AC_PROG_CC_C99 AC_SUBST(GNUCASH_MAJOR_VERSION) From 90f0d9952c5bcd96b63995d580f92ff1fb89c284 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Mon, 4 May 2015 15:00:48 -0700 Subject: [PATCH 7/7] Set gmock_root to gmock_src_path if the latter is detected. Otherwise configure thinks gmock isn't installed. --- configure.ac | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 493e94af2c..f9ffa16b40 100644 --- a/configure.ac +++ b/configure.ac @@ -879,8 +879,9 @@ if test x$enable_google_test = xyes; then elif test "x$ac_cv_file__usr_src_gmock_gmock_all_cc" = xyes; then ac_cv_gmock_src_path="/usr/src/gmock" else - ac_cv_gmock_root="" + ac_cv_gmock_src_path="" fi + ac_cv_gmock_root="$ac_cv_gmock_src_path" else ac_cv_gmock_root="" fi