aboutsummaryrefslogtreecommitdiff
path: root/project/dclib
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--project/dclib/dclib-basics.h170
-rw-r--r--project/dclib/dclib-file.c146
-rw-r--r--project/dclib/dclib-file.h41
-rw-r--r--project/dclib/dclib-numeric.c395
-rw-r--r--project/dclib/dclib-system.h3
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
+ );
}
///////////////////////////////////////////////////////////////////////////////