diff --git a/Scheduler/ClockService.cc b/Scheduler/ClockService.cc index d9733d8e8d67527df34df478c9ad695f9b3a597e..612a5797940d22485c095bed9b3d40a712fb4dce 100644 --- a/Scheduler/ClockService.cc +++ b/Scheduler/ClockService.cc @@ -27,16 +27,58 @@ //#include "ClockService.ih" // Custom includes -#include <errno.h> -#include <signal.h> -#include <sys/time.h> -#include <pthread.h> -#include "../Utils/Exception.hh" +#include <boost/regex.hpp> +#include "Console/Console.hh" //#include "ClockService.mpp" #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// +prefix_ void +senf::parseClockServiceInterval(console::ParseCommandInfo::TokensRange const & tokens, + ClockService::clock_type & out) +{ + out = 0; + std::string value; + { + senf::console::CheckedArgumentIteratorWrapper arg (tokens); + senf::console::parse( *(arg++), value ); + } + static boost::sregex_iterator::regex_type rx ("[mun]?[dhms]"); + boost::sregex_iterator i (value.begin(), value.end(), rx); + boost::sregex_iterator const i_end; + std::string::const_iterator j (value.begin()); + for (; i != i_end; ++i) { + boost::sregex_iterator::value_type::value_type match ((*i)[0]); + long double v (boost::lexical_cast<long double>(std::string(j, match.first))); + char scale (0); + char unit (0); + if (match.length() == 2) { + scale = *match.first; + unit = *boost::next(match.first); + } else { + SENF_ASSERT( match.length() == 1); + unit = *match.first; + } + switch (scale) { + case 0: break; + case 'n': v /= 1000.0; + case 'u': v /= 1000.0; + case 'm': v /= 1000.0; + } + switch (unit) { + case 'd': v *= 24.0; + case 'h': v *= 60.0; + case 'm': v *= 60.0; + case 's': v *= 1000000000.0; + } + out += senf::ClockService::nanoseconds(senf::ClockService::int64_type(v)); + j = match.second; + } + if (j != value.end()) + throw senf::console::SyntaxErrorException(); +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "ClockService.mpp" diff --git a/Scheduler/ClockService.hh b/Scheduler/ClockService.hh index 5b02c19088c3a601464c09d0ccf38709d0e84893..bad8b6e2ec20824c19ae33131c8c22235281000a 100644 --- a/Scheduler/ClockService.hh +++ b/Scheduler/ClockService.hh @@ -33,6 +33,7 @@ #include <boost/scoped_ptr.hpp> #include <boost/cstdint.hpp> #include "../Utils/singleton.hh" +#include "Console/Parse.hh" //#include "ClockService.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -150,6 +151,41 @@ namespace senf { #endif }; + /** \brief Console argument parser to parse value as time interval + + This parser will parse a time interval specification into a ClockService::clock_type + value. The following units are supported: + + <table class="senf fixedcolumn"> + <tr><td>\c d</td><td>days</td></tr> + <tr><td>\c h</td><td>hours</td></tr> + <tr><td>\c m</td><td>minutes</td></tr> + <tr><td>\c s</td><td>seconds</td></tr> + </table> + + Additionally, the unit may be prefixed by an SI scale: + + <table class="senf fixedcolumn"> + <tr><td>\c m</td><td>milli</td></tr> + <tr><td>\c u</td><td>micro</td></tr> + <tr><td>\c n</td><td>nano</td></tr> + </table> + + An optional decimal point is also supported. A single timer interval may combine any number + of these specifications. The following are all valid intervals: + + <table class="senf fixedcolumn"> + <tr><td><code>10d</code></td><td>10 days</td></tr> + <tr><td><code>5d5d</code></td><td>10 days</td></tr> + <tr><td><code>1d2h100m3.5s</code></td><td>27 hours, 30 minutes and 3.5 seconds</td></tr> + <tr><td><code>1s100ms</code></td><td>1.1 seconds</td></tr> + <tr><td><code>1.1s</code></td><td>1.1 seconds</td></tr> + <tr><td><code>123.456us</code></td><td>123.456 microseconds</td></tr> + <tr><td><code>2md</code></td><td>(very unusual) 2 milli-days</td></tr> + </table> + */ + void parseClockServiceInterval(console::ParseCommandInfo::TokensRange const & tokens, + ClockService::clock_type & out); } ///////////////////////////////hh.e////////////////////////////////////////