# # # patch "Makefile.am" # from [32daafd4f09fdd8cee6b82c58518f5d9665bf904] # to [350712bd1630bf6976a3c04bf21b72735139414c] # # patch "cmd_diff_log.cc" # from [3c3f91765800b2dd861a997b400c4053fd6969a6] # to [b1684ddc5633e2d8e7ed741f418ccd13731fdbdd] # # patch "dates.cc" # from [eabcdf9b87e2d28ea4d8521f51262e0200ff61b2] # to [a8bef57375a94c4180618efc70bda5ecd9b1d226] # # patch "dates.hh" # from [466009e8661de2563c003594a3d6e53d63a45d01] # to [2b1dcada20482787b3637aa113f9a20aa96c8016] # # patch "globish.cc" # from [a25133bce26322aa0151d7e6420db17833283761] # to [b0e14f7e3b3c7f895639ab7fddfb6aaee10e3c7d] # ============================================================ --- Makefile.am 32daafd4f09fdd8cee6b82c58518f5d9665bf904 +++ Makefile.am 350712bd1630bf6976a3c04bf21b72735139414c @@ -125,8 +125,8 @@ BOTAN_SOURCES = \ botan/dsa_gen.cpp botan/eax.cpp botan/ecb.cpp botan/eme1.cpp \ botan/eme_pkcs.cpp botan/emsa1.cpp botan/emsa2.cpp \ botan/emsa3.cpp botan/emsa4.cpp botan/emsa_raw.cpp \ - botan/eng_base.cpp botan/engine.cpp botan/es_dev.cpp \ - botan/es_egd.cpp botan/exceptn.cpp botan/filter.cpp \ + botan/eng_base.cpp botan/engine.cpp \ + botan/exceptn.cpp botan/filter.cpp \ botan/filters.cpp botan/get_algo.cpp botan/get_enc.cpp \ botan/get_pbe.cpp botan/hash_id.cpp botan/hex.cpp \ botan/hmac.cpp botan/if_algo.cpp botan/init_def.cpp \ @@ -169,7 +169,7 @@ BOTAN_SOURCES = \ botan/dh.h botan/dl_algo.h botan/dl_group.h botan/dlies.h \ botan/eax.h botan/ecb.h botan/eme.h botan/emsa.h \ botan/eng_def.h botan/engine.h botan/enums.h botan/es_dev.h \ - botan/es_egd.h botan/exceptn.h botan/filter.h botan/filters.h \ + botan/exceptn.h botan/filter.h botan/filters.h \ botan/hash_id.h botan/hex.h botan/hmac.h botan/if_algo.h \ botan/init.h botan/kdf.h botan/keypair.h botan/libstate.h \ botan/loadstor.h botan/look_add.h botan/look_pk.h \ @@ -192,9 +192,10 @@ BOTAN_SOURCES = \ botan/x509self.h botan/x509stor.h botan/x931_rng.h \ botan/xor_buf.h +# unix only: botan/es_dev.{cpp,h} botan/es_egd.{cpp,h} +# windows only: botan/es_capi.h botan/es_capi.cpp +# botan/es_win32.{cpp,h} -# windows only: botan/es_capi.h botan/es_capi.cpp botan/es_win32.{cpp,h} - BOOST_SANDBOX_SOURCES = \ boost/circular_buffer_adaptor.hpp \ boost/circular_buffer_base.hpp \ @@ -444,13 +445,14 @@ if WIN32_PLATFORM mtn_LDADD += -lshfolder -lws2_32 -lintl -liconv -liphlpapi unit_tester_LDADD += -lshfolder -lws2_32 -lintl -liconv -liphlpapi lib3rdparty_a_CPPFLAGS += -DWIN32 - lib3rdparty_a_SOURCES += botan/es_capi.cpp botan/es_win32.cpp + lib3rdparty_a_SOURCES += botan/es_capi.h botan/es_capi.cpp \ + botan/es_win32.cpp botan/es_win32.h tester_SOURCES += win32/tester-plaf.cc check_net_SOURCES = win32/tester-check-net.c else libplatform_a_SOURCES += $(UNIX_PLATFORM_SOURCES) mtn_SOURCES += unix/main.cc - lib3rdparty_a_SOURCES += botan/es_dev.cpp + lib3rdparty_a_SOURCES += botan/es_dev.cpp botan/es_egd.cpp botan/es_egd.h tester_SOURCES += unix/tester-plaf.cc check_net_SOURCES = unix/tester-check-net.c endif ============================================================ --- cmd_diff_log.cc 3c3f91765800b2dd861a997b400c4053fd6969a6 +++ cmd_diff_log.cc b1684ddc5633e2d8e7ed741f418ccd13731fdbdd @@ -492,7 +492,7 @@ void dump_header(std::string const & rev vector lines; split_into_lines(summary(), lines); - cout << "#\n"; + out << "#\n"; if (!summary().empty()) { out << revs << "#\n"; @@ -574,7 +574,7 @@ CMD_AUTOMATE(content_diff, N_("[FILE [.. if (app.opts.with_header) { - dump_header(dummy_header, included, cout, false); + dump_header(dummy_header, included, output, false); } dump_diffs(app.lua, db, included, output, ============================================================ --- dates.cc eabcdf9b87e2d28ea4d8521f51262e0200ff61b2 +++ dates.cc a8bef57375a94c4180618efc70bda5ecd9b1d226 @@ -21,8 +21,8 @@ using std::string; // cannot be used directly, so we have to resort to #ifdef chains on the old // skool C limits macros. BOOST_STATIC_ASSERT is defined in a way that // doesn't let us use std::numeric_limits::max(), so we have to -// postpone checking it until runtime (date_t::gmtime), bleah. However, the -// check will be optimized out, and the unit tests exercise it. +// postpone checking it until runtime (our_gmtime), bleah. However, the check +// will be optimized out, and the unit tests exercise it. #if defined ULONG_MAX && ULONG_MAX > UINT_MAX #define PROBABLE_U64_MAX ULONG_MAX #define u64_C(x) x##UL @@ -36,6 +36,10 @@ using std::string; #error "How do I write a constant of type u64?" #endif +// Forward declarations required so as to not have to shuffle around code. +static s64 our_mktime(broken_down_time const & tm); +static void our_gmtime(const s64 d, broken_down_time & tm); + date_t::date_t(u64 d) : d(d) { @@ -45,7 +49,8 @@ date_t::date_t(u64 d) I(valid()); } -date_t::date_t(int sec, int min, int hour, int day, int month, int year) +date_t::date_t(int year, int month, int day, + int hour, int min, int sec, int millisec) { // general validity checks I((year >= 1970) && (year <= 9999)); @@ -54,17 +59,18 @@ date_t::date_t(int sec, int min, int hou I((hour >= 0) && (hour < 24)); I((min >= 0) && (min < 60)); I((sec >= 0) && (sec < 60)); + I((millisec >= 0) && (millisec < 1000)); - struct tm t; - t.tm_sec = sec; - t.tm_min = min; - t.tm_hour = hour; - t.tm_mday = day; - t.tm_mon = month - 1; - t.tm_year = year - 1900; + broken_down_time t; + t.millisec = millisec; + t.sec = sec; + t.min = min; + t.hour = hour; + t.day = day; + t.month = month; + t.year = year; - mktime(t); - + d = our_mktime(t); I(valid()); } @@ -87,29 +93,6 @@ dump(date_t const & d, std::string & s) s = d.as_iso_8601_extended(); } -date_t -date_t::now() -{ - using std::time_t; - using std::time; - using std::tm; - using std::gmtime; - - // This is the only place we rely on the system's time and date function - // which might operate on different epochs (i.e. 1980-01-01, as some - // Windows, old MacOS and VMS systems used). We immediately transform that - // to a struct tm representation, which is independent of the system's - // epoch. - time_t t = time(0); - struct tm b = *gmtime(&t); - - // in CE 10000, you will need to increase the size of 'buf'. - I(b.tm_year <= 9999); - - return date_t(b.tm_sec, b.tm_min, b.tm_hour, - b.tm_mday, b.tm_mon + 1, b.tm_year + 1900); -} - // The Unix epoch is 1970-01-01T00:00:00 (in UTC). As we cannot safely // assume that the system's epoch is the Unix epoch, we implement the // conversion to broken-down time by hand instead of relying on gmtime(). @@ -135,6 +118,7 @@ u64 const LEAP = 366 * DAY; u64 const DAY = 24 * HOUR; u64 const YEAR = 365 * DAY; u64 const LEAP = 366 * DAY; +u64 const FOUR_HUNDRED_YEARS = 400 * YEAR + (100 - 4 + 1) * DAY; unsigned char const MONTHS[] = { 31, // jan @@ -151,7 +135,42 @@ unsigned char const MONTHS[] = { 31, // dec }; +static s64 +get_epoch_offset() +{ + static s64 epoch_offset; + static bool know_epoch_offset = false; + broken_down_time our_t; + if (know_epoch_offset) + return epoch_offset; + + std::time_t epoch = 0; + std::tm t = *std::gmtime(&epoch); + + our_t.millisec = 0; + our_t.sec = t.tm_sec; + our_t.min = t.tm_min; + our_t.hour = t.tm_hour; + our_t.day = t.tm_mday; + our_t.month = t.tm_mon + 1; + our_t.year = t.tm_year + 1900; + + epoch_offset = our_mktime(our_t); + + know_epoch_offset = true; + return epoch_offset; +} + +date_t +date_t::now() +{ + std::time_t t = std::time(0); + date_t d; + d.d = u64(t) * 1000 + get_epoch_offset(); + return d; +} + inline bool is_leap_year(unsigned int year) { @@ -167,21 +186,22 @@ date_t::as_iso_8601_extended() const string date_t::as_iso_8601_extended() const { - struct tm tm; - gmtime(tm); + broken_down_time tm; + I(valid()); + our_gmtime(d, tm); return (FL("%04u-%02u-%02uT%02u:%02u:%02u") - % (tm.tm_year + 1900) % (tm.tm_mon + 1) % tm.tm_mday - % tm.tm_hour % tm.tm_min % tm.tm_sec).str(); + % tm.year % tm.month % tm.day + % tm.hour % tm.min % tm.sec).str(); } u64 -date_t::as_unix_epoch() const +date_t::millisecs_since_unix_epoch() const { return d; } -void -date_t::gmtime(struct tm & tm) const +static void +our_gmtime(const s64 d, broken_down_time & tm) { // these types hint to the compiler that narrowing divides are safe u64 yearbeg; @@ -238,22 +258,22 @@ date_t::gmtime(struct tm & tm) const t -= yearbeg; // Now, the months digit! - month = 0; + month = 1; for (;;) { - u64 this_month = MONTHS[month] * DAY; - if (month == 1 && is_leap_year(year)) + u64 this_month = MONTHS[month-1] * DAY; + if (month == 2 && is_leap_year(year)) this_month += DAY; if (t < this_month) break; t -= this_month; month++; - I(month < 12); + I(month <= 12); } // the rest is straightforward. - day = t / DAY; + day = t / DAY + 1; msofday = t % DAY; hour = msofday / HOUR; @@ -266,43 +286,47 @@ date_t::gmtime(struct tm & tm) const msec = msofmin % SEC; // fill in the result - tm.tm_sec = sec; - tm.tm_min = min; - tm.tm_hour = hour; - tm.tm_mday = day + 1; - tm.tm_mon = month; - tm.tm_year = year - 1900; + tm.millisec = msec; + tm.sec = sec; + tm.min = min; + tm.hour = hour; + tm.day = day; + tm.month = month; + tm.year = year; } -void -date_t::mktime(struct tm const & tm) +static s64 +our_mktime(broken_down_time const & tm) { - d = tm.tm_sec * SEC; - d += tm.tm_min * MIN; - d += tm.tm_hour * HOUR; - d += tm.tm_mday * DAY; + s64 d; + d = tm.millisec; + d += tm.sec * SEC; + d += tm.min * MIN; + d += tm.hour * HOUR; + d += (tm.day - 1) * DAY; + // add months - for (int m = 0; m < tm.tm_mon; ++m) + for (int m = 1; m < tm.month; ++m) { - d += MONTHS[m] * DAY; - if ((m == 1) && (is_leap_year(tm.tm_year))) + d += MONTHS[m-1] * DAY; + if ((m == 2) && (is_leap_year(tm.year))) d += DAY; } - // add years (which begin at 1900 for struct tm) - d += YEAR * (tm.tm_year - 70); + I(tm.year >= 0); - // add leap days for every fourth year (since 1968) - d += DAY * ((tm.tm_year - 68 - 1) / 4); + // add years (since 1970) + d += YEAR * (tm.year - 1970); - // subtract leap days for every 100th year (since 1900) - d -= DAY * ((tm.tm_year - 1) / 100); + // calculate leap days to add (or subtract) + int add_leap_days = (tm.year - 1) / 4 - 492; + add_leap_days -= (tm.year - 1) / 100 - 19; + add_leap_days += (tm.year - 1) / 400 - 4; - // add leap days for every 400th year (since 2000), subtracting one again - d += DAY * (((tm.tm_year + 300 - 1) / 400) - 1); + d += DAY * add_leap_days; - I(valid()); + return d; } // We might want to consider teaching this routine more time formats. @@ -320,8 +344,8 @@ date_t::from_string(string const & d) while (d.at(i) >= '0' && d.at(i) <= '9') i--; - // ignore milliseconds, if present, or go back to the end of the date - // string to parse the digits for seconds. + // ignore fractional seconds, if present, or go back to the end of the + // date string to parse the digits for seconds. if (d.at(i) == '.') i--; else @@ -428,7 +452,7 @@ date_t::from_string(string const & d) N(day >= 1 && day <= mdays, F("day out of range for its month in '%s'") % d); - return date_t(sec, min, hour, day, month, year); + return date_t(year, month, day, hour, min, sec); } catch (std::out_of_range) { @@ -446,7 +470,7 @@ date_t::operator +=(s64 const other) d += other; - // make sure we are still before year 10'000 + // make sure we are still before year 10,000 I(valid()); return *this; @@ -484,6 +508,57 @@ date_t::operator -(date_t const & other) #ifdef BUILD_UNIT_TESTS #include "unit_tests.hh" +UNIT_TEST(date, our_mktime) +{ + +#define OK(x) UNIT_TEST_CHECK(our_mktime(t) == (x)) + + broken_down_time t = {0, 0, 0, 0, 1, 1, 1970}; + OK(0); + + t.year = 2000; + OK(u64_C(946684800000)); + + // Make sure our_mktime works for years before 1970 as well. + t.year = 1960; + OK(-10 * YEAR - 3 * DAY); + + t.year = 1569; + OK(-FOUR_HUNDRED_YEARS - YEAR); + + t.year = 1570; + OK(-FOUR_HUNDRED_YEARS); + + t.year = 1571; + OK(-FOUR_HUNDRED_YEARS + YEAR); + + t.year = 1572; + OK(-FOUR_HUNDRED_YEARS + 2 * YEAR); + + t.year = 1573; + OK(-FOUR_HUNDRED_YEARS + 3 * YEAR + DAY); + + t.year = 1574; + OK(-FOUR_HUNDRED_YEARS + 4 * YEAR + DAY); + + t.year = 1170; + OK(-2 * FOUR_HUNDRED_YEARS); + + t.year = 770; + OK(-3 * FOUR_HUNDRED_YEARS); + + t.year = 370; + OK(-4 * FOUR_HUNDRED_YEARS); + + t.year = 0; /* year 0 anno Domini */ + OK(-1970 * YEAR - (492 - 19 + 4) * DAY); + + t.year = -1; /* year 1 BC */ + UNIT_TEST_CHECK_THROW(our_mktime(t), std::logic_error); + +#undef OK +} + UNIT_TEST(date, from_string) { #define OK(x,y) UNIT_TEST_CHECK(date_t::from_string(x).as_iso_8601_extended() \ ============================================================ --- dates.hh 466009e8661de2563c003594a3d6e53d63a45d01 +++ dates.hh 2b1dcada20482787b3637aa113f9a20aa96c8016 @@ -17,6 +17,17 @@ #include "numeric_vocab.hh" #include "sanity.hh" +// Our own "struct tm"-like struct to represent broken-down times +struct broken_down_time { + int millisec; /* milliseconds (0 - 999) */ + int sec; /* seconds (0 - 59) */ + int min; /* minutes (0 - 59) */ + int hour; /* hours (0 - 23) */ + int day; /* day of the month (1 - 31) */ + int month; /* month (1 - 12) */ + int year; /* years (anno Domini, i.e. 1999) */ +}; + struct date_t { // initialize to an invalid date @@ -25,8 +36,9 @@ struct date_t // initialize from a unix timestamp date_t(u64 d); - // initialize from multiple values - date_t(int sec, int min, int hour, int day, int month, int year); + // Initialize from broken-down time + date_t(int year, int month, int day, + int hour=0, int min=0, int sec=0, int millisec=0); bool valid() const; @@ -40,21 +52,21 @@ struct date_t // Write out date as a string. std::string as_iso_8601_extended() const; - // Retrieve the Unix epoch timestamp itself - u64 as_unix_epoch() const; + // Retrieve the internal milliseconds count since the Unix epoch. + u64 millisecs_since_unix_epoch() const; // Date comparison operators - bool operator <(struct date_t const & other) const + bool operator <(date_t const & other) const { return d < other.d; }; - bool operator <=(struct date_t const & other) const + bool operator <=(date_t const & other) const { return d <= other.d; }; - bool operator >(struct date_t const & other) const + bool operator >(date_t const & other) const { return d > other.d; }; - bool operator >=(struct date_t const & other) const + bool operator >=(date_t const & other) const { return d >= other.d; }; - bool operator ==(struct date_t const & other) const + bool operator ==(date_t const & other) const { return d == other.d; }; - bool operator !=(struct date_t const & other) const + bool operator !=(date_t const & other) const { return d != other.d; }; // Addition and subtraction of millisecond amounts @@ -70,11 +82,6 @@ private: // The date as an unsigned 64-bit count of milliseconds since // the Unix epoch (1970-01-01T00:00:00.000). u64 d; - - // Our own gmtime function which converts the internal Unix epoch - // into a struct tm. - void gmtime(struct tm & tm) const; - void mktime(struct tm const & tm); }; std::ostream & operator<< (std::ostream & o, date_t const & d); ============================================================ --- globish.cc a25133bce26322aa0151d7e6420db17833283761 +++ globish.cc b0e14f7e3b3c7f895639ab7fddfb6aaee10e3c7d @@ -334,23 +334,28 @@ find_next_subpattern(string::const_itera string::const_iterator pe, bool want_alternatives) { + L(FL("Finding subpattern in '%s'") % decode(p, pe)); unsigned int depth = 1; for (; p != pe; p++) switch (*p) { - default: break; + default: + break; case META_ALT_BRA: - depth++; break; + depth++; + break; case META_ALT_KET: depth--; if (depth == 0) return p+1; + break; case META_ALT_OR: if (depth == 1 && want_alternatives) return p+1; + break; } I(false); @@ -705,6 +710,19 @@ UNIT_TEST(globish, complex_matches) } } +UNIT_TEST(globish, nested_matches) +{ + globish g("a.{i.{x,y},j}"); + UNIT_TEST_CHECK(g.matches("a.i.x")); + UNIT_TEST_CHECK(g.matches("a.i.y")); + UNIT_TEST_CHECK(g.matches("a.j")); + UNIT_TEST_CHECK(!g.matches("q")); + UNIT_TEST_CHECK(!g.matches("a.q")); + UNIT_TEST_CHECK(!g.matches("a.j.q")); + UNIT_TEST_CHECK(!g.matches("a.i.q")); + UNIT_TEST_CHECK(!g.matches("a.i.x.q")); +} + #endif // BUILD_UNIT_TESTS // Local Variables: