:- module time.
:- use_module builtin, exception, int, io, private_builtin, std_util.
:- type (time:time_t) == int.
:- pragma foreign_import_module("C", time).
:- pred time:c_clocks_per_sec(int).
:- mode time:c_clocks_per_sec((builtin:out)) is det.
:- pred time:c_difftime(int, int, float).
:- mode time:c_difftime((builtin:in), (builtin:in), (builtin:out)) is det.
:- pred time:c_localtime(int, int, int, int, int, int, int, int, int, int).
:- mode time:c_localtime((builtin:in), (builtin:out), (builtin:out), (builtin:out), (builtin:out), (builtin:out), (builtin:out), (builtin:out), (builtin:out), (builtin:out)) is det.
:- pred time:c_gmtime(int, int, int, int, int, int, int, int, int, int).
:- mode time:c_gmtime((builtin:in), (builtin:out), (builtin:out), (builtin:out), (builtin:out), (builtin:out), (builtin:out), (builtin:out), (builtin:out), (builtin:out)) is det.
:- func time:int_to_maybe_dst(int) = (std_util:maybe((time:dst))).
:- mode time:int_to_maybe_dst((builtin:in)) = (builtin:out) is det.
:- pred time:c_mktime(int, int, int, int, int, int, int, int, int, int).
:- mode time:c_mktime((builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:out)) is det.
:- func time:maybe_dst_to_int((std_util:maybe((time:dst)))) = int.
:- mode time:maybe_dst_to_int((builtin:in)) = (builtin:out) is det.
:- pred time:c_asctime(int, int, int, int, int, int, int, int, int, string).
:- mode time:c_asctime((builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:in), (builtin:out)) is det.
:- pred time:c_ctime(int, string).
:- mode time:c_ctime((builtin:in), (builtin:out)) is det.
time:clocks_per_sec = Val_2 :-
		time:c_clocks_per_sec(Val_2).
time:difftime(T1_4, T0_5) = Diff_6 :-
		time:c_difftime(T1_4, T0_5, Diff_6).
time:localtime(Time_3) = TM_4 :-
		time:c_localtime(Time_3, Yr_5, Mnt_6, MD_7, Hrs_8, Min_9, Sec_10, YD_11, WD_12, N_13),
		TM_4 = time:tm(Yr_5, Mnt_6, MD_7, Hrs_8, Min_9, Sec_10, YD_11, WD_12, V_14),
		V_14 = time:int_to_maybe_dst(N_13).
time:gmtime(Time_3) = TM_4 :-
		time:c_gmtime(Time_3, Yr_5, Mnt_6, MD_7, Hrs_8, Min_9, Sec_10, YD_11, WD_12, N_13),
		TM_4 = time:tm(Yr_5, Mnt_6, MD_7, Hrs_8, Min_9, Sec_10, YD_11, WD_12, V_14),
		V_14 = time:int_to_maybe_dst(N_13).
time:mktime(TM_3) = Time_4 :-
		TM_3 = time:tm(Yr_5, Mnt_6, MD_7, Hrs_8, Min_9, Sec_10, YD_11, WD_12, DST_13),
		V_14 = time:maybe_dst_to_int(DST_13),
		time:c_mktime(Yr_5, Mnt_6, MD_7, Hrs_8, Min_9, Sec_10, YD_11, WD_12, V_14, Time_4).
time:asctime(TM_3) = Str_4 :-
		TM_3 = time:tm(Yr_5, Mnt_6, MD_7, Hrs_8, Min_9, Sec_10, YD_11, WD_12, DST_13),
		V_14 = time:maybe_dst_to_int(DST_13),
		time:c_asctime(Yr_5, Mnt_6, MD_7, Hrs_8, Min_9, Sec_10, YD_11, WD_12, V_14, Str_4).
time:ctime(Time_3) = Str_4 :-
		time:c_ctime(Time_3, Str_4).
:- pragma foreign_proc("C", time:c_clocks_per_sec(Ret :: (builtin:out)), [will_not_call_mercury, not_thread_safe, not_tabled_for_io, promise_pure], "{
	Ret = (MR_Integer) CLOCKS_PER_SEC;
}").
:- pragma foreign_proc("C", time:c_difftime(T1 :: (builtin:in), T0 :: (builtin:in), Diff :: (builtin:out)), [will_not_call_mercury, not_thread_safe, not_tabled_for_io, promise_pure], "{
	Diff = (MR_Float) difftime((time_t) T1, (time_t) T0);
}").
:- pragma foreign_proc("C", time:c_localtime(Time :: (builtin:in), Yr :: (builtin:out), Mnt :: (builtin:out), MD :: (builtin:out), Hrs :: (builtin:out), Min :: (builtin:out), Sec :: (builtin:out), YD :: (builtin:out), WD :: (builtin:out), N :: (builtin:out)), [will_not_call_mercury, not_thread_safe, not_tabled_for_io, promise_pure], "{
	struct tm* p;
	time_t t;

	t = Time;

	p = localtime(&t);

	/* XXX do we need to handle the case where p == NULL here? */

	Sec = (MR_Integer) p->tm_sec;
	Min = (MR_Integer) p->tm_min;
	Hrs = (MR_Integer) p->tm_hour;
	Mnt = (MR_Integer) p->tm_mon;
	Yr = (MR_Integer) p->tm_year;
	WD = (MR_Integer) p->tm_wday;
	MD = (MR_Integer) p->tm_mday;
	YD = (MR_Integer) p->tm_yday;
	N = (MR_Integer) p->tm_isdst;
}").
:- pragma foreign_proc("C", time:c_gmtime(Time :: (builtin:in), Yr :: (builtin:out), Mnt :: (builtin:out), MD :: (builtin:out), Hrs :: (builtin:out), Min :: (builtin:out), Sec :: (builtin:out), YD :: (builtin:out), WD :: (builtin:out), N :: (builtin:out)), [will_not_call_mercury, not_thread_safe, not_tabled_for_io, promise_pure], "{
	struct tm* p;
	time_t t;

	t = Time;

	p = gmtime(&t);

	/* XXX do we need to handle the case where p == NULL here? */

	Sec = (MR_Integer) p->tm_sec;
	Min = (MR_Integer) p->tm_min;
	Hrs = (MR_Integer) p->tm_hour;
	Mnt = (MR_Integer) p->tm_mon;
	Yr = (MR_Integer) p->tm_year;
	WD = (MR_Integer) p->tm_wday;
	MD = (MR_Integer) p->tm_mday;
	YD = (MR_Integer) p->tm_yday;
	N = (MR_Integer) p->tm_isdst;
}").
:- pragma foreign_proc("C", time:c_mktime(Yr :: (builtin:in), Mnt :: (builtin:in), MD :: (builtin:in), Hrs :: (builtin:in), Min :: (builtin:in), Sec :: (builtin:in), YD :: (builtin:in), WD :: (builtin:in), N :: (builtin:in), Time :: (builtin:out)), [will_not_call_mercury, not_thread_safe, not_tabled_for_io, promise_pure], "{
	struct tm t;

	t.tm_sec = Sec;
	t.tm_min = Min;
	t.tm_hour = Hrs;
	t.tm_mon = Mnt;
	t.tm_year = Yr;
	t.tm_wday = WD;
	t.tm_mday = MD;
	t.tm_yday = YD;
	t.tm_isdst = N;

	Time = (MR_Integer) mktime(&t);
}").
:- pragma foreign_proc("C", time:c_asctime(Yr :: (builtin:in), Mnt :: (builtin:in), MD :: (builtin:in), Hrs :: (builtin:in), Min :: (builtin:in), Sec :: (builtin:in), YD :: (builtin:in), WD :: (builtin:in), N :: (builtin:in), Str :: (builtin:out)), [will_not_call_mercury, not_thread_safe, not_tabled_for_io, promise_pure], "{
	struct tm t;
	char* s;

	t.tm_sec = Sec;
	t.tm_min = Min;
	t.tm_hour = Hrs;
	t.tm_mon = Mnt;
	t.tm_year = Yr;
	t.tm_wday = WD;
	t.tm_mday = MD;
	t.tm_yday = YD;
	t.tm_isdst = N;

	s = asctime(&t);

	MR_make_aligned_string_copy(Str, s);
}").
:- pragma foreign_proc("C", time:c_ctime(Time :: (builtin:in), Str :: (builtin:out)), [will_not_call_mercury, not_thread_safe, not_tabled_for_io, promise_pure], "{
	char *s;
	time_t t;

	t = Time;

	s = ctime(&t);

	MR_make_aligned_string_copy(Str, s);
}").
:- pragma termination_info(time:clock((builtin:out), (builtin:di), (builtin:uo)), infinite, can_loop).
:- pragma termination_info((time:clocks_per_sec) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(time:time((builtin:out), (builtin:di), (builtin:uo)), infinite, can_loop).
:- pragma termination_info(time:times((builtin:out), (builtin:out), (builtin:di), (builtin:uo)), infinite, can_loop).
:- pragma termination_info(time:difftime((builtin:in), (builtin:in)) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(time:localtime((builtin:in)) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(time:gmtime((builtin:in)) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(time:mktime((builtin:in)) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(time:asctime((builtin:in)) = (builtin:out), infinite, cannot_loop).
:- pragma termination_info(time:ctime((builtin:in)) = (builtin:out), infinite, cannot_loop).
