jim.c: properly free cached callframes
[jimtcl.git] / jim-clock.c
blob69fb966fc0615fa7c64b0f6d0264a77d392b8969
1 /*
2 * jim-clock.c
4 * Implements the clock command
5 */
7 /* For strptime() */
8 #ifndef _XOPEN_SOURCE
9 #define _XOPEN_SOURCE 500
10 #endif
12 #include <stdlib.h>
13 #include <string.h>
14 #include <stdio.h>
15 #include <time.h>
17 #include "jimautoconf.h"
18 #include <jim-subcmd.h>
20 #ifdef HAVE_SYS_TIME_H
21 #include <sys/time.h>
22 #endif
24 static int clock_cmd_format(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
26 /* How big is big enough? */
27 char buf[100];
28 time_t t;
29 long seconds;
31 const char *format = "%a %b %d %H:%M:%S %Z %Y";
33 if (argc == 2 || (argc == 3 && !Jim_CompareStringImmediate(interp, argv[1], "-format"))) {
34 return -1;
37 if (argc == 3) {
38 format = Jim_String(argv[2]);
41 if (Jim_GetLong(interp, argv[0], &seconds) != JIM_OK) {
42 return JIM_ERR;
44 t = seconds;
46 if (strftime(buf, sizeof(buf), format, localtime(&t)) == 0) {
47 Jim_SetResultString(interp, "format string too long", -1);
48 return JIM_ERR;
51 Jim_SetResultString(interp, buf, -1);
53 return JIM_OK;
56 #ifdef HAVE_STRPTIME
57 static int clock_cmd_scan(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
59 char *pt;
60 struct tm tm;
61 time_t now = time(0);
63 if (!Jim_CompareStringImmediate(interp, argv[1], "-format")) {
64 return -1;
67 /* Initialise with the current date/time */
68 localtime_r(&now, &tm);
70 pt = strptime(Jim_String(argv[0]), Jim_String(argv[2]), &tm);
71 if (pt == 0 || *pt != 0) {
72 Jim_SetResultString(interp, "Failed to parse time according to format", -1);
73 return JIM_ERR;
76 /* Now convert into a time_t */
77 Jim_SetResultInt(interp, mktime(&tm));
79 return JIM_OK;
81 #endif
83 static int clock_cmd_seconds(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
85 Jim_SetResultInt(interp, time(NULL));
87 return JIM_OK;
90 static int clock_cmd_micros(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
92 struct timeval tv;
94 gettimeofday(&tv, NULL);
96 Jim_SetResultInt(interp, (jim_wide) tv.tv_sec * 1000000 + tv.tv_usec);
98 return JIM_OK;
101 static int clock_cmd_millis(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
103 struct timeval tv;
105 gettimeofday(&tv, NULL);
107 Jim_SetResultInt(interp, (jim_wide) tv.tv_sec * 1000 + tv.tv_usec / 1000);
109 return JIM_OK;
112 static const jim_subcmd_type clock_command_table[] = {
113 { "seconds",
114 NULL,
115 clock_cmd_seconds,
118 /* Description: Returns the current time as seconds since the epoch */
120 { "clicks",
121 NULL,
122 clock_cmd_micros,
125 /* Description: Returns the current time in 'clicks' */
127 { "microseconds",
128 NULL,
129 clock_cmd_micros,
132 /* Description: Returns the current time in microseconds */
134 { "milliseconds",
135 NULL,
136 clock_cmd_millis,
139 /* Description: Returns the current time in milliseconds */
141 { "format",
142 "seconds ?-format format?",
143 clock_cmd_format,
146 /* Description: Format the given time */
148 #ifdef HAVE_STRPTIME
149 { "scan",
150 "str -format format",
151 clock_cmd_scan,
154 /* Description: Determine the time according to the given format */
156 #endif
157 { NULL }
160 int Jim_clockInit(Jim_Interp *interp)
162 if (Jim_PackageProvide(interp, "clock", "1.0", JIM_ERRMSG))
163 return JIM_ERR;
165 Jim_CreateCommand(interp, "clock", Jim_SubCmdProc, (void *)clock_command_table, NULL);
166 return JIM_OK;