/* // ColdMUD was created and is copyright 1993, 1994 by Greg Hudson // // ColdX is a derivitive work, and is copyright 1995 by the ColdX Project. // Full copyright information can be found in the file doc/CREDITS // // File: miscop.c // Version: 0.1-5 // Last Edited: 5 Aug 1995 // // --- // // Miscellaneous operations. */ /* #define _POSIX_SOURCE */ #include "config.h" #include <stdlib.h> #include <time.h> #include <sys/time.h> /* for mtime() */ #include "defs.h" #include "x.tab.h" #include "operator.h" #include "execute.h" #include "data.h" #include "util.h" #include "ident.h" #include "lookup.h" static void find_extreme(int which); void op_version(void) { List *version; Data *d; /* Take no arguments. */ if (!func_init_0()) return; /* Construct a list of the version numbers and push it. */ version = list_new(3); d = list_empty_spaces(version, 3); d[0].type = d[1].type = d[2].type = INTEGER; d[0].u.val = VERSION_MAJOR; d[1].u.val = VERSION_MINOR; d[2].u.val = VERSION_PATCH; push_list(version); list_discard(version); } void op_random(void) { Data *args; /* Take one integer argument. */ if (!func_init_1(&args, INTEGER)) return; /* Replace argument on stack with a random number. */ args[0].u.val = random_number(args[0].u.val) + 1; } void op_time(void) { /* Take no arguments. */ if (!func_init_0()) return; push_int(time(NULL)); } void op_localtime(void) { struct tm * tms; Data * d; List * l; time_t t; register int x; if (!func_init_0()) return; time(&t); tms = localtime(&t); #if defined(Solaris) || defined(IRIX) #define __LSIZE0__ 10 #define __LSIZE1__ 10 #else #define __LSIZE0__ 11 #define __LSIZE1__ 12 #endif l = list_new(__LSIZE0__); d = list_empty_spaces(l, __LSIZE0__); for (x=0; x < __LSIZE1__; x++) d[x].type = INTEGER; d[0].u.val = (int) t; d[1].u.val = tms->tm_sec; d[2].u.val = tms->tm_min; d[3].u.val = tms->tm_hour; d[4].u.val = tms->tm_mday; d[5].u.val = tms->tm_mon; d[6].u.val = tms->tm_year; d[7].u.val = tms->tm_wday; d[8].u.val = tms->tm_yday; d[9].u.val = tms->tm_isdst; #if !defined(Solaris) && !defined(IRIX) d[10].u.val = tms->tm_gmtoff; d[11].type = STRING; d[11].u.str = string_from_chars(tms->tm_zone, strlen(tms->tm_zone)); #endif push_list(l); list_discard(l); } /* May as well give it to them, the code is in the driver */ void op_timestamp(void) { String * str; char * s; /* Take no arguments. */ if (!func_init_0()) return; s = timestamp(NULL); str = string_from_chars(s, strlen(s)); push_string(str); string_discard(str); } void op_strftime(void) { char s[LINE]; char * fmt; Data * args; String * str; int nargs; time_t tt; struct tm * t; if (!func_init_1_or_2(&args, &nargs, STRING, INTEGER)) return; tt = ((nargs == 2) ? (time_t) args[1].u.val : time(NULL)); t = localtime(&tt); fmt = string_chars(args[0].u.str); /* some OS's are weird and do odd things when you end in % (accidentally or no) */ if (fmt[strlen(fmt)] == '%') fmt[strlen(fmt)] = NULL; if (strftime(s, LINE, fmt, t) == (size_t) 0) { cthrow(range_id, "Format results in a string longer than 80 characters."); return; } str = string_from_chars(s, strlen(s)); pop(nargs); push_string(str); string_discard(str); } void op_mtime(void) { struct timeval tp; /* Take no arguments. */ if (!func_init_0()) return; gettimeofday(&tp, NULL); /* usec is microseconds */ push_int((int) tp.tv_usec); } void op_ctime(void) { Data *args; int num_args; time_t tval; char *timestr; String *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); } /* which is 1 for max, -1 for min. */ static void find_extreme(int which) { int arg_start, num_args, i, type; Data *args, *extreme, d; arg_start = arg_starts[--arg_pos]; args = &stack[arg_start]; num_args = stack_pos - arg_start; if (!num_args) { cthrow(numargs_id, "Called with no arguments, requires at least one."); return; } type = args[0].type; if (type != INTEGER && type != STRING) { cthrow(type_id, "First argument (%D) not an integer or string.", &args[0]); return; } extreme = &args[0]; for (i = 1; i < num_args; i++) { if (args[i].type != type) { cthrow(type_id, "Arguments are not all of same type."); return; } if (data_cmp(&args[i], extreme) * which > 0) extreme = &args[i]; } /* Replace args[0] with extreme, and pop other arguments. */ data_dup(&d, extreme); data_discard(&args[0]); args[0] = d; pop(num_args - 1); } void op_max(void) { find_extreme(1); } void op_min(void) { find_extreme(-1); } void op_abs(void) { Data *args; if (!func_init_1(&args, INTEGER)) return; if (args[0].u.val < 0) args[0].u.val = -args[0].u.val; } void op_get_dbref(void) { Data *args; long dbref; if (!func_init_1(&args, SYMBOL)) return; if (!lookup_retrieve_name(args[0].u.symbol, &dbref)) { cthrow(namenf_id, "Cannot find object %I.", args[0].u.symbol); return; } pop(1); push_dbref(dbref); } void op_ticks_left(void) { if (!func_init_0()) return; push_int(cur_frame->ticks); }