init
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
PROJECT(openvibe-module-date)
|
||||
|
||||
SET(PROJECT_VERSION_MAJOR ${OV_GLOBAL_VERSION_MAJOR})
|
||||
SET(PROJECT_VERSION_MINOR ${OV_GLOBAL_VERSION_MINOR})
|
||||
SET(PROJECT_VERSION_PATCH ${OV_GLOBAL_VERSION_PATCH})
|
||||
SET(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})
|
||||
|
||||
SET(SRC_FILES
|
||||
include/date/defines.h
|
||||
include/date/DateParser.h
|
||||
src/DateParser.cpp
|
||||
)
|
||||
|
||||
IF(WIN32)
|
||||
LIST(APPEND SRC_FILES
|
||||
"include/date/WindowsDateParser.h"
|
||||
"src/WindowsDateParser.cpp"
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
INCLUDE_DIRECTORIES(include/date)
|
||||
INCLUDE("FindSourceRCProperties")
|
||||
|
||||
ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRC_FILES})
|
||||
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
FOLDER ${MODULES_FOLDER}
|
||||
COMPILE_FLAGS "-DDate_Shared -DDate_Exports")
|
||||
|
||||
ADD_LIBRARY(${PROJECT_NAME}-static STATIC ${SRC_FILES})
|
||||
SET_TARGET_PROPERTIES(${PROJECT_NAME}-static PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
FOLDER ${MODULES_FOLDER}
|
||||
COMPILE_FLAGS "-DDate_Static -DDate_Exports")
|
||||
|
||||
IF(UNIX)
|
||||
SET_TARGET_PROPERTIES(${PROJECT_NAME}-static PROPERTIES COMPILE_FLAGS "-fPIC")
|
||||
ENDIF(UNIX)
|
||||
|
||||
INCLUDE("FindOpenViBECommon")
|
||||
INCLUDE("FindThirdPartyBoost")
|
||||
INCLUDE("FindThirdPartyExpat")
|
||||
|
||||
# ---------------------------------
|
||||
# Target macros
|
||||
# Defines target operating system, architecture and compiler
|
||||
# ---------------------------------
|
||||
SET_BUILD_PLATFORM()
|
||||
|
||||
# -----------------------------
|
||||
# Install files
|
||||
# -----------------------------
|
||||
INSTALL(TARGETS ${PROJECT_NAME}
|
||||
RUNTIME DESTINATION ${DIST_BINDIR}
|
||||
LIBRARY DESTINATION ${DIST_LIBDIR}
|
||||
ARCHIVE DESTINATION ${DIST_LIBDIR})
|
||||
INSTALL(TARGETS ${PROJECT_NAME}-static
|
||||
RUNTIME DESTINATION ${DIST_BINDIR}
|
||||
LIBRARY DESTINATION ${DIST_LIBDIR}
|
||||
ARCHIVE DESTINATION ${DIST_LIBDIR})
|
||||
|
||||
INSTALL(DIRECTORY include/ DESTINATION ${DIST_INCLUDEDIR} FILES_MATCHING PATTERN "*.h" PATTERN)
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "defines.h"
|
||||
#if defined TARGET_OS_Windows
|
||||
#include "WindowsDateParser.h"
|
||||
#else
|
||||
#include <ctime>
|
||||
#endif
|
||||
|
||||
namespace DateParser {
|
||||
class Date_API CDateParser
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief parse a string representing a date along a format given by a char*, and store it in a tm struct
|
||||
* \param sStringToParse: the string to parse
|
||||
* \param sDateFormat: the string that gives the format of the date to parse, example "%Y-%m-%d %H:%M"
|
||||
* \param tmParsed: time parsed
|
||||
*/
|
||||
static char* strpTime(const char* sStringToParse, const char* sDateFormat, struct tm* tmParsed);
|
||||
|
||||
private:
|
||||
CDateParser() = default;
|
||||
};
|
||||
} // namespace DateParser
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#include "defines.h"
|
||||
#include <ctime>
|
||||
|
||||
namespace DateParser {
|
||||
extern Date_API char* windowsStrptime(const char* buf, const char* fmt, struct tm* tmParsed);
|
||||
} // namespace DateParser
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <ov_common_defines.h>
|
||||
|
||||
#if defined Date_Shared
|
||||
# if defined TARGET_OS_Windows
|
||||
# define Date_API_Export __declspec(dllexport)
|
||||
# define Date_API_Import __declspec(dllimport)
|
||||
# elif defined TARGET_OS_Linux
|
||||
# define Date_API_Export __attribute__((visibility("default")))
|
||||
# define Date_API_Import __attribute__((visibility("default")))
|
||||
# else
|
||||
# define Date_API_Export
|
||||
# define Date_API_Import
|
||||
# endif
|
||||
#else
|
||||
# define Date_API_Export
|
||||
# define Date_API_Import
|
||||
#endif
|
||||
|
||||
#if defined Date_Exports
|
||||
# define Date_API Date_API_Export
|
||||
#else
|
||||
# define Date_API Date_API_Import
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "DateParser.h"
|
||||
|
||||
namespace DateParser {
|
||||
|
||||
char* CDateParser::strpTime(const char* sStringToParse, const char* sDateFormat, struct tm* tmParsed)
|
||||
{
|
||||
#if defined TARGET_OS_Windows
|
||||
return windowsStrptime(sStringToParse, sDateFormat, tmParsed);
|
||||
#else
|
||||
return strptime(sStringToParse, sDateFormat, tmParsed);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace DateParser
|
||||
@@ -0,0 +1,357 @@
|
||||
/* $Id$ */
|
||||
/* $NetBSD: windowsStrptime.c,v 1.18 1999/04/29 02:58:30 tv Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code was contributed to The NetBSD Foundation by Klaus Klein.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <array>
|
||||
#if defined TARGET_OS_Windows
|
||||
#include <iostream>
|
||||
#include "WindowsDateParser.h"
|
||||
|
||||
namespace DateParser {
|
||||
|
||||
/*
|
||||
* We do not implement alternate representations. However, we always
|
||||
* check whether a given modifier is allowed for a certain conversion.
|
||||
*/
|
||||
#define ALT_E 0x01
|
||||
#define ALT_O 0x02
|
||||
#define LEGAL_ALT(x) if (alt_format & ~(x)) { return 0; }
|
||||
|
||||
#define EPOCH_YEAR 1970
|
||||
#define SECSPERHOUR 3600
|
||||
#define SECSPERDAY 86400
|
||||
#define TM_YEAR_BASE 1900
|
||||
|
||||
static int ConvNum(const char** buf, int* dest, const int llim, const int ulim);
|
||||
|
||||
static const std::array<const std::string, 7> DAY = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
|
||||
static const std::array<const std::string, 7> AB_DAY = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
||||
static const std::array<const std::string, 12> MON = {
|
||||
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
|
||||
};
|
||||
static const std::array<const std::string, 12> AB_MON = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||
static const std::array<const std::string, 2> AM_PM = { "AM", "PM" };
|
||||
|
||||
|
||||
Date_API char* DateParser::windowsStrptime(const char* buf, const char* fmt, struct tm* tmParsed)
|
||||
{
|
||||
char c;
|
||||
const char* bp;
|
||||
size_t len = 0;
|
||||
int i, split_year = 0;
|
||||
|
||||
bp = buf;
|
||||
|
||||
while ((c = *fmt) != '\0')
|
||||
{
|
||||
/* Clear `alternate' modifier prior to new conversion. */
|
||||
int alt_format = 0;
|
||||
|
||||
/* Eat up white-space. */
|
||||
if (isspace(c))
|
||||
{
|
||||
while (isspace(*bp)) { bp++; }
|
||||
fmt++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((c = *fmt++) != '%') { goto literal; }
|
||||
|
||||
|
||||
again: switch (c = *fmt++)
|
||||
{
|
||||
case '%': /* "%%" is converted to "%". */
|
||||
literal :
|
||||
if (c != *bp++) { return (nullptr); }
|
||||
break;
|
||||
|
||||
/*
|
||||
* "Alternative" modifiers. Just set the appropriate flag
|
||||
* and start over again.
|
||||
*/
|
||||
case 'E': /* "%E?" alternative conversion modifier. */
|
||||
LEGAL_ALT(0);
|
||||
alt_format |= ALT_E;
|
||||
goto again;
|
||||
|
||||
case 'O': /* "%O?" alternative conversion modifier. */
|
||||
LEGAL_ALT(0);
|
||||
alt_format |= ALT_O;
|
||||
goto again;
|
||||
|
||||
/*
|
||||
* "Complex" conversion rules, implemented through recursion.
|
||||
*/
|
||||
case 'c': /* Date and time, using the locale's format. */
|
||||
LEGAL_ALT(ALT_E);
|
||||
if (!((bp = windowsStrptime(bp, "%x %X", tmParsed)))) { return nullptr; }
|
||||
break;
|
||||
|
||||
case 'D': /* The date as "%m/%d/%y". */
|
||||
LEGAL_ALT(0);
|
||||
if (!((bp = windowsStrptime(bp, "%m/%d/%y", tmParsed)))) { return nullptr; }
|
||||
break;
|
||||
|
||||
case 'R': /* The time as "%H:%M". */
|
||||
LEGAL_ALT(0);
|
||||
if (!((bp = windowsStrptime(bp, "%H:%M", tmParsed)))) { return nullptr; }
|
||||
break;
|
||||
|
||||
case 'r': /* The time in 12-hour clock representation. */
|
||||
LEGAL_ALT(0);
|
||||
if (!((bp = windowsStrptime(bp, "%I:%M:%S %p", tmParsed)))) { return nullptr; }
|
||||
break;
|
||||
|
||||
case 'T': /* The time as "%H:%M:%S". */
|
||||
LEGAL_ALT(0);
|
||||
if (!((bp = windowsStrptime(bp, "%H:%M:%S", tmParsed)))) { return nullptr; }
|
||||
break;
|
||||
|
||||
case 'X': /* The time, using the locale's format. */
|
||||
LEGAL_ALT(ALT_E);
|
||||
if (!((bp = windowsStrptime(bp, "%H:%M:%S", tmParsed)))) { return nullptr; }
|
||||
break;
|
||||
|
||||
case 'x': /* The date, using the locale's format. */
|
||||
LEGAL_ALT(ALT_E);
|
||||
if (!((bp = windowsStrptime(bp, "%m/%d/%y", tmParsed)))) { return nullptr; }
|
||||
break;
|
||||
|
||||
/*
|
||||
* "Elementary" conversion rules.
|
||||
*/
|
||||
case 'A': /* The day of week, using the locale's form. */
|
||||
case 'a':
|
||||
LEGAL_ALT(0);
|
||||
for (i = 0; i < 7; ++i)
|
||||
{
|
||||
/* Full name. */
|
||||
len = DAY[i].size();
|
||||
if (strncmp(DAY[i].c_str(), bp, len) == 0) { break; }
|
||||
|
||||
/* Abbreviated name. */
|
||||
len = AB_DAY[i].size();
|
||||
if (strncmp(AB_DAY[i].c_str(), bp, len) == 0) { break; }
|
||||
}
|
||||
|
||||
/* Nothing matched. */
|
||||
if (i == 7) { return nullptr; }
|
||||
|
||||
tmParsed->tm_wday = i;
|
||||
bp += len;
|
||||
break;
|
||||
|
||||
case 'B': /* The month, using the locale's form. */
|
||||
case 'b':
|
||||
case 'h':
|
||||
LEGAL_ALT(0);
|
||||
for (i = 0; i < 12; ++i)
|
||||
{
|
||||
/* Full name. */
|
||||
len = MON[i].size();
|
||||
if (strncmp(MON[i].c_str(), bp, len) == 0) { break; }
|
||||
|
||||
/* Abbreviated name. */
|
||||
len = AB_MON[i].size();
|
||||
if (strncmp(AB_MON[i].c_str(), bp, len) == 0) { break; }
|
||||
}
|
||||
|
||||
/* Nothing matched. */
|
||||
if (i == 12) { return (nullptr); }
|
||||
|
||||
tmParsed->tm_mon = i;
|
||||
bp += len;
|
||||
break;
|
||||
|
||||
case 'C': /* The century number. */
|
||||
LEGAL_ALT(ALT_E);
|
||||
if (!(ConvNum(&bp, &i, 0, 99))) { return (nullptr); }
|
||||
|
||||
if (split_year) { tmParsed->tm_year = (tmParsed->tm_year % 100) + (i * 100); }
|
||||
else
|
||||
{
|
||||
tmParsed->tm_year = i * 100;
|
||||
split_year = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'd': /* The day of month. */
|
||||
case 'e':
|
||||
LEGAL_ALT(ALT_O);
|
||||
if (!(ConvNum(&bp, &tmParsed->tm_mday, 1, 31))) { return (nullptr); }
|
||||
break;
|
||||
|
||||
case 'k': /* The hour (24-hour clock representation). */
|
||||
LEGAL_ALT(0);
|
||||
/* FALLTHROUGH */
|
||||
case 'H':
|
||||
LEGAL_ALT(ALT_O);
|
||||
if (!(ConvNum(&bp, &tmParsed->tm_hour, 0, 23))) { return (nullptr); }
|
||||
break;
|
||||
|
||||
case 'l': /* The hour (12-hour clock representation). */
|
||||
LEGAL_ALT(0);
|
||||
/* FALLTHROUGH */
|
||||
case 'I':
|
||||
LEGAL_ALT(ALT_O);
|
||||
if (!(ConvNum(&bp, &tmParsed->tm_hour, 1, 12))) { return (nullptr); }
|
||||
if (tmParsed->tm_hour == 12) { tmParsed->tm_hour = 0; }
|
||||
break;
|
||||
|
||||
case 'j': /* The day of year. */
|
||||
LEGAL_ALT(0);
|
||||
if (!(ConvNum(&bp, &i, 1, 366))) { return (nullptr); }
|
||||
tmParsed->tm_yday = i - 1;
|
||||
break;
|
||||
|
||||
case 'M': /* The minute. */
|
||||
LEGAL_ALT(ALT_O);
|
||||
if (!(ConvNum(&bp, &tmParsed->tm_min, 0, 59))) { return (nullptr); }
|
||||
break;
|
||||
|
||||
case 'm': /* The month. */
|
||||
LEGAL_ALT(ALT_O);
|
||||
if (!(ConvNum(&bp, &i, 1, 12))) { return (nullptr); }
|
||||
tmParsed->tm_mon = i - 1;
|
||||
break;
|
||||
|
||||
case 'p': /* The locale's equivalent of AM/PM. */
|
||||
LEGAL_ALT(0);
|
||||
/* AM? */
|
||||
if (strcmp(AM_PM[0].c_str(), bp) == 0)
|
||||
{
|
||||
if (tmParsed->tm_hour > 11) { return (nullptr); }
|
||||
bp += AM_PM[0].size();
|
||||
break;
|
||||
}
|
||||
/* PM? */
|
||||
if (strcmp(AM_PM[1].c_str(), bp) == 0)
|
||||
{
|
||||
if (tmParsed->tm_hour > 11) { return (nullptr); }
|
||||
tmParsed->tm_hour += 12;
|
||||
bp += AM_PM[1].size();
|
||||
break;
|
||||
}
|
||||
|
||||
/* Nothing matched. */
|
||||
return nullptr;
|
||||
|
||||
case 'S': /* The seconds. */
|
||||
LEGAL_ALT(ALT_O);
|
||||
if (!(ConvNum(&bp, &tmParsed->tm_sec, 0, 61))) { return (nullptr); }
|
||||
break;
|
||||
|
||||
case 'U': /* The week of year, beginning on sunday. */
|
||||
case 'W': /* The week of year, beginning on monday. */
|
||||
LEGAL_ALT(ALT_O);
|
||||
/*
|
||||
* XXX This is bogus, as we can not assume any valid
|
||||
* information present in the tm structure at this
|
||||
* point to calculate a real value, so just check the
|
||||
* range for now.
|
||||
*/
|
||||
if (!(ConvNum(&bp, &i, 0, 53))) { return (nullptr); }
|
||||
break;
|
||||
|
||||
case 'w': /* The day of week, beginning on sunday. */
|
||||
LEGAL_ALT(ALT_O);
|
||||
if (!(ConvNum(&bp, &tmParsed->tm_wday, 0, 6))) { return (nullptr); }
|
||||
break;
|
||||
|
||||
case 'Y': /* The year. */
|
||||
LEGAL_ALT(ALT_E);
|
||||
if (!(ConvNum(&bp, &i, 0, 9999))) { return (nullptr); }
|
||||
|
||||
tmParsed->tm_year = i - TM_YEAR_BASE;
|
||||
break;
|
||||
|
||||
case 'y': /* The year within 100 years of the epoch. */
|
||||
LEGAL_ALT(ALT_E | ALT_O);
|
||||
if (!(ConvNum(&bp, &i, 0, 99))) { return (nullptr); }
|
||||
|
||||
if (split_year)
|
||||
{
|
||||
tmParsed->tm_year = ((tmParsed->tm_year / 100) * 100) + i;
|
||||
break;
|
||||
}
|
||||
split_year = 1;
|
||||
if (i <= 68) { tmParsed->tm_year = i + 2000 - TM_YEAR_BASE; }
|
||||
else { tmParsed->tm_year = i + 1900 - TM_YEAR_BASE; }
|
||||
break;
|
||||
|
||||
/*
|
||||
* Miscellaneous conversions.
|
||||
*/
|
||||
case 'n': /* Any kind of white-space. */
|
||||
case 't':
|
||||
LEGAL_ALT(0);
|
||||
while (isspace(*bp)) { bp++; }
|
||||
break;
|
||||
|
||||
|
||||
default: return nullptr; /* Unknown/unsupported conversion. */
|
||||
}
|
||||
}
|
||||
|
||||
/* LINTED functional specification */
|
||||
return const_cast<char*>(bp);
|
||||
}
|
||||
|
||||
|
||||
static int ConvNum(const char** buf, int* dest, const int llim, const int ulim)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
/* The limit also determines the number of valid digits. */
|
||||
int rulim = ulim;
|
||||
|
||||
if (**buf < '0' || **buf > '9') { return (0); }
|
||||
|
||||
do
|
||||
{
|
||||
result *= 10;
|
||||
result += *(*buf)++ - '0';
|
||||
rulim /= 10;
|
||||
} while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9');
|
||||
|
||||
if (result < llim || result > ulim) { return 0; }
|
||||
|
||||
*dest = result;
|
||||
return 1;
|
||||
}
|
||||
|
||||
} // namespace DateParser
|
||||
#endif
|
||||
Reference in New Issue
Block a user