53 typedef struct DateTimeCode {
58 static DateTimeCode _DateTimeCodes[] = {
60 {
'C',
"([[:digit:]]{2})" },
61 {
'd',
"([[:digit:]]{1,2})" },
62 {
'e',
"([[:digit:]]{1,2})" },
63 {
'h',
"([[:digit:]]{1,4})" },
64 {
'H',
"([[:digit:]]{1,2})" },
65 {
'j',
"([[:digit:]]{1,3})" },
66 {
'm',
"([[:digit:]]{1,2})" },
67 {
'M',
"([[:digit:]]{1,2})" },
68 {
'n',
"[[:space:]]+" },
70 {
'o',
"([+-]*[[:digit:]]*\\.[[:digit:]]+|[+-]*[[:digit:]]+)" },
71 {
'p',
"([aApP][mM])" },
73 {
'q',
"([[:digit:]]+\\.[[:digit:]]+|[[:digit:]]+)" },
75 {
's',
"([[:digit:]]+\\.[[:digit:]]+|[[:digit:]]+)" },
77 {
'S',
"([[:digit:]]{1,2}\\.[[:digit:]]+|[[:digit:]]{1,2})" },
78 {
't',
"[[:space:]]+" },
79 {
'y',
"([[:digit:]]{1,2})" },
80 {
'Y',
"([[:digit:]]{4})" },
85 static DateTimeCode _DateTimeCodes0[] = {
87 {
'C',
"([[:digit:]]{2})" },
88 {
'd',
"([[:digit:]]{2})" },
89 {
'e',
"([[:digit:]]{2})" },
90 {
'h',
"([[:digit:]]{4})" },
91 {
'H',
"([[:digit:]]{2})" },
92 {
'j',
"([[:digit:]]{3})" },
93 {
'm',
"([[:digit:]]{2})" },
94 {
'M',
"([[:digit:]]{2})" },
95 {
'n',
"[[:space:]]+" },
96 {
'o',
"([+-]*[[:digit:]]+)" },
97 {
'p',
"([aApP][mM])" },
98 {
'q',
"([[:digit:]]+)" },
99 {
's',
"([[:digit:]]+)" },
100 {
'S',
"([[:digit:]]{2})" },
101 {
't',
"[[:space:]]+" },
102 {
'y',
"([[:digit:]]{2})" },
103 {
'Y',
"([[:digit:]]{4})" },
122 static int __retime_parse(
RETime *retime,
const char *pattern)
132 if (strchr(pattern,
'(')) {
137 "Invalid regex/time pattern: '%s'\n"
138 " -> regex/time pattern can not contain the '(' character.\n",
144 length = strlen(pattern) + 512;
145 regex_pattern = calloc(length,
sizeof(
char));
147 if (!regex_pattern) {
150 "Could not parse time string pattern: '%s'\n"
151 " -> memory allocation error\n",
161 retime->
codes[0] = -1;
163 while (*sp !=
'\0') {
170 dtc = _DateTimeCodes0;
174 dtc = _DateTimeCodes;
177 for (dti = 0; dtc[dti].chr; ++dti) {
179 if (*sp == dtc[dti].chr) {
181 strcpy(rp, dtc[dti].str);
182 if (*rp ==
'(') retime->
codes[++mi] = *sp;
184 rp = strchr(rp,
'\0');
192 if (dtc == _DateTimeCodes0) {
194 "Invalid time format code '%%0%c' found in: '%s'\n",
199 "Invalid time format code '%%%c' found in: '%s'\n",
214 retime->
pattern = regex_pattern;
282 cflags = REG_EXTENDED;
287 if (!retime)
goto MEMORY_ERROR;
292 if (!retime->
tspattern)
goto MEMORY_ERROR;
296 retime->
codes = calloc(32,
sizeof(
char));
300 if (!__retime_parse(retime, pattern)) {
307 preg = &(retime->
preg);
312 "Could not compile regex/time pattern\n"
313 " -> time string pattern: '%s'\n"
314 " -> regex string pattern: '%s'\n",
323 nsubs = retime->
nsubs;
328 "Invalid regex/time pattern: '%s'\n"
329 " -> no time format codes found in pattern\n",
339 "Invalid regex/time pattern: '%s'\n"
340 " -> number of subexpressions '%d' exceeds the maximum number allowed '%d'\n",
352 "Could not compile regex/time pattern: '%s'\n"
353 " -> memory allocation error\n",
398 regex_t *preg = &(retime->
preg);
399 size_t nsubs = retime->
nsubs;
400 regmatch_t *pmatch = res->
pmatch;
401 size_t nmatch = nsubs + 1;
434 status =
re_execute(preg,
string, nmatch, pmatch, 0);
435 if (status < 0)
return(-1);
436 if (status == 0)
return (0);
442 for (mi = 1; mi < nmatch; mi++) {
444 if (pmatch[mi].rm_so == -1)
return(0);
446 length = pmatch[mi].rm_eo - pmatch[mi].rm_so;
451 "Invalid time string: '%s'\n"
452 " -> length of subexpression '%d' exceeds the maximum substring length '%d'\n",
458 strncpy(substr, (
string + pmatch[mi].rm_so), length);
459 substr[length] =
'\0';
461 switch (retime->
codes[mi]) {
468 res->
mday = atoi(substr);
471 res->
hhmm = atoi(substr);
474 res->
hour = atoi(substr);
477 res->
yday = atoi(substr);
480 res->
month = atoi(substr);
483 res->
min = atoi(substr);
487 negative = (substr[0] ==
'-') ? 1 : 0;
489 res->
offset.tv_sec = atoi(substr);
491 chrp = strchr(substr,
'.');
494 res->
offset.tv_usec = (int)(atof(chrp) * 1.0E6 + 0.5);
496 if (res->
offset.tv_usec == 1.0E6) {
509 res->
offset.tv_usec *= -1;
515 strcpy(am_pm, substr);
519 res->
secs1970 = (time_t)(atoll(substr) - 2082844800LL);
521 chrp = strchr(substr,
'.');
523 res->
usec = (int)(atof(chrp) * 1.0E6 + 0.5);
524 if (res->
usec == 1.0E6) {
536 chrp = strchr(substr,
'.');
538 res->
usec = (int)(atof(chrp) * 1.0E6 + 0.5);
539 if (res->
usec == 1.0E6) {
549 res->
sec = atoi(substr);
551 chrp = strchr(substr,
'.');
553 res->
usec = (int)(atof(chrp) * 1.0E6 + 0.5);
554 if (res->
usec == 1.0E6) {
562 res->
yy = atoi(substr);
565 res->
year = atoi(substr);
570 "Internal error in retime_execute() function\n"
571 " -> unsupported match code found: '%c'\n",
580 if ((am_pm[0] !=
'\0') && (res->
hour != -1)) {
582 if (res->
hour < 1 || res->
hour > 12)
return(0);
584 if (strcasecmp(am_pm,
"AM") == 0) {
588 if (res->
hour != 12) res->
hour += 12;
592 if ((res->
month != -1) && (res->
month > 12))
return(0);
593 if ((res->
mday != -1) && (res->
mday > 31))
return(0);
594 if ((res->
hour != -1) && (res->
hour > 23))
return(0);
595 if ((res->
min != -1) && (res->
min > 59))
return(0);
596 if ((res->
sec != -1) && (res->
sec > 60))
return(0);
600 if (res->
year == -1) {
608 res->
year = (res->
yy < 69) ? 2000 : 1900;
617 if (res->
yday != -1) {
619 if (res->
yday > 366)
return(0);
621 if (res->
year != -1) {
630 if (res->
hhmm != -1) {
632 if (res->
hhmm > 2400)
return(0);
635 res->
min = (int)(res->
hhmm%100);
637 if (res->
min > 59)
return(0);
656 regfree(&(retime->
preg));
692 else if (res->
year == -1) {
697 memset(&tm_time, 0,
sizeof(
struct tm));
699 tm_time.tm_year = res->
year - 1900;
701 if (res->
month != -1) tm_time.tm_mon = res->
month - 1;
702 if (res->
mday != -1) tm_time.tm_mday = res->
mday;
703 if (res->
hour != -1) tm_time.tm_hour = res->
hour;
704 if (res->
min != -1) tm_time.tm_min = res->
min;
705 if (res->
sec != -1) tm_time.tm_sec = res->
sec;
712 usec = (res->
usec == -1) ? 0: res->
usec;
717 usec += res->
offset.tv_usec;
729 else if (usec <= -0.5E6) {
759 if (res->
res_tv.tv_sec != -1) {
768 else if (res->
year == -1) {
773 memset(&tm_time, 0,
sizeof(
struct tm));
775 tm_time.tm_year = res->
year - 1900;
777 if (res->
month != -1) tm_time.tm_mon = res->
month - 1;
778 if (res->
mday != -1) tm_time.tm_mday = res->
mday;
779 if (res->
hour != -1) tm_time.tm_hour = res->
hour;
780 if (res->
min != -1) tm_time.tm_min = res->
min;
781 if (res->
sec != -1) tm_time.tm_sec = res->
sec;
788 usec = (res->
usec == -1) ? 0: res->
usec;
793 usec += res->
offset.tv_usec;
806 res->
res_tv.tv_usec = usec;
835 const char **patterns,
844 "Memory allocation error creating RETimeList\n");
848 retime_list->
retimes = calloc(npatterns + 1,
sizeof(
RETime *));
851 "Memory allocation error creating RETimeList\n");
857 for (pi = 0; pi < npatterns; ++pi) {
860 if (!retime_list->
retimes[pi]) {
913 for (pi = 0; pi < retime_list->
npatterns; ++pi) {
915 retime = retime_list->
retimes[pi];
918 if (status < 0)
return(-1);
940 for (pi = 0; pi < retime_list->
npatterns; ++pi) {