pike.git / src / builtin_functions.c

version» Context lines:

pike.git/src/builtin_functions.c:638:    *!    *! Convert a string or character to lower case.    *!    *! @returns    *! Returns a copy of the string @[s] with all upper case characters    *! converted to lower case, or the character @[c] converted to lower    *! case.    *!    *! @note    *! Assumes the string or character to be coded according to -  *! ISO-10646 (aka Unicode). If they are not, @[Locale.Charset.decoder] -  *! can do the initial conversion for you. +  *! ISO-10646 (aka Unicode). If they are not, @[Charset.decoder] can +  *! do the initial conversion for you.    *!    *! @note    *! Prior to Pike 7.5 this function only accepted strings.    *!    *! @seealso -  *! @[upper_case()], @[Locale.Charset.decoder] +  *! @[upper_case()], @[Charset.decoder]    */   PMOD_EXPORT void f_lower_case(INT32 args)   {    ptrdiff_t i;    struct pike_string *orig;    struct pike_string *ret;       check_all_args("lower_case", args, BIT_STRING|BIT_INT, 0);       if (TYPEOF(Pike_sp[-args]) == T_INT) {    /* NOTE: Performs the case change in place. */    DO_LOWER_CASE(Pike_sp[-args].u.integer);    pop_n_elems(args-1);    return;    }       orig = Pike_sp[-args].u.string; -  +  +  if( orig->flags & STRING_IS_LOWERCASE ) +  return; +     ret = begin_wide_shared_string(orig->len, orig->size_shift);       MEMCPY(ret->str, orig->str, orig->len << orig->size_shift);       i = orig->len;       if (!orig->size_shift) {    p_wchar0 *str = STR0(ret);       while(i--) {
pike.git/src/builtin_functions.c:693:       while(i--) {    DO_LOWER_CASE(str[i]);    }   #ifdef PIKE_DEBUG    } else {    Pike_fatal("lower_case(): Bad string shift:%d\n", orig->size_shift);   #endif    }    +  ret = end_shared_string(ret); +  ret->flags |= STRING_IS_LOWERCASE;    pop_n_elems(args); -  push_string(end_shared_string(ret)); +  push_string(ret);   }      /*! @decl string upper_case(string s)    *! @decl int upper_case(int c)    *!    *! Convert a string or character to upper case.    *!    *! @returns    *! Returns a copy of the string @[s] with all lower case characters    *! converted to upper case, or the character @[c] converted to upper    *! case.    *!    *! @note    *! Assumes the string or character to be coded according to -  *! ISO-10646 (aka Unicode). If they are not, @[Locale.Charset.decoder] -  *! can do the initial conversion for you. +  *! ISO-10646 (aka Unicode). If they are not, @[Charset.decoder] can +  *! do the initial conversion for you.    *!    *! @note    *! Prior to Pike 7.5 this function only accepted strings.    *!    *! @seealso -  *! @[lower_case()], @[Locale.Charset.decoder] +  *! @[lower_case()], @[Charset.decoder]    */   PMOD_EXPORT void f_upper_case(INT32 args)   {    ptrdiff_t i;    struct pike_string *orig;    struct pike_string *ret;    check_all_args("upper_case", args, BIT_STRING|BIT_INT, 0);       if (TYPEOF(Pike_sp[-args]) == T_INT) {    /* NOTE: Performs the case change in place. */    DO_UPPER_CASE(Pike_sp[-args].u.integer);    pop_n_elems(args-1);    return;    }       orig = Pike_sp[-args].u.string; -  +  if( orig->flags & STRING_IS_UPPERCASE ) +  { +  return; +  } +     ret=begin_wide_shared_string(orig->len,orig->size_shift);    MEMCPY(ret->str, orig->str, orig->len << orig->size_shift);       i = orig->len;       if (!orig->size_shift) {    p_wchar0 *str = STR0(ret);       while(i--) {    if(str[i]!=0xff && str[i]!=0xb5) {
pike.git/src/builtin_functions.c:793:    while(i--) {    DO_UPPER_CASE(str[i]);    }   #ifdef PIKE_DEBUG    } else {    Pike_fatal("lower_case(): Bad string shift:%d\n", orig->size_shift);   #endif    }       pop_n_elems(args); -  push_string(end_shared_string(ret)); +  ret = end_shared_string(ret); +  ret->flags |= STRING_IS_UPPERCASE; +  push_string(ret);   }      /*! @decl string random_string(int len)    *!    *! Returns a string of random characters 0-255 with the length @[len].    */   PMOD_EXPORT void f_random_string(INT32 args)   {    struct pike_string *ret;    INT_TYPE len, e;
pike.git/src/builtin_functions.c:821:   /*! @decl void random_seed(int seed)    *!    *! This function sets the initial value for the random generator.    *!    *! @seealso    *! @[random()]    */   PMOD_EXPORT void f_random_seed(INT32 args)   {    INT_TYPE i; - #ifdef AUTO_BIGNUM +     check_all_args("random_seed",args,BIT_INT | BIT_OBJECT, 0);    if(TYPEOF(Pike_sp[-args]) == T_INT)    {    i=Pike_sp[-args].u.integer;    }else{    i=hash_svalue(Pike_sp-args);    } - #else -  get_all_args("random_seed",args,"%i",&i); - #endif +     my_srand(i);    pop_n_elems(args);   }      /*! @decl int query_num_arg()    *!    *! Returns the number of arguments given when the previous function was    *! called.    *!    *! This is useful for functions that take a variable number of arguments.
pike.git/src/builtin_functions.c:948:    if ((TYPEOF(Pike_sp[1-args]) == T_INT) ||    ((TYPEOF(Pike_sp[1-args]) == T_STRING) &&    (Pike_sp[1-args].u.string->len == 1))) {    INT_TYPE val;    if (TYPEOF(Pike_sp[1-args]) == T_INT) {    val = Pike_sp[1-args].u.integer;    } else {    val = index_shared_string(Pike_sp[1-args].u.string, 0);    }    +  if( !string_range_contains( haystack, val ) ) +  { +  pop_n_elems(args); +  push_int( -1 ); +  return; +  }    switch(Pike_sp[-args].u.string->size_shift) {    case 0:    {    p_wchar0 *str = STR0(haystack);    if (val >= 256) {    start = -1;    break;    }    while (start < haystack->len) {    if (str[start] == val) break;
pike.git/src/builtin_functions.c:1171:    }    }    pop_n_elems(args+1);    push_int(1);    return;    }       a = Pike_sp[-args].u.string;       /* First handle some common special cases. */ -  if ((b->len > a->len) || (b->size_shift > a->size_shift)) { +  if ((b->len > a->len) || (b->size_shift > a->size_shift) +  || !string_range_contains_string(a, b)) {    pop_n_elems(args);    push_int(0);    return;    }       /* Trivial cases. */    if ((a == b)||(!b->len)) {    pop_n_elems(args);    push_int(1);    return;
pike.git/src/builtin_functions.c:1243:    SIMPLE_TOO_FEW_ARGS_ERROR("has_suffix", 2);    if(TYPEOF(Pike_sp[-args]) != T_STRING)    SIMPLE_ARG_TYPE_ERROR("has_suffix", 1, "string");    if(TYPEOF(Pike_sp[1-args]) != T_STRING)    SIMPLE_ARG_TYPE_ERROR("has_suffix", 2, "string");       a = Pike_sp[-args].u.string;    b = Pike_sp[1-args].u.string;       /* First handle some common special cases. */ -  if ((b->len > a->len) || (b->size_shift > a->size_shift)) { +  if ((b->len > a->len) || (b->size_shift > a->size_shift) +  || !string_range_contains_string(a, b)) {    pop_n_elems(args);    push_int(0);    return;    }       /* Trivial cases. */    if ((a == b)||(!b->len)) {    pop_n_elems(args);    push_int(1);    return;
pike.git/src/builtin_functions.c:1630:    *! Converts a string into an UTF16 compliant byte-stream.    *!    *! @note    *! Throws an error if characters not legal in an UTF16 stream are    *! encountered. Valid characters are in the range 0x00000 - 0x10ffff,    *! except for characters 0xfffe and 0xffff.    *!    *! Characters in range 0x010000 - 0x10ffff are encoded using surrogates.    *!    *! @seealso -  *! @[Locale.Charset.decoder()], @[string_to_utf8()], @[unicode_to_string()], +  *! @[Charset.decoder()], @[string_to_utf8()], @[unicode_to_string()],    *! @[utf8_to_string()]    */   PMOD_EXPORT void f_string_to_unicode(INT32 args)   {    struct pike_string *in;    struct pike_string *out = NULL;    ptrdiff_t len;    ptrdiff_t i;       get_all_args("string_to_unicode", args, "%W", &in);
pike.git/src/builtin_functions.c:1766:   }      /*! @decl string unicode_to_string(string(0..255) s)    *!    *! Converts an UTF16 byte-stream into a string.    *!    *! @note    *! This function did not decode surrogates in Pike 7.2 and earlier.    *!    *! @seealso -  *! @[Locale.Charset.decoder()], @[string_to_unicode()], @[string_to_utf8()], +  *! @[Charset.decoder()], @[string_to_unicode()], @[string_to_utf8()],    *! @[utf8_to_string()]    */   PMOD_EXPORT void f_unicode_to_string(INT32 args)   {    struct pike_string *in;    struct pike_string *out = NULL;    ptrdiff_t len, i, num_surrogates = 0;    int swab=0;    p_wchar1 surr1, surr2, surrmask, *str0;   
pike.git/src/builtin_functions.c:1932:    *! @note    *! Throws an error if characters not valid in an UTF-8 stream are    *! encountered. Valid characters are in the ranges    *! @expr{0x00000000-0x0000d7ff@} and @expr{0x0000e000-0x0010ffff@}.    *!    *! If @[extended] is 1 then characters outside the valid ranges are    *! accepted too and encoded using the same algorithm. Such encoded    *! characters are however not UTF-8 compliant.    *!    *! @seealso -  *! @[Locale.Charset.encoder()], @[string_to_unicode()], +  *! @[Charset.encoder()], @[string_to_unicode()],    *! @[unicode_to_string()], @[utf8_to_string()]    */   PMOD_EXPORT void f_string_to_utf8(INT32 args)   {    ptrdiff_t len;    struct pike_string *in;    struct pike_string *out;    ptrdiff_t i,j;    INT_TYPE extended = 0; -  +  PCHARP src; +  INT32 min, max;       get_all_args("string_to_utf8", args, "%W.%i", &in, &extended);       len = in->len;    -  for(i=0; i < in->len; i++) { -  unsigned INT32 c = index_shared_string(in, i); +  check_string_range(in, 1, &min, &max); +  +  if (min >= 0 && max <= 0x7f) { +  /* 7bit string -- already valid utf8. */ +  pop_n_elems(args - 1); +  return; +  } +  +  for(i=0,src=MKPCHARP_STR(in); i < in->len; INC_PCHARP(src,1),i++) { +  unsigned INT32 c = EXTRACT_PCHARP(src);    if (c & ~0x7f) {    /* 8bit or more. */    len++;    if (c & ~0x7ff) {    /* 12bit or more. */    len++;    if (c & ~0xffff) {    /* 17bit or more. */    len++;    if (!extended && c > 0x10ffff)
pike.git/src/builtin_functions.c:1994:    }    }    }    if (len == in->len) {    /* 7bit string -- already valid utf8. */    pop_n_elems(args - 1);    return;    }    out = begin_shared_string(len);    -  for(i=j=0; i < in->len; i++) { -  unsigned INT32 c = index_shared_string(in, i); +  for(i=j=0,src=MKPCHARP_STR(in); i < in->len; INC_PCHARP(src,1),i++) { +  unsigned INT32 c = EXTRACT_PCHARP(src);    if (!(c & ~0x7f)) {    /* 7bit */    out->str[j++] = c;    } else if (!(c & ~0x7ff)) {    /* 11bit */    out->str[j++] = 0xc0 | (c >> 6);    out->str[j++] = 0x80 | (c & 0x3f);    } else if (!(c & ~0xffff)) {    /* 16bit */    out->str[j++] = 0xe0 | (c >> 12);
pike.git/src/builtin_functions.c:2077:    *! @endint    *!    *! @note    *! Throws an error if the stream is not a legal UTF-8 byte-stream.    *!    *! @note    *! In conformance with RFC 3629 and Unicode 3.1 and later,    *! non-shortest forms are not decoded. An error is thrown instead.    *!    *! @seealso -  *! @[Locale.Charset.encoder()], @[string_to_unicode()], @[string_to_utf8()], +  *! @[Charset.encoder()], @[string_to_unicode()], @[string_to_utf8()],    *! @[unicode_to_string()]    */   PMOD_EXPORT void f_utf8_to_string(INT32 args)   {    struct pike_string *in;    struct pike_string *out;    ptrdiff_t len = 0;    int shift = 0;    ptrdiff_t i,j=0;    INT_TYPE extended = 0; -  +  INT32 min, max;       get_all_args("utf8_to_string", args, "%S.%i", &in, &extended);    -  +  check_string_range(in, 1, &min, &max); +  +  if (min >= 0 && max <= 0x7f) { +  /* 7bit string -- already valid utf8. */ +  pop_n_elems(args - 1); +  return; +  } +     for(i=0; i < in->len; i++) {    unsigned int c = STR0(in)[i];    len++;    if (c & 0x80) {    int cont = 0;       /* From table 3-6 in the Unicode standard 4.0: Well-Formed UTF-8    * Byte Sequences    *    * Code Points 1st Byte 2nd Byte 3rd Byte 4th Byte
pike.git/src/builtin_functions.c:2995:    pop_n_elems(args);    push_float( - (FLOAT_TYPE)tmp.tv_sec-((FLOAT_TYPE)tmp.tv_usec)/1000000 );    return;    }    }    pop_n_elems(args);    INACCURATE_GETTIMEOFDAY(&ret);    push_int(ret.tv_sec);   }    - /*! @decl string crypt(string password) + /*! @decl string(0..127) crypt(string password)    *! @decl int(0..1) crypt(string typed_password, string crypted_password)    *!    *! This function crypts and verifies a short string (only the first    *! 8 characters are significant).    *!    *! The first syntax crypts the string @[password] into something that    *! is hopefully hard to decrypt.    *!    *! The second syntax is used to verify @[typed_password] against    *! @[crypted_password], and returns @expr{1@} if they match, and
pike.git/src/builtin_functions.c:3211:    }    pop_n_elems(args);    push_array(a);   }      /* this should probably be moved to pike_types.c or something */   #define FIX_OVERLOADED_TYPE(n, lf, X) fix_overloaded_type(n,lf,X,CONSTANT_STRLEN(X))   /* FIXME: This function messes around with the implementation of pike_type,    * and should probably be in pike_types.h instead.    */ - static node *fix_overloaded_type(node *n, int lfun, const char *deftype, int deftypelen) + static node *fix_overloaded_type(node *n, int lfun, const char *deftype, int UNUSED(deftypelen))   {    node **first_arg;    struct pike_type *t, *t2;    first_arg=my_get_arg(&_CDR(n), 0);    if(!first_arg) return 0;    t=first_arg[0]->type;    if(!t || match_types(t, object_type_string))    {    /* Skip any name-nodes. */    while(t && t->type == PIKE_T_NAME) {
pike.git/src/builtin_functions.c:4590:    *!    *! @seealso    *! @[mappingp()], @[programp()], @[arrayp()], @[stringp()], @[functionp()],    *! @[multisetp()], @[floatp()], @[intp()]    */   PMOD_EXPORT void f_objectp(INT32 args)   {    if(args<1)    SIMPLE_TOO_FEW_ARGS_ERROR("objectp", 1);    if(TYPEOF(Pike_sp[-args]) != T_OBJECT || !Pike_sp[-args].u.object->prog - #ifdef AUTO_BIGNUM -  || is_bignum_object(Pike_sp[-args].u.object) - #endif -  ) +  || is_bignum_object(Pike_sp[-args].u.object))    {    pop_n_elems(args);    push_int(0);    }else{    pop_n_elems(args);    push_int(1);    }   }      /*! @decl int functionp(mixed arg)
pike.git/src/builtin_functions.c:7681:    *! @seealso    *! @[_next()], @[_prev()]    */   PMOD_EXPORT void f__refs(INT32 args)   {    INT32 i;       if(!args)    SIMPLE_TOO_FEW_ARGS_ERROR("_refs", 1);    -  if(TYPEOF(Pike_sp[-args]) > MAX_REF_TYPE) +  if(!REFCOUNTED_TYPE(TYPEOF(Pike_sp[-args])))    SIMPLE_BAD_ARG_ERROR("refs", 1,    "array|mapping|multiset|object|"    "function|program|string");       i=Pike_sp[-args].u.refs[0];    pop_n_elems(args);    push_int(i);   }      #ifdef PIKE_DEBUG   /* This function is for debugging *ONLY*    * do not document please. /Hubbe    */   PMOD_EXPORT void f__leak(INT32 args)   {    INT32 i;       if(!args)    SIMPLE_TOO_FEW_ARGS_ERROR("_leak", 1);    -  if(TYPEOF(Pike_sp[-args]) > MAX_REF_TYPE) +  if(!REFCOUNTED_TYPE(TYPEOF(Pike_sp[-args])))    SIMPLE_BAD_ARG_ERROR("_leak", 1,    "array|mapping|multiset|object|"    "function|program|string");       add_ref(Pike_sp[-args].u.dummy);    i=Pike_sp[-args].u.refs[0];    pop_n_elems(args);    push_int(i);   }   #endif
pike.git/src/builtin_functions.c:7768:    if(!new_master->prog)    bad_arg_error("replace_master", Pike_sp-args, args, 1, "object", Pike_sp-args,    "Called with destructed object.\n");       if (SUBTYPEOF(Pike_sp[-args]))    bad_arg_error("replace_master", Pike_sp-args, args, 1, "object", Pike_sp-args,    "Subtyped master objects are not supported yet.\n");       push_constant_text ("is_pike_master");    args++; -  object_set_index (new_master, 0, Pike_sp - 1, &svalue_int_one); +  object_set_index (new_master, 0, Pike_sp - 1, (struct svalue *) &svalue_int_one);       free_object(master_object);    master_object=new_master;    add_ref(master_object);       free_program(master_program);    master_program=master_object->prog;    add_ref(master_program);       pop_n_elems(args);
pike.git/src/builtin_functions.c:8389: Inside #if defined(PIKE_DEBUG)
   *! @note    *! This function only exists if the Pike runtime has been compiled    *! with RTL debug.    */   PMOD_EXPORT void f__gc_set_watch(INT32 args)   {    ASSERT_SECURITY_ROOT("_gc_set_watch");       if (args < 1)    SIMPLE_TOO_FEW_ARGS_ERROR("_gc_set_watch", 1); -  if (TYPEOF(Pike_sp[-args]) > MAX_REF_TYPE) +  if (!REFCOUNTED_TYPE(TYPEOF(Pike_sp[-args])))    SIMPLE_BAD_ARG_ERROR("_gc_set_watch", 1, "reference type");    gc_watch(Pike_sp[-args].u.refs);    pop_n_elems(args);   }      /*! @decl void dump_backlog()    *! @belongs Debug    *!    *! Dumps the 1024 latest executed opcodes, along with the source    *! code lines, to standard error. The backlog is only collected on
pike.git/src/builtin_functions.c:9157:       get_all_args("enumerate", args, "%i%i%i", &n, &step, &start);    if (n<0)    SIMPLE_BAD_ARG_ERROR("enumerate",1,"int(0..)");       pop_n_elems(args);    push_array(d=allocate_array(n));    for (i=0; i<n; i++)    {    ITEM(d)[i].u.integer=start; - #ifdef AUTO_BIGNUM +     if ((step>0 && start+step<start) ||    (step<0 && start+step>start)) /* overflow */    {    pop_stack();    push_int(n);    push_int(step);    convert_stack_top_to_bignum();    push_int(start);    convert_stack_top_to_bignum();    f_enumerate(3);    return;    } - #endif +     start+=step;    }    d->type_field = BIT_INT;    }    else if (args<=3 &&    ((TYPEOF(Pike_sp[1-args]) == T_INT ||    TYPEOF(Pike_sp[1-args]) == T_FLOAT) &&    (TYPEOF(Pike_sp[2-args]) == T_INT ||    TYPEOF(Pike_sp[2-args]) == T_FLOAT) ) )    {
pike.git/src/builtin_functions.c:9533:    ADD_EFUN("allocate", f_allocate,    tFunc(tInt tOr(tVoid,tSetvar(0,tMix)),tArr(tVar(0))), 0);      /* function(mixed:int) */    ADD_EFUN("arrayp", f_arrayp,tFunc(tMix,tInt01),0);      /* function(string...:string) */    ADD_EFUN("combine_path_nt",f_combine_path_nt,tFuncV(tNone,tStr,tStr),0);    ADD_EFUN("combine_path_unix",f_combine_path_unix,tFuncV(tNone,tStr,tStr),0);    ADD_EFUN("combine_path_amigaos",f_combine_path_amigaos,tFuncV(tNone,tStr,tStr),0); - #ifdef __NT__ + #if defined(__NT__) || defined(__OS2__)    ADD_EFUN("combine_path",f_combine_path_nt,tFuncV(tNone,tStr,tStr),0);   #else   #ifdef __amigaos__    ADD_EFUN("combine_path",f_combine_path_amigaos,tFuncV(tNone,tStr,tStr),0);   #else    ADD_EFUN("combine_path",f_combine_path_unix,tFuncV(tNone,tStr,tStr),0);   #endif   #endif       ADD_EFUN("compile", f_compile,    tFunc(tStr tOr(tObj, tVoid) tOr(tInt, tVoid) tOr(tInt, tVoid) tOr(tPrg(tObj), tVoid) tOr(tObj, tVoid) ,tPrg(tObj)),    OPT_EXTERNAL_DEPEND);      /* function(1=mixed:1) */    ADD_EFUN("copy_value",f_copy_value,tFunc(tSetvar(1,tMix),tVar(1)),0);      /* function(string:string)|function(string,string:int) */    ADD_EFUN("crypt",f_crypt, -  tOr(tFunc(tStr,tStr),tFunc(tStr tStr,tInt01)),OPT_EXTERNAL_DEPEND); +  tOr(tFunc(tStr,tStr7),tFunc(tStr tStr,tInt01)),OPT_EXTERNAL_DEPEND);      /* function(object|void:void) */    ADD_EFUN("destruct",f_destruct,tFunc(tOr(tObj,tVoid),tVoid),OPT_SIDE_EFFECT);      /* function(mixed,mixed:int) */    ADD_EFUN("equal",f_equal,tFunc(tMix tMix,tInt01),OPT_TRY_OPTIMIZE);       /* function(array(0=mixed),int|void,int|void:array(0)) */    ADD_FUNCTION2("everynth",f_everynth,    tFunc(tArr(tSetvar(0,tMix)) tOr(tInt,tVoid) tOr(tInt,tVoid),