#
#
# add_file "unix/parse_time.cc"
# content [32590b4a1e4f2fa9efa0f48f077d47af8f13b431]
#
# add_file "win32/parse_time.cc"
# content [6970babb88f00ec9526d1e4e3585b55dea2e7da2]
#
# patch "Makefile.am"
# from [e956bf588ace925767e267296316a673e7d4761a]
# to [6e0664ed9ae020582bc88b50023b44a94a57f474]
#
# patch "cmd_ws_commit.cc"
# from [3ffbaa10b5e4c72028f08fcbf06950e5997b7c69]
# to [53480aabfe2e2c66ebedb7c350ec632552dc2614]
#
# patch "dates.cc"
# from [24dd854d8c1be66b65a57d813b756ddf13550848]
# to [2413fafb2058055cab18cc8f6787c893f471c214]
#
# patch "platform.hh"
# from [648608271dd6559ba89bc0bb816a3de306c3355f]
# to [04a90e564b175d1193c25c2e59e9028ddefcc85d]
#
# patch "tests/branch_leaves_sync_bug/__driver__.lua"
# from [b07136d83463e208ef345d97415e53eafd244203]
# to [17b7a2b625a52f0f1e4315c99fb747c4657855e8]
#
# patch "tests/commit_default_editor/__driver__.lua"
# from [8d09d83b970265688cb9825e4e0f78c1db3b52ff]
# to [8d2c518dae48558b15227fd42c33831271f42fe6]
#
# patch "unit-tests/dates.cc"
# from [fc614466a2130277bb98e89db1398d6b85cde1a1]
# to [be9bcbe238f0221acb2c37f07b78f98b1a52471a]
#
============================================================
--- unix/parse_time.cc 32590b4a1e4f2fa9efa0f48f077d47af8f13b431
+++ unix/parse_time.cc 32590b4a1e4f2fa9efa0f48f077d47af8f13b431
@@ -0,0 +1,19 @@
+// Copyright (C) 2010 Stephen Leake
+//
+// This program is made available under the GNU GPL version 3.0 or
+// greater. See the accompanying file COPYING for details.
+//
+// This program is distributed WITHOUT ANY WARRANTY; without even the
+// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE.
+
+#include
+#include
+
+bool parse_date (const std::string s, const std::string fmt, struct tm *tp)
+{
+ char *p = strptime(s.c_str(), fmt.c_str(), tb);
+
+ return p != 0;
+}
+// end of file
============================================================
--- win32/parse_time.cc 6970babb88f00ec9526d1e4e3585b55dea2e7da2
+++ win32/parse_time.cc 6970babb88f00ec9526d1e4e3585b55dea2e7da2
@@ -0,0 +1,21 @@
+// Copyright (C) 2010 Stephen Leake
+//
+// This program is made available under the GNU GPL version 3.0 or
+// greater. See the accompanying file COPYING for details.
+//
+// This program is distributed WITHOUT ANY WARRANTY; without even the
+// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE.
+
+#include
+
+bool parse_date (const std::string s, const std::string fmt, struct tm *tp)
+{
+ // Apparently the Win32 API does not provide a date parsing function.
+ //
+ // So far, parse_date is only used in the changelog processing to
+ // allow the user to change the date cert. So we just disable that
+ // on Win32; see cmd_ws_commit.cc get_log_message_interactively.
+ return false;
+}
+// end of file
============================================================
--- Makefile.am e956bf588ace925767e267296316a673e7d4761a
+++ Makefile.am 6e0664ed9ae020582bc88b50023b44a94a57f474
@@ -145,14 +145,14 @@ UNIX_PLATFORM_SOURCES = \
unix/process.cc unix/terminal.cc unix/inodeprint.cc \
unix/fs.cc unix/make_io_binary.cc unix/os_strerror.cc \
unix/cputime.cc unix/ssh_agent_platform.cc \
- unix/ssh_agent_platform.hh
+ unix/ssh_agent_platform.hh win32/parse_time.cc
WIN32_PLATFORM_SOURCES = \
win32/read_password.cc win32/get_system_flavour.cc \
win32/process.cc win32/terminal.cc win32/inodeprint.cc \
win32/fs.cc win32/make_io_binary.cc win32/os_strerror.cc \
win32/cputime.cc win32/ssh_agent_platform.cc \
- win32/ssh_agent_platform.hh
+ win32/ssh_agent_platform.hh win32/parse_time.cc
# these files (part of the main program) contain code subject to unit testing
============================================================
--- cmd_ws_commit.cc 3ffbaa10b5e4c72028f08fcbf06950e5997b7c69
+++ cmd_ws_commit.cc 53480aabfe2e2c66ebedb7c350ec632552dc2614
@@ -1,3 +1,4 @@
+// Copyright (C) 2010 Stephen Leake
// Copyright (C) 2002 Graydon Hoare
//
// This program is made available under the GNU GPL version 2.0 or
@@ -127,6 +128,41 @@ private:
size_t offset;
};
+static bool
+date_fmt_valid (string date_fmt)
+{
+ if (date_fmt.empty())
+ {
+ return true;
+ }
+ else
+ {
+ // check that the specified date format can be used to format and
+ // parse a date
+ date_t now = date_t::now();
+ date_t parsed;
+ try
+ {
+ string formatted = now.as_formatted_localtime(date_fmt);
+ parsed = date_t::from_formatted_localtime(formatted, date_fmt);
+ }
+ catch (recoverable_failure const & e)
+ {
+ L(FL("date check failed: %s") % e.what());
+ }
+
+ if (parsed != now)
+ {
+ L(FL("date check failed: %s != %s") % now % parsed);
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+}
+
static void
get_log_message_interactively(lua_hooks & lua, workspace & work,
project_t & project,
@@ -196,12 +232,23 @@ get_log_message_interactively(lua_hooks
utf8 header;
utf8 summary;
- revision_header(rid, rev, author, date, branch, changelog, date_fmt, header);
+ bool is_date_fmt_valid = date_fmt_valid(date_fmt);
+ string null_date_fmt("");
+
+ if (!is_date_fmt_valid)
+ {
+ W(F("date format '%s' cannot be used for commit; using default instead") % date_fmt);
+ revision_header(rid, rev, author, date, branch, changelog, null_date_fmt, header);
+ }
+ else
+ {
+ revision_header(rid, rev, author, date, branch, changelog, date_fmt, header);
+ }
revision_summary(rev, summary);
- utf8 full_message(instructions() + cancel() + header() + notes() + summary(),
+ utf8 full_message(instructions() + cancel() + header() + notes() + summary(),
origin::internal);
-
+
external input_message;
external output_message;
@@ -276,7 +323,7 @@ get_log_message_interactively(lua_hooks
E(!d.empty(), origin::user,
F("Commit failed. Date value empty."));
- if (date_fmt.empty())
+ if (!is_date_fmt_valid || date_fmt.empty())
date = date_t(d);
else
date = date_t::from_formatted_localtime(d, date_fmt);
@@ -777,28 +824,9 @@ CMD(status, "status", "", CMD_REF(inform
app.lua.hook_get_date_format_spec(date_time_long, date_fmt);
}
- if (!date_fmt.empty())
- {
- // check that the specified date format can be parsed (for commit)
- date_t now = date_t::now();
- date_t parsed;
- try
- {
- string formatted = now.as_formatted_localtime(date_fmt);
- parsed = date_t::from_formatted_localtime(formatted, date_fmt);
- }
- catch (recoverable_failure const & e)
- {
- L(FL("date check failed: %s") % e.what());
- }
+ if (!date_fmt_valid(date_fmt))
+ W(F("date format '%s' cannot be used for commit") % date_fmt);
- if (parsed != now)
- {
- L(FL("date check failed: %s != %s") % now % parsed);
- W(F("date format '%s' cannot be used for commit") % date_fmt);
- }
- }
-
work.get_parent_rosters(db, old_rosters);
work.get_current_roster_shape(db, nis, new_roster);
@@ -1452,29 +1480,6 @@ CMD(commit, "commit", "ci", CMD_REF(work
author = key.official_name();
}
- if (!date_fmt.empty())
- {
- // check that the current date format can be parsed
- date_t parsed;
- try
- {
- string formatted = date.as_formatted_localtime(date_fmt);
- parsed = date_t::from_formatted_localtime(formatted, date_fmt);
- }
- catch (recoverable_failure const & e)
- {
- L(FL("date check failed: %s") % e.what());
- }
-
- if (parsed != date)
- {
- L(FL("date check failed: %s != %s") % date % parsed);
- }
-
- E(parsed == date, origin::user,
- F("date format '%s' cannot be used for commit") % date_fmt);
- }
-
if (!log_message_given)
{
// This call handles _MTN/log.
============================================================
--- dates.cc 24dd854d8c1be66b65a57d813b756ddf13550848
+++ dates.cc 2413fafb2058055cab18cc8f6787c893f471c214
@@ -8,13 +8,14 @@
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE.
+#include
+#include
+
#include "base.hh"
#include "dates.hh"
#include "sanity.hh"
+#include "platform.hh"
-#include
-#include
-
// Generic date handling routines for Monotone.
//
// The routines in this file substantively duplicate functionality of the
@@ -442,13 +443,9 @@ date_t::from_formatted_localtime(string
L(FL("parsing date '%s' with format '%s'") % s % fmt);
- char *p = strptime(s.c_str(), fmt.c_str(), &tb); // local timezone values
-
- E(p, origin::user, // strptime failed to match all of the format string
+ // get local timezone values
+ E(parse_date(s, fmt, &tb), origin::user,
F("unable to parse date '%s' with format '%s'") % s % fmt);
-
- E(*p == 0, origin::user, // extraneous characters in input string
- F("invalid date '%s' not matched by format '%s'") % s % fmt);
// strptime does *not* set the tm_isdst field in the broken down time
// struct. setting it to -1 is apparently the way to tell mktime to
@@ -494,7 +491,7 @@ date_t::from_formatted_localtime(string
tb.tm_wday == check.tm_wday &&
tb.tm_yday == check.tm_yday &&
tb.tm_isdst == check.tm_isdst,
- origin::user,
+ origin::user,
F("date '%s' is out of range and cannot be parsed")
% s);
============================================================
--- platform.hh 648608271dd6559ba89bc0bb816a3de306c3355f
+++ platform.hh 04a90e564b175d1193c25c2e59e9028ddefcc85d
@@ -15,6 +15,7 @@
#include
+#include
void read_password(std::string const & prompt, char * buf, size_t bufsz);
void get_system_flavour(std::string & ident);
@@ -164,6 +165,12 @@ std::string get_locale_dir();
// determine directory to load locale data from
std::string get_locale_dir();
+// Fill tp from s, using format fmt.
+// Returns false on failure, true on success.
+//
+// This is strptime on Unix, something else on MinGW.
+bool parse_date (const std::string s, const std::string fmt, struct tm *tp);
+
#endif // __PLATFORM_HH__
// Local Variables:
============================================================
--- tests/branch_leaves_sync_bug/__driver__.lua b07136d83463e208ef345d97415e53eafd244203
+++ tests/branch_leaves_sync_bug/__driver__.lua 17b7a2b625a52f0f1e4315c99fb747c4657855e8
@@ -6,6 +6,12 @@
-- The bug does not occur if the two workspaces use the same author
-- name and key.
+-- The bug was about logic in the branch leaves cache, not
+-- specifically about sync; it's tested adequately on Linux. 'sync
+-- file:' doesn't work on Win32, but it's not worth setting up a
+-- server for this test.
+skip_if(ostype == "Windows")
+
function abe_mtn(...)
return raw_mtn("--rcfile", test.root .. "/min_hooks.lua",
"--db=" .. test.root .. "/abe.db",
============================================================
--- tests/commit_default_editor/__driver__.lua 8d09d83b970265688cb9825e4e0f78c1db3b52ff
+++ tests/commit_default_editor/__driver__.lua 8d2c518dae48558b15227fd42c33831271f42fe6
@@ -2,6 +2,8 @@
-- which should look for an "editor" executable on the PATH and run it
-- if neither $EDITOR nor $VISUAL is set in the environment. We have
-- to override the default test hooks, which disable edit_comment.
+--
+-- Also test bad --date-format; doesn't fail, just uses the default
mtn_setup()
addfile("a", "hello there")
@@ -9,4 +11,5 @@ check(get("test_hooks.lua")) -- this res
check(get("test_hooks.lua")) -- this restores the default edit_comment
-- and provides a fake "editor" executable
-check(mtn("--branch", "testbranch", "commit"), 0, false, false)
+check(mtn("--branch", "testbranch", "commit", "--date-format", "foo"), 0, false, true)
+check(qgrep("date format 'foo' cannot be used for commit; using default instead", "stderr"))
============================================================
--- unit-tests/dates.cc fc614466a2130277bb98e89db1398d6b85cde1a1
+++ unit-tests/dates.cc be9bcbe238f0221acb2c37f07b78f98b1a52471a
@@ -188,6 +188,8 @@ UNIT_TEST(from_string)
#undef NO
}
+#ifndef WIN32
+// parse_date (used by from_formatted_localtime) not implemented on Win32
UNIT_TEST(roundtrip_localtimes)
{
#define OK(x) do { \
@@ -213,7 +215,7 @@ UNIT_TEST(roundtrip_localtimes)
end += 1000;
// these tests run with LANG=C and TZ=UTC so the %c format seems to work
- // however strptime does not like the timezone name when %c is used in
+ // however strptime does not like the timezone name when %c is used in
// other locales. with LANG=en_CA.UTF-8 this test fails.
if (sizeof(time_t) <= 4)
@@ -247,7 +249,10 @@ UNIT_TEST(roundtrip_localtimes)
#undef OK
}
+#endif
+#ifndef WIN32
+// parse_date (used by from_formatted_localtime) not implemented on Win32
UNIT_TEST(localtime_formats)
{
#define OK(d, f) do { \
@@ -309,6 +314,7 @@ UNIT_TEST(localtime_formats)
#undef OK
}
+#endif
UNIT_TEST(from_unix_epoch)
{