pike.git
/
src
/
builtin.cmod
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/builtin.cmod:19:
#include "pike_types.h" #include "pike_memory.h" #include "threads.h" #include "module_support.h" #include "cyclic.h" #include "bignum.h" #include "main.h" #include "operators.h" #include "builtin_functions.h" #include "fsort.h"
-
#include "port.h"
+
#include "gc.h" #include "block_allocator.h" #include "pikecode.h" #include "opcodes.h" #include "whitespace.h" #include <ctype.h> #include <errno.h> #include <math.h>
-
+
#include <arpa/inet.h>
DECLARATIONS /*! @module System */
-
#if defined(HAVE_MKTIME) && defined(HAVE_GMTIME) && defined(HAVE_LOCALTIME)
+
/*! @class TM *! A wrapper for the system struct tm time keeping structure. *! This can be used as a (very) lightweight alternative to Calendar. */ PIKECLASS TM { CVAR struct tm t; CVAR time_t unix_time; CVAR int modified; CVAR struct pike_string *set_zone;
pike.git/src/builtin.cmod:182:
*/ PIKEFUN int(0..1) strptime( string(1..255) format, string(1..255) data ) { if( format->size_shift || data->size_shift ) Pike_error("Only 8bit strings are supported\n"); THIS->modified = 1; if( strptime_zone( data->str, format->str, &THIS->t ) == NULL ) RETURN 0; RETURN 1; }
-
#endif
+
#endif
/* HAVE_STRPTIME */
/*! @decl string(1..255) strftime( string(1..255) format ) *! See also @[Gettext.setlocale] *! *! Convert the structure to a string. *! *! @dl *! @item %a *! The abbreviated weekday name according to the current locale *! *! @item %A
pike.git/src/builtin.cmod:349:
*! When read the fields are always normalized. *! *! Unlike the system struct tm the 'year' field is not year-1900, *! instead it is the actual year. */ PIKEFUN int(0..60) `sec() { FIX_THIS();RETURN THIS->t.tm_sec; } PIKEFUN int(0..59) `min() { FIX_THIS();RETURN THIS->t.tm_min; } PIKEFUN int(0..23) `hour() { FIX_THIS();RETURN THIS->t.tm_hour; } PIKEFUN int(1..31) `mday() { FIX_THIS();RETURN THIS->t.tm_mday; } PIKEFUN int(0..11) `mon() { FIX_THIS();RETURN THIS->t.tm_mon; }
-
PIKEFUN int `year() { FIX_THIS();RETURN THIS->t.tm_year+1900; }
+
-
+
PIKEFUN int `year() { FIX_THIS();RETURN THIS->t.tm_year+1900; }
PIKEFUN int `sec=(int a) { MODIFY(tm_sec=a); } PIKEFUN int `min=(int a) { MODIFY(tm_min=a); } PIKEFUN int `hour=(int a){ MODIFY(tm_hour=a); } PIKEFUN int `mday=(int a){ MODIFY(tm_mday=a); } PIKEFUN int `year=(int a){ MODIFY(tm_year=a-1900); } PIKEFUN int `mon=(int a){ MODIFY(tm_mon=a); } /*! @decl int isdst *! *! True if daylight savings are in effect. If this field is -1
pike.git/src/builtin.cmod:444:
Pike_error("Can not format as %c", flag ); } if( post_sum ) { push_static_text(")"); f_add(3); } }
-
PIKEFUN
mixed
cast( string to )
+
/*! @decl int|string cast(string to)
+
*!
+
*! Casted to an integer @[unix_time] will be returned.
+
*!
+
*! Casting to a string will call @[asctime].
+
*/
+
PIKEFUN
int|string
cast( string to )
flags ID_PROTECTED; { if( to == literal_int_string ) { f_TM_unix_time(0); return; } if( to == literal_string_string ) { f_TM_asctime(0);
pike.git/src/builtin.cmod:601:
free_string( THIS->set_zone ); } } /*! @endclass */ #undef FIX_THIS #ifdef STRUCT_TM_HAS___TM_GMTOFF #undef tm_zone #undef tm_gmtoff #endif
-
#endif
+
/*! @endmodule */ /*! @decl array(array(int|string|type)) describe_program(program p) *! @belongs Debug *! *! Debug function for showing the symbol table of a program. *! *! @returns *! Returns an array of arrays with the following information
pike.git/src/builtin.cmod:749:
*! *! Same as sprintf("%c",x); *! *! @seealso *! @[sprintf()] */ PMOD_EXPORT PIKEFUN string int2char(int|object x) efun; optflags OPT_TRY_OPTIMIZE;
+
rawtype tFunc(tSetvar(0, tOr(tInt,tObj)), tNStr(tVar(0)));
{ int c; struct program *p; if(TYPEOF(*x) == T_OBJECT && (p = x->u.object->prog)) { ptrdiff_t fun = FIND_LFUN(p->inherits[SUBTYPEOF(*x)].prog, LFUN__SPRINTF); if(fun != -1) { push_int('c'); f_aggregate_mapping(0);
pike.git/src/builtin.cmod:898:
/* 'A' - 'F' */ 10, 11, 12, 13, 14, 15, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 'a' - 'f' */ 10, 11, 12, 13, 14, 15, }; PMOD_EXPORT PIKEFUN string(0..255) string2hex(string s)
-
errname String.string2hex;
+
optflags OPT_TRY_OPTIMIZE; { struct pike_string *hex; unsigned char *p,*st = (unsigned char *)s->str; int i, l; if (s->size_shift) Pike_error("Bad argument 1 to string2hex(), expected 8-bit string.\n"); hex = begin_shared_string(2 * s->len);
pike.git/src/builtin.cmod:931:
/*! @decl string hex2string(string hex) *! @appears String.hex2string *! *! Convert a string of hexadecimal digits to binary data. *! *! @seealso *! @[string2hex()] */ PMOD_EXPORT PIKEFUN string(0..255) hex2string(string hex)
-
errname String.hex2string;
+
optflags OPT_TRY_OPTIMIZE; { struct pike_string *s; int tmp, i; unsigned char *p, *q = (unsigned char *)hex->str; int l = hex->len>>1; if(hex->size_shift) Pike_error("Only hex digits allowed.\n"); if(hex->len&1) Pike_error("Can't have odd number of digits.\n"); s = begin_shared_string(l);
pike.git/src/builtin.cmod:960:
/*! @decl array(int) range(string s) *! @appears String.range *! *! Returns the character range of a string in an array of two *! elements. The first element contains the lower bound and the *! second the upper. The precision is only 8 bits, so for wide *! strings only character blocks are known. */ PIKEFUN array(int) string_range(string s)
-
errname
String.
range;
+
errname range;
optflags OPT_TRY_OPTIMIZE; { int min, max; check_string_range(s, 0, &min, &max); pop_n_elems(args); push_int(min); push_int(max); f_aggregate(2); }
pike.git/src/builtin.cmod:1179:
*! @member function(int:void) "done_cb" *! This function is called when the gc is done and about to exit. *! The argument is the same value as will be returned by gc(). *! @endmapping *! *! @seealso *! @[gc], @[Debug.gc_status] */ PMOD_EXPORT PIKEFUN mapping(string:mixed) gc_parameters (void|mapping(string:mixed) params)
-
errname Pike.gc_parameters;
+
optflags OPT_SIDE_EFFECT; { struct pike_string *str; struct svalue *set; struct svalue get; if (!params) { push_mapping (allocate_mapping (6)); params = Pike_sp[-1].u.mapping; }
pike.git/src/builtin.cmod:1206:
else { \ GET; \ mapping_string_insert (params, str, &get); \ } \ } while (0) #define HANDLE_FLOAT_FACTOR(NAME, VAR) \ HANDLE_PARAM (NAME, { \ if (TYPEOF(*set) != T_FLOAT || \ set->u.float_number < 0.0 || set->u.float_number > 1.0) \
-
SIMPLE_BAD_ARG_ERROR ("
Pike.
gc_parameters", 1, \
+
SIMPLE_BAD_ARG_ERROR ("gc_parameters", 1,
\
"float between 0.0 and 1.0 for " NAME); \ VAR = DO_NOT_WARN ((double) set->u.float_number); \ }, { \ SET_SVAL(get, T_FLOAT, 0, float_number, \ DO_NOT_WARN ((FLOAT_TYPE) VAR)); \ }); HANDLE_PARAM ("enabled", { if (TYPEOF(*set) != T_INT || set->u.integer < -1 || set->u.integer > 1)
-
SIMPLE_BAD_ARG_ERROR ("
Pike.
gc_parameters", 1,
+
SIMPLE_BAD_ARG_ERROR ("gc_parameters", 1,
"integer in the range -1..1 for 'enabled'"); if (gc_enabled != set->u.integer) { if (gc_enabled > 0) { /* Disabling automatic gc - save the old alloc_threshold and set it to * the maximum value to avoid getting gc_evaluator_callback added. */ saved_alloc_threshold = alloc_threshold; alloc_threshold = GC_MAX_ALLOC_THRESHOLD; } else if (set->u.integer > 0) { /* Enabling automatic gc - restore the old alloc_threshold. If the
pike.git/src/builtin.cmod:1376:
*! occurs in the string @[haystack]. The special cases for the needle *! @expr{""@} is that it occurs one time in the empty string, zero *! times in a one character string and between every character *! (length-1) in any other string. *! *! @seealso *! @[search()], @[`/()] */ PMOD_EXPORT PIKEFUN int string_count(string haystack, string needle)
-
errname
String.
count;
+
errname count;
optflags OPT_TRY_OPTIMIZE; { ptrdiff_t c = 0; ptrdiff_t i, j; switch (needle->len) { case 0: switch (haystack->len) {
pike.git/src/builtin.cmod:1415:
RETURN DO_NOT_WARN((INT_TYPE)c); } /*! @decl string trim_whites (string s) *! @belongs String *! *! Trim leading and trailing spaces and tabs from the string @[s]. */ PMOD_EXPORT PIKEFUN string string_trim_whites (string s)
-
errname
String.
trim_whites;
+
errname trim_whites;
optflags OPT_TRY_OPTIMIZE; { ptrdiff_t start = 0, end = s->len; int chr; switch (s->size_shift) { #define DO_IT(TYPE) \ { \ for (; start < s->len; start++) { \ chr = ((TYPE *) s->str)[start]; \ if (chr != ' ' && chr != '\t') break; \
pike.git/src/builtin.cmod:1465:
*! @note *! Trailing and leading whitespace around \r and \n characters *! is stripped as well (only useful if they're not in the @[whitespace] set). *! *! @note *! This function is a lot faster with just one argument (i.e. the builtin *! whitespace set has an optimised code path). */ PMOD_EXPORT PIKEFUN string string_normalize_space (string s, string|void whitespace)
-
errname
String.
normalize_space;
+
errname normalize_space;
optflags OPT_TRY_OPTIMIZE; { size_t len = s->len, wlen; const void *src = s->str; unsigned shift = s->size_shift, replspace; const void *ws; void *wstemp = 0; struct string_builder sb; unsigned foundspace = 0;
pike.git/src/builtin.cmod:1596:
/*! @decl string trim_all_whites (string s) *! @belongs String *! *! Trim leading and trailing white spaces characters (space, tab, *! newline, carriage return, form feed, vertical tab and all the *! white spaces defined in Unicode) from the string @[s]. */ PMOD_EXPORT PIKEFUN string string_trim_all_whites (string s)
-
errname
String.
trim_all_whites;
+
errname trim_all_whites;
optflags OPT_TRY_OPTIMIZE; { ptrdiff_t start = 0, end = s->len; int chr; switch (s->size_shift) { #define DO_IT(TYPE,CASE) \ { \ for (; start < end; start++) { \ chr = ((TYPE *) s->str)[start]; \
pike.git/src/builtin.cmod:1648:
*! *! @note *! Currently returns the empty string (@expr{""@}) *! if @[verbose] is zero. *! *! @note *! The formatting and contents of the result *! may vary between different versions of Pike. */ PIKEFUN string string_status(int verbose)
-
errname
String.
status;
+
errname status;
{ RETURN add_string_status(verbose); } /*! @decl int implements(program prog, program api) *! @belongs Program *! *! Returns 1 if @[prog] implements @[api]. */ PMOD_EXPORT PIKEFUN int program_implements(program prog, program api)
-
errname
Program.
implements;
+
errname implements;
optflags OPT_TRY_OPTIMIZE; { RETURN implements(prog, api); } /*! @decl int inherits(program|object child, program parent) *! @belongs Program *! *! Returns 1 if @[child] has inherited @[parent]. */ PMOD_EXPORT PIKEFUN int program_inherits(program|object child, program parent)
-
errname
Program.
inherits;
+
errname inherits;
optflags OPT_TRY_OPTIMIZE; { struct program *p = program_from_svalue(child); if (!p)
-
SIMPLE_ARG_TYPE_ERROR("
Program.
inherits", 1, "program|object");
+
SIMPLE_ARG_TYPE_ERROR("inherits", 1, "program|object");
RETURN low_get_storage(p, parent) != -1; } /*! @decl string defined(program p) *! @belongs Program *! *! Returns a string with filename and linenumber describing where *! the program @[p] was defined. *! *! The returned string is of the format @expr{"filename:linenumber"@}. *! *! If it cannot be determined where the program was defined, @expr{0@} *! (zero) will be returned. */ PMOD_EXPORT PIKEFUN string program_defined(program p)
-
errname
Program.
defined;
+
errname defined;
optflags OPT_TRY_OPTIMIZE; { INT_TYPE line; struct pike_string *tmp = low_get_program_line(p, &line); pop_n_elems(args); if (tmp) { push_string(tmp); if(line >= 1)
pike.git/src/builtin.cmod:1740:
*! The string @[s] contains characters >= 65536. *! @endint *! *! @note *! It is possible that a future version of Pike may return *! further values. In particular the width @expr{7@} seems *! like it could be useful. */ PMOD_EXPORT PIKEFUN int(8 .. 8)|int(16 .. 16)|int(32 .. 32) string_width(string s)
-
errname
String.
width;
+
errname width;
optflags OPT_TRY_OPTIMIZE; { RETURN 8 * (1 << s->size_shift); } /*! @decl mixed m_delete(object|mapping map, mixed index) *! *! If @[map] is an object that implements @[lfun::_m_delete()], *! that function will be called with @[index] as its single argument. *!
pike.git/src/builtin.cmod:2201:
pop_stack(); push_int (0); } else { char *entry = getenv (var->str); pop_stack(); if (!entry) push_int (0); else {
-
char *eq =
STRCHR
(entry, '=');
+
char *eq =
strchr
(entry, '=');
/* There should always be a '=' in the entry, but you never know.. */ push_string (make_shared_string (eq ? eq + 1 : entry)); } } } else { #ifdef DECLARE_ENVIRON extern char **environ; #endif
pike.git/src/builtin.cmod:2229:
* one in gnu libc). */ for (n = 0; environ[n]; n++) {} m = allocate_mapping (n); #ifndef USE_SETENV if (env_allocs) new_env_allocs = allocate_mapping (m_sizeof (env_allocs)); #endif /* !USE_SETENV */ while (--n >= 0) {
-
char *entry = environ[n], *eq =
STRCHR
(entry, '=');
+
char *entry = environ[n], *eq =
strchr
(entry, '=');
if (eq) { /* gnu libc getenv ignores variables without '='. */ struct pike_string *var = make_shared_binary_string (entry, eq - entry); struct pike_string *val = make_shared_string (eq + 1); mapping_string_insert_string (m, var, val); #ifndef USE_SETENV /* Populate new_env_allocs with the env_allocs entries that * are still in use. */ if (env_allocs) { struct svalue *ea_val = low_mapping_string_lookup (env_allocs, var);
pike.git/src/builtin.cmod:2272:
* updates the real environment. Everyone should use the version in * the master instead so that the cache doesn't get stale. */ PIKEFUN void _putenv (string var, void|string val) { #ifndef USE_SETENV struct pike_string *putenv_str, *env_alloc_var; #endif if (var->size_shift) SIMPLE_ARG_TYPE_ERROR ("putenv", 1, "string(0..255)");
-
if (string_has_null (var) ||
STRCHR
(var->str, '='))
+
if (string_has_null (var) ||
strchr
(var->str, '='))
SIMPLE_ARG_ERROR ("putenv", 1, "Variable name cannot contain '=' or NUL."); if (val) { #ifndef USE_SETENV struct string_builder sb; #endif if (val->size_shift) SIMPLE_ARG_TYPE_ERROR ("putenv", 2, "void|string(0..255)"); if (string_has_null (val))
pike.git/src/builtin.cmod:2613:
push_int(3); } } /*! @decl mixed `[](int index, int|void end_or_none) *! The BacktraceFrame object can be indexed as an array. */ PIKEFUN mixed `[](int index, int|void end_or_none) { INT_TYPE end = index;
-
INT32 numargs =
0
;
+
INT32 numargs =
3
;
INT32 i;
-
if (THIS->args)
{
-
numargs = THIS->args->size;
-
}
+
if (THIS->args)
+
numargs
+
= THIS->args->size;
-
numargs += 3;
-
+
if (!end_or_none) {
-
if (index < 0)
{
+
if (index < 0)
index_error("pike_frame->`[]", Pike_sp-args, args, NULL, Pike_sp-args, "Indexing with negative index (%"PRINTPIKEINT"d)\n", index);
-
}
else if (index >= numargs)
{
+
else if (index >= numargs)
index_error("pike_frame->`[]", Pike_sp-args, args, NULL, Pike_sp-args, "Indexing with too large index (%"PRINTPIKEINT"d)\n", index);
-
}
-
}
else
{
-
if (TYPEOF(*end_or_none) != PIKE_T_INT) {
-
SIMPLE_BAD_ARG_ERROR("`[]",2,"int|void");
-
}
+
} else
end = end_or_none->u.integer;
-
}
+
pop_n_elems(args); if (end_or_none) { if ((end < 0) || (end < index) || (index >= numargs)) { f_aggregate(0); return; }
-
if (end >= numargs)
{
+
if (end >= numargs)
end = numargs-1; }
-
}
+
for (i = index; i <= end; i++) { switch(i) { case 0: /* Filename */ if (THIS->lineno == -1) fill_in_file_and_line();
-
if (THIS->filename)
{
+
if (THIS->filename)
ref_push_string(THIS->filename);
-
}
else
{
+
else
push_int(0);
-
}
+
break; case 1: /* Linenumber */ if (THIS->lineno == -1) fill_in_file_and_line(); push_int(THIS->lineno); break; case 2: /* Function */ push_svalue(&THIS->_fun); break; default: /* Arguments */ { if ((i > 2) && (THIS->args) && (i-3 < THIS->args->size)) { push_svalue(THIS->args->item + (i - 3)); break; }
-
bad_arg_error("
backtrace_frame->
`[]", Pike_sp-args, args, 1,
+
bad_arg_error("`[]", Pike_sp-args, args, 1,
"int(0..)", Pike_sp-args, "Bad argument 1 to backtrace_frame->`[](): " "Expected int(0..%d)\n", numargs + 2); } /* NOT_REACHED */ break; } }
-
if (end_or_none)
{
+
if (end_or_none)
f_aggregate(1 + end - index); }
-
}
+
/*! @decl mixed `[]=(int index, mixed value) */ PIKEFUN mixed `[]=(int index, mixed value) {
-
INT32 numargs =
0
;
+
INT32 numargs =
3
;
-
if (THIS->args)
{
-
numargs = THIS->args->size;
-
}
+
if (THIS->args)
+
numargs
+
= THIS->args->size;
-
numargs += 3;
-
-
if ((index < -numargs) || (index >= numargs))
{
+
if ((index < -numargs) || (index >= numargs))
index_error("pike_frame->`[]=", Pike_sp-args, args, NULL, Pike_sp-args, "Index %"PRINTPIKEINT"d is out of array range 0..%d,\n", index, numargs-1);
-
}
else if (index < 0)
{
+
else if (index < 0)
index += numargs;
-
}
+
if (args > 2) { pop_n_elems(args - 2); args = 2; } switch(index) { case 0: /* Filename */ if (THIS->lineno == -1) fill_in_file_and_line(); if (TYPEOF(*value) != PIKE_T_STRING) { if ((TYPEOF(*value) != PIKE_T_INT) || (value->u.integer)) {
-
SIMPLE_BAD_ARG_ERROR("
backtrace_frame->
`[]=", 2,
-
"string|int(0..0)");
+
SIMPLE_BAD_ARG_ERROR("`[]=", 2, "string|int(0..0)");
} if (THIS->filename) { free_string(THIS->filename); THIS->filename = NULL; } } else { if (THIS->filename) { free_string(THIS->filename); THIS->filename = NULL; } copy_shared_string(THIS->filename, value->u.string); } break; case 1: /* Linenumber */ if (THIS->lineno == -1) fill_in_file_and_line();
-
if (TYPEOF(*value) != PIKE_T_INT)
{
-
SIMPLE_BAD_ARG_ERROR("
backtrace_frame->
`[]=", 2, "int(1..)");
-
}
+
if (TYPEOF(*value) != PIKE_T_INT)
+
SIMPLE_BAD_ARG_ERROR("`[]=", 2, "int(1..)");
THIS->lineno = value->u.integer; break; case 2: /* Function */ if (THIS->lineno == -1) fill_in_file_and_line(); assign_svalue(&THIS->_fun, value); break; default: /* Arguments */ assign_svalue(THIS->args->item + index - 3, value); break;
pike.git/src/builtin.cmod:2957:
optflags OPT_EXTERNAL_DEPEND; { low_backtrace(& Pike_interpreter); } /*! @module String */ /*! @class Buffer *! A buffer, used for building strings. It's
-
*! conceptually similar to a string, but
you
can
only @[add]
-
*! strings
to it, and you can only @[get] the value from it once
.
+
*! conceptually similar to a string, but
speed-optimised
for
growing
+
*! strings.
*!
-
*! There is a reason for those seemingly rather odd limitations,
-
*! it makes it possible to do some optimizations that really speed
-
*! things up.
-
*!
+
*! You do not need to use this class unless you add very many *! strings together, or very large strings. *! *! @example *! For the fastest possible operation, write your code like this: *! *! @code *! String.Buffer b = String.Buffer( ); *! *! function add = b->add;
pike.git/src/builtin.cmod:2987:
*! string result = b->get(); // also clears the buffer *! @endcode */ PIKECLASS Buffer { CVAR struct string_builder str; CVAR int initial; PIKEFUN int _size_object() {
-
if( THIS->str.s )
+
RETURN THIS->str.malloced;
-
RETURN 0;
+
} void f_Buffer_get_copy( INT32 args ); void f_Buffer_get( INT32 args ); void f_Buffer_add( INT32 args );
-
/*! @decl void create(int initial_size)
+
/*! @decl void create(
void|
int
(1..)
initial_size)
*! *! Initializes a new buffer. *! *! If no @[initial_size] is specified, 256 is used. If you *! know approximately how big the buffer will be, you can optimize *! the operation of @[add()] (slightly) by passing the size to this *! function. */ PIKEFUN void create( int|void size ) { struct Buffer_struct *str = THIS;
-
if
(
size )
-
str->initial =
MAXIMUM(
size->u.integer,
512
)
;
-
else
-
str->initial = 256
;
+
init_string_builder_alloc
(
&str->str,
+
str->initial =
size ? MINIMUM
(size->u.integer,
1
)
:
256
,
0)
;
} /*! @decl string _sprintf( int flag, mapping flags ) *! It is possible to @[sprintf] a String.Buffer object
-
*! as @tt{%s@} just as if it
was
a string.
+
*! as @tt{%s@} just as if it
were
a string.
*/ PIKEFUN string _sprintf( int flag, mapping flags ) { switch( flag ) { case 'O': { struct pike_string *res; struct Buffer_struct *str = THIS; push_text( "Buffer(%d /* %d */)" );
-
if( str->str.s )
-
{
+
push_int(str->str.s->len); push_int(str->str.malloced);
-
}
-
else
-
{
-
push_int( 0 );
-
push_int( 0 );
-
}
+
f_sprintf( 3 ); dmalloc_touch_svalue(Pike_sp-1); res = Pike_sp[-1].u.string; Pike_sp--; RETURN res; } case 's': { pop_n_elems( args );
pike.git/src/builtin.cmod:3061:
} return; case 't': RETURN make_shared_binary_string("Buffer",6); } pop_n_elems( args ); push_undefined(); }
-
/*! @decl
mixed
cast( string type )
+
/*! @decl
string|int
cast( string type )
*! It is possible to cast a String.Buffer object to *! a @expr{string@} and an @expr{int@}. */
-
PIKEFUN
mixed
cast( string type )
+
PIKEFUN
string|int
cast( string type )
flags ID_PROTECTED; { if( type == literal_string_string ) { pop_stack(); if( Pike_fp->current_object->refs != 1 ) f_Buffer_get_copy( 0 ); else f_Buffer_get( 0 ); return;
pike.git/src/builtin.cmod:3094:
else f_Buffer_get( 0 ); o_cast_to_int( ); return; } pop_stack(); push_undefined(); }
-
/*! @decl
String.Buffer
`+
(
string|String.Buffer what
)
+
/*! @decl
int
`[]
(
int
index
)
*/
-
PIKEFUN object `+( string|Buffer what )
+
PIKEFUN
int `[](int index)
+
{
+
struct pike_string *s = THIS->str.s;
+
unsigned len = s->len;
+
+
if (index<0)
+
index += len;
+
if (index<0 || index>=len)
+
index_error("Buffer->`[]", Pike_sp, args, NULL, Pike_sp,
+
"Index %"PRINTPIKEINT"d is out of array range 0..%d,\n",
+
index, len-1);
+
RETURN generic_extract(s->str, s->size_shift, index);
+
}
+
+
/*! @decl Buffer `[..](int start, int start_type, int end, int end_type)
+
*/
+
PIKEFUN Buffer `[..](int start, int start_type, int end, int end_type)
+
{
+
struct Buffer_struct *str = THIS;
+
struct pike_string *s = str->str.s;
+
unsigned len = s->len, shift = s->size_shift;
+
char *p;
+
+
struct
object
*res;
+
struct Buffer_struct *str2;
+
+
pop_n_elems(args);
+
if (start_type == INDEX_FROM_END)
+
start = len-1-start;
+
if (end_type != INDEX_FROM_BEG)
+
end = len-1-end;
+
res = fast_clone_object( Buffer_program );
+
str2 = OBJ2_BUFFER( res );
+
if (start < 0)
+
start = 0;
+
if (end >= len)
+
end = len-1;
+
str2->initial = end -= start-1;
+
init_string_builder_alloc (&str2->str, end, shift);
+
p = s->str;
+
memcpy ((s = str2->str.s)->str, p+(start<<shift), end<<shift);
+
s->str[end<<shift] = 0; // Ensure NUL-termination
+
s->len = end;
+
if( (Pike_fp->current_object->flags & OBJECT_CLEAR_ON_EXIT) )
+
res->flags |= OBJECT_CLEAR_ON_EXIT;
+
push_object (res);
+
}
+
+
/*! @decl int `[]=(int index, int ch)
+
*/
+
PIKEFUN int `[]=(int index, int ch)
+
{
+
struct Buffer_struct *str = THIS;
+
struct pike_string *s = str->str.s;
+
unsigned len = s->len;
+
+
pop_n_elems(args);
+
+
if (index<0)
+
index += len;
+
if (index<0 || index>=len)
+
index_error("Buffer->`[]=", Pike_sp, args, NULL, Pike_sp,
+
"Index %"PRINTPIKEINT"d is out of array range 0..%d,\n",
+
index, len-1);
+
if ((unsigned)ch >= 256)
+
switch(s->size_shift) {
+
case 0:
+
if ((unsigned)ch < 65536)
+
len = 1;
+
else {
+
case 1:
+
if((unsigned)ch >= 65536)
+
len = 2;
+
else
+
break;
+
}
+
string_build_mkspace(&str->str, 0, str->str.known_shift = len);
+
}
+
low_set_index(str->str.s,index,ch);
+
push_int(ch);
+
}
+
+
/*! @decl Buffer
`+( string|Buffer what )
+
*/
+
PIKEFUN Buffer `+( 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); if( (Pike_fp->current_object->flags & OBJECT_CLEAR_ON_EXIT) ) res->flags |= OBJECT_CLEAR_ON_EXIT; apply( res, "add", 1 ); RETURN res; }
-
/*! @decl
String.
Buffer `+=( string|
String.
Buffer what )
+
/*! @decl Buffer `+=( string|Buffer what )
*/
-
PIKEFUN
object
`+=( string|Buffer what )
+
PIKEFUN
Buffer
`+=( 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
|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|Buffer ... arg1 )
-
rawtype tFuncV(tNone
,
tOr(tString, tObjIs_BUFFER
)
, tIntPos);
+
static
struct
pike_
string*
getotherstr
(
struct
svalue
*
other
,
unsigned
stricttype
)
{
-
struct Buffer_struct
*
str = THIS;
-
int init_from_arg0 = 0, j;
-
-
for (j=0; j < args; j++)
{
-
if
(TYPEOF(Pike_sp[j-args]) ==
PIKE_T_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"
);
+
switch(TYPEOF(
*
other))
+
{
+
case
PIKE_T_STRING
:
+
return
other
-
>u.string;
+
case
PIKE_T_OBJECT
:
+
if
(
other
-
>
u.object->prog =
=
Buffer_program)
+
return OBJ2
_
BUFFER
(
other->u
.
object
)
->str.s
;
}
-
+
if(stricttype)
+
Pike_error("Unsupported types in comparison.\n");
+
return 0;
}
-
if
(
!str->str
.
s
&&
args)
{
-
ptrdiff_t
sum
=
0;
-
int
shift
=
0;
-
for
(
j=
0
;
j
<
args;
j++
) {
+
/*!
@decl
int
(
0
.
.1)
`==(
mixed other
)
+
*!
+
*!
Is
able
to
compare
directly
with
strings
and
other
Buffers.
+
*/
+
PIKEFUN
int
(0
..1)
`==(
mixed
other
)
+
rawtype tFunc(tMixed, tInt01);
+
{
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
;
+
RETURN
((
a
=
getotherstr(other,0
)
)
?
!my
_
quick
_
strcmp
(
THIS
->str.s
,
a)
:
0
);
}
-
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
(
(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;
+
/*!
@decl
int(0..1)
`<(
mixed
other
)
+
*!
+
*!
Is
able
to
compare
directly
with
strings
and
other
Buffers.
+
*/
+
PIKEFUN
int
(
0
..
1
)
`<(
mixed
other
)
+
rawtype
tFunc
(
tMixed,
tInt01
);
+
{
+
RETURN
my
_
quick
_
strcmp
(
THIS
->str.s,
getotherstr(other,1
)
)<0
;
}
-
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++
)
+
/*!
@decl
int(0..1)
`>(
mixed
other
)
+
*!
+
*!
Is
able
to
compare
directly
with
strings
and
other Buffers
.
+
*/
+
PIKEFUN
int(0..1)
`>(
mixed
other
)
+
rawtype
tFunc(tMixed,
tInt01
)
;
{
-
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
;
+
RETURN
my
_
quick
_
strcmp
(
THIS
->str.s
,
getotherstr
(
other,1
)
)>0
;
}
-
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|
String.
Buffer ... data)
+
/*! @decl int addat(int(0..) pos, string|Buffer ... data)
*! *! Adds @[data] to the buffer, starting at position @[pos].
-
+
*! It overwrites existing content at that offset, never truncates the
+
*! buffer, possibly extends the buffer if the new content does not fit.
*! *! @returns *! Returns the size of the buffer. *! *! @note
-
*! If the
buffer
isn't
of
the
required
size,
it
will
be
padded
-
*! with NUL-characters.
+
*! If the
starting
position
@[pos]
extends
beyond
the
end
of
the
current
+
*!
buffer content, the gap will be filled
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);
+
PIKEFUN int addat(int(0..) pos, string
|Buffer
... arg1 )
+
rawtype tFuncV(
tIntPos
, tOr(tString, tObjIs_BUFFER), tIntPos);
{ struct Buffer_struct *str = THIS;
-
+
struct pike_string *s;
+
ptrdiff_t sum = 0;
+
int j,shift = 0;
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;
-
if (TYPEOF(Pike_sp[j-args]) == PIKE_T_STRING)
{
+
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))
{
+
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;
-
}
+
else
if(!(
a = OBJ2_BUFFER(Pike_sp[j-args].u.object)->str.s
))
+
continue;
sum += a->len; shift |= a->size_shift; }
-
if (!str->str.
s
)
{
-
if ((sum + pos) <
= str->
initial) {
-
sum =
str
->initial
;
-
} else {
-
sum <<= 1;
+
s
=
str->str.s;
sum += pos;
-
}
-
shift = shift & ~(shift >> 1);
-
-
init_string_builder_alloc(&str->str, sum, shift);
-
} else {
-
sum += pos;
+
shift |= str->str.known_shift; shift = shift & ~(shift >> 1);
-
if (
sum
> str
-
>str.
s->len
) {
-
string_build_mkspace(&str->str,
sum
-
str->
str.s-
>
len,
shift
)
;
-
}
else if (shift !
= str->
str.known_shift) {
-
string_build_mkspace(&str->str,
0
, shift);
+
j
=
sum
-
s->len
;
+
if
(j>0)
{
+
if
(
str->
initial
>
sum
)
+
j
= str->
initial-s->len;
+
string_build_mkspace(&str->str,
j
, shift);
}
-
}
+
else
if
(shift != str->str.known_shift)
+
string_build_mkspace(&str->str, 0, shift);
+
s = str->str.s;
/* 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);
-
}
+
if (s->len < pos)
/
/
Clear the padding
+
memset
(s->str + (s->len << s->size_shift),
+
0, (pos - s->len) << s->size_shift);
for(j = 1; j<args; j++) { struct pike_string *a;
-
if (TYPEOF(Pike_sp[j-args]) == PIKE_T_STRING)
{
+
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);
+
else
if(!(
a = OBJ2_BUFFER(Pike_sp[j-args].u.object)->str.s
))
+
continue;
+
pike_string_cpy(MKPCHARP_STR_OFF(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;
+
if (s->len < pos) {
+
s->len = pos;
+
s->str[s->len << s->size_shift] = 0;
// Ensure NUL-termination
}
-
+
+
RETURN s->len;
}
-
if
(
str->str
.
s
) {
-
RETURN
str->str.s->len;
-
} else {
-
RETURN 0
;
+
/*!
@decl
int
add
(
string|Buffer
.
.. data
)
+
*!
+
*! Adds @[data] to the buffer.
+
*!
+
*! @returns
+
*! Returns the size of the buffer.
+
*!
+
*! @seealso
+
*! @[addat()]
+
*/
+
PIKEFUN int add( string|Buffer ... arg1 )
+
rawtype tFuncV(tNone, tOr(tString, tObjIs_BUFFER), tIntPos);
+
{
+
struct
Buffer_struct
*str
= THIS;
+
push_int(
str->str.s->len
)
;
+
stack_revroll(++args);
+
f_Buffer_addat(args)
;
}
-
}
+
-
/*! @decl void putchar(int
c
)
-
*! Appends the character @[
c
] at the end of the string.
+
/*! @decl void putchar(int
ch
)
+
*! Appends the character @[
ch
] at the end of the string.
*/
-
PIKEFUN void putchar(int
c
) {
+
PIKEFUN void putchar(int
ch
) {
struct Buffer_struct *str = THIS;
-
if(!str->str.s)
-
init_
string_builder_
alloc(&str->str, str->initial, 0);
-
string_builder_
putchar(&str->str,
c
);
+
string_builder_putchar(&str->str,
ch
);
} /*! @decl int sprintf(strict_sprintf_format format, sprintf_args ... args) *! Appends the output from @[sprintf] at the end of the string. *! Returns the resulting size of the String.Buffer. */ PIKEFUN int sprintf(mixed ... arguments) rawtype tFuncV(tAttr("strict_sprintf_format", tOr(tStr, tObj)), tAttr("sprintf_args", tMix), tStr); { // FIXME: Reset length on exception? struct Buffer_struct *str = THIS;
-
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;
+
if(
(len
=
str
->len)
> 0
)
{
-
ptrdiff_t len = str->len;
-
if( len > 0 )
-
{
+
char *d = (char *)str->str; switch( str->size_shift ) { case 0: str=make_shared_binary_string0((p_wchar0 *)d,len); break; case 1: str=make_shared_binary_string1((p_wchar1 *)d,len); break;
-
case 2
:
+
default
:
str=make_shared_binary_string2((p_wchar2 *)d,len); break; } if( Pike_fp->current_object->flags & OBJECT_CLEAR_ON_EXIT ) str->flags |= STRING_CLEAR_ON_EXIT; RETURN str; }
-
}
+
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;
+
if( Pike_fp->current_object->flags & OBJECT_CLEAR_ON_EXIT ) s->flags |= STRING_CLEAR_ON_EXIT;
-
RETURN
s
;
+
push_string(s);
+
// Pick a smaller size to minimise fragmentation
+
// addat() will expand if it notices reuse of
+
// the Buffer
+
init_string_builder_alloc(&str->str, sizeof(struct svalue), 0)
;
}
-
+
+
/*! @decl Buffer|void cut(int start, int|void end, void|int discard)
+
*!
+
*! Cut and delete the range of data from the current buffer.
+
*! Returns a new buffer with the cut data, unless discard is true.
+
*!
+
*! @seealso
+
*! @[get()], @[get_copy()], @[clear()]
+
*/
+
PIKEFUN Buffer|void cut(int index, int|void end_or_none,void|int discard)
+
{
+
struct Buffer_struct *str = THIS, *str2;
+
struct object *res;
+
struct pike_string *s = str->str.s;
+
unsigned len = s->len,shift = s->size_shift;
+
char *p = s->str;
+
INT_TYPE end,vdiscard;
+
+
end = args==1 ? len-1 : end_or_none->u.integer;
+
vdiscard = args==3 ? discard->u.integer : 0;
pop_n_elems(args);
-
push
_
empty
_string();
-
return
;
+
+
if (index < 0)
+
index = 0;
+
if (end >= len)
+
end = len-1;
+
+
p = (char*)p+(index<<shift);
+
index = end-index+1;
+
end = len-end;
+
len = index<<shift;
+
if (!vdiscard)
+
{
+
struct pike
_
string *s2;
+
+
res = fast
_
clone_object( Buffer_program );
+
str2 = OBJ2_BUFFER( res );
+
init_
string
_builder_alloc
(
&str2->str, str2->initial = index, shift
);
+
memcpy((s2=str2->str.s)->str, p, len)
;
+
s2->str[len] = 0; // Ensure NUL-termination
+
s2->len = index;
}
-
+
memmove(p, p+len, end<<shift); // Copy NUL-termination
+
if( s->flags & STRING_CLEAR_ON_EXIT)
+
guaranteed_memset(p+len+(end<<shift) , 0, len );
+
s->len -= index;
-
+
if(!vdiscard)
+
{
+
if( (Pike_fp->current_object->flags & OBJECT_CLEAR_ON_EXIT) )
+
res->flags |= OBJECT_CLEAR_ON_EXIT;
+
push_object(res);
+
}
+
else
+
push_undefined();
+
}
+
/*! @decl void clear() *!
-
*! Empty the buffer, and
don't
care about
the old content.
+
*! Empty the buffer, and
discard
the old content.
*!
-
*! @note
-
*! This function was not available in Pike 7.8 and earlier.
-
*!
+
*! @seealso
-
*! @[get()]
+
*! @[get()]
, @[cut()]
*/ 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;
+
reset_string_builder(&str->str);
}
-
}
+
/*! @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
;
+
RETURN str->str.s->len;
} INIT { struct Buffer_struct *str = THIS;
-
MEMSET
( str, 0, sizeof( *str ) );
+
memset
( str, 0, sizeof( *str ) );
} EXIT gc_trivial; { struct Buffer_struct *str = THIS;
-
if( str->str.s )
-
{
+
if( Pike_fp->flags & OBJECT_CLEAR_ON_EXIT ) guaranteed_memset( str->str.s->str, 0, str->str.s->len ); free_string_builder( &str->str ); }
-
}
+
GC_RECURSE {
-
if (mc_count_bytes (Pike_fp->current_object)
&& THIS->str.s
)
+
if (mc_count_bytes (Pike_fp->current_object))
mc_counted_bytes += THIS->str.malloced; } } /*! @endclass */ /*! @class Replace *! *! This is a "compiled" version of the @[replace] function applied on
pike.git/src/builtin.cmod:3535:
* * It probably has to do with the "if (!args)" above: It should * be possible to create an empty instance. /mast */ if (!from_arg || !to_arg) { Pike_error("Bad number of arguments to create().\n"); } pop_n_elems(args-2); args = 2; if (TYPEOF(*from_arg) != T_ARRAY) {
-
SIMPLE_BAD_ARG_ERROR("
Replace
", 1,
+
SIMPLE_BAD_ARG_ERROR("
replace
", 1,
"array(string)|mapping(string:string)"); } if (TYPEOF(*to_arg) == T_STRING) { push_int(from_arg->u.array->size); stack_swap(); f_allocate(2); } if (TYPEOF(*to_arg) != T_ARRAY) {
-
SIMPLE_BAD_ARG_ERROR("
Replace
", 2, "array(string)|string");
+
SIMPLE_BAD_ARG_ERROR("
replace
", 2, "array(string)|string");
} if (from_arg->u.array->size != to_arg->u.array->size) { Pike_error("Replace must have equal-sized from and to arrays.\n"); } add_ref(THIS->from = from_arg->u.array); add_ref(THIS->to = to_arg->u.array); } if (!THIS->from->size) { /* Enter no-op mode. */ pop_n_elems(args); push_int(0); return; } if( (THIS->from->type_field & ~BIT_STRING) && (array_fix_type_field(THIS->from) & ~BIT_STRING) )
-
SIMPLE_BAD_ARG_ERROR("
Replace
", 1,
+
SIMPLE_BAD_ARG_ERROR("
replace
", 1,
"array(string)|mapping(string:string)"); if( (THIS->to->type_field & ~BIT_STRING) && (array_fix_type_field(THIS->to) & ~BIT_STRING) )
-
SIMPLE_BAD_ARG_ERROR("
Replace
", 2, "array(string)|string");
+
SIMPLE_BAD_ARG_ERROR("
replace
", 2, "array(string)|string");
compile_replace_many(&THIS->ctx, THIS->from, THIS->to, 1); pop_n_elems(args); push_int(0); } /*! @decl string `()(string str) */ PIKEFUN string `()(string str)
pike.git/src/builtin.cmod:3620:
push_svalue(encoded->item + i); stack_swap(); } pop_stack(); f_multi_string_replace_create(i); } INIT {
-
MEMSET
(&THIS->ctx, 0, sizeof(struct replace_many_context));
+
memset
(&THIS->ctx, 0, sizeof(struct replace_many_context));
} EXIT gc_trivial; { free_replace_many_context(&THIS->ctx); } } /*! @endclass
pike.git/src/builtin.cmod:3676:
THIS->del = NULL; } if (THIS->to) { free_string(THIS->to); THIS->to = NULL; } if (!del) return; if (!to) {
-
SIMPLE_BAD_ARG_ERROR("
String.SingleReplace->create
", 2, "string");
+
SIMPLE_BAD_ARG_ERROR("
replace
", 2, "string");
} if (del == to) { /* No-op... */ return; } copy_shared_string(THIS->del, del); copy_shared_string(THIS->to, to);
pike.git/src/builtin.cmod:5475:
if (THIS->num_elems) { struct pike_list_node *node = THIS->head; int i; for (i = 0; i < THIS->num_elems; i++) { assign_svalue_no_free(ITEM(a) + i, &node->val); node = node->next; } } }
-
/*! @decl
mixed
cast(string type)
+
/*! @decl
array
cast(string type)
*!
-
*! Cast the lists. @expr{array@}
and
@expr{object@} are
the only
-
*! supported
types
.
+
*! Cast the lists. @expr{array@}
is
the only
+
*! supported
type
.
*/
-
PIKEFUN
mixed
cast(string type)
+
PIKEFUN
array
cast(string type)
flags ID_PROTECTED; { pop_stack(); /* type as at least one more reference. */ if (type == literal_array_string) apply_current(f_List_cq__values_fun_num, 0);
-
else if (type == literal_object_string)
-
ref_push_object(Pike_fp->current_object);
+
else push_undefined(); } /*! @decl mixed `[](mixed key) */ PIKEFUN mixed `[](mixed key) flags ID_PROTECTED; { struct pike_list_node *node;