/*
// Full copyright information is available in the file ../doc/CREDITS
*/
#include "defs.h"
#include <time.h>
#include <string.h>
#ifdef __UNIX__
#include <sys/time.h> /* for mtime() */
#endif
#include "operators.h"
#include "execute.h"
#include "util.h"
#include "opcodes.h"
void func_anticipate_assignment(void) {
Int opcode, ind;
Long id;
cData *dp, d;
Frame *caller_frame = cur_frame->caller_frame;
Int pc;
if (!func_init_0())
return;
if (!caller_frame) {
push_int(1);
return;
}
pc=caller_frame->pc;
/* Most of this is from anticipate_assignment() */
/* skip error handling */
while ((opcode = caller_frame->opcodes[pc]) == CRITICAL_END)
pc++;
switch (opcode) {
case SET_LOCAL:
/* Zero out local variable value. */
dp = &stack[caller_frame->var_start +
caller_frame->opcodes[pc + 1]];
data_discard(dp);
dp->type = INTEGER;
dp->u.val = 0;
break;
case SET_OBJ_VAR:
/* Zero out the object variable, if it exists. */
ind = caller_frame->opcodes[pc + 1];
id = object_get_ident(caller_frame->method->object, ind);
d.type = INTEGER;
d.u.val = 0;
object_assign_var(caller_frame->object, caller_frame->method->object,
id, &d);
break;
}
push_int(1);
return;
}
void func_time(void) {
/* Take no arguments. */
if (!func_init_0())
return;
push_int(time(NULL));
}
void func_localtime(void) {
struct tm * tms;
cData * d;
cList * l;
time_t t;
cData *args;
Int nargs;
if (!func_init_0_or_1(&args, &nargs, INTEGER))
return;
if (nargs) {
t = (time_t) args[0].u.val;
pop(1);
} else
time(&t);
tms = localtime(&t);
l = list_new(11);
d = list_empty_spaces(l, 11);
/* Add one to certain elements to make them 1-x instead of 0-x */
d[0].type=INTEGER;
d[0].u.val = (cNum) t;
d[1].type=INTEGER;
d[1].u.val = tms->tm_sec;
d[2].type=INTEGER;
d[2].u.val = tms->tm_min;
d[3].type=INTEGER;
d[3].u.val = tms->tm_hour;
d[4].type=INTEGER;
d[4].u.val = tms->tm_mday;
d[5].type=INTEGER;
d[5].u.val = tms->tm_mon + 1;
d[6].type=INTEGER;
d[6].u.val = tms->tm_year;
d[7].type=INTEGER;
d[7].u.val = tms->tm_wday + 1;
d[8].type=INTEGER;
d[8].u.val = tms->tm_yday + 1;
d[9].type=INTEGER;
d[9].u.val = tms->tm_isdst;
d[10].type = STRING;
d[10].u.str= string_dup(str_tzname);
push_list(l);
list_discard(l);
}
void func_mtime(void) {
#ifdef HAVE_GETTIMEOFDAY
struct timeval tp;
#endif
if (!func_init_0())
return;
#ifdef HAVE_GETTIMEOFDAY
/* usec is microseconds */
gettimeofday(&tp, NULL);
push_int((cNum) tp.tv_usec);
#else
push_int(-1);
#endif
}
void func_ctime(void) {
cData *args;
Int num_args;
time_t tval;
char *timestr;
cStr *str;
/* Take an optional integer argument. */
if (!func_init_0_or_1(&args, &num_args, INTEGER))
return;
tval = (num_args) ? args[0].u.val : time(NULL);
timestr = ctime(&tval);
str = string_from_chars(timestr, 24);
pop(num_args);
push_string(str);
string_discard(str);
}
void func_bind_function(void) {
cData * args;
Int opcode;
/* accept a symbol and objnum */
if (!func_init_2(&args, SYMBOL, OBJNUM))
return;
opcode = find_function(ident_name(args[0].u.symbol));
if (opcode == -1) {
cthrow(perm_id, "Attempt to bind function which does not exist.");
return;
}
op_table[opcode].binding = args[1].u.objnum;
pop(2);
push_int(1);
}
void func_unbind_function(void) {
cData *args;
Int opcode;
/* accept a symbol */
if (!func_init_1(&args, SYMBOL))
return;
opcode = find_function(ident_name(args[0].u.symbol));
if (opcode == -1) {
cthrow(perm_id, "Attempt to unbind function which does not exist.");
return;
}
op_table[opcode].binding = INV_OBJNUM;
pop(1);
push_int(1);
}
#ifdef DRIVER_DEBUG
void func_debug_callers(void) {
cData *args;
if (!func_init_1(&args, INTEGER))
return;
if (args[0].u.val == 0)
clear_debug();
else if (args[0].u.val == 2)
start_full_debug();
else
start_debug();
}
void func_call_trace(void) {
if (!func_init_0())
return;
check_stack(1);
get_debug(&stack[stack_pos++]);
}
#endif