mirror of
https://github.com/systemd/systemd.git
synced 2024-10-27 18:55:40 +03:00
calendarspec: sub-second support, v3
This commit is contained in:
parent
92939fc4c0
commit
436dd70f53
@ -25,6 +25,7 @@
|
||||
#include "alloc-util.h"
|
||||
#include "calendarspec.h"
|
||||
#include "fileio.h"
|
||||
#include "parse-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
#define BITS_WEEKDAYS 127
|
||||
@ -49,7 +50,7 @@ void calendar_spec_free(CalendarSpec *c) {
|
||||
free_chain(c->day);
|
||||
free_chain(c->hour);
|
||||
free_chain(c->minute);
|
||||
free_chain(c->second);
|
||||
free_chain(c->microsecond);
|
||||
|
||||
free(c);
|
||||
}
|
||||
@ -135,7 +136,7 @@ int calendar_spec_normalize(CalendarSpec *c) {
|
||||
sort_chain(&c->day);
|
||||
sort_chain(&c->hour);
|
||||
sort_chain(&c->minute);
|
||||
sort_chain(&c->second);
|
||||
sort_chain(&c->microsecond);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -177,7 +178,7 @@ _pure_ bool calendar_spec_valid(CalendarSpec *c) {
|
||||
if (!chain_valid(c->minute, 0, 59))
|
||||
return false;
|
||||
|
||||
if (!chain_valid(c->second, 0, 59))
|
||||
if (!chain_valid(c->microsecond, 0, 60*USEC_PER_SEC-1))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -232,7 +233,7 @@ static void format_weekdays(FILE *f, const CalendarSpec *c) {
|
||||
}
|
||||
}
|
||||
|
||||
static void format_chain(FILE *f, int space, const CalendarComponent *c) {
|
||||
static void format_chain(FILE *f, int space, const CalendarComponent *c, bool usec) {
|
||||
assert(f);
|
||||
|
||||
if (!c) {
|
||||
@ -241,14 +242,25 @@ static void format_chain(FILE *f, int space, const CalendarComponent *c) {
|
||||
}
|
||||
|
||||
assert(c->value >= 0);
|
||||
if (!usec)
|
||||
fprintf(f, "%0*i", space, c->value);
|
||||
else if (c->value % USEC_PER_SEC == 0)
|
||||
fprintf(f, "%0*i", space, (int) (c->value / USEC_PER_SEC));
|
||||
else
|
||||
fprintf(f, "%0*i.%06i", space, (int) (c->value / USEC_PER_SEC), (int) (c->value % USEC_PER_SEC));
|
||||
|
||||
if (c->repeat > 0)
|
||||
if (c->repeat > 0) {
|
||||
if (!usec)
|
||||
fprintf(f, "/%i", c->repeat);
|
||||
else if (c->repeat % USEC_PER_SEC == 0)
|
||||
fprintf(f, "/%i", (int) (c->repeat / USEC_PER_SEC));
|
||||
else
|
||||
fprintf(f, "/%i.%06i", (int) (c->repeat / USEC_PER_SEC), (int) (c->repeat % USEC_PER_SEC));
|
||||
}
|
||||
|
||||
if (c->next) {
|
||||
fputc(',', f);
|
||||
format_chain(f, space, c->next);
|
||||
format_chain(f, space, c->next, usec);
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,17 +282,17 @@ int calendar_spec_to_string(const CalendarSpec *c, char **p) {
|
||||
fputc(' ', f);
|
||||
}
|
||||
|
||||
format_chain(f, 4, c->year);
|
||||
format_chain(f, 4, c->year, false);
|
||||
fputc('-', f);
|
||||
format_chain(f, 2, c->month);
|
||||
format_chain(f, 2, c->month, false);
|
||||
fputc('-', f);
|
||||
format_chain(f, 2, c->day);
|
||||
format_chain(f, 2, c->day, false);
|
||||
fputc(' ', f);
|
||||
format_chain(f, 2, c->hour);
|
||||
format_chain(f, 2, c->hour, false);
|
||||
fputc(':', f);
|
||||
format_chain(f, 2, c->minute);
|
||||
format_chain(f, 2, c->minute, false);
|
||||
fputc(':', f);
|
||||
format_chain(f, 2, c->second);
|
||||
format_chain(f, 2, c->microsecond, true);
|
||||
|
||||
if (c->utc)
|
||||
fputs(" UTC", f);
|
||||
@ -391,35 +403,70 @@ static int parse_weekdays(const char **p, CalendarSpec *c) {
|
||||
}
|
||||
}
|
||||
|
||||
static int prepend_component(const char **p, CalendarComponent **c) {
|
||||
static int parse_component_decimal(const char **p, bool usec, unsigned long *res) {
|
||||
unsigned long value;
|
||||
const char *e = NULL;
|
||||
char *ee = NULL;
|
||||
int r;
|
||||
|
||||
errno = 0;
|
||||
value = strtoul(*p, &ee, 10);
|
||||
if (errno > 0)
|
||||
return -errno;
|
||||
if (ee == *p)
|
||||
return -EINVAL;
|
||||
if ((unsigned long) (int) value != value)
|
||||
return -ERANGE;
|
||||
e = ee;
|
||||
|
||||
if (usec) {
|
||||
if (value * USEC_PER_SEC / USEC_PER_SEC != value)
|
||||
return -ERANGE;
|
||||
|
||||
value *= USEC_PER_SEC;
|
||||
if (*e == '.') {
|
||||
unsigned add;
|
||||
|
||||
e++;
|
||||
r = parse_fractional_part_u(&e, 6, &add);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (add + value < value)
|
||||
return -ERANGE;
|
||||
value += add;
|
||||
}
|
||||
}
|
||||
|
||||
*p = e;
|
||||
*res = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int prepend_component(const char **p, bool usec, CalendarComponent **c) {
|
||||
unsigned long value, repeat = 0;
|
||||
char *e = NULL, *ee = NULL;
|
||||
CalendarComponent *cc;
|
||||
int r;
|
||||
const char *e;
|
||||
|
||||
assert(p);
|
||||
assert(c);
|
||||
|
||||
errno = 0;
|
||||
value = strtoul(*p, &e, 10);
|
||||
if (errno > 0)
|
||||
return -errno;
|
||||
if (e == *p)
|
||||
return -EINVAL;
|
||||
if ((unsigned long) (int) value != value)
|
||||
return -ERANGE;
|
||||
e = *p;
|
||||
|
||||
r = parse_component_decimal(&e, usec, &value);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (*e == '/') {
|
||||
repeat = strtoul(e+1, &ee, 10);
|
||||
if (errno > 0)
|
||||
return -errno;
|
||||
if (ee == e+1)
|
||||
return -EINVAL;
|
||||
if ((unsigned long) (int) repeat != repeat)
|
||||
return -ERANGE;
|
||||
if (repeat <= 0)
|
||||
return -ERANGE;
|
||||
e++;
|
||||
r = parse_component_decimal(&e, usec, &repeat);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
e = ee;
|
||||
if (repeat == 0)
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
if (*e != 0 && *e != ' ' && *e != ',' && *e != '-' && *e != ':')
|
||||
@ -438,39 +485,12 @@ static int prepend_component(const char **p, CalendarComponent **c) {
|
||||
|
||||
if (*e ==',') {
|
||||
*p += 1;
|
||||
return prepend_component(p, c);
|
||||
return prepend_component(p, usec, c);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_chain(const char **p, CalendarComponent **c) {
|
||||
const char *t;
|
||||
CalendarComponent *cc = NULL;
|
||||
int r;
|
||||
|
||||
assert(p);
|
||||
assert(c);
|
||||
|
||||
t = *p;
|
||||
|
||||
if (t[0] == '*') {
|
||||
*p = t + 1;
|
||||
*c = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = prepend_component(&t, &cc);
|
||||
if (r < 0) {
|
||||
free_chain(cc);
|
||||
return r;
|
||||
}
|
||||
|
||||
*p = t;
|
||||
*c = cc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int const_chain(int value, CalendarComponent **c) {
|
||||
CalendarComponent *cc = NULL;
|
||||
|
||||
@ -489,6 +509,40 @@ static int const_chain(int value, CalendarComponent **c) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_chain(const char **p, bool usec, CalendarComponent **c) {
|
||||
const char *t;
|
||||
CalendarComponent *cc = NULL;
|
||||
int r;
|
||||
|
||||
assert(p);
|
||||
assert(c);
|
||||
|
||||
t = *p;
|
||||
|
||||
if (t[0] == '*') {
|
||||
if (usec) {
|
||||
r = const_chain(0, c);
|
||||
if (r < 0)
|
||||
return r;
|
||||
(*c)->repeat = USEC_PER_SEC;
|
||||
} else
|
||||
*c = NULL;
|
||||
|
||||
*p = t + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = prepend_component(&t, usec, &cc);
|
||||
if (r < 0) {
|
||||
free_chain(cc);
|
||||
return r;
|
||||
}
|
||||
|
||||
*p = t;
|
||||
*c = cc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_date(const char **p, CalendarSpec *c) {
|
||||
const char *t;
|
||||
int r;
|
||||
@ -503,7 +557,7 @@ static int parse_date(const char **p, CalendarSpec *c) {
|
||||
if (*t == 0)
|
||||
return 0;
|
||||
|
||||
r = parse_chain(&t, &first);
|
||||
r = parse_chain(&t, false, &first);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -519,7 +573,7 @@ static int parse_date(const char **p, CalendarSpec *c) {
|
||||
}
|
||||
|
||||
t++;
|
||||
r = parse_chain(&t, &second);
|
||||
r = parse_chain(&t, false, &second);
|
||||
if (r < 0) {
|
||||
free_chain(first);
|
||||
return r;
|
||||
@ -540,7 +594,7 @@ static int parse_date(const char **p, CalendarSpec *c) {
|
||||
}
|
||||
|
||||
t++;
|
||||
r = parse_chain(&t, &third);
|
||||
r = parse_chain(&t, false, &third);
|
||||
if (r < 0) {
|
||||
free_chain(first);
|
||||
free_chain(second);
|
||||
@ -582,7 +636,7 @@ static int parse_calendar_time(const char **p, CalendarSpec *c) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = parse_chain(&t, &h);
|
||||
r = parse_chain(&t, false, &h);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
@ -592,7 +646,7 @@ static int parse_calendar_time(const char **p, CalendarSpec *c) {
|
||||
}
|
||||
|
||||
t++;
|
||||
r = parse_chain(&t, &m);
|
||||
r = parse_chain(&t, false, &m);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
@ -610,7 +664,7 @@ static int parse_calendar_time(const char **p, CalendarSpec *c) {
|
||||
}
|
||||
|
||||
t++;
|
||||
r = parse_chain(&t, &s);
|
||||
r = parse_chain(&t, true, &s);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
@ -639,7 +693,8 @@ finish:
|
||||
*p = t;
|
||||
c->hour = h;
|
||||
c->minute = m;
|
||||
c->second = s;
|
||||
c->microsecond = s;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
@ -671,7 +726,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
|
||||
}
|
||||
|
||||
if (strcaseeq(p, "minutely")) {
|
||||
r = const_chain(0, &c->second);
|
||||
r = const_chain(0, &c->microsecond);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
@ -679,7 +734,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
|
||||
r = const_chain(0, &c->minute);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
r = const_chain(0, &c->second);
|
||||
r = const_chain(0, &c->microsecond);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
@ -690,7 +745,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
|
||||
r = const_chain(0, &c->minute);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
r = const_chain(0, &c->second);
|
||||
r = const_chain(0, &c->microsecond);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
@ -704,7 +759,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
|
||||
r = const_chain(0, &c->minute);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
r = const_chain(0, &c->second);
|
||||
r = const_chain(0, &c->microsecond);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
@ -724,7 +779,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
|
||||
r = const_chain(0, &c->minute);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
r = const_chain(0, &c->second);
|
||||
r = const_chain(0, &c->microsecond);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
@ -738,7 +793,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
|
||||
r = const_chain(0, &c->minute);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
r = const_chain(0, &c->second);
|
||||
r = const_chain(0, &c->microsecond);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
@ -765,7 +820,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
|
||||
r = const_chain(0, &c->minute);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
r = const_chain(0, &c->second);
|
||||
r = const_chain(0, &c->microsecond);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
@ -789,7 +844,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
|
||||
r = const_chain(0, &c->minute);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
r = const_chain(0, &c->second);
|
||||
r = const_chain(0, &c->microsecond);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
@ -906,14 +961,16 @@ static bool matches_weekday(int weekdays_bits, const struct tm *tm, bool utc) {
|
||||
return (weekdays_bits & (1 << k));
|
||||
}
|
||||
|
||||
static int find_next(const CalendarSpec *spec, struct tm *tm) {
|
||||
static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
|
||||
struct tm c;
|
||||
int tm_usec;
|
||||
int r;
|
||||
|
||||
assert(spec);
|
||||
assert(tm);
|
||||
|
||||
c = *tm;
|
||||
tm_usec = *usec;
|
||||
|
||||
for (;;) {
|
||||
/* Normalize the current date */
|
||||
@ -927,7 +984,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) {
|
||||
if (r > 0) {
|
||||
c.tm_mon = 0;
|
||||
c.tm_mday = 1;
|
||||
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
||||
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
|
||||
}
|
||||
if (r < 0 || tm_out_of_bounds(&c, spec->utc))
|
||||
return r;
|
||||
@ -938,29 +995,29 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) {
|
||||
|
||||
if (r > 0) {
|
||||
c.tm_mday = 1;
|
||||
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
||||
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
|
||||
}
|
||||
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
|
||||
c.tm_year ++;
|
||||
c.tm_mon = 0;
|
||||
c.tm_mday = 1;
|
||||
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
||||
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
r = find_matching_component(spec->day, &c.tm_mday);
|
||||
if (r > 0)
|
||||
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
||||
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
|
||||
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
|
||||
c.tm_mon ++;
|
||||
c.tm_mday = 1;
|
||||
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
||||
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!matches_weekday(spec->weekdays_bits, &c, spec->utc)) {
|
||||
c.tm_mday++;
|
||||
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
||||
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -969,7 +1026,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) {
|
||||
c.tm_min = c.tm_sec = 0;
|
||||
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
|
||||
c.tm_mday ++;
|
||||
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
||||
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -978,19 +1035,23 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) {
|
||||
c.tm_sec = 0;
|
||||
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
|
||||
c.tm_hour ++;
|
||||
c.tm_min = c.tm_sec = 0;
|
||||
c.tm_min = c.tm_sec = tm_usec = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
r = find_matching_component(spec->second, &c.tm_sec);
|
||||
c.tm_sec = c.tm_sec * USEC_PER_SEC + tm_usec;
|
||||
r = find_matching_component(spec->microsecond, &c.tm_sec);
|
||||
tm_usec = c.tm_sec % USEC_PER_SEC;
|
||||
c.tm_sec /= USEC_PER_SEC;
|
||||
|
||||
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
|
||||
c.tm_min ++;
|
||||
c.tm_sec = 0;
|
||||
c.tm_sec = tm_usec = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
*tm = c;
|
||||
*usec = tm_usec;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -999,14 +1060,17 @@ int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next)
|
||||
struct tm tm;
|
||||
time_t t;
|
||||
int r;
|
||||
usec_t tm_usec;
|
||||
|
||||
assert(spec);
|
||||
assert(next);
|
||||
|
||||
t = (time_t) (usec / USEC_PER_SEC) + 1;
|
||||
usec++;
|
||||
t = (time_t) (usec / USEC_PER_SEC);
|
||||
assert_se(localtime_or_gmtime_r(&t, &tm, spec->utc));
|
||||
tm_usec = usec % USEC_PER_SEC;
|
||||
|
||||
r = find_next(spec, &tm);
|
||||
r = find_next(spec, &tm, &tm_usec);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -1014,6 +1078,6 @@ int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next)
|
||||
if (t == (time_t) -1)
|
||||
return -EINVAL;
|
||||
|
||||
*next = (usec_t) t * USEC_PER_SEC;
|
||||
*next = (usec_t) t * USEC_PER_SEC + tm_usec;
|
||||
return 0;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ typedef struct CalendarSpec {
|
||||
|
||||
CalendarComponent *hour;
|
||||
CalendarComponent *minute;
|
||||
CalendarComponent *second;
|
||||
CalendarComponent *microsecond;
|
||||
} CalendarSpec;
|
||||
|
||||
void calendar_spec_free(CalendarSpec *c);
|
||||
|
@ -490,3 +490,39 @@ int safe_atod(const char *s, double *ret_d) {
|
||||
*ret_d = (double) d;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) {
|
||||
size_t i;
|
||||
unsigned val = 0;
|
||||
const char *s;
|
||||
|
||||
s = *p;
|
||||
|
||||
/* accept any number of digits, strtoull is limted to 19 */
|
||||
for(i=0; i < digits; i++,s++) {
|
||||
if (*s < '0' || *s > '9') {
|
||||
if (i == 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* too few digits, pad with 0 */
|
||||
for (; i < digits; i++)
|
||||
val *= 10;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
val *= 10;
|
||||
val += *s - '0';
|
||||
}
|
||||
|
||||
/* maybe round up */
|
||||
if (*s >= '5' && *s <= '9')
|
||||
val++;
|
||||
|
||||
s += strspn(s, DIGITS);
|
||||
|
||||
*p = s;
|
||||
*res = val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -90,3 +90,5 @@ static inline int safe_atoli(const char *s, long int *ret_u) {
|
||||
#endif
|
||||
|
||||
int safe_atod(const char *s, double *ret_d);
|
||||
|
||||
int parse_fractional_part_u(const char **s, size_t digits, unsigned *res);
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
@ -658,29 +659,18 @@ int parse_timestamp(const char *t, usec_t *usec) {
|
||||
|
||||
parse_usec:
|
||||
{
|
||||
char *end;
|
||||
unsigned long long val;
|
||||
size_t l;
|
||||
unsigned add;
|
||||
|
||||
k++;
|
||||
if (*k < '0' || *k > '9')
|
||||
r = parse_fractional_part_u(&k, 6, &add);
|
||||
if (r < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* base 10 instead of base 0, .09 is not base 8 */
|
||||
errno = 0;
|
||||
val = strtoull(k, &end, 10);
|
||||
if (*end || errno)
|
||||
if (*k)
|
||||
return -EINVAL;
|
||||
|
||||
l = end-k;
|
||||
x_usec = add;
|
||||
|
||||
/* val has l digits, make them 6 */
|
||||
for (; l < 6; l++)
|
||||
val *= 10;
|
||||
for (; l > 6; l--)
|
||||
val /= 10;
|
||||
|
||||
x_usec = val;
|
||||
}
|
||||
|
||||
from_tm:
|
||||
|
Loading…
Reference in New Issue
Block a user