IntegerField.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011
  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>
  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 wchar_t *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. {L"ago", TOKEN_AGO},
  167. {L"now", TOKEN_NOW},
  168. {L"am", TOKEN_AM},
  169. {L"pm", TOKEN_PM},
  170. {L"this", TOKEN_THIS},
  171. {L"date", TOKEN_DATE},
  172. {L"time", TOKEN_TIME},
  173. {L"of", TOKEN_OF},
  174. {L"at", TOKEN_AT},
  175. {L"the", TOKEN_THE},
  176. {L"yesterday", TOKEN_YESTERDAY},
  177. {L"tomorrow", TOKEN_TOMORROW},
  178. {L"today", TOKEN_TODAY},
  179. {L"from", TOKEN_FROM},
  180. {L"before", TOKEN_BEFORE},
  181. {L"after", TOKEN_AFTER},
  182. {L"past", TOKEN_AFTER},
  183. {L"monday", TOKEN_MONDAY},
  184. {L"mon", TOKEN_MONDAY},
  185. {L"tuesday", TOKEN_TUESDAY},
  186. {L"tue", TOKEN_TUESDAY},
  187. {L"wednesday", TOKEN_WEDNESDAY},
  188. {L"wed", TOKEN_WEDNESDAY},
  189. {L"thursday", TOKEN_THURSDAY},
  190. {L"thu", TOKEN_THURSDAY},
  191. {L"friday", TOKEN_FRIDAY},
  192. {L"fri", TOKEN_FRIDAY},
  193. {L"saturday", TOKEN_SATURDAY},
  194. {L"sat", TOKEN_SATURDAY},
  195. {L"sunday", TOKEN_SUNDAY},
  196. {L"sun", TOKEN_SUNDAY},
  197. {L"midnight", TOKEN_MIDNIGHT},
  198. {L"noon", TOKEN_NOON},
  199. {L"second", TOKEN_SECOND},
  200. {L"seconds", TOKEN_SECOND},
  201. {L"sec", TOKEN_SECOND},
  202. {L"s", TOKEN_SECOND},
  203. {L"minute", TOKEN_MINUTE},
  204. {L"minutes", TOKEN_MINUTE},
  205. {L"min", TOKEN_MINUTE},
  206. {L"mn", TOKEN_MINUTE},
  207. {L"m", TOKEN_MINUTE},
  208. {L"hour", TOKEN_HOUR},
  209. {L"hours", TOKEN_HOUR},
  210. {L"h", TOKEN_HOUR},
  211. {L"day", TOKEN_DAY},
  212. {L"days", TOKEN_DAY},
  213. {L"d", TOKEN_DAY},
  214. {L"week", TOKEN_WEEK},
  215. {L"weeks", TOKEN_WEEK},
  216. {L"w", TOKEN_WEEK},
  217. {L"month", TOKEN_MONTH},
  218. {L"months", TOKEN_MONTH},
  219. {L"year", TOKEN_YEAR},
  220. {L"years", TOKEN_YEAR},
  221. {L"y", TOKEN_YEAR},
  222. {L"january", TOKEN_JANUARY},
  223. {L"jan", TOKEN_JANUARY},
  224. {L"february", TOKEN_FEBRUARY},
  225. {L"feb", TOKEN_FEBRUARY},
  226. {L"march", TOKEN_MARCH},
  227. {L"mar", TOKEN_MARCH},
  228. {L"april", TOKEN_APRIL},
  229. {L"apr", TOKEN_APRIL},
  230. {L"may", TOKEN_MAY},
  231. {L"june", TOKEN_JUNE},
  232. {L"jun", TOKEN_JUNE},
  233. {L"july", TOKEN_JULY},
  234. {L"jul", TOKEN_JULY},
  235. {L"august", TOKEN_AUGUST},
  236. {L"aug", TOKEN_AUGUST},
  237. {L"september", TOKEN_SEPTEMBER},
  238. {L"sep", TOKEN_SEPTEMBER},
  239. {L"october", TOKEN_OCTOBER},
  240. {L"oct", TOKEN_OCTOBER},
  241. {L"november", TOKEN_NOVEMBER},
  242. {L"nov", TOKEN_NOVEMBER},
  243. {L"december", TOKEN_DECEMBER},
  244. {L"dec", TOKEN_DECEMBER},
  245. };
  246. //---------------------------------------------------------------------------
  247. int IntegerField::LookupToken(const wchar_t *t) {
  248. for (int i=0;i<sizeof(Int_Tokens)/sizeof(tokenstruct);i++) {
  249. if (!_wcsicmp(Int_Tokens[i].token, t))
  250. return Int_Tokens[i].tid;
  251. }
  252. return TOKEN_IDENTIFIER;
  253. }
  254. static int myatoi(const wchar_t *p, int len) {
  255. wchar_t *w = (wchar_t *)_malloca((len+1)*sizeof(wchar_t));
  256. wcsncpy(w, p, len);
  257. w[len] = 0;
  258. int a = (w ? wcstol(w, 0, 10) : 0);
  259. _freea(w);
  260. return a;
  261. }
  262. static int isallnum(const wchar_t *p)
  263. {
  264. while (p && *p) {
  265. if (*p < L'0' || *p > L'9') return 0;
  266. p++;
  267. }
  268. return 1;
  269. }
  270. //---------------------------------------------------------------------------
  271. int IntegerField::ApplyConversion(const wchar_t *format, TimeParse *tp) {
  272. int size;
  273. int value = GetValue();
  274. wchar_t *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 wchar_t *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 = wcstol(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. wchar_t *z;
  682. int tokenLen=(int)wcslen(token);
  683. if (tokenLen>=2)
  684. {
  685. z = token+tokenLen-2;
  686. if (!_wcsicmp(z, L"st") || !_wcsicmp(z, L"nd") || !_wcsicmp(z, L"rd") || !_wcsicmp(z, L"th")) {
  687. int j = myatoi(token, (int)(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 = wcschr(token, L':');
  698. if (z)
  699. {
  700. if (tp) tp->absolute_hastime = 1;
  701. wchar_t *zz = wcschr(z+1, L':');
  702. int a, b = 0, 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 = wcstol(zz+1,0,10); }
  707. else b = wcstol(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 = wcschr(token, L'/');
  727. if (z) {
  728. if (tp) tp->absolute_hasdate = 1;
  729. wchar_t *zz = wcschr(z+1, L'/');
  730. int a, b = 0, 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 = wcstol(zz+1,0,10); }
  735. else b = _wtoi(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((int)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((int)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((int)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. }