diff options
| author | Wiimm <wiimm@wiimm.de> | 2020-10-03 14:59:19 +0200 |
|---|---|---|
| committer | Wiimm <wiimm@wiimm.de> | 2020-10-03 14:59:19 +0200 |
| commit | a0815499b2d9014695e6e261c909476729445360 (patch) | |
| tree | 7a31ed50ee3c1c62b86f7ddc09273c4cd7eadc8d /project/dclib | |
| parent | 89f00e8e4730b4834e6cc0c96e14f137ca4ac169 (diff) | |
SZS v2.20a
Diffstat (limited to '')
| -rw-r--r-- | project/dclib/dclib-basics.h | 170 | ||||
| -rw-r--r-- | project/dclib/dclib-file.c | 146 | ||||
| -rw-r--r-- | project/dclib/dclib-file.h | 41 | ||||
| -rw-r--r-- | project/dclib/dclib-numeric.c | 395 | ||||
| -rw-r--r-- | project/dclib/dclib-system.h | 3 |
5 files changed, 465 insertions, 290 deletions
diff --git a/project/dclib/dclib-basics.h b/project/dclib/dclib-basics.h index a13c748..68eeca7 100644 --- a/project/dclib/dclib-basics.h +++ b/project/dclib/dclib-basics.h @@ -70,6 +70,20 @@ // /////////////////////////////////////////////////////////////////////////////// +/////////////// HAVE_* /////////////// +/////////////////////////////////////////////////////////////////////////////// + +#undef HAVE_CLOCK_GETTIME +#if _POSIX_C_SOURCE >= 199309L + #define HAVE_CLOCK_GETTIME 1 +#else + #define HAVE_CLOCK_GETTIME 0 +#endif + +/////////////////////////////////////////////////////////////////////////////// + +// +/////////////////////////////////////////////////////////////////////////////// /////////////// bits /////////////// /////////////////////////////////////////////////////////////////////////////// @@ -3364,6 +3378,14 @@ char * ScanSIFactor #define USEC_PER_DAY (SEC_PER_DAY*USEC_PER_SEC) #define USEC_PER_WEEK (SEC_PER_WEEK*USEC_PER_SEC) +#define NSEC_PER_USEC 1000ull +#define NSEC_PER_MSEC 1000000ull +#define NSEC_PER_SEC 1000000000ull +#define NSEC_PER_MIN (60*NSEC_PER_SEC) +#define NSEC_PER_HOUR (3600*NSEC_PER_SEC) +#define NSEC_PER_DAY (SEC_PER_DAY*NSEC_PER_SEC) +#define NSEC_PER_WEEK (SEC_PER_WEEK*NSEC_PER_SEC) + //--- time types typedef uint u_sec_t; // unsigned type to store time as seconds @@ -3372,6 +3394,8 @@ typedef u64 u_msec_t; // unsigned type to store time as milliseconds typedef s64 s_msec_t; // signed type to store time as milliseconds typedef u64 u_usec_t; // unsigned type to store time as microseconds typedef s64 s_usec_t; // signed type to store time as microseconds +typedef u64 u_nsec_t; // unsigned type to store time as nanoseconds +typedef s64 s_nsec_t; // signed type to store time as nanoseconds // [[DayTime_t]] typedef struct DayTime_t @@ -3382,6 +3406,7 @@ typedef struct DayTime_t int min; // minute of hour int sec; // second of minute int usec; // microsecond of second + int nsec; // nanosecond of second } DayTime_t; @@ -3389,6 +3414,7 @@ DayTime_t; extern s64 timezone_adjust_sec; extern s64 timezone_adjust_usec; +extern s64 timezone_adjust_nsec; extern int timezone_adjust_isdst; /////////////////////////////////////////////////////////////////////////////// @@ -3397,25 +3423,31 @@ void SetupTimezone ( bool force ); int GetTimezoneAdjust ( time_t tim ); struct timeval GetTimeOfDay ( bool localtime ); +struct timespec GetClockTime ( bool localtime ); DayTime_t GetDayTime ( bool localtime ); u_sec_t GetTimeSec ( bool localtime ); u_msec_t GetTimeMSec ( bool localtime ); u_usec_t GetTimeUSec ( bool localtime ); +u_nsec_t GetTimeNSec ( bool localtime ); u_msec_t GetTimerMSec(void); u_usec_t GetTimerUSec(void); +u_nsec_t GetTimerNSec(void); static inline u64 double2msec ( double d ) { return d>0.0 ? (u64)trunc( 1e3*d+0.5 ) : 0; } static inline u64 double2usec ( double d ) { return d>0.0 ? (u64)trunc( 1e6*d+0.5 ) : 0; } +static inline u64 double2nsec ( double d ) { return d>0.0 ? (u64)trunc( 1e9*d+0.5 ) : 0; } static inline double msec2double ( u64 num ) { return num * 1e-3; } static inline double usec2double ( u64 num ) { return num * 1e-6; } +static inline double nsec2double ( u64 num ) { return num * 1e-9; } //--- another epoch: Monday, 2001-01-01 #define EPOCH_2001_SEC 0x3a4fc880 #define EPOCH_2001_MSEC (EPOCH_2001_SEC*MSEC_PER_SEC) #define EPOCH_2001_USEC (EPOCH_2001_SEC*USEC_PER_SEC) +#define EPOCH_2001_NSEC (EPOCH_2001_SEC*NSEC_PER_SEC) /////////////////////////////////////////////////////////////////////////////// @@ -3437,28 +3469,56 @@ ccp PrintTimeByFormatUTC //----------------------------------------------------------------------------- -ccp PrintUsecByFormat +ccp PrintNSecByFormat ( // returns temporary buffer by GetCircBuf(); ccp format, // format string for strftime() - // 1-6 '@' in row replaced by digits of 'usec' + // 1-9 '@' in row replaced by digits of 'nsec' time_t tim, // seconds since epoch - uint usec // micro second of second + uint nsec // nanosecond of second ); -ccp PrintUsecByFormatUTC +ccp PrintNSecByFormatUTC ( // returns temporary buffer by GetCircBuf(); ccp format, // format string for strftime() - // 1-6 '@' in row replaced by digits of 'usec' + // 1-9 '@' in row replaced by digits of 'nsec' time_t tim, // seconds since epoch - uint usec // micro second of second + uint nsec // nanosecond of second ); //----------------------------------------------------------------------------- +static inline ccp PrintUSecByFormat +( + // returns temporary buffer by GetCircBuf(); + + ccp format, // format string for strftime() + // 1-9 '@' in row replaced by digits of 'usec' + time_t tim, // seconds since epoch + uint usec // microsecond of second +) +{ + return PrintNSecByFormat(format,tim,usec*NSEC_PER_USEC); +} + +static inline ccp PrintUSecByFormatUTC +( + // returns temporary buffer by GetCircBuf(); + + ccp format, // format string for strftime() + // 1-9 '@' in row replaced by digits of 'usec' + time_t tim, // seconds since epoch + uint usec // microsecond of second +) +{ + return PrintNSecByFormatUTC(format,tim,usec*NSEC_PER_USEC); +} + +//----------------------------------------------------------------------------- + ccp PrintTimevalByFormat ( // returns temporary buffer by GetCircBuf(); @@ -3475,6 +3535,24 @@ ccp PrintTimevalByFormatUTC const struct timeval *tv // time to print, if NULL use gettimeofday() ); +//----------------------------------------------------------------------------- + +ccp PrintTimespecByFormat +( + // returns temporary buffer by GetCircBuf(); + + ccp format, // format string for strftime() + const struct timespec *ts // time to print, if NULL use GetClockTime(false) +); + +ccp PrintTimespecByFormatUTC +( + // returns temporary buffer by GetCircBuf(); + + ccp format, // format string for strftime() + const struct timespec *ts // time to print, if NULL use GetClockTime(false) +); + /////////////////////////////////////////////////////////////////////////////// ccp PrintTimeSec @@ -3485,8 +3563,6 @@ ccp PrintTimeSec u_sec_t sec // seconds (=time) to print ); -//----------------------------------------------------------------------------- - ccp PrintTimeMSec ( char * buf, // result buffer (>23 bytes are good) @@ -3496,8 +3572,6 @@ ccp PrintTimeMSec uint fraction // number of digits (0-3) to print as fraction ); -//----------------------------------------------------------------------------- - ccp PrintTimeUSec ( char * buf, // result buffer (>26 bytes are good) @@ -3507,6 +3581,15 @@ ccp PrintTimeUSec uint fraction // number of digits (0-6) to print as fraction ); +ccp PrintTimeNSec +( + char * buf, // result buffer (>26 bytes are good) + // If NULL, a local circulary static buffer is used + size_t buf_size, // size of 'buf', ignored if buf==NULL + u_nsec_t nsec, // nanoseconds to print + uint fraction // number of digits (0-9) to print as fraction +); + //----------------------------------------------------------------------------- ccp PrintTimerMSec @@ -3524,7 +3607,16 @@ ccp PrintTimerUSec // If NULL, a local circulary static buffer is used size_t buf_size, // size of 'buf', ignored if buf==NULL s_usec_t usec, // microseconds to print - uint fraction // number of digits (0-3) to print as fraction + uint fraction // number of digits (0-6) to print as fraction +); + +ccp PrintTimerNSec +( + char * buf, // result buffer (>16 bytes are good) + // If NULL, a local circulary static buffer is used + size_t buf_size, // size of 'buf', ignored if buf==NULL + s_nsec_t nsec, // nanoseconds to print + uint fraction // number of digits (0-9) to print as fraction ); //----------------------------------------------------------------------------- @@ -3535,7 +3627,8 @@ ccp PrintTimer3 // helper function // If NULL, a local circulary static buffer is used size_t buf_size, // size of 'buf', ignored if buf==NULL u64 sec, // seconds to print - int usec, // 0...999999: usec fraction, otherwise suppress ms/us output + int usec, // 0...999999: usec fraction, + // otherwise suppress ms/us output bool aligned // true: print aligned 3 character output ); @@ -3583,7 +3676,8 @@ ccp PrintTimer4 // helper function // If NULL, a local circulary static buffer is used size_t buf_size, // size of 'buf', ignored if buf==NULL u64 sec, // seconds to print - int usec, // 0...999999: usec fraction, otherwise suppress ms/us output + int usec, // 0...999999: usec fraction, + // otherwise suppress ms/us output bool aligned // true: print aligned 4 character output ); @@ -3632,7 +3726,7 @@ ccp PrintTimer6 // helper function size_t buf_size, // size of 'buf', ignored if buf==NULL u64 sec, // seconds to print int usec, // 0...999999: usec fraction, - // otherwise suppress ms/us output + // otherwise suppress ms/us output bool aligned // true: print aligned 6 character output ); @@ -3742,19 +3836,6 @@ static inline ccp PrintTimerSec7s return PrintTimerUSec7s(buf,buf_size,1000000ll*sec,mode); } -//----------------------------------------------------------------------------- - -typedef struct xtime_t -{ - time_t time; - suseconds_t usec; - u64 total_usec; - u64 rel_usec; - -} xtime_t; - -u64 GetXTime ( xtime_t * xtime ); - // /////////////////////////////////////////////////////////////////////////////// /////////////// scan date & time /////////////// @@ -3762,18 +3843,41 @@ u64 GetXTime ( xtime_t * xtime ); // ScanInterval*() is old ==> try ScanDuration() +//----------------------------------------------------------------------------- +// new interface : all functions return first not scanned char + +char * ScanIntervalTS +( + struct timespec *res_ts, // not NULL: store result here + ccp source // source text +); + +char * ScanIntervalUSec +( + u_usec_t *res_usec, // not NULL: store total microseconds + ccp source // source text +); + + +char * ScanIntervalNSec +( + u_nsec_t *res_nsec, // not NULL: store total nanoseconds + ccp source // source text +); + +//----------------------------------------------------------------------------- +// legacy interface : all functions return first not scanned char + char * ScanInterval ( time_t *res_time, // not NULL: store seconds - u32 *res_usec, // not NULL: store micro seconds of second + u32 *res_usec, // not NULL: store microseconds of second ccp source // source text ); -/////////////////////////////////////////////////////////////////////////////// - char * ScanInterval64 ( - u64 *res_usec, // not NULL: store total micro seconds + u64 *res_usec, // not NULL: store total microseconds ccp source // source text ); @@ -3782,7 +3886,7 @@ char * ScanInterval64 char * ScanDateTime ( time_t *res_time, // not NULL: store seconds - u32 *res_usec, // not NULL: store micro seconds of second + u32 *res_usec, // not NULL: store microseconds of second ccp source, // source text bool allow_delta // true: allow +|- interval ); @@ -3791,7 +3895,7 @@ char * ScanDateTime char * ScanDateTime64 ( - u64 *res_usec, // not NULL: store total micro seconds + u64 *res_usec, // not NULL: store total microseconds ccp source, // source text bool allow_delta // true: allow +|- interval ); diff --git a/project/dclib/dclib-file.c b/project/dclib/dclib-file.c index cef7add..4f02ea5 100644 --- a/project/dclib/dclib-file.c +++ b/project/dclib/dclib-file.c @@ -198,7 +198,6 @@ FileAttrib_t * ClearFileAttrib FileAttrib_t * dest // NULL or destination attribute ) { - #if HAVE_FILEATTRIB_NSEC if (dest) { memset(dest,0,sizeof(*dest)); @@ -207,10 +206,6 @@ FileAttrib_t * ClearFileAttrib dest->ctime.tv_nsec = dest->itime.tv_nsec = UTIME_OMIT; } - #else - if (dest) - memset(dest,0,sizeof(*dest)); - #endif return dest; } @@ -222,17 +217,8 @@ FileAttrib_t * TouchFileAttrib ) { DASSERT(dest); - #if HAVE_FILEATTRIB_NSEC - struct timeval tv; - if (!gettimeofday(&tv,0)) - { - dest->atime.tv_sec = tv.tv_sec; - dest->atime.tv_nsec = tv.tv_usec * 1000; - dest->mtime = dest->ctime = dest->itime = dest->atime; - } - #else - dest->mtime = dest->ctime = dest->atime = dest->itime = time(0); - #endif + dest->atime = GetClockTime(false); + dest->mtime = dest->ctime = dest->itime = dest->atime; return dest; } @@ -248,8 +234,6 @@ FileAttrib_t * SetFileAttrib { DASSERT(dest); - #if HAVE_FILEATTRIB_NSEC - if (src_fa) memcpy(dest,src_fa,sizeof(*dest)); else if (src_stat) @@ -275,25 +259,6 @@ FileAttrib_t * SetFileAttrib dest->mode = src_stat->st_mode; } - #else - - if (src_fa) - memcpy(dest,src_fa,sizeof(*dest)); - else if (src_stat) - { - memset(dest,0,sizeof(*dest)); - if (S_ISREG(src_stat->st_mode)) - { - dest->atime = src_stat->st_atime; - dest->mtime = src_stat->st_mtime; - dest->ctime = src_stat->st_ctime; - dest->itime = dest->mtime > dest->ctime ? dest->mtime : dest->ctime; - dest->size = src_stat->st_size; - } - dest->mode = src_stat->st_mode; - } - - #endif return dest; } @@ -308,17 +273,15 @@ FileAttrib_t * MaxFileAttrib { DASSERT(dest); - #if HAVE_FILEATTRIB_NSEC - if (src_fa) { - if (CompareTimeSpec(&dest->atime,&src_fa->atime)>0) dest->atime = src_fa->atime; - if (CompareTimeSpec(&dest->mtime,&src_fa->mtime)>0) dest->mtime = src_fa->mtime; - if (CompareTimeSpec(&dest->ctime,&src_fa->ctime)>0) dest->ctime = src_fa->ctime; - if (CompareTimeSpec(&dest->itime,&src_fa->itime)>0) dest->itime = src_fa->itime; + if (CompareTimeSpec(&dest->atime,&src_fa->atime)<0) dest->atime = src_fa->atime; + if (CompareTimeSpec(&dest->mtime,&src_fa->mtime)<0) dest->mtime = src_fa->mtime; + if (CompareTimeSpec(&dest->ctime,&src_fa->ctime)<0) dest->ctime = src_fa->ctime; + if (CompareTimeSpec(&dest->itime,&src_fa->itime)<0) dest->itime = src_fa->itime; - if ( dest->size < src_fa->size ) - dest->size = src_fa->size; + if ( dest->size < src_fa->size ) + dest->size = src_fa->size; dest->mode = src_fa->mode; } @@ -327,44 +290,44 @@ FileAttrib_t * MaxFileAttrib if ( S_ISREG(src_stat->st_mode) ) { #if HAVE_STATTIME_NSEC - if ( CompareTimeSpec(&dest->atime,&src_stat->st_atim) > 0 ) + if ( CompareTimeSpec(&dest->atime,&src_stat->st_atim) < 0 ) dest->atime = src_stat->st_atim; - if ( CompareTimeSpec(&dest->mtime,&src_stat->st_mtim) > 0 ) + if ( CompareTimeSpec(&dest->mtime,&src_stat->st_mtim) < 0 ) dest->mtime = src_stat->st_mtim; - if ( CompareTimeSpec(&dest->ctime,&src_stat->st_ctim) > 0 ) + if ( CompareTimeSpec(&dest->ctime,&src_stat->st_ctim) < 0 ) dest->ctime = src_stat->st_ctim; - if ( CompareTimeSpec(&dest->itime,&src_stat->st_mtim) > 0 ) + if ( CompareTimeSpec(&dest->itime,&src_stat->st_mtim) < 0 ) dest->itime = src_stat->st_mtim; - if ( CompareTimeSpec(&dest->itime,&src_stat->st_ctim) > 0 ) + if ( CompareTimeSpec(&dest->itime,&src_stat->st_ctim) < 0 ) dest->itime = src_stat->st_ctim; #else - if ( CompareTimeSpecTime(&dest->atime,src_stat->st_atime) > 0 ) + if ( CompareTimeSpecTime(&dest->atime,src_stat->st_atime) < 0 ) { dest->atime.tv_sec = src_stat->st_atime; dest->atime.tv_nsec = 0; } - if ( CompareTimeSpecTime(&dest->mtime,src_stat->st_mtime) > 0 ) + if ( CompareTimeSpecTime(&dest->mtime,src_stat->st_mtime) < 0 ) { dest->mtime.tv_sec = src_stat->st_mtime; dest->mtime.tv_nsec = 0; } - if ( CompareTimeSpecTime(&dest->ctime,src_stat->st_ctime) > 0 ) + if ( CompareTimeSpecTime(&dest->ctime,src_stat->st_ctime) < 0 ) { dest->ctime.tv_sec = src_stat->st_ctime; dest->ctime.tv_nsec = 0; } - if ( CompareTimeSpecTime(&dest->itime,src_stat->st_mtime) > 0 ) + if ( CompareTimeSpecTime(&dest->itime,src_stat->st_mtime) < 0 ) { dest->itime.tv_sec = src_stat->st_mtime; dest->itime.tv_nsec = 0; } - if ( CompareTimeSpecTime(&dest->itime,src_stat->st_ctime) > 0 ) + if ( CompareTimeSpecTime(&dest->itime,src_stat->st_ctime) < 0 ) { dest->itime.tv_sec = src_stat->st_ctime; dest->itime.tv_nsec = 0; @@ -372,43 +335,11 @@ FileAttrib_t * MaxFileAttrib #endif if ( dest->size < src_stat->st_size ) - dest->size = src_stat->st_size; - } - dest->mode = src_stat->st_mode; - } - - #else - - if (src_fa) - { - if ( dest->atime < src_fa->atime ) dest->atime = src_fa->atime; - if ( dest->mtime < src_fa->mtime ) dest->mtime = src_fa->mtime; - if ( dest->ctime < src_fa->ctime ) dest->ctime = src_fa->ctime; - if ( dest->itime < src_fa->itime ) dest->itime = src_fa->itime; - - if ( dest->size < src_fa->size ) dest->size = src_fa->size; - - dest->mode = src_fa->mode; - } - - if (src_stat) - { - if ( S_ISREG(src_stat->st_mode) ) - { - if ( dest->atime < src_stat->st_atime ) dest->atime = src_stat->st_atime; - if ( dest->mtime < src_stat->st_mtime ) dest->mtime = src_stat->st_mtime; - if ( dest->ctime < src_stat->st_ctime ) dest->ctime = src_stat->st_ctime; - - if ( dest->itime < dest->mtime ) dest->itime = dest->mtime; - if ( dest->itime < dest->ctime ) dest->itime = dest->ctime; - - if ( dest->size < src_stat->st_size ) dest->size = src_stat->st_size; + dest->size = src_stat->st_size; } dest->mode = src_stat->st_mode; } - #endif - return dest; } @@ -424,8 +355,6 @@ FileAttrib_t * NormalizeFileAttrib if ( fa->size < 0 ) fa->size = 0; - #if HAVE_FILEATTRIB_NSEC - if (IsTimeSpecNull(&fa->mtime)) { if (!IsTimeSpecNull(&fa->itime)) @@ -446,32 +375,6 @@ FileAttrib_t * NormalizeFileAttrib fa->atime = CompareTimeSpec(&fa->itime,&fa->ctime) > 0 ? fa->itime : fa->ctime; - #else - - time_t mtime = fa->mtime; - if (!mtime) - { - mtime = fa->itime; - if (!mtime) - { - mtime = fa->ctime; - if (!mtime) - mtime = fa->atime; - } - } - fa->mtime = mtime; - - if (!fa->itime) - fa->itime = fa->ctime > mtime ? fa->ctime : mtime; - - if (!fa->ctime) - fa->ctime = fa->itime > mtime ? fa->itime : mtime; - - if (!fa->atime) - fa->atime = fa->itime > fa->ctime ? fa->itime : fa->ctime; - - #endif - return fa; } @@ -887,19 +790,8 @@ enumError CloseFile TRACE("UNLINK %s\n",f->fname); unlink(f->fname); } - #if HAVE_FILEATTRIB_NSEC else if ( set_time == 1 && !IsTimeSpecNull(&f->fatt.mtime) ) utimensat(AT_FDCWD,f->fname,f->fatt.times,0); - #else - else if ( set_time == 1 && f->fatt.mtime ) - { - struct utimbuf ubuf; - ubuf.actime = f->fatt.atime - ? f->fatt.atime : f->fatt.mtime; - ubuf.modtime = f->fatt.mtime; - utime(f->fname,&ubuf); - } - #endif else if ( set_time > 1 || f->fmode & FM_TOUCH ) { utime(f->fname,0); diff --git a/project/dclib/dclib-file.h b/project/dclib/dclib-file.h index 05e520e..6f6aee9 100644 --- a/project/dclib/dclib-file.h +++ b/project/dclib/dclib-file.h @@ -128,7 +128,7 @@ ccp GetFileOpenMode /////////////////////////////////////////////////////////////////////////////// #ifndef HAVE_STATTIME_NSEC - #if defined(st_atime) && defined(st_mtime) && defined(st_ctime) && !defined(__APPLE__) + #ifdef _STATBUF_ST_NSEC #define HAVE_STATTIME_NSEC 1 #else #define HAVE_STATTIME_NSEC 0 @@ -200,35 +200,13 @@ static inline bool IsTimeSpecNull ( const struct timespec *ts ) /////////////////////////////////////////////////////////////////////////////// /////////////// struct FileAttrib_t /////////////// /////////////////////////////////////////////////////////////////////////////// - -#ifndef HAVE_FILEATTRIB_NSEC - #if defined(st_mtime) && !defined(__APPLE__) - #define HAVE_FILEATTRIB_NSEC 1 - #else - #define HAVE_FILEATTRIB_NSEC 1 - #endif -#endif - -#undef FILEATTRIB_SEC -#undef FILEATTRIB_NSEC -#if HAVE_FILEATTRIB_NSEC - #define FILEATTRIB_SEC(t) ((t).tv_sec) - #define FILEATTRIB_NSEC(t) ((t).tv_nsec) -#else - #define FILEATTRIB_SEC(t) (t) - #define FILEATTRIB_NSEC(t) 0 -#endif - -/////////////////////////////////////////////////////////////////////////////// // [[FileAttrib_t]] typedef struct FileAttrib_t { - #if HAVE_FILEATTRIB_NSEC - union { - struct timespec times[4]; + struct timespec times[4]; // all times as array struct { // order compatible to utimensat() and futimens() @@ -241,17 +219,6 @@ typedef struct FileAttrib_t size_t size; // file size mode_t mode; // file mode - - #else - time_t mtime; // time of last content modification - time_t ctime; // time of file creation or last status change - time_t atime; // last ascces time - time_t itime; // insertion time (special time for archives) - - size_t size; // file size - mode_t mode; // file mode - #endif - } FileAttrib_t; @@ -262,8 +229,8 @@ FileAttrib_t * ClearFileAttrib FileAttrib_t * dest // NULL or destination attribute ); -static inline FileAttrib_t * ZeroFileAttrib ( FileAttrib_t * dest ) - { DASSERT(dest); memset(dest,0,sizeof(*dest)); return dest; } +static inline void ZeroFileAttrib ( FileAttrib_t * dest ) + { DASSERT(dest); memset(dest,0,sizeof(*dest)); } FileAttrib_t * TouchFileAttrib ( diff --git a/project/dclib/dclib-numeric.c b/project/dclib/dclib-numeric.c index 8be5cf6..138053d 100644 --- a/project/dclib/dclib-numeric.c +++ b/project/dclib/dclib-numeric.c @@ -1950,6 +1950,7 @@ mem_t EncodeByModeMem s64 timezone_adjust_sec = -1; s64 timezone_adjust_usec = -1; +s64 timezone_adjust_nsec = -1; int timezone_adjust_isdst = -1; /////////////////////////////////////////////////////////////////////////////// @@ -1959,10 +1960,11 @@ void SetupTimezone ( bool force ) if ( force || timezone_adjust_sec == -1 ) { timezone_adjust_sec = GetTimezoneAdjust(GetTimeSec(false)); - timezone_adjust_usec = 1000000ll * timezone_adjust_sec; - TRACE("TZ: %s,%s, %ld, %d => %lld %lld\n", + timezone_adjust_usec = USEC_PER_SEC * timezone_adjust_sec; + timezone_adjust_nsec = NSEC_PER_SEC * timezone_adjust_sec; + TRACE("TZ: %s,%s, %ld, %d => %lld %lld %lld\n", tzname[0], tzname[1], timezone, daylight, - timezone_adjust_sec, timezone_adjust_usec ); + timezone_adjust_sec, timezone_adjust_usec, timezone_adjust_nsec ); } } @@ -1993,41 +1995,76 @@ int GetTimezoneAdjust ( time_t tim ) /////////////////////////////////////////////////////////////////////////////// -struct timeval GetTimeOfDay ( bool localtime ) +static u_sec_t AdjustLocalTime ( u_sec_t sec ) { static uint last_hour = 0; + const uint hour = sec / 3600; + if ( last_hour != hour ) + { + last_hour = hour; + SetupTimezone(true); + } + return sec - timezone_adjust_sec; +} + +//----------------------------------------------------------------------------- + +struct timeval GetTimeOfDay ( bool localtime ) +{ struct timeval tval; gettimeofday(&tval,NULL); if (localtime) + tval.tv_sec = AdjustLocalTime(tval.tv_sec); + return tval; +} + +//----------------------------------------------------------------------------- + +struct timespec GetClockTime ( bool localtime ) +{ + struct timespec ts; + + #if HAVE_CLOCK_GETTIME + if (!clock_gettime(CLOCK_REALTIME,&ts)) { - const uint hour = tval.tv_sec / 3600; - if ( last_hour != hour ) - { - last_hour = hour; - SetupTimezone(true); - } - tval.tv_sec -= timezone_adjust_sec; + if (localtime) + ts.tv_sec = AdjustLocalTime(ts.tv_sec); + return ts; } - return tval; + #endif + + // fall back + struct timeval tval = GetTimeOfDay(localtime); + ts.tv_sec = tval.tv_sec; + ts.tv_nsec = tval.tv_usec * NSEC_PER_USEC; + return ts; } /////////////////////////////////////////////////////////////////////////////// DayTime_t GetDayTime ( bool localtime ) { - struct timeval tval = GetTimeOfDay(localtime); div_t d; - DayTime_t dt; - dt.time = tval.tv_sec; - d = div(tval.tv_sec,86400); + + #if HAVE_CLOCK_GETTIME + struct timespec tim = GetClockTime(localtime); + dt.usec = tim.tv_nsec / NSEC_PER_USEC; + dt.nsec = tim.tv_nsec; + #else + struct timeval tim = GetTimeOfDay(localtime); + dt.usec = tim.tv_usec; + dt.nsec = tim.tv_usec * NSEC_PER_USEC; + #endif + + dt.time = tim.tv_sec; + d = div(tim.tv_sec,86400); dt.day = d.quot; d = div(d.rem,3600); dt.hour = d.quot; d = div(d.rem,60); dt.min = d.quot; dt.sec = d.rem; - dt.usec = tval.tv_usec; return dt; } @@ -2045,7 +2082,7 @@ u_sec_t GetTimeSec ( bool localtime ) u_msec_t GetTimeMSec ( bool localtime ) { struct timeval tval = GetTimeOfDay(localtime); - return (u64)(tval.tv_sec) * 1000ll + tval.tv_usec/1000; + return (u_msec_t)(tval.tv_sec) * MSEC_PER_SEC + tval.tv_usec/USEC_PER_MSEC; } /////////////////////////////////////////////////////////////////////////////// @@ -2053,7 +2090,15 @@ u_msec_t GetTimeMSec ( bool localtime ) u_usec_t GetTimeUSec ( bool localtime ) { struct timeval tval = GetTimeOfDay(localtime); - return (u64)(tval.tv_sec) * 1000000ll + tval.tv_usec; + return (u_usec_t)(tval.tv_sec) * USEC_PER_SEC + tval.tv_usec; +} + +/////////////////////////////////////////////////////////////////////////////// + +u_nsec_t GetTimeNSec ( bool localtime ) +{ + struct timespec ts = GetClockTime(localtime); + return (u_nsec_t)(ts.tv_sec) * NSEC_PER_SEC + ts.tv_nsec; } // @@ -2067,24 +2112,36 @@ static time_t time_base = 0; u_msec_t GetTimerMSec() { - struct timeval tval; - gettimeofday(&tval,NULL); + struct timeval tv; + gettimeofday(&tv,NULL); if (!time_base) - time_base = tval.tv_sec; + time_base = tv.tv_sec; - return (u_msec_t)( tval.tv_sec - time_base ) * 1000 + tval.tv_usec/1000; + return (u_msec_t)( tv.tv_sec - time_base ) * MSEC_PER_SEC + + tv.tv_usec/USEC_PER_MSEC; } /////////////////////////////////////////////////////////////////////////////// u_usec_t GetTimerUSec() { - struct timeval tval; - gettimeofday(&tval,NULL); + struct timeval tv; + gettimeofday(&tv,NULL); if (!time_base) - time_base = tval.tv_sec; + time_base = tv.tv_sec; - return (u_usec_t)( tval.tv_sec - time_base ) * 1000000 + tval.tv_usec; + return (u_usec_t)( tv.tv_sec - time_base ) * USEC_PER_SEC + tv.tv_usec; +} + +/////////////////////////////////////////////////////////////////////////////// + +u_usec_t GetTimerNSec() +{ + struct timespec ts = GetClockTime(false); + if (!time_base) + time_base = ts.tv_sec; + + return (u_usec_t)( ts.tv_sec - time_base ) * NSEC_PER_SEC + ts.tv_nsec; } /////////////////////////////////////////////////////////////////////////////// @@ -2128,14 +2185,14 @@ ccp PrintTimeByFormatUTC /////////////////////////////////////////////////////////////////////////////// -ccp PrintUsecByFormat +ccp PrintNSecByFormat ( // returns temporary buffer by GetCircBuf(); ccp format, // format string for strftime() - // 1-6 '@' in row replaced by digits of 'usec' + // 1-9 '@' in row replaced by digits of 'nsec' time_t tim, // seconds since epoch - uint usec // micro second of second + uint nsec // nanosecond of second ) { char buf[100]; @@ -2144,9 +2201,9 @@ ccp PrintUsecByFormat char *at = strchr(buf,'@'); if (at) { - char ubuf[8]; - snprintf(ubuf,sizeof(ubuf),"%06u",usec); - ccp src = ubuf; + char nbuf[10]; + snprintf(nbuf,sizeof(nbuf),"%09u",nsec); + ccp src = nbuf; while ( *at == '@' && *src ) *at++ = *src++; } @@ -2156,14 +2213,14 @@ ccp PrintUsecByFormat //----------------------------------------------------------------------------- -ccp PrintUsecByFormatUTC +ccp PrintNSecByFormatUTC ( // returns temporary buffer by GetCircBuf(); ccp format, // format string for strftime() - // 1-6 '@' in row replaced by digits of 'usec' + // 1-9 '@' in row replaced by digits of 'nsec' time_t tim, // seconds since epoch - uint usec // micro second of second + uint nsec // nanosecond of second ) { char buf[100]; @@ -2172,9 +2229,9 @@ ccp PrintUsecByFormatUTC char *at = strchr(buf,'@'); if (at) { - char ubuf[8]; - snprintf(ubuf,sizeof(ubuf),"%06u",usec); - ccp src = ubuf; + char nbuf[10]; + snprintf(nbuf,sizeof(nbuf),"%09u",nsec); + ccp src = nbuf; while ( *at == '@' && *src ) *at++ = *src++; } @@ -2199,7 +2256,7 @@ ccp PrintTimevalByFormat tv = &temp; } - return PrintUsecByFormat(format,tv->tv_sec,tv->tv_usec); + return PrintUSecByFormat(format,tv->tv_sec,tv->tv_usec); } //----------------------------------------------------------------------------- @@ -2219,7 +2276,47 @@ ccp PrintTimevalByFormatUTC tv = &temp; } - return PrintUsecByFormatUTC(format,tv->tv_sec,tv->tv_usec); + return PrintUSecByFormatUTC(format,tv->tv_sec,tv->tv_usec); +} + +/////////////////////////////////////////////////////////////////////////////// + +ccp PrintTimespecByFormat +( + // returns temporary buffer by GetCircBuf(); + + ccp format, // format string for strftime() + const struct timespec *ts // time to print, if NULL use GetClockTime(false) +) +{ + struct timespec temp; + if (!ts) + { + temp = GetClockTime(true); + ts = &temp; + } + + return PrintNSecByFormat(format,ts->tv_sec,ts->tv_nsec); +} + +//----------------------------------------------------------------------------- + +ccp PrintTimespecByFormatUTC +( + // returns temporary buffer by GetCircBuf(); + + ccp format, // format string for strftime() + const struct timespec *ts // time to print, if NULL use GetClockTime(false) +) +{ + struct timespec temp; + if (!ts) + { + temp = GetClockTime(false); + ts = &temp; + } + + return PrintNSecByFormatUTC(format,ts->tv_sec,ts->tv_nsec); } /////////////////////////////////////////////////////////////////////////////// @@ -2256,13 +2353,13 @@ ccp PrintTimeMSec if (!buf) buf = GetCircBuf( buf_size = 24 ); - time_t time = msec / 1000; + time_t time = msec / MSEC_PER_SEC; struct tm *tm = localtime(&time); uint len = strftime(buf,buf_size,"%F %T",tm); if ( fraction && len + 4 < buf_size ) { - len += snprintf(buf+len, buf_size-len, ".%03llu", msec % 1000 ); + len += snprintf(buf+len, buf_size-len, ".%03llu", msec % MSEC_PER_SEC ); const uint pos = len - 3 + ( fraction < 3 ? fraction : 3 ); if ( pos < buf_size ) buf[pos] = 0; @@ -2285,13 +2382,13 @@ ccp PrintTimeUSec if (!buf) buf = GetCircBuf( buf_size = 28 ); - time_t time = usec / 1000000; + time_t time = usec / USEC_PER_SEC; struct tm *tm = localtime(&time); uint len = strftime(buf,buf_size,"%F %T",tm); if ( fraction && len + 7 < buf_size ) { - len += snprintf(buf+len, buf_size-len, ".%06llu", usec % 1000000 ); + len += snprintf(buf+len, buf_size-len, ".%06llu", usec % USEC_PER_SEC ); const uint pos = len - 6 + ( fraction < 6 ? fraction : 6 ); if ( pos < buf_size ) buf[pos] = 0; @@ -2301,6 +2398,35 @@ ccp PrintTimeUSec } /////////////////////////////////////////////////////////////////////////////// + +ccp PrintTimeNSec +( + char * buf, // result buffer (>26 bytes are good) + // If NULL, a local circulary static buffer is used + size_t buf_size, // size of 'buf', ignored if buf==NULL + u_nsec_t nsec, // nanoseconds to print + uint fraction // number of digits (0-9) to print as fraction +) +{ + if (!buf) + buf = GetCircBuf( buf_size = 32 ); + + time_t time = nsec / NSEC_PER_SEC; + struct tm *tm = localtime(&time); + uint len = strftime(buf,buf_size,"%F %T",tm); + + if ( fraction && len + 10 < buf_size ) + { + len += snprintf(buf+len, buf_size-len, ".%09llu", nsec % NSEC_PER_SEC ); + const uint pos = len - 9 + ( fraction < 9 ? fraction : 9 ); + if ( pos < buf_size ) + buf[pos] = 0; + } + + return buf; +} + +/////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// ccp PrintTimerMSec @@ -2345,7 +2471,7 @@ ccp PrintTimerUSec // If NULL, a local circulary static buffer is used size_t buf_size, // size of 'buf', ignored if buf==NULL s_usec_t usec, // microseconds to print - uint fraction // number of digits (0-3) to print as fraction + uint fraction // number of digits (0-6) to print as fraction ) { if ( !buf || buf_size < 4 ) @@ -2355,12 +2481,12 @@ ccp PrintTimerUSec if (minus) usec = -usec; - u32 sec = (u64)usec / 1000000; + u32 sec = usec / USEC_PER_SEC; if (fraction) { const uint len = snprintf(buf+1,buf_size-1,"%02d:%02d:%02d.%06lld", - sec/3600, sec/60%60, sec%60, (u64)usec%1000000 ); + sec/3600, sec/60%60, sec%60, (u64)usec%USEC_PER_SEC ); if ( len > 6 && fraction < 6 ) { const uint pos = len - 6 + fraction; @@ -2383,7 +2509,54 @@ ccp PrintTimerUSec } /////////////////////////////////////////////////////////////////////////////// + +ccp PrintTimerNSec +( + char * buf, // result buffer (>16 bytes are good) + // If NULL, a local circulary static buffer is used + size_t buf_size, // size of 'buf', ignored if buf==NULL + s_nsec_t nsec, // nanoseconds to print + uint fraction // number of digits (0-9) to print as fraction +) +{ + if ( !buf || buf_size < 4 ) + buf = GetCircBuf( buf_size = 24 ); + + const bool minus = nsec < 0; + if (minus) + nsec = -nsec; + + u32 sec = nsec / NSEC_PER_SEC; + + if (fraction) + { + const uint len = snprintf(buf+1,buf_size-1,"%02d:%02d:%02d.%09lld", + sec/3600, sec/60%60, sec%60, (u64)nsec%NSEC_PER_SEC ); + if ( len > 9 && fraction < 9 ) + { + const uint pos = len - 9 + fraction; + if ( pos < buf_size ) + buf[pos] = 0; + } + } + else + snprintf(buf+1,buf_size-1,"%02d:%02d:%02d", + sec/3600, sec/60%60, sec%60 ); + + char *ptr = buf+1; + while ( *ptr == '0' || *ptr == ':' ) + ptr++; + if ( *ptr == '.' ) + ptr--; + if (minus) + *--ptr = '-'; + return ptr; +} + /////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +// [[nsec]] -> PrintTimer3U(), PrintTimer3N() ccp PrintTimer3 ( @@ -2440,6 +2613,8 @@ ccp PrintTimer3 /////////////////////////////////////////////////////////////////////////////// +// [[nsec]] -> PrintTimer4U(), PrintTimer4N() + ccp PrintTimer4 ( char * buf, // result buffer (>4 bytes) @@ -2495,6 +2670,8 @@ ccp PrintTimer4 /////////////////////////////////////////////////////////////////////////////// +// [[nsec]] -> PrintTimer6U(), PrintTimer6N() + ccp PrintTimer6 ( char * buf, // result buffer (>6 bytes) @@ -2635,6 +2812,8 @@ ccp PrintTimer6 /////////////////////////////////////////////////////////////////////////////// +// [[nsec]] -> PrintTimer4Us(), PrintTimer4Ns() + ccp PrintTimerUSec4s ( char * buf, // result buffer (>4 bytes) @@ -2673,6 +2852,8 @@ ccp PrintTimerUSec4s /////////////////////////////////////////////////////////////////////////////// +// [[nsec]] -> PrintTimer7Us(), PrintTimer7Ns() + ccp PrintTimerUSec7s ( char * buf, // result buffer (>7 bytes) @@ -2709,45 +2890,18 @@ ccp PrintTimerUSec7s return buf; } -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -#if 0 -u64 GetXTime ( xtime_t * xtime ) -{ - struct timeval tval; - gettimeofday(&tval,0); - if (!time_base) - time_base = tval.tv_sec; - if (!rel_usec_base) - rel_usec_base = (u64)( tval.tv_sec - time_base ) * 1000000 + tval.tv_usec; - - const ull total_usec = 1000000ull * tval.tv_sec + tval.tv_usec; - - if (xtime) - { - xtime->time = tval.tv_sec; - xtime->usec = tval.tv_usec; - xtime->total_usec = total_usec; - xtime->rel_usec = total_usec - rel_usec_base; - } - return total_usec; -} -#endif - // /////////////////////////////////////////////////////////////////////////////// /////////////// scan date & time /////////////// /////////////////////////////////////////////////////////////////////////////// -char * ScanInterval +char * ScanIntervalTS ( - time_t *res_time, // not NULL: store seconds - u32 *res_usec, // not NULL: store micro seconds of second + struct timespec *res_ts, // not NULL: store result here ccp source // source text ) { - uint days = 0, sec = 0, usec = 0; + uint days = 0, sec = 0, nsec = 0; bool day_possible = true; uint colon_count = 0; char *src = source ? (char*)source : ""; @@ -2757,7 +2911,7 @@ char * ScanInterval for(;;) { - if ( *src < '0' || *src >='9' ) + if ( *src < '0' || *src >= '9' ) break; ulong num = strtoul(src,&src,10); if ( *src == 'd' && day_possible ) @@ -2779,11 +2933,11 @@ char * ScanInterval { src++; uint i; - for ( i = 0; i < 6; i++ ) + for ( i = 0; i < 9; i++ ) { - usec *= 10; + nsec *= 10; if ( *src >= '0' && *src <= '9' ) - usec += *src++ - '0'; + nsec += *src++ - '0'; } while ( *src >= '0' && *src <= '9' ) src++; @@ -2793,32 +2947,87 @@ char * ScanInterval } } + if (res_ts) + { + res_ts->tv_sec = days * SEC_PER_DAY + sec; + res_ts->tv_nsec = nsec; + } + + return src; +} + +/////////////////////////////////////////////////////////////////////////////// + +char * ScanIntervalUSec +( + u_usec_t *res_usec, // not NULL: store total microseconds + ccp source // source text +) +{ + struct timespec ts; + char *res = ScanIntervalTS(&ts,source); + + if (res_usec) + *res_usec = ts.tv_sec * USEC_PER_SEC + ts.tv_nsec / NSEC_PER_USEC; + return res; +} + +/////////////////////////////////////////////////////////////////////////////// + +char * ScanIntervalNSec +( + u_nsec_t *res_nsec, // not NULL: store total nanoseconds + ccp source // source text +) +{ + struct timespec ts; + char *res = ScanIntervalTS(&ts,source); + + if (res_nsec) + *res_nsec = ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec; + return res; +} + +/////////////////////////////////////////////////////////////////////////////// + +char * ScanInterval +( + time_t *res_time, // not NULL: store seconds + u32 *res_usec, // not NULL: store microseconds of second + ccp source // source text +) +{ + struct timespec ts; + char *res = ScanIntervalTS(&ts,source); + if (res_time) - *res_time = days * 86400 + sec; + *res_time = ts.tv_sec; if (res_usec) - *res_usec = usec; - return src; + *res_usec = ts.tv_nsec / NSEC_PER_USEC; + + return res; } /////////////////////////////////////////////////////////////////////////////// char * ScanInterval64 ( - u64 *res_usec, // not NULL: store total micro seconds + u64 *res_usec, // not NULL: store total microseconds ccp source // source text ) { - time_t time; - u32 usec; - char *src = ScanInterval(&time,&usec,source); + u_usec_t usec; + char *res = ScanIntervalUSec(&usec,source); if (res_usec) - *res_usec = time * 1000000ull + usec; - return src; + *res_usec = usec; + return res; } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// +// [[nsec]] + char * ScanDateTime ( time_t *res_time, // not NULL: store seconds here @@ -2938,9 +3147,11 @@ char * ScanDateTime /////////////////////////////////////////////////////////////////////////////// +// [[nsec]] + char * ScanDateTime64 ( - u64 *res_usec, // not NULL: store total micro seconds + u64 *res_usec, // not NULL: store total microseconds ccp source, // source text bool allow_delta // true: allow +|- interval ) diff --git a/project/dclib/dclib-system.h b/project/dclib/dclib-system.h index 64a021d..e5a7380 100644 --- a/project/dclib/dclib-system.h +++ b/project/dclib/dclib-system.h @@ -92,7 +92,8 @@ static inline void dclibPrintSystem ( FILE * f ) "SYSTEM_LINUX\t:= 1\n" #endif ,SYSTEM - ,SYSTEMID ); + ,SYSTEMID + ); } /////////////////////////////////////////////////////////////////////////////// |
