pike.git / src / builtin_functions.c

version» Context lines:

pike.git/src/builtin_functions.c:898:    *!    *! @seealso    *! @[call_function()]    */   void f_query_num_arg(INT32 args)   {    pop_n_elems(args);    push_int(Pike_fp ? Pike_fp->args : 0);   }    - /*! @decl int search(string haystack, string|int needle, int|void start) -  *! @decl int search(array haystack, mixed needle, int|void start) + /*! @decl int search(string haystack, string|int needle, int|void start, @ +  *! int|void end) +  *! @decl int search(array haystack, mixed needle, int|void start, int|void end)    *! @decl mixed search(mapping haystack, mixed needle, mixed|void start)    *! @decl mixed search(object haystack, mixed needle, mixed|void start, @    *! mixed ... extra_args)    *!    *! Search for @[needle] in @[haystack].    *!    *! @param haystack    *! Item to search in. This can be one of:    *! @mixed    *! @type string
pike.git/src/builtin_functions.c:941:    *! elements with @[`==()] until a match with @[needle] is found.    *! If @[needle] is found @[haystack] will be advanced to the element,    *! and the iterator index will be returned. If @[needle] is not    *! found, @[haystack] will be advanced to the end.    *! @endmixed    *!    *! @param start    *! If the optional argument @[start] is present search is started at    *! this position. This has no effect on mappings.    *! +  *! @param end +  *! If the optional argument @[end] is present, the search will terminate +  *! at this position if not found earlier. +  *!    *! @returns    *! Returns the position of @[needle] in @[haystack] if found.    *!    *! If not found the returned value depends on the type of @[haystack]:    *! @mixed    *! @type string|array    *! @expr{-1@}.    *! @type mapping|object(Iterator)    *! @[UNDEFINED].    *! @type object
pike.git/src/builtin_functions.c:970:    *! For mappings and object @[UNDEFINED] will be returned when not found.    *! In all other cases @expr{-1@} will be returned when not found.    *!    *! @seealso    *! @[indices()], @[values()], @[zero_type()], @[has_value()],    *! @[has_prefix()], @[has_suffix()]    */   PMOD_EXPORT void f_search(INT32 args)   {    ptrdiff_t start; +  ptrdiff_t end;       if(args < 2)    SIMPLE_WRONG_NUM_ARGS_ERROR("search", 2);       switch(TYPEOF(Pike_sp[-args]))    {    case T_STRING:    {    struct pike_string *haystack = Pike_sp[-args].u.string;       start=0; -  +  end = haystack->len;    if(args > 2)    {    if(TYPEOF(Pike_sp[2-args]) != T_INT)    SIMPLE_ARG_TYPE_ERROR("search", 3, "int");       start=Pike_sp[2-args].u.integer;    if(start<0) {    bad_arg_error("search", Pike_sp-args, args, 3, "int(0..)", Pike_sp+2-args,    "Start must be greater or equal to zero.\n");    } -  +  +  if (args > 3) { +  if(TYPEOF(Pike_sp[3-args]) != T_INT) +  SIMPLE_ARG_TYPE_ERROR("search", 4, "int"); +  +  if (Pike_sp[3-args].u.integer < end) { +  end = Pike_sp[3-args].u.integer; +  if(start<0) { +  bad_arg_error("search", Pike_sp-args, args, 4, "int(0..)", +  Pike_sp+3-args, +  "End must be greater or equal to zero.\n");    } -  +  } +  } +  }       if(haystack->len < start)    bad_arg_error("search", Pike_sp-args, args, 3, "int(0..)", Pike_sp-args,    "Start must not be greater than the "    "length of the string.\n");    -  +  if (end <= start) { +  pop_n_elems(args); +  push_int(-1); +  return; +  } +     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);    }   
pike.git/src/builtin_functions.c:1022:    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) { +  while (start < end) {    if (str[start] == val) break;    start++;    }    }    break;    case 1:    {    p_wchar1 *str = STR1(haystack);    if (val >= 65536) {    start = -1;    break;    } -  while (start < haystack->len) { +  while (start < end) {    if (str[start] == val) break;    start++;    }    }    break;    case 2:    {    p_wchar2 *str = STR2(haystack); -  while (start < haystack->len) { +  while (start < end) {    if (str[start] == (p_wchar2)val) break;    start++;    }    }    break;    } -  if (start >= haystack->len) { -  start = -1; -  } +     } else if(TYPEOF(Pike_sp[1-args]) == T_STRING) {    /* Handle searching for the empty string. */    if (Pike_sp[1-args].u.string->len) {    start = string_search(haystack,    Pike_sp[1-args].u.string,    start);    }    } else {    SIMPLE_ARG_TYPE_ERROR("search", 2, "string | int");    }    pop_n_elems(args); -  +  if (start >= end) { +  start = -1; +  }    push_int64(start);    break;    }       case T_ARRAY:    start=0; -  +  end = Pike_sp[-args].u.array->size;    if(args > 2)    {    if(TYPEOF(Pike_sp[2-args]) != T_INT)    SIMPLE_ARG_TYPE_ERROR("search", 3, "int");       start=Pike_sp[2-args].u.integer;    if(start<0) {    bad_arg_error("search", Pike_sp-args, args, 3, "int(0..)", Pike_sp+2-args,    "Start must be greater or equal to zero.\n");    } -  +  +  if (args > 3) { +  if(TYPEOF(Pike_sp[3-args]) != T_INT) +  SIMPLE_ARG_TYPE_ERROR("search", 4, "int"); +  +  if (Pike_sp[3-args].u.integer < end) { +  end = Pike_sp[3-args].u.integer; +  if(end<0) { +  bad_arg_error("search", Pike_sp-args, args, 4, "int(0..)", +  Pike_sp+3-args, +  "End must be greater or equal to zero.\n");    } -  +  } +  } +  }    start=array_search(Pike_sp[-args].u.array,Pike_sp+1-args,start);    pop_n_elems(args); -  +  if (start >= end) { +  start = -1; +  }    push_int64(start);    break;       case T_MAPPING:    if(args > 2) {    mapping_search_no_free(Pike_sp,Pike_sp[-args].u.mapping,Pike_sp+1-args,Pike_sp+2-args);    } else {    mapping_search_no_free(Pike_sp,Pike_sp[-args].u.mapping,Pike_sp+1-args,0);    }    free_svalue(Pike_sp-args);
pike.git/src/builtin_functions.c:9545:    tOr6(tFunc(tMap(tSetvar(0,tMix),tSetvar(1,tMix)) tArr(tVar(0)),    tArr(tVar(1))),    tFunc(tSet(tSetvar(0,tMix)) tArr(tVar(0)), tArr(tInt01)),    tFunc(tString tArr(tInt), tArr(tInt)),    tFunc(tArr(tSetvar(0,tMix)) tArr(tInt), tArr(tVar(1))),    tFunc(tArray tArr(tNot(tInt)), tArray),    tFunc(tOr4(tObj,tFunction,tPrg(tObj),tInt) tArray, tArray)), 0);       /* FIXME: Is the third arg a good idea when the first is a mapping? */    ADD_EFUN("search",f_search, -  tOr4(tFunc(tStr tOr(tStr,tInt) tOr(tVoid,tInt), +  tOr4(tFunc(tStr tOr(tStr,tInt) tOr(tVoid,tInt) tOr(tVoid,tInt),    tInt), -  tFunc(tArr(tSetvar(0,tMix)) tVar(0) tOr(tVoid,tInt), +  tFunc(tArr(tSetvar(0,tMix)) tVar(0) tOr(tVoid,tInt) tOr(tVoid,tInt),    tInt),    tFunc(tMap(tSetvar(1,tMix),tSetvar(2,tMix)) tVar(2)    tOr(tVoid,tVar(1)), tVar(1)),    tFuncV(tObj tMix tOr(tVoid, tSetvar(3, tMix)), tMix, tVar(3))),    0);       ADD_EFUN2("has_prefix", f_has_prefix, tFunc(tOr(tStr,tObj) tStr,tInt01),    OPT_TRY_OPTIMIZE, 0, 0);       ADD_EFUN2("has_suffix", f_has_suffix, tFunc(tStr tStr,tInt01),