gnucash master: Multiple changes pushed
Geert Janssens
gjanssens at code.gnucash.org
Wed May 3 06:21:07 EDT 2017
Updated via https://github.com/Gnucash/gnucash/commit/e0af43d4 (commit)
via https://github.com/Gnucash/gnucash/commit/3603ec1a (commit)
via https://github.com/Gnucash/gnucash/commit/9af57849 (commit)
via https://github.com/Gnucash/gnucash/commit/7df29b57 (commit)
via https://github.com/Gnucash/gnucash/commit/50700373 (commit)
from https://github.com/Gnucash/gnucash/commit/1a3595cb (commit)
commit e0af43d413bb6d41f36e91f52e2c7db031db8079
Author: Geert Janssens <geert at kobaltwit.be>
Date: Wed May 3 12:19:04 2017 +0200
Properly handle import of reconcile state.
Gnucash exports this state localized it should expect a localized state on import.
diff --git a/src/import-export/csv-imp/gnc-trans-props.cpp b/src/import-export/csv-imp/gnc-trans-props.cpp
index 363a629..de0d886 100644
--- a/src/import-export/csv-imp/gnc-trans-props.cpp
+++ b/src/import-export/csv-imp/gnc-trans-props.cpp
@@ -136,16 +136,16 @@ GncNumeric parse_amount (const std::string &str, int currency_format)
static char parse_reconciled (const std::string& reconcile)
{
- if (g_strcmp0 (reconcile.c_str(), _("n")) == 0) // Not reconciled
+ if (g_strcmp0 (reconcile.c_str(), gnc_get_reconcile_str(NREC)) == 0) // Not reconciled
return NREC;
- else if (g_strcmp0 (reconcile.c_str(), _("c")) == 0) // Cleared
+ else if (g_strcmp0 (reconcile.c_str(), gnc_get_reconcile_str(CREC)) == 0) // Cleared
return CREC;
- else if (g_strcmp0 (reconcile.c_str(), _("y")) == 0) // Reconciled
+ else if (g_strcmp0 (reconcile.c_str(), gnc_get_reconcile_str(YREC)) == 0) // Reconciled
return YREC;
- else if (g_strcmp0 (reconcile.c_str(), _("f")) == 0) // Frozen
+ else if (g_strcmp0 (reconcile.c_str(), gnc_get_reconcile_str(FREC)) == 0) // Frozen
return FREC;
- else if (g_strcmp0 (reconcile.c_str(), _("v")) == 0) // Voided will be handled at the transaction level
- return NREC; // so return not reconciled here
+ else if (g_strcmp0 (reconcile.c_str(), gnc_get_reconcile_str(VREC)) == 0) // Voided will be handled at the transaction level
+ return NREC; // so return not reconciled here
else
throw std::invalid_argument (_("Value can't be parsed into a valid reconcile state."));
}
commit 3603ec1aa857b85ed56b24847300a03ce20a1f4e
Author: Geert Janssens <geert at kobaltwit.be>
Date: Wed May 3 09:44:36 2017 +0200
Document supported date formats in the saved csv settings
diff --git a/src/import-export/csv-imp/gnc-csv-trans-settings.cpp b/src/import-export/csv-imp/gnc-csv-trans-settings.cpp
index f3456f0..6278d48 100644
--- a/src/import-export/csv-imp/gnc-csv-trans-settings.cpp
+++ b/src/import-export/csv-imp/gnc-csv-trans-settings.cpp
@@ -27,6 +27,7 @@
*/
#include "gnc-csv-trans-settings.hpp"
+#include <sstream>
extern "C"
{
@@ -337,6 +338,15 @@ CsvTransSettings::save (void)
g_key_file_set_string (keyfile, group.c_str(), CSV_SEP, m_separators.c_str());
g_key_file_set_integer (keyfile, group.c_str(), CSV_DATE, m_date_format);
+ std::ostringstream cmt_ss;
+ cmt_ss << "Supported date formats: ";
+ int fmt_num = 0;
+ std::for_each (GncDate::c_formats.cbegin(), GncDate::c_formats.cend(),
+ [&cmt_ss, &fmt_num](const GncDateFormat& fmt)
+ { cmt_ss << fmt_num++ << ": '" << fmt.m_fmt << "', "; });
+ auto cmt = cmt_ss.str().substr(0, static_cast<long>(cmt_ss.tellp()) - 2);
+ g_key_file_set_comment (keyfile, group.c_str(), CSV_DATE,
+ cmt.c_str(), nullptr);
g_key_file_set_integer (keyfile, group.c_str(), CSV_CURRENCY, m_currency_format);
g_key_file_set_string (keyfile, group.c_str(), CSV_ENCODING, m_encoding.c_str());
commit 9af57849ba1bc6e954f6b5aae61ec85e4c09a0e2
Author: Geert Janssens <geert at kobaltwit.be>
Date: Mon May 1 20:19:49 2017 +0200
Use GncDate in csv importer
This removes all date specific functionality from the importer
diff --git a/src/import-export/csv-imp/assistant-csv-trans-import.cpp b/src/import-export/csv-imp/assistant-csv-trans-import.cpp
index 05219da..3cd6c60 100644
--- a/src/import-export/csv-imp/assistant-csv-trans-import.cpp
+++ b/src/import-export/csv-imp/assistant-csv-trans-import.cpp
@@ -521,10 +521,8 @@ CsvImpTransAssist::CsvImpTransAssist ()
/* Add in the date format combo box and hook it up to an event handler. */
date_format_combo = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
- for (int i = 0; i < num_date_formats; i++)
- {
- gtk_combo_box_text_append_text (date_format_combo, _(date_format_user[i]));
- }
+ for (auto& date_fmt : GncDate::c_formats)
+ gtk_combo_box_text_append_text (date_format_combo, _(date_fmt.m_fmt.c_str()));
gtk_combo_box_set_active (GTK_COMBO_BOX(date_format_combo), 0);
g_signal_connect (G_OBJECT(date_format_combo), "changed",
G_CALLBACK(csv_tximp_preview_date_fmt_sel_cb), this);
@@ -1560,7 +1558,7 @@ CsvImpTransAssist::preview_refresh ()
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(fixed_button),
(tx_imp->file_format() != GncImpFileFormat::CSV));
- // This section deals with the combo's and character encoding
+ // Set Date & Currency Format and Character encoding
gtk_combo_box_set_active (GTK_COMBO_BOX(date_format_combo),
tx_imp->date_format());
gtk_combo_box_set_active (GTK_COMBO_BOX(currency_format_combo),
diff --git a/src/import-export/csv-imp/gnc-trans-props.cpp b/src/import-export/csv-imp/gnc-trans-props.cpp
index c537d54..363a629 100644
--- a/src/import-export/csv-imp/gnc-trans-props.cpp
+++ b/src/import-export/csv-imp/gnc-trans-props.cpp
@@ -93,115 +93,6 @@ GncTransPropType sanitize_trans_prop (GncTransPropType prop, bool multi_split)
return GncTransPropType::NONE;
}
-/* Regular expressions used to parse dates per date format */
-const char* date_regex[] = {
- "(?:" // either y-m-d
- "(?<YEAR>[0-9]+)[-/.' ]+"
- "(?<MONTH>[0-9]+)[-/.' ]+"
- "(?<DAY>[0-9]+)"
- "|" // or CCYYMMDD
- "(?<YEAR>[0-9]{4})"
- "(?<MONTH>[0-9]{2})"
- "(?<DAY>[0-9]{2})"
- ")",
-
- "(?:" // either d-m-y
- "(?<DAY>[0-9]+)[-/.' ]+"
- "(?<MONTH>[0-9]+)[-/.' ]+"
- "(?<YEAR>[0-9]+)"
- "|" // or DDMMCCYY
- "(?<DAY>[0-9]{2})"
- "(?<MONTH>[0-9]{2})"
- "(?<YEAR>[0-9]{4})"
- ")",
-
- "(?:" // either m-d-y
- "(?<MONTH>[0-9]+)[-/.' ]+"
- "(?<DAY>[0-9]+)[-/.' ]+"
- "(?<YEAR>[0-9]+)"
- "|" // or MMDDCCYY
- "(?<MONTH>[0-9]{2})"
- "(?<DAY>[0-9]{2})"
- "(?<YEAR>[0-9]{4})"
- ")",
-
- "(?:" // either d-m(-y)
- "(?<DAY>[0-9]+)[-/.' ]+"
- "(?<MONTH>[0-9]+)(?:[-/.' ]+"
- "(?<YEAR>[0-9]+))?"
- "|" // or DDMM(CCYY)
- "(?<DAY>[0-9]{2})"
- "(?<MONTH>[0-9]{2})"
- "(?<YEAR>[0-9]+)?"
- ")",
-
- "(?:" // either m-d(-y)
- "(?<MONTH>[0-9]+)[-/.' ]+"
- "(?<DAY>[0-9]+)(?:[-/.' ]+"
- "(?<YEAR>[0-9]+))?"
- "|" // or MMDD(CCYY)
- "(?<MONTH>[0-9]{2})"
- "(?<DAY>[0-9]{2})"
- "(?<YEAR>[0-9]+)?"
- ")",
-};
-
-/** Parses a string into a date, given a format. This function
- * requires only knowing the order in which the year, month and day
- * appear. For example, 01-02-2003 will be parsed the same way as
- * 01/02/2003.
- * @param date_str The string containing a date being parsed
- * @param format An index specifying a format in date_format_user
- * @exception std::invalid_argument if the string can't be parsed into a date.
- * @return The parsed value of date_str on success, throws on failure
- */
-
-time64 parse_date (const std::string &date_str, int format)
-{
- boost::regex r(date_regex[format]);
- boost::smatch what;
- if(!boost::regex_search(date_str, what, r))
- throw std::invalid_argument (_("Value can't be parsed into a date using the selected date format.")); // regex didn't find a match
-
- // Attention: different behavior from 2.6.x series !
- // If date format without year was selected, the match
- // should NOT have found a year.
- if ((format >= 3) && (what.length("YEAR") != 0))
- throw std::invalid_argument (_("Value appears to contain a year while the selected format forbids this."));
-
- auto day = std::stoi (what.str("DAY"));
- auto month = std::stoi (what.str("MONTH"));
-
- int year;
- if (format < 3)
- {
- /* The input dates have a year, so use that one */
- year = std::stoi (what.str("YEAR"));
-
- /* Handle two-digit years. */
- if (year < 100)
- {
- /* We allow two-digit years in the range 1969 - 2068. */
- if (year < 69)
- year += 2000;
- else
- year += 1900;
- }
- }
- else
- {
- /* The input dates don't have a year, so work with today's year.
- */
- gnc_timespec2dmy(timespec_now(), nullptr, nullptr, &year);
- }
-
- auto ts = gnc_dmy2timespec_neutral(day, month, year);
- if (ts.tv_sec == INT64_MAX)
- throw std::invalid_argument (_("Value can't be parsed into a date using the selected date format."));
-
- return ts.tv_sec;
-}
-
/** Convert str into a GncRational using the user-specified (import) currency format.
* @param str The string to be parsed
@@ -317,7 +208,7 @@ void GncPreTrans::set (GncTransPropType prop_type, const std::string& value)
case GncTransPropType::DATE:
m_date = boost::none;
- m_date = parse_date (value, m_date_format); // Throws if parsing fails
+ m_date = GncDate(value, GncDate::c_formats[m_date_format].m_fmt); // Throws if parsing fails
break;
case GncTransPropType::NUM:
@@ -417,7 +308,8 @@ Transaction* GncPreTrans::create_trans (QofBook* book, gnc_commodity* currency)
auto trans = xaccMallocTransaction (book);
xaccTransBeginEdit (trans);
xaccTransSetCurrency (trans, m_commodity ? *m_commodity : currency);
- xaccTransSetDatePostedSecsNormalized (trans, *m_date);
+ xaccTransSetDatePostedSecsNormalized (trans,
+ static_cast<time64>(GncDateTime(*m_date, DayPart::neutral)));
if (m_num)
xaccTransSetNum (trans, m_num->c_str());
@@ -558,13 +450,15 @@ void GncPreSplit::set (GncTransPropType prop_type, const std::string& value)
case GncTransPropType::REC_DATE:
m_rec_date = boost::none;
if (!value.empty())
- m_rec_date = parse_date (value, m_date_format); // Throws if parsing fails
+ m_rec_date = GncDate (value,
+ GncDate::c_formats[m_date_format].m_fmt); // Throws if parsing fails
break;
case GncTransPropType::TREC_DATE:
m_trec_date = boost::none;
if (!value.empty())
- m_trec_date = parse_date (value, m_date_format); // Throws if parsing fails
+ m_trec_date = GncDate (value,
+ GncDate::c_formats[m_date_format].m_fmt); // Throws if parsing fails
break;
default:
@@ -641,7 +535,7 @@ static void trans_add_split (Transaction* trans, Account* account, GncNumeric am
const boost::optional<std::string>& action,
const boost::optional<std::string>& memo,
const boost::optional<char>& rec_state,
- const boost::optional<time64> rec_date,
+ const boost::optional<GncDate>& rec_date,
const boost::optional<GncNumeric> price)
{
QofBook* book = xaccTransGetBook (trans);
@@ -691,7 +585,8 @@ static void trans_add_split (Transaction* trans, Account* account, GncNumeric am
if (rec_state && *rec_state != 'n')
xaccSplitSetReconcile (split, *rec_state);
if (rec_state && *rec_state == YREC && rec_date)
- xaccSplitSetDateReconciledSecs (split, *rec_date);
+ xaccSplitSetDateReconciledSecs (split,
+ static_cast<time64>(GncDateTime(*rec_date, DayPart::neutral)));
}
diff --git a/src/import-export/csv-imp/gnc-trans-props.hpp b/src/import-export/csv-imp/gnc-trans-props.hpp
index 8188206..47c23ba 100644
--- a/src/import-export/csv-imp/gnc-trans-props.hpp
+++ b/src/import-export/csv-imp/gnc-trans-props.hpp
@@ -41,6 +41,7 @@ extern "C" {
#include <map>
#include <memory>
#include <boost/optional.hpp>
+#include <gnc-datetime.hpp>
#include <gnc-numeric.hpp>
/** Enumeration for column types. These are the different types of
@@ -103,7 +104,6 @@ private:
GncTransPropType sanitize_trans_prop (GncTransPropType prop, bool multi_split);
-time64 parse_date (const std::string &date_str, int format);
gnc_commodity* parse_commodity (const std::string& comm_str);
GncNumeric parse_amount (const std::string &str, int currency_format);
@@ -139,7 +139,7 @@ public:
private:
int m_date_format;
boost::optional<std::string> m_differ;
- boost::optional<time64> m_date;
+ boost::optional<GncDate> m_date;
boost::optional<std::string> m_num;
boost::optional<std::string> m_desc;
boost::optional<std::string> m_notes;
@@ -176,12 +176,12 @@ private:
boost::optional<GncNumeric> m_price;
boost::optional<std::string> m_memo;
boost::optional<char> m_rec_state;
- boost::optional<time64> m_rec_date;
+ boost::optional<GncDate> m_rec_date;
boost::optional<std::string> m_taction;
boost::optional<Account*> m_taccount;
boost::optional<std::string> m_tmemo;
boost::optional<char> m_trec_state;
- boost::optional<time64> m_trec_date;
+ boost::optional<GncDate> m_trec_date;
bool created = false;
std::map<GncTransPropType, std::string> m_errors;
diff --git a/src/import-export/csv-imp/gnc-tx-import.cpp b/src/import-export/csv-imp/gnc-tx-import.cpp
index 7dbaff8..daa85b4 100644
--- a/src/import-export/csv-imp/gnc-tx-import.cpp
+++ b/src/import-export/csv-imp/gnc-tx-import.cpp
@@ -43,14 +43,6 @@ extern "C" {
G_GNUC_UNUSED static QofLogModule log_module = GNC_MOD_IMPORT;
-const int num_date_formats = 5;
-const gchar* date_format_user[] = {N_("y-m-d"),
- N_("d-m-y"),
- N_("m-d-y"),
- N_("d-m"),
- N_("m-d")
- };
-
const int num_currency_formats = 3;
const gchar* currency_format_user[] = {N_("Locale"),
N_("Period: 123,456.78"),
@@ -742,6 +734,8 @@ void GncTxImport::update_pre_trans_props (uint32_t row, uint32_t col, GncTransPr
if ((prop_type == GncTransPropType::NONE) || (prop_type > GncTransPropType::TRANS_PROPS))
return; /* Only deal with transaction related properties. */
+ /* Deliberately make a copy of the GncPreTrans. It may be the original one was shared
+ * with a previous line and should no longer be after the transprop is changed. */
auto trans_props = std::make_shared<GncPreTrans> (*(std::get<PL_PRETRANS>(m_parsed_lines[row])).get());
auto value = std::string();
diff --git a/src/import-export/csv-imp/gnc-tx-import.hpp b/src/import-export/csv-imp/gnc-tx-import.hpp
index fbded6e..4e7482c 100644
--- a/src/import-export/csv-imp/gnc-tx-import.hpp
+++ b/src/import-export/csv-imp/gnc-tx-import.hpp
@@ -64,10 +64,6 @@ struct DraftTransaction
extern const int num_currency_formats;
extern const gchar* currency_format_user[];
-/* A set of date formats that the user sees. */
-extern const int num_date_formats;
-extern const gchar* date_format_user[];
-
/** An enum describing the columns found in a parse_line_t. Currently these are:
* - a tokenized line of input
* - an optional error string
diff --git a/src/import-export/csv-imp/test/test-tx-import.cpp b/src/import-export/csv-imp/test/test-tx-import.cpp
index 1df18a4..76a4362 100644
--- a/src/import-export/csv-imp/test/test-tx-import.cpp
+++ b/src/import-export/csv-imp/test/test-tx-import.cpp
@@ -62,150 +62,3 @@ public:
protected:
std::unique_ptr<GncTxImport> tx_importer;
};
-
-
-/* parse_date
-time64 parse_date (const char* date_str, int format)// C: 14 in 7 SCM: 9 in 2 Local: 1:0:0
-*/
-TEST(GncTxImportTest, parse_date)
-{
- time64 rawtime = gnc_time (nullptr);
- struct tm *tm = gnc_gmtime (&rawtime);
- int curr_year = tm->tm_year;
-
-
- /* Note: tm_year = year - 1900 and tm_mon = 0-11
- * I'm writing the expected values as subtractions for easier
- * comparison with the date string under test
- */
- parse_date_data test_dates[] =
- {
- // supported combinations -/.'
- { 0, "2013-08-01", 2013 - 1900, 8 - 1, 1},
- { 0, "2013-8-01", 2013 - 1900, 8 - 1, 1},
- { 0, "2013-08-1", 2013 - 1900, 8 - 1, 1},
- { 0, "2013-8-1", 2013 - 1900, 8 - 1, 1},
- { 0, "13-08-01", 2013 - 1900, 8 - 1, 1},
- { 0, "13-8-01", 2013 - 1900, 8 - 1, 1},
- { 0, "13-08-1", 2013 - 1900, 8 - 1, 1},
- { 0, "13-8-1", 2013 - 1900, 8 - 1, 1},
- { 0, "2009/11/04", 2009 - 1900, 11 - 1, 4},
- { 0, "1985.3.12", 1985 - 1900, 3 - 1, 12},
- { 0, "3'6'8", 2003 - 1900, 6 - 1, 8},
- { 0, "20130801", 2013 - 1900, 8 - 1, 1},
- { 1, "01-08-2013", 2013 - 1900, 8 - 1, 1},
- { 1, "01-8-2013", 2013 - 1900, 8 - 1, 1},
- { 1, "1-08-2013", 2013 - 1900, 8 - 1, 1},
- { 1, "1-8-2013", 2013 - 1900, 8 - 1, 1},
- { 1, "01-08-13", 2013 - 1900, 8 - 1, 1},
- { 1, "01-8-13", 2013 - 1900, 8 - 1, 1},
- { 1, "1-08-13", 2013 - 1900, 8 - 1, 1},
- { 1, "1-8-13", 2013 - 1900, 8 - 1, 1},
- { 1, "04/11/2009", 2009 - 1900, 11 - 1, 4},
- { 1, "12.3.1985", 1985 - 1900, 3 - 1, 12},
- { 1, "8'6'3", 2003 - 1900, 6 - 1, 8},
- { 1, "01082013", 2013 - 1900, 8 - 1, 1},
- { 2, "08-01-2013", 2013 - 1900, 8 - 1, 1},
- { 2, "8-01-2013", 2013 - 1900, 8 - 1, 1},
- { 2, "08-1-2013", 2013 - 1900, 8 - 1, 1},
- { 2, "8-1-2013", 2013 - 1900, 8 - 1, 1},
- { 2, "08-01-13", 2013 - 1900, 8 - 1, 1},
- { 2, "8-01-13", 2013 - 1900, 8 - 1, 1},
- { 2, "08-1-13", 2013 - 1900, 8 - 1, 1},
- { 2, "8-1-13", 2013 - 1900, 8 - 1, 1},
- { 2, "11/04/2009", 2009 - 1900, 11 - 1, 4},
- { 2, "3.12.1985", 1985 - 1900, 3 - 1, 12},
- { 2, "6'8'3", 2003 - 1900, 6 - 1, 8},
- { 2, "08012013", 2013 - 1900, 8 - 1, 1},
- { 3, "01-08", curr_year, 8 - 1, 1},
- { 3, "01-8", curr_year, 8 - 1, 1},
- { 3, "1-08", curr_year, 8 - 1, 1},
- { 3, "1-8", curr_year, 8 - 1, 1},
- { 3, "04/11", curr_year, 11 - 1, 4},
- { 3, "12.3", curr_year, 3 - 1, 12},
- { 3, "8'6", curr_year, 6 - 1, 8},
- { 3, "0108", curr_year, 8 - 1, 1},
- { 4, "08-01", curr_year, 8 - 1, 1},
- { 4, "8-01", curr_year, 8 - 1, 1},
- { 4, "08-1", curr_year, 8 - 1, 1},
- { 4, "8-1", curr_year, 8 - 1, 1},
- { 4, "11/04", curr_year, 11 - 1, 4},
- { 4, "3.12", curr_year, 3 - 1, 12},
- { 4, "6'8", curr_year, 6 - 1, 8},
- { 4, "0801", curr_year, 8 - 1, 1},
-
- // ambiguous date formats
- // current parser doesn't know how to disambiguate
- // and hence refuses to parse
- // can possibly improved with a smarter parser
- { 0, "130801", -1, -1, -1},
- { 1, "010813", -1, -1, -1},
- { 2, "080113", -1, -1, -1},
-
- // Combinations that don't make sense
- // but can still be entered by a user
- // Should ideally all result in refusal to parse...
- { 0, "08-01", -1, -1, -1},
- { 0, "0801", -1, -1, -1},
- { 1, "01-08", -1, -1, -1},
- { 1, "0108", -1, -1, -1},
- { 2, "08-01", -1, -1, -1},
- { 2, "0801", -1, -1, -1},
- { 3, "01-08-2013", -1, -1, -1},
- { 3, "01-08-13", -1, -1, -1},
- { 3, "08-08-08", -1, -1, -1},
- { 3, "01082013", -1, -1, -1},
- { 3, "010813", -1, -1, -1},
- { 3, "20130108", -1, -1, -1},
- { 4, "08-01-2013", -1, -1, -1},
- { 4, "08-01-13", -1, -1, -1},
- { 4, "2013-08-01", -1, -1, -1},
- { 4, "09-08-01", -1, -1, -1},
- { 4, "08012013", -1, -1, -1},
- { 4, "080113", -1, -1, -1},
- { 4, "20130801", -1, -1, -1},
-
- // Sentinel to mark the end of available tests
- { 0, NULL, 0, 0, 0},
-
- };
- int i = 0;
-
- gnc_tm_free(tm);
- while (test_dates[i].date_str)
- {
- gboolean success = TRUE;
- int got_year = 0, got_month = 0, got_day = 0;
-
- try
- {
- rawtime = parse_date (std::string(test_dates[i].date_str), test_dates[i].date_fmt);
- tm = gnc_gmtime (&rawtime);
- got_year = tm->tm_year;
- got_month = tm->tm_mon;
- got_day = tm->tm_mday;
- gnc_tm_free(tm);
- }
- catch (std::invalid_argument)
- {
- got_year = got_month = got_day = -1;
- }
-
- if ((got_year != test_dates[i].exp_year) ||
- (got_month != test_dates[i].exp_month) ||
- (got_day != test_dates[i].exp_day))
- {
- g_error ("Parse_date failed for date '%s' and format '%d'.\n"
- "Expected result: year %d, month %d, day %d\n"
- "Obtained result: year %d, month %d, day %d",
- test_dates[i].date_str,
- test_dates[i].date_fmt,
- test_dates[i].exp_year,
- test_dates[i].exp_month,
- test_dates[i].exp_day,
- got_year, got_month, got_day);
- }
-
- i++;
- }
-}
commit 7df29b572a2309ae0ee730285f91d2116b8ff426
Author: Geert Janssens <geert at kobaltwit.be>
Date: Tue May 2 23:09:23 2017 +0200
Add copy constructor and assignment operator to GncDate
diff --git a/src/libqof/qof/gnc-datetime.cpp b/src/libqof/qof/gnc-datetime.cpp
index 2a193ae..fcd55c5 100644
--- a/src/libqof/qof/gnc-datetime.cpp
+++ b/src/libqof/qof/gnc-datetime.cpp
@@ -509,10 +509,18 @@ GncDate::GncDate(const std::string str, const std::string fmt) :
m_impl(new GncDateImpl(str, fmt)) {}
GncDate::GncDate(std::unique_ptr<GncDateImpl> impl) :
m_impl(std::move(impl)) {}
+GncDate::GncDate(const GncDate& a) :
+m_impl(new GncDateImpl(*a.m_impl)) {}
GncDate::GncDate(GncDate&&) = default;
GncDate::~GncDate() = default;
GncDate&
+GncDate::operator=(const GncDate& a)
+{
+ m_impl.reset(new GncDateImpl(*a.m_impl));
+ return *this;
+}
+GncDate&
GncDate::operator=(GncDate&&) = default;
void
diff --git a/src/libqof/qof/gnc-datetime.hpp b/src/libqof/qof/gnc-datetime.hpp
index 2d879d6..104220d 100644
--- a/src/libqof/qof/gnc-datetime.hpp
+++ b/src/libqof/qof/gnc-datetime.hpp
@@ -244,9 +244,23 @@ class GncDate
* - fmt doesn't specify a year, yet a year was found in the string
*/
GncDate(const std::string str, const std::string fmt);
+ /** Construct a GncDate from a GncDateImpl.
+ */
GncDate(std::unique_ptr<GncDateImpl> impl);
+ /** Copy constructor.
+ */
+ GncDate(const GncDate&);
+ /** Move constructor.
+ */
GncDate(GncDate&&);
+ /** Default destructor.
+ */
~GncDate();
+ /** Copy assignment operator.
+ */
+ GncDate& operator=(const GncDate&);
+ /** Move assignment operator.
+ */
GncDate& operator=(GncDate&&);
/** Set the date object to the computer clock's current day. */
void today();
diff --git a/src/libqof/qof/test/gtest-gnc-datetime.cpp b/src/libqof/qof/test/gtest-gnc-datetime.cpp
index b914896..b334230 100644
--- a/src/libqof/qof/test/gtest-gnc-datetime.cpp
+++ b/src/libqof/qof/test/gtest-gnc-datetime.cpp
@@ -37,6 +37,22 @@ TEST(gnc_date_constructors, test_ymd_constructor)
EXPECT_FALSE(date.isnull());
}
+TEST(gnc_date_constructors, test_copy_constructor)
+{
+ GncDate a(2045, 11, 13);
+ GncDate b(a);
+ EXPECT_FALSE(a.isnull());
+ EXPECT_TRUE (a == b);
+}
+
+TEST(gnc_date_constructors, test_move_constructor)
+{
+ GncDate a(2045, 11, 13);
+ GncDate b(std::move(a));
+ EXPECT_TRUE(a.isnull());
+ EXPECT_TRUE (b.format("%Y-%m-%d") == "2045-11-13");
+}
+
typedef struct
{
const char* date_fmt;
@@ -46,9 +62,6 @@ typedef struct
int exp_day;
} parse_date_data;
-/* parse_date
- * time64 parse_date (const char* date_str, int format)// C: 14 in 7 SCM: 9 in 2 Local: 1:0:0
- */
TEST(gnc_date_constructors, test_str_format_constructor)
{
auto today = GncDate();
@@ -215,6 +228,23 @@ TEST(gnc_date_operators, test_more_less_than)
EXPECT_FALSE (c >= a);
}
+TEST(gnc_date_operators, test_copy_assignment)
+{
+ GncDate a(2017, 1, 6);
+ GncDate b;
+ b = a;
+ EXPECT_TRUE (a == b);
+}
+
+TEST(gnc_date_operators, test_move_assignment)
+{
+ GncDate a(2045, 11, 13);
+ GncDate b;
+ b = std::move(a);
+ EXPECT_TRUE(a.isnull());
+ EXPECT_TRUE (b.format("%Y-%m-%d") == "2045-11-13");
+}
+
TEST(gnc_datetime_constructors, test_default_constructor)
{
GncDateTime atime;
commit 507003731404820f32ce436b6930ea099aadeead
Author: Geert Janssens <geert at kobaltwit.be>
Date: Sat Apr 29 18:01:12 2017 +0200
Add comparison operators for GncDate
Note the operands are const GncDate& because the GncDate has no copy
constructor/assigment operator (any other definition would fail
when used with variables of type boost::optional<GncDate>)
diff --git a/src/libqof/qof/gnc-datetime.cpp b/src/libqof/qof/gnc-datetime.cpp
index 6191cf7..2a193ae 100644
--- a/src/libqof/qof/gnc-datetime.cpp
+++ b/src/libqof/qof/gnc-datetime.cpp
@@ -213,6 +213,12 @@ private:
Date m_greg;
friend GncDateTimeImpl::GncDateTimeImpl(const GncDateImpl&, DayPart);
+ friend bool operator<(const GncDateImpl&, const GncDateImpl&);
+ friend bool operator>(const GncDateImpl&, const GncDateImpl&);
+ friend bool operator==(const GncDateImpl&, const GncDateImpl&);
+ friend bool operator<=(const GncDateImpl&, const GncDateImpl&);
+ friend bool operator>=(const GncDateImpl&, const GncDateImpl&);
+ friend bool operator!=(const GncDateImpl&, const GncDateImpl&);
};
/* Member function definitions for GncDateTimeImpl.
@@ -427,6 +433,13 @@ GncDateImpl::format(const char* format) const
return ss.str();
}
+bool operator<(const GncDateImpl& a, const GncDateImpl& b) { return a.m_greg < b.m_greg; }
+bool operator>(const GncDateImpl& a, const GncDateImpl& b) { return a.m_greg > b.m_greg; }
+bool operator==(const GncDateImpl& a, const GncDateImpl& b) { return a.m_greg == b.m_greg; }
+bool operator<=(const GncDateImpl& a, const GncDateImpl& b) { return a.m_greg <= b.m_greg; }
+bool operator>=(const GncDateImpl& a, const GncDateImpl& b) { return a.m_greg >= b.m_greg; }
+bool operator!=(const GncDateImpl& a, const GncDateImpl& b) { return a.m_greg != b.m_greg; }
+
/* =================== Presentation-class Implementations ====================*/
/* GncDateTime */
@@ -519,3 +532,10 @@ GncDate::year_month_day() const
{
return m_impl->year_month_day();
}
+
+bool operator<(const GncDate& a, const GncDate& b) { return *(a.m_impl) < *(b.m_impl); }
+bool operator>(const GncDate& a, const GncDate& b) { return *(a.m_impl) > *(b.m_impl); }
+bool operator==(const GncDate& a, const GncDate& b) { return *(a.m_impl) == *(b.m_impl); }
+bool operator<=(const GncDate& a, const GncDate& b) { return *(a.m_impl) <= *(b.m_impl); }
+bool operator>=(const GncDate& a, const GncDate& b) { return *(a.m_impl) >= *(b.m_impl); }
+bool operator!=(const GncDate& a, const GncDate& b) { return *(a.m_impl) != *(b.m_impl); }
diff --git a/src/libqof/qof/gnc-datetime.hpp b/src/libqof/qof/gnc-datetime.hpp
index 59fb059..2d879d6 100644
--- a/src/libqof/qof/gnc-datetime.hpp
+++ b/src/libqof/qof/gnc-datetime.hpp
@@ -270,6 +270,23 @@ private:
std::unique_ptr<GncDateImpl> m_impl;
friend GncDateTime::GncDateTime(const GncDate&, DayPart);
+ friend bool operator<(const GncDate&, const GncDate&);
+ friend bool operator>(const GncDate&, const GncDate&);
+ friend bool operator==(const GncDate&, const GncDate&);
+ friend bool operator<=(const GncDate&, const GncDate&);
+ friend bool operator>=(const GncDate&, const GncDate&);
+ friend bool operator!=(const GncDate&, const GncDate&);
};
+/**@{
+ * Standard comparison operators working on GncDate objects.
+ */
+bool operator<(const GncDate& a, const GncDate& b);
+bool operator>(const GncDate& a, const GncDate& b);
+bool operator==(const GncDate& a, const GncDate& b);
+bool operator<=(const GncDate& a, const GncDate& b);
+bool operator>=(const GncDate& a, const GncDate& b);
+bool operator!=(const GncDate& a, const GncDate& b);
+/**@}*/
+
#endif // __GNC_DATETIME_HPP__
diff --git a/src/libqof/qof/test/gtest-gnc-datetime.cpp b/src/libqof/qof/test/gtest-gnc-datetime.cpp
index 0730bd3..b914896 100644
--- a/src/libqof/qof/test/gtest-gnc-datetime.cpp
+++ b/src/libqof/qof/test/gtest-gnc-datetime.cpp
@@ -183,6 +183,38 @@ TEST(gnc_date_constructors, test_str_format_constructor)
}
}
+TEST(gnc_date_operators, test_equality)
+{
+ GncDate a(2017, 1, 6);
+ GncDate b(2017, 1, 6);
+ GncDate c(2015, 6, 13);
+ EXPECT_TRUE (a == b);
+ EXPECT_FALSE (a == c);
+ EXPECT_TRUE (a != c);
+ EXPECT_FALSE (a != b);
+}
+
+TEST(gnc_date_operators, test_more_less_than)
+{
+ GncDate a(2017, 1, 6);
+ GncDate b(2017, 1, 6);
+ GncDate c(2015, 6, 13);
+ EXPECT_TRUE (a >= b);
+ EXPECT_TRUE (a <= b);
+ EXPECT_FALSE (a > b);
+ EXPECT_FALSE (a < b);
+
+ EXPECT_TRUE (a > c);
+ EXPECT_TRUE (a >= c);
+ EXPECT_FALSE (a < c);
+ EXPECT_FALSE (a <= c);
+
+ EXPECT_TRUE (c < a);
+ EXPECT_TRUE (c <= a);
+ EXPECT_FALSE (c > a);
+ EXPECT_FALSE (c >= a);
+}
+
TEST(gnc_datetime_constructors, test_default_constructor)
{
GncDateTime atime;
Summary of changes:
.../csv-imp/assistant-csv-trans-import.cpp | 8 +-
.../csv-imp/gnc-csv-trans-settings.cpp | 10 ++
src/import-export/csv-imp/gnc-trans-props.cpp | 137 +++----------------
src/import-export/csv-imp/gnc-trans-props.hpp | 8 +-
src/import-export/csv-imp/gnc-tx-import.cpp | 10 +-
src/import-export/csv-imp/gnc-tx-import.hpp | 4 -
src/import-export/csv-imp/test/test-tx-import.cpp | 147 ---------------------
src/libqof/qof/gnc-datetime.cpp | 28 ++++
src/libqof/qof/gnc-datetime.hpp | 31 +++++
src/libqof/qof/test/gtest-gnc-datetime.cpp | 68 +++++++++-
10 files changed, 159 insertions(+), 292 deletions(-)
More information about the gnucash-changes
mailing list