cb22561995-10-11Fredrik Hübinette (Hubbe) /*\
06983f1996-09-22Fredrik Hübinette (Hubbe) ||| This file a part of Pike, and is copyright by Fredrik Hubinette ||| Pike is distributed as GPL (General Public License)
cb22561995-10-11Fredrik Hübinette (Hubbe) ||| See the files COPYING and DISCLAIMER for more information. \*/
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "global.h"
4102d01998-03-12Henrik Grubbström (Grubba) RCSID("$Id: builtin_functions.c,v 1.63 1998/03/12 13:34:28 grubba Exp $");
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "interpret.h" #include "svalue.h"
bb55f81997-03-16Fredrik Hübinette (Hubbe) #include "pike_macros.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "object.h" #include "program.h" #include "array.h" #include "error.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "constants.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "mapping.h" #include "stralloc.h" #include "lex.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "multiset.h" #include "pike_types.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "rusage.h" #include "operators.h" #include "fsort.h" #include "callback.h"
624d091996-02-24Fredrik Hübinette (Hubbe) #include "gc.h"
ed70b71996-06-09Fredrik Hübinette (Hubbe) #include "backend.h" #include "main.h"
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) #include "pike_memory.h"
07513e1996-10-04Fredrik Hübinette (Hubbe) #include "threads.h"
3beb891996-06-21Fredrik Hübinette (Hubbe) #include "time_stuff.h"
6023ae1997-01-18Fredrik Hübinette (Hubbe) #include "version.h"
aac0151997-01-26Fredrik Hübinette (Hubbe) #include "encode.h"
3beb891996-06-21Fredrik Hübinette (Hubbe) #include <math.h>
38bddc1996-08-12Fredrik Hübinette (Hubbe) #include <ctype.h>
32a9581997-01-31Fredrik Hübinette (Hubbe) #include "module_support.h"
9c6f7d1997-04-15Fredrik Hübinette (Hubbe) #include "module.h" #include "opcodes.h"
fc33451997-10-02Fredrik Hübinette (Hubbe) #include "cyclic.h"
6930181996-02-25Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifdef HAVE_CRYPT_H #include <crypt.h> #endif
38bddc1996-08-12Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe) void f_equal(INT32 args) { int i; if(args < 2) error("Too few arguments to equal.\n"); i=is_equal(sp-2,sp-1); pop_n_elems(args); push_int(i); } void f_aggregate(INT32 args) { struct array *a; #ifdef DEBUG if(args < 0) fatal("Negative args to f_aggregate()\n"); #endif
99946c1996-02-17Fredrik Hübinette (Hubbe)  a=aggregate_array(args);
5267b71995-08-09Fredrik Hübinette (Hubbe)  push_array(a); /* beware, macro */ } void f_trace(INT32 args) { extern int t_flag;
32a9581997-01-31Fredrik Hübinette (Hubbe)  int old_t_flag=t_flag; get_all_args("trace",args,"%i",&t_flag); pop_n_elems(args); push_int(old_t_flag);
5267b71995-08-09Fredrik Hübinette (Hubbe) } void f_hash(INT32 args) { INT32 i; if(!args) error("Too few arguments to hash()\n"); if(sp[-args].type != T_STRING) error("Bad argument 1 to hash()\n"); i=hashstr((unsigned char *)sp[-args].u.string->str,100); if(args > 1) { if(sp[1-args].type != T_INT) error("Bad argument 2 to hash()\n"); if(!sp[1-args].u.integer) error("Modulo by zero in hash()\n"); i%=(unsigned INT32)sp[1-args].u.integer; } pop_n_elems(args); push_int(i); } void f_copy_value(INT32 args) { if(!args) error("Too few arguments to copy_value()\n"); pop_n_elems(args-1); copy_svalues_recursively_no_free(sp,sp-1,1,0); free_svalue(sp-1); sp[-1]=sp[0]; } void f_ctime(INT32 args) {
05a6f11998-01-29Henrik Grubbström (Grubba)  time_t i;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!args) error("Too few arguments to ctime()\n"); if(sp[-args].type != T_INT) error("Bad argument 1 to ctime()\n");
05a6f11998-01-29Henrik Grubbström (Grubba)  i=(time_t)sp[-args].u.integer;
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_n_elems(args);
05a6f11998-01-29Henrik Grubbström (Grubba)  push_string(make_shared_string(ctime(&i)));
5267b71995-08-09Fredrik Hübinette (Hubbe) } void f_lower_case(INT32 args) { INT32 i;
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *ret;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!args) error("Too few arguments to lower_case()\n"); if(sp[-args].type != T_STRING) error("Bad argument 1 to lower_case()\n"); ret=begin_shared_string(sp[-args].u.string->len); MEMCPY(ret->str, sp[-args].u.string->str,sp[-args].u.string->len); for (i = sp[-args].u.string->len-1; i>=0; i--)
13cc841996-11-01Fredrik Hübinette (Hubbe)  if (isupper(EXTRACT_UCHAR( ret->str + i))) ret->str[i] = tolower(EXTRACT_UCHAR(ret->str+i));
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_n_elems(args); push_string(end_shared_string(ret)); } void f_upper_case(INT32 args) { INT32 i;
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *ret;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!args) error("Too few arguments to upper_case()\n"); if(sp[-args].type != T_STRING) error("Bad argument 1 to upper_case()\n"); ret=begin_shared_string(sp[-args].u.string->len); MEMCPY(ret->str, sp[-args].u.string->str,sp[-args].u.string->len); for (i = sp[-args].u.string->len-1; i>=0; i--)
13cc841996-11-01Fredrik Hübinette (Hubbe)  if (islower(EXTRACT_UCHAR(ret->str+i))) ret->str[i] = toupper(EXTRACT_UCHAR(ret->str+i));
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_n_elems(args); push_string(end_shared_string(ret)); } void f_random(INT32 args) { if(!args) error("Too few arguments to random()\n"); if(sp[-args].type != T_INT) error("Bad argument 1 to random()\n"); if(sp[-args].u.integer <= 0) { sp[-args].u.integer = 0; }else{ sp[-args].u.integer = my_rand() % sp[-args].u.integer; } pop_n_elems(args-1); }
cb22561995-10-11Fredrik Hübinette (Hubbe) void f_random_seed(INT32 args) { if(!args) error("Too few arguments to random_seed()\n"); if(sp[-args].type != T_INT) error("Bad argument 1 to random_seed()\n"); my_srand(sp[-args].u.integer);
f6f02d1995-10-16Fredrik Hübinette (Hubbe)  pop_n_elems(args);
cb22561995-10-11Fredrik Hübinette (Hubbe) }
5267b71995-08-09Fredrik Hübinette (Hubbe) void f_query_num_arg(INT32 args) { pop_n_elems(args);
cb22561995-10-11Fredrik Hübinette (Hubbe)  push_int(fp ? fp->args : 0);
5267b71995-08-09Fredrik Hübinette (Hubbe) } void f_search(INT32 args) { INT32 start; if(args < 2) error("Too few arguments to search().\n"); switch(sp[-args].type) { case T_STRING: { char *ptr; INT32 len; if(sp[1-args].type != T_STRING) error("Bad argument 2 to search()\n"); start=0; if(args > 2) { if(sp[2-args].type!=T_INT) error("Bad argument 3 to search()\n"); start=sp[2-args].u.integer; } len=sp[-args].u.string->len - start;
3beb891996-06-21Fredrik Hübinette (Hubbe)  if(len>0 && (ptr=my_memmem(sp[1-args].u.string->str, sp[1-args].u.string->len, sp[-args].u.string->str+start, len)))
5267b71995-08-09Fredrik Hübinette (Hubbe)  { start=ptr-sp[-args].u.string->str; }else{ start=-1; } pop_n_elems(args); push_int(start); break; } case T_ARRAY: start=0; if(args > 2) { if(sp[2-args].type!=T_INT) error("Bad argument 3 to search()\n"); start=sp[2-args].u.integer; } start=array_search(sp[-args].u.array,sp+1-args,start); pop_n_elems(args); push_int(start); break; case T_MAPPING: if(args > 2) mapping_search_no_free(sp,sp[-args].u.mapping,sp+1-args,sp+2-args); else mapping_search_no_free(sp,sp[-args].u.mapping,sp+1-args,0); free_svalue(sp-args); sp[-args]=*sp; pop_n_elems(args-1); return; default: error("Bad argument 2 to search()\n"); } } void f_call_function(INT32 args) {
3beb891996-06-21Fredrik Hübinette (Hubbe)  INT32 expected_stack=sp-args+2-evaluator_stack;
5267b71995-08-09Fredrik Hübinette (Hubbe)  strict_apply_svalue(sp-args, args - 1);
3beb891996-06-21Fredrik Hübinette (Hubbe)  if(sp < expected_stack + evaluator_stack)
8b63781996-04-11Fredrik Hübinette (Hubbe)  { #ifdef DEBUG
3beb891996-06-21Fredrik Hübinette (Hubbe)  if(sp+1 != expected_stack + evaluator_stack) fatal("Stack underflow!\n");
8b63781996-04-11Fredrik Hübinette (Hubbe) #endif pop_stack(); push_int(0); }else{ free_svalue(sp-2); sp[-2]=sp[-1]; sp--; }
5267b71995-08-09Fredrik Hübinette (Hubbe) } void f_backtrace(INT32 args) { INT32 frames;
0bd5a41997-03-10Fredrik Hübinette (Hubbe)  struct frame *f,*of;
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct array *a,*i; frames=0; if(args) pop_n_elems(args); for(f=fp;f;f=f->parent_frame) frames++; sp->type=T_ARRAY;
99946c1996-02-17Fredrik Hübinette (Hubbe)  sp->u.array=a=allocate_array_no_init(frames,0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  sp++;
0bd5a41997-03-10Fredrik Hübinette (Hubbe)  of=0; for(f=fp;f;f=(of=f)->parent_frame)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { char *program_name; frames--;
c647321997-10-21Fredrik Hübinette (Hubbe)  if(f->current_object && f->context.prog)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
0bd5a41997-03-10Fredrik Hübinette (Hubbe)  INT32 args; args=f->num_args; args=MINIMUM(f->num_args, sp - f->locals); if(of) args=MINIMUM(f->num_args, of->locals - f->locals); args=MAXIMUM(args,0); ITEM(a)[frames].u.array=i=allocate_array_no_init(3+args,0);
99946c1996-02-17Fredrik Hübinette (Hubbe)  ITEM(a)[frames].type=T_ARRAY;
bb55f81997-03-16Fredrik Hübinette (Hubbe)  assign_svalues_no_free(ITEM(i)+3, f->locals, args, BIT_MIXED);
c647321997-10-21Fredrik Hübinette (Hubbe)  if(f->current_object->prog) { ITEM(i)[2].type=T_FUNCTION; ITEM(i)[2].subtype=f->fun; ITEM(i)[2].u.object=f->current_object; f->current_object->refs++; }else{ ITEM(i)[2].type=T_INT; ITEM(i)[2].subtype=NUMBER_DESTRUCTED; ITEM(i)[2].u.integer=0; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(f->pc) { program_name=get_line(f->pc, f->context.prog, & ITEM(i)[1].u.integer); ITEM(i)[1].subtype=NUMBER_NUMBER; ITEM(i)[1].type=T_INT; ITEM(i)[0].u.string=make_shared_string(program_name); #ifdef __CHECKER__ ITEM(i)[0].subtype=0; #endif ITEM(i)[0].type=T_STRING; }else{ ITEM(i)[1].u.integer=0; ITEM(i)[1].subtype=NUMBER_NUMBER; ITEM(i)[1].type=T_INT; ITEM(i)[0].u.integer=0; ITEM(i)[0].subtype=NUMBER_NUMBER; ITEM(i)[0].type=T_INT; } }else{
99946c1996-02-17Fredrik Hübinette (Hubbe)  ITEM(a)[frames].type=T_INT; ITEM(a)[frames].u.integer=0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
c5d9811996-05-16Fredrik Hübinette (Hubbe)  a->type_field = BIT_ARRAY | BIT_INT;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
06983f1996-09-22Fredrik Hübinette (Hubbe) void f_add_constant(INT32 args)
5267b71995-08-09Fredrik Hübinette (Hubbe) { if(args<1) error("Too few arguments to add_efun.\n"); if(sp[-args].type!=T_STRING) error("Bad argument 1 to add_efun.\n"); if(args>1) { low_add_efun(sp[-args].u.string, sp-args+1); }else{ low_add_efun(sp[-args].u.string, 0); } pop_n_elems(args); } void f_compile_file(INT32 args) { struct program *p; if(args<1) error("Too few arguments to compile_file.\n"); if(sp[-args].type!=T_STRING) error("Bad argument 1 to compile_file.\n"); p=compile_file(sp[-args].u.string); pop_n_elems(args); push_program(p); } static char *combine_path(char *cwd,char *file) { /* cwd is supposed to be combined already */ char *ret; register char *from,*to; char *my_cwd; my_cwd=0; if(file[0]=='/') { cwd="/"; file++; }
779b2c1995-11-20Fredrik Hübinette (Hubbe) #ifdef DEBUG if(!cwd) fatal("No cwd in combine_path!\n"); #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) 
e709751997-03-12Fredrik Hübinette (Hubbe)  if(!*cwd || cwd[strlen(cwd)-1]=='/')
5267b71995-08-09Fredrik Hübinette (Hubbe)  { ret=(char *)xalloc(strlen(cwd)+strlen(file)+1); strcpy(ret,cwd); strcat(ret,file); }else{ ret=(char *)xalloc(strlen(cwd)+strlen(file)+2); strcpy(ret,cwd); strcat(ret,"/"); strcat(ret,file); } from=to=ret;
b603cd1997-08-26Fredrik Hübinette (Hubbe)  /* Skip all leading "./" */ while(from[0]=='.' && from[1]=='/') from+=2;
5267b71995-08-09Fredrik Hübinette (Hubbe)  while(( *to = *from )) { if(*from == '/') {
9674d41997-11-13Fredrik Hübinette (Hubbe)  while(to>ret && to[-1]=='/') to--;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(from[1] == '.') { switch(from[2]) { case '.': if(from[3] == '/' || from[3] == 0) {
b603cd1997-08-26Fredrik Hübinette (Hubbe)  char *tmp=to; while(--tmp>=ret) if(*tmp == '/') break;
9674d41997-11-13Fredrik Hübinette (Hubbe)  tmp++;
b603cd1997-08-26Fredrik Hübinette (Hubbe) 
9674d41997-11-13Fredrik Hübinette (Hubbe)  if(tmp[0]=='.' && tmp[1]=='.' && (tmp[2]=='/' || !tmp[2]))
b603cd1997-08-26Fredrik Hübinette (Hubbe)  break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  from+=3;
b603cd1997-08-26Fredrik Hübinette (Hubbe)  to=tmp;
5267b71995-08-09Fredrik Hübinette (Hubbe)  continue; } break; case 0:
44c89f1997-08-27Henrik Grubbström (Grubba)  case '/':
5267b71995-08-09Fredrik Hübinette (Hubbe)  from+=2; continue; } } } from++; to++; }
9674d41997-11-13Fredrik Hübinette (Hubbe) 
2b5d7f1997-11-16Fredrik Hübinette (Hubbe)  if(*ret && from[-1]!='/' && to[-1]=='/') *--to=0;
9674d41997-11-13Fredrik Hübinette (Hubbe) 
b603cd1997-08-26Fredrik Hübinette (Hubbe)  if(!*ret) { if(*cwd=='/') { ret[0]='/'; ret[1]=0; }else{ ret[0]='.'; ret[1]=0; } }
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(my_cwd) free(my_cwd); return ret; } void f_combine_path(INT32 args) { char *path; if(args<2) error("Too few arguments to combine_path.\n"); if(sp[-args].type != T_STRING) error("Bad argument 1 to combine_path.\n"); if(sp[1-args].type != T_STRING) error("Bad argument 2 to combine_path.\n"); path=combine_path(sp[-args].u.string->str,sp[1-args].u.string->str); pop_n_elems(args); sp->u.string=make_shared_string(path); sp->type=T_STRING; sp++; free(path); } void f_function_object(INT32 args) { if(args < 1) error("Too few arguments to function_object()\n"); if(sp[-args].type != T_FUNCTION) error("Bad argument 1 to function_object.\n");
bdb5091996-09-25Fredrik Hübinette (Hubbe)  if(sp[-args].subtype == FUNCTION_BUILTIN)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { pop_n_elems(args); push_int(0); }else{ pop_n_elems(args-1); sp[-1].type=T_OBJECT; } } void f_function_name(INT32 args) {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *s;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(args < 1) error("Too few arguments to function_object()\n"); if(sp[-args].type != T_FUNCTION) error("Bad argument 1 to function_object.\n");
bdb5091996-09-25Fredrik Hübinette (Hubbe)  if(sp[-args].subtype == FUNCTION_BUILTIN)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { pop_n_elems(args); push_int(0); }else{ if(!sp[-args].u.object->prog) error("function_name on destructed object.\n"); copy_shared_string(s,ID_FROM_INT(sp[-args].u.object->prog, sp[-args].subtype)->name); pop_n_elems(args); sp->type=T_STRING; sp->u.string=s; sp++; } } void f_zero_type(INT32 args) { if(args < 1) error("Too few arguments to zero_type()\n"); if(sp[-args].type != T_INT)
3f6d8f1996-11-26Fredrik Hübinette (Hubbe)  { pop_n_elems(args); push_int(0);
8e9fdf1996-12-04Fredrik Hübinette (Hubbe)  } else if((sp[-args].type==T_OBJECT || sp[-args].type==T_FUNCTION) && !sp[-args].u.object->prog) { pop_n_elems(args); push_int(NUMBER_DESTRUCTED); } {
3f6d8f1996-11-26Fredrik Hübinette (Hubbe)  pop_n_elems(args-1); sp[-1].u.integer=sp[-1].subtype; sp[-1].subtype=NUMBER_NUMBER; }
5267b71995-08-09Fredrik Hübinette (Hubbe) }
06983f1996-09-22Fredrik Hübinette (Hubbe) void f_all_constants(INT32 args)
5267b71995-08-09Fredrik Hübinette (Hubbe) { pop_n_elems(args);
aac0151997-01-26Fredrik Hübinette (Hubbe)  push_mapping(get_builtin_constants()); sp[-1].u.mapping->refs++;
5267b71995-08-09Fredrik Hübinette (Hubbe) } void f_allocate(INT32 args) { INT32 size; if(args < 1) error("Too few arguments to allocate.\n"); if(sp[-args].type!=T_INT) error("Bad argument 1 to allocate.\n"); size=sp[-args].u.integer; if(size < 0) error("Allocate on negative number.\n"); pop_n_elems(args);
99946c1996-02-17Fredrik Hübinette (Hubbe)  push_array( allocate_array(size) );
5267b71995-08-09Fredrik Hübinette (Hubbe) } void f_rusage(INT32 args) {
99946c1996-02-17Fredrik Hübinette (Hubbe)  INT32 *rus,e;
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct array *v; pop_n_elems(args); rus=low_rusage(); if(!rus) error("System rusage information not available.\n");
99946c1996-02-17Fredrik Hübinette (Hubbe)  v=allocate_array_no_init(29,0); for(e=0;e<29;e++) { ITEM(v)[e].type=T_INT; ITEM(v)[e].subtype=NUMBER_NUMBER; ITEM(v)[e].u.integer=rus[e]; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  sp->u.array=v; sp->type=T_ARRAY; sp++; } void f_this_object(INT32 args) { pop_n_elems(args);
cb22561995-10-11Fredrik Hübinette (Hubbe)  if(fp) { sp->u.object=fp->current_object; sp->type=T_OBJECT; fp->current_object->refs++; sp++; }else{ push_int(0); }
5267b71995-08-09Fredrik Hübinette (Hubbe) } void f_throw(INT32 args) { if(args < 1) error("Too few arguments to throw()\n"); pop_n_elems(args-1); throw_value=sp[-1]; sp--; throw(); }
81b84e1996-12-03Fredrik Hübinette (Hubbe) static struct callback_list exit_callbacks;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
3beb891996-06-21Fredrik Hübinette (Hubbe) struct callback *add_exit_callback(callback_func call,
8f4f881996-06-20Fredrik Hübinette (Hubbe)  void *arg,
3beb891996-06-21Fredrik Hübinette (Hubbe)  callback_func free_func)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
8f4f881996-06-20Fredrik Hübinette (Hubbe)  return add_to_callback(&exit_callbacks, call, arg, free_func);
5267b71995-08-09Fredrik Hübinette (Hubbe) } void f_exit(INT32 args) {
dceabb1996-10-09Fredrik Hübinette (Hubbe)  ONERROR tmp;
cb22561995-10-11Fredrik Hübinette (Hubbe)  int i;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(args < 1) error("Too few arguments to exit.\n"); if(sp[-args].type != T_INT) error("Bad argument 1 to exit.\n");
e709751997-03-12Fredrik Hübinette (Hubbe)  i=sp[-args].u.integer;
47b1ee1997-02-28Fredrik Hübinette (Hubbe) #ifdef _REENTRANT
156fd51997-10-27Fredrik Hübinette (Hubbe)  if(num_threads>1) exit(i);
47b1ee1997-02-28Fredrik Hübinette (Hubbe) #endif
dceabb1996-10-09Fredrik Hübinette (Hubbe)  SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!");
12d3281996-09-26Fredrik Hübinette (Hubbe) 
52c0d31996-07-01Fredrik Hübinette (Hubbe)  call_callback(&exit_callbacks, (void *)0);
8f4f881996-06-20Fredrik Hübinette (Hubbe)  free_callback(&exit_callbacks);
cb22561995-10-11Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  exit_modules();
cb22561995-10-11Fredrik Hübinette (Hubbe) 
dceabb1996-10-09Fredrik Hübinette (Hubbe)  UNSET_ONERROR(tmp);
fe13331998-03-03Fredrik Hübinette (Hubbe)  #ifdef DEBUG_MALLOC {
edfa4b1998-03-03Henrik Grubbström (Grubba)  extern void cleanup_memhdrs(void);
fe13331998-03-03Fredrik Hübinette (Hubbe)  cleanup_memhdrs(); } #endif
cb22561995-10-11Fredrik Hübinette (Hubbe)  exit(i);
5267b71995-08-09Fredrik Hübinette (Hubbe) } void f_time(INT32 args) { pop_n_elems(args);
4102d01998-03-12Henrik Grubbström (Grubba)  if(!args) GETTIMEOFDAY(&current_time); push_int(current_time.tv_sec);
5267b71995-08-09Fredrik Hübinette (Hubbe) } void f_crypt(INT32 args) { char salt[2];
8beaf71996-04-13Fredrik Hübinette (Hubbe)  char *ret, *saltp;
5267b71995-08-09Fredrik Hübinette (Hubbe)  char *choise = "cbhisjKlm4k65p7qrJfLMNQOPxwzyAaBDFgnoWXYCZ0123tvdHueEGISRTUV89./"; if(args < 1) error("Too few arguments to crypt()\n"); if(sp[-args].type != T_STRING) error("Bad argument 1 to crypt()\n"); if(args>1) { if(sp[1-args].type != T_STRING || sp[1-args].u.string->len < 2)
0f6deb1997-08-06Fredrik Hübinette (Hubbe)  { pop_n_elems(args); push_int(0); return; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
8beaf71996-04-13Fredrik Hübinette (Hubbe)  saltp=sp[1-args].u.string->str;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } else {
99e2121996-09-23Fredrik Hübinette (Hubbe)  unsigned int foo; /* Sun CC want's this :( */ foo=my_rand(); salt[0] = choise[foo % (unsigned int) strlen(choise)]; foo=my_rand(); salt[1] = choise[foo % (unsigned int) strlen(choise)];
8beaf71996-04-13Fredrik Hübinette (Hubbe)  saltp=salt;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } #ifdef HAVE_CRYPT
8beaf71996-04-13Fredrik Hübinette (Hubbe)  ret = (char *)crypt(sp[-args].u.string->str, saltp);
5267b71995-08-09Fredrik Hübinette (Hubbe) #else #ifdef HAVE__CRYPT
8beaf71996-04-13Fredrik Hübinette (Hubbe)  ret = (char *)_crypt(sp[-args].u.string->str, saltp);
5267b71995-08-09Fredrik Hübinette (Hubbe) #else ret = sp[-args].u.string->str; #endif #endif if(args < 2) { pop_n_elems(args); push_string(make_shared_string(ret)); }else{ int i; i=!strcmp(ret,sp[1-args].u.string->str); pop_n_elems(args); push_int(i); } } void f_destruct(INT32 args) { struct object *o; if(args) { if(sp[-args].type != T_OBJECT) error("Bad arguments 1 to destruct()\n");
cb22561995-10-11Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  o=sp[-args].u.object;
cb22561995-10-11Fredrik Hübinette (Hubbe)  }else{ if(!fp) error("Destruct called without argument from callback function.\n"); o=fp->current_object;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } destruct(o);
cb22561995-10-11Fredrik Hübinette (Hubbe)  pop_n_elems(args);
5267b71995-08-09Fredrik Hübinette (Hubbe) } void f_indices(INT32 args) { INT32 size; struct array *a; if(args < 1) error("Too few arguments to indices()\n"); switch(sp[-args].type) { case T_STRING: size=sp[-args].u.string->len; goto qjump; case T_ARRAY: size=sp[-args].u.array->size; qjump:
99946c1996-02-17Fredrik Hübinette (Hubbe)  a=allocate_array_no_init(size,0);
5c8e891995-10-29Fredrik Hübinette (Hubbe)  while(--size>=0)
99946c1996-02-17Fredrik Hübinette (Hubbe)  { ITEM(a)[size].type=T_INT; ITEM(a)[size].subtype=NUMBER_NUMBER; ITEM(a)[size].u.integer=size; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; case T_MAPPING:
ed70b71996-06-09Fredrik Hübinette (Hubbe)  a=mapping_indices(sp[-args].u.mapping);
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
06983f1996-09-22Fredrik Hübinette (Hubbe)  case T_MULTISET: a=copy_array(sp[-args].u.multiset->ind);
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
6d4c4c1995-11-06Fredrik Hübinette (Hubbe)  case T_OBJECT: a=object_indices(sp[-args].u.object); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  default: error("Bad argument 1 to indices()\n"); return; /* make apcc happy */ } pop_n_elems(args); push_array(a); } void f_values(INT32 args) { INT32 size; struct array *a; if(args < 1)
ed70b71996-06-09Fredrik Hübinette (Hubbe)  error("Too few arguments to values()\n");
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(sp[-args].type) { case T_STRING: size=sp[-args].u.string->len;
99946c1996-02-17Fredrik Hübinette (Hubbe)  a=allocate_array_no_init(size,0);
5c8e891995-10-29Fredrik Hübinette (Hubbe)  while(--size>=0)
99946c1996-02-17Fredrik Hübinette (Hubbe)  { ITEM(a)[size].type=T_INT; ITEM(a)[size].subtype=NUMBER_NUMBER; ITEM(a)[size].u.integer=EXTRACT_UCHAR(sp[-args].u.string->str+size); }
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; case T_ARRAY: a=copy_array(sp[-args].u.array); break; case T_MAPPING:
ed70b71996-06-09Fredrik Hübinette (Hubbe)  a=mapping_values(sp[-args].u.mapping);
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
06983f1996-09-22Fredrik Hübinette (Hubbe)  case T_MULTISET: size=sp[-args].u.multiset->ind->size;
99946c1996-02-17Fredrik Hübinette (Hubbe)  a=allocate_array_no_init(size,0); while(--size>=0) { ITEM(a)[size].type=T_INT; ITEM(a)[size].subtype=NUMBER_NUMBER; ITEM(a)[size].u.integer=1; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
6d4c4c1995-11-06Fredrik Hübinette (Hubbe)  case T_OBJECT: a=object_values(sp[-args].u.object); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  default: error("Bad argument 1 to values()\n"); return; /* make apcc happy */ } pop_n_elems(args); push_array(a); } void f_next_object(INT32 args) { struct object *o; if(args < 1) { o=first_object; }else{ if(sp[-args].type != T_OBJECT) error("Bad argument 1 to next_object()\n"); o=sp[-args].u.object->next; } pop_n_elems(args); if(!o) { push_int(0); }else{ o->refs++; push_object(o); } } void f_object_program(INT32 args) { struct program *p; if(args < 1) error("Too few argumenets to object_program()\n");
b301041996-11-26Fredrik Hübinette (Hubbe)  if(sp[-args].type == T_OBJECT) p=sp[-args].u.object->prog; else p=0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_n_elems(args); if(!p) { push_int(0); }else{ p->refs++; push_program(p); } } void f_reverse(INT32 args) { if(args < 1) error("Too few arguments to reverse()\n"); switch(sp[-args].type) { case T_STRING: { INT32 e;
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *s;
5267b71995-08-09Fredrik Hübinette (Hubbe)  s=begin_shared_string(sp[-args].u.string->len); for(e=0;e<sp[-args].u.string->len;e++) s->str[e]=sp[-args].u.string->str[sp[-args].u.string->len-1-e]; s=end_shared_string(s); pop_n_elems(args); push_string(s); break; } case T_INT: { INT32 e; e=sp[-args].u.integer;
5c8e891995-10-29Fredrik Hübinette (Hubbe)  e=((e & 0x55555555UL)<<1) + ((e & 0xaaaaaaaaUL)>>1); e=((e & 0x33333333UL)<<2) + ((e & 0xccccccccUL)>>2); e=((e & 0x0f0f0f0fUL)<<4) + ((e & 0xf0f0f0f0UL)>>4); e=((e & 0x00ff00ffUL)<<8) + ((e & 0xff00ff00UL)>>8); e=((e & 0x0000ffffUL)<<16)+ ((e & 0xffff0000UL)>>16);
5267b71995-08-09Fredrik Hübinette (Hubbe)  sp[-args].u.integer=e; pop_n_elems(args-1); break; } case T_ARRAY: { struct array *a; a=reverse_array(sp[-args].u.array); pop_n_elems(args); push_array(a); break; } default: error("Bad argument 1 to reverse()\n"); } } struct tupel {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *ind,*val;
5267b71995-08-09Fredrik Hübinette (Hubbe) }; static int replace_sortfun(void *a,void *b) { return my_quick_strcmp( ((struct tupel *)a)->ind, ((struct tupel *)b)->ind); }
06983f1996-09-22Fredrik Hübinette (Hubbe) static struct pike_string * replace_many(struct pike_string *str,
3beb891996-06-21Fredrik Hübinette (Hubbe)  struct array *from, struct array *to)
5267b71995-08-09Fredrik Hübinette (Hubbe) { char *s; INT32 length,e; struct tupel *v; int set_start[256]; int set_end[256]; if(from->size != to->size) error("Replace must have equal-sized from and to arrays.\n"); if(!from->size) { reference_shared_string(str); return str; } v=(struct tupel *)xalloc(sizeof(struct tupel)*from->size);
99946c1996-02-17Fredrik Hübinette (Hubbe)  for(e=0;e<from->size;e++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
99946c1996-02-17Fredrik Hübinette (Hubbe)  if(ITEM(from)[e].type != T_STRING) error("Replace: from array not string *\n"); v[e].ind=ITEM(from)[e].u.string;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
99946c1996-02-17Fredrik Hübinette (Hubbe)  for(e=0;e<to->size;e++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
99946c1996-02-17Fredrik Hübinette (Hubbe)  if(ITEM(to)[e].type != T_STRING) error("Replace: to array not string *\n"); v[e].val=ITEM(to)[e].u.string;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } fsort((char *)v,from->size,sizeof(struct tupel),(fsortfun)replace_sortfun); for(e=0;e<256;e++) set_end[e]=set_start[e]=0; for(e=0;e<from->size;e++) { set_start[EXTRACT_UCHAR(v[from->size-1-e].ind->str)]=from->size-e-1; set_end[EXTRACT_UCHAR(v[e].ind->str)]=e+1; } init_buf(); length=str->len; s=str->str; for(;length > 0;) { INT32 a,b,c; if((b=set_end[EXTRACT_UCHAR(s)])) { a=set_start[EXTRACT_UCHAR(s)]; while(a<b) { c=(a+b)/2; if(low_quick_binary_strcmp(v[c].ind->str,v[c].ind->len,s,length) <=0) { if(a==c) break; a=c; }else{ b=c; } }
779b2c1995-11-20Fredrik Hübinette (Hubbe)  if(a<from->size &&
afa3651996-02-10Fredrik Hübinette (Hubbe)  length >= v[a].ind->len && !low_quick_binary_strcmp(v[a].ind->str,v[a].ind->len, s,v[a].ind->len))
5267b71995-08-09Fredrik Hübinette (Hubbe)  { c=v[a].ind->len; if(!c) c=1; s+=c; length-=c; my_binary_strcat(v[a].val->str,v[a].val->len); continue; } } my_putchar(*s); s++; length--; } free((char *)v); return free_buf(); } void f_replace(INT32 args) { if(args < 3) error("Too few arguments to replace()\n"); switch(sp[-args].type) { case T_ARRAY: { array_replace(sp[-args].u.array,sp+1-args,sp+2-args); pop_n_elems(args-1); break; } case T_MAPPING: {
ed70b71996-06-09Fredrik Hübinette (Hubbe)  mapping_replace(sp[-args].u.mapping,sp+1-args,sp+2-args);
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_n_elems(args-1); break; } case T_STRING: {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *s;
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(sp[1-args].type) { default: error("Bad argument 2 to replace()\n"); case T_STRING: if(sp[2-args].type != T_STRING) error("Bad argument 3 to replace()\n"); s=string_replace(sp[-args].u.string, sp[1-args].u.string, sp[2-args].u.string); break; case T_ARRAY: if(sp[2-args].type != T_ARRAY) error("Bad argument 3 to replace()\n"); s=replace_many(sp[-args].u.string, sp[1-args].u.array, sp[2-args].u.array); } pop_n_elems(args); push_string(s); break; }
8b63781996-04-11Fredrik Hübinette (Hubbe)  default: error("Bad argument 1 to replace().\n");
5267b71995-08-09Fredrik Hübinette (Hubbe)  } } void f_compile_string(INT32 args) { struct program *p; if(args < 1) error("Too few arguments to compile_string()\n"); if(sp[-args].type != T_STRING) error("Bad argument 1 to compile_string()\n"); if(args < 2) { push_string(make_shared_string("-")); args++; } if(sp[1-args].type != T_STRING) error("Bad argument 2 to compile_string()\n"); p=compile_string(sp[-args].u.string,sp[1-args].u.string); pop_n_elems(args); push_program(p); } void f_mkmapping(INT32 args) { struct mapping *m;
3c197b1997-02-18Fredrik Hübinette (Hubbe)  struct array *a,*b; get_all_args("mkmapping",args,"%a%a",&a,&b); if(a->size != b->size) error("mkmapping called on arrays of different sizes\n");
5267b71995-08-09Fredrik Hübinette (Hubbe)  m=mkmapping(sp[-args].u.array, sp[1-args].u.array); pop_n_elems(args); push_mapping(m); } void f_objectp(INT32 args) { if(args<1) error("Too few arguments to objectp.\n"); if(sp[-args].type != T_OBJECT || !sp[-args].u.object->prog) { pop_n_elems(args); push_int(0); }else{ pop_n_elems(args); push_int(1); } } void f_functionp(INT32 args) { if(args<1) error("Too few arguments to functionp.\n"); if(sp[-args].type != T_FUNCTION ||
bdb5091996-09-25Fredrik Hübinette (Hubbe)  (sp[-args].subtype != FUNCTION_BUILTIN && !sp[-args].u.object->prog))
5267b71995-08-09Fredrik Hübinette (Hubbe)  { pop_n_elems(args); push_int(0); }else{ pop_n_elems(args); push_int(1); } }
cb22561995-10-11Fredrik Hübinette (Hubbe) void f_sleep(INT32 args) {
3beb891996-06-21Fredrik Hübinette (Hubbe)  struct timeval t1,t2,t3;
cb22561995-10-11Fredrik Hübinette (Hubbe)  INT32 a,b;
3beb891996-06-21Fredrik Hübinette (Hubbe)  if(!args) error("Too few arguments to sleep.\n"); GETTIMEOFDAY(&t1); switch(sp[-args].type) { case T_INT: t2.tv_sec=sp[-args].u.integer; t2.tv_usec=0; break; case T_FLOAT: { FLOAT_TYPE f; f=sp[-args].u.float_number; t2.tv_sec=floor(f); t2.tv_usec=(long)(1000000.0*(f-floor(f))); break; } default:
cb22561995-10-11Fredrik Hübinette (Hubbe)  error("Bad argument 1 to sleep.\n");
3beb891996-06-21Fredrik Hübinette (Hubbe)  }
52c0d31996-07-01Fredrik Hübinette (Hubbe)  my_add_timeval(&t1, &t2);
cb22561995-10-11Fredrik Hübinette (Hubbe)  pop_n_elems(args); while(1) {
3beb891996-06-21Fredrik Hübinette (Hubbe)  GETTIMEOFDAY(&t2);
52c0d31996-07-01Fredrik Hübinette (Hubbe)  if(my_timercmp(&t1, <= , &t2))
3beb891996-06-21Fredrik Hübinette (Hubbe)  break;
cb22561995-10-11Fredrik Hübinette (Hubbe) 
3beb891996-06-21Fredrik Hübinette (Hubbe)  t3=t1; my_subtract_timeval(&t3, &t2);
cb22561995-10-11Fredrik Hübinette (Hubbe) 
07513e1996-10-04Fredrik Hübinette (Hubbe)  THREADS_ALLOW();
3beb891996-06-21Fredrik Hübinette (Hubbe)  select(0,0,0,0,&t3);
07513e1996-10-04Fredrik Hübinette (Hubbe)  THREADS_DISALLOW();
06983f1996-09-22Fredrik Hübinette (Hubbe)  check_threads_etc();
cb22561995-10-11Fredrik Hübinette (Hubbe)  } }
624d091996-02-24Fredrik Hübinette (Hubbe) void f_gc(INT32 args) { INT32 tmp; pop_n_elems(args); tmp=num_objects; do_gc(); push_int(tmp - num_objects); }
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifdef TYPEP #undef TYPEP #endif #define TYPEP(ID,NAME,TYPE) \ void ID(INT32 args) \ { \ int t; \ if(args<1) error("Too few arguments to %s.\n",NAME); \ t=sp[-args].type == TYPE; \ pop_n_elems(args); \ push_int(t); \ } TYPEP(f_programp, "programp", T_PROGRAM) TYPEP(f_intp, "intpp", T_INT) TYPEP(f_mappingp, "mappingp", T_MAPPING) TYPEP(f_arrayp, "arrayp", T_ARRAY)
06983f1996-09-22Fredrik Hübinette (Hubbe) TYPEP(f_multisetp, "multisetp", T_MULTISET)
5267b71995-08-09Fredrik Hübinette (Hubbe) TYPEP(f_stringp, "stringp", T_STRING) TYPEP(f_floatp, "floatp", T_FLOAT)
ed70b71996-06-09Fredrik Hübinette (Hubbe) void f_sort(INT32 args) { INT32 e,*order;
bee4301997-02-24Fredrik Hübinette (Hubbe)  if(args < 1)
ed70b71996-06-09Fredrik Hübinette (Hubbe)  fatal("Too few arguments to sort().\n"); for(e=0;e<args;e++) { if(sp[e-args].type != T_ARRAY) error("Bad argument %ld to sort().\n",(long)(e+1)); if(sp[e-args].u.array->size != sp[-args].u.array->size) error("Argument %ld to sort() has wrong size.\n",(long)(e+1)); }
3beb891996-06-21Fredrik Hübinette (Hubbe)  if(args > 1) { order=get_alpha_order(sp[-args].u.array); for(e=0;e<args;e++) order_array(sp[e-args].u.array,order); free((char *)order); pop_n_elems(args-1); } else { sort_array_destructively(sp[-args].u.array); }
ed70b71996-06-09Fredrik Hübinette (Hubbe) } void f_rows(INT32 args) { INT32 e; struct array *a,*tmp; if(args < 2) error("Too few arguments to rows().\n"); if(sp[1-args].type!=T_ARRAY) error("Bad argument 1 to rows().\n"); tmp=sp[1-args].u.array; push_array(a=allocate_array(tmp->size)); for(e=0;e<a->size;e++) index_no_free(ITEM(a)+e, sp-args-1, ITEM(tmp)+e); a->refs++; pop_n_elems(args+1); push_array(a); } void f_column(INT32 args) { INT32 e; struct array *a,*tmp;
fc33451997-10-02Fredrik Hübinette (Hubbe)  DECLARE_CYCLIC();
ed70b71996-06-09Fredrik Hübinette (Hubbe)  if(args < 2) error("Too few arguments to column().\n"); if(sp[-args].type!=T_ARRAY) error("Bad argument 1 to column().\n"); tmp=sp[-args].u.array;
fc33451997-10-02Fredrik Hübinette (Hubbe)  if((a=(struct array *)BEGIN_CYCLIC(tmp,0))) { a->refs++; pop_n_elems(args); push_array(a); }else{ push_array(a=allocate_array(tmp->size)); SET_CYCLIC_RET(a);
ed70b71996-06-09Fredrik Hübinette (Hubbe) 
fc33451997-10-02Fredrik Hübinette (Hubbe)  for(e=0;e<a->size;e++) index_no_free(ITEM(a)+e, ITEM(tmp)+e, sp-args);
ed70b71996-06-09Fredrik Hübinette (Hubbe) 
fc33451997-10-02Fredrik Hübinette (Hubbe)  END_CYCLIC(); a->refs++; pop_n_elems(args+1); push_array(a); }
ed70b71996-06-09Fredrik Hübinette (Hubbe) } #ifdef DEBUG void f__verify_internals(INT32 args) { INT32 tmp; tmp=d_flag; d_flag=0x7fffffff; do_debug(); d_flag=tmp;
0381531996-09-25Fredrik Hübinette (Hubbe)  do_gc();
ed70b71996-06-09Fredrik Hübinette (Hubbe)  pop_n_elems(args); }
a03d951997-10-14Fredrik Hübinette (Hubbe) void f__debug(INT32 args) { INT32 i=d_flag; get_all_args("_debug",args,"%i",&d_flag); pop_n_elems(args); push_int(i); }
ed70b71996-06-09Fredrik Hübinette (Hubbe) #endif
3beb891996-06-21Fredrik Hübinette (Hubbe) #ifdef HAVE_LOCALTIME void f_localtime(INT32 args)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
3beb891996-06-21Fredrik Hübinette (Hubbe)  struct tm *tm; time_t t; if (args<1 || sp[-1].type!=T_INT) error("Illegal argument to localtime");
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) 
3beb891996-06-21Fredrik Hübinette (Hubbe)  t=sp[-1].u.integer; tm=localtime(&t); pop_n_elems(args);
ed70b71996-06-09Fredrik Hübinette (Hubbe) 
3beb891996-06-21Fredrik Hübinette (Hubbe)  push_string(make_shared_string("sec")); push_int(tm->tm_sec); push_string(make_shared_string("min")); push_int(tm->tm_min); push_string(make_shared_string("hour")); push_int(tm->tm_hour);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) 
3beb891996-06-21Fredrik Hübinette (Hubbe)  push_string(make_shared_string("mday")); push_int(tm->tm_mday); push_string(make_shared_string("mon")); push_int(tm->tm_mon); push_string(make_shared_string("year")); push_int(tm->tm_year); push_string(make_shared_string("wday")); push_int(tm->tm_wday); push_string(make_shared_string("yday")); push_int(tm->tm_yday); push_string(make_shared_string("isdst")); push_int(tm->tm_isdst); #ifdef HAVE_EXTERNAL_TIMEZONE push_string(make_shared_string("timezone")); push_int(timezone); f_aggregate_mapping(20); #else #ifdef STRUCT_TM_HAS_GMTOFF push_string(make_shared_string("timezone")); push_int(tm->tm_gmtoff); f_aggregate_mapping(20); #else f_aggregate_mapping(18); #endif
c5d9811996-05-16Fredrik Hübinette (Hubbe) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) }
3beb891996-06-21Fredrik Hübinette (Hubbe) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b5d2dc1997-01-27Fredrik Hübinette (Hubbe) #ifdef HAVE_MKTIME static void f_mktime (INT32 args) { INT32 sec, min, hour, mday, mon, year, isdst, tz; struct tm date; struct svalue s; struct svalue * r; int retval; if (args<1) error ("Too few arguments to mktime().\n"); if(args == 1) { MEMSET(&date, 0, sizeof(date)); push_text("sec"); push_text("min"); push_text("hour"); push_text("mday"); push_text("mon"); push_text("year"); push_text("isdst"); push_text("timezone"); f_aggregate(8); f_rows(2); sp--; push_array_items(sp->u.array); args=8; }
32a9581997-01-31Fredrik Hübinette (Hubbe)  get_all_args("mktime",args, "%i%i%i%i%i%i%i",
b5d2dc1997-01-27Fredrik Hübinette (Hubbe)  &sec, &min, &hour, &mday, &mon, &year, &isdst, &tz); date.tm_sec=sec; date.tm_min=min; date.tm_hour=hour; date.tm_mday=mday; date.tm_mon=mon; date.tm_year=year; date.tm_isdst=isdst; #if STRUCT_TM_HAS_GMTOFF date.tm_gmtoff=tz; retval=mktime(&date); #else #ifdef HAVE_EXTERNAL_TIMEZONE if(sp[8-args].subtype == NUMBER_NUMBER) { int save_timezone=timezone; timezone=tz; retval=mktime(&date); timezone=save_timezone;
2befad1997-01-28Fredrik Hübinette (Hubbe)  }else{ retval=mktime(&date);
b5d2dc1997-01-27Fredrik Hübinette (Hubbe)  } #else retval=mktime(&date); #endif #endif if (retval == -1) error ("mktime: Cannot convert.\n"); pop_n_elems(args); push_int(retval); } #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) 
156fd51997-10-27Fredrik Hübinette (Hubbe) /* Check if the string s[0..len[ matches the glob m[0..mlen[ */
ed70b71996-06-09Fredrik Hübinette (Hubbe) static int does_match(char *s, int len, char *m, int mlen) { int i,j;
7a1bed1996-12-01Fredrik Hübinette (Hubbe)  for (i=j=0; i<mlen; i++)
ed70b71996-06-09Fredrik Hübinette (Hubbe)  { switch (m[i]) {
7a1bed1996-12-01Fredrik Hübinette (Hubbe)  case '?': if(j++>=len) return 0; break;
ed70b71996-06-09Fredrik Hübinette (Hubbe)  case '*': i++; if (i==mlen) return 1; /* slut */ for (;j<len;j++) if (does_match(s+j,len-j,m+i,mlen-i)) return 1; return 0; default:
7a1bed1996-12-01Fredrik Hübinette (Hubbe)  if(j>=len || m[i]!=s[j]) return 0; j++;
ed70b71996-06-09Fredrik Hübinette (Hubbe)  } }
7a1bed1996-12-01Fredrik Hübinette (Hubbe)  return j==len;
ed70b71996-06-09Fredrik Hübinette (Hubbe) } void f_glob(INT32 args) { INT32 i,matches; struct array *a;
3beb891996-06-21Fredrik Hübinette (Hubbe)  struct svalue *sval, tmp;
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *glob;
ed70b71996-06-09Fredrik Hübinette (Hubbe)  if(args < 2) error("Too few arguments to glob().\n"); if(args > 2) pop_n_elems(args-2);
3beb891996-06-21Fredrik Hübinette (Hubbe)  args=2;
ed70b71996-06-09Fredrik Hübinette (Hubbe) 
3beb891996-06-21Fredrik Hübinette (Hubbe)  if (sp[-args].type!=T_STRING)
ed70b71996-06-09Fredrik Hübinette (Hubbe)  error("Bad argument 2 to glob().\n"); glob=sp[-args].u.string;
3beb891996-06-21Fredrik Hübinette (Hubbe)  switch(sp[1-args].type)
ed70b71996-06-09Fredrik Hübinette (Hubbe)  { case T_STRING:
3beb891996-06-21Fredrik Hübinette (Hubbe)  i=does_match(sp[1-args].u.string->str, sp[1-args].u.string->len, glob->str, glob->len);
ed70b71996-06-09Fredrik Hübinette (Hubbe)  pop_n_elems(2); push_int(i); break; case T_ARRAY:
3beb891996-06-21Fredrik Hübinette (Hubbe)  a=sp[1-args].u.array; matches=0;
ed70b71996-06-09Fredrik Hübinette (Hubbe)  for(i=0;i<a->size;i++) {
5635941997-09-10Fredrik Hübinette (Hubbe)  if(ITEM(a)[i].type != T_STRING) error("Bad argument 2 to glob()\n");
3beb891996-06-21Fredrik Hübinette (Hubbe)  if(does_match(ITEM(a)[i].u.string->str, ITEM(a)[i].u.string->len, glob->str, glob->len))
ed70b71996-06-09Fredrik Hübinette (Hubbe)  { ITEM(a)[i].u.string->refs++; push_string(ITEM(a)[i].u.string); matches++; } } f_aggregate(matches); tmp=sp[-1]; sp--; pop_n_elems(2); sp[0]=tmp; sp++; break; default: error("Bad argument 2 to glob().\n"); } }
10be851998-02-24Mirar (Pontus Hagland) /**** diff ************************************************************/ static struct array* diff_compare_table(struct array *a,struct array *b) { struct array *res; struct mapping *map; struct svalue *pval; int i; map=allocate_mapping(256); push_mapping(map); /* in case of out of memory */ for (i=0; i<b->size; i++) { pval=low_mapping_lookup(map,b->item+i); if (!pval) { struct svalue val; val.type=T_ARRAY; val.u.array=low_allocate_array(1,1); val.u.array->item[0].type=T_INT; val.u.array->item[0].subtype=NUMBER_NUMBER; val.u.array->item[0].u.integer=i; mapping_insert(map,b->item+i,&val); free_svalue(&val); } else { pval->u.array=resize_array(pval->u.array,pval->u.array->size+1); pval->u.array->item[pval->u.array->size-1].type=T_INT; pval->u.array->item[pval->u.array->size-1].subtype=NUMBER_NUMBER; pval->u.array->item[pval->u.array->size-1].u.integer=i; } } res=low_allocate_array(a->size,0); for (i=0; i<a->size; i++) { pval=low_mapping_lookup(map,a->item+i); if (!pval) { res->item[i].type=T_ARRAY; (res->item[i].u.array=&empty_array)->refs++; } else { assign_svalue(res->item+i,pval); } } pop_stack(); return res; } struct diff_magic_link { int x; int refs; struct diff_magic_link *prev; }; struct diff_magic_link_pool { struct diff_magic_link *firstfree; struct diff_magic_link_pool *next; int firstfreenum; struct diff_magic_link dml[1]; }; #define DMLPOOLSIZE 16384 static int dmls=0; static INLINE struct diff_magic_link_pool* dml_new_pool(struct diff_magic_link_pool **pools) { struct diff_magic_link_pool *new; new=malloc(sizeof(struct diff_magic_link_pool)+ sizeof(struct diff_magic_link)*DMLPOOLSIZE); if (!new) return NULL; /* fail */ new->firstfreenum=0; new->firstfree=NULL; new->next=*pools; *pools=new; return *pools; } static INLINE struct diff_magic_link* dml_new(struct diff_magic_link_pool **pools) { struct diff_magic_link *new; struct diff_magic_link_pool *pool; dmls++; if ( *pools && (new=(*pools)->firstfree) ) { (*pools)->firstfree=new->prev; new->prev=NULL; return new; } pool=*pools; while (pool) { if (pool->firstfreenum<DMLPOOLSIZE) return pool->dml+(pool->firstfreenum++); pool=pool->next; } if ( (pool=dml_new_pool(pools)) ) { pool->firstfreenum=1; return pool->dml; } return NULL; } static INLINE void dml_free_pools(struct diff_magic_link_pool *pools) { struct diff_magic_link_pool *pool; while (pools) { pool=pools->next; free(pools); pools=pool; } } static INLINE void dml_delete(struct diff_magic_link_pool *pools, struct diff_magic_link *dml) { if (dml->prev && !--dml->prev->refs) dml_delete(pools,dml->prev); dmls--; dml->prev=pools->firstfree; pools->firstfree=dml; } static INLINE int diff_ponder_stack(int x, struct diff_magic_link **dml, int top) { int middle,a,b; a=0; b=top; while (b>a) { middle=(a+b)/2; if (dml[middle]->x<x) a=middle+1; else if (dml[middle]->x>x) b=middle; else return middle; } if (a<top && dml[a]->x<x) a++; return a; } static INLINE int diff_ponder_array(int x, struct svalue *arr, int top) { int middle,a,b; a=0; b=top; while (b>a) { middle=(a+b)/2; if (arr[middle].u.integer<x) a=middle+1; else if (arr[middle].u.integer>x) b=middle; else return middle; } if (a<top && arr[a].u.integer<x) a++; return a; } static struct array* diff_longest_sequence(struct array *cmptbl) { int i,j,top=0,lsize=0; struct array *a; struct diff_magic_link_pool *pools=NULL; struct diff_magic_link *dml; struct diff_magic_link **stack; stack=malloc(sizeof(struct diff_magic_link*)*cmptbl->size); if (!stack) error("out of memory\n"); for (i=0; i<cmptbl->size; i++) { struct svalue *inner=cmptbl->item[i].u.array->item; for (j=cmptbl->item[i].u.array->size; j--;) { int x=inner[j].u.integer; int pos; if (top && x<=stack[top-1]->x) pos=diff_ponder_stack(x,stack,top); else pos=top; if (pos && j) { if (stack[pos-1]->x+1 < inner[j].u.integer) { j=diff_ponder_array(stack[pos-1]->x+1,inner,j); x=inner[j].u.integer; } } else { j=0; x=inner->u.integer; } if (pos==top) { if (! (dml=dml_new(&pools)) ) { dml_free_pools(pools); free(stack); error("out of memory\n"); } dml->x=x; dml->refs=1; if (pos) (dml->prev=stack[pos-1])->refs++; else dml->prev=NULL; top++; stack[pos]=dml; }
edfa4b1998-03-03Henrik Grubbström (Grubba)  else if (stack[pos]->x!=x) {
10be851998-02-24Mirar (Pontus Hagland)  if (pos && stack[pos]->refs==1 && stack[pos-1]==stack[pos]->prev) { stack[pos]->x=x; } else { if (! (dml=dml_new(&pools)) ) { dml_free_pools(pools); free(stack); error("out of memory\n"); } dml->x=x; dml->refs=1; if (pos) (dml->prev=stack[pos-1])->refs++; else dml->prev=NULL; if (!--stack[pos]->refs) dml_delete(pools,stack[pos]); stack[pos]=dml; }
edfa4b1998-03-03Henrik Grubbström (Grubba)  }
10be851998-02-24Mirar (Pontus Hagland)  } } /* FIXME(?) memory unfreed upon error here */ a=low_allocate_array(top,0); if (top) { dml=stack[top-1]; while (dml) { a->item[--top].u.integer=dml->x; dml=dml->prev; } } free(stack); dml_free_pools(pools); return a; } static struct array* diff_build(struct array *a, struct array *b, struct array *seq) { struct array *ad,*bd; int bi,ai,lbi,lai,i,eqstart; b->refs++; a->refs++; /* protect from getting optimized... */ /* FIXME(?) memory unfreed upon error here (and later) */ ad=low_allocate_array(0,32); bd=low_allocate_array(0,32); eqstart=0; lbi=bi=ai=-1; for (i=0; i<seq->size; i++) { bi=seq->item[i].u.integer; if (bi!=lbi+1 || !is_equal(a->item+ai+1,b->item+bi)) { /* insert the equality */ if (lbi>=eqstart) { struct array *eq; eq=slice_array(b,eqstart,lbi+1); push_array(eq); sp--; ad=resize_array(ad,ad->size+1); bd=resize_array(bd,bd->size+1); sp->u.refs[0]++; ad->item[ad->size-1] = bd->item[bd->size-1] = *sp; } /* insert the difference */ lai=ai; ai=array_search(a,b->item+bi,ai+1)-1; bd=resize_array(bd,bd->size+1); ad=resize_array(ad,ad->size+1); push_array(slice_array(b,lbi+1,bi)); bd->item[bd->size-1]=*--sp; push_array(slice_array(a,lai+1,ai+1)); ad->item[ad->size-1]=*--sp; eqstart=bi; } ai++; lbi=bi; } if (lbi>=eqstart) { struct array *eq; eq=slice_array(b,eqstart,lbi+1); push_array(eq); sp--; ad=resize_array(ad,ad->size+1); bd=resize_array(bd,bd->size+1); sp->u.refs[0]++; ad->item[ad->size-1] = bd->item[bd->size-1] = *sp; } if (b->size>bi+1 || a->size>ai+1) { ad=resize_array(ad,ad->size+1); bd=resize_array(bd,bd->size+1); push_array(slice_array(b,lbi+1,b->size)); bd->item[bd->size-1]=*--sp; push_array(slice_array(a,ai+1,a->size)); ad->item[ad->size-1]=*--sp; } b->refs--; a->refs--; /* i know what i'm doing... */ push_array(ad); push_array(bd); f_aggregate(2); sp--; return sp->u.array; } void f_diff(INT32 args) { struct array *seq; struct array *cmptbl; struct array *diff; if (args<2) error("Too few arguments to diff().\n"); if (sp[-args].type!=T_ARRAY || sp[1-args].type!=T_ARRAY) error("Illegal arguments to diff().\n"); cmptbl=diff_compare_table(sp[-args].u.array,sp[1-args].u.array); push_array(cmptbl); seq=diff_longest_sequence(cmptbl); push_array(seq); diff=diff_build(sp[-2-args].u.array,sp[1-2-args].u.array,seq); pop_n_elems(2+args); push_array(diff); } void f_diff_compare_table(INT32 args) { struct array *cmptbl; if (args<2) error("Too few arguments to diff().\n"); if (sp[-args].type!=T_ARRAY || sp[1-args].type!=T_ARRAY) error("Illegal arguments to diff().\n"); cmptbl=diff_compare_table(sp[-args].u.array,sp[1-args].u.array); pop_n_elems(args); push_array(cmptbl); } void f_diff_longest_sequence(INT32 args) { struct array *seq; struct array *cmptbl; struct array *diff; if (args<2) error("Too few arguments to diff().\n"); if (sp[-args].type!=T_ARRAY || sp[1-args].type!=T_ARRAY) error("Illegal arguments to diff().\n"); cmptbl=diff_compare_table(sp[-args].u.array,sp[1-args].u.array); push_array(cmptbl); seq=diff_longest_sequence(cmptbl); pop_n_elems(args+1); push_array(seq); } /**********************************************************************/
c3c7031996-12-04Fredrik Hübinette (Hubbe) static struct callback_list memory_usage_callback; struct callback *add_memory_usage_callback(callback_func call, void *arg, callback_func free_func) { return add_to_callback(&memory_usage_callback, call, arg, free_func); } void f__memory_usage(INT32 args) { INT32 num,size; struct svalue *ss; pop_n_elems(args); ss=sp; count_memory_in_mappings(&num, &size); push_text("num_mappings"); push_int(num); push_text("mapping_bytes"); push_int(size); count_memory_in_strings(&num, &size); push_text("num_strings"); push_int(num); push_text("string_bytes"); push_int(size); count_memory_in_arrays(&num, &size); push_text("num_arrays"); push_int(num); push_text("array_bytes"); push_int(size); count_memory_in_programs(&num,&size); push_text("num_programs"); push_int(num); push_text("program_bytes"); push_int(size); count_memory_in_multisets(&num, &size); push_text("num_multisets"); push_int(num); push_text("multiset_bytes"); push_int(size); count_memory_in_objects(&num, &size); push_text("num_objects"); push_int(num);
4d58591996-12-04Fredrik Hübinette (Hubbe)  push_text("object_bytes");
c3c7031996-12-04Fredrik Hübinette (Hubbe)  push_int(size); count_memory_in_callbacks(&num, &size); push_text("num_callbacks"); push_int(num); push_text("callback_bytes"); push_int(size); count_memory_in_callables(&num, &size); push_text("num_callables"); push_int(num); push_text("callable_bytes"); push_int(size); call_callback(&memory_usage_callback, (void *)0); f_aggregate_mapping(sp-ss); }
8e9fdf1996-12-04Fredrik Hübinette (Hubbe) void f__next(INT32 args) { struct svalue tmp; if(!args) error("Too few arguments to _next()\n"); pop_n_elems(args-1); tmp=sp[-1]; switch(tmp.type) { case T_OBJECT: tmp.u.object=tmp.u.object->next; break; case T_ARRAY: tmp.u.array=tmp.u.array->next; break; case T_MAPPING: tmp.u.mapping=tmp.u.mapping->next; break; case T_MULTISET:tmp.u.multiset=tmp.u.multiset->next; break; case T_PROGRAM: tmp.u.program=tmp.u.program->next; break; case T_STRING: tmp.u.string=tmp.u.string->next; break; default: error("Bad argument 1 to _next()\n"); } if(tmp.u.refs) { assign_svalue(sp-1,&tmp); }else{ pop_stack(); push_int(0); } } void f__prev(INT32 args) { struct svalue tmp; if(!args) error("Too few arguments to _next()\n"); pop_n_elems(args-1); tmp=sp[-1]; switch(tmp.type) { case T_OBJECT: tmp.u.object=tmp.u.object->prev; break; case T_ARRAY: tmp.u.array=tmp.u.array->prev; break; case T_MAPPING: tmp.u.mapping=tmp.u.mapping->prev; break; case T_MULTISET:tmp.u.multiset=tmp.u.multiset->prev; break; case T_PROGRAM: tmp.u.program=tmp.u.program->prev; break; default: error("Bad argument 1 to _prev()\n"); } if(tmp.u.refs) { assign_svalue(sp-1,&tmp); }else{ pop_stack(); push_int(0); } }
6023ae1997-01-18Fredrik Hübinette (Hubbe) void f__refs(INT32 args) { INT32 i; if(!args) error("Too few arguments to _refs()\n"); if(sp[-args].type > MAX_REF_TYPE) error("Bad argument 1 to _refs()\n"); i=sp[-args].u.refs[0]; pop_n_elems(args); push_int(i); } void f_replace_master(INT32 args) { if(!args) error("Too few arguments to replace_master()\n"); if(sp[-args].type != T_OBJECT) error("Bad argument 1 to replace_master()\n"); if(!sp[-args].u.object->prog) error("replace_master() called with destructed object.\n"); free_object(master_object); master_object=sp[-args].u.object; master_object->refs++; free_program(master_program); master_program=master_object->prog; master_program->refs++; pop_n_elems(args); }
41e4341997-09-06Henrik Grubbström (Grubba) void f_master(INT32 args) { pop_n_elems(args); master_object->refs++; push_object(master_object); }
9548a81997-05-07Per Hedbor #ifdef HAVE_GETHRVTIME #include <sys/time.h> void f_gethrvtime(INT32 args) { pop_n_elems(args);
65d4ed1997-11-02Henrik Grubbström (Grubba)  push_int((INT32)(gethrvtime()/1000));
9548a81997-05-07Per Hedbor } void f_gethrtime(INT32 args) { pop_n_elems(args);
65d4ed1997-11-02Henrik Grubbström (Grubba)  push_int((INT32)(gethrtime()/1000));
9548a81997-05-07Per Hedbor }
0dbc6f1997-11-02Henrik Grubbström (Grubba) #endif /* HAVE_GETHRVTIME */
9548a81997-05-07Per Hedbor 
44c89f1997-08-27Henrik Grubbström (Grubba) #ifdef PROFILING static void f_get_prof_info(INT32 args) { struct program *prog; int num_functions; int i; if (!args) { error("get_profiling_info(): Too few arguments\n"); } if (sp[-args].type != T_PROGRAM) { error("get_profiling_info(): Bad argument 1\n"); } prog = sp[-args].u.program; prog->refs++; pop_n_elems(args); /* ({ num_clones, ([ "fun_name":({ num_calls }) ]) }) */ push_int(prog->num_clones);
1dfed21997-11-02Henrik Grubbström (Grubba)  for(num_functions=i=0; i<(int)prog->num_identifiers; i++) {
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  if (IDENTIFIER_IS_FUNCTION(prog->identifiers[i].identifier_flags)) {
44c89f1997-08-27Henrik Grubbström (Grubba)  num_functions++; prog->identifiers[i].name->refs++; push_string(prog->identifiers[i].name); push_int(prog->identifiers[i].num_calls); f_aggregate(1); } } f_aggregate_mapping(num_functions * 2); f_aggregate(2); } #endif /* PROFILING */
ef5b9e1997-10-07Fredrik Hübinette (Hubbe) void f_object_variablep(INT32 args) { struct object *o; struct pike_string *s; int ret; get_all_args("variablep",args,"%o%S",&o, &s); if(!o->prog) error("variablep() called on destructed object.\n"); ret=find_shared_string_identifier(s,o->prog); if(ret!=-1) { ret=IDENTIFIER_IS_VARIABLE(ID_FROM_INT(o->prog, ret)->identifier_flags); }else{ ret=0; } pop_n_elems(args); push_int(!!ret); }
be478c1997-08-30Henrik Grubbström (Grubba) void init_builtin_efuns(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
3beb891996-06-21Fredrik Hübinette (Hubbe)  init_operators();
9548a81997-05-07Per Hedbor  #ifdef HAVE_GETHRVTIME add_efun("gethrvtime",f_gethrvtime,"function(void:int)",OPT_EXTERNAL_DEPEND); add_efun("gethrtime", f_gethrtime,"function(void:int)", OPT_EXTERNAL_DEPEND); #endif
3beb891996-06-21Fredrik Hübinette (Hubbe) 
44c89f1997-08-27Henrik Grubbström (Grubba) #ifdef PROFILING add_efun("get_profiling_info", f_get_prof_info, "function(program:array)", OPT_EXTERNAL_DEPEND); #endif /* PROFILING */
591c0c1997-01-19Fredrik Hübinette (Hubbe)  add_efun("_refs",f__refs,"function(function|string|array|mapping|multiset|object|program:int)",OPT_EXTERNAL_DEPEND);
6023ae1997-01-18Fredrik Hübinette (Hubbe)  add_efun("replace_master",f_replace_master,"function(object:void)",OPT_SIDE_EFFECT);
8987841997-09-09Fredrik Hübinette (Hubbe)  add_efun("master",f_master,"function(:object)",OPT_EXTERNAL_DEPEND);
06983f1996-09-22Fredrik Hübinette (Hubbe)  add_efun("add_constant",f_add_constant,"function(string,void|mixed:void)",OPT_SIDE_EFFECT);
5267b71995-08-09Fredrik Hübinette (Hubbe)  add_efun("aggregate",f_aggregate,"function(mixed ...:mixed *)",OPT_TRY_OPTIMIZE);
06983f1996-09-22Fredrik Hübinette (Hubbe)  add_efun("aggregate_multiset",f_aggregate_multiset,"function(mixed ...:multiset)",OPT_TRY_OPTIMIZE);
5267b71995-08-09Fredrik Hübinette (Hubbe)  add_efun("aggregate_mapping",f_aggregate_mapping,"function(mixed ...:mapping)",OPT_TRY_OPTIMIZE);
06983f1996-09-22Fredrik Hübinette (Hubbe)  add_efun("all_constants",f_all_constants,"function(:mapping(string:mixed))",OPT_EXTERNAL_DEPEND);
5267b71995-08-09Fredrik Hübinette (Hubbe)  add_efun("allocate", f_allocate, "function(int, string|void:mixed *)", 0); add_efun("arrayp", f_arrayp, "function(mixed:int)",0);
3beb891996-06-21Fredrik Hübinette (Hubbe)  add_efun("backtrace",f_backtrace,"function(:array(array(function|int|string)))",OPT_EXTERNAL_DEPEND);
5267b71995-08-09Fredrik Hübinette (Hubbe)  add_efun("call_function",f_call_function,"function(mixed,mixed ...:mixed)",OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND);
d2c6081996-11-07Fredrik Hübinette (Hubbe) 
3beb891996-06-21Fredrik Hübinette (Hubbe)  add_efun("column",f_column,"function(array,mixed:array)",0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  add_efun("combine_path",f_combine_path,"function(string,string:string)",0); add_efun("compile_file",f_compile_file,"function(string:program)",OPT_EXTERNAL_DEPEND); add_efun("compile_string",f_compile_string,"function(string,string|void:program)",OPT_EXTERNAL_DEPEND); add_efun("copy_value",f_copy_value,"function(mixed:mixed)",0); add_efun("crypt",f_crypt,"function(string:string)|function(string,string:int)",OPT_EXTERNAL_DEPEND); add_efun("ctime",f_ctime,"function(int:string)",OPT_TRY_OPTIMIZE); add_efun("destruct",f_destruct,"function(object|void:void)",OPT_SIDE_EFFECT); add_efun("equal",f_equal,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE); add_efun("exit",f_exit,"function(int:void)",OPT_SIDE_EFFECT); add_efun("floatp", f_floatp, "function(mixed:int)",OPT_TRY_OPTIMIZE); add_efun("function_name",f_function_name,"function(function:string)",OPT_TRY_OPTIMIZE); add_efun("function_object",f_function_object,"function(function:object)",OPT_TRY_OPTIMIZE); add_efun("functionp", f_functionp, "function(mixed:int)",OPT_TRY_OPTIMIZE);
3beb891996-06-21Fredrik Hübinette (Hubbe)  add_efun("glob",f_glob,"function(string,string:int)|function(string,string*:array(string))",OPT_TRY_OPTIMIZE);
5267b71995-08-09Fredrik Hübinette (Hubbe)  add_efun("hash",f_hash,"function(string,int|void:int)",OPT_TRY_OPTIMIZE);
06983f1996-09-22Fredrik Hübinette (Hubbe)  add_efun("indices",f_indices,"function(string|array:int*)|function(mapping|multiset:mixed*)|function(object:string*)",0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  add_efun("intp", f_intp, "function(mixed:int)",OPT_TRY_OPTIMIZE);
06983f1996-09-22Fredrik Hübinette (Hubbe)  add_efun("multisetp", f_multisetp, "function(mixed:int)",OPT_TRY_OPTIMIZE);
5267b71995-08-09Fredrik Hübinette (Hubbe)  add_efun("lower_case",f_lower_case,"function(string:string)",OPT_TRY_OPTIMIZE); add_efun("m_delete",f_m_delete,"function(mapping,mixed:mapping)",0);
3beb891996-06-21Fredrik Hübinette (Hubbe)  add_efun("mappingp",f_mappingp,"function(mixed:int)",OPT_TRY_OPTIMIZE);
5267b71995-08-09Fredrik Hübinette (Hubbe)  add_efun("mkmapping",f_mkmapping,"function(mixed *,mixed *:mapping)",OPT_TRY_OPTIMIZE); add_efun("next_object",f_next_object,"function(void|object:object)",OPT_EXTERNAL_DEPEND);
8e9fdf1996-12-04Fredrik Hübinette (Hubbe)  add_efun("_next",f__next,"function(string:string)|function(object:object)|function(mapping:mapping)|function(multiset:multiset)|function(program:program)|function(array:array)",OPT_EXTERNAL_DEPEND); add_efun("_prev",f__prev,"function(object:object)|function(mapping:mapping)|function(multiset:multiset)|function(program:program)|function(array:array)",OPT_EXTERNAL_DEPEND);
1b601b1996-11-26Fredrik Hübinette (Hubbe)  add_efun("object_program",f_object_program,"function(mixed:program)",0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  add_efun("objectp", f_objectp, "function(mixed:int)",0); add_efun("programp",f_programp,"function(mixed:int)",0); add_efun("query_num_arg",f_query_num_arg,"function(:int)",OPT_EXTERNAL_DEPEND); add_efun("random",f_random,"function(int:int)",OPT_EXTERNAL_DEPEND);
cb22561995-10-11Fredrik Hübinette (Hubbe)  add_efun("random_seed",f_random_seed,"function(int:void)",OPT_SIDE_EFFECT);
5267b71995-08-09Fredrik Hübinette (Hubbe)  add_efun("replace",f_replace,"function(string,string,string:string)|function(string,string*,string*:string)|function(array,mixed,mixed:array)|function(mapping,mixed,mixed:array)",0); add_efun("reverse",f_reverse,"function(int:int)|function(string:string)|function(array:array)",0);
3beb891996-06-21Fredrik Hübinette (Hubbe)  add_efun("rows",f_rows,"function(mixed,array:array)",0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  add_efun("rusage", f_rusage, "function(:int *)",OPT_EXTERNAL_DEPEND); add_efun("search",f_search,"function(string,string,void|int:int)|function(array,mixed,void|int:int)|function(mapping,mixed:mixed)",0);
3beb891996-06-21Fredrik Hübinette (Hubbe)  add_efun("sleep", f_sleep, "function(float|int:void)",OPT_SIDE_EFFECT); add_efun("sort",f_sort,"function(array(mixed),array(mixed)...:array(mixed))",OPT_SIDE_EFFECT);
5267b71995-08-09Fredrik Hübinette (Hubbe)  add_efun("stringp", f_stringp, "function(mixed:int)",0); add_efun("this_object", f_this_object, "function(:object)",OPT_EXTERNAL_DEPEND);
e82b301997-01-29Fredrik Hübinette (Hubbe)  add_efun("throw",f_throw,"function(mixed:void)",OPT_SIDE_EFFECT);
5267b71995-08-09Fredrik Hübinette (Hubbe)  add_efun("time",f_time,"function(void|int:int)",OPT_EXTERNAL_DEPEND); add_efun("trace",f_trace,"function(int:int)",OPT_SIDE_EFFECT); add_efun("upper_case",f_upper_case,"function(string:string)",0);
06983f1996-09-22Fredrik Hübinette (Hubbe)  add_efun("values",f_values,"function(string|multiset:int*)|function(array|mapping|object:mixed*)",0);
1b601b1996-11-26Fredrik Hübinette (Hubbe)  add_efun("zero_type",f_zero_type,"function(mixed:int)",0);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
3beb891996-06-21Fredrik Hübinette (Hubbe) #ifdef HAVE_LOCALTIME add_efun("localtime",f_localtime,"function(int:mapping(string:int))",OPT_EXTERNAL_DEPEND);
ed70b71996-06-09Fredrik Hübinette (Hubbe) #endif
b5d2dc1997-01-27Fredrik Hübinette (Hubbe) #ifdef HAVE_MKTIME add_efun("mktime",f_mktime,"function(int,int,int,int,int,int,int,int:int)|function(object|mapping:int)",OPT_TRY_OPTIMIZE); #endif
3beb891996-06-21Fredrik Hübinette (Hubbe) #ifdef DEBUG add_efun("_verify_internals",f__verify_internals,"function(:void)",OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND);
a03d951997-10-14Fredrik Hübinette (Hubbe)  add_efun("_debug",f__debug,"function(int:int)",OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND);
ed70b71996-06-09Fredrik Hübinette (Hubbe) #endif
c3c7031996-12-04Fredrik Hübinette (Hubbe)  add_efun("_memory_usage",f__memory_usage,"function(:mapping(string:int))",OPT_EXTERNAL_DEPEND);
ed70b71996-06-09Fredrik Hübinette (Hubbe) 
3beb891996-06-21Fredrik Hübinette (Hubbe)  add_efun("gc",f_gc,"function(:int)",OPT_SIDE_EFFECT);
aac0151997-01-26Fredrik Hübinette (Hubbe)  add_efun("version", f_version, "function(:string)", OPT_TRY_OPTIMIZE); add_efun("encode_value", f_encode_value, "function(mixed:string)", OPT_TRY_OPTIMIZE); add_efun("decode_value", f_decode_value, "function(string:mixed)", OPT_TRY_OPTIMIZE);
ef5b9e1997-10-07Fredrik Hübinette (Hubbe)  add_efun("object_variablep", f_object_variablep, "function(object,string:int)", OPT_EXTERNAL_DEPEND);
10be851998-02-24Mirar (Pontus Hagland)  add_function("diff",f_diff,"function(array,array:array(array))",OPT_TRY_OPTIMIZE); add_function("diff_longest_sequence",f_diff_longest_sequence,"function(array,array:array(int))",OPT_TRY_OPTIMIZE); add_function("diff_compare_table",f_diff_compare_table,"function(array,array:array(array))",OPT_TRY_OPTIMIZE);
3beb891996-06-21Fredrik Hübinette (Hubbe) }
5267b71995-08-09Fredrik Hübinette (Hubbe)