/* --------------------------------------------------------------------------- Nullsoft Database Engine -------------------- codename: Near Death Experience --------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------- IntegerField Class --------------------------------------------------------------------------- */ #include "nde.h" #include "Query.h" #include #ifdef _WIN32 #include // for alloca #endif //--------------------------------------------------------------------------- IntegerField::IntegerField(int Val) { InitField(); Type = FIELD_INTEGER; Value = Val; } //--------------------------------------------------------------------------- void IntegerField::InitField(void) { Type = FIELD_INTEGER; Value=0; } //--------------------------------------------------------------------------- IntegerField::IntegerField() { InitField(); } //--------------------------------------------------------------------------- IntegerField::~IntegerField() { } //--------------------------------------------------------------------------- void IntegerField::ReadTypedData(const uint8_t *data, size_t len) { CHECK_INT(len); Value = *((int *)data); } //--------------------------------------------------------------------------- void IntegerField::WriteTypedData(uint8_t *data, size_t len) { CHECK_INT(len); *((int *)data) = Value; } //--------------------------------------------------------------------------- int IntegerField::GetValue(void) { return Value; } //--------------------------------------------------------------------------- void IntegerField::SetValue(int Val) { Value = Val; } #include //--------------------------------------------------------------------------- size_t IntegerField::GetDataSize(void) { return 4; } //--------------------------------------------------------------------------- int IntegerField::Compare(Field *Entry) { if (!Entry) return -1; return GetValue() < ((IntegerField*)Entry)->GetValue() ? -1 : (GetValue() > ((IntegerField*)Entry)->GetValue() ? 1 : 0); } //--------------------------------------------------------------------------- bool IntegerField::ApplyFilter(Field *Data, int op) { bool r; switch (op) { case FILTER_EQUALS: r = Value == ((IntegerField *)Data)->GetValue(); break; case FILTER_NOTEQUALS: r = Value != ((IntegerField *)Data)->GetValue(); break; case FILTER_NOTCONTAINS: r = (bool)!(Value & ((IntegerField *)Data)->GetValue()); break; case FILTER_CONTAINS: r = !!(Value & ((IntegerField *)Data)->GetValue()); break; case FILTER_ABOVE: r = (bool)(Value > ((IntegerField *)Data)->GetValue()); break; case FILTER_BELOW: r = (bool)(Value < ((IntegerField *)Data)->GetValue()); break; case FILTER_BELOWOREQUAL: r = (bool)(Value <= ((IntegerField *)Data)->GetValue()); break; case FILTER_ABOVEOREQUAL: r = (bool)(Value >= ((IntegerField *)Data)->GetValue()); break; case FILTER_ISEMPTY: r = (Value == 0 || Value == -1); break; case FILTER_ISNOTEMPTY: r = !(Value == 0 || Value == -1); break; default: r = true; break; } return r; } //--------------------------------------------------------------------------- typedef struct { CFStringRef token; int tid; } tokenstruct; enum { TOKEN_AGO = 128, TOKEN_NOW, TOKEN_YESTERDAY, TOKEN_TOMORROW, TOKEN_TODAY, TOKEN_OF, TOKEN_THE, TOKEN_DATE, TOKEN_FROM, TOKEN_BEFORE, TOKEN_AFTER, TOKEN_THIS, TOKEN_SUNDAY, TOKEN_MONDAY, TOKEN_TUESDAY, TOKEN_WEDNESDAY, TOKEN_THURSDAY, TOKEN_FRIDAY, TOKEN_SATURDAY, TOKEN_MIDNIGHT, TOKEN_NOON, TOKEN_AM, TOKEN_PM, TOKEN_JANUARY, TOKEN_FEBRUARY, TOKEN_MARCH, TOKEN_APRIL, TOKEN_MAY, TOKEN_JUNE, TOKEN_JULY, TOKEN_AUGUST, TOKEN_SEPTEMBER, TOKEN_OCTOBER, TOKEN_NOVEMBER, TOKEN_DECEMBER, TOKEN_TIME, TOKEN_SECOND, TOKEN_MINUTE, TOKEN_HOUR, TOKEN_DAY, TOKEN_WEEK, TOKEN_MONTH, TOKEN_YEAR, TOKEN_AT, }; tokenstruct Int_Tokens[] = { // Feel free to add more... {CFSTR("ago"), TOKEN_AGO}, {CFSTR("now"), TOKEN_NOW}, {CFSTR("am"), TOKEN_AM}, {CFSTR("pm"), TOKEN_PM}, {CFSTR("this"), TOKEN_THIS}, {CFSTR("date"), TOKEN_DATE}, {CFSTR("time"), TOKEN_TIME}, {CFSTR("of"), TOKEN_OF}, {CFSTR("at"), TOKEN_AT}, {CFSTR("the"), TOKEN_THE}, {CFSTR("yesterday"), TOKEN_YESTERDAY}, {CFSTR("tomorrow"), TOKEN_TOMORROW}, {CFSTR("today"), TOKEN_TODAY}, {CFSTR("from"), TOKEN_FROM}, {CFSTR("before"), TOKEN_BEFORE}, {CFSTR("after"), TOKEN_AFTER}, {CFSTR("past"), TOKEN_AFTER}, {CFSTR("monday"), TOKEN_MONDAY}, {CFSTR("mon"), TOKEN_MONDAY}, {CFSTR("tuesday"), TOKEN_TUESDAY}, {CFSTR("tue"), TOKEN_TUESDAY}, {CFSTR("wednesday"), TOKEN_WEDNESDAY}, {CFSTR("wed"), TOKEN_WEDNESDAY}, {CFSTR("thursday"), TOKEN_THURSDAY}, {CFSTR("thu"), TOKEN_THURSDAY}, {CFSTR("friday"), TOKEN_FRIDAY}, {CFSTR("fri"), TOKEN_FRIDAY}, {CFSTR("saturday"), TOKEN_SATURDAY}, {CFSTR("sat"), TOKEN_SATURDAY}, {CFSTR("sunday"), TOKEN_SUNDAY}, {CFSTR("sun"), TOKEN_SUNDAY}, {CFSTR("midnight"), TOKEN_MIDNIGHT}, {CFSTR("noon"), TOKEN_NOON}, {CFSTR("second"), TOKEN_SECOND}, {CFSTR("seconds"), TOKEN_SECOND}, {CFSTR("sec"), TOKEN_SECOND}, {CFSTR("s"), TOKEN_SECOND}, {CFSTR("minute"), TOKEN_MINUTE}, {CFSTR("minutes"), TOKEN_MINUTE}, {CFSTR("min"), TOKEN_MINUTE}, {CFSTR("mn"), TOKEN_MINUTE}, {CFSTR("m"), TOKEN_MINUTE}, {CFSTR("hour"), TOKEN_HOUR}, {CFSTR("hours"), TOKEN_HOUR}, {CFSTR("h"), TOKEN_HOUR}, {CFSTR("day"), TOKEN_DAY}, {CFSTR("days"), TOKEN_DAY}, {CFSTR("d"), TOKEN_DAY}, {CFSTR("week"), TOKEN_WEEK}, {CFSTR("weeks"), TOKEN_WEEK}, {CFSTR("w"), TOKEN_WEEK}, {CFSTR("month"), TOKEN_MONTH}, {CFSTR("months"), TOKEN_MONTH}, {CFSTR("year"), TOKEN_YEAR}, {CFSTR("years"), TOKEN_YEAR}, {CFSTR("y"), TOKEN_YEAR}, {CFSTR("january"), TOKEN_JANUARY}, {CFSTR("jan"), TOKEN_JANUARY}, {CFSTR("february"), TOKEN_FEBRUARY}, {CFSTR("feb"), TOKEN_FEBRUARY}, {CFSTR("march"), TOKEN_MARCH}, {CFSTR("mar"), TOKEN_MARCH}, {CFSTR("april"), TOKEN_APRIL}, {CFSTR("apr"), TOKEN_APRIL}, {CFSTR("may"), TOKEN_MAY}, {CFSTR("june"), TOKEN_JUNE}, {CFSTR("jun"), TOKEN_JUNE}, {CFSTR("july"), TOKEN_JULY}, {CFSTR("jul"), TOKEN_JULY}, {CFSTR("august"), TOKEN_AUGUST}, {CFSTR("aug"), TOKEN_AUGUST}, {CFSTR("september"), TOKEN_SEPTEMBER}, {CFSTR("sep"), TOKEN_SEPTEMBER}, {CFSTR("october"), TOKEN_OCTOBER}, {CFSTR("oct"), TOKEN_OCTOBER}, {CFSTR("november"), TOKEN_NOVEMBER}, {CFSTR("nov"), TOKEN_NOVEMBER}, {CFSTR("december"), TOKEN_DECEMBER}, {CFSTR("dec"), TOKEN_DECEMBER}, }; //--------------------------------------------------------------------------- int IntegerField::LookupToken(CFStringRef t) { for (int i=0;iis_relative = 0; tp->offset_value = 0; tp->offset_whence = -1; tp->offset_what = -1; tp->offset_used = 0; tp->relative_year = -1; tp->relative_month = -1; tp->relative_day = -1; tp->relative_hour = -1; tp->relative_min = -1; tp->relative_sec = -1; tp->relative_kwday = -1; tp->absolute_hastime = 0; tp->absolute_hasdate = 0; } time_t now; time(&now); struct tm *o = localtime(&now); struct tm origin = *o; struct tm origin_flags = {0,0,0,0,0,0,0,0,0}; struct tm onow = *o; const char *p = format; int t = -1; int lastt = -1; origin.tm_isdst = -1; while (1) { int save_lastt = lastt; lastt = t; t = Scanner::Query_GetNextToken(p, &size, &token, 1); if (t == TOKEN_EOQ) break; switch (t) { case TOKEN_THIS: kthis = true; break; case TOKEN_AGO: case TOKEN_BEFORE: // before defaults to before now (= ago) ago = true; if (tp) { tp->is_relative = 1; tp->offset_whence = 1; tp->offset_used = 1; } break; 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 ago = false; // no break case TOKEN_FROM: from = true; if (tp) { tp->is_relative = 1; tp->offset_whence = 0; tp->offset_used = 1; } break; case TOKEN_DATE: { if (!kthis) break; kthis = false; origin.tm_year = onow.tm_year; origin_flags.tm_year = 1; origin.tm_mon = onow.tm_mon; origin_flags.tm_mon = 1; origin.tm_mday = onow.tm_mday - onow.tm_wday; origin_flags.tm_mday = 1; if (!origin_flags.tm_hour) origin.tm_hour = 0; if (!origin_flags.tm_min) origin.tm_min = 0; if (!origin_flags.tm_sec) origin.tm_sec = 0; if (tp) { tp->relative_year = -1; tp->relative_month = -1; tp->relative_day = -1; } break; } case TOKEN_TIME: { if (!kthis) break; kthis = false; origin.tm_hour = onow.tm_hour; origin_flags.tm_hour = 1; origin.tm_min = onow.tm_min; origin_flags.tm_min = 1; origin.tm_sec = onow.tm_sec; origin_flags.tm_sec = 1; if (tp) { tp->relative_sec = -1; tp->relative_min = -1; tp->relative_hour = -1; } break; } case TOKEN_SECOND: case TOKEN_MINUTE: case TOKEN_HOUR: case TOKEN_DAY: case TOKEN_WEEK: case TOKEN_MONTH: case TOKEN_YEAR: if (kthis) { kthis = false; switch (t) { case TOKEN_SECOND: origin.tm_sec = onow.tm_sec; origin_flags.tm_sec = 1; if (tp) tp->relative_sec = -1; break; case TOKEN_MINUTE: origin.tm_min = onow.tm_min; origin_flags.tm_min = 1; if (!origin_flags.tm_sec) origin.tm_sec = 0; if (tp) tp->relative_min = -1; break; case TOKEN_HOUR: origin.tm_hour = onow.tm_hour; origin_flags.tm_hour = 1; if (!origin_flags.tm_min) origin.tm_min = 0; if (!origin_flags.tm_sec) origin.tm_sec = 0; if (tp) tp->relative_hour = -1; break; case TOKEN_DAY: origin.tm_mday = onow.tm_mday; origin_flags.tm_mday = 1; if (!origin_flags.tm_hour) origin.tm_hour = 0; if (!origin_flags.tm_min) origin.tm_min = 0; if (!origin_flags.tm_sec) origin.tm_sec = 0; if (tp) tp->relative_day = -1; break; case TOKEN_WEEK: origin.tm_mday = onow.tm_mday - onow.tm_wday; origin_flags.tm_mday = 1; if (!origin_flags.tm_hour) origin.tm_hour = 0; if (!origin_flags.tm_min) origin.tm_min = 0; if (!origin_flags.tm_sec) origin.tm_sec = 0; if (tp) tp->relative_day = -2; break; case TOKEN_MONTH: origin.tm_mon = onow.tm_mon; origin_flags.tm_mon = 1; if (!origin_flags.tm_mday) origin.tm_mday = 1; if (!origin_flags.tm_hour) origin.tm_hour = 0; if (!origin_flags.tm_min) origin.tm_min = 0; if (!origin_flags.tm_sec) origin.tm_sec = 0; if (tp) tp->relative_month = -1; break; case TOKEN_YEAR: origin.tm_year = onow.tm_year; origin_flags.tm_year = 1; if (!origin_flags.tm_mon) origin.tm_mon = 0; if (!origin_flags.tm_mday) origin.tm_mday = 1; if (!origin_flags.tm_hour) origin.tm_hour = 0; if (!origin_flags.tm_min) origin.tm_min = 0; if (!origin_flags.tm_sec) origin.tm_sec = 0; if (tp) tp->relative_year = -1; break; } break; } if (lastnumber > 0) { value = lastnumber; lastnumber = 0; if (tp) tp->offset_value = value; } what = t; if (tp) { switch (what) { case TOKEN_SECOND: tp->offset_what = 6; break; case TOKEN_MINUTE: tp->offset_what = 5; break; case TOKEN_HOUR: tp->offset_what = 4; break; case TOKEN_DAY: tp->offset_what = 3; break; case TOKEN_WEEK: tp->offset_what = 2; break; case TOKEN_MONTH: tp->offset_what = 1; break; case TOKEN_YEAR: tp->offset_what = 0; break; } } break; case TOKEN_SUNDAY: case TOKEN_MONDAY: case TOKEN_TUESDAY: case TOKEN_WEDNESDAY: case TOKEN_THURSDAY: case TOKEN_FRIDAY: case TOKEN_SATURDAY: { kthis = false; int dow = t-TOKEN_MONDAY; if (dow > onow.tm_mday) origin.tm_mday = 7 - (dow - onow.tm_mday); else origin.tm_mday = dow; origin_flags.tm_mday = 1; if (!origin_flags.tm_hour) origin.tm_hour = 0; if (!origin_flags.tm_min) origin.tm_min = 0; if (!origin_flags.tm_sec) origin.tm_sec = 0; } if (tp) tp->relative_kwday = t-TOKEN_SUNDAY; break; case TOKEN_MIDNIGHT: kthis = false; origin.tm_hour = 0; origin_flags.tm_hour = 1; if (!origin_flags.tm_min) { if (tp) tp->relative_min = 0; origin.tm_min = 0; origin_flags.tm_min = 1; } if (!origin_flags.tm_sec) { if (tp) tp->relative_sec = 0; origin.tm_sec = 0; origin_flags.tm_sec = 1; } if (tp) tp->relative_hour = 0; break; case TOKEN_NOON: kthis = false; origin.tm_hour = 12; origin_flags.tm_hour = 1; if (!origin_flags.tm_min) { if (tp) tp->relative_min = 0; origin.tm_min = 0; origin_flags.tm_min = 1; } if (!origin_flags.tm_sec) { if (tp) tp->relative_sec = 0; origin.tm_sec = 0; origin_flags.tm_sec = 1; } if (tp) tp->relative_hour = 12; break; case TOKEN_AM: kthis = false; if (lastnumber > 0) { origin.tm_hour = lastnumber; if (!origin_flags.tm_min) { if (tp) tp->relative_min = 0; origin.tm_min = 0; origin_flags.tm_min = 1; } if (!origin_flags.tm_sec) { if (tp) tp->relative_sec = 0; origin.tm_sec = 0; origin_flags.tm_sec = 1; } if (tp) tp->relative_hour = lastnumber; lastnumber = 0; } else { if (origin.tm_hour > 12) origin.tm_hour -= 12; if (tp) tp->relative_hour = origin.tm_hour; } origin_flags.tm_hour = 1; break; case TOKEN_PM: kthis = false; if (lastnumber > 0) { origin.tm_hour = lastnumber > 12 ? lastnumber : lastnumber + 12; if (!origin_flags.tm_min) { if (tp) tp->relative_min = 0; origin.tm_min = 0; origin_flags.tm_min = 1; } if (!origin_flags.tm_sec) { if (tp) tp->relative_sec = 0; origin.tm_sec = 0; origin_flags.tm_sec = 1; } if (tp) tp->relative_hour = lastnumber; lastnumber = 0; } else { if (origin.tm_hour <= 12) origin.tm_hour += 12; if (tp) tp->relative_hour = origin.tm_hour; } origin_flags.tm_hour = 1; break; case TOKEN_NOW: kthis = false; if (!origin_flags.tm_year) { if (tp) tp->relative_year = -1; origin.tm_year = onow.tm_year; } origin_flags.tm_year = 1; if (!origin_flags.tm_mon) { if (tp) tp->relative_month = -1; origin.tm_mon = onow.tm_mon; } origin_flags.tm_mon = 1; if (!origin_flags.tm_mday) { if (tp) tp->relative_day = -1; origin.tm_mday = onow.tm_mday; } origin_flags.tm_mday = 1; if (!origin_flags.tm_hour) { if (tp) tp->relative_hour = -1; origin.tm_hour = onow.tm_hour; } origin_flags.tm_hour = 1; if (!origin_flags.tm_min) { if (tp) tp->relative_min = -1; origin.tm_min = onow.tm_min; } origin_flags.tm_min = 1; if (!origin_flags.tm_sec) { if (tp) tp->relative_sec = -1; origin.tm_sec = onow.tm_sec; } break; case TOKEN_YESTERDAY: kthis = false; origin.tm_mday = onow.tm_mday - 1; origin_flags.tm_mday = 1; if (tp) tp->relative_kwday = 7; break; case TOKEN_TODAY: origin.tm_mday = onow.tm_mday; origin_flags.tm_mday = 1; if (tp) tp->relative_kwday = 8; break; case TOKEN_TOMORROW: kthis = false; origin.tm_mday = onow.tm_mday + 1; origin_flags.tm_mday = 1; if (tp) tp->relative_kwday = 9; break; case TOKEN_JANUARY: case TOKEN_FEBRUARY: case TOKEN_MARCH: case TOKEN_APRIL: case TOKEN_MAY: case TOKEN_JUNE: case TOKEN_JULY: case TOKEN_AUGUST: case TOKEN_SEPTEMBER: case TOKEN_OCTOBER: case TOKEN_NOVEMBER: case TOKEN_DECEMBER: kthis = false; if (lastnumber > 0) { origin.tm_mday = lastnumber; origin_flags.tm_mday = 1; lastnumber = 0; } origin.tm_mon = t-TOKEN_JANUARY; if (!origin_flags.tm_mday) origin.tm_mday = 1; if (!origin_flags.tm_hour) origin.tm_hour = 0; if (!origin_flags.tm_min) origin.tm_min = 0; if (!origin_flags.tm_sec) origin.tm_sec = 0; origin_flags.tm_mon = 1; if (tp) tp->relative_month = t-TOKEN_JANUARY; break; case TOKEN_IDENTIFIER: { kthis = false; // check for a year value int i = CFStringGetIntValue(token); if (i > 1970 && i < 2038 && isallnum(token)) { // max time_t range origin.tm_year = i-1900; if (!origin_flags.tm_mday) origin.tm_mday = 1; if (!origin_flags.tm_mon) origin.tm_mon = 0; if (!origin_flags.tm_hour) origin.tm_hour = 0; if (!origin_flags.tm_min) origin.tm_min = 0; if (!origin_flags.tm_sec) origin.tm_sec = 0; if (tp) tp->relative_year = i; break; } // check for 1st, 2nd, 3rd, 4th, etc. if (Ends(token, CFSTR("st")) | Ends(token, CFSTR("nd")) | Ends(token, CFSTR("rd")) | Ends(token, CFSTR("th"))) { int j = CFStringGetIntValue(token); if (j >= 1 && j <= 31) { origin.tm_mday = j; origin_flags.tm_mday = 1; if (tp) tp->relative_day = j; break; } } // check for a time string (##:##:##) #ifdef _WIN32 z = wcschr(token, L':'); if (z) { if (tp) tp->absolute_hastime = 1; wchar_t *zz = wcschr(z+1, L':'); int a, b, c=0; a = myatoi(token, (int)(z-token)); if (zz && *(zz+1) == 0) zz = NULL; if (zz && !isallnum(zz+1)) zz = NULL; if (zz) { b = myatoi(z+1, (int)(zz-(z+1))); c = wcstol(zz+1,0,10); } else b = wcstol(z+1,0,10); origin.tm_hour = a; origin.tm_min = b; if (tp) { tp->relative_hour = a; tp->relative_min = b; } if (zz && !origin_flags.tm_sec) { origin.tm_sec = c; if (tp) tp->relative_sec = c; } else if (!origin_flags.tm_sec) { origin.tm_sec = 0; } origin_flags.tm_sec = 1; origin_flags.tm_hour = 1; origin_flags.tm_min = 1; break; } #else // TODO!!! maybe CFDateFormatterGetAbsoluteTimeFromString ? #endif // check for a date string in the format ##/##/## #ifdef _WIN32 z = wcschr(token, L'/'); if (z) { if (tp) tp->absolute_hasdate = 1; wchar_t *zz = wcschr(z+1, L'/'); int a, b, c=onow.tm_year; a = myatoi(token, (int)(z-token)); if (zz && !isallnum(zz+1)) zz = NULL; if (zz && *(zz+1) == 0) zz = NULL; if (zz) { b = myatoi(z+1, (int)(zz-(z+1))); c = wcstol(zz+1,0,10); } else b = _wtoi(z+1); if (b > 1969 && b < 2038) { // mm/yyyy origin.tm_year = b-1900; origin_flags.tm_year = 1; origin.tm_mon = a-1; origin_flags.tm_mon = 1; if (!origin_flags.tm_mday) origin.tm_mday = 1; if (!origin_flags.tm_hour) origin.tm_hour = 0; if (!origin_flags.tm_min) origin.tm_min = 0; if (!origin_flags.tm_sec) origin.tm_sec = 0; if (tp) { tp->relative_year = b; tp->relative_month = a-1; } } else { // mm/dd(/yy[yy]) if (c < 70) c += 100; if (c > 138) c -= 1900; origin.tm_year = c; origin.tm_mon = a-1; origin.tm_mday = b == 0 ? 1 : b; origin_flags.tm_year = 1; origin_flags.tm_mon = 1; origin_flags.tm_mday = 1; if (!origin_flags.tm_hour) origin.tm_hour = 0; if (!origin_flags.tm_min) origin.tm_min = 0; if (!origin_flags.tm_sec) origin.tm_sec = 0; if (tp) { tp->relative_year = c+1900; tp->relative_month = a-1; tp->relative_day = b; } } origin_flags.tm_year = 1; origin_flags.tm_mon = 1; origin_flags.tm_mday = 1; break; } #else // TODO!!! maybe CFDateFormatterCreateDateFromString ? #endif if (isallnum(token)) { lastnumber = i; switch (lastt) { case TOKEN_JANUARY: case TOKEN_FEBRUARY: case TOKEN_MARCH: case TOKEN_APRIL: case TOKEN_MAY: case TOKEN_JUNE: case TOKEN_JULY: case TOKEN_AUGUST: case TOKEN_SEPTEMBER: case TOKEN_OCTOBER: case TOKEN_NOVEMBER: case TOKEN_DECEMBER: origin.tm_mday = lastnumber; origin_flags.tm_mday = 1; lastnumber = 0; if (!origin_flags.tm_hour) origin.tm_hour = 0; if (!origin_flags.tm_min) origin.tm_min = 0; if (!origin_flags.tm_sec) origin.tm_sec = 0; if (tp) tp->relative_day = lastnumber; break; case TOKEN_AT: { origin.tm_hour = lastnumber; origin.tm_min = 0; origin.tm_sec = 0; origin_flags.tm_hour = 1; origin_flags.tm_min = 1; origin_flags.tm_sec = 1; if (tp) { tp->relative_hour = lastnumber; tp->relative_min = 0; tp->relative_sec = 0; } lastnumber = 0; break; } } } break; } default: lastt = save_lastt; break; } p += size; } if (lastnumber) { switch (lastt) { case TOKEN_JANUARY: case TOKEN_FEBRUARY: case TOKEN_MARCH: case TOKEN_APRIL: case TOKEN_MAY: case TOKEN_JUNE: case TOKEN_JULY: case TOKEN_AUGUST: case TOKEN_SEPTEMBER: case TOKEN_OCTOBER: case TOKEN_NOVEMBER: case TOKEN_DECEMBER: origin.tm_mday = lastnumber; lastnumber = 0; if (!origin_flags.tm_hour) origin.tm_hour = 0; if (!origin_flags.tm_min) origin.tm_min = 0; if (!origin_flags.tm_sec) origin.tm_sec = 0; if (tp) tp->relative_day = lastnumber; break; } } if (ago) { // if ago (or before), from is optional since if it wasn't specified we use now switch (what) { case TOKEN_SECOND: origin.tm_sec -= value; break; case TOKEN_MINUTE: origin.tm_min -= value; break; case TOKEN_HOUR: origin.tm_hour -= value; break; case TOKEN_DAY: origin.tm_mday -= value; break; case TOKEN_WEEK: origin.tm_mday -= value*7; break; case TOKEN_MONTH: origin.tm_mon -= value; break; case TOKEN_YEAR: origin.tm_year -= value; break; } time_t o = mktime(&origin); SetValue(o); if (token) CFRelease(token); if (tp) tp->absolute_datetime = GetValue(); return 1; } else if (from) { // from (or after) was specified, but not ago, 5 mn from x is x + 5 mn switch (what) { case TOKEN_SECOND: origin.tm_sec += value; break; case TOKEN_MINUTE: origin.tm_min += value; break; case TOKEN_HOUR: origin.tm_hour += value; break; case TOKEN_DAY: origin.tm_mday += value; break; case TOKEN_WEEK: origin.tm_mday += value*7; break; case TOKEN_MONTH: origin.tm_mon += value; break; case TOKEN_YEAR: origin.tm_year += value; break; } time_t o = mktime(&origin); SetValue(o); if (token) CFRelease(token); if (tp) tp->absolute_datetime = GetValue(); return 1; } else { // none of ago/from/before/after were specified, just make a date/time with what we got and ignore our old value time_t o = mktime(&origin); SetValue(o); if (token) CFRelease(token); if (tp) tp->absolute_datetime = GetValue(); return 1; } if (token) CFRelease(token); if (tp) tp->absolute_datetime = GetValue(); return 0; } //--------------------------------------------------------------------------- DateTimeField::DateTimeField(int Val) : IntegerField(Val) { Type = FIELD_DATETIME; } //--------------------------------------------------------------------------- DateTimeField::DateTimeField() { Type = FIELD_DATETIME; } //--------------------------------------------------------------------------- DateTimeField::~DateTimeField() { } //--------------------------------------------------------------------------- LengthField::LengthField(int Val) : IntegerField(Val) { Type = FIELD_LENGTH; } //--------------------------------------------------------------------------- LengthField::LengthField() { Type = FIELD_LENGTH; } //--------------------------------------------------------------------------- LengthField::~LengthField() { }