// Copyright (C) 1999-2005 Open Source Telecom Corporation.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
//
// This exception applies only to the code released under the name GNU
// ccScript. If you copy code from other releases into a copy of GNU
// ccScript, as the General Public License permits, the exception does
// not apply to the code that you add in this way. To avoid misleading
// anyone as to the status of such modified files, you must delete
// this exception notice from them.
//
// If you write modifications of your own for GNU ccScript, it is your choice
// whether to permit this exception to apply to your modifications.
// If you do not wish that, delete this exception notice.
//
#include "script3.h"
namespace ccscript3Extension {
using namespace std;
using namespace ost;
class TimeProperty : public ScriptProperty
{
public:
TimeProperty();
void set(const char *data, char *temp, unsigned size);
long getValue(const char *data);
char token(void);
void clear(char *data, unsigned size);
static bool testLocaltime(ScriptInterp *interp, const char *v);
};
class DateProperty : public ScriptProperty
{
public:
DateProperty();
void set(const char *data, char *temp, unsigned size);
long getValue(const char *data);
char token(void);
void clear(char *data, unsigned size);
};
class TimeMethods : public ScriptMethods
{
public:
bool scrTime(void);
bool scrDate(void);
};
class TimeChecks : public ScriptChecks
{
public:
};
static Script::Define runtime[] = {
{"time", true, (Script::Method)&TimeMethods::scrTime,
(Script::Check)&ScriptChecks::chkType},
{"date", true, (Script::Method)&TimeMethods::scrDate,
(Script::Check)&ScriptChecks::chkType},
{NULL, false, NULL, NULL}};
static ScriptBinder bindTime(runtime);
static TimeProperty typeTime;
static DateProperty typeDate;
DateProperty::DateProperty() :
ScriptProperty("date")
{
}
char DateProperty::token(void)
{
return '-';
}
long DateProperty::getValue(const char *date)
{
long year, month, day;
const char *fp, *lp;
fp = strchr(date, '-');
lp = strrchr(date, '-');
if(fp && fp != lp)
{
year = atol(date);
month = atol(++fp);
day = atol(++lp);
goto jul;
}
fp = strchr(date, '/');
lp = strrchr(date, '/');
if(fp && fp != lp)
{
year = atol(++lp);
month = atol(date);
day = atol(++fp);
goto jul;
}
fp = strchr(date, '.');
lp = strrchr(date, '.');
if(fp && fp != lp)
{
year = atol(++lp);
month = atol(++fp);
day = atol(date);
goto jul;
}
return atol(date);
jul:
if(year < 10)
year += 2000;
else if(year < 100)
year += 1900;
return day - 32075l +
1461l * (year + 4800l + ( month - 14l) / 12l) / 4l +
367l * (month - 2l - (month - 14l) / 12l * 12l) / 12l -
3l * ((year + 4900l + (month - 14l) / 12l) / 100l) / 4l;
}
void DateProperty::set(const char *data, char *save, unsigned size)
{
long julian = getValue(data);
long year, month, day;
if(size < 11)
{
snprintf(save, size, "%ld", julian);
return;
}
double i, j, k, l, n;
l = julian + 68569.0;
n = int( 4 * l / 146097.0);
l = l - int( (146097.0 * n + 3)/ 4 );
i = int( 4000.0 * (l+1)/1461001.0);
l = l - int(1461.0*i/4.0) + 31.0;
j = int( 80 * l/2447.0);
k = l - int( 2447.0 * j / 80.0);
l = int(j/11);
j = j+2-12*l;
i = 100*(n - 49) + i + l;
year = int(i);
month = int(j);
day = int(k);
snprintf(save, size, "%04ld-%02ld-%02ld", year, month, day);
}
TimeProperty::TimeProperty() :
ScriptProperty("time")
{
addConditional("localtime", &testLocaltime);
}
char TimeProperty::token(void)
{
return ':';
}
long TimeProperty::getValue(const char *data)
{
long val;
const char *mp = strchr(data, ':');
const char *sp = strrchr(data, ':');
if(mp == sp)
sp = NULL;
if(!mp)
return atol(data);
val = atol(data) * 3600l;
if(mp)
val += atol(++mp) * 60l;
if(sp)
val += atol(++sp);
return val;
}
void DateProperty::clear(char *data, unsigned size)
{
if(!size)
size = 11;
if(size < 11)
data[0] = 0;
else
strcpy(data, "0000-00-00");
}
void TimeProperty::set(const char *data, char *save, unsigned size)
{
long val = getValue(data);
val %= 86400l;
if(size < 6)
snprintf(save, size, "%ld", val);
else if(size < 9)
snprintf(save, size, "%02ld:%02ld",
val / 3600l, (val / 60l) % 60);
else
snprintf(save, size, "%02ld:%02ld:%02ld",
val / 3600l, (val / 60l) % 60, val % 60);
}
void TimeProperty::clear(char *data, unsigned size)
{
if(!size)
size = 9;
if(size < 6)
{
strcpy(data, "0");
return;
}
else if(size < 9)
snprintf(data, size, "00:00");
else
snprintf(data, size, "00:00:00");
}
bool TimeMethods::scrDate(void)
{
const char *cp;
ScriptProperty *p = &typeDate;
Symbol *sym;
time_t now;
struct tm *dt, dtd;
char dts[12];
time(&now);
dt = localtime_r(&now, &dtd);
if(dt->tm_year < 500)
dt->tm_year += 1900;
snprintf(dts, sizeof(dts), "%04d-%02d-%02d",
dt->tm_year, dt->tm_mon + 1, dt->tm_mday);
while(NULL != (cp = getOption(NULL)))
{
sym = mapSymbol(cp, 11 + sizeof(p));
if(!sym)
continue;
if(sym->type != symINITIAL)
{
commit(sym, dts);
continue;
}
sym->type = symPROPERTY;
memcpy(sym->data, &p, sizeof(p));
strcpy(sym->data + sizeof(p), dts);
}
advance();
return true;
}
bool TimeMethods::scrTime(void)
{
const char *cp;
ScriptProperty *p = &typeTime;
Symbol *sym;
time_t now;
struct tm *dt, dtd;
char dts[10];
time(&now);
dt = localtime_r(&now, &dtd);
snprintf(dts, sizeof(dts), "%02d:%02d:%02d",
dt->tm_hour, dt->tm_min, dt->tm_sec);
while(NULL != (cp = getOption(NULL)))
{
sym = mapSymbol(cp, 9 + sizeof(p));
if(!sym)
continue;
if(sym->type != symINITIAL)
{
commit(sym, dts);
continue;
}
sym->type = symPROPERTY;
memcpy(sym->data, &p, sizeof(p));
strcpy(sym->data + sizeof(p), dts);
}
advance();
return true;
}
bool TimeProperty::testLocaltime(ScriptInterp *interp, const char *v)
{
char *tok;
char *tp;
struct tm *dt, dtp;
time_t now;
char buf[256];
long ftime;
long ltime;
long ntime;
bool day[7] = {false, false, false, false, false, false, false};
static char *dayname[7] = {"sun", "mon", "tue", "wed", "thu", "fri", "sat"};
unsigned idx;
time(&now);
dt = localtime_r(&now, &dtp);
setString(buf, sizeof(buf), v);
ntime = dt->tm_hour * 60 + dt->tm_min;
bool weekday = false;
tok = strtok_r(buf, ", ;\t", &tp);
while(NULL != tok)
{
if(strchr(tok, ':'))
{
ftime = 0;
ltime = 24 * 60;
if(*tok != '-')
{
ftime = 60 * atoi(tok);
tok = strchr(tok, ':');
if(tok)
ftime += atoi(++tok);
else
tok = "";
}
tok = strchr(tok, '-');
if(tok)
{
ltime = 60 * atoi(++tok);
tok = strchr(tok, ':');
if(tok)
ltime += atoi(++tok);
}
if(ntime < ftime || ntime > ltime)
return false;
goto loop;
}
for(idx = 0 ; idx < 7; ++idx)
{
if(!strnicmp(dayname[idx], tok, 3))
break;
}
if(idx < 7)
{
weekday = true;
day[idx] = true;
goto loop;
}
if(!stricmp(tok, "weekday"))
{
weekday = true;
day[1] = day[2] = day[3] = day[4] = day[5] = true;
goto loop;
}
if(!stricmp(tok, "weekend"))
{
weekday = true;
day[0] = day[6] = true;
goto loop;
}
loop:
tok = strtok_r(NULL, ", ;\t", &tp);
}
if(weekday)
return day[dt->tm_wday];
return true;
}
}; // namespace
syntax highlighted by Code2HTML, v. 0.9.1