Branch: Tag:

2017-02-15

2017-02-15 12:04:42 by Henrik Grubbström (Grubba) <grubba@grubba.org>

search: Added end argument for the string and array cases.

905:    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)
948:    *! 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.    *!
977:   PMOD_EXPORT void f_search(INT32 args)   {    ptrdiff_t start; +  ptrdiff_t end;       if(args < 2)    SIMPLE_WRONG_NUM_ARGS_ERROR("search", 2);
988:    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)
998:    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))) {
1029:    start = -1;    break;    } -  while (start < haystack->len) { +  while (start < end) {    if (str[start] == val) break;    start++;    }
1042:    start = -1;    break;    } -  while (start < haystack->len) { +  while (start < end) {    if (str[start] == val) break;    start++;    }
1051:    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) {
1072:    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)
1088:    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;   
9552:       /* 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)),