* Style cleanup, no functional change.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27005 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,21 +1,22 @@
|
|||||||
/*
|
/*
|
||||||
** Copyright 2003, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2003-2008, Axel Dörfler, [email protected].
|
||||||
** Distributed under the terms of the OpenBeOS License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <OS.h>
|
|
||||||
#include <parsedate.h>
|
#include <parsedate.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <OS.h>
|
||||||
|
|
||||||
|
|
||||||
#define TRACE_PARSEDATE 0
|
#define TRACE_PARSEDATE 1
|
||||||
#if TRACE_PARSEDATE
|
#if TRACE_PARSEDATE
|
||||||
# define TRACE(x) printf x ;
|
# define TRACE(x) debug_printf x ;
|
||||||
#else
|
#else
|
||||||
# define TRACE(x) ;
|
# define TRACE(x) ;
|
||||||
#endif
|
#endif
|
||||||
@@ -106,7 +107,7 @@ static const char * const kFormatsTable[] = {
|
|||||||
"H [p]",
|
"H [p]",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
static const char * const *sFormatsTable = kFormatsTable;
|
static const char* const* sFormatsTable = kFormatsTable;
|
||||||
|
|
||||||
|
|
||||||
enum field_type {
|
enum field_type {
|
||||||
@@ -173,14 +174,21 @@ struct known_identifier {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const known_identifier kIdentifiers[] = {
|
static const known_identifier kIdentifiers[] = {
|
||||||
{"today", NULL, TYPE_UNIT, FLAG_RELATIVE | FLAG_NOT_MODIFIABLE, UNIT_DAY, 0},
|
{"today", NULL, TYPE_UNIT, FLAG_RELATIVE | FLAG_NOT_MODIFIABLE,
|
||||||
{"tomorrow", NULL, TYPE_UNIT, FLAG_RELATIVE | FLAG_NOT_MODIFIABLE, UNIT_DAY, 1},
|
UNIT_DAY, 0},
|
||||||
{"yesterday", NULL, TYPE_UNIT, FLAG_RELATIVE | FLAG_NOT_MODIFIABLE, UNIT_DAY, -1},
|
{"tomorrow", NULL, TYPE_UNIT, FLAG_RELATIVE | FLAG_NOT_MODIFIABLE,
|
||||||
{"now", NULL, TYPE_UNIT, FLAG_RELATIVE | FLAG_NOT_MODIFIABLE | FLAG_NOW, 0},
|
UNIT_DAY, 1},
|
||||||
|
{"yesterday", NULL, TYPE_UNIT, FLAG_RELATIVE | FLAG_NOT_MODIFIABLE,
|
||||||
|
UNIT_DAY, -1},
|
||||||
|
{"now", NULL, TYPE_UNIT,
|
||||||
|
FLAG_RELATIVE | FLAG_NOT_MODIFIABLE | FLAG_NOW, 0},
|
||||||
|
|
||||||
{"this", NULL, TYPE_MODIFIER, FLAG_NEXT_LAST_THIS, UNIT_NONE, MODIFY_THIS},
|
{"this", NULL, TYPE_MODIFIER, FLAG_NEXT_LAST_THIS, UNIT_NONE,
|
||||||
{"next", NULL, TYPE_MODIFIER, FLAG_NEXT_LAST_THIS, UNIT_NONE, MODIFY_NEXT},
|
MODIFY_THIS},
|
||||||
{"last", NULL, TYPE_MODIFIER, FLAG_NEXT_LAST_THIS, UNIT_NONE, MODIFY_LAST},
|
{"next", NULL, TYPE_MODIFIER, FLAG_NEXT_LAST_THIS, UNIT_NONE,
|
||||||
|
MODIFY_NEXT},
|
||||||
|
{"last", NULL, TYPE_MODIFIER, FLAG_NEXT_LAST_THIS, UNIT_NONE,
|
||||||
|
MODIFY_LAST},
|
||||||
|
|
||||||
{"years", "year", TYPE_UNIT, FLAG_RELATIVE, UNIT_YEAR, 1},
|
{"years", "year", TYPE_UNIT, FLAG_RELATIVE, UNIT_YEAR, 1},
|
||||||
{"months", "month",TYPE_UNIT, FLAG_RELATIVE, UNIT_MONTH, 1},
|
{"months", "month",TYPE_UNIT, FLAG_RELATIVE, UNIT_MONTH, 1},
|
||||||
@@ -194,7 +202,8 @@ static const known_identifier kIdentifiers[] = {
|
|||||||
{"minutes", "mins", TYPE_UNIT, FLAG_RELATIVE, UNIT_SECOND, 60},
|
{"minutes", "mins", TYPE_UNIT, FLAG_RELATIVE, UNIT_SECOND, 60},
|
||||||
|
|
||||||
{"am", NULL, TYPE_MERIDIAN, FLAG_NOT_MODIFIABLE, UNIT_SECOND, 0},
|
{"am", NULL, TYPE_MERIDIAN, FLAG_NOT_MODIFIABLE, UNIT_SECOND, 0},
|
||||||
{"pm", NULL, TYPE_MERIDIAN, FLAG_NOT_MODIFIABLE, UNIT_SECOND, 12 * 60 * 60},
|
{"pm", NULL, TYPE_MERIDIAN, FLAG_NOT_MODIFIABLE, UNIT_SECOND,
|
||||||
|
12 * 60 * 60},
|
||||||
|
|
||||||
{"sunday", "sun", TYPE_WEEKDAY, FLAG_NONE, UNIT_DAY, 0},
|
{"sunday", "sun", TYPE_WEEKDAY, FLAG_NONE, UNIT_DAY, 0},
|
||||||
{"monday", "mon", TYPE_WEEKDAY, FLAG_NONE, UNIT_DAY, 1},
|
{"monday", "mon", TYPE_WEEKDAY, FLAG_NONE, UNIT_DAY, 1},
|
||||||
@@ -218,7 +227,7 @@ static const known_identifier kIdentifiers[] = {
|
|||||||
{"december", "dec", TYPE_MONTH, FLAG_NONE, UNIT_MONTH, 12},
|
{"december", "dec", TYPE_MONTH, FLAG_NONE, UNIT_MONTH, 12},
|
||||||
|
|
||||||
{"GMT", NULL, TYPE_TIME_ZONE, FLAG_NONE, UNIT_SECOND, 0},
|
{"GMT", NULL, TYPE_TIME_ZONE, FLAG_NONE, UNIT_SECOND, 0},
|
||||||
// ToDo: add more time zones
|
// TODO: add more time zones
|
||||||
|
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
@@ -230,7 +239,7 @@ class DateMask {
|
|||||||
DateMask() : fMask(0UL) {}
|
DateMask() : fMask(0UL) {}
|
||||||
|
|
||||||
void Set(uint8 type) { fMask |= Flag(type); }
|
void Set(uint8 type) { fMask |= Flag(type); }
|
||||||
bool IsSet(uint8 type) { return fMask & Flag(type); }
|
bool IsSet(uint8 type) { return (fMask & Flag(type)) != 0; }
|
||||||
|
|
||||||
bool HasTime();
|
bool HasTime();
|
||||||
bool IsComplete();
|
bool IsComplete();
|
||||||
@@ -253,8 +262,8 @@ struct parsed_element {
|
|||||||
|
|
||||||
void SetCharType(uint8 fieldType, int8 modify = MODIFY_NONE);
|
void SetCharType(uint8 fieldType, int8 modify = MODIFY_NONE);
|
||||||
|
|
||||||
void Adopt(const known_identifier &identifier);
|
void Adopt(const known_identifier& identifier);
|
||||||
void AdoptUnit(const known_identifier &identifier);
|
void AdoptUnit(const known_identifier& identifier);
|
||||||
bool IsNextLastThis();
|
bool IsNextLastThis();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -269,7 +278,7 @@ parsed_element::SetCharType(uint8 fieldType, int8 modify)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
parsed_element::Adopt(const known_identifier &identifier)
|
parsed_element::Adopt(const known_identifier& identifier)
|
||||||
{
|
{
|
||||||
base_type = type = identifier.type;
|
base_type = type = identifier.type;
|
||||||
flags = identifier.flags;
|
flags = identifier.flags;
|
||||||
@@ -284,7 +293,7 @@ parsed_element::Adopt(const known_identifier &identifier)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
parsed_element::AdoptUnit(const known_identifier &identifier)
|
parsed_element::AdoptUnit(const known_identifier& identifier)
|
||||||
{
|
{
|
||||||
base_type = type = TYPE_UNIT;
|
base_type = type = TYPE_UNIT;
|
||||||
flags = identifier.flags;
|
flags = identifier.flags;
|
||||||
@@ -297,7 +306,8 @@ inline bool
|
|||||||
parsed_element::IsNextLastThis()
|
parsed_element::IsNextLastThis()
|
||||||
{
|
{
|
||||||
return base_type == TYPE_MODIFIER
|
return base_type == TYPE_MODIFIER
|
||||||
&& (modifier == MODIFY_NEXT || modifier == MODIFY_LAST || modifier == MODIFY_THIS);
|
&& (modifier == MODIFY_NEXT || modifier == MODIFY_LAST
|
||||||
|
|| modifier == MODIFY_THIS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -312,16 +322,15 @@ DateMask::HasTime()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** This method checks if the date mask is complete in the
|
/*! This method checks if the date mask is complete in the
|
||||||
* sense that it doesn't need to have a prefilled "struct tm"
|
sense that it doesn't need to have a prefilled "struct tm"
|
||||||
* when its time value is computed.
|
when its time value is computed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DateMask::IsComplete()
|
DateMask::IsComplete()
|
||||||
{
|
{
|
||||||
// mask must be absolute, at last
|
// mask must be absolute, at last
|
||||||
if (fMask & Flag(TYPE_UNIT))
|
if ((fMask & Flag(TYPE_UNIT)) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// minimal set of flags to have a complete set
|
// minimal set of flags to have a complete set
|
||||||
@@ -332,8 +341,8 @@ DateMask::IsComplete()
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
status_t
|
static status_t
|
||||||
preparseDate(const char *dateString, parsed_element *elements)
|
preparseDate(const char* dateString, parsed_element* elements)
|
||||||
{
|
{
|
||||||
int32 index = 0, modify = MODIFY_NONE;
|
int32 index = 0, modify = MODIFY_NONE;
|
||||||
char c;
|
char c;
|
||||||
@@ -388,8 +397,9 @@ preparseDate(const char *dateString, parsed_element *elements)
|
|||||||
|
|
||||||
// check for "1st", "2nd, "3rd", "4th", ...
|
// check for "1st", "2nd, "3rd", "4th", ...
|
||||||
|
|
||||||
const char *suffixes[] = {"th", "st", "nd", "rd"};
|
const char* suffixes[] = {"th", "st", "nd", "rd"};
|
||||||
const char *validSuffix = elements[index].value > 3 ? "th" : suffixes[elements[index].value];
|
const char* validSuffix = elements[index].value > 3
|
||||||
|
? "th" : suffixes[elements[index].value];
|
||||||
if (!strncasecmp(dateString + 1, validSuffix, 2)
|
if (!strncasecmp(dateString + 1, validSuffix, 2)
|
||||||
&& !isalpha(dateString[3])) {
|
&& !isalpha(dateString[3])) {
|
||||||
// for now, just ignore the suffix - but we might be able
|
// for now, just ignore the suffix - but we might be able
|
||||||
@@ -400,7 +410,7 @@ preparseDate(const char *dateString, parsed_element *elements)
|
|||||||
} else if (isalpha(c)) {
|
} else if (isalpha(c)) {
|
||||||
// fetch whole string
|
// fetch whole string
|
||||||
|
|
||||||
const char *string = dateString;
|
const char* string = dateString;
|
||||||
while (isalpha(dateString[1]))
|
while (isalpha(dateString[1]))
|
||||||
dateString++;
|
dateString++;
|
||||||
int32 length = dateString + 1 - string;
|
int32 length = dateString + 1 - string;
|
||||||
@@ -408,7 +418,7 @@ preparseDate(const char *dateString, parsed_element *elements)
|
|||||||
// compare with known strings
|
// compare with known strings
|
||||||
// ToDo: should understand other languages as well...
|
// ToDo: should understand other languages as well...
|
||||||
|
|
||||||
const known_identifier *identifier = kIdentifiers;
|
const known_identifier* identifier = kIdentifiers;
|
||||||
for (; identifier->string; identifier++) {
|
for (; identifier->string; identifier++) {
|
||||||
if (!strncasecmp(identifier->string, string, length)
|
if (!strncasecmp(identifier->string, string, length)
|
||||||
&& !identifier->string[length])
|
&& !identifier->string[length])
|
||||||
@@ -486,7 +496,7 @@ preparseDate(const char *dateString, parsed_element *elements)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
computeRelativeUnit(parsed_element &element, struct tm &tm, int *_flags)
|
computeRelativeUnit(parsed_element& element, struct tm& tm, int* _flags)
|
||||||
{
|
{
|
||||||
// set the relative start depending on unit
|
// set the relative start depending on unit
|
||||||
|
|
||||||
@@ -504,7 +514,7 @@ computeRelativeUnit(parsed_element &element, struct tm &tm, int *_flags)
|
|||||||
|
|
||||||
// adjust value
|
// adjust value
|
||||||
|
|
||||||
if (element.flags & FLAG_RELATIVE) {
|
if ((element.flags & FLAG_RELATIVE) != 0) {
|
||||||
if (element.unit == UNIT_MONTH)
|
if (element.unit == UNIT_MONTH)
|
||||||
tm.tm_mon += element.value;
|
tm.tm_mon += element.value;
|
||||||
else if (element.unit == UNIT_DAY)
|
else if (element.unit == UNIT_DAY)
|
||||||
@@ -536,17 +546,17 @@ computeRelativeUnit(parsed_element &element, struct tm &tm, int *_flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Uses the format assignment (through "format", and "optional") for the parsed elements
|
/*! Uses the format assignment (through "format", and "optional") for the
|
||||||
* and calculates the time value with respect to "now".
|
parsed elements and calculates the time value with respect to "now".
|
||||||
* Will also set the day/minute relative flags in "_flags".
|
Will also set the day/minute relative flags in "_flags".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static time_t
|
static time_t
|
||||||
computeDate(const char *format, bool *optional, parsed_element *elements, time_t now, DateMask dateMask, int *_flags)
|
computeDate(const char* format, bool* optional, parsed_element* elements,
|
||||||
|
time_t now, DateMask dateMask, int* _flags)
|
||||||
{
|
{
|
||||||
TRACE(("matches: %s\n", format));
|
TRACE(("matches: %s\n", format));
|
||||||
|
|
||||||
parsed_element *element = elements;
|
parsed_element* element = elements;
|
||||||
uint32 position = 0;
|
uint32 position = 0;
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
|
|
||||||
@@ -641,8 +651,9 @@ computeDate(const char *format, bool *optional, parsed_element *elements, time_t
|
|||||||
tm.tm_sec += element->value - timezone;
|
tm.tm_sec += element->value - timezone;
|
||||||
break;
|
break;
|
||||||
case 'T': // time unit
|
case 'T': // time unit
|
||||||
if (element->flags & FLAG_NOW) {
|
if ((element->flags & FLAG_NOW) != 0) {
|
||||||
*_flags = PARSEDATE_MINUTE_RELATIVE_TIME | PARSEDATE_RELATIVE_TIME;
|
*_flags = PARSEDATE_MINUTE_RELATIVE_TIME
|
||||||
|
| PARSEDATE_RELATIVE_TIME;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -666,7 +677,7 @@ computeDate(const char *format, bool *optional, parsed_element *elements, time_t
|
|||||||
|
|
||||||
|
|
||||||
time_t
|
time_t
|
||||||
parsedate_etc(const char *dateString, time_t now, int *_flags)
|
parsedate_etc(const char* dateString, time_t now, int* _flags)
|
||||||
{
|
{
|
||||||
// preparse date string so that it can be easily compared to our formats
|
// preparse date string so that it can be easily compared to our formats
|
||||||
|
|
||||||
@@ -681,10 +692,10 @@ parsedate_etc(const char *dateString, time_t now, int *_flags)
|
|||||||
for (int32 index = 0; elements[index].type != TYPE_END; index++) {
|
for (int32 index = 0; elements[index].type != TYPE_END; index++) {
|
||||||
parsed_element e = elements[index];
|
parsed_element e = elements[index];
|
||||||
|
|
||||||
printf(" %ld: type = %ld, base_type = %ld, unit = %ld, flags = %ld, value = %Ld (%s)\n",
|
printf(" %ld: type = %u, base_type = %u, unit = %u, flags = %u, "
|
||||||
index, e.type, e.base_type, e.unit, e.flags, e.value,
|
"value = %Ld (%s)\n", index, e.type, e.base_type, e.unit, e.flags,
|
||||||
e.value_type == VALUE_NUMERICAL ? "numerical" :
|
e.value, e.value_type == VALUE_NUMERICAL
|
||||||
(e.value_type == VALUE_STRING ? "string" : "char"));
|
? "numerical" : (e.value_type == VALUE_STRING ? "string" : "char"));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -693,11 +704,11 @@ parsedate_etc(const char *dateString, time_t now, int *_flags)
|
|||||||
for (int32 index = 0; sFormatsTable[index]; index++) {
|
for (int32 index = 0; sFormatsTable[index]; index++) {
|
||||||
// test if this format matches our date string
|
// test if this format matches our date string
|
||||||
|
|
||||||
const char *format = sFormatsTable[index];
|
const char* format = sFormatsTable[index];
|
||||||
uint32 position = 0;
|
uint32 position = 0;
|
||||||
DateMask dateMask;
|
DateMask dateMask;
|
||||||
|
|
||||||
parsed_element *element = elements;
|
parsed_element* element = elements;
|
||||||
while (element->type != TYPE_END) {
|
while (element->type != TYPE_END) {
|
||||||
// skip whitespace
|
// skip whitespace
|
||||||
while (isspace(format[0]))
|
while (isspace(format[0]))
|
||||||
@@ -775,7 +786,7 @@ parsedate_etc(const char *dateString, time_t now, int *_flags)
|
|||||||
dateMask.Set(TYPE_UNIT);
|
dateMask.Set(TYPE_UNIT);
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
if (element->flags & FLAG_HAS_DASH) {
|
if ((element->flags & FLAG_HAS_DASH) != 0) {
|
||||||
element--; // consider this element again
|
element--; // consider this element again
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -840,7 +851,8 @@ parsedate_etc(const char *dateString, time_t now, int *_flags)
|
|||||||
// skip the closing ']'
|
// skip the closing ']'
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the format is already empty (since we reached our last element)
|
// check if the format is already empty (since we reached our last
|
||||||
|
// element)
|
||||||
while (format[0]) {
|
while (format[0]) {
|
||||||
if (format[0] == '[')
|
if (format[0] == '[')
|
||||||
format += 3;
|
format += 3;
|
||||||
@@ -854,7 +866,8 @@ parsedate_etc(const char *dateString, time_t now, int *_flags)
|
|||||||
|
|
||||||
// made it here? then we seem to have found our guy
|
// made it here? then we seem to have found our guy
|
||||||
|
|
||||||
return computeDate(sFormatsTable[index], optional, elements, now, dateMask, _flags);
|
return computeDate(sFormatsTable[index], optional, elements, now,
|
||||||
|
dateMask, _flags);
|
||||||
|
|
||||||
skip_format:
|
skip_format:
|
||||||
// check if the next format has the same beginning as the skipped one,
|
// check if the next format has the same beginning as the skipped one,
|
||||||
@@ -873,7 +886,7 @@ parsedate_etc(const char *dateString, time_t now, int *_flags)
|
|||||||
|
|
||||||
|
|
||||||
time_t
|
time_t
|
||||||
parsedate(const char *dateString, time_t now)
|
parsedate(const char* dateString, time_t now)
|
||||||
{
|
{
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
@@ -882,15 +895,15 @@ parsedate(const char *dateString, time_t now)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
set_dateformats(const char **table)
|
set_dateformats(const char** table)
|
||||||
{
|
{
|
||||||
sFormatsTable = table ? table : kFormatsTable;
|
sFormatsTable = table ? table : kFormatsTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char **
|
const char**
|
||||||
get_dateformats(void)
|
get_dateformats(void)
|
||||||
{
|
{
|
||||||
return const_cast<const char **>(sFormatsTable);
|
return const_cast<const char**>(sFormatsTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user