1
0

IntegerField.cpp 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015
  1. /* ---------------------------------------------------------------------------
  2. Nullsoft Database Engine
  3. --------------------
  4. codename: Near Death Experience
  5. --------------------------------------------------------------------------- */
  6. /* ---------------------------------------------------------------------------
  7. IntegerField Class
  8. Windows implementation
  9. Field data layout:
  10. [4 bytes] value
  11. --------------------------------------------------------------------------- */
  12. #include "../nde.h"
  13. #include "Query.h"
  14. #include <time.h>
  15. #include <malloc.h> // for alloca
  16. //---------------------------------------------------------------------------
  17. IntegerField::IntegerField(int Val)
  18. {
  19. InitField();
  20. Type = FIELD_INTEGER;
  21. Value = Val;
  22. }
  23. //---------------------------------------------------------------------------
  24. void IntegerField::InitField(void)
  25. {
  26. Type = FIELD_INTEGER;
  27. Value=0;
  28. }
  29. //---------------------------------------------------------------------------
  30. IntegerField::IntegerField()
  31. {
  32. InitField();
  33. }
  34. //---------------------------------------------------------------------------
  35. IntegerField::~IntegerField()
  36. {
  37. }
  38. //---------------------------------------------------------------------------
  39. void IntegerField::ReadTypedData(const uint8_t *data, size_t len)
  40. {
  41. CHECK_INT(len);
  42. Value = *((int *)data);
  43. }
  44. //---------------------------------------------------------------------------
  45. void IntegerField::WriteTypedData(uint8_t *data, size_t len)
  46. {
  47. CHECK_INT(len);
  48. *((int *)data) = Value;
  49. }
  50. //---------------------------------------------------------------------------
  51. int IntegerField::GetValue(void)
  52. {
  53. return Value;
  54. }
  55. //---------------------------------------------------------------------------
  56. void IntegerField::SetValue(int Val)
  57. {
  58. Value = Val;
  59. }
  60. #include <limits.h>
  61. //---------------------------------------------------------------------------
  62. size_t IntegerField::GetDataSize(void)
  63. {
  64. return 4;
  65. }
  66. //---------------------------------------------------------------------------
  67. int IntegerField::Compare(Field *Entry)
  68. {
  69. if (!Entry) return -1;
  70. return GetValue() < ((IntegerField*)Entry)->GetValue() ? -1 : (GetValue() > ((IntegerField*)Entry)->GetValue() ? 1 : 0);
  71. }
  72. //---------------------------------------------------------------------------
  73. bool IntegerField::ApplyFilter(Field *Data, int op)
  74. {
  75. bool r;
  76. switch (op)
  77. {
  78. case FILTER_EQUALS:
  79. r = Value == ((IntegerField *)Data)->GetValue();
  80. break;
  81. case FILTER_NOTEQUALS:
  82. r = Value != ((IntegerField *)Data)->GetValue();
  83. break;
  84. case FILTER_NOTCONTAINS:
  85. r = (bool)!(Value & ((IntegerField *)Data)->GetValue());
  86. break;
  87. case FILTER_CONTAINS:
  88. r = !!(Value & ((IntegerField *)Data)->GetValue());
  89. break;
  90. case FILTER_ABOVE:
  91. r = (bool)(Value > ((IntegerField *)Data)->GetValue());
  92. break;
  93. case FILTER_BELOW:
  94. r = (bool)(Value < ((IntegerField *)Data)->GetValue());
  95. break;
  96. case FILTER_BELOWOREQUAL:
  97. r = (bool)(Value <= ((IntegerField *)Data)->GetValue());
  98. break;
  99. case FILTER_ABOVEOREQUAL:
  100. r = (bool)(Value >= ((IntegerField *)Data)->GetValue());
  101. break;
  102. case FILTER_ISEMPTY:
  103. r = (Value == 0 || Value == -1);
  104. break;
  105. case FILTER_ISNOTEMPTY:
  106. r = !(Value == 0 || Value == -1);
  107. break;
  108. default:
  109. r = true;
  110. break;
  111. }
  112. return r;
  113. }
  114. //---------------------------------------------------------------------------
  115. typedef struct {
  116. const char *token;
  117. int tid;
  118. } tokenstruct;
  119. enum {
  120. TOKEN_AGO = 128,
  121. TOKEN_NOW,
  122. TOKEN_YESTERDAY,
  123. TOKEN_TOMORROW,
  124. TOKEN_TODAY,
  125. TOKEN_OF,
  126. TOKEN_THE,
  127. TOKEN_DATE,
  128. TOKEN_FROM,
  129. TOKEN_BEFORE,
  130. TOKEN_AFTER,
  131. TOKEN_THIS,
  132. TOKEN_SUNDAY,
  133. TOKEN_MONDAY,
  134. TOKEN_TUESDAY,
  135. TOKEN_WEDNESDAY,
  136. TOKEN_THURSDAY,
  137. TOKEN_FRIDAY,
  138. TOKEN_SATURDAY,
  139. TOKEN_MIDNIGHT,
  140. TOKEN_NOON,
  141. TOKEN_AM,
  142. TOKEN_PM,
  143. TOKEN_JANUARY,
  144. TOKEN_FEBRUARY,
  145. TOKEN_MARCH,
  146. TOKEN_APRIL,
  147. TOKEN_MAY,
  148. TOKEN_JUNE,
  149. TOKEN_JULY,
  150. TOKEN_AUGUST,
  151. TOKEN_SEPTEMBER,
  152. TOKEN_OCTOBER,
  153. TOKEN_NOVEMBER,
  154. TOKEN_DECEMBER,
  155. TOKEN_TIME,
  156. TOKEN_SECOND,
  157. TOKEN_MINUTE,
  158. TOKEN_HOUR,
  159. TOKEN_DAY,
  160. TOKEN_WEEK,
  161. TOKEN_MONTH,
  162. TOKEN_YEAR,
  163. TOKEN_AT,
  164. };
  165. tokenstruct Int_Tokens[] = { // Feel free to add more...
  166. {"ago", TOKEN_AGO},
  167. {"now", TOKEN_NOW},
  168. {"am", TOKEN_AM},
  169. {"pm", TOKEN_PM},
  170. {"this", TOKEN_THIS},
  171. {"date", TOKEN_DATE},
  172. {"time", TOKEN_TIME},
  173. {"of", TOKEN_OF},
  174. {"at", TOKEN_AT},
  175. {"the", TOKEN_THE},
  176. {"yesterday", TOKEN_YESTERDAY},
  177. {"tomorrow", TOKEN_TOMORROW},
  178. {"today", TOKEN_TODAY},
  179. {"from", TOKEN_FROM},
  180. {"before", TOKEN_BEFORE},
  181. {"after", TOKEN_AFTER},
  182. {"past", TOKEN_AFTER},
  183. {"monday", TOKEN_MONDAY},
  184. {"mon", TOKEN_MONDAY},
  185. {"tuesday", TOKEN_TUESDAY},
  186. {"tue", TOKEN_TUESDAY},
  187. {"wednesday", TOKEN_WEDNESDAY},
  188. {"wed", TOKEN_WEDNESDAY},
  189. {"thursday", TOKEN_THURSDAY},
  190. {"thu", TOKEN_THURSDAY},
  191. {"friday", TOKEN_FRIDAY},
  192. {"fri", TOKEN_FRIDAY},
  193. {"saturday", TOKEN_SATURDAY},
  194. {"sat", TOKEN_SATURDAY},
  195. {"sunday", TOKEN_SUNDAY},
  196. {"sun", TOKEN_SUNDAY},
  197. {"midnight", TOKEN_MIDNIGHT},
  198. {"noon", TOKEN_NOON},
  199. {"second", TOKEN_SECOND},
  200. {"seconds", TOKEN_SECOND},
  201. {"sec", TOKEN_SECOND},
  202. {"s", TOKEN_SECOND},
  203. {"minute", TOKEN_MINUTE},
  204. {"minutes", TOKEN_MINUTE},
  205. {"min", TOKEN_MINUTE},
  206. {"mn", TOKEN_MINUTE},
  207. {"m", TOKEN_MINUTE},
  208. {"hour", TOKEN_HOUR},
  209. {"hours", TOKEN_HOUR},
  210. {"h", TOKEN_HOUR},
  211. {"day", TOKEN_DAY},
  212. {"days", TOKEN_DAY},
  213. {"d", TOKEN_DAY},
  214. {"week", TOKEN_WEEK},
  215. {"weeks", TOKEN_WEEK},
  216. {"w", TOKEN_WEEK},
  217. {"month", TOKEN_MONTH},
  218. {"months", TOKEN_MONTH},
  219. {"year", TOKEN_YEAR},
  220. {"years", TOKEN_YEAR},
  221. {"y", TOKEN_YEAR},
  222. {"january", TOKEN_JANUARY},
  223. {"jan", TOKEN_JANUARY},
  224. {"february", TOKEN_FEBRUARY},
  225. {"feb", TOKEN_FEBRUARY},
  226. {"march", TOKEN_MARCH},
  227. {"mar", TOKEN_MARCH},
  228. {"april", TOKEN_APRIL},
  229. {"apr", TOKEN_APRIL},
  230. {"may", TOKEN_MAY},
  231. {"june", TOKEN_JUNE},
  232. {"jun", TOKEN_JUNE},
  233. {"july", TOKEN_JULY},
  234. {"jul", TOKEN_JULY},
  235. {"august", TOKEN_AUGUST},
  236. {"aug", TOKEN_AUGUST},
  237. {"september", TOKEN_SEPTEMBER},
  238. {"sep", TOKEN_SEPTEMBER},
  239. {"october", TOKEN_OCTOBER},
  240. {"oct", TOKEN_OCTOBER},
  241. {"november", TOKEN_NOVEMBER},
  242. {"nov", TOKEN_NOVEMBER},
  243. {"december", TOKEN_DECEMBER},
  244. {"dec", TOKEN_DECEMBER},
  245. };
  246. //---------------------------------------------------------------------------
  247. int IntegerField::LookupToken(const char *t) {
  248. for (int i=0;i<sizeof(Int_Tokens)/sizeof(tokenstruct);i++) {
  249. if (!strcasecmp(Int_Tokens[i].token, t))
  250. return Int_Tokens[i].tid;
  251. }
  252. return TOKEN_IDENTIFIER;
  253. }
  254. static int myatoi(const char *p, int len) {
  255. char *w = (char *)alloca((len+1)*sizeof(char));
  256. strncpy(w, p, len);
  257. w[len] = 0;
  258. int a = strtol(w,0, 10);
  259. //free(w);
  260. return a;
  261. }
  262. static int isallnum(const char *p)
  263. {
  264. while (p && *p) {
  265. if (*p < '0' || *p > '9') return 0;
  266. p++;
  267. }
  268. return 1;
  269. }
  270. //---------------------------------------------------------------------------
  271. int IntegerField::ApplyConversion(const char *format, TimeParse *tp) {
  272. int size;
  273. int value = GetValue();
  274. char *token = 0;
  275. bool ago = false;
  276. bool from = false;
  277. bool kthis = false;
  278. int what = TOKEN_MINUTE;
  279. int lastnumber = value;
  280. if (tp) {
  281. tp->is_relative = 0;
  282. tp->offset_value = 0;
  283. tp->offset_whence = -1;
  284. tp->offset_what = -1;
  285. tp->offset_used = 0;
  286. tp->relative_year = -1;
  287. tp->relative_month = -1;
  288. tp->relative_day = -1;
  289. tp->relative_hour = -1;
  290. tp->relative_min = -1;
  291. tp->relative_sec = -1;
  292. tp->relative_kwday = -1;
  293. tp->absolute_hastime = 0;
  294. tp->absolute_hasdate = 0;
  295. }
  296. time_t now;
  297. time(&now);
  298. struct tm *o = localtime(&now);
  299. struct tm origin = *o;
  300. struct tm origin_flags = {0,0,0,0,0,0,0,0,0};
  301. struct tm onow = *o;
  302. const char *p = format;
  303. int t = -1;
  304. int lastt = -1;
  305. origin.tm_isdst = -1;
  306. while (1) {
  307. int save_lastt = lastt;
  308. lastt = t;
  309. t = Scanner::Query_GetNextToken(p, &size, &token, 1);
  310. if (t == TOKEN_EOQ) break;
  311. switch (t) {
  312. case TOKEN_THIS:
  313. kthis = true;
  314. break;
  315. case TOKEN_AGO:
  316. case TOKEN_BEFORE: // before defaults to before now (= ago)
  317. ago = true;
  318. if (tp) {
  319. tp->is_relative = 1;
  320. tp->offset_whence = 1;
  321. tp->offset_used = 1;
  322. }
  323. break;
  324. case TOKEN_AFTER: // if after, ago is discarded, coz 5 mn ago after x has no meaning, so we get it as 5 mn after x
  325. ago = false;
  326. // no break
  327. case TOKEN_FROM:
  328. from = true;
  329. if (tp) {
  330. tp->is_relative = 1;
  331. tp->offset_whence = 0;
  332. tp->offset_used = 1;
  333. }
  334. break;
  335. case TOKEN_DATE: {
  336. if (!kthis) break;
  337. kthis = false;
  338. origin.tm_year = onow.tm_year;
  339. origin_flags.tm_year = 1;
  340. origin.tm_mon = onow.tm_mon;
  341. origin_flags.tm_mon = 1;
  342. origin.tm_mday = onow.tm_mday - onow.tm_wday;
  343. origin_flags.tm_mday = 1;
  344. if (!origin_flags.tm_hour)
  345. origin.tm_hour = 0;
  346. if (!origin_flags.tm_min)
  347. origin.tm_min = 0;
  348. if (!origin_flags.tm_sec)
  349. origin.tm_sec = 0;
  350. if (tp) {
  351. tp->relative_year = -1;
  352. tp->relative_month = -1;
  353. tp->relative_day = -1;
  354. }
  355. break;
  356. }
  357. case TOKEN_TIME: {
  358. if (!kthis) break;
  359. kthis = false;
  360. origin.tm_hour = onow.tm_hour;
  361. origin_flags.tm_hour = 1;
  362. origin.tm_min = onow.tm_min;
  363. origin_flags.tm_min = 1;
  364. origin.tm_sec = onow.tm_sec;
  365. origin_flags.tm_sec = 1;
  366. if (tp) {
  367. tp->relative_sec = -1;
  368. tp->relative_min = -1;
  369. tp->relative_hour = -1;
  370. }
  371. break;
  372. }
  373. case TOKEN_SECOND:
  374. case TOKEN_MINUTE:
  375. case TOKEN_HOUR:
  376. case TOKEN_DAY:
  377. case TOKEN_WEEK:
  378. case TOKEN_MONTH:
  379. case TOKEN_YEAR:
  380. if (kthis) {
  381. kthis = false;
  382. switch (t) {
  383. case TOKEN_SECOND:
  384. origin.tm_sec = onow.tm_sec;
  385. origin_flags.tm_sec = 1;
  386. if (tp) tp->relative_sec = -1;
  387. break;
  388. case TOKEN_MINUTE:
  389. origin.tm_min = onow.tm_min;
  390. origin_flags.tm_min = 1;
  391. if (!origin_flags.tm_sec)
  392. origin.tm_sec = 0;
  393. if (tp) tp->relative_min = -1;
  394. break;
  395. case TOKEN_HOUR:
  396. origin.tm_hour = onow.tm_hour;
  397. origin_flags.tm_hour = 1;
  398. if (!origin_flags.tm_min)
  399. origin.tm_min = 0;
  400. if (!origin_flags.tm_sec)
  401. origin.tm_sec = 0;
  402. if (tp) tp->relative_hour = -1;
  403. break;
  404. case TOKEN_DAY:
  405. origin.tm_mday = onow.tm_mday;
  406. origin_flags.tm_mday = 1;
  407. if (!origin_flags.tm_hour)
  408. origin.tm_hour = 0;
  409. if (!origin_flags.tm_min)
  410. origin.tm_min = 0;
  411. if (!origin_flags.tm_sec)
  412. origin.tm_sec = 0;
  413. if (tp) tp->relative_day = -1;
  414. break;
  415. case TOKEN_WEEK:
  416. origin.tm_mday = onow.tm_mday - onow.tm_wday;
  417. origin_flags.tm_mday = 1;
  418. if (!origin_flags.tm_hour)
  419. origin.tm_hour = 0;
  420. if (!origin_flags.tm_min)
  421. origin.tm_min = 0;
  422. if (!origin_flags.tm_sec)
  423. origin.tm_sec = 0;
  424. if (tp) tp->relative_day = -2;
  425. break;
  426. case TOKEN_MONTH:
  427. origin.tm_mon = onow.tm_mon;
  428. origin_flags.tm_mon = 1;
  429. if (!origin_flags.tm_mday)
  430. origin.tm_mday = 1;
  431. if (!origin_flags.tm_hour)
  432. origin.tm_hour = 0;
  433. if (!origin_flags.tm_min)
  434. origin.tm_min = 0;
  435. if (!origin_flags.tm_sec)
  436. origin.tm_sec = 0;
  437. if (tp) tp->relative_month = -1;
  438. break;
  439. case TOKEN_YEAR:
  440. origin.tm_year = onow.tm_year;
  441. origin_flags.tm_year = 1;
  442. if (!origin_flags.tm_mon)
  443. origin.tm_mon = 0;
  444. if (!origin_flags.tm_mday)
  445. origin.tm_mday = 1;
  446. if (!origin_flags.tm_hour)
  447. origin.tm_hour = 0;
  448. if (!origin_flags.tm_min)
  449. origin.tm_min = 0;
  450. if (!origin_flags.tm_sec)
  451. origin.tm_sec = 0;
  452. if (tp) tp->relative_year = -1;
  453. break;
  454. }
  455. break;
  456. }
  457. if (lastnumber > 0) {
  458. value = lastnumber;
  459. lastnumber = 0;
  460. if (tp) tp->offset_value = value;
  461. }
  462. what = t;
  463. if (tp) {
  464. switch (what) {
  465. case TOKEN_SECOND:
  466. tp->offset_what = 6; break;
  467. case TOKEN_MINUTE:
  468. tp->offset_what = 5; break;
  469. case TOKEN_HOUR:
  470. tp->offset_what = 4; break;
  471. case TOKEN_DAY:
  472. tp->offset_what = 3; break;
  473. case TOKEN_WEEK:
  474. tp->offset_what = 2; break;
  475. case TOKEN_MONTH:
  476. tp->offset_what = 1; break;
  477. case TOKEN_YEAR:
  478. tp->offset_what = 0; break;
  479. }
  480. }
  481. break;
  482. case TOKEN_SUNDAY:
  483. case TOKEN_MONDAY:
  484. case TOKEN_TUESDAY:
  485. case TOKEN_WEDNESDAY:
  486. case TOKEN_THURSDAY:
  487. case TOKEN_FRIDAY:
  488. case TOKEN_SATURDAY: {
  489. kthis = false;
  490. int dow = t-TOKEN_MONDAY;
  491. if (dow > onow.tm_mday)
  492. origin.tm_mday = 7 - (dow - onow.tm_mday);
  493. else
  494. origin.tm_mday = dow;
  495. origin_flags.tm_mday = 1;
  496. if (!origin_flags.tm_hour)
  497. origin.tm_hour = 0;
  498. if (!origin_flags.tm_min)
  499. origin.tm_min = 0;
  500. if (!origin_flags.tm_sec)
  501. origin.tm_sec = 0;
  502. }
  503. if (tp) tp->relative_kwday = t-TOKEN_SUNDAY;
  504. break;
  505. case TOKEN_MIDNIGHT:
  506. kthis = false;
  507. origin.tm_hour = 0;
  508. origin_flags.tm_hour = 1;
  509. if (!origin_flags.tm_min) {
  510. if (tp) tp->relative_min = 0;
  511. origin.tm_min = 0;
  512. origin_flags.tm_min = 1;
  513. }
  514. if (!origin_flags.tm_sec) {
  515. if (tp) tp->relative_sec = 0;
  516. origin.tm_sec = 0;
  517. origin_flags.tm_sec = 1;
  518. }
  519. if (tp) tp->relative_hour = 0;
  520. break;
  521. case TOKEN_NOON:
  522. kthis = false;
  523. origin.tm_hour = 12;
  524. origin_flags.tm_hour = 1;
  525. if (!origin_flags.tm_min) {
  526. if (tp) tp->relative_min = 0;
  527. origin.tm_min = 0;
  528. origin_flags.tm_min = 1;
  529. }
  530. if (!origin_flags.tm_sec) {
  531. if (tp) tp->relative_sec = 0;
  532. origin.tm_sec = 0;
  533. origin_flags.tm_sec = 1;
  534. }
  535. if (tp) tp->relative_hour = 12;
  536. break;
  537. case TOKEN_AM:
  538. kthis = false;
  539. if (lastnumber > 0) {
  540. origin.tm_hour = lastnumber;
  541. if (!origin_flags.tm_min) {
  542. if (tp) tp->relative_min = 0;
  543. origin.tm_min = 0;
  544. origin_flags.tm_min = 1;
  545. }
  546. if (!origin_flags.tm_sec) {
  547. if (tp) tp->relative_sec = 0;
  548. origin.tm_sec = 0;
  549. origin_flags.tm_sec = 1;
  550. }
  551. if (tp) tp->relative_hour = lastnumber;
  552. lastnumber = 0;
  553. } else {
  554. if (origin.tm_hour > 12) origin.tm_hour -= 12;
  555. if (tp) tp->relative_hour = origin.tm_hour;
  556. }
  557. origin_flags.tm_hour = 1;
  558. break;
  559. case TOKEN_PM:
  560. kthis = false;
  561. if (lastnumber > 0) {
  562. origin.tm_hour = lastnumber > 12 ? lastnumber : lastnumber + 12;
  563. if (!origin_flags.tm_min) {
  564. if (tp) tp->relative_min = 0;
  565. origin.tm_min = 0;
  566. origin_flags.tm_min = 1;
  567. }
  568. if (!origin_flags.tm_sec) {
  569. if (tp) tp->relative_sec = 0;
  570. origin.tm_sec = 0;
  571. origin_flags.tm_sec = 1;
  572. }
  573. if (tp) tp->relative_hour = lastnumber;
  574. lastnumber = 0;
  575. } else {
  576. if (origin.tm_hour <= 12) origin.tm_hour += 12;
  577. if (tp) tp->relative_hour = origin.tm_hour;
  578. }
  579. origin_flags.tm_hour = 1;
  580. break;
  581. case TOKEN_NOW:
  582. kthis = false;
  583. if (!origin_flags.tm_year) {
  584. if (tp) tp->relative_year = -1;
  585. origin.tm_year = onow.tm_year;
  586. }
  587. origin_flags.tm_year = 1;
  588. if (!origin_flags.tm_mon) {
  589. if (tp) tp->relative_month = -1;
  590. origin.tm_mon = onow.tm_mon;
  591. }
  592. origin_flags.tm_mon = 1;
  593. if (!origin_flags.tm_mday) {
  594. if (tp) tp->relative_day = -1;
  595. origin.tm_mday = onow.tm_mday;
  596. }
  597. origin_flags.tm_mday = 1;
  598. if (!origin_flags.tm_hour) {
  599. if (tp) tp->relative_hour = -1;
  600. origin.tm_hour = onow.tm_hour;
  601. }
  602. origin_flags.tm_hour = 1;
  603. if (!origin_flags.tm_min) {
  604. if (tp) tp->relative_min = -1;
  605. origin.tm_min = onow.tm_min;
  606. }
  607. origin_flags.tm_min = 1;
  608. if (!origin_flags.tm_sec) {
  609. if (tp) tp->relative_sec = -1;
  610. origin.tm_sec = onow.tm_sec;
  611. }
  612. break;
  613. case TOKEN_YESTERDAY:
  614. kthis = false;
  615. origin.tm_mday = onow.tm_mday - 1;
  616. origin_flags.tm_mday = 1;
  617. if (tp) tp->relative_kwday = 7;
  618. break;
  619. case TOKEN_TODAY:
  620. origin.tm_mday = onow.tm_mday;
  621. origin_flags.tm_mday = 1;
  622. if (tp) tp->relative_kwday = 8;
  623. break;
  624. case TOKEN_TOMORROW:
  625. kthis = false;
  626. origin.tm_mday = onow.tm_mday + 1;
  627. origin_flags.tm_mday = 1;
  628. if (tp) tp->relative_kwday = 9;
  629. break;
  630. case TOKEN_JANUARY:
  631. case TOKEN_FEBRUARY:
  632. case TOKEN_MARCH:
  633. case TOKEN_APRIL:
  634. case TOKEN_MAY:
  635. case TOKEN_JUNE:
  636. case TOKEN_JULY:
  637. case TOKEN_AUGUST:
  638. case TOKEN_SEPTEMBER:
  639. case TOKEN_OCTOBER:
  640. case TOKEN_NOVEMBER:
  641. case TOKEN_DECEMBER:
  642. kthis = false;
  643. if (lastnumber > 0) {
  644. origin.tm_mday = lastnumber;
  645. origin_flags.tm_mday = 1;
  646. lastnumber = 0;
  647. }
  648. origin.tm_mon = t-TOKEN_JANUARY;
  649. if (!origin_flags.tm_mday)
  650. origin.tm_mday = 1;
  651. if (!origin_flags.tm_hour)
  652. origin.tm_hour = 0;
  653. if (!origin_flags.tm_min)
  654. origin.tm_min = 0;
  655. if (!origin_flags.tm_sec)
  656. origin.tm_sec = 0;
  657. origin_flags.tm_mon = 1;
  658. if (tp) tp->relative_month = t-TOKEN_JANUARY;
  659. break;
  660. case TOKEN_IDENTIFIER:
  661. {
  662. kthis = false;
  663. // check for a year value
  664. int i = strtol(token,0,10);
  665. if (i > 1970 && i < 2038 && isallnum(token)) { // max time_t range
  666. origin.tm_year = i-1900;
  667. if (!origin_flags.tm_mday)
  668. origin.tm_mday = 1;
  669. if (!origin_flags.tm_mon)
  670. origin.tm_mon = 0;
  671. if (!origin_flags.tm_hour)
  672. origin.tm_hour = 0;
  673. if (!origin_flags.tm_min)
  674. origin.tm_min = 0;
  675. if (!origin_flags.tm_sec)
  676. origin.tm_sec = 0;
  677. if (tp) tp->relative_year = i;
  678. break;
  679. }
  680. // check for 1st, 2nd, 3rd, 4th, etc.
  681. char *z;
  682. size_t tokenLen=strlen(token);
  683. if (tokenLen>=2)
  684. {
  685. z = token+tokenLen-2;
  686. if (!_stricmp(z, "st") || !_stricmp(z, "nd") || !_stricmp(z, "rd") || !_stricmp(z, "th")) {
  687. int j = myatoi(token, z-token);
  688. if (j >= 1 && j <= 31) {
  689. origin.tm_mday = j;
  690. origin_flags.tm_mday = 1;
  691. if (tp) tp->relative_day = j;
  692. break;
  693. }
  694. }
  695. }
  696. // check for a time string (##:##:##)
  697. z = strchr(token, ':');
  698. if (z)
  699. {
  700. if (tp) tp->absolute_hastime = 1;
  701. char *zz = strchr(z+1, ':');
  702. int a, b, c=0;
  703. a = myatoi(token, (int)(z-token));
  704. if (zz && *(zz+1) == 0) zz = NULL;
  705. if (zz && !isallnum(zz+1)) zz = NULL;
  706. if (zz) { b = myatoi(z+1, (int)(zz-(z+1))); c = strtol(zz+1,0,10); }
  707. else b = strtol(z+1,0,10);
  708. origin.tm_hour = a;
  709. origin.tm_min = b;
  710. if (tp) {
  711. tp->relative_hour = a;
  712. tp->relative_min = b;
  713. }
  714. if (zz && !origin_flags.tm_sec) {
  715. origin.tm_sec = c;
  716. if (tp) tp->relative_sec = c;
  717. } else if (!origin_flags.tm_sec) {
  718. origin.tm_sec = 0;
  719. }
  720. origin_flags.tm_sec = 1;
  721. origin_flags.tm_hour = 1;
  722. origin_flags.tm_min = 1;
  723. break;
  724. }
  725. // check for a date string in the format ##/##/##
  726. z = strchr(token, '/');
  727. if (z) {
  728. if (tp) tp->absolute_hasdate = 1;
  729. char *zz = strchr(z+1, '/');
  730. int a, b, c=onow.tm_year;
  731. a = myatoi(token, (int)(z-token));
  732. if (zz && !isallnum(zz+1)) zz = NULL;
  733. if (zz && *(zz+1) == 0) zz = NULL;
  734. if (zz) { b = myatoi(z+1, (int)(zz-(z+1))); c = strtol(zz+1,0,10); }
  735. else b = atoi(z+1);
  736. if (b > 1969 && b < 2038) {
  737. // mm/yyyy
  738. origin.tm_year = b-1900;
  739. origin_flags.tm_year = 1;
  740. origin.tm_mon = a-1;
  741. origin_flags.tm_mon = 1;
  742. if (!origin_flags.tm_mday)
  743. origin.tm_mday = 1;
  744. if (!origin_flags.tm_hour)
  745. origin.tm_hour = 0;
  746. if (!origin_flags.tm_min)
  747. origin.tm_min = 0;
  748. if (!origin_flags.tm_sec)
  749. origin.tm_sec = 0;
  750. if (tp) {
  751. tp->relative_year = b;
  752. tp->relative_month = a-1;
  753. }
  754. } else {
  755. // mm/dd(/yy[yy])
  756. if (c < 70) c += 100;
  757. if (c > 138) c -= 1900;
  758. origin.tm_year = c;
  759. origin.tm_mon = a-1;
  760. origin.tm_mday = b == 0 ? 1 : b;
  761. origin_flags.tm_year = 1;
  762. origin_flags.tm_mon = 1;
  763. origin_flags.tm_mday = 1;
  764. if (!origin_flags.tm_hour)
  765. origin.tm_hour = 0;
  766. if (!origin_flags.tm_min)
  767. origin.tm_min = 0;
  768. if (!origin_flags.tm_sec)
  769. origin.tm_sec = 0;
  770. if (tp) {
  771. tp->relative_year = c+1900;
  772. tp->relative_month = a-1;
  773. tp->relative_day = b;
  774. }
  775. }
  776. origin_flags.tm_year = 1;
  777. origin_flags.tm_mon = 1;
  778. origin_flags.tm_mday = 1;
  779. break;
  780. }
  781. if (isallnum(token))
  782. {
  783. lastnumber = i;
  784. switch (lastt) {
  785. case TOKEN_JANUARY:
  786. case TOKEN_FEBRUARY:
  787. case TOKEN_MARCH:
  788. case TOKEN_APRIL:
  789. case TOKEN_MAY:
  790. case TOKEN_JUNE:
  791. case TOKEN_JULY:
  792. case TOKEN_AUGUST:
  793. case TOKEN_SEPTEMBER:
  794. case TOKEN_OCTOBER:
  795. case TOKEN_NOVEMBER:
  796. case TOKEN_DECEMBER:
  797. origin.tm_mday = lastnumber;
  798. origin_flags.tm_mday = 1;
  799. lastnumber = 0;
  800. if (!origin_flags.tm_hour)
  801. origin.tm_hour = 0;
  802. if (!origin_flags.tm_min)
  803. origin.tm_min = 0;
  804. if (!origin_flags.tm_sec)
  805. origin.tm_sec = 0;
  806. if (tp) tp->relative_day = lastnumber;
  807. break;
  808. case TOKEN_AT: {
  809. origin.tm_hour = lastnumber;
  810. origin.tm_min = 0;
  811. origin.tm_sec = 0;
  812. origin_flags.tm_hour = 1;
  813. origin_flags.tm_min = 1;
  814. origin_flags.tm_sec = 1;
  815. if (tp) {
  816. tp->relative_hour = lastnumber;
  817. tp->relative_min = 0;
  818. tp->relative_sec = 0;
  819. }
  820. lastnumber = 0;
  821. break;
  822. }
  823. }
  824. }
  825. break;
  826. }
  827. default:
  828. lastt = save_lastt;
  829. break;
  830. }
  831. p += size;
  832. }
  833. if (lastnumber) {
  834. switch (lastt) {
  835. case TOKEN_JANUARY:
  836. case TOKEN_FEBRUARY:
  837. case TOKEN_MARCH:
  838. case TOKEN_APRIL:
  839. case TOKEN_MAY:
  840. case TOKEN_JUNE:
  841. case TOKEN_JULY:
  842. case TOKEN_AUGUST:
  843. case TOKEN_SEPTEMBER:
  844. case TOKEN_OCTOBER:
  845. case TOKEN_NOVEMBER:
  846. case TOKEN_DECEMBER:
  847. origin.tm_mday = lastnumber;
  848. lastnumber = 0;
  849. if (!origin_flags.tm_hour)
  850. origin.tm_hour = 0;
  851. if (!origin_flags.tm_min)
  852. origin.tm_min = 0;
  853. if (!origin_flags.tm_sec)
  854. origin.tm_sec = 0;
  855. if (tp) tp->relative_day = lastnumber;
  856. break;
  857. }
  858. }
  859. if (ago) { // if ago (or before), from is optional since if it wasn't specified we use now
  860. switch (what) {
  861. case TOKEN_SECOND:
  862. origin.tm_sec -= value;
  863. break;
  864. case TOKEN_MINUTE:
  865. origin.tm_min -= value;
  866. break;
  867. case TOKEN_HOUR:
  868. origin.tm_hour -= value;
  869. break;
  870. case TOKEN_DAY:
  871. origin.tm_mday -= value;
  872. break;
  873. case TOKEN_WEEK:
  874. origin.tm_mday -= value*7;
  875. break;
  876. case TOKEN_MONTH:
  877. origin.tm_mon -= value;
  878. break;
  879. case TOKEN_YEAR:
  880. origin.tm_year -= value;
  881. break;
  882. }
  883. time_t o = mktime(&origin);
  884. SetValue(o);
  885. ndestring_release(token);
  886. if (tp) tp->absolute_datetime = GetValue();
  887. return 1;
  888. } else if (from) { // from (or after) was specified, but not ago, 5 mn from x is x + 5 mn
  889. switch (what) {
  890. case TOKEN_SECOND:
  891. origin.tm_sec += value;
  892. break;
  893. case TOKEN_MINUTE:
  894. origin.tm_min += value;
  895. break;
  896. case TOKEN_HOUR:
  897. origin.tm_hour += value;
  898. break;
  899. case TOKEN_DAY:
  900. origin.tm_mday += value;
  901. break;
  902. case TOKEN_WEEK:
  903. origin.tm_mday += value*7;
  904. break;
  905. case TOKEN_MONTH:
  906. origin.tm_mon += value;
  907. break;
  908. case TOKEN_YEAR:
  909. origin.tm_year += value;
  910. break;
  911. }
  912. time_t o = mktime(&origin);
  913. SetValue(o);
  914. ndestring_release(token);
  915. if (tp) tp->absolute_datetime = GetValue();
  916. return 1;
  917. } else { // none of ago/from/before/after were specified, just make a date/time with what we got and ignore our old value
  918. time_t o = mktime(&origin);
  919. SetValue(o);
  920. ndestring_release(token);
  921. if (tp) tp->absolute_datetime = GetValue();
  922. return 1;
  923. }
  924. ndestring_release(token);
  925. if (tp) tp->absolute_datetime = GetValue();
  926. return 0;
  927. }
  928. //---------------------------------------------------------------------------
  929. DateTimeField::DateTimeField(int Val) : IntegerField(Val)
  930. {
  931. Type = FIELD_DATETIME;
  932. }
  933. //---------------------------------------------------------------------------
  934. DateTimeField::DateTimeField()
  935. {
  936. Type = FIELD_DATETIME;
  937. }
  938. //---------------------------------------------------------------------------
  939. DateTimeField::~DateTimeField()
  940. {
  941. }
  942. //---------------------------------------------------------------------------
  943. LengthField::LengthField(int Val) : IntegerField(Val)
  944. {
  945. Type = FIELD_LENGTH;
  946. }
  947. //---------------------------------------------------------------------------
  948. LengthField::LengthField()
  949. {
  950. Type = FIELD_LENGTH;
  951. }
  952. //---------------------------------------------------------------------------
  953. LengthField::~LengthField()
  954. {
  955. }