pike.git / src / operators.c

version» Context lines:

pike.git/src/operators.c:1:   /*\   ||| This file a part of Pike, and is copyright by Fredrik Hubinette   ||| Pike is distributed as GPL (General Public License)   ||| See the files COPYING and DISCLAIMER for more information.   \*/   #include "global.h"   #include <math.h> - RCSID("$Id: operators.c,v 1.42 1998/10/12 22:55:10 hubbe Exp $"); + RCSID("$Id: operators.c,v 1.43 1998/10/14 05:48:45 hubbe Exp $");   #include "interpret.h"   #include "svalue.h"   #include "multiset.h"   #include "mapping.h"   #include "array.h"   #include "stralloc.h"   #include "opcodes.h"   #include "operators.h"   #include "language.h"   #include "pike_memory.h"   #include "error.h"   #include "docode.h"   #include "constants.h"   #include "peep.h"   #include "lex.h"   #include "program.h"   #include "object.h"   #include "pike_types.h"   #include "module_support.h" -  + #include "pike_macros.h"      #define COMPARISON(ID,NAME,FUN) \   void ID(INT32 args) \   { \    int i; \    switch(args) \    { \    case 0: case 1: \    PIKE_ERROR(NAME, "Too few arguments\n", sp, args); \    case 2: \
pike.git/src/operators.c:132:    case T_PROGRAM:    case T_FUNCTION:    PIKE_ERROR("`+", "Bad argument 1\n", sp, args);    }    PIKE_ERROR("`+", "Incompatible types\n", sp, args);    return; /* compiler hint */       case BIT_STRING:    {    struct pike_string *r; -  char *buf; +  PCHARP buf;    INT32 tmp;    int max_shift=0;       if(args==1) return;       size=0;    for(e=-args;e<0;e++)    {    size+=sp[e].u.string->len;    if(sp[e].u.string->size_shift > max_shift)    max_shift=sp[e].u.string->size_shift;    }       tmp=sp[-args].u.string->len;    r=new_realloc_shared_string(sp[-args].u.string,size,max_shift);    sp[-args].type=T_INT; -  buf=r->str+(tmp<<max_shift); +  buf=MKPCHARP_STR_OFF(r,tmp);    for(e=-args+1;e<0;e++)    { -  pike_string_cpy(buf,max_shift,sp[e].u.string); -  buf+=sp[e].u.string->len << max_shift; +  pike_string_cpy(buf,sp[e].u.string); +  INC_PCHARP(buf,sp[e].u.string->len);    }    sp[-args].u.string=end_shared_string(r);    sp[-args].type=T_STRING;    for(e=-args+1;e<0;e++) free_string(sp[e].u.string);    sp-=args-1;       break;    }       case BIT_STRING | BIT_INT:    case BIT_STRING | BIT_FLOAT:    case BIT_STRING | BIT_FLOAT | BIT_INT:    {    struct pike_string *r; -  char *buf; +  PCHARP buf;    char buffer[50];    int max_shift=0;    size=0;    for(e=-args;e<0;e++)    {    switch(sp[e].type)    {    case T_STRING:    size+=sp[e].u.string->len;    if(sp[e].u.string->size_shift > max_shift)
pike.git/src/operators.c:193:    size+=14;    break;       case T_FLOAT:    size+=22;    break;    }    }       r=begin_wide_shared_string(size,max_shift); -  buf=r->str; +  buf=MKPCHARP_STR(r);    size=0;       for(e=-args;e<0;e++)    {    switch(sp[e].type)    {    case T_STRING: -  pike_string_cpy(buf,max_shift,sp[e].u.string); -  buf+=sp[e].u.string->len<<max_shift; +  pike_string_cpy(buf,sp[e].u.string); +  INC_PCHARP(buf,sp[e].u.string->len);    break;       case T_INT:    sprintf(buffer,"%ld",(long)sp[e].u.integer);    goto append_buffer;       case T_FLOAT:    sprintf(buffer,"%f",(double)sp[e].u.float_number);    append_buffer:    switch(max_shift)    { -  case 0: convert_0_to_0((p_wchar0 *)buf,buffer,strlen(buffer)); break; -  case 1: convert_0_to_1((p_wchar1 *)buf,buffer,strlen(buffer)); break; -  case 2: convert_0_to_2((p_wchar2 *)buf,buffer,strlen(buffer)); break; +  case 0: +  convert_0_to_0((p_wchar0 *)buf.ptr,buffer,strlen(buffer)); +  break; +  +  case 1: +  convert_0_to_1((p_wchar1 *)buf.ptr,buffer,strlen(buffer)); +  break; +  +  case 2: +  convert_0_to_2((p_wchar2 *)buf.ptr,buffer,strlen(buffer)); +  break; +     } -  buf+=strlen(buffer)<<max_shift; +  INC_PCHARP(buf,strlen(buffer));    }    } -  r->len=(buf-r->str)>>max_shift; +  r->len=SUBTRACT_PCHARP(buf,MKPCHARP_STR(r));    low_set_index(r,r->len,0);    r=end_shared_string(r);    pop_n_elems(args);    push_string(r);    break;    }       case BIT_INT:    size=0;    for(e=-args; e<0; e++) size+=sp[e].u.integer;
pike.git/src/operators.c:664:    }       case T_ARRAY:    {    struct array *a;    a=and_arrays(sp[-2].u.array, sp[-1].u.array);    pop_n_elems(2);    push_array(a);    return;    } -  case T_STRING: -  { -  struct pike_string *s; -  INT32 len, i; +     -  len = sp[-2].u.string->len; -  if (len != sp[-1].u.string->len) -  PIKE_ERROR("`&", "Bitwise AND on strings of different lengths.\n", sp, 2); -  s = begin_shared_string(len); -  for (i=0; i<len; i++) -  s->str[i] = sp[-2].u.string->str[i] & sp[-1].u.string->str[i]; -  pop_n_elems(2); -  push_string(end_shared_string(s)); -  return; + #define STRING_BITOP(OP,STROP) \ +  case T_STRING: \ +  { \ +  struct pike_string *s; \ +  INT32 len, i; \ +  \ +  len = sp[-2].u.string->len; \ +  if (len != sp[-1].u.string->len) \ +  PIKE_ERROR("`" #OP, "Bitwise "STROP \ +  " on strings of different lengths.\n", sp, 2); \ +  if(!sp[-2].u.string->size_shift && !sp[-1].u.string->size_shift) \ +  { \ +  s = begin_shared_string(len); \ +  for (i=0; i<len; i++) \ +  s->str[i] = sp[-2].u.string->str[i] OP sp[-1].u.string->str[i]; \ +  }else{ \ +  s = begin_wide_shared_string(len, \ +  MAXIMUM(sp[-2].u.string->size_shift, \ +  sp[-1].u.string->size_shift)); \ +  for (i=0; i<len; i++) \ +  low_set_index(s,i,index_shared_string(sp[-2].u.string,i) OP \ +  index_shared_string(sp[-1].u.string,i)); \ +  } \ +  pop_n_elems(2); \ +  push_string(end_shared_string(s)); \ +  return; \    } -  +  +  STRING_BITOP(&,"AND") +     default:    PIKE_ERROR("`&", "Bitwise and on illegal type.\n", sp, 2);    }   }      /* This function is used to speed up or/xor/and on    * arrays multisets and mappings. This is done by    * calling the operator for each pair of arguments    * first, then recursively doing the same on the    * results until only one value remains.
pike.git/src/operators.c:830:       case T_ARRAY:    {    struct array *a;    a=merge_array_without_order(sp[-2].u.array, sp[-1].u.array, OP_OR);    pop_n_elems(2);    push_array(a);    return;    }    -  case T_STRING: -  { -  struct pike_string *s; -  INT32 len, i; +  STRING_BITOP(|,"OR")    -  len = sp[-2].u.string->len; -  if (len != sp[-1].u.string->len) -  PIKE_ERROR("`|", "Bitwise OR on strings of different lengths.\n", sp, 2); -  s = begin_shared_string(len); -  for (i=0; i<len; i++) -  s->str[i] = sp[-2].u.string->str[i] | sp[-1].u.string->str[i]; -  pop_n_elems(2); -  push_string(end_shared_string(s)); -  return; -  } -  +     default:    PIKE_ERROR("`|", "Bitwise or on illegal type.\n", sp, 2);    }   }      void f_or(INT32 args)   {    switch(args)    {    case 0: PIKE_ERROR("`|", "Too few arguments.\n", sp, 0);
pike.git/src/operators.c:934:       case T_ARRAY:    {    struct array *a;    a=merge_array_without_order(sp[-2].u.array, sp[-1].u.array, OP_XOR);    pop_n_elems(2);    push_array(a);    return;    }    -  case T_STRING: -  { -  struct pike_string *s; -  INT32 len, i; +  STRING_BITOP(^,"XOR")    -  len = sp[-2].u.string->len; -  if (len != sp[-1].u.string->len) -  PIKE_ERROR("`^", "Bitwise XOR on strings of different lengths.\n", sp, 2); -  s = begin_shared_string(len); -  for (i=0; i<len; i++) -  s->str[i] = sp[-2].u.string->str[i] ^ sp[-1].u.string->str[i]; -  pop_n_elems(2); -  push_string(end_shared_string(s)); -  return; -  } -  +     default:    PIKE_ERROR("`^", "Bitwise XOR on illegal type.\n", sp, 2);    }   }      void f_xor(INT32 args)   {    switch(args)    {    case 0: PIKE_ERROR("`^", "Too few arguments.\n", sp, 0);
pike.git/src/operators.c:1084:    sp[-2].u.array->type_field);    ret->type_field=sp[-2].u.array->type_field;    pop_n_elems(2);    push_array(ret);    return;    }    case TWO_TYPES(T_STRING, T_INT):    {    struct pike_string *ret;    char *pos; -  INT32 e; +  INT32 e,len;    if(sp[-1].u.integer < 0)    PIKE_ERROR("`*", "Cannot multiply string by negative number.\n", sp, 2); -  ret=begin_shared_string(sp[-2].u.string->len * sp[-1].u.integer); +  ret=begin_wide_shared_string(sp[-2].u.string->len * sp[-1].u.integer, +  sp[-2].u.string->size_shift);    pos=ret->str; -  for(e=0;e<sp[-1].u.integer;e++,pos+=sp[-2].u.string->len) -  MEMCPY(pos,sp[-2].u.string->str,sp[-2].u.string->len); +  len=sp[-2].u.string->len << sp[-2].u.string->size_shift; +  for(e=0;e<sp[-1].u.integer;e++,pos+=len) +  MEMCPY(pos,sp[-2].u.string->str,len);    pop_n_elems(2); -  push_string(end_shared_string(ret)); +  push_string(low_end_shared_string(ret));    return;    }       case TWO_TYPES(T_ARRAY,T_STRING):    {    struct pike_string *ret;    ret=implode(sp[-2].u.array,sp[-1].u.string);    free_string(sp[-1].u.string);    free_array(sp[-2].u.array);    sp[-2].type=T_STRING;
pike.git/src/operators.c:1194:    if(sp[-2].type!=sp[-1].type && !float_promote())    {    if(call_lfun(LFUN_DIVIDE, LFUN_RDIVIDE))    return;       switch(TWO_TYPES(sp[-2].type,sp[-1].type))    {    case TWO_TYPES(T_STRING,T_INT):    {    struct array *a; -  char *pos=sp[-2].u.string->str; -  INT32 size,e,len; +  INT32 size,e,len,pos=0;       len=sp[-1].u.integer;    if(!len)    PIKE_ERROR("`/", "Division by zero.\n", sp, 2);       if(len<0)    {    len=-len;    size=sp[-2].u.string->len / len;    pos+=sp[-2].u.string->len % len;    }else{    size=sp[-2].u.string->len / len;    }    a=allocate_array(size);    for(e=0;e<size;e++)    { -  a->item[e].u.string=make_shared_binary_string(pos,len); +  a->item[e].u.string=string_slice(sp[-2].u.string, pos,len);    a->item[e].type=T_STRING;    pos+=len;    }    a->type_field=BIT_STRING;    pop_n_elems(2);    push_array(a);    return;    }       case TWO_TYPES(T_STRING,T_FLOAT):
pike.git/src/operators.c:1241:       if(len<0)    {    len=-len;    size=(INT32)ceil( ((double)sp[-2].u.string->len) / len);    a=allocate_array(size);       for(last=sp[-2].u.string->len,e=0;e<size-1;e++)    {    pos=sp[-2].u.string->len - (INT32)((e+1)*len); -  a->item[size-1-e].u.string=make_shared_binary_string( -  sp[-2].u.string->str + pos, +  a->item[size-1-e].u.string=string_slice(sp[-2].u.string, +  pos,    last-pos);    a->item[size-1-e].type=T_STRING;    last=pos;    }    pos=0; -  a->item[0].u.string=make_shared_binary_string( -  sp[-2].u.string->str + pos, +  a->item[0].u.string=string_slice(sp[-2].u.string, +  pos,    last-pos);    a->item[0].type=T_STRING;    }else{    size=(INT32)ceil( ((double)sp[-2].u.string->len) / len);    a=allocate_array(size);       for(last=0,e=0;e<size-1;e++)    {    pos=(INT32)((e+1)*len); -  a->item[e].u.string=make_shared_binary_string( -  sp[-2].u.string->str + last, +  a->item[e].u.string=string_slice(sp[-2].u.string, +  last,    pos-last);    a->item[e].type=T_STRING;    last=pos;    }    pos=sp[-2].u.string->len; -  a->item[e].u.string=make_shared_binary_string( -  sp[-2].u.string->str + last, +  a->item[e].u.string=string_slice(sp[-2].u.string, +  last,    pos-last);    a->item[e].type=T_STRING;    }    a->type_field=BIT_STRING;    pop_n_elems(2);    push_array(a);    return;    }      
pike.git/src/operators.c:1482:       tmp=sp[-1].u.integer;    if(tmp<0)    {    tmp=s->len % -tmp;    base=0;    }else{    tmp=s->len % tmp;    base=s->len - tmp;    } -  s=make_shared_binary_string(s->str + base, tmp); +  s=string_slice(s, base, tmp);    pop_n_elems(2);    push_string(s);    return;    }          case TWO_TYPES(T_ARRAY,T_INT):    {    struct array *a=sp[-2].u.array;    INT32 tmp,base;
pike.git/src/operators.c:1642:       case T_FLOAT:    sp[-1].u.float_number = -1.0 - sp[-1].u.float_number;    break;       case T_STRING:    {    struct pike_string *s;    INT32 len, i;    +  if(sp[-1].u.string->size_shift) +  error("`~ cannot handle wide strings.\n"); +     len = sp[-1].u.string->len;    s = begin_shared_string(len);    for (i=0; i<len; i++)    s->str[i] = ~ sp[-1].u.string->str[i];    pop_n_elems(1);    push_string(end_shared_string(s));    break;    }       default: