@@ -132,18 +132,83 @@ static struct {
132132#define LAYOUT_RFC3339 "2006-01-02T15:04:05-07:00"
133133#define LAYOUT_RFC3339_UTC "2006-01-02T15:04:05Z"
134134
135+ #define LAYOUT_RFC3339NANO "2006-01-02T15:04:05.999999999-07:00"
136+ #define LAYOUT_RFC3339NANO_UTC "2006-01-02T15:04:05.999999999Z"
137+
138+ static size_t slog_timestamp_nanos (
139+ char * restrict s , const size_t maxsize , const uint32_t flags ,
140+ const struct timespec * restrict tp )
141+ {
142+ if (flags & SLOG_FLAG_UTC ) {
143+ if (!STRFTIME_UTC (s , maxsize , & tp -> tv_sec )) {
144+ return 0 ;
145+ }
146+ unsigned char * restrict e =
147+ (unsigned char * )s + sizeof (LAYOUT_RFC3339NANO_UTC );
148+ int ns = (int )tp -> tv_nsec ;
149+ * -- e = '\0' ;
150+ * -- e = 'Z' ;
151+ * -- e = '0' + ns % 10 , ns /= 10 ;
152+ * -- e = '0' + ns % 10 , ns /= 10 ;
153+ * -- e = '0' + ns % 10 , ns /= 10 ;
154+ * -- e = '0' + ns % 10 , ns /= 10 ;
155+ * -- e = '0' + ns % 10 , ns /= 10 ;
156+ * -- e = '0' + ns % 10 , ns /= 10 ;
157+ * -- e = '0' + ns % 10 , ns /= 10 ;
158+ * -- e = '0' + ns % 10 , ns /= 10 ;
159+ * -- e = '0' + ns % 10 ;
160+ * -- e = '.' ;
161+ return STRLEN (LAYOUT_RFC3339NANO_UTC );
162+ }
163+
164+ if (!STRFTIME (s , maxsize , & tp -> tv_sec )) {
165+ return 0 ;
166+ }
167+ const unsigned char * restrict tz =
168+ (unsigned char * )s + STRLEN (LAYOUT_C );
169+ unsigned char * restrict e =
170+ (unsigned char * )s + sizeof (LAYOUT_RFC3339NANO );
171+ * -- e = '\0' ;
172+ * -- e = * -- tz ;
173+ * -- e = * -- tz ;
174+ * -- e = ':' ;
175+ * -- e = * -- tz ;
176+ * -- e = * -- tz ;
177+ * -- e = * -- tz ;
178+ int ns = (int )tp -> tv_nsec ;
179+ * -- e = '0' + ns % 10 , ns /= 10 ;
180+ * -- e = '0' + ns % 10 , ns /= 10 ;
181+ * -- e = '0' + ns % 10 , ns /= 10 ;
182+ * -- e = '0' + ns % 10 , ns /= 10 ;
183+ * -- e = '0' + ns % 10 , ns /= 10 ;
184+ * -- e = '0' + ns % 10 , ns /= 10 ;
185+ * -- e = '0' + ns % 10 , ns /= 10 ;
186+ * -- e = '0' + ns % 10 , ns /= 10 ;
187+ * -- e = '0' + ns % 10 ;
188+ * -- e = '.' ;
189+ return STRLEN (LAYOUT_RFC3339NANO );
190+ }
191+
135192/* a fixed-length layout conforming to both ISO 8601 and RFC 3339 */
136- static size_t slog_timestamp (
137- char * restrict s , const size_t maxsize , const time_t * restrict t ,
138- const uint32_t flags )
193+ static size_t
194+ slog_timestamp (char * restrict s , const size_t maxsize , const uint32_t flags )
139195{
196+ if (flags & SLOG_FLAG_NANOS ) {
197+ struct timespec ts ;
198+ if (timespec_get (& ts , TIME_UTC ) == TIME_UTC ) {
199+ return slog_timestamp_nanos (s , maxsize , flags , & ts );
200+ }
201+ }
202+
203+ time_t now ;
204+ (void )time (& now );
140205 if (flags & SLOG_FLAG_UTC ) {
141- if (!STRFTIME_UTC (s , maxsize , t )) {
206+ if (!STRFTIME_UTC (s , maxsize , & now )) {
142207 return 0 ;
143208 }
144209 return STRLEN (LAYOUT_RFC3339_UTC );
145210 }
146- if (!STRFTIME (s , maxsize , t )) {
211+ if (!STRFTIME (s , maxsize , & now )) {
147212 return 0 ;
148213 }
149214 const char * restrict tz = s + STRLEN (LAYOUT_C );
@@ -157,11 +222,9 @@ static size_t slog_timestamp(
157222
158223#define BUF_APPENDTS (buf , flags ) \
159224 do { \
160- time_t now; \
161- (void)time(&now); \
162225 ((buf).len += slog_timestamp( \
163226 (char *)(buf).data + (buf).len, \
164- (buf).cap - (buf).len, &now, (flags))); \
227+ (buf).cap - (buf).len, (flags))); \
165228 } while (0)
166229
167230static const char * slog_filename (const char * restrict file )
0 commit comments