pike.git / src / builtin.cmod

version» Context lines:

pike.git/src/builtin.cmod:3015:    if( Pike_fp->current_object->refs != 1 )    f_Buffer_get_copy( 0 );    else    f_Buffer_get( 0 );    o_cast_to_int( );    return;    }    Pike_error("Cannot cast to %S\n", type);    }    -  /*! @decl String.Buffer `+( string what ) +  /*! @decl String.Buffer `+( string|String.Buffer what )    */ -  PIKEFUN object `+( string what ) +  PIKEFUN object `+( string|Buffer what ) +  rawtype tFunc(tOr(tString, tObjIs_BUFFER), tObjIs_BUFFER);    {    struct Buffer_struct *str = THIS, *str2;    struct object *res = fast_clone_object( Buffer_program );    str2 = OBJ2_BUFFER( res );    str2->initial = str->initial;    if( str->str.s )    init_string_builder_copy (&str2->str, &str->str);    apply( res, "add", 1 );    RETURN res;    }    -  /*! @decl String.Buffer `+=( string what ) +  /*! @decl String.Buffer `+=( string|String.Buffer what )    */ -  PIKEFUN object `+=( string what ) +  PIKEFUN object `+=( string|Buffer what ) +  rawtype tFunc(tOr(tString, tObjIs_BUFFER), tObjIs_BUFFER);    {    f_Buffer_add( 1 );    REF_RETURN Pike_fp->current_object;    }    -  /*! @decl int add(string ... data) +  /*! @decl int add(string|String.Buffer ... data)    *!    *! Adds @[data] to the buffer.    *!    *! @returns    *! Returns the size of the buffer.    *! -  +  *! @note +  *! Pike 7.8 and earlier did not support adding @[String.Buffer]s +  *! directly. +  *!    *! @seealso    *! @[addat()]    */ -  PIKEFUN int add( string ... arg1 ) +  PIKEFUN int add( string|Buffer ... arg1 ) +  rawtype tFuncV(tNone, tOr(tString, tObjIs_BUFFER), tIntPos);    {    struct Buffer_struct *str = THIS;    int init_from_arg0 = 0, j;       if (!str->str.s && args) {    ptrdiff_t sum = 0;    int shift = 0;    for (j=0; j < args; j++) { -  struct pike_string *a = Pike_sp[j-args].u.string; +  struct pike_string *a; +  if (TYPEOF(Pike_sp[j-args]) == PIKE_T_STRING) { +  a = Pike_sp[j-args].u.string; +  } else if ((TYPEOF(Pike_sp[j-args]) != PIKE_T_OBJECT) || +  (Pike_sp[j-args].u.object->prog != Buffer_program)) { +  SIMPLE_BAD_ARG_ERROR("add", j+1, "string|String.Buffer"); +  } else { +  a = OBJ2_BUFFER(Pike_sp[j-args].u.object)->str.s; +  if (!a) continue; +  }    sum += a->len;    shift |= a->size_shift;    }    if (sum < str->initial)    sum = str->initial;    else if (sum > str->initial)    sum <<= 1;    shift = shift & ~(shift >> 1);    -  if (shift == Pike_sp[-args].u.string->size_shift && +  if ((TYPEOF(Pike_sp[-args]) == PIKE_T_STRING) && +  (shift == Pike_sp[-args].u.string->size_shift) &&    init_string_builder_with_string (&str->str, Pike_sp[-args].u.string)) {    mark_free_svalue (Pike_sp - args);    if (sum > str->str.s->len)    string_build_mkspace (&str->str, sum - str->str.s->len, shift);    init_from_arg0 = 1;    }    else    init_string_builder_alloc(&str->str, sum, shift);       /* We know it will be a string that really is this wide. */    str->str.known_shift = shift;    }       for( j = init_from_arg0; j<args; j++ )    { -  struct pike_string *a = Pike_sp[j-args].u.string; +  struct pike_string *a; +  if (TYPEOF(Pike_sp[j-args]) == PIKE_T_STRING) { +  a = Pike_sp[j-args].u.string; +  } else { +  a = OBJ2_BUFFER(Pike_sp[j-args].u.object)->str.s; +  if (!a) continue; +  }    string_builder_shared_strcat( &str->str, a );    }       if (str->str.s) {    RETURN str->str.s->len;    } else {    RETURN 0;    }    }    -  /*! @decl int addat(int(0..) pos, string ... data) +  /*! @decl int addat(int(0..) pos, string|String.Buffer ... data)    *!    *! Adds @[data] to the buffer, starting at position @[pos].    *!    *! @returns    *! Returns the size of the buffer.    *!    *! @note -  *! If the buffer isn't of the required size, it is padded +  *! If the buffer isn't of the required size, it will be padded    *! with NUL-characters.    *! -  +  *! @note +  *! Pike 7.8 and earlier did not support adding @[String.Buffer]s +  *! directly. +  *!    *! @seealso    *! @[add()]    */    PIKEFUN int addat(int(0..) pos, string ... arg1 ) -  +  rawtype tFuncV(tNone, tOr(tString, tObjIs_BUFFER), tIntPos);    {    struct Buffer_struct *str = THIS;       if (pos < 0)    SIMPLE_BAD_ARG_ERROR("addat", 1, "int(0..)");       if (args) {    int init_from_arg0 = 0, j;    ptrdiff_t sum = 0;    int shift = 0;    for (j=1; j < args; j++) { -  struct pike_string *a = Pike_sp[j-args].u.string; +  struct pike_string *a; +  if (TYPEOF(Pike_sp[j-args]) == PIKE_T_STRING) { +  a = Pike_sp[j-args].u.string; +  } else if ((TYPEOF(Pike_sp[j-args]) != PIKE_T_OBJECT) || +  (Pike_sp[j-args].u.object->prog != Buffer_program)) { +  SIMPLE_BAD_ARG_ERROR("addat", j+1, "string|String.Buffer"); +  } else { +  a = OBJ2_BUFFER(Pike_sp[j-args].u.object)->str.s; +  if (!a) continue; +  }    sum += a->len;    shift |= a->size_shift;    }       if (!str->str.s) {    if ((sum + pos) <= str->initial) {    sum = str->initial;    } else {    sum <<= 1;    sum += pos;
pike.git/src/builtin.cmod:3154:    /* We know it will be a string that really is this wide. */    str->str.known_shift = shift;       if (str->str.s->len < pos) {    /* Clear the padding. */    MEMSET(str->str.s->str + (str->str.s->len << str->str.s->size_shift),    0, (pos - str->str.s->len) << str->str.s->size_shift);    }       for(j = 1; j<args; j++) { -  struct pike_string *a = Pike_sp[j-args].u.string; +  struct pike_string *a; +  if (TYPEOF(Pike_sp[j-args]) == PIKE_T_STRING) { +  a = Pike_sp[j-args].u.string; +  } else { +  a = OBJ2_BUFFER(Pike_sp[j-args].u.object)->str.s; +  if (!a) continue; +  }    pike_string_cpy(MKPCHARP_STR_OFF(str->str.s, pos), a);    pos += a->len;    }       if (str->str.s->len < pos) {    str->str.s->len = pos;    /* Ensure NUL-termination */    str->str.s->str[str->str.s->len << str->str.s->size_shift] = 0;    }    }
pike.git/src/builtin.cmod:3204:    if(!str->str.s)    init_string_builder_alloc(&str->str, str->initial, 0);    low_f_sprintf(args, 0, &str->str);    RETURN str->str.s->len;    }       /*! @decl string get_copy()    *!    *! Get the data from the buffer. Significantly slower than @[get],    *! but does not clear the buffer. +  *! +  *! @seealso +  *! @[get()]    */    PIKEFUN string get_copy()    {    struct pike_string *str = THIS->str.s;    if( str )    {    ptrdiff_t len = str->len;    if( len > 0 )    {    char *d = (char *)str->str;
pike.git/src/builtin.cmod:3238:    push_empty_string();    return;    }       /*! @decl string get()    *!    *! Get the data from the buffer.    *!    *! @note    *! This will clear the data in the buffer +  *! +  *! @seealso +  *! @[get_copy()], @[clear()]    */    PIKEFUN string get( )    {    struct Buffer_struct *str = THIS;    if( str->str.s )    {    struct pike_string *s = finish_string_builder( &str->str );    str->str.malloced = 0;    str->str.s = NULL;    RETURN s;    }    pop_n_elems(args);    push_empty_string();    return;    }    -  +  /*! @decl void clear() +  *! +  *! Empty the buffer, and don't care about the old content. +  *! +  *! @note +  *! This function was not available in Pike 7.8 and earlier. +  *! +  *! @seealso +  *! @[get()] +  */ +  PIKEFUN void clear() +  { +  /* FIXME: Support resetting the initial size? */ +  struct Buffer_struct *str = THIS; +  if (str->str.s) { +  /* FIXME: There's also the alternative of using +  * reset_string_builder() here. +  */ +  free_string_builder(&str->str); +  str->str.s = NULL; +  } +  } +     /*! @decl int _sizeof()    *!    *! Returns the size of the buffer.    */    PIKEFUN int _sizeof()    {    struct Buffer_struct *str = THIS;    RETURN str->str.s ? str->str.s->len : 0;    }