parse_date.re 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260
  1. /*
  2. * The MIT License (MIT)
  3. *
  4. * Copyright (c) 2015 Derick Rethans
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. /* $Id$ */
  25. #include "timelib.h"
  26. #include <stdio.h>
  27. #include <ctype.h>
  28. #include <math.h>
  29. #include <assert.h>
  30. #ifdef HAVE_STDLIB_H
  31. #include <stdlib.h>
  32. #endif
  33. #ifdef HAVE_STRING_H
  34. #include <string.h>
  35. #else
  36. #include <strings.h>
  37. #endif
  38. #if defined(_MSC_VER)
  39. # define strtoll(s, f, b) _atoi64(s)
  40. #elif !defined(HAVE_STRTOLL)
  41. # if defined(HAVE_ATOLL)
  42. # define strtoll(s, f, b) atoll(s)
  43. # else
  44. # define strtoll(s, f, b) strtol(s, f, b)
  45. # endif
  46. #endif
  47. #define TIMELIB_UNSET -99999
  48. #define TIMELIB_SECOND 1
  49. #define TIMELIB_MINUTE 2
  50. #define TIMELIB_HOUR 3
  51. #define TIMELIB_DAY 4
  52. #define TIMELIB_MONTH 5
  53. #define TIMELIB_YEAR 6
  54. #define TIMELIB_WEEKDAY 7
  55. #define TIMELIB_SPECIAL 8
  56. #define EOI 257
  57. #define TIME 258
  58. #define DATE 259
  59. #define TIMELIB_XMLRPC_SOAP 260
  60. #define TIMELIB_TIME12 261
  61. #define TIMELIB_TIME24 262
  62. #define TIMELIB_GNU_NOCOLON 263
  63. #define TIMELIB_GNU_NOCOLON_TZ 264
  64. #define TIMELIB_ISO_NOCOLON 265
  65. #define TIMELIB_AMERICAN 266
  66. #define TIMELIB_ISO_DATE 267
  67. #define TIMELIB_DATE_FULL 268
  68. #define TIMELIB_DATE_TEXT 269
  69. #define TIMELIB_DATE_NOCOLON 270
  70. #define TIMELIB_PG_YEARDAY 271
  71. #define TIMELIB_PG_TEXT 272
  72. #define TIMELIB_PG_REVERSE 273
  73. #define TIMELIB_CLF 274
  74. #define TIMELIB_DATE_NO_DAY 275
  75. #define TIMELIB_SHORTDATE_WITH_TIME 276
  76. #define TIMELIB_DATE_FULL_POINTED 277
  77. #define TIMELIB_TIME24_WITH_ZONE 278
  78. #define TIMELIB_ISO_WEEK 279
  79. #define TIMELIB_LF_DAY_OF_MONTH 280
  80. #define TIMELIB_WEEK_DAY_OF_MONTH 281
  81. #define TIMELIB_TIMEZONE 300
  82. #define TIMELIB_AGO 301
  83. #define TIMELIB_RELATIVE 310
  84. #define TIMELIB_ERROR 999
  85. /* Some compilers like AIX, defines uchar in sys/types.h */
  86. #undef uchar
  87. typedef unsigned char uchar;
  88. #define BSIZE 8192
  89. #define YYCTYPE uchar
  90. #define YYCURSOR cursor
  91. #define YYLIMIT s->lim
  92. #define YYMARKER s->ptr
  93. #define YYFILL(n) return EOI;
  94. #define RET(i) {s->cur = cursor; return i;}
  95. #define timelib_string_free timelib_free
  96. #define TIMELIB_HAVE_TIME() { if (s->time->have_time) { add_error(s, "Double time specification"); timelib_string_free(str); return TIMELIB_ERROR; } else { s->time->have_time = 1; s->time->h = 0; s->time->i = 0; s->time->s = 0; s->time->f = 0; } }
  97. #define TIMELIB_UNHAVE_TIME() { s->time->have_time = 0; s->time->h = 0; s->time->i = 0; s->time->s = 0; s->time->f = 0; }
  98. #define TIMELIB_HAVE_DATE() { if (s->time->have_date) { add_error(s, "Double date specification"); timelib_string_free(str); return TIMELIB_ERROR; } else { s->time->have_date = 1; } }
  99. #define TIMELIB_UNHAVE_DATE() { s->time->have_date = 0; s->time->d = 0; s->time->m = 0; s->time->y = 0; }
  100. #define TIMELIB_HAVE_RELATIVE() { s->time->have_relative = 1; }
  101. #define TIMELIB_HAVE_WEEKDAY_RELATIVE() { s->time->have_relative = 1; s->time->relative.have_weekday_relative = 1; }
  102. #define TIMELIB_HAVE_SPECIAL_RELATIVE() { s->time->have_relative = 1; s->time->relative.have_special_relative = 1; }
  103. #define TIMELIB_HAVE_TZ() { s->cur = cursor; if (s->time->have_zone) { s->time->have_zone > 1 ? add_error(s, "Double timezone specification") : add_warning(s, "Double timezone specification"); timelib_string_free(str); s->time->have_zone++; return TIMELIB_ERROR; } else { s->time->have_zone++; } }
  104. #define TIMELIB_INIT s->cur = cursor; str = timelib_string(s); ptr = str
  105. #define TIMELIB_DEINIT timelib_string_free(str)
  106. #define TIMELIB_ADJUST_RELATIVE_WEEKDAY() if (in->time.have_weekday_relative && (in.rel.d > 0)) { in.rel.d -= 7; }
  107. #define TIMELIB_PROCESS_YEAR(x, l) { \
  108. if (((x) == TIMELIB_UNSET) || ((l) >= 4)) { \
  109. /* (x) = 0; */ \
  110. } else if ((x) < 100) { \
  111. if ((x) < 70) { \
  112. (x) += 2000; \
  113. } else { \
  114. (x) += 1900; \
  115. } \
  116. } \
  117. }
  118. #ifdef DEBUG_PARSER
  119. #define DEBUG_OUTPUT(s) printf("%s\n", s);
  120. #define YYDEBUG(s,c) { if (s != -1) { printf("state: %d ", s); printf("[%c]\n", c); } }
  121. #else
  122. #define DEBUG_OUTPUT(s)
  123. #define YYDEBUG(s,c)
  124. #endif
  125. #include "timelib_structs.h"
  126. typedef struct timelib_elems {
  127. unsigned int c; /* Number of elements */
  128. char **v; /* Values */
  129. } timelib_elems;
  130. typedef struct Scanner {
  131. int fd;
  132. uchar *lim, *str, *ptr, *cur, *tok, *pos;
  133. unsigned int line, len;
  134. struct timelib_error_container *errors;
  135. struct timelib_time *time;
  136. const timelib_tzdb *tzdb;
  137. } Scanner;
  138. typedef struct _timelib_lookup_table {
  139. const char *name;
  140. int type;
  141. int value;
  142. } timelib_lookup_table;
  143. typedef struct _timelib_relunit {
  144. const char *name;
  145. int unit;
  146. int multiplier;
  147. } timelib_relunit;
  148. /* The timezone table. */
  149. const static timelib_tz_lookup_table timelib_timezone_lookup[] = {
  150. #include "timezonemap.h"
  151. { NULL, 0, 0, NULL },
  152. };
  153. const static timelib_tz_lookup_table timelib_timezone_fallbackmap[] = {
  154. #include "fallbackmap.h"
  155. { NULL, 0, 0, NULL },
  156. };
  157. const static timelib_tz_lookup_table timelib_timezone_utc[] = {
  158. { "utc", 0, 0, "UTC" },
  159. };
  160. static timelib_relunit const timelib_relunit_lookup[] = {
  161. { "sec", TIMELIB_SECOND, 1 },
  162. { "secs", TIMELIB_SECOND, 1 },
  163. { "second", TIMELIB_SECOND, 1 },
  164. { "seconds", TIMELIB_SECOND, 1 },
  165. { "min", TIMELIB_MINUTE, 1 },
  166. { "mins", TIMELIB_MINUTE, 1 },
  167. { "minute", TIMELIB_MINUTE, 1 },
  168. { "minutes", TIMELIB_MINUTE, 1 },
  169. { "hour", TIMELIB_HOUR, 1 },
  170. { "hours", TIMELIB_HOUR, 1 },
  171. { "day", TIMELIB_DAY, 1 },
  172. { "days", TIMELIB_DAY, 1 },
  173. { "week", TIMELIB_DAY, 7 },
  174. { "weeks", TIMELIB_DAY, 7 },
  175. { "fortnight", TIMELIB_DAY, 14 },
  176. { "fortnights", TIMELIB_DAY, 14 },
  177. { "forthnight", TIMELIB_DAY, 14 },
  178. { "forthnights", TIMELIB_DAY, 14 },
  179. { "month", TIMELIB_MONTH, 1 },
  180. { "months", TIMELIB_MONTH, 1 },
  181. { "year", TIMELIB_YEAR, 1 },
  182. { "years", TIMELIB_YEAR, 1 },
  183. { "monday", TIMELIB_WEEKDAY, 1 },
  184. { "mon", TIMELIB_WEEKDAY, 1 },
  185. { "tuesday", TIMELIB_WEEKDAY, 2 },
  186. { "tue", TIMELIB_WEEKDAY, 2 },
  187. { "wednesday", TIMELIB_WEEKDAY, 3 },
  188. { "wed", TIMELIB_WEEKDAY, 3 },
  189. { "thursday", TIMELIB_WEEKDAY, 4 },
  190. { "thu", TIMELIB_WEEKDAY, 4 },
  191. { "friday", TIMELIB_WEEKDAY, 5 },
  192. { "fri", TIMELIB_WEEKDAY, 5 },
  193. { "saturday", TIMELIB_WEEKDAY, 6 },
  194. { "sat", TIMELIB_WEEKDAY, 6 },
  195. { "sunday", TIMELIB_WEEKDAY, 0 },
  196. { "sun", TIMELIB_WEEKDAY, 0 },
  197. { "weekday", TIMELIB_SPECIAL, TIMELIB_SPECIAL_WEEKDAY },
  198. { "weekdays", TIMELIB_SPECIAL, TIMELIB_SPECIAL_WEEKDAY },
  199. { NULL, 0, 0 }
  200. };
  201. /* The relative text table. */
  202. static timelib_lookup_table const timelib_reltext_lookup[] = {
  203. { "first", 0, 1 },
  204. { "next", 0, 1 },
  205. { "second", 0, 2 },
  206. { "third", 0, 3 },
  207. { "fourth", 0, 4 },
  208. { "fifth", 0, 5 },
  209. { "sixth", 0, 6 },
  210. { "seventh", 0, 7 },
  211. { "eight", 0, 8 },
  212. { "eighth", 0, 8 },
  213. { "ninth", 0, 9 },
  214. { "tenth", 0, 10 },
  215. { "eleventh", 0, 11 },
  216. { "twelfth", 0, 12 },
  217. { "last", 0, -1 },
  218. { "previous", 0, -1 },
  219. { "this", 1, 0 },
  220. { NULL, 1, 0 }
  221. };
  222. /* The month table. */
  223. static timelib_lookup_table const timelib_month_lookup[] = {
  224. { "jan", 0, 1 },
  225. { "feb", 0, 2 },
  226. { "mar", 0, 3 },
  227. { "apr", 0, 4 },
  228. { "may", 0, 5 },
  229. { "jun", 0, 6 },
  230. { "jul", 0, 7 },
  231. { "aug", 0, 8 },
  232. { "sep", 0, 9 },
  233. { "sept", 0, 9 },
  234. { "oct", 0, 10 },
  235. { "nov", 0, 11 },
  236. { "dec", 0, 12 },
  237. { "i", 0, 1 },
  238. { "ii", 0, 2 },
  239. { "iii", 0, 3 },
  240. { "iv", 0, 4 },
  241. { "v", 0, 5 },
  242. { "vi", 0, 6 },
  243. { "vii", 0, 7 },
  244. { "viii", 0, 8 },
  245. { "ix", 0, 9 },
  246. { "x", 0, 10 },
  247. { "xi", 0, 11 },
  248. { "xii", 0, 12 },
  249. { "january", 0, 1 },
  250. { "february", 0, 2 },
  251. { "march", 0, 3 },
  252. { "april", 0, 4 },
  253. { "may", 0, 5 },
  254. { "june", 0, 6 },
  255. { "july", 0, 7 },
  256. { "august", 0, 8 },
  257. { "september", 0, 9 },
  258. { "october", 0, 10 },
  259. { "november", 0, 11 },
  260. { "december", 0, 12 },
  261. { NULL, 0, 0 }
  262. };
  263. #if 0
  264. static char* timelib_ltrim(char *s)
  265. {
  266. char *ptr = s;
  267. while (ptr[0] == ' ' || ptr[0] == '\t') {
  268. ptr++;
  269. }
  270. return ptr;
  271. }
  272. #endif
  273. #if 0
  274. uchar *fill(Scanner *s, uchar *cursor){
  275. if(!s->eof){
  276. unsigned int cnt = s->tok - s->bot;
  277. if(cnt){
  278. memcpy(s->bot, s->tok, s->lim - s->tok);
  279. s->tok = s->bot;
  280. s->ptr -= cnt;
  281. cursor -= cnt;
  282. s->pos -= cnt;
  283. s->lim -= cnt;
  284. }
  285. if((s->top - s->lim) < BSIZE){
  286. uchar *buf = (uchar*) timelib_malloc(((s->lim - s->bot) + BSIZE)*sizeof(uchar));
  287. memcpy(buf, s->tok, s->lim - s->tok);
  288. s->tok = buf;
  289. s->ptr = &buf[s->ptr - s->bot];
  290. cursor = &buf[cursor - s->bot];
  291. s->pos = &buf[s->pos - s->bot];
  292. s->lim = &buf[s->lim - s->bot];
  293. s->top = &s->lim[BSIZE];
  294. timelib_free(s->bot);
  295. s->bot = buf;
  296. }
  297. if((cnt = read(s->fd, (char*) s->lim, BSIZE)) != BSIZE){
  298. s->eof = &s->lim[cnt]; *(s->eof)++ = '\n';
  299. }
  300. s->lim += cnt;
  301. }
  302. return cursor;
  303. }
  304. #endif
  305. static void add_warning(Scanner *s, char *error)
  306. {
  307. s->errors->warning_count++;
  308. s->errors->warning_messages = timelib_realloc(s->errors->warning_messages, s->errors->warning_count * sizeof(timelib_error_message));
  309. s->errors->warning_messages[s->errors->warning_count - 1].position = s->tok ? s->tok - s->str : 0;
  310. s->errors->warning_messages[s->errors->warning_count - 1].character = s->tok ? *s->tok : 0;
  311. s->errors->warning_messages[s->errors->warning_count - 1].message = timelib_strdup(error);
  312. }
  313. static void add_error(Scanner *s, char *error)
  314. {
  315. s->errors->error_count++;
  316. s->errors->error_messages = timelib_realloc(s->errors->error_messages, s->errors->error_count * sizeof(timelib_error_message));
  317. s->errors->error_messages[s->errors->error_count - 1].position = s->tok ? s->tok - s->str : 0;
  318. s->errors->error_messages[s->errors->error_count - 1].character = s->tok ? *s->tok : 0;
  319. s->errors->error_messages[s->errors->error_count - 1].message = timelib_strdup(error);
  320. }
  321. static void add_pbf_warning(Scanner *s, char *error, char *sptr, char *cptr)
  322. {
  323. s->errors->warning_count++;
  324. s->errors->warning_messages = timelib_realloc(s->errors->warning_messages, s->errors->warning_count * sizeof(timelib_error_message));
  325. s->errors->warning_messages[s->errors->warning_count - 1].position = cptr - sptr;
  326. s->errors->warning_messages[s->errors->warning_count - 1].character = *cptr;
  327. s->errors->warning_messages[s->errors->warning_count - 1].message = timelib_strdup(error);
  328. }
  329. static void add_pbf_error(Scanner *s, char *error, char *sptr, char *cptr)
  330. {
  331. s->errors->error_count++;
  332. s->errors->error_messages = timelib_realloc(s->errors->error_messages, s->errors->error_count * sizeof(timelib_error_message));
  333. s->errors->error_messages[s->errors->error_count - 1].position = cptr - sptr;
  334. s->errors->error_messages[s->errors->error_count - 1].character = *cptr;
  335. s->errors->error_messages[s->errors->error_count - 1].message = timelib_strdup(error);
  336. }
  337. static timelib_sll timelib_meridian(char **ptr, timelib_sll h)
  338. {
  339. timelib_sll retval = 0;
  340. while (!strchr("AaPp", **ptr)) {
  341. ++*ptr;
  342. }
  343. if (**ptr == 'a' || **ptr == 'A') {
  344. if (h == 12) {
  345. retval = -12;
  346. }
  347. } else if (h != 12) {
  348. retval = 12;
  349. }
  350. ++*ptr;
  351. if (**ptr == '.') {
  352. ++*ptr;
  353. }
  354. if (**ptr == 'M' || **ptr == 'm') {
  355. ++*ptr;
  356. }
  357. if (**ptr == '.') {
  358. ++*ptr;
  359. }
  360. return retval;
  361. }
  362. static timelib_sll timelib_meridian_with_check(char **ptr, timelib_sll h)
  363. {
  364. timelib_sll retval = 0;
  365. while (**ptr && !strchr("AaPp", **ptr)) {
  366. ++*ptr;
  367. }
  368. if(!**ptr) {
  369. return TIMELIB_UNSET;
  370. }
  371. if (**ptr == 'a' || **ptr == 'A') {
  372. if (h == 12) {
  373. retval = -12;
  374. }
  375. } else if (h != 12) {
  376. retval = 12;
  377. }
  378. ++*ptr;
  379. if (**ptr == '.') {
  380. ++*ptr;
  381. if (**ptr != 'm' && **ptr != 'M') {
  382. return TIMELIB_UNSET;
  383. }
  384. ++*ptr;
  385. if (**ptr != '.' ) {
  386. return TIMELIB_UNSET;
  387. }
  388. ++*ptr;
  389. } else if (**ptr == 'm' || **ptr == 'M') {
  390. ++*ptr;
  391. } else {
  392. return TIMELIB_UNSET;
  393. }
  394. return retval;
  395. }
  396. static char *timelib_string(Scanner *s)
  397. {
  398. char *tmp = timelib_calloc(1, s->cur - s->tok + 1);
  399. memcpy(tmp, s->tok, s->cur - s->tok);
  400. return tmp;
  401. }
  402. static timelib_sll timelib_get_nr_ex(char **ptr, int max_length, int *scanned_length)
  403. {
  404. char *begin, *end, *str;
  405. timelib_sll tmp_nr = TIMELIB_UNSET;
  406. int len = 0;
  407. while ((**ptr < '0') || (**ptr > '9')) {
  408. if (**ptr == '\0') {
  409. return TIMELIB_UNSET;
  410. }
  411. ++*ptr;
  412. }
  413. begin = *ptr;
  414. while ((**ptr >= '0') && (**ptr <= '9') && len < max_length) {
  415. ++*ptr;
  416. ++len;
  417. }
  418. end = *ptr;
  419. if (scanned_length) {
  420. *scanned_length = end - begin;
  421. }
  422. str = timelib_calloc(1, end - begin + 1);
  423. memcpy(str, begin, end - begin);
  424. tmp_nr = strtoll(str, NULL, 10);
  425. timelib_free(str);
  426. return tmp_nr;
  427. }
  428. static timelib_sll timelib_get_nr(char **ptr, int max_length)
  429. {
  430. return timelib_get_nr_ex(ptr, max_length, NULL);
  431. }
  432. static void timelib_skip_day_suffix(char **ptr)
  433. {
  434. if (isspace(**ptr)) {
  435. return;
  436. }
  437. if (!strncasecmp(*ptr, "nd", 2) || !strncasecmp(*ptr, "rd", 2) ||!strncasecmp(*ptr, "st", 2) || !strncasecmp(*ptr, "th", 2)) {
  438. *ptr += 2;
  439. }
  440. }
  441. static double timelib_get_frac_nr(char **ptr, int max_length)
  442. {
  443. char *begin, *end, *str;
  444. double tmp_nr = TIMELIB_UNSET;
  445. int len = 0;
  446. while ((**ptr != '.') && (**ptr != ':') && ((**ptr < '0') || (**ptr > '9'))) {
  447. if (**ptr == '\0') {
  448. return TIMELIB_UNSET;
  449. }
  450. ++*ptr;
  451. }
  452. begin = *ptr;
  453. while (((**ptr == '.') || (**ptr == ':') || ((**ptr >= '0') && (**ptr <= '9'))) && len < max_length) {
  454. ++*ptr;
  455. ++len;
  456. }
  457. end = *ptr;
  458. str = timelib_calloc(1, end - begin + 1);
  459. memcpy(str, begin, end - begin);
  460. if (str[0] == ':') {
  461. str[0] = '.';
  462. }
  463. tmp_nr = strtod(str, NULL);
  464. timelib_free(str);
  465. return tmp_nr;
  466. }
  467. static timelib_ull timelib_get_unsigned_nr(char **ptr, int max_length)
  468. {
  469. timelib_ull dir = 1;
  470. while (((**ptr < '0') || (**ptr > '9')) && (**ptr != '+') && (**ptr != '-')) {
  471. if (**ptr == '\0') {
  472. return TIMELIB_UNSET;
  473. }
  474. ++*ptr;
  475. }
  476. while (**ptr == '+' || **ptr == '-')
  477. {
  478. if (**ptr == '-') {
  479. dir *= -1;
  480. }
  481. ++*ptr;
  482. }
  483. return dir * timelib_get_nr(ptr, max_length);
  484. }
  485. static timelib_sll timelib_lookup_relative_text(char **ptr, int *behavior)
  486. {
  487. char *word;
  488. char *begin = *ptr, *end;
  489. timelib_sll value = 0;
  490. const timelib_lookup_table *tp;
  491. while ((**ptr >= 'A' && **ptr <= 'Z') || (**ptr >= 'a' && **ptr <= 'z')) {
  492. ++*ptr;
  493. }
  494. end = *ptr;
  495. word = timelib_calloc(1, end - begin + 1);
  496. memcpy(word, begin, end - begin);
  497. for (tp = timelib_reltext_lookup; tp->name; tp++) {
  498. if (strcasecmp(word, tp->name) == 0) {
  499. value = tp->value;
  500. *behavior = tp->type;
  501. }
  502. }
  503. timelib_free(word);
  504. return value;
  505. }
  506. static timelib_sll timelib_get_relative_text(char **ptr, int *behavior)
  507. {
  508. while (**ptr == ' ' || **ptr == '\t' || **ptr == '-' || **ptr == '/') {
  509. ++*ptr;
  510. }
  511. return timelib_lookup_relative_text(ptr, behavior);
  512. }
  513. static timelib_long timelib_lookup_month(char **ptr)
  514. {
  515. char *word;
  516. char *begin = *ptr, *end;
  517. timelib_long value = 0;
  518. const timelib_lookup_table *tp;
  519. while ((**ptr >= 'A' && **ptr <= 'Z') || (**ptr >= 'a' && **ptr <= 'z')) {
  520. ++*ptr;
  521. }
  522. end = *ptr;
  523. word = timelib_calloc(1, end - begin + 1);
  524. memcpy(word, begin, end - begin);
  525. for (tp = timelib_month_lookup; tp->name; tp++) {
  526. if (strcasecmp(word, tp->name) == 0) {
  527. value = tp->value;
  528. }
  529. }
  530. timelib_free(word);
  531. return value;
  532. }
  533. static timelib_long timelib_get_month(char **ptr)
  534. {
  535. while (**ptr == ' ' || **ptr == '\t' || **ptr == '-' || **ptr == '.' || **ptr == '/') {
  536. ++*ptr;
  537. }
  538. return timelib_lookup_month(ptr);
  539. }
  540. static void timelib_eat_spaces(char **ptr)
  541. {
  542. while (**ptr == ' ' || **ptr == '\t') {
  543. ++*ptr;
  544. }
  545. }
  546. static void timelib_eat_until_separator(char **ptr)
  547. {
  548. ++*ptr;
  549. while (strchr(" \t.,:;/-0123456789", **ptr) == NULL) {
  550. ++*ptr;
  551. }
  552. }
  553. static const timelib_relunit* timelib_lookup_relunit(char **ptr)
  554. {
  555. char *word;
  556. char *begin = *ptr, *end;
  557. const timelib_relunit *tp, *value = NULL;
  558. while (**ptr != '\0' && **ptr != ' ' && **ptr != ',' && **ptr != '\t' && **ptr != ';' && **ptr != ':' &&
  559. **ptr != '/' && **ptr != '.' && **ptr != '-' && **ptr != '(' && **ptr != ')' ) {
  560. ++*ptr;
  561. }
  562. end = *ptr;
  563. word = timelib_calloc(1, end - begin + 1);
  564. memcpy(word, begin, end - begin);
  565. for (tp = timelib_relunit_lookup; tp->name; tp++) {
  566. if (strcasecmp(word, tp->name) == 0) {
  567. value = tp;
  568. break;
  569. }
  570. }
  571. timelib_free(word);
  572. return value;
  573. }
  574. static void timelib_set_relative(char **ptr, timelib_sll amount, int behavior, Scanner *s)
  575. {
  576. const timelib_relunit* relunit;
  577. if (!(relunit = timelib_lookup_relunit(ptr))) {
  578. return;
  579. }
  580. switch (relunit->unit) {
  581. case TIMELIB_SECOND: s->time->relative.s += amount * relunit->multiplier; break;
  582. case TIMELIB_MINUTE: s->time->relative.i += amount * relunit->multiplier; break;
  583. case TIMELIB_HOUR: s->time->relative.h += amount * relunit->multiplier; break;
  584. case TIMELIB_DAY: s->time->relative.d += amount * relunit->multiplier; break;
  585. case TIMELIB_MONTH: s->time->relative.m += amount * relunit->multiplier; break;
  586. case TIMELIB_YEAR: s->time->relative.y += amount * relunit->multiplier; break;
  587. case TIMELIB_WEEKDAY:
  588. TIMELIB_HAVE_WEEKDAY_RELATIVE();
  589. TIMELIB_UNHAVE_TIME();
  590. s->time->relative.d += (amount > 0 ? amount - 1 : amount) * 7;
  591. s->time->relative.weekday = relunit->multiplier;
  592. s->time->relative.weekday_behavior = behavior;
  593. break;
  594. case TIMELIB_SPECIAL:
  595. TIMELIB_HAVE_SPECIAL_RELATIVE();
  596. TIMELIB_UNHAVE_TIME();
  597. s->time->relative.special.type = relunit->multiplier;
  598. s->time->relative.special.amount = amount;
  599. }
  600. }
  601. const static timelib_tz_lookup_table* abbr_search(const char *word, timelib_long gmtoffset, int isdst)
  602. {
  603. int first_found = 0;
  604. const timelib_tz_lookup_table *tp, *first_found_elem = NULL;
  605. const timelib_tz_lookup_table *fmp;
  606. if (strcasecmp("utc", word) == 0 || strcasecmp("gmt", word) == 0) {
  607. return timelib_timezone_utc;
  608. }
  609. for (tp = timelib_timezone_lookup; tp->name; tp++) {
  610. if (strcasecmp(word, tp->name) == 0) {
  611. if (!first_found) {
  612. first_found = 1;
  613. first_found_elem = tp;
  614. if (gmtoffset == -1) {
  615. return tp;
  616. }
  617. }
  618. if (tp->gmtoffset == gmtoffset) {
  619. return tp;
  620. }
  621. }
  622. }
  623. if (first_found) {
  624. return first_found_elem;
  625. }
  626. /* Still didn't find anything, let's find the zone solely based on
  627. * offset/isdst then */
  628. for (fmp = timelib_timezone_fallbackmap; fmp->name; fmp++) {
  629. if ((fmp->gmtoffset * 60) == gmtoffset && fmp->type == isdst) {
  630. return fmp;
  631. }
  632. }
  633. return NULL;
  634. }
  635. static timelib_long timelib_lookup_abbr(char **ptr, int *dst, char **tz_abbr, int *found)
  636. {
  637. char *word;
  638. char *begin = *ptr, *end;
  639. timelib_long value = 0;
  640. const timelib_tz_lookup_table *tp;
  641. while (**ptr != '\0' && **ptr != ')' && **ptr != ' ') {
  642. ++*ptr;
  643. }
  644. end = *ptr;
  645. word = timelib_calloc(1, end - begin + 1);
  646. memcpy(word, begin, end - begin);
  647. if ((tp = abbr_search(word, -1, 0))) {
  648. value = -tp->gmtoffset / 60;
  649. *dst = tp->type;
  650. value += tp->type * 60;
  651. *found = 1;
  652. } else {
  653. *found = 0;
  654. }
  655. *tz_abbr = word;
  656. return value;
  657. }
  658. timelib_long timelib_parse_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_found, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_wrapper)
  659. {
  660. timelib_tzinfo *res;
  661. timelib_long retval = 0;
  662. *tz_not_found = 0;
  663. while (**ptr == ' ' || **ptr == '\t' || **ptr == '(') {
  664. ++*ptr;
  665. }
  666. if ((*ptr)[0] == 'G' && (*ptr)[1] == 'M' && (*ptr)[2] == 'T' && ((*ptr)[3] == '+' || (*ptr)[3] == '-')) {
  667. *ptr += 3;
  668. }
  669. if (**ptr == '+') {
  670. ++*ptr;
  671. t->is_localtime = 1;
  672. t->zone_type = TIMELIB_ZONETYPE_OFFSET;
  673. *tz_not_found = 0;
  674. t->dst = 0;
  675. retval = -1 * timelib_parse_tz_cor(ptr);
  676. } else if (**ptr == '-') {
  677. ++*ptr;
  678. t->is_localtime = 1;
  679. t->zone_type = TIMELIB_ZONETYPE_OFFSET;
  680. *tz_not_found = 0;
  681. t->dst = 0;
  682. retval = timelib_parse_tz_cor(ptr);
  683. } else {
  684. int found = 0;
  685. timelib_long offset = 0;
  686. char *tz_abbr;
  687. t->is_localtime = 1;
  688. /* First, we lookup by abbreviation only */
  689. offset = timelib_lookup_abbr(ptr, dst, &tz_abbr, &found);
  690. if (found) {
  691. t->zone_type = TIMELIB_ZONETYPE_ABBR;
  692. timelib_time_tz_abbr_update(t, tz_abbr);
  693. }
  694. /* Otherwise, we look if we have a TimeZone identifier */
  695. if (!found || strcmp("UTC", tz_abbr) == 0) {
  696. if ((res = tz_wrapper(tz_abbr, tzdb)) != NULL) {
  697. t->tz_info = res;
  698. t->zone_type = TIMELIB_ZONETYPE_ID;
  699. found++;
  700. }
  701. }
  702. timelib_free(tz_abbr);
  703. *tz_not_found = (found == 0);
  704. retval = offset;
  705. }
  706. while (**ptr == ')') {
  707. ++*ptr;
  708. }
  709. return retval;
  710. }
  711. #define timelib_split_free(arg) { \
  712. int i; \
  713. for (i = 0; i < arg.c; i++) { \
  714. timelib_free(arg.v[i]); \
  715. } \
  716. if (arg.v) { \
  717. timelib_free(arg.v); \
  718. } \
  719. }
  720. static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper)
  721. {
  722. uchar *cursor = s->cur;
  723. char *str, *ptr = NULL;
  724. std:
  725. s->tok = cursor;
  726. s->len = 0;
  727. /*!re2c
  728. any = [\000-\377];
  729. space = [ \t]+;
  730. frac = "."[0-9]+;
  731. ago = 'ago';
  732. hour24 = [01]?[0-9] | "2"[0-4];
  733. hour24lz = [01][0-9] | "2"[0-4];
  734. hour12 = "0"?[1-9] | "1"[0-2];
  735. minute = [0-5]?[0-9];
  736. minutelz = [0-5][0-9];
  737. second = minute | "60";
  738. secondlz = minutelz | "60";
  739. meridian = ([AaPp] "."? [Mm] "."?) [\000\t ];
  740. tz = "("? [A-Za-z]{1,6} ")"? | [A-Z][a-z]+([_/-][A-Za-z]+)+;
  741. tzcorrection = "GMT"? [+-] hour24 ":"? minute?;
  742. daysuf = "st" | "nd" | "rd" | "th";
  743. month = "0"? [0-9] | "1"[0-2];
  744. day = (([0-2]?[0-9]) | ("3"[01])) daysuf?;
  745. year = [0-9]{1,4};
  746. year2 = [0-9]{2};
  747. year4 = [0-9]{4};
  748. year4withsign = [+-]? [0-9]{4};
  749. dayofyear = "00"[1-9] | "0"[1-9][0-9] | [1-2][0-9][0-9] | "3"[0-5][0-9] | "36"[0-6];
  750. weekofyear = "0"[1-9] | [1-4][0-9] | "5"[0-3];
  751. monthlz = "0" [0-9] | "1" [0-2];
  752. daylz = "0" [0-9] | [1-2][0-9] | "3" [01];
  753. dayfull = 'sunday' | 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday';
  754. dayabbr = 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat' | 'sun';
  755. dayspecial = 'weekday' | 'weekdays';
  756. daytext = dayfull | dayabbr | dayspecial;
  757. monthfull = 'january' | 'february' | 'march' | 'april' | 'may' | 'june' | 'july' | 'august' | 'september' | 'october' | 'november' | 'december';
  758. monthabbr = 'jan' | 'feb' | 'mar' | 'apr' | 'may' | 'jun' | 'jul' | 'aug' | 'sep' | 'sept' | 'oct' | 'nov' | 'dec';
  759. monthroman = "I" | "II" | "III" | "IV" | "V" | "VI" | "VII" | "VIII" | "IX" | "X" | "XI" | "XII";
  760. monthtext = monthfull | monthabbr | monthroman;
  761. /* Time formats */
  762. timetiny12 = hour12 space? meridian;
  763. timeshort12 = hour12[:.]minutelz space? meridian;
  764. timelong12 = hour12[:.]minute[:.]secondlz space? meridian;
  765. timeshort24 = 't'? hour24[:.]minute;
  766. timelong24 = 't'? hour24[:.]minute[:.]second;
  767. iso8601long = 't'? hour24 [:.] minute [:.] second frac;
  768. /* iso8601shorttz = hour24 [:] minutelz space? (tzcorrection | tz); */
  769. iso8601normtz = 't'? hour24 [:.] minute [:.] secondlz space? (tzcorrection | tz);
  770. /* iso8601longtz = hour24 [:] minute [:] secondlz frac space? (tzcorrection | tz); */
  771. gnunocolon = 't'? hour24lz minutelz;
  772. /* gnunocolontz = hour24lz minutelz space? (tzcorrection | tz); */
  773. iso8601nocolon = 't'? hour24lz minutelz secondlz;
  774. /* iso8601nocolontz = hour24lz minutelz secondlz space? (tzcorrection | tz); */
  775. /* Date formats */
  776. americanshort = month "/" day;
  777. american = month "/" day "/" year;
  778. iso8601dateslash = year4 "/" monthlz "/" daylz "/"?;
  779. dateslash = year4 "/" month "/" day;
  780. iso8601date4 = year4withsign "-" monthlz "-" daylz;
  781. iso8601date2 = year2 "-" monthlz "-" daylz;
  782. gnudateshorter = year4 "-" month;
  783. gnudateshort = year "-" month "-" day;
  784. pointeddate4 = day [.\t-] month [.-] year4;
  785. pointeddate2 = day [.\t] month "." year2;
  786. datefull = day ([ \t.-])* monthtext ([ \t.-])* year;
  787. datenoday = monthtext ([ .\t-])* year4;
  788. datenodayrev = year4 ([ .\t-])* monthtext;
  789. datetextual = monthtext ([ .\t-])* day [,.stndrh\t ]+ year;
  790. datenoyear = monthtext ([ .\t-])* day ([,.stndrh\t ]+|[\000]);
  791. datenoyearrev = day ([ .\t-])* monthtext;
  792. datenocolon = year4 monthlz daylz;
  793. /* Special formats */
  794. soap = year4 "-" monthlz "-" daylz "T" hour24lz ":" minutelz ":" secondlz frac tzcorrection?;
  795. xmlrpc = year4 monthlz daylz "T" hour24 ":" minutelz ":" secondlz;
  796. xmlrpcnocolon = year4 monthlz daylz 't' hour24 minutelz secondlz;
  797. wddx = year4 "-" month "-" day "T" hour24 ":" minute ":" second;
  798. pgydotd = year4 "."? dayofyear;
  799. pgtextshort = monthabbr "-" daylz "-" year;
  800. pgtextreverse = year "-" monthabbr "-" daylz;
  801. mssqltime = hour12 ":" minutelz ":" secondlz [:.] [0-9]+ meridian;
  802. isoweekday = year4 "-"? "W" weekofyear "-"? [0-7];
  803. isoweek = year4 "-"? "W" weekofyear;
  804. exif = year4 ":" monthlz ":" daylz " " hour24lz ":" minutelz ":" secondlz;
  805. firstdayof = 'first day of';
  806. lastdayof = 'last day of';
  807. backof = 'back of ' hour24 (space? meridian)?;
  808. frontof = 'front of ' hour24 (space? meridian)?;
  809. /* Common Log Format: 10/Oct/2000:13:55:36 -0700 */
  810. clf = day "/" monthabbr "/" year4 ":" hour24lz ":" minutelz ":" secondlz space tzcorrection;
  811. /* Timestamp format: @1126396800 */
  812. timestamp = "@" "-"? [0-9]+;
  813. /* To fix some ambiguities */
  814. dateshortwithtimeshort12 = datenoyear timeshort12;
  815. dateshortwithtimelong12 = datenoyear timelong12;
  816. dateshortwithtimeshort = datenoyear timeshort24;
  817. dateshortwithtimelong = datenoyear timelong24;
  818. dateshortwithtimelongtz = datenoyear iso8601normtz;
  819. /*
  820. * Relative regexps
  821. */
  822. reltextnumber = 'first'|'second'|'third'|'fourth'|'fifth'|'sixth'|'seventh'|'eight'|'eighth'|'ninth'|'tenth'|'eleventh'|'twelfth';
  823. reltexttext = 'next'|'last'|'previous'|'this';
  824. reltextunit = (('sec'|'second'|'min'|'minute'|'hour'|'day'|'fortnight'|'forthnight'|'month'|'year') 's'?) | 'weeks' | daytext;
  825. relnumber = ([+-]*[ \t]*[0-9]+);
  826. relative = relnumber space? (reltextunit | 'week' );
  827. relativetext = (reltextnumber|reltexttext) space reltextunit;
  828. relativetextweek = reltexttext space 'week';
  829. weekdayof = (reltextnumber|reltexttext) space (dayfull|dayabbr) space 'of';
  830. */
  831. /*!re2c
  832. /* so that vim highlights correctly */
  833. 'yesterday'
  834. {
  835. DEBUG_OUTPUT("yesterday");
  836. TIMELIB_INIT;
  837. TIMELIB_HAVE_RELATIVE();
  838. TIMELIB_UNHAVE_TIME();
  839. s->time->relative.d = -1;
  840. TIMELIB_DEINIT;
  841. return TIMELIB_RELATIVE;
  842. }
  843. 'now'
  844. {
  845. DEBUG_OUTPUT("now");
  846. TIMELIB_INIT;
  847. TIMELIB_DEINIT;
  848. return TIMELIB_RELATIVE;
  849. }
  850. 'noon'
  851. {
  852. DEBUG_OUTPUT("noon");
  853. TIMELIB_INIT;
  854. TIMELIB_UNHAVE_TIME();
  855. TIMELIB_HAVE_TIME();
  856. s->time->h = 12;
  857. TIMELIB_DEINIT;
  858. return TIMELIB_RELATIVE;
  859. }
  860. 'midnight' | 'today'
  861. {
  862. DEBUG_OUTPUT("midnight | today");
  863. TIMELIB_INIT;
  864. TIMELIB_UNHAVE_TIME();
  865. TIMELIB_DEINIT;
  866. return TIMELIB_RELATIVE;
  867. }
  868. 'tomorrow'
  869. {
  870. DEBUG_OUTPUT("tomorrow");
  871. TIMELIB_INIT;
  872. TIMELIB_HAVE_RELATIVE();
  873. TIMELIB_UNHAVE_TIME();
  874. s->time->relative.d = 1;
  875. TIMELIB_DEINIT;
  876. return TIMELIB_RELATIVE;
  877. }
  878. timestamp
  879. {
  880. timelib_ull i;
  881. TIMELIB_INIT;
  882. TIMELIB_HAVE_RELATIVE();
  883. TIMELIB_UNHAVE_DATE();
  884. TIMELIB_UNHAVE_TIME();
  885. TIMELIB_HAVE_TZ();
  886. i = timelib_get_unsigned_nr((char **) &ptr, 24);
  887. s->time->y = 1970;
  888. s->time->m = 1;
  889. s->time->d = 1;
  890. s->time->h = s->time->i = s->time->s = 0;
  891. s->time->f = 0.0;
  892. s->time->relative.s += i;
  893. s->time->is_localtime = 1;
  894. s->time->zone_type = TIMELIB_ZONETYPE_OFFSET;
  895. s->time->z = 0;
  896. s->time->dst = 0;
  897. TIMELIB_DEINIT;
  898. return TIMELIB_RELATIVE;
  899. }
  900. firstdayof | lastdayof
  901. {
  902. DEBUG_OUTPUT("firstdayof | lastdayof");
  903. TIMELIB_INIT;
  904. TIMELIB_HAVE_RELATIVE();
  905. /* skip "last day of" or "first day of" */
  906. if (*ptr == 'l' || *ptr == 'L') {
  907. s->time->relative.first_last_day_of = TIMELIB_SPECIAL_LAST_DAY_OF_MONTH;
  908. } else {
  909. s->time->relative.first_last_day_of = TIMELIB_SPECIAL_FIRST_DAY_OF_MONTH;
  910. }
  911. TIMELIB_DEINIT;
  912. return TIMELIB_LF_DAY_OF_MONTH;
  913. }
  914. backof | frontof
  915. {
  916. DEBUG_OUTPUT("backof | frontof");
  917. TIMELIB_INIT;
  918. TIMELIB_UNHAVE_TIME();
  919. TIMELIB_HAVE_TIME();
  920. if (*ptr == 'b') {
  921. s->time->h = timelib_get_nr((char **) &ptr, 2);
  922. s->time->i = 15;
  923. } else {
  924. s->time->h = timelib_get_nr((char **) &ptr, 2) - 1;
  925. s->time->i = 45;
  926. }
  927. if (*ptr != '\0' ) {
  928. timelib_eat_spaces((char **) &ptr);
  929. s->time->h += timelib_meridian((char **) &ptr, s->time->h);
  930. }
  931. TIMELIB_DEINIT;
  932. return TIMELIB_LF_DAY_OF_MONTH;
  933. }
  934. weekdayof
  935. {
  936. timelib_sll i;
  937. int behavior = 0;
  938. DEBUG_OUTPUT("weekdayof");
  939. TIMELIB_INIT;
  940. TIMELIB_HAVE_RELATIVE();
  941. TIMELIB_HAVE_SPECIAL_RELATIVE();
  942. i = timelib_get_relative_text((char **) &ptr, &behavior);
  943. timelib_eat_spaces((char **) &ptr);
  944. if (i > 0) { /* first, second... etc */
  945. s->time->relative.special.type = TIMELIB_SPECIAL_DAY_OF_WEEK_IN_MONTH;
  946. timelib_set_relative((char **) &ptr, i, 1, s);
  947. } else { /* last */
  948. s->time->relative.special.type = TIMELIB_SPECIAL_LAST_DAY_OF_WEEK_IN_MONTH;
  949. timelib_set_relative((char **) &ptr, i, behavior, s);
  950. }
  951. TIMELIB_DEINIT;
  952. return TIMELIB_WEEK_DAY_OF_MONTH;
  953. }
  954. timetiny12 | timeshort12 | timelong12
  955. {
  956. DEBUG_OUTPUT("timetiny12 | timeshort12 | timelong12");
  957. TIMELIB_INIT;
  958. TIMELIB_HAVE_TIME();
  959. s->time->h = timelib_get_nr((char **) &ptr, 2);
  960. if (*ptr == ':' || *ptr == '.') {
  961. s->time->i = timelib_get_nr((char **) &ptr, 2);
  962. if (*ptr == ':' || *ptr == '.') {
  963. s->time->s = timelib_get_nr((char **) &ptr, 2);
  964. }
  965. }
  966. s->time->h += timelib_meridian((char **) &ptr, s->time->h);
  967. TIMELIB_DEINIT;
  968. return TIMELIB_TIME12;
  969. }
  970. mssqltime
  971. {
  972. DEBUG_OUTPUT("mssqltime");
  973. TIMELIB_INIT;
  974. TIMELIB_HAVE_TIME();
  975. s->time->h = timelib_get_nr((char **) &ptr, 2);
  976. s->time->i = timelib_get_nr((char **) &ptr, 2);
  977. if (*ptr == ':' || *ptr == '.') {
  978. s->time->s = timelib_get_nr((char **) &ptr, 2);
  979. if (*ptr == ':' || *ptr == '.') {
  980. s->time->f = timelib_get_frac_nr((char **) &ptr, 8);
  981. }
  982. }
  983. timelib_eat_spaces((char **) &ptr);
  984. s->time->h += timelib_meridian((char **) &ptr, s->time->h);
  985. TIMELIB_DEINIT;
  986. return TIMELIB_TIME24_WITH_ZONE;
  987. }
  988. timeshort24 | timelong24 /* | iso8601short | iso8601norm */ | iso8601long /*| iso8601shorttz | iso8601normtz | iso8601longtz*/
  989. {
  990. int tz_not_found;
  991. DEBUG_OUTPUT("timeshort24 | timelong24 | iso8601long");
  992. TIMELIB_INIT;
  993. TIMELIB_HAVE_TIME();
  994. s->time->h = timelib_get_nr((char **) &ptr, 2);
  995. s->time->i = timelib_get_nr((char **) &ptr, 2);
  996. if (*ptr == ':' || *ptr == '.') {
  997. s->time->s = timelib_get_nr((char **) &ptr, 2);
  998. if (*ptr == '.') {
  999. s->time->f = timelib_get_frac_nr((char **) &ptr, 8);
  1000. }
  1001. }
  1002. if (*ptr != '\0') {
  1003. s->time->z = timelib_parse_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper);
  1004. if (tz_not_found) {
  1005. add_error(s, "The timezone could not be found in the database");
  1006. }
  1007. }
  1008. TIMELIB_DEINIT;
  1009. return TIMELIB_TIME24_WITH_ZONE;
  1010. }
  1011. gnunocolon
  1012. {
  1013. DEBUG_OUTPUT("gnunocolon");
  1014. TIMELIB_INIT;
  1015. switch (s->time->have_time) {
  1016. case 0:
  1017. s->time->h = timelib_get_nr((char **) &ptr, 2);
  1018. s->time->i = timelib_get_nr((char **) &ptr, 2);
  1019. s->time->s = 0;
  1020. break;
  1021. case 1:
  1022. s->time->y = timelib_get_nr((char **) &ptr, 4);
  1023. break;
  1024. default:
  1025. TIMELIB_DEINIT;
  1026. add_error(s, "Double time specification");
  1027. return TIMELIB_ERROR;
  1028. }
  1029. s->time->have_time++;
  1030. TIMELIB_DEINIT;
  1031. return TIMELIB_GNU_NOCOLON;
  1032. }
  1033. /*
  1034. gnunocolontz
  1035. {
  1036. DEBUG_OUTPUT("gnunocolontz");
  1037. TIMELIB_INIT;
  1038. switch (s->time->have_time) {
  1039. case 0:
  1040. s->time->h = timelib_get_nr((char **) &ptr, 2);
  1041. s->time->i = timelib_get_nr((char **) &ptr, 2);
  1042. s->time->s = 0;
  1043. s->time->z = timelib_parse_zone((char **) &ptr, &s->time->dst, s->time, s->tzdb, tz_get_wrapper);
  1044. break;
  1045. case 1:
  1046. s->time->y = timelib_get_nr((char **) &ptr, 4);
  1047. break;
  1048. default:
  1049. TIMELIB_DEINIT;
  1050. return TIMELIB_ERROR;
  1051. }
  1052. s->time->have_time++;
  1053. TIMELIB_DEINIT;
  1054. return TIMELIB_GNU_NOCOLON_TZ;
  1055. }
  1056. */
  1057. iso8601nocolon /*| iso8601nocolontz*/
  1058. {
  1059. int tz_not_found;
  1060. DEBUG_OUTPUT("iso8601nocolon");
  1061. TIMELIB_INIT;
  1062. TIMELIB_HAVE_TIME();
  1063. s->time->h = timelib_get_nr((char **) &ptr, 2);
  1064. s->time->i = timelib_get_nr((char **) &ptr, 2);
  1065. s->time->s = timelib_get_nr((char **) &ptr, 2);
  1066. if (*ptr != '\0') {
  1067. s->time->z = timelib_parse_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper);
  1068. if (tz_not_found) {
  1069. add_error(s, "The timezone could not be found in the database");
  1070. }
  1071. }
  1072. TIMELIB_DEINIT;
  1073. return TIMELIB_ISO_NOCOLON;
  1074. }
  1075. americanshort | american
  1076. {
  1077. int length = 0;
  1078. DEBUG_OUTPUT("americanshort | american");
  1079. TIMELIB_INIT;
  1080. TIMELIB_HAVE_DATE();
  1081. s->time->m = timelib_get_nr((char **) &ptr, 2);
  1082. s->time->d = timelib_get_nr((char **) &ptr, 2);
  1083. if (*ptr == '/') {
  1084. s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
  1085. TIMELIB_PROCESS_YEAR(s->time->y, length);
  1086. }
  1087. TIMELIB_DEINIT;
  1088. return TIMELIB_AMERICAN;
  1089. }
  1090. iso8601date4 | iso8601dateslash | dateslash
  1091. {
  1092. DEBUG_OUTPUT("iso8601date4 | iso8601date2 | iso8601dateslash | dateslash");
  1093. TIMELIB_INIT;
  1094. TIMELIB_HAVE_DATE();
  1095. s->time->y = timelib_get_unsigned_nr((char **) &ptr, 4);
  1096. s->time->m = timelib_get_nr((char **) &ptr, 2);
  1097. s->time->d = timelib_get_nr((char **) &ptr, 2);
  1098. TIMELIB_DEINIT;
  1099. return TIMELIB_ISO_DATE;
  1100. }
  1101. iso8601date2
  1102. {
  1103. int length = 0;
  1104. DEBUG_OUTPUT("iso8601date2");
  1105. TIMELIB_INIT;
  1106. TIMELIB_HAVE_DATE();
  1107. s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
  1108. s->time->m = timelib_get_nr((char **) &ptr, 2);
  1109. s->time->d = timelib_get_nr((char **) &ptr, 2);
  1110. TIMELIB_PROCESS_YEAR(s->time->y, length);
  1111. TIMELIB_DEINIT;
  1112. return TIMELIB_ISO_DATE;
  1113. }
  1114. gnudateshorter
  1115. {
  1116. int length = 0;
  1117. DEBUG_OUTPUT("gnudateshorter");
  1118. TIMELIB_INIT;
  1119. TIMELIB_HAVE_DATE();
  1120. s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
  1121. s->time->m = timelib_get_nr((char **) &ptr, 2);
  1122. s->time->d = 1;
  1123. TIMELIB_PROCESS_YEAR(s->time->y, length);
  1124. TIMELIB_DEINIT;
  1125. return TIMELIB_ISO_DATE;
  1126. }
  1127. gnudateshort
  1128. {
  1129. int length = 0;
  1130. DEBUG_OUTPUT("gnudateshort");
  1131. TIMELIB_INIT;
  1132. TIMELIB_HAVE_DATE();
  1133. s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
  1134. s->time->m = timelib_get_nr((char **) &ptr, 2);
  1135. s->time->d = timelib_get_nr((char **) &ptr, 2);
  1136. TIMELIB_PROCESS_YEAR(s->time->y, length);
  1137. TIMELIB_DEINIT;
  1138. return TIMELIB_ISO_DATE;
  1139. }
  1140. datefull
  1141. {
  1142. int length = 0;
  1143. DEBUG_OUTPUT("datefull");
  1144. TIMELIB_INIT;
  1145. TIMELIB_HAVE_DATE();
  1146. s->time->d = timelib_get_nr((char **) &ptr, 2);
  1147. timelib_skip_day_suffix((char **) &ptr);
  1148. s->time->m = timelib_get_month((char **) &ptr);
  1149. s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
  1150. TIMELIB_PROCESS_YEAR(s->time->y, length);
  1151. TIMELIB_DEINIT;
  1152. return TIMELIB_DATE_FULL;
  1153. }
  1154. pointeddate4
  1155. {
  1156. DEBUG_OUTPUT("pointed date YYYY");
  1157. TIMELIB_INIT;
  1158. TIMELIB_HAVE_DATE();
  1159. s->time->d = timelib_get_nr((char **) &ptr, 2);
  1160. s->time->m = timelib_get_nr((char **) &ptr, 2);
  1161. s->time->y = timelib_get_nr((char **) &ptr, 4);
  1162. TIMELIB_DEINIT;
  1163. return TIMELIB_DATE_FULL_POINTED;
  1164. }
  1165. pointeddate2
  1166. {
  1167. int length = 0;
  1168. DEBUG_OUTPUT("pointed date YY");
  1169. TIMELIB_INIT;
  1170. TIMELIB_HAVE_DATE();
  1171. s->time->d = timelib_get_nr((char **) &ptr, 2);
  1172. s->time->m = timelib_get_nr((char **) &ptr, 2);
  1173. s->time->y = timelib_get_nr_ex((char **) &ptr, 2, &length);
  1174. TIMELIB_PROCESS_YEAR(s->time->y, length);
  1175. TIMELIB_DEINIT;
  1176. return TIMELIB_DATE_FULL_POINTED;
  1177. }
  1178. datenoday
  1179. {
  1180. int length = 0;
  1181. DEBUG_OUTPUT("datenoday");
  1182. TIMELIB_INIT;
  1183. TIMELIB_HAVE_DATE();
  1184. s->time->m = timelib_get_month((char **) &ptr);
  1185. s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
  1186. s->time->d = 1;
  1187. TIMELIB_PROCESS_YEAR(s->time->y, length);
  1188. TIMELIB_DEINIT;
  1189. return TIMELIB_DATE_NO_DAY;
  1190. }
  1191. datenodayrev
  1192. {
  1193. int length = 0;
  1194. DEBUG_OUTPUT("datenodayrev");
  1195. TIMELIB_INIT;
  1196. TIMELIB_HAVE_DATE();
  1197. s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
  1198. s->time->m = timelib_get_month((char **) &ptr);
  1199. s->time->d = 1;
  1200. TIMELIB_PROCESS_YEAR(s->time->y, length);
  1201. TIMELIB_DEINIT;
  1202. return TIMELIB_DATE_NO_DAY;
  1203. }
  1204. datetextual | datenoyear
  1205. {
  1206. int length = 0;
  1207. DEBUG_OUTPUT("datetextual | datenoyear");
  1208. TIMELIB_INIT;
  1209. TIMELIB_HAVE_DATE();
  1210. s->time->m = timelib_get_month((char **) &ptr);
  1211. s->time->d = timelib_get_nr((char **) &ptr, 2);
  1212. s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
  1213. TIMELIB_PROCESS_YEAR(s->time->y, length);
  1214. TIMELIB_DEINIT;
  1215. return TIMELIB_DATE_TEXT;
  1216. }
  1217. datenoyearrev
  1218. {
  1219. DEBUG_OUTPUT("datenoyearrev");
  1220. TIMELIB_INIT;
  1221. TIMELIB_HAVE_DATE();
  1222. s->time->d = timelib_get_nr((char **) &ptr, 2);
  1223. timelib_skip_day_suffix((char **) &ptr);
  1224. s->time->m = timelib_get_month((char **) &ptr);
  1225. TIMELIB_DEINIT;
  1226. return TIMELIB_DATE_TEXT;
  1227. }
  1228. datenocolon
  1229. {
  1230. DEBUG_OUTPUT("datenocolon");
  1231. TIMELIB_INIT;
  1232. TIMELIB_HAVE_DATE();
  1233. s->time->y = timelib_get_nr((char **) &ptr, 4);
  1234. s->time->m = timelib_get_nr((char **) &ptr, 2);
  1235. s->time->d = timelib_get_nr((char **) &ptr, 2);
  1236. TIMELIB_DEINIT;
  1237. return TIMELIB_DATE_NOCOLON;
  1238. }
  1239. xmlrpc | xmlrpcnocolon | soap | wddx | exif
  1240. {
  1241. int tz_not_found;
  1242. DEBUG_OUTPUT("xmlrpc | xmlrpcnocolon | soap | wddx | exif");
  1243. TIMELIB_INIT;
  1244. TIMELIB_HAVE_TIME();
  1245. TIMELIB_HAVE_DATE();
  1246. s->time->y = timelib_get_nr((char **) &ptr, 4);
  1247. s->time->m = timelib_get_nr((char **) &ptr, 2);
  1248. s->time->d = timelib_get_nr((char **) &ptr, 2);
  1249. s->time->h = timelib_get_nr((char **) &ptr, 2);
  1250. s->time->i = timelib_get_nr((char **) &ptr, 2);
  1251. s->time->s = timelib_get_nr((char **) &ptr, 2);
  1252. if (*ptr == '.') {
  1253. s->time->f = timelib_get_frac_nr((char **) &ptr, 9);
  1254. if (*ptr) { /* timezone is optional */
  1255. s->time->z = timelib_parse_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper);
  1256. if (tz_not_found) {
  1257. add_error(s, "The timezone could not be found in the database");
  1258. }
  1259. }
  1260. }
  1261. TIMELIB_DEINIT;
  1262. return TIMELIB_XMLRPC_SOAP;
  1263. }
  1264. pgydotd
  1265. {
  1266. int length = 0;
  1267. DEBUG_OUTPUT("pgydotd");
  1268. TIMELIB_INIT;
  1269. TIMELIB_HAVE_DATE();
  1270. s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
  1271. s->time->d = timelib_get_nr((char **) &ptr, 3);
  1272. s->time->m = 1;
  1273. TIMELIB_PROCESS_YEAR(s->time->y, length);
  1274. TIMELIB_DEINIT;
  1275. return TIMELIB_PG_YEARDAY;
  1276. }
  1277. isoweekday
  1278. {
  1279. timelib_sll w, d;
  1280. DEBUG_OUTPUT("isoweekday");
  1281. TIMELIB_INIT;
  1282. TIMELIB_HAVE_DATE();
  1283. TIMELIB_HAVE_RELATIVE();
  1284. s->time->y = timelib_get_nr((char **) &ptr, 4);
  1285. w = timelib_get_nr((char **) &ptr, 2);
  1286. d = timelib_get_nr((char **) &ptr, 1);
  1287. s->time->m = 1;
  1288. s->time->d = 1;
  1289. s->time->relative.d = timelib_daynr_from_weeknr(s->time->y, w, d);
  1290. TIMELIB_DEINIT;
  1291. return TIMELIB_ISO_WEEK;
  1292. }
  1293. isoweek
  1294. {
  1295. timelib_sll w, d;
  1296. DEBUG_OUTPUT("isoweek");
  1297. TIMELIB_INIT;
  1298. TIMELIB_HAVE_DATE();
  1299. TIMELIB_HAVE_RELATIVE();
  1300. s->time->y = timelib_get_nr((char **) &ptr, 4);
  1301. w = timelib_get_nr((char **) &ptr, 2);
  1302. d = 1;
  1303. s->time->m = 1;
  1304. s->time->d = 1;
  1305. s->time->relative.d = timelib_daynr_from_weeknr(s->time->y, w, d);
  1306. TIMELIB_DEINIT;
  1307. return TIMELIB_ISO_WEEK;
  1308. }
  1309. pgtextshort
  1310. {
  1311. int length = 0;
  1312. DEBUG_OUTPUT("pgtextshort");
  1313. TIMELIB_INIT;
  1314. TIMELIB_HAVE_DATE();
  1315. s->time->m = timelib_get_month((char **) &ptr);
  1316. s->time->d = timelib_get_nr((char **) &ptr, 2);
  1317. s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
  1318. TIMELIB_PROCESS_YEAR(s->time->y, length);
  1319. TIMELIB_DEINIT;
  1320. return TIMELIB_PG_TEXT;
  1321. }
  1322. pgtextreverse
  1323. {
  1324. int length = 0;
  1325. DEBUG_OUTPUT("pgtextreverse");
  1326. TIMELIB_INIT;
  1327. TIMELIB_HAVE_DATE();
  1328. s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
  1329. s->time->m = timelib_get_month((char **) &ptr);
  1330. s->time->d = timelib_get_nr((char **) &ptr, 2);
  1331. TIMELIB_PROCESS_YEAR(s->time->y, length);
  1332. TIMELIB_DEINIT;
  1333. return TIMELIB_PG_TEXT;
  1334. }
  1335. clf
  1336. {
  1337. int tz_not_found;
  1338. DEBUG_OUTPUT("clf");
  1339. TIMELIB_INIT;
  1340. TIMELIB_HAVE_TIME();
  1341. TIMELIB_HAVE_DATE();
  1342. s->time->d = timelib_get_nr((char **) &ptr, 2);
  1343. s->time->m = timelib_get_month((char **) &ptr);
  1344. s->time->y = timelib_get_nr((char **) &ptr, 4);
  1345. s->time->h = timelib_get_nr((char **) &ptr, 2);
  1346. s->time->i = timelib_get_nr((char **) &ptr, 2);
  1347. s->time->s = timelib_get_nr((char **) &ptr, 2);
  1348. s->time->z = timelib_parse_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper);
  1349. if (tz_not_found) {
  1350. add_error(s, "The timezone could not be found in the database");
  1351. }
  1352. TIMELIB_DEINIT;
  1353. return TIMELIB_CLF;
  1354. }
  1355. year4
  1356. {
  1357. DEBUG_OUTPUT("year4");
  1358. TIMELIB_INIT;
  1359. s->time->y = timelib_get_nr((char **) &ptr, 4);
  1360. TIMELIB_DEINIT;
  1361. return TIMELIB_CLF;
  1362. }
  1363. ago
  1364. {
  1365. DEBUG_OUTPUT("ago");
  1366. TIMELIB_INIT;
  1367. s->time->relative.y = 0 - s->time->relative.y;
  1368. s->time->relative.m = 0 - s->time->relative.m;
  1369. s->time->relative.d = 0 - s->time->relative.d;
  1370. s->time->relative.h = 0 - s->time->relative.h;
  1371. s->time->relative.i = 0 - s->time->relative.i;
  1372. s->time->relative.s = 0 - s->time->relative.s;
  1373. s->time->relative.weekday = 0 - s->time->relative.weekday;
  1374. if (s->time->relative.weekday == 0) {
  1375. s->time->relative.weekday = -7;
  1376. }
  1377. if (s->time->relative.have_special_relative && s->time->relative.special.type == TIMELIB_SPECIAL_WEEKDAY) {
  1378. s->time->relative.special.amount = 0 - s->time->relative.special.amount;
  1379. }
  1380. TIMELIB_DEINIT;
  1381. return TIMELIB_AGO;
  1382. }
  1383. daytext
  1384. {
  1385. const timelib_relunit* relunit;
  1386. DEBUG_OUTPUT("daytext");
  1387. TIMELIB_INIT;
  1388. TIMELIB_HAVE_RELATIVE();
  1389. TIMELIB_HAVE_WEEKDAY_RELATIVE();
  1390. TIMELIB_UNHAVE_TIME();
  1391. relunit = timelib_lookup_relunit((char**) &ptr);
  1392. s->time->relative.weekday = relunit->multiplier;
  1393. if (s->time->relative.weekday_behavior != 2) {
  1394. s->time->relative.weekday_behavior = 1;
  1395. }
  1396. TIMELIB_DEINIT;
  1397. return TIMELIB_WEEKDAY;
  1398. }
  1399. relativetextweek
  1400. {
  1401. timelib_sll i;
  1402. int behavior = 0;
  1403. DEBUG_OUTPUT("relativetextweek");
  1404. TIMELIB_INIT;
  1405. TIMELIB_HAVE_RELATIVE();
  1406. while(*ptr) {
  1407. i = timelib_get_relative_text((char **) &ptr, &behavior);
  1408. timelib_eat_spaces((char **) &ptr);
  1409. timelib_set_relative((char **) &ptr, i, behavior, s);
  1410. s->time->relative.weekday_behavior = 2;
  1411. /* to handle the format weekday + last/this/next week */
  1412. if (s->time->relative.have_weekday_relative == 0) {
  1413. TIMELIB_HAVE_WEEKDAY_RELATIVE();
  1414. s->time->relative.weekday = 1;
  1415. }
  1416. }
  1417. TIMELIB_DEINIT;
  1418. return TIMELIB_RELATIVE;
  1419. }
  1420. relativetext
  1421. {
  1422. timelib_sll i;
  1423. int behavior = 0;
  1424. DEBUG_OUTPUT("relativetext");
  1425. TIMELIB_INIT;
  1426. TIMELIB_HAVE_RELATIVE();
  1427. while(*ptr) {
  1428. i = timelib_get_relative_text((char **) &ptr, &behavior);
  1429. timelib_eat_spaces((char **) &ptr);
  1430. timelib_set_relative((char **) &ptr, i, behavior, s);
  1431. }
  1432. TIMELIB_DEINIT;
  1433. return TIMELIB_RELATIVE;
  1434. }
  1435. monthfull | monthabbr
  1436. {
  1437. DEBUG_OUTPUT("monthtext");
  1438. TIMELIB_INIT;
  1439. TIMELIB_HAVE_DATE();
  1440. s->time->m = timelib_lookup_month((char **) &ptr);
  1441. TIMELIB_DEINIT;
  1442. return TIMELIB_DATE_TEXT;
  1443. }
  1444. tzcorrection | tz
  1445. {
  1446. int tz_not_found;
  1447. DEBUG_OUTPUT("tzcorrection | tz");
  1448. TIMELIB_INIT;
  1449. TIMELIB_HAVE_TZ();
  1450. s->time->z = timelib_parse_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper);
  1451. if (tz_not_found) {
  1452. add_error(s, "The timezone could not be found in the database");
  1453. }
  1454. TIMELIB_DEINIT;
  1455. return TIMELIB_TIMEZONE;
  1456. }
  1457. dateshortwithtimeshort12 | dateshortwithtimelong12
  1458. {
  1459. DEBUG_OUTPUT("dateshortwithtimeshort12 | dateshortwithtimelong12");
  1460. TIMELIB_INIT;
  1461. TIMELIB_HAVE_DATE();
  1462. s->time->m = timelib_get_month((char **) &ptr);
  1463. s->time->d = timelib_get_nr((char **) &ptr, 2);
  1464. TIMELIB_HAVE_TIME();
  1465. s->time->h = timelib_get_nr((char **) &ptr, 2);
  1466. s->time->i = timelib_get_nr((char **) &ptr, 2);
  1467. if (*ptr == ':' || *ptr == '.') {
  1468. s->time->s = timelib_get_nr((char **) &ptr, 2);
  1469. if (*ptr == '.') {
  1470. s->time->f = timelib_get_frac_nr((char **) &ptr, 8);
  1471. }
  1472. }
  1473. s->time->h += timelib_meridian((char **) &ptr, s->time->h);
  1474. TIMELIB_DEINIT;
  1475. return TIMELIB_SHORTDATE_WITH_TIME;
  1476. }
  1477. dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz
  1478. {
  1479. int tz_not_found;
  1480. DEBUG_OUTPUT("dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz");
  1481. TIMELIB_INIT;
  1482. TIMELIB_HAVE_DATE();
  1483. s->time->m = timelib_get_month((char **) &ptr);
  1484. s->time->d = timelib_get_nr((char **) &ptr, 2);
  1485. TIMELIB_HAVE_TIME();
  1486. s->time->h = timelib_get_nr((char **) &ptr, 2);
  1487. s->time->i = timelib_get_nr((char **) &ptr, 2);
  1488. if (*ptr == ':') {
  1489. s->time->s = timelib_get_nr((char **) &ptr, 2);
  1490. if (*ptr == '.') {
  1491. s->time->f = timelib_get_frac_nr((char **) &ptr, 8);
  1492. }
  1493. }
  1494. if (*ptr != '\0') {
  1495. s->time->z = timelib_parse_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper);
  1496. if (tz_not_found) {
  1497. add_error(s, "The timezone could not be found in the database");
  1498. }
  1499. }
  1500. TIMELIB_DEINIT;
  1501. return TIMELIB_SHORTDATE_WITH_TIME;
  1502. }
  1503. relative
  1504. {
  1505. timelib_ull i;
  1506. DEBUG_OUTPUT("relative");
  1507. TIMELIB_INIT;
  1508. TIMELIB_HAVE_RELATIVE();
  1509. while(*ptr) {
  1510. i = timelib_get_unsigned_nr((char **) &ptr, 24);
  1511. timelib_eat_spaces((char **) &ptr);
  1512. timelib_set_relative((char **) &ptr, i, 1, s);
  1513. }
  1514. TIMELIB_DEINIT;
  1515. return TIMELIB_RELATIVE;
  1516. }
  1517. [ .,\t]
  1518. {
  1519. goto std;
  1520. }
  1521. "\000"|"\n"
  1522. {
  1523. s->pos = cursor; s->line++;
  1524. goto std;
  1525. }
  1526. any
  1527. {
  1528. add_error(s, "Unexpected character");
  1529. goto std;
  1530. }
  1531. */
  1532. }
  1533. /*!max:re2c */
  1534. timelib_time* timelib_strtotime(char *s, size_t len, struct timelib_error_container **errors, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_get_wrapper)
  1535. {
  1536. Scanner in;
  1537. int t;
  1538. char *e = s + len - 1;
  1539. memset(&in, 0, sizeof(in));
  1540. in.errors = timelib_malloc(sizeof(struct timelib_error_container));
  1541. in.errors->warning_count = 0;
  1542. in.errors->warning_messages = NULL;
  1543. in.errors->error_count = 0;
  1544. in.errors->error_messages = NULL;
  1545. if (len > 0) {
  1546. while (isspace(*s) && s < e) {
  1547. s++;
  1548. }
  1549. while (isspace(*e) && e > s) {
  1550. e--;
  1551. }
  1552. }
  1553. if (e - s < 0) {
  1554. in.time = timelib_time_ctor();
  1555. add_error(&in, "Empty string");
  1556. if (errors) {
  1557. *errors = in.errors;
  1558. } else {
  1559. timelib_error_container_dtor(in.errors);
  1560. }
  1561. in.time->y = in.time->d = in.time->m = in.time->h = in.time->i = in.time->s = in.time->f = in.time->dst = in.time->z = TIMELIB_UNSET;
  1562. in.time->is_localtime = in.time->zone_type = 0;
  1563. return in.time;
  1564. }
  1565. e++;
  1566. in.str = timelib_malloc((e - s) + YYMAXFILL);
  1567. memset(in.str, 0, (e - s) + YYMAXFILL);
  1568. memcpy(in.str, s, (e - s));
  1569. in.lim = in.str + (e - s) + YYMAXFILL;
  1570. in.cur = in.str;
  1571. in.time = timelib_time_ctor();
  1572. in.time->y = TIMELIB_UNSET;
  1573. in.time->d = TIMELIB_UNSET;
  1574. in.time->m = TIMELIB_UNSET;
  1575. in.time->h = TIMELIB_UNSET;
  1576. in.time->i = TIMELIB_UNSET;
  1577. in.time->s = TIMELIB_UNSET;
  1578. in.time->f = TIMELIB_UNSET;
  1579. in.time->z = TIMELIB_UNSET;
  1580. in.time->dst = TIMELIB_UNSET;
  1581. in.tzdb = tzdb;
  1582. in.time->is_localtime = 0;
  1583. in.time->zone_type = 0;
  1584. in.time->relative.days = TIMELIB_UNSET;
  1585. do {
  1586. t = scan(&in, tz_get_wrapper);
  1587. #ifdef DEBUG_PARSER
  1588. printf("%d\n", t);
  1589. #endif
  1590. } while(t != EOI);
  1591. /* do funky checking whether the parsed time was valid time */
  1592. if (in.time->have_time && !timelib_valid_time( in.time->h, in.time->i, in.time->s)) {
  1593. add_warning(&in, "The parsed time was invalid");
  1594. }
  1595. /* do funky checking whether the parsed date was valid date */
  1596. if (in.time->have_date && !timelib_valid_date( in.time->y, in.time->m, in.time->d)) {
  1597. add_warning(&in, "The parsed date was invalid");
  1598. }
  1599. timelib_free(in.str);
  1600. if (errors) {
  1601. *errors = in.errors;
  1602. } else {
  1603. timelib_error_container_dtor(in.errors);
  1604. }
  1605. return in.time;
  1606. }
  1607. #define TIMELIB_CHECK_NUMBER \
  1608. if (strchr("0123456789", *ptr) == NULL) \
  1609. { \
  1610. add_pbf_error(s, "Unexpected data found.", string, begin); \
  1611. }
  1612. #define TIMELIB_CHECK_SIGNED_NUMBER \
  1613. if (strchr("-0123456789", *ptr) == NULL) \
  1614. { \
  1615. add_pbf_error(s, "Unexpected data found.", string, begin); \
  1616. }
  1617. static void timelib_time_reset_fields(timelib_time *time)
  1618. {
  1619. assert(time != NULL);
  1620. time->y = 1970;
  1621. time->m = 1;
  1622. time->d = 1;
  1623. time->h = time->i = time->s = 0;
  1624. time->f = 0.0;
  1625. time->tz_info = NULL;
  1626. }
  1627. static void timelib_time_reset_unset_fields(timelib_time *time)
  1628. {
  1629. assert(time != NULL);
  1630. if (time->y == TIMELIB_UNSET ) time->y = 1970;
  1631. if (time->m == TIMELIB_UNSET ) time->m = 1;
  1632. if (time->d == TIMELIB_UNSET ) time->d = 1;
  1633. if (time->h == TIMELIB_UNSET ) time->h = 0;
  1634. if (time->i == TIMELIB_UNSET ) time->i = 0;
  1635. if (time->s == TIMELIB_UNSET ) time->s = 0;
  1636. if (time->f == TIMELIB_UNSET ) time->f = 0.0;
  1637. }
  1638. timelib_time *timelib_parse_from_format(char *format, char *string, size_t len, timelib_error_container **errors, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_get_wrapper)
  1639. {
  1640. char *fptr = format;
  1641. char *ptr = string;
  1642. char *begin;
  1643. timelib_sll tmp;
  1644. Scanner in;
  1645. Scanner *s = &in;
  1646. int allow_extra = 0;
  1647. memset(&in, 0, sizeof(in));
  1648. in.errors = timelib_malloc(sizeof(struct timelib_error_container));
  1649. in.errors->warning_count = 0;
  1650. in.errors->warning_messages = NULL;
  1651. in.errors->error_count = 0;
  1652. in.errors->error_messages = NULL;
  1653. in.time = timelib_time_ctor();
  1654. in.time->y = TIMELIB_UNSET;
  1655. in.time->d = TIMELIB_UNSET;
  1656. in.time->m = TIMELIB_UNSET;
  1657. in.time->h = TIMELIB_UNSET;
  1658. in.time->i = TIMELIB_UNSET;
  1659. in.time->s = TIMELIB_UNSET;
  1660. in.time->f = TIMELIB_UNSET;
  1661. in.time->z = TIMELIB_UNSET;
  1662. in.time->dst = TIMELIB_UNSET;
  1663. in.tzdb = tzdb;
  1664. in.time->is_localtime = 0;
  1665. in.time->zone_type = 0;
  1666. /* Loop over the format string */
  1667. while (*fptr && *ptr) {
  1668. begin = ptr;
  1669. switch (*fptr) {
  1670. case 'D': /* three letter day */
  1671. case 'l': /* full day */
  1672. {
  1673. const timelib_relunit* tmprel = 0;
  1674. tmprel = timelib_lookup_relunit((char **) &ptr);
  1675. if (!tmprel) {
  1676. add_pbf_error(s, "A textual day could not be found", string, begin);
  1677. break;
  1678. } else {
  1679. in.time->have_relative = 1;
  1680. in.time->relative.have_weekday_relative = 1;
  1681. in.time->relative.weekday = tmprel->multiplier;
  1682. in.time->relative.weekday_behavior = 1;
  1683. }
  1684. }
  1685. break;
  1686. case 'd': /* two digit day, with leading zero */
  1687. case 'j': /* two digit day, without leading zero */
  1688. TIMELIB_CHECK_NUMBER;
  1689. if ((s->time->d = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) {
  1690. add_pbf_error(s, "A two digit day could not be found", string, begin);
  1691. }
  1692. break;
  1693. case 'S': /* day suffix, ignored, nor checked */
  1694. timelib_skip_day_suffix((char **) &ptr);
  1695. break;
  1696. case 'z': /* day of year - resets month (0 based) - also initializes everything else to !TIMELIB_UNSET */
  1697. TIMELIB_CHECK_NUMBER;
  1698. if ((tmp = timelib_get_nr((char **) &ptr, 3)) == TIMELIB_UNSET) {
  1699. add_pbf_error(s, "A three digit day-of-year could not be found", string, begin);
  1700. } else {
  1701. s->time->m = 1;
  1702. s->time->d = tmp + 1;
  1703. timelib_do_normalize(s->time);
  1704. }
  1705. break;
  1706. case 'm': /* two digit month, with leading zero */
  1707. case 'n': /* two digit month, without leading zero */
  1708. TIMELIB_CHECK_NUMBER;
  1709. if ((s->time->m = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) {
  1710. add_pbf_error(s, "A two digit month could not be found", string, begin);
  1711. }
  1712. break;
  1713. case 'M': /* three letter month */
  1714. case 'F': /* full month */
  1715. tmp = timelib_lookup_month((char **) &ptr);
  1716. if (!tmp) {
  1717. add_pbf_error(s, "A textual month could not be found", string, begin);
  1718. } else {
  1719. s->time->m = tmp;
  1720. }
  1721. break;
  1722. case 'y': /* two digit year */
  1723. {
  1724. int length = 0;
  1725. TIMELIB_CHECK_NUMBER;
  1726. if ((s->time->y = timelib_get_nr_ex((char **) &ptr, 2, &length)) == TIMELIB_UNSET) {
  1727. add_pbf_error(s, "A two digit year could not be found", string, begin);
  1728. }
  1729. TIMELIB_PROCESS_YEAR(s->time->y, length);
  1730. }
  1731. break;
  1732. case 'Y': /* four digit year */
  1733. TIMELIB_CHECK_NUMBER;
  1734. if ((s->time->y = timelib_get_nr((char **) &ptr, 4)) == TIMELIB_UNSET) {
  1735. add_pbf_error(s, "A four digit year could not be found", string, begin);
  1736. }
  1737. break;
  1738. case 'g': /* two digit hour, with leading zero */
  1739. case 'h': /* two digit hour, without leading zero */
  1740. TIMELIB_CHECK_NUMBER;
  1741. if ((s->time->h = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) {
  1742. add_pbf_error(s, "A two digit hour could not be found", string, begin);
  1743. }
  1744. if (s->time->h > 12) {
  1745. add_pbf_error(s, "Hour can not be higher than 12", string, begin);
  1746. }
  1747. break;
  1748. case 'G': /* two digit hour, with leading zero */
  1749. case 'H': /* two digit hour, without leading zero */
  1750. TIMELIB_CHECK_NUMBER;
  1751. if ((s->time->h = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) {
  1752. add_pbf_error(s, "A two digit hour could not be found", string, begin);
  1753. }
  1754. break;
  1755. case 'a': /* am/pm/a.m./p.m. */
  1756. case 'A': /* AM/PM/A.M./P.M. */
  1757. if (s->time->h == TIMELIB_UNSET) {
  1758. add_pbf_error(s, "Meridian can only come after an hour has been found", string, begin);
  1759. } else if ((tmp = timelib_meridian_with_check((char **) &ptr, s->time->h)) == TIMELIB_UNSET) {
  1760. add_pbf_error(s, "A meridian could not be found", string, begin);
  1761. } else {
  1762. s->time->h += tmp;
  1763. }
  1764. break;
  1765. case 'i': /* two digit minute, with leading zero */
  1766. {
  1767. int length;
  1768. timelib_sll min;
  1769. TIMELIB_CHECK_NUMBER;
  1770. min = timelib_get_nr_ex((char **) &ptr, 2, &length);
  1771. if (min == TIMELIB_UNSET || length != 2) {
  1772. add_pbf_error(s, "A two digit minute could not be found", string, begin);
  1773. } else {
  1774. s->time->i = min;
  1775. }
  1776. }
  1777. break;
  1778. case 's': /* two digit second, with leading zero */
  1779. {
  1780. int length;
  1781. timelib_sll sec;
  1782. TIMELIB_CHECK_NUMBER;
  1783. sec = timelib_get_nr_ex((char **) &ptr, 2, &length);
  1784. if (sec == TIMELIB_UNSET || length != 2) {
  1785. add_pbf_error(s, "A two digit second could not be found", string, begin);
  1786. } else {
  1787. s->time->s = sec;
  1788. }
  1789. }
  1790. break;
  1791. case 'u': /* up to six digit millisecond */
  1792. {
  1793. double f;
  1794. char *tptr;
  1795. TIMELIB_CHECK_NUMBER;
  1796. tptr = ptr;
  1797. if ((f = timelib_get_nr((char **) &ptr, 6)) == TIMELIB_UNSET || (ptr - tptr < 1)) {
  1798. add_pbf_error(s, "A six digit millisecond could not be found", string, begin);
  1799. } else {
  1800. s->time->f = (f / pow(10, (ptr - tptr)));
  1801. }
  1802. }
  1803. break;
  1804. case ' ': /* any sort of whitespace (' ' and \t) */
  1805. timelib_eat_spaces((char **) &ptr);
  1806. break;
  1807. case 'U': /* epoch seconds */
  1808. TIMELIB_CHECK_SIGNED_NUMBER;
  1809. TIMELIB_HAVE_RELATIVE();
  1810. tmp = timelib_get_unsigned_nr((char **) &ptr, 24);
  1811. s->time->y = 1970;
  1812. s->time->m = 1;
  1813. s->time->d = 1;
  1814. s->time->h = s->time->i = s->time->s = 0;
  1815. s->time->f = 0.0;
  1816. s->time->relative.s += tmp;
  1817. s->time->is_localtime = 1;
  1818. s->time->zone_type = TIMELIB_ZONETYPE_OFFSET;
  1819. s->time->z = 0;
  1820. s->time->dst = 0;
  1821. break;
  1822. case 'e': /* timezone */
  1823. case 'P': /* timezone */
  1824. case 'T': /* timezone */
  1825. case 'O': /* timezone */
  1826. {
  1827. int tz_not_found;
  1828. s->time->z = timelib_parse_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper);
  1829. if (tz_not_found) {
  1830. add_pbf_error(s, "The timezone could not be found in the database", string, begin);
  1831. }
  1832. }
  1833. break;
  1834. case '#': /* separation symbol */
  1835. if (*ptr == ';' || *ptr == ':' || *ptr == '/' || *ptr == '.' || *ptr == ',' || *ptr == '-' || *ptr == '(' || *ptr == ')') {
  1836. ++ptr;
  1837. } else {
  1838. add_pbf_error(s, "The separation symbol ([;:/.,-]) could not be found", string, begin);
  1839. }
  1840. break;
  1841. case ';':
  1842. case ':':
  1843. case '/':
  1844. case '.':
  1845. case ',':
  1846. case '-':
  1847. case '(':
  1848. case ')':
  1849. if (*ptr == *fptr) {
  1850. ++ptr;
  1851. } else {
  1852. add_pbf_error(s, "The separation symbol could not be found", string, begin);
  1853. }
  1854. break;
  1855. case '!': /* reset all fields to default */
  1856. timelib_time_reset_fields(s->time);
  1857. break; /* break intentionally not missing */
  1858. case '|': /* reset all fields to default when not set */
  1859. timelib_time_reset_unset_fields(s->time);
  1860. break; /* break intentionally not missing */
  1861. case '?': /* random char */
  1862. ++ptr;
  1863. break;
  1864. case '\\': /* escaped char */
  1865. if(!fptr[1]) {
  1866. add_pbf_error(s, "Escaped character expected", string, begin);
  1867. break;
  1868. }
  1869. fptr++;
  1870. if (*ptr == *fptr) {
  1871. ++ptr;
  1872. } else {
  1873. add_pbf_error(s, "The escaped character could not be found", string, begin);
  1874. }
  1875. break;
  1876. case '*': /* random chars until a separator or number ([ \t.,:;/-0123456789]) */
  1877. timelib_eat_until_separator((char **) &ptr);
  1878. break;
  1879. case '+': /* allow extra chars in the format */
  1880. allow_extra = 1;
  1881. break;
  1882. default:
  1883. if (*fptr != *ptr) {
  1884. add_pbf_error(s, "The format separator does not match", string, begin);
  1885. }
  1886. ptr++;
  1887. }
  1888. fptr++;
  1889. }
  1890. if (*ptr) {
  1891. if (allow_extra) {
  1892. add_pbf_warning(s, "Trailing data", string, ptr);
  1893. } else {
  1894. add_pbf_error(s, "Trailing data", string, ptr);
  1895. }
  1896. }
  1897. /* ignore trailing +'s */
  1898. while (*fptr == '+') {
  1899. fptr++;
  1900. }
  1901. if (*fptr) {
  1902. /* Trailing | and ! specifiers are valid. */
  1903. int done = 0;
  1904. while (*fptr && !done) {
  1905. switch (*fptr++) {
  1906. case '!': /* reset all fields to default */
  1907. timelib_time_reset_fields(s->time);
  1908. break;
  1909. case '|': /* reset all fields to default when not set */
  1910. timelib_time_reset_unset_fields(s->time);
  1911. break;
  1912. default:
  1913. add_pbf_error(s, "Data missing", string, ptr);
  1914. done = 1;
  1915. }
  1916. }
  1917. }
  1918. /* clean up a bit */
  1919. if (s->time->h != TIMELIB_UNSET || s->time->i != TIMELIB_UNSET || s->time->s != TIMELIB_UNSET) {
  1920. if (s->time->h == TIMELIB_UNSET ) {
  1921. s->time->h = 0;
  1922. }
  1923. if (s->time->i == TIMELIB_UNSET ) {
  1924. s->time->i = 0;
  1925. }
  1926. if (s->time->s == TIMELIB_UNSET ) {
  1927. s->time->s = 0;
  1928. }
  1929. }
  1930. /* do funky checking whether the parsed time was valid time */
  1931. if (s->time->h != TIMELIB_UNSET && s->time->i != TIMELIB_UNSET &&
  1932. s->time->s != TIMELIB_UNSET &&
  1933. !timelib_valid_time( s->time->h, s->time->i, s->time->s)) {
  1934. add_pbf_warning(s, "The parsed time was invalid", string, ptr);
  1935. }
  1936. /* do funky checking whether the parsed date was valid date */
  1937. if (s->time->y != TIMELIB_UNSET && s->time->m != TIMELIB_UNSET &&
  1938. s->time->d != TIMELIB_UNSET &&
  1939. !timelib_valid_date( s->time->y, s->time->m, s->time->d)) {
  1940. add_pbf_warning(s, "The parsed date was invalid", string, ptr);
  1941. }
  1942. if (errors) {
  1943. *errors = in.errors;
  1944. } else {
  1945. timelib_error_container_dtor(in.errors);
  1946. }
  1947. return in.time;
  1948. }
  1949. void timelib_fill_holes(timelib_time *parsed, timelib_time *now, int options)
  1950. {
  1951. if (!(options & TIMELIB_OVERRIDE_TIME) && parsed->have_date && !parsed->have_time) {
  1952. parsed->h = 0;
  1953. parsed->i = 0;
  1954. parsed->s = 0;
  1955. parsed->f = 0;
  1956. }
  1957. if (parsed->y == TIMELIB_UNSET) parsed->y = now->y != TIMELIB_UNSET ? now->y : 0;
  1958. if (parsed->d == TIMELIB_UNSET) parsed->d = now->d != TIMELIB_UNSET ? now->d : 0;
  1959. if (parsed->m == TIMELIB_UNSET) parsed->m = now->m != TIMELIB_UNSET ? now->m : 0;
  1960. if (parsed->h == TIMELIB_UNSET) parsed->h = now->h != TIMELIB_UNSET ? now->h : 0;
  1961. if (parsed->i == TIMELIB_UNSET) parsed->i = now->i != TIMELIB_UNSET ? now->i : 0;
  1962. if (parsed->s == TIMELIB_UNSET) parsed->s = now->s != TIMELIB_UNSET ? now->s : 0;
  1963. if (parsed->f == TIMELIB_UNSET) parsed->f = now->f != TIMELIB_UNSET ? now->f : 0;
  1964. if (parsed->z == TIMELIB_UNSET) parsed->z = now->z != TIMELIB_UNSET ? now->z : 0;
  1965. if (parsed->dst == TIMELIB_UNSET) parsed->dst = now->dst != TIMELIB_UNSET ? now->dst : 0;
  1966. if (!parsed->tz_abbr) {
  1967. parsed->tz_abbr = now->tz_abbr ? timelib_strdup(now->tz_abbr) : NULL;
  1968. }
  1969. if (!parsed->tz_info) {
  1970. parsed->tz_info = now->tz_info ? (!(options & TIMELIB_NO_CLONE) ? timelib_tzinfo_clone(now->tz_info) : now->tz_info) : NULL;
  1971. }
  1972. if (parsed->zone_type == 0 && now->zone_type != 0) {
  1973. parsed->zone_type = now->zone_type;
  1974. /* parsed->tz_abbr = now->tz_abbr ? timelib_strdup(now->tz_abbr) : NULL;
  1975. parsed->tz_info = now->tz_info ? timelib_tzinfo_clone(now->tz_info) : NULL;
  1976. */ parsed->is_localtime = 1;
  1977. }
  1978. /* timelib_dump_date(parsed, 2);
  1979. timelib_dump_date(now, 2);
  1980. */
  1981. }
  1982. char *timelib_timezone_id_from_abbr(const char *abbr, timelib_long gmtoffset, int isdst)
  1983. {
  1984. const timelib_tz_lookup_table *tp;
  1985. tp = abbr_search(abbr, gmtoffset, isdst);
  1986. if (tp) {
  1987. return (tp->full_tz_name);
  1988. } else {
  1989. return NULL;
  1990. }
  1991. }
  1992. const timelib_tz_lookup_table *timelib_timezone_abbreviations_list(void)
  1993. {
  1994. return timelib_timezone_lookup;
  1995. }
  1996. #ifdef DEBUG_PARSER_STUB
  1997. int main(void)
  1998. {
  1999. timelib_time time = timelib_strtotime("May 12");
  2000. printf ("%04d-%02d-%02d %02d:%02d:%02d.%-5d %+04d %1d",
  2001. time.y, time.m, time.d, time.h, time.i, time.s, time.f, time.z, time.dst);
  2002. if (time.have_relative) {
  2003. printf ("%3dY %3dM %3dD / %3dH %3dM %3dS",
  2004. time.relative.y, time.relative.m, time.relative.d, time.relative.h, time.relative.i, time.relative.s);
  2005. }
  2006. if (time.have_weekday_relative) {
  2007. printf (" / %d", time.relative.weekday);
  2008. }
  2009. if (time.have_weeknr_day) {
  2010. printf(" / %dW%d", time.relative.weeknr_day.weeknr, time.relative.weeknr_day.dayofweek);
  2011. }
  2012. return 0;
  2013. }
  2014. #endif
  2015. /*
  2016. * vim: syntax=c
  2017. */