1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
/*
* SPL - The SPL Programming Language
* Copyright (C) 2005, 2006 Michael Bauer <mihi@lo-res.org>
* Copyright (C) 2006 Clifford Wolf <clifford@clifford.at>
*
* 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
*
* mod_time.c: A simple spl module for time and time manipulations.
*/
/**
* A module for time and time manipulations
*/
#define _GNU_SOURCE
#include <stdlib.h>
#include <time.h>
#include "spl.h"
#include "compat.h"
extern void SPL_ABI(spl_mod_time_init)(struct spl_vm *vm, struct spl_module *mod, int restore);
extern void SPL_ABI(spl_mod_time_done)(struct spl_vm *vm, struct spl_module *mod);
/* conversion of node to struct tm */
static void convert_node_to_tm(struct spl_task *task, struct spl_node *node, struct tm *ttm)
{
memset(ttm, 0, sizeof(struct tm));
ttm->tm_sec = spl_get_int(spl_lookup(task, node, "sec", SPL_LOOKUP_TEST));
ttm->tm_min = spl_get_int(spl_lookup(task, node, "min", SPL_LOOKUP_TEST));
ttm->tm_hour = spl_get_int(spl_lookup(task, node, "hour", SPL_LOOKUP_TEST));
ttm->tm_mday = spl_get_int(spl_lookup(task, node, "mday", SPL_LOOKUP_TEST));
ttm->tm_mon = spl_get_int(spl_lookup(task, node, "mon", SPL_LOOKUP_TEST));
ttm->tm_year = spl_get_int(spl_lookup(task, node, "year", SPL_LOOKUP_TEST));
ttm->tm_wday = spl_get_int(spl_lookup(task, node, "wday", SPL_LOOKUP_TEST));
ttm->tm_yday = spl_get_int(spl_lookup(task, node, "yday", SPL_LOOKUP_TEST));
ttm->tm_isdst = spl_get_int(spl_lookup(task, node, "isdst", SPL_LOOKUP_TEST));
#if !defined USECYGWINAPI && !defined USEWIN32API && !defined USEIRIXAPI
ttm->tm_zone = spl_get_string(spl_lookup(task, node, "zone", SPL_LOOKUP_TEST));
ttm->tm_gmtoff = spl_get_int(spl_lookup(task, node, "gmtoff", SPL_LOOKUP_TEST));
#endif
spl_put(task->vm, node);
}
/* conversion of struct tm to node */
static struct spl_node *convert_tm_to_node(struct spl_task *task, struct tm *ttm)
{
struct spl_node *result = spl_get(0);
spl_create(task, result, "sec", SPL_NEW_INT(ttm->tm_sec), SPL_CREATE_LOCAL);
spl_create(task, result, "min", SPL_NEW_INT(ttm->tm_min), SPL_CREATE_LOCAL);
spl_create(task, result, "hour", SPL_NEW_INT(ttm->tm_hour), SPL_CREATE_LOCAL);
spl_create(task, result, "mday", SPL_NEW_INT(ttm->tm_mday), SPL_CREATE_LOCAL);
spl_create(task, result, "mon", SPL_NEW_INT(ttm->tm_mon), SPL_CREATE_LOCAL);
spl_create(task, result, "year", SPL_NEW_INT(ttm->tm_year), SPL_CREATE_LOCAL);
spl_create(task, result, "wday", SPL_NEW_INT(ttm->tm_wday), SPL_CREATE_LOCAL);
spl_create(task, result, "yday", SPL_NEW_INT(ttm->tm_yday), SPL_CREATE_LOCAL);
spl_create(task, result, "isdst", SPL_NEW_INT(ttm->tm_isdst), SPL_CREATE_LOCAL);
#if !defined USECYGWINAPI && !defined USEWIN32API && !defined USEIRIXAPI
spl_create(task, result, "zone", SPL_NEW_STRING_DUP(ttm->tm_zone), SPL_CREATE_LOCAL);
spl_create(task, result, "gmtoff", SPL_NEW_INT(ttm->tm_gmtoff), SPL_CREATE_LOCAL);
#endif
return result;
}
/**
* This function returns the number of seconds since the epoch.
*/
// builtin time()
static struct spl_node *handler_time(struct spl_task *task UNUSED, void *data UNUSED)
{
return SPL_NEW_INT(time(NULL));
}
/**
* This function converts the number of seconds since the epoch (as
* returned by [[time()]]) so a node with the childs .sec, .min, .hour, .mday
* .month, .wday, .year, .yday, .gmtoff, .isdst and .zone. (It is simply a
* wrapper to the struct tm as defined in time.h.)
*/
// builtin time_local(time)
static struct spl_node *handler_localtime(struct spl_task *task, void *data UNUSED)
{
time_t tt = spl_clib_get_int(task);
struct tm ttm;
#ifdef USEWIN32API
ttm = *localtime(&tt);
#else
localtime_r(&tt, &ttm);
#endif
return convert_tm_to_node(task, &ttm);
}
/**
* This function converts the nuber of seconds since the epoch (as
* treturned by [[time()]]) to a time node as returned by [[time_local()]],
* but in GMT.
*/
// builtin time_gm(time)
static struct spl_node *handler_gmtime(struct spl_task *task, void *data UNUSED)
{
time_t tt = spl_clib_get_int(task);
struct tm ttm;
#ifdef USEWIN32API
ttm = *gmtime(&tt);
#else
gmtime_r(&tt, &ttm);
#endif
return convert_tm_to_node(task, &ttm);
}
/**
* This function returns the difference in seconds between time1 and time0.
* It expects two ints containing the number of seconds since the epoch as
* returned by [[time()]].
*/
// builtin time_diff(time1, time0)
static struct spl_node *handler_difftime(struct spl_task *task, void *data UNUSED)
{
return SPL_NEW_INT(difftime(spl_clib_get_int(task), spl_clib_get_int(task)));
}
/**
* This Function formats a time node as returned by [[time_local()]] according
* to the strftime manpage. This is simply a wrapper to the strftime() C
* library function.
*/
// builtin time_fmt(format, tm)
static struct spl_node *handler_fmttime(struct spl_task *task, void *data UNUSED)
{
char *format = spl_clib_get_string(task);
struct tm ttm;
convert_node_to_tm(task, spl_clib_get_node(task), &ttm);
int buffer_len = strlen(format) + 1024;
char buffer[buffer_len];
int rc = strftime(buffer, buffer_len-1, format, &ttm);
return rc > 0 ? SPL_NEW_STRING_DUP(buffer) : SPL_NEW_STRING_DUP("");
}
/**
* This function converts a time node as returned by [[time_local()]] to the
* count of seconds since the epoch as returned by [[time()]].
*/
// builtin time_mk(tm)
static struct spl_node *handler_mktime(struct spl_task *task, void *data UNUSED)
{
struct tm ttm;
convert_node_to_tm(task, spl_clib_get_node(task), &ttm);
return SPL_NEW_INT(mktime(&ttm));
}
/**
* This function converts a time node as returned by [[time_gm()]] to the
* count of seconds since the epoch as returned by [[time()]], it works similar
* to mktime but assumes the time node is in GMT.
*
* This function is not available on the CYGWIN platform.
*/
// builtin time_mkgm(tm)
#if !defined USECYGWINAPI && !defined USEWIN32API && !defined USEIRIXAPI
static struct spl_node *handler_timegm(struct spl_task *task, void *data UNUSED)
{
struct tm ttm;
convert_node_to_tm(task, spl_clib_get_node(task), &ttm);
return SPL_NEW_INT(timegm(&ttm));
}
#endif
void SPL_ABI(spl_mod_time_init)(struct spl_vm *vm, struct spl_module *mod UNUSED, int restore UNUSED)
{
spl_clib_reg(vm, "time", handler_time, 0);
spl_clib_reg(vm, "time_local", handler_localtime, 0);
spl_clib_reg(vm, "time_gm", handler_gmtime, 0);
spl_clib_reg(vm, "time_diff", handler_difftime, 0);
spl_clib_reg(vm, "time_fmt", handler_fmttime, 0);
spl_clib_reg(vm, "time_mk", handler_mktime, 0);
#if !defined USECYGWINAPI && !defined USEWIN32API && !defined USEIRIXAPI
spl_clib_reg(vm, "time_mkgm", handler_timegm, 0);
#endif
return;
}
void SPL_ABI(spl_mod_time_done)(struct spl_vm *vm UNUSED, struct spl_module *mod UNUSED)
{
return;
}
|