summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-08-25 06:02:00 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-08-25 06:02:00 -0700
commite9f0db2c472e4a88a2a250caf559b3100c86fe67 (patch)
tree21a7bdcf7485b9ab8bbafe65078b503191929d83 /lib.c
parentc6fce0478a206a84f678e63ec242047f02ba8547 (diff)
downloadtxr-e9f0db2c472e4a88a2a250caf559b3100c86fe67.tar.gz
txr-e9f0db2c472e4a88a2a250caf559b3100c86fe67.tar.bz2
txr-e9f0db2c472e4a88a2a250caf559b3100c86fe67.zip
Adding time-parse method.
* lib.c (time_parse_s): New symbol variable. (tm_to_time_struct): New static function, based on code moved out of broken_time_struct. (broken_time_struct): Bulk of code replaced with call to tm_to_time_struct. (time_struct_to_tm): New parameter, strict. Indicates whether nils in time struct are converted to zeros, or whether they trigger errors. (time_string_meth): Specify strict conversion of argument time struct to to struct tm when calling time_struct_to_tm. (time_parse_meth): New static function. (time_init): Initialize time_parse_s symbol variable; add time-parse static slot to time struct; initialize slot with new method. * txr.1: Document time-parse method.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c83
1 files changed, 66 insertions, 17 deletions
diff --git a/lib.c b/lib.c
index 9eea4598..61a43c01 100644
--- a/lib.c
+++ b/lib.c
@@ -115,7 +115,7 @@ val list_f, less_f, greater_f;
val prog_string;
-val time_s, time_local_s, time_utc_s, time_string_s;
+val time_s, time_local_s, time_utc_s, time_string_s, time_parse_s;
val year_s, month_s, day_s, hour_s, min_s, sec_s, dst_s;
static val env_list;
@@ -9279,18 +9279,23 @@ static val broken_time_list(struct tm *tms)
nao);
}
+static void tm_to_time_struct(val time_struct, struct tm *ptm)
+{
+ slotset(time_struct, year_s, num(ptm->tm_year + 1900));
+ slotset(time_struct, month_s, num_fast(ptm->tm_mon + 1));
+ slotset(time_struct, day_s, num_fast(ptm->tm_mday));
+ slotset(time_struct, hour_s, num_fast(ptm->tm_hour));
+ slotset(time_struct, min_s, num_fast(ptm->tm_min));
+ slotset(time_struct, sec_s, num_fast(ptm->tm_sec));
+ slotset(time_struct, dst_s, tnil(ptm->tm_isdst));
+}
+
static val broken_time_struct(struct tm *tms)
{
args_decl(args, ARGS_MIN);
val ts = make_struct(time_s, nil, args);
- slotset(ts, year_s, num(tms->tm_year + 1900));
- slotset(ts, month_s, num_fast(tms->tm_mon + 1));
- slotset(ts, day_s, num_fast(tms->tm_mday));
- slotset(ts, hour_s, num_fast(tms->tm_hour));
- slotset(ts, min_s, num_fast(tms->tm_min));
- slotset(ts, sec_s, num_fast(tms->tm_sec));
- slotset(ts, dst_s, tnil(tms->tm_isdst));
+ tm_to_time_struct(ts, tms);
return ts;
}
@@ -9343,12 +9348,13 @@ static void time_fields_to_tm(struct tm *ptm,
val year, val month, val day,
val hour, val min, val sec, val dst)
{
- ptm->tm_year = c_num(year) - 1900;
- ptm->tm_mon = c_num(month) - 1;
- ptm->tm_mday = c_num(day);
- ptm->tm_hour = c_num(hour);
- ptm->tm_min = c_num(min);
- ptm->tm_sec = c_num(sec);
+ uses_or2;
+ ptm->tm_year = c_num(or2(year, zero)) - 1900;
+ ptm->tm_mon = c_num(or2(month, zero)) - 1;
+ ptm->tm_mday = c_num(or2(day, zero));
+ ptm->tm_hour = c_num(or2(hour, zero));
+ ptm->tm_min = c_num(or2(min, zero));
+ ptm->tm_sec = c_num(or2(sec, zero));
if (!dst)
ptm->tm_isdst = 0;
@@ -9358,7 +9364,7 @@ static void time_fields_to_tm(struct tm *ptm,
ptm->tm_isdst = 1;
}
-static void time_struct_to_tm(struct tm *ptm, val time_struct)
+static void time_struct_to_tm(struct tm *ptm, val time_struct, val strict)
{
val year = slot(time_struct, year_s);
val month = slot(time_struct, month_s);
@@ -9367,6 +9373,16 @@ static void time_struct_to_tm(struct tm *ptm, val time_struct)
val min = slot(time_struct, min_s);
val sec = slot(time_struct, sec_s);
val dst = slot(time_struct, dst_s);
+
+ if (!strict) {
+ year = (year ? year : zero);
+ month = (month ? month : zero);
+ day = (day ? day : zero);
+ hour = (hour ? hour : zero);
+ min = (min ? min : zero);
+ sec = (sec ? sec : zero);
+ }
+
time_fields_to_tm(ptm, year, month, day, hour, min, sec, dst);
}
@@ -9485,7 +9501,7 @@ static val time_meth(val utc_p, val time_struct)
static val time_string_meth(val time_struct, val format)
{
struct tm tms = { 0 };
- time_struct_to_tm(&tms, time_struct);
+ time_struct_to_tm(&tms, time_struct, t);
char buffer[512] = "";
char *fmt = utf8_dup_to(c_str(format));
@@ -9497,6 +9513,35 @@ static val time_string_meth(val time_struct, val format)
return string_own(utf8_dup_from(buffer));
}
+#if HAVE_STRPTIME
+
+static val time_parse_meth(val time_struct, val format, val string)
+{
+ struct tm tms = { 0 };
+ time_struct_to_tm(&tms, time_struct, nil);
+ val ret = nil;
+
+ {
+ const wchar_t *w_str = c_str(string);
+ const wchar_t *w_fmt = c_str(format);
+ char *str = utf8_dup_to(w_str);
+ char *fmt = utf8_dup_to(w_fmt);
+ char *ptr = strptime(str, fmt, &tms);
+
+ if (ptr != 0) {
+ tm_to_time_struct(time_struct, &tms);
+ ret = string_utf8(ptr);
+ }
+
+ free(fmt);
+ free(str);
+ }
+
+ return ret;
+}
+
+#endif
+
static void time_init(void)
{
val time_st;
@@ -9505,6 +9550,7 @@ static void time_init(void)
time_local_s = intern(lit("time-local"), user_package);
time_utc_s = intern(lit("time-utc"), user_package);
time_string_s = intern(lit("time-string"), user_package);
+ time_parse_s = intern(lit("time-parse"), user_package);
year_s = intern(lit("year"), user_package);
month_s = intern(lit("month"), user_package);
day_s = intern(lit("day"), user_package);
@@ -9515,7 +9561,7 @@ static void time_init(void)
time_st = make_struct_type(time_s, nil,
list(time_local_s, time_utc_s,
- time_string_s, nao),
+ time_string_s, time_parse_s, nao),
list(year_s, month_s, day_s,
hour_s, min_s, sec_s, dst_s, nao),
nil, nil, nil, nil);
@@ -9523,6 +9569,9 @@ static void time_init(void)
static_slot_set(time_st, time_local_s, func_f1(nil, time_meth));
static_slot_set(time_st, time_utc_s, func_f1(t, time_meth));
static_slot_set(time_st, time_string_s, func_n2(time_string_meth));
+#if HAVE_STRPTIME
+ static_slot_set(time_st, time_parse_s, func_n3(time_parse_meth));
+#endif
}
void init(mem_t *(*oom)(mem_t *, size_t), val *stack_bottom)