1
6
7
8
9
10
11
14
15
16
17
18
19
20
21
28
29
30
31
32
36
37
43
67
68
69
70
71
72
73
74
75
76
77
80
83
86
87
88
89
90
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
129
130
133
136
137
138
139
140
144
145
146
147
148
149
150
151
152
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
189
196
203
210
211
218
219
226
227
228
229
/* ... */
#include "jimautoconf.h"
#ifdef STRPTIME_NEEDS_XOPEN_SOURCE
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 500
#endif/* ... */
#endif
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <jim-subcmd.h>
5 includes
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
struct clock_options {
int gmt;
const char *format;
...};
/* ... */
static int parse_clock_options(Jim_Interp *interp, int argc, Jim_Obj *const *argv, struct clock_options *opts)
{
static const char * const options[] = { "-gmt", "-format", NULL };
enum { OPT_GMT, OPT_FORMAT, };
int i;
for (i = 0; i < argc; i += 2) {
int option;
if (Jim_GetEnum(interp, argv[i], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) {
return JIM_ERR;
}if (Jim_GetEnum(interp, argv[i], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { ... }
switch (option) {
case OPT_GMT:
if (Jim_GetBoolean(interp, argv[i + 1], &opts->gmt) != JIM_OK) {
return JIM_ERR;
}if (Jim_GetBoolean(interp, argv[i + 1], &opts->gmt) != JIM_OK) { ... }
break;case OPT_GMT:
case OPT_FORMAT:
opts->format = Jim_String(argv[i + 1]);
break;case OPT_FORMAT:
}switch (option) { ... }
}for (i = 0; i < argc; i += 2) { ... }
return JIM_OK;
}{ ... }
static int clock_cmd_format(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
char buf[100];
time_t t;
jim_wide seconds;
struct clock_options options = { 0, "%a %b %d %H:%M:%S %Z %Y" };
struct tm *tm;
if (Jim_GetWide(interp, argv[0], &seconds) != JIM_OK) {
return JIM_ERR;
}if (Jim_GetWide(interp, argv[0], &seconds) != JIM_OK) { ... }
if (argc % 2 == 0) {
return -1;
}if (argc % 2 == 0) { ... }
if (parse_clock_options(interp, argc - 1, argv + 1, &options) == JIM_ERR) {
return JIM_ERR;
}if (parse_clock_options(interp, argc - 1, argv + 1, &options) == JIM_ERR) { ... }
t = seconds;
tm = options.gmt ? gmtime(&t) : localtime(&t);
if (tm == NULL || strftime(buf, sizeof(buf), options.format, tm) == 0) {
Jim_SetResultString(interp, "format string too long or invalid time", -1);
return JIM_ERR;
}if (tm == NULL || strftime(buf, sizeof(buf), options.format, tm) == 0) { ... }
Jim_SetResultString(interp, buf, -1);
return JIM_OK;
}{ ... }
#ifdef HAVE_STRPTIME
/* ... */
static time_t jim_timegm(const struct tm *tm)
{
int m = tm->tm_mon + 1;
int y = 1900 + tm->tm_year - (m <= 2);
int era = (y >= 0 ? y : y - 399) / 400;
unsigned yoe = (unsigned)(y - era * 400);
unsigned doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + tm->tm_mday - 1;
unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;
long days = (era * 146097 + (int)doe - 719468);
int secs = tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec;
return days * 24 * 60 * 60 + secs;
}jim_timegm (const struct tm *tm) { ... }
static int clock_cmd_scan(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
char *pt;
struct tm tm;
time_t now = time(NULL);
struct clock_options options = { 0, NULL };
if (argc % 2 == 0) {
return -1;
}if (argc % 2 == 0) { ... }
if (parse_clock_options(interp, argc - 1, argv + 1, &options) == JIM_ERR) {
return JIM_ERR;
}if (parse_clock_options(interp, argc - 1, argv + 1, &options) == JIM_ERR) { ... }
if (options.format == NULL) {
return -1;
}if (options.format == NULL) { ... }
localtime_r(&now, &tm);
pt = strptime(Jim_String(argv[0]), options.format, &tm);
if (pt == 0 || *pt != 0) {
Jim_SetResultString(interp, "Failed to parse time according to format", -1);
return JIM_ERR;
}if (pt == 0 || *pt != 0) { ... }
Jim_SetResultInt(interp, options.gmt ? jim_timegm(&tm) : mktime(&tm));
return JIM_OK;
}clock_cmd_scan (Jim_Interp *interp, int argc, Jim_Obj *const *argv) { ... }
/* ... */#endif
static int clock_cmd_seconds(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_SetResultInt(interp, time(NULL));
return JIM_OK;
}{ ... }
static int clock_cmd_micros(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
struct timeval tv;
gettimeofday(&tv, NULL);
Jim_SetResultInt(interp, (jim_wide) tv.tv_sec * 1000000 + tv.tv_usec);
return JIM_OK;
}{ ... }
static int clock_cmd_millis(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
struct timeval tv;
gettimeofday(&tv, NULL);
Jim_SetResultInt(interp, (jim_wide) tv.tv_sec * 1000 + tv.tv_usec / 1000);
return JIM_OK;
}{ ... }
static const jim_subcmd_type clock_command_table[] = {
{ "clicks",
NULL,
clock_cmd_micros,
0,
0,
...},
{ "format",
"seconds ?-format string? ?-gmt boolean?",
clock_cmd_format,
1,
5,
...},
{ "microseconds",
NULL,
clock_cmd_micros,
0,
0,
...},
{ "milliseconds",
NULL,
clock_cmd_millis,
0,
0,
...},
#ifdef HAVE_STRPTIME
{ "scan",
"str -format format ?-gmt boolean?",
clock_cmd_scan,
3,
5,
...},/* ... */
#endif
{ "seconds",
NULL,
clock_cmd_seconds,
0,
0,
...},
{ NULL }
...};
int Jim_clockInit(Jim_Interp *interp)
{
Jim_PackageProvideCheck(interp, "clock");
Jim_CreateCommand(interp, "clock", Jim_SubCmdProc, (void *)clock_command_table, NULL);
return JIM_OK;
}{ ... }