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. \*/
b788cd1998-07-04Henrik Grubbström (Grubba) #include "global.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include <math.h> #include <ctype.h> #include "interpret.h" #include "svalue.h" #include "array.h" #include "stralloc.h" #include "mapping.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "multiset.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "opcodes.h" #include "object.h" #include "error.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "pike_types.h"
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) #include "pike_memory.h"
9c6f7d1997-04-15Fredrik Hübinette (Hubbe) #include "fd_control.h"
98f2b11998-02-19Fredrik Hübinette (Hubbe) #include "cyclic.h" #include "builtin_functions.h"
53842a1998-04-15Fredrik Hübinette (Hubbe) #include "module_support.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) 
db4a401998-10-09Fredrik Hübinette (Hubbe) RCSID("$Id: opcodes.c,v 1.30 1998/10/09 17:56:32 hubbe Exp $");
24ddc71998-03-28Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe) void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind) { INT32 i; switch(what->type) { case T_ARRAY: simple_array_index_no_free(to,what->u.array,ind); break; case T_MAPPING: mapping_index_no_free(to,what->u.mapping,ind); break; case T_OBJECT: object_index_no_free(to, what->u.object, ind); break;
06983f1996-09-22Fredrik Hübinette (Hubbe)  case T_MULTISET: i=multiset_member(what->u.multiset, ind);
5267b71995-08-09Fredrik Hübinette (Hubbe)  to->type=T_INT; to->subtype=i ? NUMBER_UNDEFINED : 0; to->u.integer=i; break; case T_STRING: if(ind->type==T_INT) { i=ind->u.integer; if(i<0) i+=what->u.string->len; if(i<0 || i>=what->u.string->len)
e747d81998-05-21Henrik Grubbström (Grubba)  error("Index %d is out of range 0 - %d.\n", i, what->u.string->len-1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  else
db4a401998-10-09Fredrik Hübinette (Hubbe)  i=index_shared_string(what->u.string,i);
5267b71995-08-09Fredrik Hübinette (Hubbe)  to->type=T_INT; to->subtype=NUMBER_NUMBER; to->u.integer=i; break; }else{ error("Index is not an integer.\n"); }
3a1bef1998-06-07Henrik Grubbström (Grubba)  case T_PROGRAM: program_index_no_free(to, what->u.program, ind); break; case T_FUNCTION: { struct program *p = program_from_svalue(what); if (p) { program_index_no_free(to, p, ind); break; } } /* FALL THROUGH */
5267b71995-08-09Fredrik Hübinette (Hubbe)  default: error("Indexing a basic type.\n"); } }
be478c1997-08-30Henrik Grubbström (Grubba) void o_index(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
de2a581997-09-28Fredrik Hübinette (Hubbe)  struct svalue s; index_no_free(&s,sp-2,sp-1); pop_n_elems(2); *sp=s;
5683de1995-11-06Fredrik Hübinette (Hubbe)  sp++;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
98f2b11998-02-19Fredrik Hübinette (Hubbe) void o_cast(struct pike_string *type, INT32 run_time_type)
5267b71995-08-09Fredrik Hübinette (Hubbe) { INT32 i;
07c0731996-06-21Fredrik Hübinette (Hubbe) 
98f2b11998-02-19Fredrik Hübinette (Hubbe)  if(run_time_type != sp[-1].type)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
98f2b11998-02-19Fredrik Hübinette (Hubbe)  if(run_time_type == T_MIXED)
07c0731996-06-21Fredrik Hübinette (Hubbe)  return;
98f2b11998-02-19Fredrik Hübinette (Hubbe)  if(sp[-1].type == T_OBJECT)
07c0731996-06-21Fredrik Hübinette (Hubbe)  {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *s;
98f2b11998-02-19Fredrik Hübinette (Hubbe)  s=describe_type(type);
07c0731996-06-21Fredrik Hübinette (Hubbe)  push_string(s); if(!sp[-2].u.object->prog) error("Cast called on destructed object.\n");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(FIND_LFUN(sp[-2].u.object->prog,LFUN_CAST) == -1)
07c0731996-06-21Fredrik Hübinette (Hubbe)  error("No cast method in object.\n"); apply_lfun(sp[-2].u.object, LFUN_CAST, 1); free_svalue(sp-2); sp[-2]=sp[-1]; sp--; return; }
98f2b11998-02-19Fredrik Hübinette (Hubbe)  switch(run_time_type)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
98f2b11998-02-19Fredrik Hübinette (Hubbe)  case T_MIXED:
e97d731998-02-27Fredrik Hübinette (Hubbe)  return;
98f2b11998-02-19Fredrik Hübinette (Hubbe)  case T_ARRAY: switch(sp[-1].type) { case T_MAPPING: { struct array *a=mapping_to_array(sp[-1].u.mapping); pop_stack(); push_array(a); break; } case T_STRING: f_values(1); break; case T_MULTISET: f_indices(1); break; default:
f7f8a61998-05-14Fredrik Hübinette (Hubbe)  error("Cannot cast %s to array.\n",get_name_of_type(sp[-1].type));
98f2b11998-02-19Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
98f2b11998-02-19Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_INT:
98f2b11998-02-19Fredrik Hübinette (Hubbe)  switch(sp[-1].type) { case T_FLOAT: i=(int)(sp[-1].u.float_number); break; case T_STRING: i=STRTOL(sp[-1].u.string->str,0,0); free_string(sp[-1].u.string); break; default:
f7f8a61998-05-14Fredrik Hübinette (Hubbe)  error("Cannot cast %s to int.\n",get_name_of_type(sp[-1].type));
98f2b11998-02-19Fredrik Hübinette (Hubbe)  } sp[-1].type=T_INT; sp[-1].u.integer=i;
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
98f2b11998-02-19Fredrik Hübinette (Hubbe)  case T_FLOAT: { FLOAT_TYPE f; switch(sp[-1].type) { case T_INT: f=(FLOAT_TYPE)(sp[-1].u.integer); break; case T_STRING: f=STRTOD(sp[-1].u.string->str,0); free_string(sp[-1].u.string); break; default:
f7f8a61998-05-14Fredrik Hübinette (Hubbe)  error("Cannot cast %s to float.\n",get_name_of_type(sp[-1].type));
98f2b11998-02-19Fredrik Hübinette (Hubbe)  f=0.0; } sp[-1].type=T_FLOAT; sp[-1].u.float_number=f;
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; }
98f2b11998-02-19Fredrik Hübinette (Hubbe)  case T_STRING:
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
98f2b11998-02-19Fredrik Hübinette (Hubbe)  char buf[200]; switch(sp[-1].type) { case T_INT: sprintf(buf,"%ld",(long)sp[-1].u.integer); break; case T_FLOAT: sprintf(buf,"%f",(double)sp[-1].u.float_number); break;
0707481998-05-06Henrik Grubbström (Grubba)  case T_ARRAY: { int i; struct array *a = sp[-1].u.array; struct pike_string *s; for(i = a->size; i--; ) { if (a->item[i].type != T_INT) { error("cast: Item %d is not an integer.\n", i); } if ((a->item[i].u.integer < 0) || (a->item[i].u.integer > 255)) { error("cast: Wide strings are not supported yet.\n" "Index %d is %d, and is out of range 0 .. 255.\n", i, a->item[i].u.integer); } } s = begin_shared_string(a->size); for(i = a->size; i--; ) { s->str[i] = a->item[i].u.integer; } s = end_shared_string(s); pop_stack(); push_string(s); return; } break;
98f2b11998-02-19Fredrik Hübinette (Hubbe)  default:
f7f8a61998-05-14Fredrik Hübinette (Hubbe)  error("Cannot cast %s to string.\n",get_name_of_type(sp[-1].type));
98f2b11998-02-19Fredrik Hübinette (Hubbe)  } sp[-1].type=T_STRING; sp[-1].u.string=make_shared_string(buf);
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; }
98f2b11998-02-19Fredrik Hübinette (Hubbe)  case T_OBJECT: switch(sp[-1].type) { case T_STRING: if(fp->pc) { INT32 lineno; push_text(get_line(fp->pc, fp->context.prog, &lineno)); }else{ push_int(0); } APPLY_MASTER("cast_to_object",2); return; case T_FUNCTION: sp[-1].type = T_OBJECT; break;
569c171998-02-27Fredrik Hübinette (Hubbe)  default:
f7f8a61998-05-14Fredrik Hübinette (Hubbe)  error("Cannot cast %s to object.\n",get_name_of_type(sp[-1].type));
98f2b11998-02-19Fredrik Hübinette (Hubbe)  } break; case T_PROGRAM:
0e70221998-04-05Fredrik Hübinette (Hubbe)  switch(sp[-1].type) { case T_STRING: if(fp->pc) { INT32 lineno; push_text(get_line(fp->pc, fp->context.prog, &lineno)); }else{ push_int(0); } APPLY_MASTER("cast_to_program",2); return; case T_FUNCTION:
0a9e131997-02-16Fredrik Hübinette (Hubbe)  {
0e70221998-04-05Fredrik Hübinette (Hubbe)  struct program *p=program_from_function(sp-1); if(p) {
d6ac731998-04-20Henrik Grubbström (Grubba)  add_ref(p);
0e70221998-04-05Fredrik Hübinette (Hubbe)  pop_stack(); push_program(p); }else{ pop_stack(); push_int(0); }
0a9e131997-02-16Fredrik Hübinette (Hubbe)  }
98f2b11998-02-19Fredrik Hübinette (Hubbe)  return;
0e70221998-04-05Fredrik Hübinette (Hubbe)  default:
f7f8a61998-05-14Fredrik Hübinette (Hubbe)  error("Cannot cast %s to a program.\n",get_name_of_type(sp[-1].type));
0e70221998-04-05Fredrik Hübinette (Hubbe)  }
98f2b11998-02-19Fredrik Hübinette (Hubbe)  } }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
98f2b11998-02-19Fredrik Hübinette (Hubbe) #ifdef DEBUG if(run_time_type != sp[-1].type)
569c171998-02-27Fredrik Hübinette (Hubbe)  fatal("Internal error: Cast failed (run_time_type = %d, sp[-1].type = %d.)\n",run_time_type,sp[-1].type);
98f2b11998-02-19Fredrik Hübinette (Hubbe) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) 
98f2b11998-02-19Fredrik Hübinette (Hubbe)  switch(run_time_type) { case T_ARRAY:
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
98f2b11998-02-19Fredrik Hübinette (Hubbe)  struct pike_string *itype; INT32 run_time_itype;
7ea3341998-05-16Fredrik Hübinette (Hubbe)  push_string(itype=index_type(type,0));
98f2b11998-02-19Fredrik Hübinette (Hubbe)  run_time_itype=compile_type_to_runtime_type(itype); if(run_time_itype != T_MIXED)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
98f2b11998-02-19Fredrik Hübinette (Hubbe)  struct array *a; struct array *tmp=sp[-2].u.array; DECLARE_CYCLIC(); if((a=(struct array *)BEGIN_CYCLIC(tmp,0))) { ref_push_array(a); }else{ INT32 e,i; struct pike_string *s;
7ea3341998-05-16Fredrik Hübinette (Hubbe) #ifdef DEBUG struct svalue *save_sp=sp+1; #endif
98f2b11998-02-19Fredrik Hübinette (Hubbe)  push_array(a=allocate_array(tmp->size)); SET_CYCLIC_RET(a); for(e=0;e<a->size;e++) { push_svalue(tmp->item+e); o_cast(itype, run_time_itype); array_set_index(a,e,sp-1); pop_stack(); }
7ea3341998-05-16Fredrik Hübinette (Hubbe) #ifdef DEBUG if(save_sp!=sp) fatal("o_cast left stack droppings.\n"); #endif
98f2b11998-02-19Fredrik Hübinette (Hubbe)  END_CYCLIC(); } assign_svalue(sp-3,sp-1); pop_stack();
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
98f2b11998-02-19Fredrik Hübinette (Hubbe)  pop_stack();
5267b71995-08-09Fredrik Hübinette (Hubbe)  } } }
98f2b11998-02-19Fredrik Hübinette (Hubbe) void f_cast(void) { #ifdef DEBUG struct svalue *save_sp=sp; #endif o_cast(sp[-2].u.string, compile_type_to_runtime_type(sp[-2].u.string)); #ifdef DEBUG if(save_sp != sp) fatal("Internal error: o_cast() left droppings on stack.\n"); #endif free_svalue(sp-2); sp[-2]=sp[-1]; sp--; }
5267b71995-08-09Fredrik Hübinette (Hubbe) /* flags: * operators: %d %s %f %c %n %[ %% */
53842a1998-04-15Fredrik Hübinette (Hubbe) static int read_set(unsigned char *match,int cnt,char *set,int match_len)
5267b71995-08-09Fredrik Hübinette (Hubbe) { int init; int last=0; int e; if(cnt>=match_len) error("Error in sscanf format string.\n"); if(match[cnt]=='^') { for(e=0;e<256;e++) set[e]=1; init=0; cnt++; if(cnt>=match_len) error("Error in sscanf format string.\n"); }else{ for(e=0;e<256;e++) set[e]=0; init=1; }
53842a1998-04-15Fredrik Hübinette (Hubbe)  if(match[cnt]==']' || match[cnt]=='-')
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
53842a1998-04-15Fredrik Hübinette (Hubbe)  set[last=match[cnt]]=init;
5267b71995-08-09Fredrik Hübinette (Hubbe)  cnt++; if(cnt>=match_len) error("Error in sscanf format string.\n"); } for(;match[cnt]!=']';cnt++) { if(match[cnt]=='-') { cnt++; if(cnt>=match_len) error("Error in sscanf format string.\n"); if(match[cnt]==']') { set['-']=init; break; }
5c8e891995-10-29Fredrik Hübinette (Hubbe)  for(e=last;e<(int) EXTRACT_UCHAR(match+cnt);e++) set[e]=init;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } set[last=EXTRACT_UCHAR(match+cnt)]=init; } return cnt; }
53842a1998-04-15Fredrik Hübinette (Hubbe) 
4bd22e1998-05-25Marcus Comstedt  /* Parse binary IEEE strings on a machine which uses a different kind of floating point internally */ #ifndef FLOAT_IS_IEEE_BIG #ifndef FLOAT_IS_IEEE_LITTLE #define NEED_CUSTOM_IEEE #endif #endif #ifndef NEED_CUSTOM_IEEE #ifndef DOUBLE_IS_IEEE_BIG #ifndef DOUBLE_IS_IEEE_LITTLE #define NEED_CUSTOM_IEEE #endif #endif #endif #ifdef NEED_CUSTOM_IEEE #if HAVE_LDEXP #define LDEXP ldexp #else extern double LDEXP(double x, int exp); /* defined in encode.c */ #endif INLINE static float low_parse_IEEE_float(char *b, int sz) { unsigned INT32 f, extra_f; int s, e; unsigned char x[4]; double r; x[0] = EXTRACT_UCHAR(b); x[1] = EXTRACT_UCHAR(b+1); x[2] = EXTRACT_UCHAR(b+2); x[3] = EXTRACT_UCHAR(b+3); s = ((x[0]&0x80)? 1 : 0); if(sz==4) { e = (((int)(x[0]&0x7f))<<1)|((x[1]&0x80)>>7); f = (((unsigned INT32)(x[1]&0x7f))<<16)|(((unsigned INT32)x[2])<<8)|x[3]; extra_f = 0; if(e==255) e = 9999; else if(e>0) { f |= 0x00800000; e -= 127+23; } else e -= 126+23; } else { e = (((int)(x[0]&0x7f))<<4)|((x[1]&0xf0)>>4); f = (((unsigned INT32)(x[1]&0x0f))<<16)|(((unsigned INT32)x[2])<<8)|x[3]; extra_f = (((unsigned INT32)EXTRACT_UCHAR(b+4))<<24)| (((unsigned INT32)EXTRACT_UCHAR(b+5))<<16)| (((unsigned INT32)EXTRACT_UCHAR(b+6))<<8)| ((unsigned INT32)EXTRACT_UCHAR(b+7)); if(e==2047) e = 9999; else if(e>0) { f |= 0x00100000; e -= 1023+20; } else e -= 1022+20; } if(e>=9999) if(f||extra_f) { /* NAN */ /* Hmm... No idea how to generate NaN in a portable way. */ /* Let's turn it into a 0 for now... */ return (float)0.0; } else { /* +/- Infinity */ #ifdef HUGE_VAL return (float)(s? -HUGE_VAL:HUGE_VAL); #else /* This number is infinite enough... :) */ e = 1024; f = 1; extra_f = 0; #endif } r = (double)f; if(extra_f) r += ((double)extra_f)/4294967296.0; return (float)(s? -LDEXP(r, e):LDEXP(r, e)); } #endif
53842a1998-04-15Fredrik Hübinette (Hubbe) static INT32 really_low_sscanf(char *input, long input_len, char *match, long match_len, long *chars_matched, int *success)
5267b71995-08-09Fredrik Hübinette (Hubbe) { struct svalue sval;
2a50961995-08-23Fredrik Hübinette (Hubbe)  int e,cnt,matches,eye,arg;
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  int no_assign,field_length;
5267b71995-08-09Fredrik Hübinette (Hubbe)  char set[256]; struct svalue *argp;
53842a1998-04-15Fredrik Hübinette (Hubbe)  success[0]=0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  arg=eye=matches=0; for(cnt=0;cnt<match_len;cnt++) { for(;cnt<match_len;cnt++) { if(match[cnt]=='%') { if(match[cnt+1]=='%') { cnt++; }else{ break; } } if(eye>=input_len || input[eye]!=match[cnt])
53842a1998-04-15Fredrik Hübinette (Hubbe)  { chars_matched[0]=eye;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return matches;
53842a1998-04-15Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  eye++; }
53842a1998-04-15Fredrik Hübinette (Hubbe)  if(cnt>=match_len) { chars_matched[0]=eye; return matches; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  #ifdef DEBUG if(match[cnt]!='%' || match[cnt+1]=='%') { fatal("Error in sscanf.\n"); } #endif
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  no_assign=0; field_length=-1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  cnt++; if(cnt>=match_len) error("Error in sscanf format string.\n");
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  while(1)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  switch(match[cnt]) { case '*': no_assign=1; cnt++; if(cnt>=match_len) error("Error in sscanf format string.\n"); continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { char *t; field_length=STRTOL(match+cnt,&t,10); cnt=t-match; continue; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
53842a1998-04-15Fredrik Hübinette (Hubbe)  case '{': { ONERROR err; long tmp; for(e=cnt+1,tmp=1;tmp;e++) { if(!match[e]) { error("Missing %%} in format string.\n"); break; /* UNREACHED */ } if(match[e]=='%') { switch(match[e+1]) { case '%': e++; break; case '}': tmp--; break; case '{': tmp++; break; } } } sval.type=T_ARRAY; sval.u.array=allocate_array(0); SET_ONERROR(err, do_free_array, sval.u.array); while(1) { int yes; struct svalue *save_sp=sp; really_low_sscanf(input+eye, input_len-eye, match+cnt+1, e-cnt-2, &tmp, &yes); if(yes) { f_aggregate(sp-save_sp); sval.u.array=append_array(sval.u.array,sp-1); pop_stack(); eye+=tmp; }else{ pop_n_elems(sp-save_sp); break; } } cnt=e; UNSET_ONERROR(err); break; }
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  case 'c': if(field_length == -1) field_length = 1;
53842a1998-04-15Fredrik Hübinette (Hubbe)  if(eye+field_length > input_len) { chars_matched[0]=eye; return matches; }
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  sval.type=T_INT; sval.subtype=NUMBER_NUMBER; sval.u.integer=0; while(--field_length >= 0) { sval.u.integer<<=8; sval.u.integer|=EXTRACT_UCHAR(input+eye); eye++; } break;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  case 'd': { char * t;
53842a1998-04-15Fredrik Hübinette (Hubbe)  if(eye>=input_len) { chars_matched[0]=eye; return matches; }
bf13151998-04-14Fredrik Hübinette (Hubbe)  if(field_length != -1 && eye+field_length < input_len) {
53842a1998-04-15Fredrik Hübinette (Hubbe)  char save=input[eye+field_length]; input[eye+field_length]=0; /* DANGEROUS */
bf13151998-04-14Fredrik Hübinette (Hubbe)  sval.u.integer=STRTOL(input+eye,&t,10);
53842a1998-04-15Fredrik Hübinette (Hubbe)  input[eye+field_length]=save;
bf13151998-04-14Fredrik Hübinette (Hubbe)  }else sval.u.integer=STRTOL(input+eye,&t,10);
53842a1998-04-15Fredrik Hübinette (Hubbe)  if(input + eye == t) { chars_matched[0]=eye; return matches; }
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  eye=t-input; sval.type=T_INT; sval.subtype=NUMBER_NUMBER; break; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  case 'x': { char * t;
53842a1998-04-15Fredrik Hübinette (Hubbe)  if(eye>=input_len) { chars_matched[0]=eye; return matches; }
bf13151998-04-14Fredrik Hübinette (Hubbe)  if(field_length != -1 && eye+field_length < input_len) {
53842a1998-04-15Fredrik Hübinette (Hubbe)  char save=input[eye+field_length]; input[eye+field_length]=0; /* DANGEROUS */
bf13151998-04-14Fredrik Hübinette (Hubbe)  sval.u.integer=STRTOL(input+eye,&t,16);
53842a1998-04-15Fredrik Hübinette (Hubbe)  input[eye+field_length]=save;
bf13151998-04-14Fredrik Hübinette (Hubbe)  }else sval.u.integer=STRTOL(input+eye,&t,16);
53842a1998-04-15Fredrik Hübinette (Hubbe)  if(input + eye == t) { chars_matched[0]=eye; return matches; }
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  eye=t-input; sval.type=T_INT; sval.subtype=NUMBER_NUMBER; break; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  case 'o': { char * t;
53842a1998-04-15Fredrik Hübinette (Hubbe)  if(eye>=input_len) { chars_matched[0]=eye; return matches; }
bf13151998-04-14Fredrik Hübinette (Hubbe)  if(field_length != -1 && eye+field_length < input_len) {
53842a1998-04-15Fredrik Hübinette (Hubbe)  char save=input[eye+field_length]; input[eye+field_length]=0; /* DANGEROUS */
bf13151998-04-14Fredrik Hübinette (Hubbe)  sval.u.integer=STRTOL(input+eye,&t,8);
53842a1998-04-15Fredrik Hübinette (Hubbe)  input[eye+field_length]=save;
bf13151998-04-14Fredrik Hübinette (Hubbe)  }else sval.u.integer=STRTOL(input+eye,&t,8);
53842a1998-04-15Fredrik Hübinette (Hubbe)  if(input + eye == t) { chars_matched[0]=eye; return matches; }
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  eye=t-input; sval.type=T_INT; sval.subtype=NUMBER_NUMBER; break; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  case 'D':
6b60b81998-02-04Fredrik Hübinette (Hubbe)  case 'i':
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  char * t;
53842a1998-04-15Fredrik Hübinette (Hubbe)  if(eye>=input_len) { chars_matched[0]=eye; return matches; }
bf13151998-04-14Fredrik Hübinette (Hubbe)  if(field_length != -1 && eye+field_length < input_len) {
53842a1998-04-15Fredrik Hübinette (Hubbe)  char save=input[eye+field_length]; input[eye+field_length]=0; /* DANGEROUS */
bf13151998-04-14Fredrik Hübinette (Hubbe)  sval.u.integer=STRTOL(input+eye,&t,0);
53842a1998-04-15Fredrik Hübinette (Hubbe)  input[eye+field_length]=save;
bf13151998-04-14Fredrik Hübinette (Hubbe)  }else sval.u.integer=STRTOL(input+eye,&t,0);
53842a1998-04-15Fredrik Hübinette (Hubbe)  if(input + eye == t) { chars_matched[0]=eye; return matches; }
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  eye=t-input; sval.type=T_INT; sval.subtype=NUMBER_NUMBER; break; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  case 'f': { char * t;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
53842a1998-04-15Fredrik Hübinette (Hubbe)  if(eye>=input_len) { chars_matched[0]=eye; return matches; }
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  sval.u.float_number=STRTOD(input+eye,&t);
53842a1998-04-15Fredrik Hübinette (Hubbe)  if(input + eye == t) { chars_matched[0]=eye; return matches; }
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  eye=t-input; sval.type=T_FLOAT;
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifdef __CHECKER__ sval.subtype=0; #endif break;
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
4bd22e1998-05-25Marcus Comstedt  case 'F': if(field_length == -1) field_length = 4; if(field_length != 4 && field_length != 8) error("Invalid IEEE width %d in sscanf format string.\n", field_length); if(eye+field_length > input_len) { chars_matched[0]=eye; return matches; } sval.type=T_FLOAT; #ifdef __CHECKER__ sval.subtype=0; #endif switch(field_length) { case 4: #ifdef FLOAT_IS_IEEE_BIG { float f; ((char *)&f)[0] = *(input+eye); ((char *)&f)[1] = *(input+eye+1); ((char *)&f)[2] = *(input+eye+2); ((char *)&f)[3] = *(input+eye+3); sval.u.float_number = f; } #else #ifdef FLOAT_IS_IEEE_LITTLE { float f; ((char *)&f)[3] = *(input+eye); ((char *)&f)[2] = *(input+eye+1); ((char *)&f)[1] = *(input+eye+2); ((char *)&f)[0] = *(input+eye+3); sval.u.float_number = f; } #else sval.u.float_number = low_parse_IEEE_float(input+eye, 4); #endif #endif eye += 4; break; case 8: #ifdef DOUBLE_IS_IEEE_BIG { double d; ((char *)&d)[0] = *(input+eye); ((char *)&d)[1] = *(input+eye+1); ((char *)&d)[2] = *(input+eye+2); ((char *)&d)[3] = *(input+eye+3); ((char *)&d)[4] = *(input+eye+4); ((char *)&d)[5] = *(input+eye+5); ((char *)&d)[6] = *(input+eye+6); ((char *)&d)[7] = *(input+eye+7); sval.u.float_number = (float)d; } #else #ifdef DOUBLE_IS_IEEE_LITTLE { double d; ((char *)&d)[7] = *(input+eye); ((char *)&d)[6] = *(input+eye+1); ((char *)&d)[5] = *(input+eye+2); ((char *)&d)[4] = *(input+eye+3); ((char *)&d)[3] = *(input+eye+4); ((char *)&d)[2] = *(input+eye+5); ((char *)&d)[1] = *(input+eye+6); ((char *)&d)[0] = *(input+eye+7); sval.u.float_number = (float)d; } #else sval.u.float_number = low_parse_IEEE_float(input+eye, 8); #endif #endif eye += 8; break; } break;
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  case 's': if(field_length != -1)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  if(input_len - eye < field_length)
53842a1998-04-15Fredrik Hübinette (Hubbe)  { chars_matched[0]=eye;
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  return matches;
53842a1998-04-15Fredrik Hübinette (Hubbe)  }
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  sval.type=T_STRING;
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifdef __CHECKER__
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  sval.subtype=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  sval.u.string=make_shared_binary_string(input+eye,field_length); eye+=field_length; break; } if(cnt+1>=match_len)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  sval.type=T_STRING; #ifdef __CHECKER__ sval.subtype=0; #endif sval.u.string=make_shared_binary_string(input+eye,input_len-eye); eye=input_len; break; }else{ char *end_str_start; char *end_str_end; char *s=0; /* make gcc happy */ char *p=0; /* make gcc happy */ int start,contains_percent_percent, new_eye; start=eye; end_str_start=match+cnt+1; s=match+cnt+1; test_again: if(*s=='%')
5267b71995-08-09Fredrik Hübinette (Hubbe)  { s++;
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  if(*s=='*') s++; switch(*s) { case 'n': s++; goto test_again;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  case 's':
24697f1997-03-12Henrik Grubbström (Grubba)  error("Illegal to have two adjecent %%s.\n");
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  return 0; /* make gcc happy */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  /* sscanf("foo-bar","%s%d",a,b) might not work as expected */ case 'd': for(e=0;e<256;e++) set[e]=1; for(e='0';e<='9';e++) set[e]=0; set['-']=0; goto match_set; case 'o': for(e=0;e<256;e++) set[e]=1; for(e='0';e<='7';e++) set[e]=0; goto match_set; case 'x': for(e=0;e<256;e++) set[e]=1; for(e='0';e<='9';e++) set[e]=0; for(e='a';e<='f';e++) set[e]=0; goto match_set; case 'D': for(e=0;e<256;e++) set[e]=1; for(e='0';e<='9';e++) set[e]=0; set['-']=0; set['x']=0; goto match_set; case 'f': for(e=0;e<256;e++) set[e]=1; for(e='0';e<='9';e++) set[e]=0; set['.']=set['-']=0; goto match_set; case '[': /* oh dear */
53842a1998-04-15Fredrik Hübinette (Hubbe)  read_set((unsigned char *)match,s-match+1,set,match_len);
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  for(e=0;e<256;e++) set[e]=!set[e]; goto match_set; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  contains_percent_percent=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  for(e=cnt;e<match_len;e++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  if(match[e]=='%')
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  if(match[e+1]=='%') { contains_percent_percent=1; e++; }else{ break; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  end_str_end=match+e;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  if(!contains_percent_percent)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  s=my_memmem(end_str_start, end_str_end-end_str_start, input+eye, input_len-eye);
53842a1998-04-15Fredrik Hübinette (Hubbe)  if(!s) { chars_matched[0]=eye; return matches; }
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  eye=s-input; new_eye=eye+end_str_end-end_str_start; }else{ for(;eye<input_len;eye++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  p=input+eye; for(s=end_str_start;s<end_str_end;s++,p++) { if(*s!=*p) break; if(*s=='%') s++; } if(s==end_str_end) break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  if(eye==input_len)
53842a1998-04-15Fredrik Hübinette (Hubbe)  { chars_matched[0]=eye;
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  return matches;
53842a1998-04-15Fredrik Hübinette (Hubbe)  }
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  new_eye=p-input;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  sval.type=T_STRING;
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifdef __CHECKER__
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  sval.subtype=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  sval.u.string=make_shared_binary_string(input+start,eye-start);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  cnt=end_str_end-match-1; eye=new_eye; break; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  case '[':
53842a1998-04-15Fredrik Hübinette (Hubbe)  cnt=read_set((unsigned char *)match,cnt+1,set,match_len);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  match_set: for(e=eye;eye<input_len && set[EXTRACT_UCHAR(input+eye)];eye++); sval.type=T_STRING;
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifdef __CHECKER__
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  sval.subtype=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  sval.u.string=make_shared_binary_string(input+e,eye-e); break;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  case 'n': sval.type=T_INT; sval.subtype=NUMBER_NUMBER; sval.u.integer=eye; break;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
3d2fb21996-08-06Fredrik Hübinette (Hubbe)  default: error("Unknown sscanf token %%%c\n",match[cnt]); } break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } matches++;
53842a1998-04-15Fredrik Hübinette (Hubbe)  if(no_assign)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
53842a1998-04-15Fredrik Hübinette (Hubbe)  free_svalue(&sval); }else{ check_stack(1); *sp++=sval; #ifdef DEBUG sval.type=99; #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
53842a1998-04-15Fredrik Hübinette (Hubbe)  chars_matched[0]=eye; success[0]=1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return matches; }
53842a1998-04-15Fredrik Hübinette (Hubbe) void o_sscanf(INT32 args)
5267b71995-08-09Fredrik Hübinette (Hubbe) { #ifdef DEBUG extern int t_flag; #endif
53842a1998-04-15Fredrik Hübinette (Hubbe)  INT32 e,i; int x; long matched_chars; struct svalue *save_sp=sp; if(sp[-args].type != T_STRING) error("Bad argument 1 to sscanf().\n"); if(sp[1-args].type != T_STRING) error("Bad argument 1 to sscanf().\n"); i=really_low_sscanf(sp[-args].u.string->str, sp[-args].u.string->len, sp[1-args].u.string->str, sp[1-args].u.string->len, &matched_chars, &x); if(sp-save_sp > args/2-1) error("Too few arguments for sscanf format.\n"); for(x=0;x<sp-save_sp;x++) assign_lvalue(save_sp-args+2+x*2,save_sp+x); pop_n_elems(sp-save_sp +args);
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifdef DEBUG if(t_flag >2) { int nonblock; if((nonblock=query_nonblocking(2))) set_nonblocking(2,0);
f90e541995-08-17Fredrik Hübinette (Hubbe)  fprintf(stderr,"- Matches: %ld\n",(long)i);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(nonblock) set_nonblocking(2,1); }
53842a1998-04-15Fredrik Hübinette (Hubbe) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  push_int(i); }
53842a1998-04-15Fredrik Hübinette (Hubbe)  void f_sscanf(INT32 args) { #ifdef DEBUG extern int t_flag; #endif INT32 e,i; int x; long matched_chars; struct svalue *save_sp=sp; struct array *a; check_all_args("array_sscanf",args,BIT_STRING, BIT_STRING,0); i=really_low_sscanf(sp[-args].u.string->str, sp[-args].u.string->len, sp[1-args].u.string->str, sp[1-args].u.string->len, &matched_chars, &x); a=aggregate_array(sp-save_sp); pop_n_elems(args); push_array(a); }