e576bb | 2002-10-11 | Martin Nilsson | |
|
aedfb1 | 2002-10-09 | Martin Nilsson | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "global.h"
#include "interpret.h"
#include "svalue.h"
|
bb55f8 | 1997-03-16 | Fredrik Hübinette (Hubbe) | | #include "pike_macros.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "object.h"
#include "program.h"
#include "array.h"
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | #include "pike_error.h"
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | #include "constants.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "mapping.h"
#include "stralloc.h"
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | #include "multiset.h"
#include "pike_types.h"
|
66bcf0 | 2002-12-07 | Henrik Grubbström (Grubba) | | #include "pike_rusage.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "operators.h"
#include "fsort.h"
#include "callback.h"
|
624d09 | 1996-02-24 | Fredrik Hübinette (Hubbe) | | #include "gc.h"
|
ed70b7 | 1996-06-09 | Fredrik Hübinette (Hubbe) | | #include "backend.h"
#include "main.h"
|
9aa6fa | 1997-05-19 | Fredrik Hübinette (Hubbe) | | #include "pike_memory.h"
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | #include "threads.h"
|
3beb89 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | #include "time_stuff.h"
|
6023ae | 1997-01-18 | Fredrik Hübinette (Hubbe) | | #include "version.h"
|
aac015 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | #include "encode.h"
|
38bddc | 1996-08-12 | Fredrik Hübinette (Hubbe) | | #include <ctype.h>
|
32a958 | 1997-01-31 | Fredrik Hübinette (Hubbe) | | #include "module_support.h"
|
9c6f7d | 1997-04-15 | Fredrik Hübinette (Hubbe) | | #include "module.h"
#include "opcodes.h"
|
fc3345 | 1997-10-02 | Fredrik Hübinette (Hubbe) | | #include "cyclic.h"
|
89b072 | 1998-05-05 | Fredrik Hübinette (Hubbe) | | #include "signal_handler.h"
|
c1073a | 1999-05-11 | Mirar (Pontus Hagland) | | #include "builtin_functions.h"
|
39ac73 | 1999-10-20 | Fredrik Noring | | #include "bignum.h"
|
629c5e | 2001-08-31 | Martin Stjernholm | | #include "peep.h"
|
081147 | 2001-07-02 | Fredrik Hübinette (Hubbe) | | #include "docode.h"
#include "lex.h"
|
a63b36 | 2003-11-07 | Martin Stjernholm | | #include "pike_float.h"
|
a52eee | 2015-08-02 | Henrik Grubbström (Grubba) | | #include "stuff.h"
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | #include "pike_compiler.h"
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | |
|
1abad8 | 2011-07-01 | Martin Stjernholm | | #include <errno.h>
|
8bee43 | 1998-04-01 | Henrik Grubbström (Grubba) | | #ifdef HAVE_POLL
|
df284f | 1998-04-29 | Henrik Grubbström (Grubba) | | #ifdef HAVE_POLL_H
|
8bee43 | 1998-04-01 | Henrik Grubbström (Grubba) | | #include <poll.h>
|
df284f | 1998-04-29 | Henrik Grubbström (Grubba) | | #endif /* HAVE_POLL_H */
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#endif /* HAVE_SYS_POLL_H */
|
8bee43 | 1998-04-01 | Henrik Grubbström (Grubba) | | #endif /* HAVE_POLL */
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #ifdef HAVE_CRYPT_H
#include <crypt.h>
#endif
|
8fe810 | 1998-03-16 | Henrik Grubbström (Grubba) | |
|
92bb06 | 1998-05-19 | Henrik Grubbström (Grubba) | |
|
38bddc | 1996-08-12 | Fredrik Hübinette (Hubbe) | |
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | |
51eb17 | 2015-05-14 | Henrik Grubbström (Grubba) | | *! This function checks if the values @[a] and @[b] are equivalent.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
51eb17 | 2015-05-14 | Henrik Grubbström (Grubba) | | *! @returns
*! If either of the values is an object the (normalized) result
*! of calling @[lfun::_equal()] will be returned.
*!
*! Returns @expr{1@} if both values are false (zero, destructed objects,
*! prototype functions, etc).
*!
*! Returns @expr{0@} (zero) if the values have different types.
*!
*! Otherwise depending on the type of the values:
*! @mixed
*! @type int
*! @type float
*! @type string
*! @type program
*! Returns the same as @expr{a == b@}.
*! @type array
*! @type mapping
*! @type multiset
*! @type object
*! The contents of @[a] and @[b] are checked recursively, and
*! if all their contents are @[equal] and in the same place,
*! they are considered equal.
*!
*! Note that for objects this case is only reached if neither
*! @[a] nor @[b] implements @[lfun::_equal()].
*! @type type
*! Returns @expr{(a <= b) && (b <= a)@}.
*! @endmixed
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
7e1799 | 2015-06-17 | Henrik Grubbström (Grubba) | | *! @[copy_value()], @[`==()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_equal(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
int i;
|
7cc831 | 1998-04-10 | Henrik Grubbström (Grubba) | | if(args != 2)
|
06bd61 | 2016-01-26 | Martin Nilsson | | SIMPLE_WRONG_NUM_ARGS_ERROR("equal", 2);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | i=is_equal(Pike_sp-2,Pike_sp-1);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
push_int(i);
}
|
7535f8 | 2001-01-08 | Henrik Grubbström (Grubba) | | |
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Construct an array with the arguments as indices.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! This function could be written in Pike as:
|
f79bd8 | 2003-04-01 | Martin Nilsson | | *! @code
*! array aggregate(mixed ... elems) { return elems; }
*! @endcode
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @note
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Arrays are dynamically allocated there is no need to declare them
|
f79bd8 | 2003-04-01 | Martin Nilsson | | *! like @expr{int a[10]=allocate(10);@} (and it isn't possible either) like
*! in C, just @expr{array(int) a=allocate(10);@} will do.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[sizeof()], @[arrayp()], @[allocate()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void debug_f_aggregate(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
struct array *a;
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | a=aggregate_array(args);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | push_array(a);
}
|
faafc5 | 2005-03-16 | Henrik Grubbström (Grubba) | | static node *optimize_f_aggregate(node *n)
{
node *args = CDR(n);
node *new_args = NULL;
node *add_args = NULL;
int count;
if (!args) return NULL;
args->parent = NULL;
for (count = 0; args->token == F_ARG_LIST; args = CAR(args)) {
if (CDR(args) && CDR(args)->token == F_PUSH_ARRAY) {
count += 16;
} else {
count++;
}
if (!CAR(args)) break;
CAR(args)->parent = args;
}
if (args->token == F_PUSH_ARRAY) {
count += 16;
} else if (args->token != F_ARG_LIST) {
count++;
}
if (count <= 32) {
CDR(n)->parent = n;
return NULL;
}
count = 0;
if (args->token != F_ARG_LIST) {
if (args->token == F_PUSH_ARRAY) {
add_args = copy_node(CAR(args));
} else {
new_args = copy_node(args);
count = 1;
}
args = args->parent;
}
for(; args; args = args->parent) {
|
594f16 | 2007-01-15 | Henrik Grubbström (Grubba) | | if (!CDR(args)) continue;
|
faafc5 | 2005-03-16 | Henrik Grubbström (Grubba) | | if (CDR(args)->token == F_PUSH_ARRAY) {
if (count) {
add_args = mknode(F_ARG_LIST, add_args,
mkapplynode(copy_node(CAR(n)), new_args));
new_args = NULL;
count = 0;
}
add_args = mknode(F_ARG_LIST, add_args, copy_node(CADR(args)));
} else {
new_args = mknode(F_ARG_LIST, new_args, copy_node(CDR(args)));
count++;
if (count > 31) {
add_args = mknode(F_ARG_LIST, add_args,
mkapplynode(copy_node(CAR(n)), new_args));
new_args = NULL;
count = 0;
}
}
}
if (count) {
add_args = mknode(F_ARG_LIST, add_args,
mkapplynode(copy_node(CAR(n)), new_args));
new_args = NULL;
count = 0;
}
CDR(n)->parent = n;
return mkefuncallnode("`+", add_args);
}
|
081147 | 2001-07-02 | Fredrik Hübinette (Hubbe) | |
|
1b068a | 2011-05-15 | Per Hedbor | | #define MK_HASHMEM(NAME, TYPE) ATTRIBUTE((const)) \
|
01b921 | 2016-01-12 | Per Hedbor | | static inline size_t NAME(const TYPE *str, ptrdiff_t len, ptrdiff_t maxn) \
|
1b068a | 2011-05-15 | Per Hedbor | | { \
size_t ret,c; \
\
ret = len*92873743; \
\
len = MINIMUM(maxn,len); \
for(; len>=0; len--) \
{ \
c=str++[0]; \
ret ^= ( ret << 4 ) + c ; \
ret &= 0x7fffffff; \
} \
return ret; \
}
MK_HASHMEM(simple_hashmem, unsigned char)
MK_HASHMEM(simple_hashmem1, p_wchar1)
MK_HASHMEM(simple_hashmem2, p_wchar2)
|
f6c5cf | 2014-12-06 | Henrik Grubbström (Grubba) | | |
1a3aec | 2014-11-24 | Stephen R. van den Berg | | *!
*! Return an integer derived from the string @[s]. The same string
|
c3bc8f | 2015-06-17 | Henrik Grubbström (Grubba) | | *! always hashes to the same value, also between processes.
|
1a3aec | 2014-11-24 | Stephen R. van den Berg | | *!
*! If @[max] is given, the result will be >= 0 and < @[max],
*! otherwise the result will be >= 0 and <= 0x7fffffff.
*!
*! @note
|
c3bc8f | 2015-06-17 | Henrik Grubbström (Grubba) | | *! This function is provided for backward compatibility with
*! code written for Pike up and including version 7.4.
|
1a3aec | 2014-11-24 | Stephen R. van den Berg | | *!
*! This function is byte-order dependant for wide strings.
*!
*! @seealso
|
c3bc8f | 2015-06-17 | Henrik Grubbström (Grubba) | | *! @[hash()], @[hash_7_0]
|
1a3aec | 2014-11-24 | Stephen R. van den Berg | | */
static void f_hash_7_4(INT32 args)
{
size_t i = 0;
struct pike_string *s = Pike_sp[-args].u.string;
if(!args)
|
06bd61 | 2016-01-26 | Martin Nilsson | | SIMPLE_WRONG_NUM_ARGS_ERROR("7.4::hash",1);
|
1a3aec | 2014-11-24 | Stephen R. van den Berg | |
if(TYPEOF(Pike_sp[-args]) != T_STRING)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("7.4::hash", 1, "string");
|
1a3aec | 2014-11-24 | Stephen R. van den Berg | |
i = simple_hashmem((unsigned char *)s->str, s->len<<s->size_shift,
100<<s->size_shift);
if(args > 1)
{
if(TYPEOF(Pike_sp[1-args]) != T_INT)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("7.4::hash",2,"int");
|
1a3aec | 2014-11-24 | Stephen R. van den Berg | |
if(!Pike_sp[1-args].u.integer)
PIKE_ERROR("7.4::hash", "Modulo by zero.\n", Pike_sp, args);
i%=(unsigned INT32)Pike_sp[1-args].u.integer;
}
pop_n_elems(args);
push_int64(i);
}
|
01b921 | 2016-01-12 | Per Hedbor | | ATTRIBUTE((const)) static inline size_t hashstr(const unsigned char *str, ptrdiff_t maxn)
|
1a3aec | 2014-11-24 | Stephen R. van den Berg | | {
size_t ret,c;
if(!(ret=str++[0]))
return ret;
for(; maxn>=0; maxn--)
{
c=str++[0];
if(!c) break;
ret ^= ( ret << 4 ) + c ;
ret &= 0x7fffffff;
}
return ret;
}
|
39073b | 2014-11-24 | Martin Nilsson | | *! @[hash()], @[hash_7_4]
|
1a3aec | 2014-11-24 | Stephen R. van den Berg | | */
static void f_hash_7_0( INT32 args )
{
struct pike_string *s = Pike_sp[-args].u.string;
unsigned int i;
if(!args)
|
06bd61 | 2016-01-26 | Martin Nilsson | | SIMPLE_WRONG_NUM_ARGS_ERROR("7.0::hash",1);
|
1a3aec | 2014-11-24 | Stephen R. van den Berg | | if(TYPEOF(Pike_sp[-args]) != T_STRING)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("7.0::hash", 1, "string");
|
1a3aec | 2014-11-24 | Stephen R. van den Berg | |
if( s->size_shift )
{
f_hash_7_4( args );
return;
}
|
bd6739 | 2015-10-14 | Martin Nilsson | | i = (unsigned int)hashstr( (unsigned char *)s->str,
MINIMUM(100,s->len));
|
1a3aec | 2014-11-24 | Stephen R. van den Berg | | if(args > 1)
{
if(TYPEOF(Pike_sp[1-args]) != T_INT)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("7.0::hash",2,"int");
|
1a3aec | 2014-11-24 | Stephen R. van den Berg | |
if(!Pike_sp[1-args].u.integer)
PIKE_ERROR("7.0::hash", "Modulo by zero.\n", Pike_sp, args);
i%=(unsigned INT32)Pike_sp[1-args].u.integer;
}
pop_n_elems(args);
push_int( i );
}
|
ce4d67 | 2001-01-31 | Henrik Grubbström (Grubba) | | |
5ad096 | 2003-11-10 | Martin Stjernholm | | *! Return an integer derived from the string @[s]. The same string
*! always hashes to the same value, also between processes,
*! architectures, and Pike versions (see compatibility notes below,
*! though).
*!
*! If @[max] is given, the result will be >= 0 and < @[max],
*! otherwise the result will be >= 0 and <= 0x7fffffff.
|
ce4d67 | 2001-01-31 | Henrik Grubbström (Grubba) | | *!
*! @note
|
1a3aec | 2014-11-24 | Stephen R. van den Berg | | *! The hash algorithm was changed in Pike 7.5. If you want a hash
|
c3bc8f | 2015-06-17 | Henrik Grubbström (Grubba) | | *! that is compatible with Pike 7.4 and earlier, use @[hash_7_4()].
|
1a3aec | 2014-11-24 | Stephen R. van den Berg | | *! The difference only affects wide strings.
*!
*! The hash algorithm was also changed in Pike 7.1. If you want a hash
|
c3bc8f | 2015-06-17 | Henrik Grubbström (Grubba) | | *! that is compatible with Pike 7.0 and earlier, use @[hash_7_0()].
|
1a3aec | 2014-11-24 | Stephen R. van den Berg | | *!
*! @note
|
e751c4 | 2010-05-19 | Henrik Grubbström (Grubba) | | *! This hash function differs from the one provided by @[hash_value()],
*! in that @[hash_value()] returns a process specific value.
*!
|
ce4d67 | 2001-01-31 | Henrik Grubbström (Grubba) | | *! @seealso
|
f6c5cf | 2014-12-06 | Henrik Grubbström (Grubba) | | *! @[hash_7_0()], @[hash_7_4()], @[hash_value]
|
ce4d67 | 2001-01-31 | Henrik Grubbström (Grubba) | | */
|
5d98c4 | 2003-03-02 | Henrik Grubbström (Grubba) | | PMOD_EXPORT void f_hash(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
cb787a | 2000-08-24 | Henrik Grubbström (Grubba) | | size_t i = 0;
|
5d98c4 | 2003-03-02 | Henrik Grubbström (Grubba) | | struct pike_string *s;
|
93b720 | 2000-08-14 | Henrik Grubbström (Grubba) | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if(!args)
|
06bd61 | 2016-01-26 | Martin Nilsson | | SIMPLE_WRONG_NUM_ARGS_ERROR("hash",1);
|
98d8e7 | 2000-12-10 | Per Hedbor | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[-args]) != T_STRING)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("hash", 1, "string");
|
f28591 | 1999-03-09 | Fredrik Hübinette (Hubbe) | |
|
5d98c4 | 2003-03-02 | Henrik Grubbström (Grubba) | | s = Pike_sp[-args].u.string;
switch(s->size_shift) {
case 0:
i = simple_hashmem(STR0(s), s->len, 100);
break;
case 1:
i = simple_hashmem1(STR1(s), s->len, 100);
break;
case 2:
i = simple_hashmem2(STR2(s), s->len, 100);
break;
}
|
98d8e7 | 2000-12-10 | Per Hedbor | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if(args > 1)
{
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[1-args]) != T_INT)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("hash",2,"int");
|
1a3aec | 2014-11-24 | Stephen R. van den Berg | |
|
c5ab04 | 2004-05-13 | Martin Nilsson | | if(Pike_sp[1-args].u.integer <= 0)
PIKE_ERROR("hash", "Modulo < 1.\n", Pike_sp, args);
|
5d98c4 | 2003-03-02 | Henrik Grubbström (Grubba) | |
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | i%=(unsigned INT32)Pike_sp[1-args].u.integer;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
pop_n_elems(args);
|
93b720 | 2000-08-14 | Henrik Grubbström (Grubba) | | push_int64(i);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
5ad096 | 2003-11-10 | Martin Stjernholm | | |
e751c4 | 2010-05-19 | Henrik Grubbström (Grubba) | | *! is called and its result returned.
|
5ad096 | 2003-11-10 | Martin Stjernholm | | *!
*! @note
|
e751c4 | 2010-05-19 | Henrik Grubbström (Grubba) | | *! This is the hashing method used by mappings.
|
5ad096 | 2003-11-10 | Martin Stjernholm | | *!
*! @seealso
|
e751c4 | 2010-05-19 | Henrik Grubbström (Grubba) | | *! @[hash()], @[lfun::__hash()]
|
5ad096 | 2003-11-10 | Martin Stjernholm | | */
void f_hash_value(INT32 args)
{
unsigned INT32 h;
if(!args)
|
06bd61 | 2016-01-26 | Martin Nilsson | | SIMPLE_WRONG_NUM_ARGS_ERROR("hash_value",1);
|
5ad096 | 2003-11-10 | Martin Stjernholm | |
h = hash_svalue (Pike_sp - args);
pop_n_elems (args);
push_int (h);
}
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | |
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Copy a value recursively.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! If the result value is changed destructively (only possible for
*! multisets, arrays and mappings) the copied value will not be changed.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! The resulting value will always be equal to the copied (as tested with
*! the function @[equal()]), but they may not the the same value (as tested
*! with @[`==()]).
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[equal()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_copy_value(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
if(!args)
|
06bd61 | 2016-01-26 | Martin Nilsson | | SIMPLE_WRONG_NUM_ARGS_ERROR("copy_value",1);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
pop_n_elems(args-1);
|
c2464e | 2009-08-26 | Henrik Grubbström (Grubba) | | push_undefined();
|
cada52 | 2009-08-26 | Martin Stjernholm | | copy_svalues_recursively_no_free(Pike_sp-1,Pike_sp-2,1,0);
free_svalue(Pike_sp-2);
move_svalue (Pike_sp - 2, Pike_sp - 1);
Pike_sp--;
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | dmalloc_touch_svalue(Pike_sp-1);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | struct case_info {
|
9776dd | 2001-06-21 | Henrik Grubbström (Grubba) | | INT32 low;
|
8fe0e4 | 2005-05-08 | Martin Nilsson | | INT16 mode;
INT16 data;
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | };
|
002bd5 | 2008-05-29 | Martin Nilsson | | #define CIM_NONE 0 /* Case-less */
#define CIM_UPPERDELTA 1 /* Upper-case, delta to lower-case in data */
#define CIM_LOWERDELTA 2 /* Lower-case, -delta to upper-case in data */
#define CIM_CASEBIT 3 /* Some case, case mask in data */
#define CIM_CASEBITOFF 4 /* Same as above, but also offset by data */
#define CIM_LONGUPPERDELTA 5 /* Upper-case, delta + 0x7fff. */
#define CIM_LONGLOWERDELTA 6 /* Lower-case, delta + 0x7fff. */
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | |
|
0cb415 | 2000-07-19 | Andreas Lange | | static const struct case_info case_info[] = {
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | #include "case_info.h"
|
9776dd | 2001-06-21 | Henrik Grubbström (Grubba) | | { 0x7fffffff, CIM_NONE, 0x0000, },
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | };
|
9776dd | 2001-06-21 | Henrik Grubbström (Grubba) | | static struct case_info *find_ci(INT32 c)
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | {
static struct case_info *cache = NULL;
|
5e3f72 | 1999-03-20 | Per Hedbor | | struct case_info *ci = cache;
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | int lo = 0;
int hi = NELEM(case_info);
|
9776dd | 2001-06-21 | Henrik Grubbström (Grubba) | | if ((c < 0) || (c > 0xeffff)) {
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | return NULL;
|
9776dd | 2001-06-21 | Henrik Grubbström (Grubba) | | }
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | |
if ((ci) && (ci[0].low <= c) && (ci[1].low > c)) {
|
13670c | 2015-05-25 | Martin Nilsson | | return ci;
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | }
while (lo != hi-1) {
int mid = (lo + hi)/2;
if (case_info[mid].low < c) {
lo = mid;
} else if (case_info[mid].low == c) {
lo = mid;
break;
} else {
hi = mid;
}
}
|
a8d36d | 2000-07-19 | Andreas Lange | | return(cache = (struct case_info *)case_info + lo);
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | }
|
9776dd | 2001-06-21 | Henrik Grubbström (Grubba) | | static struct case_info *find_ci_shift0(INT32 c)
|
480bf0 | 2000-07-27 | Andreas Lange | | {
static struct case_info *cache = NULL;
struct case_info *ci = cache;
int lo = 0;
int hi = CASE_INFO_SHIFT0_HIGH;
|
9776dd | 2001-06-21 | Henrik Grubbström (Grubba) | | if ((c < 0) || (c > 0xefffff)) {
|
480bf0 | 2000-07-27 | Andreas Lange | | return NULL;
|
9776dd | 2001-06-21 | Henrik Grubbström (Grubba) | | }
|
480bf0 | 2000-07-27 | Andreas Lange | |
if ((ci) && (ci[0].low <= c) && (ci[1].low > c)) {
|
13670c | 2015-05-25 | Martin Nilsson | | return ci;
|
480bf0 | 2000-07-27 | Andreas Lange | | }
while (lo != hi-1) {
int mid = (lo + hi)>>1;
if (case_info[mid].low < c) {
lo = mid;
} else if (case_info[mid].low == c) {
lo = mid;
break;
} else {
hi = mid;
}
}
return(cache = (struct case_info *)case_info + lo);
}
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | #define DO_LOWER_CASE(C) do {\
|
9776dd | 2001-06-21 | Henrik Grubbström (Grubba) | | INT32 c = C; \
|
002bd5 | 2008-05-29 | Martin Nilsson | | if(c<0xb5){if(c >= 'A' && c <= 'Z' ) C=c+0x20; } \
/*else if(c==0xa77d) C=0x1d79;*/ else { \
|
332595 | 2004-04-13 | Jonas Wallden | | struct case_info *ci = find_ci(c); \
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | if (ci) { \
switch(ci->mode) { \
|
002bd5 | 2008-05-29 | Martin Nilsson | | case CIM_NONE: case CIM_LOWERDELTA: case CIM_LONGLOWERDELTA: break; \
|
164d67 | 1999-03-20 | Henrik Grubbström (Grubba) | | case CIM_UPPERDELTA: C = c + ci->data; break; \
case CIM_CASEBIT: C = c | ci->data; break; \
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | case CIM_CASEBITOFF: C = ((c - ci->data) | ci->data) + ci->data; break; \
|
002bd5 | 2008-05-29 | Martin Nilsson | | case CIM_LONGUPPERDELTA: \
C = c + ci->data + ( ci->data>0 ? 0x7fff : -0x8000 ); break; \
|
c6b604 | 2008-05-03 | Martin Nilsson | | DO_IF_DEBUG( default: Pike_fatal("lower_case(): Unknown case_info mode: %d\n", ci->mode); ) \
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | } \
|
bd662f | 2004-04-12 | Per Hedbor | | }} \
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | } while(0)
|
480bf0 | 2000-07-27 | Andreas Lange | | #define DO_LOWER_CASE_SHIFT0(C) do {\
|
9776dd | 2001-06-21 | Henrik Grubbström (Grubba) | | INT32 c = C; \
|
03c75f | 2004-10-14 | Martin Nilsson | | if(c<0xb5){if(c >= 'A' && c <= 'Z' ) C=c+0x20;}else {\
|
480bf0 | 2000-07-27 | Andreas Lange | | struct case_info *ci = find_ci_shift0(c); \
if (ci) { \
switch(ci->mode) { \
case CIM_NONE: case CIM_LOWERDELTA: break; \
case CIM_UPPERDELTA: C = c + ci->data; break; \
case CIM_CASEBIT: C = c | ci->data; break; \
case CIM_CASEBITOFF: C = ((c - ci->data) | ci->data) + ci->data; break; \
|
c6b604 | 2008-05-03 | Martin Nilsson | | DO_IF_DEBUG( default: Pike_fatal("lower_case(): Unknown case_info mode: %d\n", ci->mode); ) \
|
480bf0 | 2000-07-27 | Andreas Lange | | } \
|
bd662f | 2004-04-12 | Per Hedbor | | }} \
|
480bf0 | 2000-07-27 | Andreas Lange | | } while(0)
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | #define DO_UPPER_CASE(C) do {\
|
9776dd | 2001-06-21 | Henrik Grubbström (Grubba) | | INT32 c = C; \
|
002bd5 | 2008-05-29 | Martin Nilsson | | if(c<0xb5){if(c >= 'a' && c <= 'z' ) C=c-0x20; } \
/*else if(c==0x1d79) C=0xa77d;*/ else {\
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | struct case_info *ci = find_ci(c); \
if (ci) { \
switch(ci->mode) { \
|
002bd5 | 2008-05-29 | Martin Nilsson | | case CIM_NONE: case CIM_UPPERDELTA: case CIM_LONGUPPERDELTA: break; \
|
164d67 | 1999-03-20 | Henrik Grubbström (Grubba) | | case CIM_LOWERDELTA: C = c - ci->data; break; \
case CIM_CASEBIT: C = c & ~ci->data; break; \
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | case CIM_CASEBITOFF: C = ((c - ci->data)& ~ci->data) + ci->data; break; \
|
002bd5 | 2008-05-29 | Martin Nilsson | | case CIM_LONGLOWERDELTA: \
C = c - ci->data - ( ci->data>0 ? 0x7fff : -0x8000 ); break; \
|
c6b604 | 2008-05-03 | Martin Nilsson | | DO_IF_DEBUG( default: Pike_fatal("upper_case(): Unknown case_info mode: %d\n", ci->mode); ) \
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | } \
|
bd662f | 2004-04-12 | Per Hedbor | | }} \
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | } while(0)
|
480bf0 | 2000-07-27 | Andreas Lange | | #define DO_UPPER_CASE_SHIFT0(C) do {\
|
9776dd | 2001-06-21 | Henrik Grubbström (Grubba) | | INT32 c = C; \
|
03c75f | 2004-10-14 | Martin Nilsson | | if(c<0xb5){if(c >= 'a' && c <= 'z' ) C=c-0x20;}else {\
|
480bf0 | 2000-07-27 | Andreas Lange | | struct case_info *ci = find_ci_shift0(c); \
if (ci) { \
switch(ci->mode) { \
case CIM_NONE: case CIM_UPPERDELTA: break; \
case CIM_LOWERDELTA: C = c - ci->data; break; \
case CIM_CASEBIT: C = c & ~ci->data; break; \
case CIM_CASEBITOFF: C = ((c - ci->data)& ~ci->data) + ci->data; break; \
|
c6b604 | 2008-05-03 | Martin Nilsson | | DO_IF_DEBUG( default: Pike_fatal("lower_case(): Unknown case_info mode: %d\n", ci->mode); ) \
|
480bf0 | 2000-07-27 | Andreas Lange | | } \
|
bd662f | 2004-04-12 | Per Hedbor | | }} \
|
480bf0 | 2000-07-27 | Andreas Lange | | } while(0)
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | |
6f1856 | 2003-09-05 | Henrik Grubbström (Grubba) | | *! @decl int lower_case(int c)
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
6f1856 | 2003-09-05 | Henrik Grubbström (Grubba) | | *! Convert a string or character to lower case.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @returns
*! Returns a copy of the string @[s] with all upper case characters
|
6f1856 | 2003-09-05 | Henrik Grubbström (Grubba) | | *! converted to lower case, or the character @[c] converted to lower
*! case.
*!
*! @note
*! Assumes the string or character to be coded according to
|
0b8d2f | 2013-06-17 | Martin Nilsson | | *! ISO-10646 (aka Unicode). If they are not, @[Charset.decoder] can
*! do the initial conversion for you.
|
6f1856 | 2003-09-05 | Henrik Grubbström (Grubba) | | *!
*! @note
*! Prior to Pike 7.5 this function only accepted strings.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
0b8d2f | 2013-06-17 | Martin Nilsson | | *! @[upper_case()], @[Charset.decoder]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_lower_case(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
93b720 | 2000-08-14 | Henrik Grubbström (Grubba) | | ptrdiff_t i;
|
cabe03 | 1999-03-19 | Henrik Grubbström (Grubba) | | struct pike_string *orig;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *ret;
|
6f1856 | 2003-09-05 | Henrik Grubbström (Grubba) | |
check_all_args("lower_case", args, BIT_STRING|BIT_INT, 0);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-args]) == T_INT) {
|
6f1856 | 2003-09-05 | Henrik Grubbström (Grubba) | |
DO_LOWER_CASE(Pike_sp[-args].u.integer);
pop_n_elems(args-1);
return;
}
|
992551 | 2013-05-31 | Per Hedbor | |
|
c5ab04 | 2004-05-13 | Martin Nilsson | | orig = Pike_sp[-args].u.string;
|
992551 | 2013-05-31 | Per Hedbor | |
if( orig->flags & STRING_IS_LOWERCASE )
return;
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | ret = begin_wide_shared_string(orig->len, orig->size_shift);
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(ret->str, orig->str, orig->len << orig->size_shift);
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | |
i = orig->len;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | if (!orig->size_shift) {
p_wchar0 *str = STR0(ret);
while(i--) {
|
480bf0 | 2000-07-27 | Andreas Lange | | DO_LOWER_CASE_SHIFT0(str[i]);
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | }
} else if (orig->size_shift == 1) {
p_wchar1 *str = STR1(ret);
while(i--) {
DO_LOWER_CASE(str[i]);
}
} else if (orig->size_shift == 2) {
p_wchar2 *str = STR2(ret);
while(i--) {
DO_LOWER_CASE(str[i]);
}
|
c6b604 | 2008-05-03 | Martin Nilsson | | #ifdef PIKE_DEBUG
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | } else {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("lower_case(): Bad string shift:%d\n", orig->size_shift);
|
c6b604 | 2008-05-03 | Martin Nilsson | | #endif
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
992551 | 2013-05-31 | Per Hedbor | | ret = end_shared_string(ret);
ret->flags |= STRING_IS_LOWERCASE;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
|
992551 | 2013-05-31 | Per Hedbor | | push_string(ret);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | |
6f1856 | 2003-09-05 | Henrik Grubbström (Grubba) | | *! @decl int upper_case(int c)
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
6f1856 | 2003-09-05 | Henrik Grubbström (Grubba) | | *! Convert a string or character to upper case.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @returns
*! Returns a copy of the string @[s] with all lower case characters
|
6f1856 | 2003-09-05 | Henrik Grubbström (Grubba) | | *! converted to upper case, or the character @[c] converted to upper
*! case.
*!
*! @note
*! Assumes the string or character to be coded according to
|
0b8d2f | 2013-06-17 | Martin Nilsson | | *! ISO-10646 (aka Unicode). If they are not, @[Charset.decoder] can
*! do the initial conversion for you.
|
6f1856 | 2003-09-05 | Henrik Grubbström (Grubba) | | *!
*! @note
*! Prior to Pike 7.5 this function only accepted strings.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
0b8d2f | 2013-06-17 | Martin Nilsson | | *! @[lower_case()], @[Charset.decoder]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_upper_case(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
93b720 | 2000-08-14 | Henrik Grubbström (Grubba) | | ptrdiff_t i;
|
cabe03 | 1999-03-19 | Henrik Grubbström (Grubba) | | struct pike_string *orig;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *ret;
|
6f1856 | 2003-09-05 | Henrik Grubbström (Grubba) | | check_all_args("upper_case", args, BIT_STRING|BIT_INT, 0);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-args]) == T_INT) {
|
6f1856 | 2003-09-05 | Henrik Grubbström (Grubba) | |
DO_UPPER_CASE(Pike_sp[-args].u.integer);
pop_n_elems(args-1);
return;
}
|
992551 | 2013-05-31 | Per Hedbor | |
|
c5ab04 | 2004-05-13 | Martin Nilsson | | orig = Pike_sp[-args].u.string;
|
992551 | 2013-05-31 | Per Hedbor | | if( orig->flags & STRING_IS_UPPERCASE )
{
return;
}
|
5e3f72 | 1999-03-20 | Per Hedbor | | ret=begin_wide_shared_string(orig->len,orig->size_shift);
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(ret->str, orig->str, orig->len << orig->size_shift);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | i = orig->len;
if (!orig->size_shift) {
p_wchar0 *str = STR0(ret);
while(i--) {
|
0cb415 | 2000-07-19 | Andreas Lange | | if(str[i]!=0xff && str[i]!=0xb5) {
|
480bf0 | 2000-07-27 | Andreas Lange | | DO_UPPER_CASE_SHIFT0(str[i]);
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | } else {
|
c5ab04 | 2004-05-13 | Martin Nilsson | |
int j = orig->len;
struct pike_string *wret = begin_wide_shared_string(j, 1);
p_wchar1 *wstr = STR1(wret);
while(--j>i)
wstr[j] = str[j];
i++;
while(i--)
switch( str[i] ) {
case 0xff: wstr[i] = 0x178; break;
case 0xb5: wstr[i] = 0x39c; break;
default:
DO_UPPER_CASE_SHIFT0(str[i]);
wstr[i] = str[i];
break;
}
|
fb2294 | 2008-06-16 | Martin Stjernholm | | do_free_unlinked_pike_string(ret);
|
c5ab04 | 2004-05-13 | Martin Nilsson | | ret = wret;
break;
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | }
}
} else if (orig->size_shift == 1) {
p_wchar1 *str = STR1(ret);
while(i--) {
DO_UPPER_CASE(str[i]);
}
} else if (orig->size_shift == 2) {
p_wchar2 *str = STR2(ret);
while(i--) {
DO_UPPER_CASE(str[i]);
}
|
c6b604 | 2008-05-03 | Martin Nilsson | | #ifdef PIKE_DEBUG
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | } else {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("lower_case(): Bad string shift:%d\n", orig->size_shift);
|
c6b604 | 2008-05-03 | Martin Nilsson | | #endif
|
94d992 | 1999-03-20 | Henrik Grubbström (Grubba) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
pop_n_elems(args);
|
992551 | 2013-05-31 | Per Hedbor | | ret = end_shared_string(ret);
ret->flags |= STRING_IS_UPPERCASE;
push_string(ret);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | |
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! This function sets the initial value for the random generator.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[random()]
|
70532f | 2016-01-17 | Martin Nilsson | | *!
*! @deprecated
*! @[Random.Deterministic]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
606837 | 2016-01-18 | Martin Nilsson | | static void f_random_seed(INT32 args)
|
cb2256 | 1995-10-11 | Fredrik Hübinette (Hubbe) | | {
|
8aefbc | 1999-03-19 | Fredrik Hübinette (Hubbe) | | INT_TYPE i;
|
f6f02d | 1995-10-16 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
|
cb2256 | 1995-10-11 | Fredrik Hübinette (Hubbe) | | }
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | |
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Returns the number of arguments given when the previous function was
*! called.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! This is useful for functions that take a variable number of arguments.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[call_function()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | void f_query_num_arg(INT32 args)
{
pop_n_elems(args);
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | push_int(Pike_fp ? Pike_fp->args : 0);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
9cf6c8 | 2001-03-11 | Henrik Grubbström (Grubba) | | |
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *! @decl int search(array haystack, mixed needle, int|void start)
*! @decl mixed search(mapping haystack, mixed needle, mixed|void start)
|
b5b59a | 2003-09-04 | Henrik Grubbström (Grubba) | | *! @decl mixed search(object haystack, mixed needle, mixed|void start)
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Search for @[needle] in @[haystack]. Return the position of @[needle] in
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! @[haystack] or @expr{-1@} if not found.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! If the optional argument @[start] is present search is started at
*! this position.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
b5b59a | 2003-09-04 | Henrik Grubbström (Grubba) | | *! @mixed haystack
*! @type string
*! When @[haystack] is a string @[needle] must be a string or an int,
*! and the first occurrence of the string or int is returned.
*!
*! @type array
*! When @[haystack] is an array, @[needle] is compared only to
*! one value at a time in @[haystack].
*!
*! @type mapping
*! When @[haystack] is a mapping, @[search()] tries to find the index
*! connected to the data @[needle]. That is, it tries to lookup the
*! mapping backwards. If @[needle] isn't present in the mapping, zero
*! is returned, and zero_type() will return 1 for this zero.
*!
*! @type object
*! When @[haystack] is an object implementing @[lfun::_search()],
*! the result of calling @[lfun::_search()] with @[needle] will
*! be returned.
*!
*! If @[haystack] is an object that doesn't implement @[lfun::_search()]
*! it is assumed to be an @[Iterator], and implement
*! @[Iterator()->index()], @[Iterator()->value()], and
*! @[Iterator()->next()]. @[search()] will then start comparing
*! 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 (and will thus
*! evaluate to false), and a zero with zero_type 1 will be returned.
*! @endmixed
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
b5b59a | 2003-09-04 | Henrik Grubbström (Grubba) | | *! @note
*! If @[start] is supplied to an iterator object without an
*! @[lfun::_search()], @[haystack] will need to implement
*! @[Iterator()->set_index()].
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
594f16 | 2007-01-15 | Henrik Grubbström (Grubba) | | *! @note
*! For mappings and object @[UNDEFINED] will be returned when not found.
*! In all other cases @expr{-1@} will be returned when not found.
*!
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *! @seealso
|
13670c | 2015-05-25 | Martin Nilsson | | *! @[indices()], @[values()], @[zero_type()], @[has_value()],
|
38cb40 | 2010-03-30 | Peter Bortas | | *! @[has_prefix()], @[has_suffix()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_search(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
93b720 | 2000-08-14 | Henrik Grubbström (Grubba) | | ptrdiff_t start;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
if(args < 2)
|
06bd61 | 2016-01-26 | Martin Nilsson | | SIMPLE_WRONG_NUM_ARGS_ERROR("search", 2);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | switch(TYPEOF(Pike_sp[-args]))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
case T_STRING:
{
|
9cf6c8 | 2001-03-11 | Henrik Grubbström (Grubba) | | struct pike_string *haystack = Pike_sp[-args].u.string;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | start=0;
if(args > 2)
{
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[2-args]) != T_INT)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("search", 3, "int");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | start=Pike_sp[2-args].u.integer;
|
d0d01b | 1999-03-20 | Henrik Grubbström (Grubba) | | if(start<0) {
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | bad_arg_error("search", Pike_sp-args, args, 3, "int(0..)", Pike_sp+2-args,
|
d0d01b | 1999-03-20 | Henrik Grubbström (Grubba) | | "Start must be greater or equal to zero.\n");
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
9cf6c8 | 2001-03-11 | Henrik Grubbström (Grubba) | | if(haystack->len < start)
bad_arg_error("search", Pike_sp-args, args, 3, "int(0..)", Pike_sp-args,
|
d0d01b | 1999-03-20 | Henrik Grubbström (Grubba) | | "Start must not be greater than the "
"length of the string.\n");
|
84f4f9 | 1998-02-27 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if ((TYPEOF(Pike_sp[1-args]) == T_INT) ||
((TYPEOF(Pike_sp[1-args]) == T_STRING) &&
|
f05e11 | 2009-09-09 | Henrik Grubbström (Grubba) | | (Pike_sp[1-args].u.string->len == 1))) {
INT_TYPE val;
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[1-args]) == T_INT) {
|
f05e11 | 2009-09-09 | Henrik Grubbström (Grubba) | | val = Pike_sp[1-args].u.integer;
} else {
val = index_shared_string(Pike_sp[1-args].u.string, 0);
|
e38ce9 | 2001-10-30 | Henrik Grubbström (Grubba) | | }
|
992551 | 2013-05-31 | Per Hedbor | |
if( !string_range_contains( haystack, val ) )
{
pop_n_elems(args);
push_int( -1 );
return;
}
|
9cf6c8 | 2001-03-11 | Henrik Grubbström (Grubba) | | 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;
start++;
}
}
break;
case 1:
{
p_wchar1 *str = STR1(haystack);
if (val >= 65536) {
start = -1;
break;
}
while (start < haystack->len) {
if (str[start] == val) break;
start++;
}
}
break;
case 2:
{
p_wchar2 *str = STR2(haystack);
while (start < haystack->len) {
if (str[start] == (p_wchar2)val) break;
start++;
}
}
break;
}
if (start >= haystack->len) {
start = -1;
}
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | } else if(TYPEOF(Pike_sp[1-args]) == T_STRING) {
|
f05e11 | 2009-09-09 | Henrik Grubbström (Grubba) | |
if (Pike_sp[1-args].u.string->len) {
start = string_search(haystack,
Pike_sp[1-args].u.string,
start);
}
|
9cf6c8 | 2001-03-11 | Henrik Grubbström (Grubba) | | } else {
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("search", 2, "string | int");
|
9cf6c8 | 2001-03-11 | Henrik Grubbström (Grubba) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
|
93b720 | 2000-08-14 | Henrik Grubbström (Grubba) | | push_int64(start);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | break;
}
case T_ARRAY:
start=0;
if(args > 2)
{
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[2-args]) != T_INT)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("search", 3, "int");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | start=Pike_sp[2-args].u.integer;
|
c2998a | 1999-11-08 | Henrik Grubbström (Grubba) | | if(start<0) {
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | bad_arg_error("search", Pike_sp-args, args, 3, "int(0..)", Pike_sp+2-args,
|
c2998a | 1999-11-08 | Henrik Grubbström (Grubba) | | "Start must be greater or equal to zero.\n");
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | start=array_search(Pike_sp[-args].u.array,Pike_sp+1-args,start);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
|
93b720 | 2000-08-14 | Henrik Grubbström (Grubba) | | push_int64(start);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | break;
case T_MAPPING:
|
c2998a | 1999-11-08 | Henrik Grubbström (Grubba) | | if(args > 2) {
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | mapping_search_no_free(Pike_sp,Pike_sp[-args].u.mapping,Pike_sp+1-args,Pike_sp+2-args);
|
c2998a | 1999-11-08 | Henrik Grubbström (Grubba) | | } else {
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | mapping_search_no_free(Pike_sp,Pike_sp[-args].u.mapping,Pike_sp+1-args,0);
|
c2998a | 1999-11-08 | Henrik Grubbström (Grubba) | | }
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | free_svalue(Pike_sp-args);
Pike_sp[-args]=*Pike_sp;
dmalloc_touch_svalue(Pike_sp);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args-1);
return;
|
b5b59a | 2003-09-04 | Henrik Grubbström (Grubba) | | case T_OBJECT:
|
f54c78 | 2004-12-22 | Henrik Grubbström (Grubba) | | {
struct program *p;
if ((p = (Pike_sp[-args].u.object->prog))) {
struct object *o = Pike_sp[-args].u.object;
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | int id_level = p->inherits[SUBTYPEOF(Pike_sp[-args])].identifier_level;
|
f54c78 | 2004-12-22 | Henrik Grubbström (Grubba) | | int id;
int next, ind;
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | p = p->inherits[SUBTYPEOF(Pike_sp[-args])].prog;
|
f54c78 | 2004-12-22 | Henrik Grubbström (Grubba) | |
id = low_find_lfun(p, LFUN__SEARCH);
if (id >= 0) {
apply_low(o, id + id_level, args-1);
stack_pop_n_elems_keep_top(1);
return;
|
b5b59a | 2003-09-04 | Henrik Grubbström (Grubba) | | }
|
f54c78 | 2004-12-22 | Henrik Grubbström (Grubba) | |
if (((id = find_identifier("value", p)) >= 0) &&
((next = find_identifier("next", p)) >= 0) &&
((ind = find_identifier("index", p)) >= 0)) {
id += id_level;
next += id_level;
ind += id_level;
if (args > 2) {
int fun = find_identifier("set_index", p);
if (fun < 0)
Pike_error ("Cannot call unknown function \"%s\".\n", fun);
apply_low(o, fun + id_level, args-2);
pop_stack();
|
b5b59a | 2003-09-04 | Henrik Grubbström (Grubba) | | }
|
f54c78 | 2004-12-22 | Henrik Grubbström (Grubba) | |
while(1) {
apply_low(o, id, 0);
if (is_eq(Pike_sp-2, Pike_sp-1)) {
apply_low(o, ind, 0);
stack_pop_n_elems_keep_top(3);
return;
}
apply_low(o, next, 0);
if (UNSAFE_IS_ZERO(Pike_sp-1)) {
pop_n_elems(4);
|
13670c | 2015-05-25 | Martin Nilsson | | push_undefined();
|
f54c78 | 2004-12-22 | Henrik Grubbström (Grubba) | | return;
}
pop_n_elems(2);
|
b5b59a | 2003-09-04 | Henrik Grubbström (Grubba) | | }
}
}
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | default:
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("search", 1, "string|array|mapping|object");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
929a86 | 2010-02-23 | Henrik Grubbström (Grubba) | | |
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Returns @expr{1@} if the string @[s] starts with @[prefix],
*! returns @expr{0@} (zero) otherwise.
|
38cb40 | 2010-03-30 | Peter Bortas | | *!
|
dfaa43 | 2010-11-15 | Henrik Grubbström (Grubba) | | *! When @[s] is an object, it needs to implement
*! @[lfun::_sizeof()] and @[lfun::`[]].
*!
|
38cb40 | 2010-03-30 | Peter Bortas | | *! @seealso
*! @[has_suffix()], @[has_value()], @[search()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_has_prefix(INT32 args)
|
a4f17f | 2000-04-12 | Henrik Grubbström (Grubba) | | {
struct pike_string *a, *b;
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args!=2)
SIMPLE_WRONG_NUM_ARGS_ERROR("has_prefix", 2);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if((TYPEOF(Pike_sp[-args]) != T_STRING) &&
(TYPEOF(Pike_sp[-args]) != T_OBJECT))
|
929a86 | 2010-02-23 | Henrik Grubbström (Grubba) | | SIMPLE_ARG_TYPE_ERROR("has_prefix", 1, "string|object");
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[1-args]) != T_STRING)
|
7d1e03 | 2004-05-18 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("has_prefix", 2, "string");
b = Pike_sp[1-args].u.string;
|
a4f17f | 2000-04-12 | Henrik Grubbström (Grubba) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-args]) == T_OBJECT) {
|
929a86 | 2010-02-23 | Henrik Grubbström (Grubba) | | ptrdiff_t i;
struct object *o = Pike_sp[-args].u.object;
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | int inherit_no = SUBTYPEOF(Pike_sp[-args]);
|
dfaa43 | 2010-11-15 | Henrik Grubbström (Grubba) | |
|
e30542 | 2012-05-11 | Henrik Grubbström (Grubba) | | if (!o->prog || FIND_LFUN(o->prog, LFUN__SIZEOF) < 0) {
|
368623 | 2014-08-18 | Martin Nilsson | | Pike_error("Object in argument 1 lacks lfun::_sizeof().\n");
|
e30542 | 2012-05-11 | Henrik Grubbström (Grubba) | | }
|
dfaa43 | 2010-11-15 | Henrik Grubbström (Grubba) | | apply_lfun(o, LFUN__SIZEOF, 0);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if ((TYPEOF(Pike_sp[-1]) != T_INT) || (Pike_sp[-1].u.integer < b->len)) {
|
dfaa43 | 2010-11-15 | Henrik Grubbström (Grubba) | | pop_n_elems(args + 1);
push_int(0);
return;
}
|
929a86 | 2010-02-23 | Henrik Grubbström (Grubba) | |
for (i = 0; i < b->len; i++) {
p_wchar2 ch = index_shared_string(b, i);
Pike_sp[-1].u.integer = i;
object_index_no_free(Pike_sp-1, o, inherit_no, Pike_sp-1);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-1]) != PIKE_T_INT) {
|
929a86 | 2010-02-23 | Henrik Grubbström (Grubba) | | Pike_error("Unexepected value returned from index operator.\n");
}
if (ch != Pike_sp[-1].u.integer) {
pop_n_elems(args + 1);
push_int(0);
return;
}
}
|
36f105 | 2010-02-23 | Henrik Grubbström (Grubba) | | pop_n_elems(args+1);
|
929a86 | 2010-02-23 | Henrik Grubbström (Grubba) | | push_int(1);
return;
}
a = Pike_sp[-args].u.string;
|
a4f17f | 2000-04-12 | Henrik Grubbström (Grubba) | |
|
676582 | 2013-06-10 | Tobias S. Josefowitz | | if ((b->len > a->len) || (b->size_shift > a->size_shift)
|| !string_range_contains_string(a, b)) {
|
a4f17f | 2000-04-12 | Henrik Grubbström (Grubba) | | pop_n_elems(args);
push_int(0);
return;
}
if ((a == b)||(!b->len)) {
pop_n_elems(args);
push_int(1);
return;
}
if (a->size_shift == b->size_shift) {
|
67074e | 2014-09-03 | Martin Nilsson | | int res = !memcmp(a->str, b->str, b->len << b->size_shift);
|
a4f17f | 2000-04-12 | Henrik Grubbström (Grubba) | | pop_n_elems(args);
push_int(res);
return;
}
#define TWO_SHIFTS(S1, S2) ((S1)|((S2)<<2))
switch(TWO_SHIFTS(a->size_shift, b->size_shift)) {
#define CASE_SHIFT(S1, S2) \
case TWO_SHIFTS(S1, S2): \
{ \
PIKE_CONCAT(p_wchar,S1) *s1 = PIKE_CONCAT(STR,S1)(a); \
PIKE_CONCAT(p_wchar,S2) *s2 = PIKE_CONCAT(STR,S2)(b); \
|
93b720 | 2000-08-14 | Henrik Grubbström (Grubba) | | ptrdiff_t len = b->len; \
|
a4f17f | 2000-04-12 | Henrik Grubbström (Grubba) | | while(len-- && (s1[len] == s2[len])) \
; \
pop_n_elems(args); \
push_int(len == -1); \
return; \
} \
break
CASE_SHIFT(1,0);
CASE_SHIFT(2,0);
CASE_SHIFT(2,1);
}
#undef CASE_SHIFT
#undef TWO_SHIFTS
}
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | |
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Returns @expr{1@} if the string @[s] ends with @[suffix],
*! returns @expr{0@} (zero) otherwise.
|
38cb40 | 2010-03-30 | Peter Bortas | | *!
*! @seealso
*! @[has_prefix()], @[has_value()], @[search()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
54277b | 2000-12-18 | Henrik Grubbström (Grubba) | | PMOD_EXPORT void f_has_suffix(INT32 args)
{
struct pike_string *a, *b;
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args!=2)
SIMPLE_WRONG_NUM_ARGS_ERROR("has_suffix", 2);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[-args]) != T_STRING)
|
7d1e03 | 2004-05-18 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("has_suffix", 1, "string");
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[1-args]) != T_STRING)
|
7d1e03 | 2004-05-18 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("has_suffix", 2, "string");
a = Pike_sp[-args].u.string;
b = Pike_sp[1-args].u.string;
|
54277b | 2000-12-18 | Henrik Grubbström (Grubba) | |
|
676582 | 2013-06-10 | Tobias S. Josefowitz | | if ((b->len > a->len) || (b->size_shift > a->size_shift)
|| !string_range_contains_string(a, b)) {
|
54277b | 2000-12-18 | Henrik Grubbström (Grubba) | | pop_n_elems(args);
push_int(0);
return;
}
if ((a == b)||(!b->len)) {
pop_n_elems(args);
push_int(1);
return;
}
if (a->size_shift == b->size_shift) {
|
67074e | 2014-09-03 | Martin Nilsson | | int res = !memcmp(a->str + ((a->len - b->len)<<b->size_shift), b->str,
|
54277b | 2000-12-18 | Henrik Grubbström (Grubba) | | b->len << b->size_shift);
pop_n_elems(args);
push_int(res);
return;
}
#define TWO_SHIFTS(S1, S2) ((S1)|((S2)<<2))
switch(TWO_SHIFTS(a->size_shift, b->size_shift)) {
#define CASE_SHIFT(S1, S2) \
case TWO_SHIFTS(S1, S2): \
{ \
PIKE_CONCAT(p_wchar,S1) *s1 = PIKE_CONCAT(STR,S1)(a) + a->len - b->len; \
PIKE_CONCAT(p_wchar,S2) *s2 = PIKE_CONCAT(STR,S2)(b); \
ptrdiff_t len = b->len; \
while(len-- && (s1[len] == s2[len])) \
; \
pop_n_elems(args); \
push_int(len == -1); \
return; \
} \
break
CASE_SHIFT(1,0);
CASE_SHIFT(2,0);
CASE_SHIFT(2,1);
}
#undef CASE_SHIFT
#undef TWO_SHIFTS
}
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | |
01587a | 2003-06-03 | Martin Stjernholm | | *! @decl int has_index(mapping|multiset|object|program haystack, mixed index)
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Search for @[index] in @[haystack].
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @returns
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Returns @expr{1@} if @[index] is in the index domain of @[haystack],
*! or @expr{0@} (zero) if not found.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! This function is equivalent to (but sometimes faster than):
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
f79bd8 | 2003-04-01 | Martin Nilsson | | *! @code
*! search(indices(haystack), index) != -1
*! @endcode
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @note
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! A negative index in strings and arrays as recognized by the
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! index operators @expr{`[]()@} and @expr{`[]=()@} is not considered
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! a proper index by @[has_index()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
38cb40 | 2010-03-30 | Peter Bortas | | *! @[has_value()], @[has_prefix()], @[has_suffix()], @[indices()],
*! @[search()], @[values()], @[zero_type()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_has_index(INT32 args)
|
538a89 | 2000-01-21 | Fredrik Noring | | {
int t = 0;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args != 2)
SIMPLE_WRONG_NUM_ARGS_ERROR("has_index", 2);
|
538a89 | 2000-01-21 | Fredrik Noring | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | switch(TYPEOF(Pike_sp[-2]))
|
538a89 | 2000-01-21 | Fredrik Noring | | {
case T_STRING:
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[-1]) == T_INT)
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | t = (0 <= Pike_sp[-1].u.integer && Pike_sp[-1].u.integer < Pike_sp[-2].u.string->len);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
538a89 | 2000-01-21 | Fredrik Noring | | pop_n_elems(args);
push_int(t);
break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
538a89 | 2000-01-21 | Fredrik Noring | | case T_ARRAY:
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[-1]) == T_INT)
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | t = (0 <= Pike_sp[-1].u.integer && Pike_sp[-1].u.integer < Pike_sp[-2].u.array->size);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
538a89 | 2000-01-21 | Fredrik Noring | | pop_n_elems(args);
push_int(t);
break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
538a89 | 2000-01-21 | Fredrik Noring | | case T_MAPPING:
|
b3f9b2 | 2015-03-31 | Per Hedbor | | t=!!low_mapping_lookup( Pike_sp[-2].u.mapping, Pike_sp-1 );
pop_n_elems(2);
push_int(t);
break;
case T_MULTISET:
t = multiset_member( Pike_sp[-2].u.multiset, Pike_sp-1 );
pop_n_elems(2);
push_int(t);
break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
538a89 | 2000-01-21 | Fredrik Noring | | case T_OBJECT:
|
01587a | 2003-06-03 | Martin Stjernholm | | case T_PROGRAM:
|
7b5804 | 2000-01-24 | Fredrik Noring | | |
a4a172 | 2000-12-05 | Per Hedbor | | error for non-valid indices. Therefore it's not a good idea
|
7b5804 | 2000-01-24 | Fredrik Noring | | to use the index operator.
Maybe we should use object->_has_index(index) provided that
the object implements it.
|
13670c | 2015-05-25 | Martin Nilsson | |
|
538a89 | 2000-01-21 | Fredrik Noring | | /Noring */
|
89c91b | 2008-01-05 | Martin Nilsson | |
|
538a89 | 2000-01-21 | Fredrik Noring | |
stack_swap();
f_indices(1);
stack_swap();
f_search(2);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[-1]) == T_INT)
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | Pike_sp[-1].u.integer = (Pike_sp[-1].u.integer != -1);
|
538a89 | 2000-01-21 | Fredrik Noring | | else
PIKE_ERROR("has_index",
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | "Function `search' gave incorrect result.\n", Pike_sp, args);
|
01587a | 2003-06-03 | Martin Stjernholm | | break;
default:
SIMPLE_ARG_TYPE_ERROR ("has_index", 1,
"string|array|mapping|multiset|object|program");
|
538a89 | 2000-01-21 | Fredrik Noring | | }
}
|
9cf6c8 | 2001-03-11 | Henrik Grubbström (Grubba) | | |
01587a | 2003-06-03 | Martin Stjernholm | | *! @decl int has_value(array|mapping|object|program haystack, mixed value)
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Search for @[value] in @[haystack].
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @returns
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Returns @expr{1@} if @[value] is in the value domain of @[haystack],
*! or @expr{0@} (zero) if not found.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! This function is in all cases except when both arguments are strings
*! equivalent to (but sometimes faster than):
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
f79bd8 | 2003-04-01 | Martin Nilsson | | *! @code
*! search(values(@[haystack]), @[value]) != -1
*! @endcode
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! If both arguments are strings, @[has_value()] is equivalent to:
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
f79bd8 | 2003-04-01 | Martin Nilsson | | *! @code
*! search(@[haystack], @[value]) != -1
*! @endcode
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
13670c | 2015-05-25 | Martin Nilsson | | *! @[has_index()], @[indices()], @[search()], @[has_prefix()],
|
38cb40 | 2010-03-30 | Peter Bortas | | *! @[has_suffix()], @[values()], @[zero_type()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_has_value(INT32 args)
|
538a89 | 2000-01-21 | Fredrik Noring | | {
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args != 2)
SIMPLE_WRONG_NUM_ARGS_ERROR("has_value", 2);
|
538a89 | 2000-01-21 | Fredrik Noring | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | switch(TYPEOF(Pike_sp[-2]))
|
538a89 | 2000-01-21 | Fredrik Noring | | {
case T_MAPPING:
f_search(2);
f_zero_type(1);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[-1]) == T_INT)
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | Pike_sp[-1].u.integer = !Pike_sp[-1].u.integer;
|
538a89 | 2000-01-21 | Fredrik Noring | | else
PIKE_ERROR("has_value",
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | "Function `zero_type' gave incorrect result.\n", Pike_sp, args);
|
538a89 | 2000-01-21 | Fredrik Noring | | break;
|
01587a | 2003-06-03 | Martin Stjernholm | |
case T_PROGRAM:
|
538a89 | 2000-01-21 | Fredrik Noring | | case T_OBJECT:
|
f54c78 | 2004-12-22 | Henrik Grubbström (Grubba) | | use `search' directly since it's undefined whether it returns
|
538a89 | 2000-01-21 | Fredrik Noring | | -1 (array) or 0 (mapping) during e.g. some data type emulation.
|
13670c | 2015-05-25 | Martin Nilsson | |
|
7b5804 | 2000-01-24 | Fredrik Noring | | Maybe we should use object->_has_value(value) provided that
the object implements it.
|
13670c | 2015-05-25 | Martin Nilsson | |
|
538a89 | 2000-01-21 | Fredrik Noring | | /Noring */
|
9cf6c8 | 2001-03-11 | Henrik Grubbström (Grubba) | |
|
01587a | 2003-06-03 | Martin Stjernholm | |
case T_MULTISET:
|
538a89 | 2000-01-21 | Fredrik Noring | | stack_swap();
f_values(1);
stack_swap();
|
01587a | 2003-06-03 | Martin Stjernholm | |
|
aa1488 | 2000-01-24 | Martin Stjernholm | | case T_STRING:
|
538a89 | 2000-01-21 | Fredrik Noring | | case T_ARRAY:
f_search(2);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[-1]) == T_INT)
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | Pike_sp[-1].u.integer = (Pike_sp[-1].u.integer != -1);
|
538a89 | 2000-01-21 | Fredrik Noring | | else
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("has_value", "Search gave incorrect result.\n", Pike_sp, args);
|
01587a | 2003-06-03 | Martin Stjernholm | | break;
default:
SIMPLE_ARG_TYPE_ERROR ("has_value", 1, "string|array|mapping|object|program");
|
538a89 | 2000-01-21 | Fredrik Noring | | }
}
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | |
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Add a new predefined constant.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! This function is often used to add builtin functions.
*! All programs compiled after the @[add_constant()] function has been
*! called can access @[value] by the name @[name].
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! If there is a constant called @[name] already, it will be replaced by
*! by the new definition. This will not affect already compiled programs.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Calling @[add_constant()] without a value will remove that name from
*! the list of constants. As with replacing, this will not affect already
*! compiled programs.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[all_constants()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_add_constant(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
if(args<1)
|
06bd61 | 2016-01-26 | Martin Nilsson | | SIMPLE_WRONG_NUM_ARGS_ERROR("add_constant", 1);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[-args]) != T_STRING)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("add_constant", 1, "string");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
if(args>1)
{
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | dmalloc_touch_svalue(Pike_sp-args+1);
low_add_efun(Pike_sp[-args].u.string, Pike_sp-args+1);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }else{
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | low_add_efun(Pike_sp[-args].u.string, 0);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
pop_n_elems(args);
}
|
f7fb1a | 2004-05-01 | Martin Stjernholm | | |
97e816 | 2004-05-01 | Martin Stjernholm | | *!
*! @[combine_path_unix()] concatenates in UNIX style, which also is
*! appropriate for e.g. URL:s ("/" separates path components and
*! absolute paths start with "/"). @[combine_path_nt()]
*! concatenates according to NT filesystem conventions ("/" and "\"
*! separates path components and there might be a drive letter in
*! front of absolute paths). @[combine_path_amigaos()] concatenates
*! according to AmigaOS filesystem conventions.
*!
*! @[combine_path()] is equivalent to @[combine_path_unix()] on UNIX-like
|
81ffaa | 2003-12-18 | Marcus Comstedt | | *! operating systems, and equivalent to @[combine_path_nt()] on NT-like
*! operating systems, and equivalent to @[combine_path_amigaos()] on
*! AmigaOS-like operating systems.
|
9849a7 | 2001-06-08 | Henrik Grubbström (Grubba) | | *!
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[getcwd()], @[Stdio.append_path()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
05459a | 1998-04-09 | Fredrik Hübinette (Hubbe) | |
|
8e0678 | 2001-06-07 | Fredrik Hübinette (Hubbe) | | #define NT_COMBINE_PATH
#include "combine_path.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
8e0678 | 2001-06-07 | Fredrik Hübinette (Hubbe) | | #define UNIX_COMBINE_PATH
#include "combine_path.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
81ffaa | 2003-12-18 | Marcus Comstedt | | #define AMIGAOS_COMBINE_PATH
#include "combine_path.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | |
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Return the type of zero.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! There are many types of zeros out there, or at least there are two.
*! One is returned by normal functions, and one returned by mapping
*! lookups and @[find_call_out()] when what you looked for wasn't there.
*! The only way to separate these two kinds of zeros is @[zero_type()].
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @returns
*! When doing a @[find_call_out()] or mapping lookup, @[zero_type()] on
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! this value will return @expr{1@} if there was no such thing present in
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! the mapping, or if no such @tt{call_out@} could be found.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! If the argument to @[zero_type()] is a destructed object or a function
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! in a destructed object, @expr{2@} will be returned.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! In all other cases @[zero_type()] will return @expr{0@} (zero).
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
8459bf | 2001-07-27 | Martin Nilsson | | *! @[find_call_out()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_zero_type(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args != 1)
SIMPLE_WRONG_NUM_ARGS_ERROR("zero_type",1);
|
8aefbc | 1999-03-19 | Fredrik Hübinette (Hubbe) | |
|
38b42c | 2015-05-21 | Tobias S. Josefowitz | | if(IS_DESTRUCTED(Pike_sp-args))
|
3f6d8f | 1996-11-26 | Fredrik Hübinette (Hubbe) | | {
pop_n_elems(args);
|
eaa4da | 2001-10-04 | Fredrik Hübinette (Hubbe) | | push_int(NUMBER_DESTRUCTED);
|
8e9fdf | 1996-12-04 | Fredrik Hübinette (Hubbe) | | }
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | else if(TYPEOF(Pike_sp[-args]) != T_INT)
|
8e9fdf | 1996-12-04 | Fredrik Hübinette (Hubbe) | | {
pop_n_elems(args);
|
eaa4da | 2001-10-04 | Fredrik Hübinette (Hubbe) | | push_int(0);
|
8e9fdf | 1996-12-04 | Fredrik Hübinette (Hubbe) | | }
|
eaa4da | 2001-10-04 | Fredrik Hübinette (Hubbe) | | else
|
8e9fdf | 1996-12-04 | Fredrik Hübinette (Hubbe) | | {
|
3f6d8f | 1996-11-26 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args-1);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | Pike_sp[-1].u.integer = SUBTYPEOF(Pike_sp[-1]);
SET_SVAL_SUBTYPE(Pike_sp[-1], NUMBER_NUMBER);
|
3f6d8f | 1996-11-26 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
263ea3 | 2014-08-18 | Per Hedbor | | static int generate_arg_for(node *n)
|
081147 | 2001-07-02 | Fredrik Hübinette (Hubbe) | | {
if(count_args(CDR(n)) != 1) return 0;
if(do_docode(CDR(n),DO_NOT_COPY) != 1)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Count args was wrong in generate_zero_type().\n");
|
263ea3 | 2014-08-18 | Per Hedbor | | return 1;
}
static int generate_zero_type(node *n)
{
struct compilation *c = THIS_COMPILATION;
if( generate_arg_for( n ) )
emit0(F_ZERO_TYPE);
else
return 0;
return 1;
}
static int generate_undefinedp(node *n)
{
struct compilation *c = THIS_COMPILATION;
if( generate_arg_for(n) )
emit0(F_UNDEFINEDP);
else
return 0;
return 1;
}
static int generate_destructedp(node *n)
{
struct compilation *c = THIS_COMPILATION;
if( generate_arg_for(n) )
emit0(F_DESTRUCTEDP);
else
return 0;
|
081147 | 2001-07-02 | Fredrik Hübinette (Hubbe) | | return 1;
}
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | |
|
053b2d | 2015-06-05 | Henrik Grubbström (Grubba) | | |
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Converts a string into an UTF16 compliant byte-stream.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
053b2d | 2015-06-05 | Henrik Grubbström (Grubba) | | *! @param s
*! String to convert to UTF16.
*!
*! @param byteorder
*! Byte-order for the output. One of:
*! @int
*! @value 0
*! Network (aka big-endian) byte-order (default).
*! @value 1
*! Little-endian byte-order.
*! @value 2
*! Native byte-order.
*! @endint
*!
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *! @note
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! 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.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Characters in range 0x010000 - 0x10ffff are encoded using surrogates.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
0b8d2f | 2013-06-17 | Martin Nilsson | | *! @[Charset.decoder()], @[string_to_utf8()], @[unicode_to_string()],
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[utf8_to_string()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_string_to_unicode(INT32 args)
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | | {
struct pike_string *in;
struct pike_string *out = NULL;
|
93b720 | 2000-08-14 | Henrik Grubbström (Grubba) | | ptrdiff_t len;
ptrdiff_t i;
|
053b2d | 2015-06-05 | Henrik Grubbström (Grubba) | | unsigned INT_TYPE byteorder = 0;
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | |
|
053b2d | 2015-06-05 | Henrik Grubbström (Grubba) | | get_all_args("string_to_unicode", args, "%W.%i", &in, &byteorder);
if (byteorder >= 2) {
if (byteorder == 2) {
#if PIKE_BYTEORDER == 1234
byteorder = 1;
#else
byteorder = 0;
#endif
} else {
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("string_to_unicode", 2, "int(0..2)|void");
|
053b2d | 2015-06-05 | Henrik Grubbström (Grubba) | | }
}
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | |
switch(in->size_shift) {
case 0:
len = in->len * 2;
out = begin_shared_string(len);
|
89a70c | 2000-08-28 | Henrik Grubbström (Grubba) | | if (len) {
|
21b12a | 2014-09-03 | Martin Nilsson | | memset(out->str, 0, len);
|
89a70c | 2000-08-28 | Henrik Grubbström (Grubba) | | for(i = in->len; i--;) {
|
053b2d | 2015-06-05 | Henrik Grubbström (Grubba) | | out->str[i * 2 + 1 - byteorder] = in->str[i];
|
89a70c | 2000-08-28 | Henrik Grubbström (Grubba) | | }
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | | }
out = end_shared_string(out);
break;
case 1:
len = in->len * 2;
out = begin_shared_string(len);
|
053b2d | 2015-06-05 | Henrik Grubbström (Grubba) | | if (byteorder ==
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #if (PIKE_BYTEORDER == 4321)
|
053b2d | 2015-06-05 | Henrik Grubbström (Grubba) | | 1
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | | #else
|
053b2d | 2015-06-05 | Henrik Grubbström (Grubba) | | 0
#endif
) {
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | | p_wchar1 *str1 = STR1(in);
for(i = in->len; i--;) {
unsigned INT32 c = str1[i];
|
053b2d | 2015-06-05 | Henrik Grubbström (Grubba) | | out->str[i * 2 + 1 - byteorder] = c & 0xff;
out->str[i * 2 + byteorder] = c >> 8;
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | | }
|
053b2d | 2015-06-05 | Henrik Grubbström (Grubba) | | } else {
memcpy(out->str, in->str, len);
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | | }
out = end_shared_string(out);
break;
case 2:
{
p_wchar2 *str2 = STR2(in);
|
93b720 | 2000-08-14 | Henrik Grubbström (Grubba) | | ptrdiff_t j;
|
01c108 | 1998-10-10 | Henrik Grubbström (Grubba) | | len = in->len * 2;
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | |
for(i = in->len; i--;) {
if (str2[i] > 0xfffd) {
if (str2[i] < 0x10000) {
|
368623 | 2014-08-18 | Martin Nilsson | | Pike_error("Illegal character 0x%04x (index %ld) "
"is not a Unicode character.",
str2[i], PTRDIFF_T_TO_LONG(i));
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | | }
if (str2[i] > 0x10ffff) {
|
368623 | 2014-08-18 | Martin Nilsson | | Pike_error("Character 0x%08x (index %ld) "
"is out of range (0x00000000..0x0010ffff).",
str2[i], PTRDIFF_T_TO_LONG(i));
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | | }
|
053b2d | 2015-06-05 | Henrik Grubbström (Grubba) | | |
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | | */
len += 2;
}
}
out = begin_shared_string(len);
|
01c108 | 1998-10-10 | Henrik Grubbström (Grubba) | | j = len;
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | | for(i = in->len; i--;) {
unsigned INT32 c = str2[i];
j -= 2;
if (c > 0xffff) {
c -= 0x10000;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
053b2d | 2015-06-05 | Henrik Grubbström (Grubba) | | out->str[j + 1 - byteorder] = c & 0xff;
out->str[j + byteorder] = 0xdc | ((c >> 8) & 0x03);
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | | j -= 2;
c >>= 10;
c |= 0xd800;
}
|
053b2d | 2015-06-05 | Henrik Grubbström (Grubba) | | out->str[j + 1 - byteorder] = c & 0xff;
out->str[j + byteorder] = c >> 8;
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | | }
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | | if (j) {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("string_to_unicode(): Indexing error: len:%ld, j:%ld.\n",
|
69bb40 | 2000-08-17 | Henrik Grubbström (Grubba) | | PTRDIFF_T_TO_LONG(len), PTRDIFF_T_TO_LONG(j));
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | | }
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #endif /* PIKE_DEBUG */
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | | out = end_shared_string(out);
}
break;
}
pop_n_elems(args);
push_string(out);
}
|
c5046a | 2015-06-05 | Henrik Grubbström (Grubba) | | |
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Converts an UTF16 byte-stream into a string.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
c5046a | 2015-06-05 | Henrik Grubbström (Grubba) | | *! @param s
*! String to convert to UTF16.
*!
*! @param byteorder
*! Default input byte-order. One of:
*! @int
*! @value 0
*! Network (aka big-endian) byte-order (default).
*! @value 1
*! Little-endian byte-order.
*! @value 2
*! Native byte-order.
*! @endint
*! Note that this argument is disregarded if @[s] starts with a BOM.
*!
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *! @seealso
|
0b8d2f | 2013-06-17 | Martin Nilsson | | *! @[Charset.decoder()], @[string_to_unicode()], @[string_to_utf8()],
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[utf8_to_string()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_unicode_to_string(INT32 args)
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | | {
struct pike_string *in;
struct pike_string *out = NULL;
|
f27279 | 2001-04-18 | Marcus Comstedt | | ptrdiff_t len, i, num_surrogates = 0;
|
c5046a | 2015-06-05 | Henrik Grubbström (Grubba) | | INT_TYPE byteorder = 0;
|
f27279 | 2001-04-18 | Marcus Comstedt | | int swab=0;
p_wchar1 surr1, surr2, surrmask, *str0;
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | |
|
c5046a | 2015-06-05 | Henrik Grubbström (Grubba) | | get_all_args("unicode_to_string", args, "%S.%i", &in, &byteorder);
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | |
if (in->len & 1) {
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | bad_arg_error("unicode_to_string", Pike_sp-args, args, 1, "string", Pike_sp-args,
|
d0d01b | 1999-03-20 | Henrik Grubbström (Grubba) | | "String length is odd.\n");
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | | }
|
c5046a | 2015-06-05 | Henrik Grubbström (Grubba) | | if (byteorder >= 2) {
if (byteorder == 2) {
#if PIKE_BYTEORDER == 1234
byteorder = 1;
#else
byteorder = 0;
#endif
} else {
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("unicode_to_string", 2, "int(0..2)|void");
|
c5046a | 2015-06-05 | Henrik Grubbström (Grubba) | | }
}
if (byteorder !=
#if PIKE_BYTEORDER == 1234
1
#else
0
#endif
) {
swab = 1;
}
|
f27279 | 2001-04-18 | Marcus Comstedt | |
str0 = (p_wchar1 *)in->str;
len = in->len;
|
2f1f3e | 2001-05-03 | Henrik Grubbström (Grubba) | | if (len && (str0[0] == 0xfeff)) {
|
f27279 | 2001-04-18 | Marcus Comstedt | |
swab = 0;
str0 ++;
len -= 2;
|
2f1f3e | 2001-05-03 | Henrik Grubbström (Grubba) | | } else if (len && (str0[0] == 0xfffe)) {
|
f27279 | 2001-04-18 | Marcus Comstedt | |
swab = 1;
str0 ++;
len -= 2;
} else {
|
c5046a | 2015-06-05 | Henrik Grubbström (Grubba) | |
|
f27279 | 2001-04-18 | Marcus Comstedt | | }
if (swab) {
surr1 = 0xd8;
surr2 = 0xdc;
surrmask = 0xfc;
} else {
surr1 = 0xd800;
surr2 = 0xdc00;
surrmask = 0xfc00;
}
for (i = len; i >= 4; i -= 2, str0++)
if ( (str0[0]&surrmask) == surr1 &&
(str0[1]&surrmask) == surr2 )
num_surrogates ++;
str0++;
len = len / 2 - num_surrogates;
out = begin_wide_shared_string(len, (num_surrogates? 2 : 1));
if (!swab) {
if (num_surrogates) {
p_wchar2 *str2 = STR2(out);
for (i = len; i--; --str0)
if ((str0[-1]&surrmask) == surr2 && num_surrogates &&
(str0[-2]&surrmask) == surr1) {
|
13670c | 2015-05-25 | Martin Nilsson | |
|
f27279 | 2001-04-18 | Marcus Comstedt | | str2[i] = ((str0[-2]&0x3ff)<<10) + (str0[-1]&0x3ff) + 0x10000;
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | |
|
f27279 | 2001-04-18 | Marcus Comstedt | | --str0;
--num_surrogates;
} else
str2[i] = str0[-1];
} else
|
c9d397 | 2014-09-03 | Martin Nilsson | | memcpy(out->str, str0-len, len*2);
|
f27279 | 2001-04-18 | Marcus Comstedt | | } else {
|
13670c | 2015-05-25 | Martin Nilsson | |
|
f27279 | 2001-04-18 | Marcus Comstedt | | if (num_surrogates) {
p_wchar2 *str2 = STR2(out);
|
2f1f3e | 2001-05-03 | Henrik Grubbström (Grubba) | | for (i = len; i--; --str0) {
|
f27279 | 2001-04-18 | Marcus Comstedt | |
if ((str0[-1]&surrmask) == surr2 && num_surrogates &&
(str0[-2]&surrmask) == surr1) {
|
13670c | 2015-05-25 | Martin Nilsson | |
|
2f1f3e | 2001-05-03 | Henrik Grubbström (Grubba) | | #if (PIKE_BYTEORDER == 4321)
|
bdafb5 | 2001-05-08 | Henrik Grubbström (Grubba) | | str2[i] = ((((unsigned char *)str0)[-3]&3)<<18) +
(((unsigned char *)str0)[-4]<<10) +
((((unsigned char *)str0)[-1]&3)<<8) +
((unsigned char *)str0)[-2] +
|
2f1f3e | 2001-05-03 | Henrik Grubbström (Grubba) | | 0x10000;
#else /* PIKE_BYTEORDER != 4321 */
|
f27279 | 2001-04-18 | Marcus Comstedt | | str2[i] = ((((unsigned char *)str0)[-4]&3)<<18) +
(((unsigned char *)str0)[-3]<<10) +
((((unsigned char *)str0)[-2]&3)<<8) +
((unsigned char *)str0)[-1] +
0x10000;
|
2f1f3e | 2001-05-03 | Henrik Grubbström (Grubba) | | #endif /* PIKE_BYTEORDER == 4321 */
|
f27279 | 2001-04-18 | Marcus Comstedt | | --str0;
--num_surrogates;
|
2f1f3e | 2001-05-03 | Henrik Grubbström (Grubba) | | } else {
#if (PIKE_BYTEORDER == 4321)
str2[i] = (((unsigned char *)str0)[-1]<<8) +
((unsigned char *)str0)[-2];
#else /* PIKE_BYTEORDER != 4321 */
|
f27279 | 2001-04-18 | Marcus Comstedt | | str2[i] = (((unsigned char *)str0)[-2]<<8) +
((unsigned char *)str0)[-1];
|
2f1f3e | 2001-05-03 | Henrik Grubbström (Grubba) | | #endif /* PIKE_BYTEORDER == 4321 */
}
}
|
f27279 | 2001-04-18 | Marcus Comstedt | | } else {
p_wchar1 *str1 = STR1(out);
|
2f1f3e | 2001-05-03 | Henrik Grubbström (Grubba) | | for (i = len; i--; --str0) {
#if (PIKE_BYTEORDER == 4321)
str1[i] = (((unsigned char *)str0)[-1]<<8) +
((unsigned char *)str0)[-2];
#else /* PIKE_BYTEORDER != 4321 */
|
f27279 | 2001-04-18 | Marcus Comstedt | | str1[i] = (((unsigned char *)str0)[-2]<<8) +
((unsigned char *)str0)[-1];
|
2f1f3e | 2001-05-03 | Henrik Grubbström (Grubba) | | #endif /* PIKE_BYTEORDER == 4321 */
}
|
4643ea | 1998-10-10 | Henrik Grubbström (Grubba) | | }
}
out = end_shared_string(out);
pop_n_elems(args);
push_string(out);
}
|
976573 | 2014-05-22 | Per Hedbor | |
static void f_string_filter_non_unicode( INT32 args )
{
struct pike_string *in;
INT32 min,max;
int i;
static const p_wchar1 replace = 0xfffd;
static const PCHARP repl_char = {(void*)&replace,1};
get_all_args("filter_non_unicode", args, "%W", &in);
check_string_range( in, 1, &min, &max );
if( !in->len || (min >= 0 && max < 0xd800) )
return;
if( (max < 0 || min > 0x10ffff) || (max < 0xe000 && min > 0xd7ff) )
{
debug_make_shared_binary_pcharp( repl_char, 1 );
push_int( in->len );
o_multiply();
}
else
{
struct string_builder out;
init_string_builder_alloc( &out, in->len, 1 );
for( i=0; i<in->len; i++ )
{
p_wchar2 c = index_shared_string(in,i);
if( (c < 0 || c > 0x10ffff) || (c>0xd7ff && c<0xe000) )
string_builder_append( &out, repl_char, 1 );
else
string_builder_putchar( &out, c );
}
push_string( finish_string_builder( &out ) );
}
}
|
f23c5d | 2007-06-02 | Martin Bähr | | |
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
dee894 | 2005-04-02 | Martin Stjernholm | | *! Converts a string into an UTF-8 compliant byte-stream.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @note
|
dee894 | 2005-04-02 | Martin Stjernholm | | *! 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@}.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
dee894 | 2005-04-02 | Martin Stjernholm | | *! 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.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
0b8d2f | 2013-06-17 | Martin Nilsson | | *! @[Charset.encoder()], @[string_to_unicode()],
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[unicode_to_string()], @[utf8_to_string()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
77cc59 | 2003-11-14 | Martin Stjernholm | | PMOD_EXPORT void f_string_to_utf8(INT32 args)
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | {
|
93b720 | 2000-08-14 | Henrik Grubbström (Grubba) | | ptrdiff_t len;
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | struct pike_string *in;
struct pike_string *out;
|
69bb40 | 2000-08-17 | Henrik Grubbström (Grubba) | | ptrdiff_t i,j;
|
2adf00 | 2004-02-29 | Martin Stjernholm | | INT_TYPE extended = 0;
|
52b5d9 | 2013-05-17 | Arne Goedeke | | PCHARP src;
|
1ac9ce | 2013-06-10 | Arne Goedeke | | INT32 min, max;
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | |
|
2adf00 | 2004-02-29 | Martin Stjernholm | | get_all_args("string_to_utf8", args, "%W.%i", &in, &extended);
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | |
len = in->len;
|
1ac9ce | 2013-06-10 | Arne Goedeke | | check_string_range(in, 1, &min, &max);
if (min >= 0 && max <= 0x7f) {
pop_n_elems(args - 1);
return;
}
|
52b5d9 | 2013-05-17 | Arne Goedeke | | for(i=0,src=MKPCHARP_STR(in); i < in->len; INC_PCHARP(src,1),i++) {
unsigned INT32 c = EXTRACT_PCHARP(src);
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | if (c & ~0x7f) {
len++;
if (c & ~0x7ff) {
len++;
if (c & ~0xffff) {
len++;
|
dee894 | 2005-04-02 | Martin Stjernholm | | if (!extended && c > 0x10ffff)
bad_arg_error ("string_to_utf8", Pike_sp - args, args, 1,
NULL, Pike_sp - args,
"Character 0x%08x at index %"PRINTPTRDIFFT"d is "
"outside the allowed range.\n",
c, i);
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | if (c & ~0x1fffff) {
len++;
if (c & ~0x3ffffff) {
len++;
if (c & ~0x7fffffff) {
len++;
}
}
}
}
|
dee894 | 2005-04-02 | Martin Stjernholm | | else if (!extended && c >= 0xd800 && c <= 0xdfff)
bad_arg_error ("string_to_utf8", Pike_sp - args, args, 1,
NULL, Pike_sp - args,
"Character 0x%08x at index %"PRINTPTRDIFFT"d is "
"in the surrogate range and therefore invalid.\n",
c, i);
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | }
}
}
if (len == in->len) {
|
8e3f35 | 1998-10-23 | Henrik Grubbström (Grubba) | |
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | pop_n_elems(args - 1);
return;
}
out = begin_shared_string(len);
|
52b5d9 | 2013-05-17 | Arne Goedeke | | for(i=j=0,src=MKPCHARP_STR(in); i < in->len; INC_PCHARP(src,1),i++) {
unsigned INT32 c = EXTRACT_PCHARP(src);
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | if (!(c & ~0x7f)) {
out->str[j++] = c;
} else if (!(c & ~0x7ff)) {
out->str[j++] = 0xc0 | (c >> 6);
out->str[j++] = 0x80 | (c & 0x3f);
} else if (!(c & ~0xffff)) {
out->str[j++] = 0xe0 | (c >> 12);
out->str[j++] = 0x80 | ((c >> 6) & 0x3f);
out->str[j++] = 0x80 | (c & 0x3f);
} else if (!(c & ~0x1fffff)) {
out->str[j++] = 0xf0 | (c >> 18);
out->str[j++] = 0x80 | ((c >> 12) & 0x3f);
out->str[j++] = 0x80 | ((c >> 6) & 0x3f);
out->str[j++] = 0x80 | (c & 0x3f);
} else if (!(c & ~0x3ffffff)) {
out->str[j++] = 0xf8 | (c >> 24);
out->str[j++] = 0x80 | ((c >> 18) & 0x3f);
out->str[j++] = 0x80 | ((c >> 12) & 0x3f);
out->str[j++] = 0x80 | ((c >> 6) & 0x3f);
out->str[j++] = 0x80 | (c & 0x3f);
} else if (!(c & ~0x7fffffff)) {
out->str[j++] = 0xfc | (c >> 30);
out->str[j++] = 0x80 | ((c >> 24) & 0x3f);
out->str[j++] = 0x80 | ((c >> 18) & 0x3f);
out->str[j++] = 0x80 | ((c >> 12) & 0x3f);
out->str[j++] = 0x80 | ((c >> 6) & 0x3f);
out->str[j++] = 0x80 | (c & 0x3f);
} else {
|
bd6739 | 2015-10-14 | Martin Nilsson | | out->str[j++] = (char)0xfe;
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | out->str[j++] = 0x80 | ((c >> 30) & 0x3f);
out->str[j++] = 0x80 | ((c >> 24) & 0x3f);
out->str[j++] = 0x80 | ((c >> 18) & 0x3f);
out->str[j++] = 0x80 | ((c >> 12) & 0x3f);
out->str[j++] = 0x80 | ((c >> 6) & 0x3f);
out->str[j++] = 0x80 | (c & 0x3f);
}
}
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | if (len != j) {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("string_to_utf8(): Calculated and actual lengths differ: "
|
dee894 | 2005-04-02 | Martin Stjernholm | | "%"PRINTPTRDIFFT"d != %"PRINTPTRDIFFT"d\n", len, j);
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | }
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #endif /* PIKE_DEBUG */
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | out = end_shared_string(out);
pop_n_elems(args);
push_string(out);
}
|
f23c5d | 2007-06-02 | Martin Bähr | | |
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
dee894 | 2005-04-02 | Martin Stjernholm | | *! Converts an UTF-8 byte-stream into a string.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
6aebbf | 2012-02-23 | Henrik Grubbström (Grubba) | | *! @param s
*! String of UTF-8 encoded data to decode.
*!
*! @param extended
*! Bitmask with extension options.
*! @int
*! @value 1
*! Accept and decode the extension used by @[string_to_utf8()].
*! @value 2
*! Accept and decode UTF-8 encoded UTF-16 (ie accept and
*! decode valid surrogates).
*! @endint
*!
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *! @note
|
dee894 | 2005-04-02 | Martin Stjernholm | | *! Throws an error if the stream is not a legal UTF-8 byte-stream.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
dee894 | 2005-04-02 | Martin Stjernholm | | *! @note
|
974d4a | 2015-08-22 | Martin Nilsson | | *! In conformance with @rfc{3629@} and Unicode 3.1 and later,
|
793182 | 2005-08-01 | Martin Stjernholm | | *! non-shortest forms are not decoded. An error is thrown instead.
|
dee894 | 2005-04-02 | Martin Stjernholm | | *!
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *! @seealso
|
0b8d2f | 2013-06-17 | Martin Nilsson | | *! @[Charset.encoder()], @[string_to_unicode()], @[string_to_utf8()],
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[unicode_to_string()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_utf8_to_string(INT32 args)
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | {
struct pike_string *in;
struct pike_string *out;
|
dee894 | 2005-04-02 | Martin Stjernholm | | ptrdiff_t len = 0;
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | int shift = 0;
|
cc724f | 2005-05-05 | Martin Nilsson | | ptrdiff_t i,j=0;
|
2adf00 | 2004-02-29 | Martin Stjernholm | | INT_TYPE extended = 0;
|
1ac9ce | 2013-06-10 | Arne Goedeke | | INT32 min, max;
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | |
|
2adf00 | 2004-02-29 | Martin Stjernholm | | get_all_args("utf8_to_string", args, "%S.%i", &in, &extended);
|
ed6590 | 1998-10-31 | Henrik Grubbström (Grubba) | |
|
1ac9ce | 2013-06-10 | Arne Goedeke | | check_string_range(in, 1, &min, &max);
if (min >= 0 && max <= 0x7f) {
pop_n_elems(args - 1);
return;
}
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | for(i=0; i < in->len; i++) {
|
57dd67 | 2005-04-02 | Martin Stjernholm | | unsigned int c = STR0(in)[i];
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | len++;
if (c & 0x80) {
int cont = 0;
|
dee894 | 2005-04-02 | Martin Stjernholm | |
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | if ((c & 0xc0) == 0x80) {
|
dee894 | 2005-04-02 | Martin Stjernholm | | bad_arg_error ("utf8_to_string", Pike_sp - args, args, 1,
NULL, Pike_sp - args,
"Invalid continuation character 0x%02x "
"at index %"PRINTPTRDIFFT"d.\n",
c, i);
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | }
|
dee894 | 2005-04-02 | Martin Stjernholm | |
|
6aebbf | 2012-02-23 | Henrik Grubbström (Grubba) | | #define GET_CHAR(in, i, c) do { \
|
dee894 | 2005-04-02 | Martin Stjernholm | | i++; \
if (i >= in->len) \
bad_arg_error ("utf8_to_string", Pike_sp - args, args, 1, \
NULL, Pike_sp - args, \
"Truncated UTF-8 sequence at end of string.\n"); \
|
57dd67 | 2005-04-02 | Martin Stjernholm | | c = STR0 (in)[i]; \
|
6aebbf | 2012-02-23 | Henrik Grubbström (Grubba) | | } while(0)
#define GET_CONT_CHAR(in, i, c) do { \
GET_CHAR(in, i, c); \
|
dee894 | 2005-04-02 | Martin Stjernholm | | if ((c & 0xc0) != 0x80) \
bad_arg_error ("utf8_to_string", Pike_sp - args, args, 1, \
NULL, Pike_sp - args, \
"Expected continuation character at index %d, " \
"got 0x%02x.\n", \
i, c); \
} while (0)
#define UTF8_SEQ_ERROR(prefix, c, i, problem) do { \
bad_arg_error ("utf8_to_string", Pike_sp - args, args, 1, \
NULL, Pike_sp - args, \
"UTF-8 sequence beginning with %s0x%02x " \
"at index %"PRINTPTRDIFFT"d %s.\n", \
prefix, c, i, problem); \
} while (0)
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | if ((c & 0xe0) == 0xc0) {
|
dee894 | 2005-04-02 | Martin Stjernholm | | if (!(c & 0x1e))
UTF8_SEQ_ERROR ("", c, i, "is a non-shortest form");
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | cont = 1;
if (c & 0x1c) {
if (shift < 1) {
shift = 1;
}
}
|
dee894 | 2005-04-02 | Martin Stjernholm | | }
else if ((c & 0xf0) == 0xe0) {
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | |
|
dee894 | 2005-04-02 | Martin Stjernholm | | if (c == 0xe0) {
GET_CONT_CHAR (in, i, c);
if (!(c & 0x20))
UTF8_SEQ_ERROR ("0xe0 ", c, i - 1, "is a non-shortest form");
cont = 1;
}
|
6aebbf | 2012-02-23 | Henrik Grubbström (Grubba) | | else if (!(extended & 1) && c == 0xed) {
|
dee894 | 2005-04-02 | Martin Stjernholm | | GET_CONT_CHAR (in, i, c);
|
6aebbf | 2012-02-23 | Henrik Grubbström (Grubba) | | if (c & 0x20) {
if (!(extended & 2)) {
UTF8_SEQ_ERROR ("0xed ", c, i - 1, "would decode to "
"a UTF-16 surrogate character");
}
if (c & 0x10) {
UTF8_SEQ_ERROR ("0xed ", c, i - 1, "would decode to "
"a UTF-16 low surrogate character");
}
GET_CONT_CHAR(in, i, c);
GET_CHAR (in, i, c);
if (c != 0xed) {
UTF8_SEQ_ERROR ("", c, i-1, "UTF-16 low surrogate "
"character required");
}
GET_CONT_CHAR (in, i, c);
if ((c & 0xf0) != 0xb0) {
UTF8_SEQ_ERROR ("0xed ", c, i-1, "UTF-16 low surrogate "
"character required");
}
shift = 2;
}
|
dee894 | 2005-04-02 | Martin Stjernholm | | cont = 1;
}
else
cont = 2;
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | if (shift < 1) {
shift = 1;
}
|
dee894 | 2005-04-02 | Martin Stjernholm | | }
else {
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | if ((c & 0xf8) == 0xf0) {
|
dee894 | 2005-04-02 | Martin Stjernholm | | if (c == 0xf0) {
GET_CONT_CHAR (in, i, c);
if (!(c & 0x30))
UTF8_SEQ_ERROR ("0xf0 ", c, i - 1, "is a non-shortest form");
cont = 2;
|
ed6590 | 1998-10-31 | Henrik Grubbström (Grubba) | | }
|
6aebbf | 2012-02-23 | Henrik Grubbström (Grubba) | | else if (!(extended & 1)) {
|
dee894 | 2005-04-02 | Martin Stjernholm | | if (c > 0xf4)
UTF8_SEQ_ERROR ("", c, i, "would decode to "
"a character outside the valid UTF-8 range");
else if (c == 0xf4) {
GET_CONT_CHAR (in, i, c);
if (c > 0x8f)
UTF8_SEQ_ERROR ("0xf4 ", c, i - 1, "would decode to "
"a character outside the valid UTF-8 range");
cont = 2;
}
else
cont = 3;
}
else
cont = 3;
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | }
|
dee894 | 2005-04-02 | Martin Stjernholm | |
else if (c == 0xff)
bad_arg_error ("utf8_to_string", Pike_sp - args, args, 1,
NULL, Pike_sp - args,
"Invalid character 0xff at index %"PRINTPTRDIFFT"d.\n",
i);
|
6aebbf | 2012-02-23 | Henrik Grubbström (Grubba) | | else if (!(extended & 1))
|
dee894 | 2005-04-02 | Martin Stjernholm | | UTF8_SEQ_ERROR ("", c, i, "would decode to "
"a character outside the valid UTF-8 range");
else {
if ((c & 0xfc) == 0xf8) {
if (c == 0xf8) {
GET_CONT_CHAR (in, i, c);
if (!(c & 0x38))
UTF8_SEQ_ERROR ("0xf8 ", c, i - 1, "is a non-shortest form");
cont = 3;
}
else
cont = 4;
} else if ((c & 0xfe) == 0xfc) {
if (c == 0xfc) {
GET_CONT_CHAR (in, i, c);
if (!(c & 0x3c))
UTF8_SEQ_ERROR ("0xfc ", c, i - 1, "is a non-shortest form");
cont = 4;
}
else
cont = 5;
} else if (c == 0xfe) {
GET_CONT_CHAR (in, i, c);
if (!(c & 0x3e))
UTF8_SEQ_ERROR ("0xfe ", c, i - 1, "is a non-shortest form");
else if (c & 0x3c)
UTF8_SEQ_ERROR ("0xfe ", c, i - 1, "would decode to "
"a too large character value");
cont = 5;
}
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | }
|
57dd67 | 2005-04-02 | Martin Stjernholm | |
if (shift < 2)
shift = 2;
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | }
|
dee894 | 2005-04-02 | Martin Stjernholm | |
while(cont--)
GET_CONT_CHAR (in, i, c);
|
57dd67 | 2005-04-02 | Martin Stjernholm | |
|
6aebbf | 2012-02-23 | Henrik Grubbström (Grubba) | | #undef GET_CHAR
|
57dd67 | 2005-04-02 | Martin Stjernholm | | #undef GET_CONT_CHAR
#undef UTF8_SEQ_ERROR
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | }
}
if (len == in->len) {
pop_n_elems(args-1);
return;
}
out = begin_wide_shared_string(len, shift);
|
57dd67 | 2005-04-02 | Martin Stjernholm | | switch (shift) {
case 0: {
|
cfd642 | 2005-04-02 | Martin Stjernholm | | p_wchar0 *out_str = STR0 (out);
|
cc724f | 2005-05-05 | Martin Nilsson | | for(i=0; i < in->len;) {
|
57dd67 | 2005-04-02 | Martin Stjernholm | | unsigned int c = STR0(in)[i++];
if (c & 0x80) {
unsigned int c2 = STR0(in)[i++] & 0x3f;
c &= 0x1f;
c = (c << 6) | c2;
}
out_str[j++] = c;
}
break;
}
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | |
|
57dd67 | 2005-04-02 | Martin Stjernholm | | case 1: {
|
cfd642 | 2005-04-02 | Martin Stjernholm | | p_wchar1 *out_str = STR1 (out);
|
cc724f | 2005-05-05 | Martin Nilsson | | for(i=0; i < in->len;) {
|
57dd67 | 2005-04-02 | Martin Stjernholm | | unsigned int c = STR0(in)[i++];
if (c & 0x80) {
if ((c & 0xe0) == 0xc0) {
unsigned int c2 = STR0(in)[i++] & 0x3f;
c &= 0x1f;
c = (c << 6) | c2;
} else {
unsigned int c2 = STR0(in)[i++] & 0x3f;
unsigned int c3 = STR0(in)[i++] & 0x3f;
c &= 0x0f;
c = (c << 12) | (c2 << 6) | c3;
}
}
out_str[j++] = c;
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | }
|
57dd67 | 2005-04-02 | Martin Stjernholm | | break;
}
case 2: {
|
cfd642 | 2005-04-02 | Martin Stjernholm | | p_wchar2 *out_str = STR2 (out);
|
cc724f | 2005-05-05 | Martin Nilsson | | for(i=0; i < in->len;) {
|
57dd67 | 2005-04-02 | Martin Stjernholm | | unsigned int c = STR0(in)[i++];
if (c & 0x80) {
int cont = 0;
if ((c & 0xe0) == 0xc0) {
cont = 1;
c &= 0x1f;
} else if ((c & 0xf0) == 0xe0) {
cont = 2;
c &= 0x0f;
} else if ((c & 0xf8) == 0xf0) {
cont = 3;
c &= 0x07;
} else if ((c & 0xfc) == 0xf8) {
cont = 4;
c &= 0x03;
} else if ((c & 0xfe) == 0xfc) {
cont = 5;
c &= 0x01;
} else {
cont = 6;
c = 0;
}
while(cont--) {
unsigned int c2 = STR0(in)[i++] & 0x3f;
c = (c << 6) | c2;
}
|
6aebbf | 2012-02-23 | Henrik Grubbström (Grubba) | | if ((extended & 2) && (c & 0xfc00) == 0xdc00) {
c &= 0x3ff;
|
941222 | 2012-02-23 | Henrik Grubbström (Grubba) | | c |= ((out_str[--j] & 0x3ff)<<10) + 0x10000;
|
6aebbf | 2012-02-23 | Henrik Grubbström (Grubba) | | }
|
57dd67 | 2005-04-02 | Martin Stjernholm | | }
out_str[j++] = c;
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | }
|
57dd67 | 2005-04-02 | Martin Stjernholm | | break;
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | }
}
|
57dd67 | 2005-04-02 | Martin Stjernholm | |
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | if (j != len) {
|
368623 | 2014-08-18 | Martin Nilsson | | Pike_fatal("Calculated and actual lengths differ: "
|
2d76f2 | 2005-05-20 | Martin Stjernholm | | "%"PRINTPTRDIFFT"d != %"PRINTPTRDIFFT"d\n",
|
368623 | 2014-08-18 | Martin Nilsson | | len, j);
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | }
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #endif /* PIKE_DEBUG */
|
57dd67 | 2005-04-02 | Martin Stjernholm | | out = low_end_shared_string(out);
|
cfd642 | 2005-04-02 | Martin Stjernholm | | #ifdef PIKE_DEBUG
check_string (out);
#endif
|
be4077 | 1998-10-15 | Henrik Grubbström (Grubba) | | pop_n_elems(args);
push_string(out);
}
|
f23c5d | 2007-06-02 | Martin Bähr | | |
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
aa0bdf | 1999-11-08 | Per Hedbor | | static void f_parse_pike_type( INT32 args )
{
|
babd87 | 2001-02-23 | Henrik Grubbström (Grubba) | | struct pike_type *t;
|
1f88bf | 2001-09-24 | Henrik Grubbström (Grubba) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if( !args || TYPEOF(Pike_sp[-1]) != T_STRING ||
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | Pike_sp[-1].u.string->size_shift )
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | Pike_error( "__parse_pike_type requires a 8bit string as its first argument\n" );
|
babd87 | 2001-02-23 | Henrik Grubbström (Grubba) | | t = parse_type( (char *)STR0(Pike_sp[-1].u.string) );
|
aa0bdf | 1999-11-08 | Per Hedbor | | pop_stack();
|
babd87 | 2001-02-23 | Henrik Grubbström (Grubba) | |
|
986b52 | 2001-03-17 | Henrik Grubbström (Grubba) | | push_string(type_to_string(t));
free_type(t);
|
aa0bdf | 1999-11-08 | Per Hedbor | | }
|
718adc | 2014-02-24 | Henrik Grubbström (Grubba) | |
|
cf27cc | 2007-04-20 | Henrik Grubbström (Grubba) | | *!
*! Return the resulting type from a soft cast of @[from] to @[to].
*/
static void f___soft_cast(INT32 args)
{
struct pike_type *res;
|
24adc7 | 2008-09-26 | Martin Nilsson | | if (args < 2) Pike_error("Bad number of arguments to __soft_cast().\n");
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-args]) != PIKE_T_TYPE) {
|
24adc7 | 2008-09-26 | Martin Nilsson | | Pike_error("Bad argument 1 to __soft_cast() expected type.\n");
|
cf27cc | 2007-04-20 | Henrik Grubbström (Grubba) | | }
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[1-args]) != PIKE_T_TYPE) {
|
24adc7 | 2008-09-26 | Martin Nilsson | | Pike_error("Bad argument 2 to __soft_cast() expected type.\n");
|
cf27cc | 2007-04-20 | Henrik Grubbström (Grubba) | | }
if (!(res = soft_cast(Pike_sp[-args].u.type,
Pike_sp[1-args].u.type, 0))) {
pop_n_elems(args);
push_undefined();
} else {
pop_n_elems(args);
push_type_value(res);
}
}
|
718adc | 2014-02-24 | Henrik Grubbström (Grubba) | | |
44fe36 | 2007-03-26 | Henrik Grubbström (Grubba) | | *!
*! Check whether a function of type @[fun_type] may be called
*! with a first argument of type @[arg_type].
*!
|
88d195 | 2007-03-28 | Henrik Grubbström (Grubba) | | *! @param flags
*! The following flags are currently defined:
*! @int
*! @value 1
*! Strict types. Fail if not all possible values in @[arg_type]
*! are valid as the first argument to @[fun_type].
*! @value 2
*! Last argument. @[arg_type] is the last argument to @[fun_type].
*! @value 3
*! Both strict types and last argument as above.
*! @endint
*!
|
44fe36 | 2007-03-26 | Henrik Grubbström (Grubba) | | *! @returns
*! Returns a continuation type on success.
*!
*! Returns @tt{0@} (zero) on failure.
*/
|
34d9b5 | 2007-03-29 | Henrik Grubbström (Grubba) | | static void f___low_check_call(INT32 args)
|
44fe36 | 2007-03-26 | Henrik Grubbström (Grubba) | | {
struct pike_type *res;
|
960b40 | 2011-12-09 | Henrik Grubbström (Grubba) | | INT32 flags = CALL_NOT_LAST_ARG;
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | struct svalue *sval = NULL;
|
34d9b5 | 2007-03-29 | Henrik Grubbström (Grubba) | | if (args < 2) Pike_error("Bad number of arguments to __low_check_call().\n");
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-args]) != PIKE_T_TYPE) {
|
34d9b5 | 2007-03-29 | Henrik Grubbström (Grubba) | | Pike_error("Bad argument 1 to __low_check_call() expected type.\n");
|
44fe36 | 2007-03-26 | Henrik Grubbström (Grubba) | | }
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[1-args]) != PIKE_T_TYPE) {
|
34d9b5 | 2007-03-29 | Henrik Grubbström (Grubba) | | Pike_error("Bad argument 2 to __low_check_call() expected type.\n");
|
88d195 | 2007-03-28 | Henrik Grubbström (Grubba) | | }
if (args > 2) {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[2-args]) != PIKE_T_INT) {
|
34d9b5 | 2007-03-29 | Henrik Grubbström (Grubba) | | Pike_error("Bad argument 3 to __low_check_call() expected int.\n");
|
88d195 | 2007-03-28 | Henrik Grubbström (Grubba) | | }
|
960b40 | 2011-12-09 | Henrik Grubbström (Grubba) | | flags = Pike_sp[2-args].u.integer ^ CALL_NOT_LAST_ARG;
|
44fe36 | 2007-03-26 | Henrik Grubbström (Grubba) | | }
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | if (args > 3) sval = Pike_sp + 3 - args;
|
88d195 | 2007-03-28 | Henrik Grubbström (Grubba) | | if (!(res = low_new_check_call(Pike_sp[-args].u.type,
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | Pike_sp[1-args].u.type, flags, sval))) {
|
44fe36 | 2007-03-26 | Henrik Grubbström (Grubba) | | pop_n_elems(args);
push_undefined();
} else {
pop_n_elems(args);
push_type_value(res);
}
}
|
718adc | 2014-02-24 | Henrik Grubbström (Grubba) | | |
44fe36 | 2007-03-26 | Henrik Grubbström (Grubba) | | *!
*! Check what a function of the type @[fun_type] will
*! return if called with no arguments.
*!
*! @returns
*! Returns the type of the returned value on success
*!
*! Returns @tt{0@} (zero) on failure.
*/
static void f___get_return_type(INT32 args)
{
struct pike_type *res;
if (args != 1) {
Pike_error("Bad number of arguments to __get_return_type().\n");
}
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-1]) != PIKE_T_TYPE) {
|
44fe36 | 2007-03-26 | Henrik Grubbström (Grubba) | | Pike_error("Bad argument 1 to __get_return_type() expected type.\n");
}
if (!(res = new_get_return_type(Pike_sp[-1].u.type, 0))) {
pop_n_elems(args);
push_undefined();
} else {
pop_n_elems(args);
push_type_value(res);
}
}
|
718adc | 2014-02-24 | Henrik Grubbström (Grubba) | | |
44fe36 | 2007-03-26 | Henrik Grubbström (Grubba) | | *!
*! Check if a function of the type @[fun_type] may be called
*! with an argument, and return the type of that argument.
*!
*! @returns
*! Returns the expected type of the first argument to the function.
*!
*! Returns @tt{0@} (zero) if a function of the type @[fun_type]
*! may not be called with any argument, or if it is not callable.
*/
|
c91468 | 2014-04-07 | Henrik Grubbström (Grubba) | | void f___get_first_arg_type(INT32 args)
|
44fe36 | 2007-03-26 | Henrik Grubbström (Grubba) | | {
struct pike_type *res;
if (args != 1) {
Pike_error("Bad number of arguments to __get_first_arg_type().\n");
}
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-1]) != PIKE_T_TYPE) {
|
44fe36 | 2007-03-26 | Henrik Grubbström (Grubba) | | Pike_error("Bad argument 1 to __get_first_arg_type() expected type.\n");
}
|
301daf | 2011-12-09 | Henrik Grubbström (Grubba) | | if (!(res = get_first_arg_type(Pike_sp[-1].u.type, CALL_NOT_LAST_ARG)) &&
!(res = get_first_arg_type(Pike_sp[-1].u.type, 0))) {
|
44fe36 | 2007-03-26 | Henrik Grubbström (Grubba) | | pop_n_elems(args);
push_undefined();
} else {
pop_n_elems(args);
push_type_value(res);
}
}
|
718adc | 2014-02-24 | Henrik Grubbström (Grubba) | | |
a54cfc | 2011-01-17 | Henrik Grubbström (Grubba) | | *!
*! Get the attribute markers for a type.
*!
*! @returns
*! Returns an array with the attributes for the type @[t].
*!
*! @seealso
|
718adc | 2014-02-24 | Henrik Grubbström (Grubba) | | *! @[get_return_type()], @[get_first_arg_type()]
|
a54cfc | 2011-01-17 | Henrik Grubbström (Grubba) | | */
static void f___get_type_attributes(INT32 args)
{
struct pike_type *t;
int count = 0;
if (args != 1) {
Pike_error("Bad number of arguments to __get_type_attributes().\n");
}
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-1]) != PIKE_T_TYPE) {
|
a54cfc | 2011-01-17 | Henrik Grubbström (Grubba) | | Pike_error("Bad argument 1 to __get_type_attributes() expected type.\n");
}
t = Pike_sp[-1].u.type;
while ((t->type == PIKE_T_ATTRIBUTE) || (t->type == PIKE_T_NAME)) {
if (t->type == PIKE_T_ATTRIBUTE) {
ref_push_string((struct pike_string *)t->car);
count++;
}
t = t->cdr;
}
f_aggregate(count);
stack_pop_n_elems_keep_top(args);
}
|
718adc | 2014-02-24 | Henrik Grubbström (Grubba) | |
|
19febd | 2002-02-14 | Martin Nilsson | | |
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Returns a mapping containing all global constants, indexed on the name
*! of the constant, and with the value of the constant as value.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[add_constant()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_all_constants(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
pop_n_elems(args);
|
0e8861 | 1998-04-16 | Fredrik Hübinette (Hubbe) | | ref_push_mapping(get_builtin_constants());
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
e290f3 | 2006-01-27 | Henrik Grubbström (Grubba) | | |
5671ce | 2006-01-26 | Henrik Grubbström (Grubba) | | *!
*! Returns the currently active compilation compatibility handler, or
*! @tt{0@} (zero) if none is active.
*!
*! @note
*! This function should only be used during a call of @[compile()].
*!
*! @seealso
*! @[get_active_error_handler()], @[compile()],
|
e290f3 | 2006-01-27 | Henrik Grubbström (Grubba) | | *! @[master()->get_compilation_handler()], @[CompilationHandler]
|
5671ce | 2006-01-26 | Henrik Grubbström (Grubba) | | */
PMOD_EXPORT void f_get_active_compilation_handler(INT32 args)
{
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct compilation *c = NULL;
if (compilation_program) {
struct pike_frame *compiler_frame = Pike_fp;
while (compiler_frame &&
(compiler_frame->context->prog != compilation_program)) {
compiler_frame = compiler_frame->next;
}
if (compiler_frame) {
c = (struct compilation *)compiler_frame->current_storage;
}
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
5671ce | 2006-01-26 | Henrik Grubbström (Grubba) | | pop_n_elems(args);
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | if (c && c->compat_handler) {
ref_push_object(c->compat_handler);
|
5671ce | 2006-01-26 | Henrik Grubbström (Grubba) | | } else {
push_int(0);
}
}
|
e290f3 | 2006-01-27 | Henrik Grubbström (Grubba) | | |
5671ce | 2006-01-26 | Henrik Grubbström (Grubba) | | *!
*! Returns the currently active compilation error handler
|
e290f3 | 2006-01-27 | Henrik Grubbström (Grubba) | | *! (second argument to @[compile()]), or @tt{0@} (zero) if none
|
5671ce | 2006-01-26 | Henrik Grubbström (Grubba) | | *! is active.
*!
*! @note
*! This function should only be used during a call of @[compile()].
*!
*! @seealso
|
e290f3 | 2006-01-27 | Henrik Grubbström (Grubba) | | *! @[get_active_compilation_handler()], @[compile()], @[CompilationHandler]
|
5671ce | 2006-01-26 | Henrik Grubbström (Grubba) | | */
PMOD_EXPORT void f_get_active_error_handler(INT32 args)
{
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct compilation *c = NULL;
if (compilation_program) {
struct pike_frame *compiler_frame = Pike_fp;
while (compiler_frame &&
(compiler_frame->context->prog != compilation_program)) {
compiler_frame = compiler_frame->next;
}
if (compiler_frame) {
c = (struct compilation *)compiler_frame->current_storage;
}
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
5671ce | 2006-01-26 | Henrik Grubbström (Grubba) | | pop_n_elems(args);
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | if (c && c->handler) {
ref_push_object(c->handler);
|
5671ce | 2006-01-26 | Henrik Grubbström (Grubba) | | } else {
push_int(0);
}
}
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | |
2523ce | 2003-04-28 | Martin Stjernholm | | *! @decl array allocate(int size, mixed init)
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
2523ce | 2003-04-28 | Martin Stjernholm | | *! Allocate an array of @[size] elements. If @[init] is specified
*! then each element is initialized by copying that value
*! recursively.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[sizeof()], @[aggregate()], @[arrayp()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_allocate(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
3ee2a6 | 2004-11-14 | Alexander Demenshin | | INT_TYPE size;
|
8267f4 | 1998-01-28 | Fredrik Hübinette (Hubbe) | | struct array *a;
|
e6c089 | 2010-07-27 | Martin Stjernholm | | struct svalue *init = NULL;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
87a342 | 2004-05-13 | Martin Nilsson | | get_all_args("allocate", args, "%+.%*", &size, &init);
|
2cff8d | 2004-11-14 | Martin Stjernholm | | if (size > MAX_INT32)
SIMPLE_ARG_ERROR ("allocate", 1, "Integer too large to use as array size.");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
8267f4 | 1998-01-28 | Fredrik Hübinette (Hubbe) | | a=allocate_array(size);
if(args>1)
{
INT32 e;
|
2523ce | 2003-04-28 | Martin Stjernholm | | push_array (a);
|
e6c089 | 2010-07-27 | Martin Stjernholm | | if (init) {
for(e=0;e<size;e++)
copy_svalues_recursively_no_free(a->item+e, init, 1, 0);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | a->type_field = 1 << TYPEOF(*init);
|
e6c089 | 2010-07-27 | Martin Stjernholm | | }
else {
for(e=0;e<size;e++)
ITEM (a)[e] = svalue_undefined;
a->type_field = BIT_INT;
}
|
2523ce | 2003-04-28 | Martin Stjernholm | | stack_pop_n_elems_keep_top (args);
}
else {
a->type_field = BIT_INT;
pop_n_elems(args);
push_array(a);
|
8267f4 | 1998-01-28 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
0ee38f | 2002-05-11 | Martin Stjernholm | | |
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Returns the object we are currently evaluating in.
|
0ee38f | 2002-05-11 | Martin Stjernholm | | *!
|
4f44a4 | 2015-06-18 | Henrik Grubbström (Grubba) | | *! @param level
*! @[level] may be used to access the object of a surrounding
|
0ee38f | 2002-05-11 | Martin Stjernholm | | *! class: The object at level 0 is the current object, the object
|
aa7e42 | 2003-08-03 | Martin Stjernholm | | *! at level 1 is the one belonging to the class that surrounds
*! the class that the object comes from, and so on.
*!
*! @note
*! As opposed to a qualified @expr{this@} reference such as
*! @expr{global::this@}, this function doesn't always access the
*! objects belonging to the lexically surrounding classes. If the
*! class containing the call has been inherited then the objects
*! surrounding the inheriting class are accessed.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | void f_this_object(INT32 args)
{
|
aa7e42 | 2003-08-03 | Martin Stjernholm | | int level, l;
struct object *o;
|
0ee38f | 2002-05-11 | Martin Stjernholm | | if (args) {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-args]) != T_INT || Pike_sp[-args].u.integer < 0)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR ("this_object", 1, "a non-negative integer");
|
0ee38f | 2002-05-11 | Martin Stjernholm | | level = Pike_sp[-args].u.integer;
}
else
level = 0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
|
aa7e42 | 2003-08-03 | Martin Stjernholm | |
o = Pike_fp->current_object;
for (l = 0; l < level; l++) {
struct program *p = o->prog;
if (!p)
Pike_error ("Object %d level(s) up is destructed - cannot get the parent.\n", l);
if (!(p->flags & PROGRAM_USES_PARENT))
Pike_error ("Object %d level(s) up lacks parent reference.\n", l);
o = PARENT_INFO(o)->parent;
|
cb2256 | 1995-10-11 | Fredrik Hübinette (Hubbe) | | }
|
aa7e42 | 2003-08-03 | Martin Stjernholm | | ref_push_object(o);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
0ee38f | 2002-05-11 | Martin Stjernholm | | static node *optimize_this_object(node *n)
|
b62ab0 | 1999-12-12 | Henrik Grubbström (Grubba) | | {
|
aa7e42 | 2003-08-03 | Martin Stjernholm | | int level = 0;
|
0ee38f | 2002-05-11 | Martin Stjernholm | |
if (CDR (n)) {
|
885388 | 2008-04-26 | Henrik Grubbström (Grubba) | | struct compilation *c = THIS_COMPILATION;
|
0ee38f | 2002-05-11 | Martin Stjernholm | | struct program_state *state = Pike_compiler;
|
885388 | 2008-04-26 | Henrik Grubbström (Grubba) | |
CHECK_COMPILER();
|
0ee38f | 2002-05-11 | Martin Stjernholm | | if (CDR (n)->token != F_CONSTANT) {
int i;
|
885388 | 2008-04-26 | Henrik Grubbström (Grubba) | | for (i = 0; i < c->compilation_depth; i++, state = state->previous)
|
0ee38f | 2002-05-11 | Martin Stjernholm | | state->new_program->flags |= PROGRAM_USES_PARENT | PROGRAM_NEEDS_PARENT;
return NULL;
}
else {
|
aa7e42 | 2003-08-03 | Martin Stjernholm | | int i;
|
0ee38f | 2002-05-11 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(CDR(n)->u.sval) != T_INT || CDR(n)->u.sval.u.integer < 0)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal ("The type check for this_object() failed.\n");
|
0ee38f | 2002-05-11 | Martin Stjernholm | | #endif
level = CDR (n)->u.sval.u.integer;
|
885388 | 2008-04-26 | Henrik Grubbström (Grubba) | | for (i = MINIMUM(level, c->compilation_depth); i;
|
073ccf | 2003-08-04 | Henrik Grubbström (Grubba) | | i--, state = state->previous) {
state->new_program->flags |=
PROGRAM_USES_PARENT | PROGRAM_NEEDS_PARENT;
}
|
0ee38f | 2002-05-11 | Martin Stjernholm | | }
}
|
aa7e42 | 2003-08-03 | Martin Stjernholm | |
if (!level) {
free_type(n->type);
type_stack_mark();
push_object_type(0, Pike_compiler->new_program->id);
n->type = pop_unfinished_type();
if (n->parent) {
n->parent->node_info |= OPT_TYPE_NOT_FIXED;
}
|
b62ab0 | 1999-12-12 | Henrik Grubbström (Grubba) | | }
|
aa7e42 | 2003-08-03 | Martin Stjernholm | |
|
b62ab0 | 1999-12-12 | Henrik Grubbström (Grubba) | | return NULL;
}
|
081147 | 2001-07-02 | Fredrik Hübinette (Hubbe) | | static int generate_this_object(node *n)
{
|
0ee38f | 2002-05-11 | Martin Stjernholm | | int level;
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct compilation *c = THIS_COMPILATION;
CHECK_COMPILER();
|
0ee38f | 2002-05-11 | Martin Stjernholm | |
if (CDR (n)) {
if (CDR (n)->token != F_CONSTANT)
return 0;
else {
#ifdef PIKE_DEBUG
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(CDR(n)->u.sval) != T_INT || CDR(n)->u.sval.u.integer < 0)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal ("The type check for this_object() failed.\n");
|
0ee38f | 2002-05-11 | Martin Stjernholm | | #endif
level = CDR (n)->u.sval.u.integer;
}
}
else level = 0;
emit1(F_THIS_OBJECT, level);
|
384f22 | 2008-08-28 | Henrik Grubbström (Grubba) | | modify_stack_depth(1);
|
081147 | 2001-07-02 | Fredrik Hübinette (Hubbe) | | return 1;
}
|
bf5cbe | 2005-02-18 | Henrik Grubbström (Grubba) | | |
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Throw @[value] to a waiting @[catch].
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! If no @[catch] is waiting the global error handling will send the
*! value to @[master()->handle_error()].
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! If you throw an array with where the first index contains an error
*! message and the second index is a backtrace, (the output from
*! @[backtrace()]) then it will be treated exactly like a real error
*! by overlying functions.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[catch]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_throw(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args != 1)
SIMPLE_WRONG_NUM_ARGS_ERROR("throw", 1);
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | assign_svalue(&throw_value,Pike_sp-args);
|
864d3c | 1998-01-29 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
|
641d5c | 1998-04-09 | Fredrik Hübinette (Hubbe) | | throw_severity=0;
|
dc7cc9 | 1998-01-14 | Fredrik Hübinette (Hubbe) | | pike_throw();
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
ba5857 | 2008-07-09 | Henrik Grubbström (Grubba) | | int in_forked_child = 0;
|
19e2c3 | 2004-03-02 | Martin Nilsson | | |
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Exit the whole Pike program with the given @[returncode].
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Using @[exit()] with any other value than @expr{0@} (zero) indicates
*! that something went wrong during execution. See your system manuals
*! for more information about return codes.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
b5ef7d | 2004-01-11 | Martin Nilsson | | *! The arguments after the @[returncode] will be used for a call to
*! @[werror] to output a message on stderr.
*!
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[_exit()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_exit(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
b4c5de | 1999-03-25 | Fredrik Hübinette (Hubbe) | | static int in_exit=0;
|
811116 | 2003-09-07 | Martin Nilsson | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if(args < 1)
|
06bd61 | 2016-01-26 | Martin Nilsson | | SIMPLE_WRONG_NUM_ARGS_ERROR("exit", 1);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[-args]) != T_INT)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("exit", 1, "int");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | if(in_exit) Pike_error("exit already called!\n");
|
b4c5de | 1999-03-25 | Fredrik Hübinette (Hubbe) | | in_exit=1;
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(args>1 && TYPEOF(Pike_sp[1-args]) == T_STRING) {
|
ea8487 | 2007-01-15 | Henrik Grubbström (Grubba) | | struct svalue *s =
simple_mapping_string_lookup(get_builtin_constants(), "werror");
if (s) {
apply_svalue(s, args-1);
pop_stack();
|
7f6914 | 2007-01-15 | Henrik Grubbström (Grubba) | | } else {
|
ea8487 | 2007-01-15 | Henrik Grubbström (Grubba) | | fprintf(stderr, "No efun::werror() at exit.\n");
pop_n_elems(args-1);
}
|
d8e90a | 2004-05-09 | Martin Nilsson | | args=1;
}
|
b5ef7d | 2004-01-11 | Martin Nilsson | |
|
ba5857 | 2008-07-09 | Henrik Grubbström (Grubba) | | if (in_forked_child) {
f__exit(args);
}
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | assign_svalue(&throw_value, Pike_sp-args);
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | throw_severity=THROW_EXIT;
pike_throw();
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | |
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! This function does the same as @[exit], but doesn't bother to clean
*! up the Pike interpreter before exiting. This means that no destructors
*! will be called, caches will not be flushed, file locks might not be
*! released, and databases might not be closed properly.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Use with extreme caution.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[exit()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
608d73 | 1998-03-20 | Fredrik Hübinette (Hubbe) | | void f__exit(INT32 args)
{
|
b2acc9 | 2004-05-13 | Martin Nilsson | | int code;
|
811116 | 2003-09-07 | Martin Nilsson | |
|
d9ed86 | 2005-11-19 | Henrik Grubbström (Grubba) | | get_all_args("_exit", args, "%d", &code);
|
608d73 | 1998-03-20 | Fredrik Hübinette (Hubbe) | |
|
d9a93b | 2001-07-01 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
{
|
143d88 | 2003-11-14 | Martin Stjernholm | | exit_opcodes();
|
d9a93b | 2001-07-01 | Fredrik Hübinette (Hubbe) | | }
#endif
|
ba5857 | 2008-07-09 | Henrik Grubbström (Grubba) | |
|
b2acc9 | 2004-05-13 | Martin Nilsson | | exit(code);
|
608d73 | 1998-03-20 | Fredrik Hübinette (Hubbe) | | }
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | |
df0f87 | 2003-04-14 | Martin Stjernholm | | *! This function returns the number of seconds since 00:00:00 UTC, 1 Jan 1970.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
93af2d | 2003-10-31 | Martin Stjernholm | | *! The second syntax does not query the system for the current
*! time. Instead the latest done by the pike process is returned
*! again. That's slightly faster but can be wildly inaccurate. Pike
*! queries the time internally when a thread has waited for
*! something, typically in @[sleep] or in a backend (see
*! @[Pike.Backend]).
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! The third syntax can be used to measure time more preciely than one
*! second. It return how many seconds has passed since @[t]. The precision
*! of this function varies from system to system.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
5ef905 | 2003-01-13 | Martin Stjernholm | | *! @[ctime()], @[localtime()], @[mktime()], @[gmtime()],
|
2cccd3 | 2003-01-13 | Martin Stjernholm | | *! @[System.gettimeofday], @[gethrtime]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_time(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
f01020 | 2011-11-16 | Tobias S. Josefowitz | | struct timeval ret;
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(!args ||
(TYPEOF(Pike_sp[-args]) == T_INT && Pike_sp[-args].u.integer == 0))
|
d0e674 | 1998-07-15 | Fredrik Hübinette (Hubbe) | | {
|
f01020 | 2011-11-16 | Tobias S. Josefowitz | | ACCURATE_GETTIMEOFDAY(&ret);
pop_n_elems(args);
push_int(ret.tv_sec);
return;
|
d0e674 | 1998-07-15 | Fredrik Hübinette (Hubbe) | | }else{
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[-args]) == T_INT && Pike_sp[-args].u.integer > 1)
|
d0e674 | 1998-07-15 | Fredrik Hübinette (Hubbe) | | {
struct timeval tmp;
|
f01020 | 2011-11-16 | Tobias S. Josefowitz | | ACCURATE_GETTIMEOFDAY(&ret);
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | tmp.tv_sec=Pike_sp[-args].u.integer;
|
d0e674 | 1998-07-15 | Fredrik Hübinette (Hubbe) | | tmp.tv_usec=0;
|
f01020 | 2011-11-16 | Tobias S. Josefowitz | | my_subtract_timeval(&tmp,&ret);
|
d0e674 | 1998-07-15 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
|
65a549 | 2000-08-10 | Per Hedbor | | push_float( - (FLOAT_TYPE)tmp.tv_sec-((FLOAT_TYPE)tmp.tv_usec)/1000000 );
|
d0e674 | 1998-07-15 | Fredrik Hübinette (Hubbe) | | return;
}
}
pop_n_elems(args);
|
f01020 | 2011-11-16 | Tobias S. Josefowitz | | INACCURATE_GETTIMEOFDAY(&ret);
push_int(ret.tv_sec);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
bff327 | 2013-05-28 | Martin Nilsson | | |
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *! @decl int(0..1) crypt(string typed_password, string crypted_password)
*!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! This function crypts and verifies a short string (only the first
*! 8 characters are significant).
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! The first syntax crypts the string @[password] into something that
*! is hopefully hard to decrypt.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! The second syntax is used to verify @[typed_password] against
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! @[crypted_password], and returns @expr{1@} if they match, and
*! @expr{0@} (zero) otherwise.
|
b2acc9 | 2004-05-13 | Martin Nilsson | | *!
*! @note
*! Note that strings containing null characters will only be
*! processed up until the null character.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_crypt(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
char salt[2];
|
ddc1a3 | 2010-07-27 | Martin Stjernholm | | char *ret, *pwd, *saltp = NULL;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | char *choise =
"cbhisjKlm4k65p7qrJfLMNQOPxwzyAaBDFgnoWXYCZ0123tvdHueEGISRTUV89./";
|
b2acc9 | 2004-05-13 | Martin Nilsson | | get_all_args("crypt", args, "%s.%s", &pwd, &saltp);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
ddc1a3 | 2010-07-27 | Martin Stjernholm | | if(saltp)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
b2acc9 | 2004-05-13 | Martin Nilsson | | if( Pike_sp[1-args].u.string->len < 2 )
|
0f6deb | 1997-08-06 | Fredrik Hübinette (Hubbe) | | {
pop_n_elems(args);
push_int(0);
return;
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | } else {
|
a51d50 | 2015-11-15 | Martin Nilsson | | salt[0] = choise[my_rand(strlen(choise))];
salt[1] = choise[my_rand(strlen(choise))];
|
8beaf7 | 1996-04-13 | Fredrik Hübinette (Hubbe) | | saltp=salt;
|
44e09d | 2011-11-24 | Henrik Grubbström (Grubba) | | if (args > 1) {
pop_n_elems(args-1);
args = 1;
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
#ifdef HAVE_CRYPT
|
b2acc9 | 2004-05-13 | Martin Nilsson | | ret = (char *)crypt(pwd, saltp);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #else
#ifdef HAVE__CRYPT
|
b2acc9 | 2004-05-13 | Martin Nilsson | | ret = (char *)_crypt(pwd, saltp);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #else
|
24adc7 | 2008-09-26 | Martin Nilsson | | #error No crypt function found and fallback failed.
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #endif
#endif
|
95b2f8 | 2011-06-29 | Henrik Grubbström (Grubba) | | if (!ret) {
switch(errno) {
#ifdef ELIBACC
case ELIBACC:
Pike_error("Failed to load a required shared library. "
"Unsupported salt.\n");
break;
#endif
case ENOMEM:
Pike_error("Out of memory.\n");
break;
case EINVAL:
default:
Pike_error("Unsupported salt (%d).\n", errno);
break;
}
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if(args < 2)
{
pop_n_elems(args);
|
f0e6f1 | 2003-12-06 | Martin Nilsson | | push_text(ret);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }else{
int i;
|
b2acc9 | 2004-05-13 | Martin Nilsson | | i=!strcmp(ret,saltp);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
push_int(i);
}
}
|
c8bb3c | 2004-04-20 | Martin Nilsson | | |
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Mark an object as destructed.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
c8bb3c | 2004-04-20 | Martin Nilsson | | *! Calls @expr{o->destroy()@}, and then clears all variables in the
*! object. If no argument is given, the current object is destructed.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! All pointers and function pointers to this object will become zero.
*! The destructed object will be freed from memory as soon as possible.
|
13670c | 2015-05-25 | Martin Nilsson | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_destruct(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
struct object *o;
if(args)
{
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[-args]) != T_OBJECT) {
if ((TYPEOF(Pike_sp[-args]) == T_INT) &&
|
b5d71b | 2001-06-09 | Henrik Grubbström (Grubba) | | (!Pike_sp[-args].u.integer)) {
pop_n_elems(args);
return;
}
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("destruct", 1, "object");
|
b5d71b | 2001-06-09 | Henrik Grubbström (Grubba) | | }
|
e99c7a | 1999-10-29 | Martin Stjernholm | |
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | o=Pike_sp[-args].u.object;
|
cb2256 | 1995-10-11 | Fredrik Hübinette (Hubbe) | | }else{
|
b5d71b | 2001-06-09 | Henrik Grubbström (Grubba) | | if(!Pike_fp) {
PIKE_ERROR("destruct",
"Destruct called without argument from callback function.\n",
Pike_sp, args);
}
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | o=Pike_fp->current_object;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
4d6d78 | 1999-11-14 | Martin Stjernholm | | if (o->prog && o->prog->flags & PROGRAM_NO_EXPLICIT_DESTRUCT)
|
b5d71b | 2001-06-09 | Henrik Grubbström (Grubba) | | PIKE_ERROR("destruct", "Object can't be destructed explicitly.\n",
Pike_sp, args);
|
54717e | 2001-06-28 | Fredrik Hübinette (Hubbe) | | debug_malloc_touch(o);
|
09f288 | 2005-02-09 | Martin Stjernholm | | destruct_object (o, DESTRUCT_EXPLICIT);
|
cb2256 | 1995-10-11 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
|
44138c | 2000-08-02 | Fredrik Hübinette (Hubbe) | | destruct_objects_to_destruct();
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
937c46 | 2001-02-06 | Henrik Grubbström (Grubba) | | |
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Return an array of all valid indices for the value @[x].
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
55d134 | 2015-06-26 | Henrik Grubbström (Grubba) | | *! @param x
*! @mixed
*! @type string
*! @type array
*! For strings and arrays this is simply an array of ascending
*! numbers.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
55d134 | 2015-06-26 | Henrik Grubbström (Grubba) | | *! @type mapping
*! @type multiset
*! For mappings and multisets, the array might contain any value.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
55d134 | 2015-06-26 | Henrik Grubbström (Grubba) | | *! @type object
*! For objects which define @[lfun::_indices()] that return value
*! is used.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
55d134 | 2015-06-26 | Henrik Grubbström (Grubba) | | *! For other objects an array with the names of all non-protected
*! symbols is returned.
*! @endmixed
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
7195af | 2011-01-15 | Henrik Grubbström (Grubba) | | *! @[values()], @[types()], @[lfun::_indices()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_indices(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
93b720 | 2000-08-14 | Henrik Grubbström (Grubba) | | ptrdiff_t size;
|
cb787a | 2000-08-24 | Henrik Grubbström (Grubba) | | struct array *a = NULL;
|
93b720 | 2000-08-14 | Henrik Grubbström (Grubba) | |
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args != 1)
SIMPLE_WRONG_NUM_ARGS_ERROR("indices", 1);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | switch(TYPEOF(Pike_sp[-args]))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
case T_STRING:
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | size=Pike_sp[-args].u.string->len;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | goto qjump;
case T_ARRAY:
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | size=Pike_sp[-args].u.array->size;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
qjump:
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | a=allocate_array_no_init(size,0);
|
5c8e89 | 1995-10-29 | Fredrik Hübinette (Hubbe) | | while(--size>=0)
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | {
|
2523ce | 2003-04-28 | Martin Stjernholm | |
|
bd6739 | 2015-10-14 | Martin Nilsson | | ITEM(a)[size].u.integer = (INT_TYPE)size;
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | }
|
2523ce | 2003-04-28 | Martin Stjernholm | | a->type_field = BIT_INT;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | break;
case T_MAPPING:
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | a=mapping_indices(Pike_sp[-args].u.mapping);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | break;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | case T_MULTISET:
|
5b15bb | 2001-12-10 | Martin Stjernholm | | a = multiset_indices (Pike_sp[-args].u.multiset);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | break;
|
6d4c4c | 1995-11-06 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | a=object_indices(Pike_sp[-args].u.object, SUBTYPEOF(Pike_sp[-args]));
|
6d4c4c | 1995-11-06 | Fredrik Hübinette (Hubbe) | | break;
|
fa3145 | 1998-05-25 | Henrik Grubbström (Grubba) | | case T_PROGRAM:
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | a = program_indices(Pike_sp[-args].u.program);
|
fa3145 | 1998-05-25 | Henrik Grubbström (Grubba) | | break;
|
0ceb87 | 1998-06-07 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
{
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | struct program *p = program_from_svalue(Pike_sp-args);
|
0ceb87 | 1998-06-07 | Henrik Grubbström (Grubba) | | if (p) {
a = program_indices(p);
break;
}
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | default:
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("indices", 1,
"string|array|mapping|"
"multiset|object|program|function");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
pop_n_elems(args);
push_array(a);
}
|
babd87 | 2001-02-23 | Henrik Grubbström (Grubba) | |
|
4d7b18 | 1999-12-07 | Fredrik Hübinette (Hubbe) | | #define FIX_OVERLOADED_TYPE(n, lf, X) fix_overloaded_type(n,lf,X,CONSTANT_STRLEN(X))
|
ac0455 | 2001-02-20 | Henrik Grubbström (Grubba) | |
|
74dfe8 | 2012-12-30 | Jonas Walldén | | static node *fix_overloaded_type(node *n, int lfun, const char *deftype, int UNUSED(deftypelen))
|
4d7b18 | 1999-12-07 | Fredrik Hübinette (Hubbe) | | {
node **first_arg;
|
ac0455 | 2001-02-20 | Henrik Grubbström (Grubba) | | struct pike_type *t, *t2;
|
4d7b18 | 1999-12-07 | Fredrik Hübinette (Hubbe) | | 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))
{
|
54f8ac | 2001-03-17 | Henrik Grubbström (Grubba) | |
while(t && t->type == PIKE_T_NAME) {
t = t->cdr;
}
|
391350 | 2002-06-25 | Henrik Grubbström (Grubba) | |
|
54f8ac | 2001-03-17 | Henrik Grubbström (Grubba) | |
|
391350 | 2002-06-25 | Henrik Grubbström (Grubba) | | if(t && (t->type == T_OBJECT))
|
4d7b18 | 1999-12-07 | Fredrik Hübinette (Hubbe) | | {
|
d2361e | 2003-06-30 | Martin Stjernholm | | struct program *p = id_to_program(CDR_TO_INT(t));
|
4d7b18 | 1999-12-07 | Fredrik Hübinette (Hubbe) | | if(p)
{
int fun=FIND_LFUN(p, lfun);
|
46aa64 | 1999-12-29 | Henrik Grubbström (Grubba) | | if(fun!=-1 &&
|
babd87 | 2001-02-23 | Henrik Grubbström (Grubba) | | (t2 = check_call(function_type_string, ID_FROM_INT(p, fun)->type,
0)))
|
4d7b18 | 1999-12-07 | Fredrik Hübinette (Hubbe) | | {
|
d68a07 | 2001-02-20 | Henrik Grubbström (Grubba) | | free_type(n->type);
|
babd87 | 2001-02-23 | Henrik Grubbström (Grubba) | | n->type = t2;
|
4d7b18 | 1999-12-07 | Fredrik Hübinette (Hubbe) | | return 0;
}
}
}
|
13670c | 2015-05-25 | Martin Nilsson | | |
4d7b18 | 1999-12-07 | Fredrik Hübinette (Hubbe) | | * the deftype....
*/
#if 1
if(deftype)
{
|
8a2a52 | 2001-03-03 | Henrik Grubbström (Grubba) | | t2 = make_pike_type(deftype);
|
babd87 | 2001-02-23 | Henrik Grubbström (Grubba) | | t = n->type;
n->type = or_pike_types(t,t2,0);
|
d68a07 | 2001-02-20 | Henrik Grubbström (Grubba) | | free_type(t);
free_type(t2);
|
4d7b18 | 1999-12-07 | Fredrik Hübinette (Hubbe) | | }
#endif
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
4d7b18 | 1999-12-07 | Fredrik Hübinette (Hubbe) | | return 0;
}
static node *fix_indices_type(node *n)
{
return FIX_OVERLOADED_TYPE(n, LFUN__INDICES, tArray);
}
static node *fix_values_type(node *n)
{
return FIX_OVERLOADED_TYPE(n, LFUN__VALUES, tArray);
}
|
aab841 | 1999-12-07 | Henrik Grubbström (Grubba) | | static node *fix_aggregate_mapping_type(node *n)
{
|
d68a07 | 2001-02-20 | Henrik Grubbström (Grubba) | | struct pike_type *types[2] = { NULL, NULL };
|
aab841 | 1999-12-07 | Henrik Grubbström (Grubba) | | node *args = CDR(n);
|
d68a07 | 2001-02-20 | Henrik Grubbström (Grubba) | | struct pike_type *new_type = NULL;
|
aab841 | 1999-12-07 | Henrik Grubbström (Grubba) | |
#ifdef PIKE_DEBUG
if (l_flag > 2) {
fprintf(stderr, "Fixing type for aggregate_mapping():\n");
print_tree(n);
fprintf(stderr, "Original type:");
simple_describe_type(n->type);
}
#endif /* PIKE_DEBUG */
if (args) {
node *arg = args;
int argno = 0;
args->parent = 0;
while(arg) {
|
f01a89 | 1999-12-08 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
if (l_flag > 4) {
fprintf(stderr, "Searching for arg #%d...\n", argno);
}
#endif /* PIKE_DEBUG */
|
aab841 | 1999-12-07 | Henrik Grubbström (Grubba) | | if (arg->token == F_ARG_LIST) {
if (CAR(arg)) {
CAR(arg)->parent = arg;
arg = CAR(arg);
continue;
}
if (CDR(arg)) {
CDR(arg)->parent = arg;
arg = CDR(arg);
continue;
}
retrace:
|
f01a89 | 1999-12-08 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
if (l_flag > 4) {
fprintf(stderr, "Retracing in search for arg %d...\n", argno);
}
#endif /* PIKE_DEBUG */
|
aab841 | 1999-12-07 | Henrik Grubbström (Grubba) | | while (arg->parent &&
(!CDR(arg->parent) || (CDR(arg->parent) == arg))) {
arg = arg->parent;
}
if (!arg->parent) {
break;
}
arg = arg->parent;
CDR(arg)->parent = arg;
arg = CDR(arg);
continue;
}
if (arg->token == F_PUSH_ARRAY) {
|
babd87 | 2001-02-23 | Henrik Grubbström (Grubba) | |
|
8a2a52 | 2001-03-03 | Henrik Grubbström (Grubba) | | MAKE_CONSTANT_TYPE(new_type, tMap(tMixed, tMixed));
|
aab841 | 1999-12-07 | Henrik Grubbström (Grubba) | | goto set_type;
}
|
f01a89 | 1999-12-08 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
if (l_flag > 4) {
fprintf(stderr, "Found arg #%d:\n", argno);
print_tree(arg);
simple_describe_type(arg->type);
|
aab841 | 1999-12-07 | Henrik Grubbström (Grubba) | | }
|
f01a89 | 1999-12-08 | Henrik Grubbström (Grubba) | | #endif /* PIKE_DEBUG */
do {
if (types[argno]) {
|
ac0455 | 2001-02-20 | Henrik Grubbström (Grubba) | | struct pike_type *t = or_pike_types(types[argno], arg->type, 0);
|
d68a07 | 2001-02-20 | Henrik Grubbström (Grubba) | | free_type(types[argno]);
|
f01a89 | 1999-12-08 | Henrik Grubbström (Grubba) | | types[argno] = t;
#ifdef PIKE_DEBUG
if (l_flag > 4) {
fprintf(stderr, "Resulting type for arg #%d:\n", argno);
simple_describe_type(types[argno]);
}
#endif /* PIKE_DEBUG */
} else {
|
be6fec | 2001-04-01 | Henrik Grubbström (Grubba) | | copy_pike_type(types[argno], arg->type);
|
f01a89 | 1999-12-08 | Henrik Grubbström (Grubba) | | }
argno = !argno;
} while (argno && arg->parent && CAR(arg->parent) == CDR(arg->parent));
|
aab841 | 1999-12-07 | Henrik Grubbström (Grubba) | | goto retrace;
}
if (argno) {
yyerror("Odd number of arguments to aggregate_mapping().");
goto done;
}
if (!types[0]) {
|
8a2a52 | 2001-03-03 | Henrik Grubbström (Grubba) | | MAKE_CONSTANT_TYPE(new_type, tMap(tZero, tZero));
|
aab841 | 1999-12-07 | Henrik Grubbström (Grubba) | | goto set_type;
}
type_stack_mark();
|
d68a07 | 2001-02-20 | Henrik Grubbström (Grubba) | | push_finished_type(types[1]);
push_finished_type(types[0]);
|
aab841 | 1999-12-07 | Henrik Grubbström (Grubba) | | push_type(T_MAPPING);
new_type = pop_unfinished_type();
} else {
|
8a2a52 | 2001-03-03 | Henrik Grubbström (Grubba) | | MAKE_CONSTANT_TYPE(new_type, tMap(tZero, tZero));
|
aab841 | 1999-12-07 | Henrik Grubbström (Grubba) | | goto set_type;
}
if (new_type) {
set_type:
|
d68a07 | 2001-02-20 | Henrik Grubbström (Grubba) | | free_type(n->type);
|
aab841 | 1999-12-07 | Henrik Grubbström (Grubba) | | n->type = new_type;
#ifdef PIKE_DEBUG
if (l_flag > 2) {
fprintf(stderr, "Result type: ");
simple_describe_type(new_type);
}
#endif /* PIKE_DEBUG */
if (n->parent) {
n->parent->node_info |= OPT_TYPE_NOT_FIXED;
|
13670c | 2015-05-25 | Martin Nilsson | | }
|
aab841 | 1999-12-07 | Henrik Grubbström (Grubba) | | }
done:
if (args) {
args->parent = n;
}
if (types[1]) {
|
d68a07 | 2001-02-20 | Henrik Grubbström (Grubba) | | free_type(types[1]);
|
aab841 | 1999-12-07 | Henrik Grubbström (Grubba) | | }
if (types[0]) {
|
d68a07 | 2001-02-20 | Henrik Grubbström (Grubba) | | free_type(types[0]);
|
aab841 | 1999-12-07 | Henrik Grubbström (Grubba) | | }
return NULL;
}
|
937c46 | 2001-02-06 | Henrik Grubbström (Grubba) | | |
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
b2acc9 | 2004-05-13 | Martin Nilsson | | *! Return an array of all possible values from indexing the value
*! @[x].
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
55d134 | 2015-06-26 | Henrik Grubbström (Grubba) | | *! @param x
*! @mixed
*! @type string
*! For strings an array of int with the ISO10646 codes of the
*! characters in the string is returned.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
55d134 | 2015-06-26 | Henrik Grubbström (Grubba) | | *! @type multiset
*! For a multiset an array filled with ones (@expr{1@}) is
*! returned.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
55d134 | 2015-06-26 | Henrik Grubbström (Grubba) | | *! @type array
*! For arrays a single-level copy of @[x] is returned.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
55d134 | 2015-06-26 | Henrik Grubbström (Grubba) | | *! @type mapping
*! For mappings the array may contain any value.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
55d134 | 2015-06-26 | Henrik Grubbström (Grubba) | | *! @type object
*! For objects which define @[lfun::_values()] that return value
*! is used.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
55d134 | 2015-06-26 | Henrik Grubbström (Grubba) | | *! For other objects an array with the values of all non-protected
*! symbols is returned.
*! @endmixed
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
7195af | 2011-01-15 | Henrik Grubbström (Grubba) | | *! @[indices()], @[types()], @[lfun::_values()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_values(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
93b720 | 2000-08-14 | Henrik Grubbström (Grubba) | | ptrdiff_t size;
|
cb787a | 2000-08-24 | Henrik Grubbström (Grubba) | | struct array *a = NULL;
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args != 1)
SIMPLE_WRONG_NUM_ARGS_ERROR("values", 1);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | switch(TYPEOF(Pike_sp[-args]))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
case T_STRING:
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | size = Pike_sp[-args].u.string->len;
|
c628dc | 1998-10-10 | Henrik Grubbström (Grubba) | | a = allocate_array_no_init(size,0);
while(--size >= 0)
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | {
|
2523ce | 2003-04-28 | Martin Stjernholm | |
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | ITEM(a)[size].u.integer = index_shared_string(Pike_sp[-args].u.string, size);
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | }
|
2523ce | 2003-04-28 | Martin Stjernholm | | a->type_field = BIT_INT;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | break;
case T_ARRAY:
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | a=copy_array(Pike_sp[-args].u.array);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | break;
case T_MAPPING:
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | a=mapping_values(Pike_sp[-args].u.mapping);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | break;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | case T_MULTISET:
|
5b15bb | 2001-12-10 | Martin Stjernholm | | a = multiset_values (Pike_sp[-args].u.multiset);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | break;
|
6d4c4c | 1995-11-06 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | a=object_values(Pike_sp[-args].u.object, SUBTYPEOF(Pike_sp[-args]));
|
6d4c4c | 1995-11-06 | Fredrik Hübinette (Hubbe) | | break;
|
fa3145 | 1998-05-25 | Henrik Grubbström (Grubba) | | case T_PROGRAM:
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | a = program_values(Pike_sp[-args].u.program);
|
fa3145 | 1998-05-25 | Henrik Grubbström (Grubba) | | break;
|
0ceb87 | 1998-06-07 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
{
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | struct program *p = program_from_svalue(Pike_sp - args);
|
0ceb87 | 1998-06-07 | Henrik Grubbström (Grubba) | | if (p) {
a = program_values(p);
break;
}
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | default:
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("values", 1,
"string|array|mapping|multiset|"
"object|program|function");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
pop_n_elems(args);
push_array(a);
}
|
7195af | 2011-01-15 | Henrik Grubbström (Grubba) | | |
55d134 | 2015-06-26 | Henrik Grubbström (Grubba) | | *! Return an array with the types of all valid indices for the value @[x].
|
7195af | 2011-01-15 | Henrik Grubbström (Grubba) | | *!
|
55d134 | 2015-06-26 | Henrik Grubbström (Grubba) | | *! @param x
*! @mixed
*! @type string
*! For strings this is simply an array with @tt{int@}
|
7195af | 2011-01-15 | Henrik Grubbström (Grubba) | | *!
|
55d134 | 2015-06-26 | Henrik Grubbström (Grubba) | | *! @type array
*! @type mapping
*! @type multiset
*! For arrays, mappings and multisets this is simply
*! an array with @tt{mixed@}.
|
7195af | 2011-01-15 | Henrik Grubbström (Grubba) | | *!
|
55d134 | 2015-06-26 | Henrik Grubbström (Grubba) | | *! @type object
*! For objects which define @[lfun::_types()] that return value
*! is used.
|
7195af | 2011-01-15 | Henrik Grubbström (Grubba) | | *!
|
55d134 | 2015-06-26 | Henrik Grubbström (Grubba) | | *! For other objects an array with type types for all non-protected
*! symbols is returned.
*! @endmixed
|
7195af | 2011-01-15 | Henrik Grubbström (Grubba) | | *!
*! @note
*! This function was added in Pike 7.9.
*!
*! @seealso
*! @[indices()], @[values()], @[lfun::_types()]
*/
PMOD_EXPORT void f_types(INT32 args)
{
ptrdiff_t size;
struct array *a = NULL;
struct pike_type *default_type = mixed_type_string;
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args != 1)
SIMPLE_WRONG_NUM_ARGS_ERROR("types", 1);
|
7195af | 2011-01-15 | Henrik Grubbström (Grubba) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | switch(TYPEOF(Pike_sp[-args]))
|
7195af | 2011-01-15 | Henrik Grubbström (Grubba) | | {
case T_STRING:
default_type = int_type_string;
size=Pike_sp[-args].u.string->len;
goto qjump;
case T_MAPPING:
size = Pike_sp[-args].u.mapping->data->size;
goto qjump;
case T_MULTISET:
default_type = int_type_string;
size = Pike_sp[-args].u.multiset->msd->size;
goto qjump;
case T_ARRAY:
size=Pike_sp[-args].u.array->size;
qjump:
a=allocate_array_no_init(size,0);
while(--size>=0)
{
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(ITEM(a)[size], PIKE_T_TYPE, 0, type, default_type);
add_ref(default_type);
|
7195af | 2011-01-15 | Henrik Grubbström (Grubba) | | }
a->type_field = BIT_TYPE;
break;
case T_OBJECT:
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | a=object_types(Pike_sp[-args].u.object, SUBTYPEOF(Pike_sp[-args]));
|
7195af | 2011-01-15 | Henrik Grubbström (Grubba) | | break;
case T_PROGRAM:
a = program_types(Pike_sp[-args].u.program);
break;
case T_FUNCTION:
{
struct program *p = program_from_svalue(Pike_sp-args);
if (p) {
a = program_types(p);
break;
}
}
default:
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("types", 1,
"string|array|mapping|"
"multiset|object|program|function");
|
7195af | 2011-01-15 | Henrik Grubbström (Grubba) | | }
pop_n_elems(args);
push_array(a);
}
|
fd25e0 | 2003-04-27 | Martin Nilsson | | |
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
fd25e0 | 2003-04-27 | Martin Nilsson | | *! Return the program from which @[o] was instantiated. If the
|
f3f0e8 | 2003-04-27 | Henrik Grubbström (Grubba) | | *! object was instantiated from a class using parent references
*! the generating function will be returned.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! If @[o] is not an object or has been destructed @expr{0@} (zero)
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! will be returned.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_object_program(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args != 1)
SIMPLE_WRONG_NUM_ARGS_ERROR("object_program", 1);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[-args]) == T_OBJECT)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | struct object *o=Pike_sp[-args].u.object;
|
c07fe5 | 2003-01-16 | Martin Stjernholm | | struct program *p = o->prog;
if(p)
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (SUBTYPEOF(Pike_sp[-args])) {
|
d22ebc | 2008-05-28 | Henrik Grubbström (Grubba) | |
struct external_variable_context loc;
loc.o = o;
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | p = (loc.inherit = p->inherits + SUBTYPEOF(Pike_sp[-args]))->prog;
|
d22ebc | 2008-05-28 | Henrik Grubbström (Grubba) | | if (p->flags & PROGRAM_USES_PARENT) {
loc.parent_identifier = loc.inherit->parent_identifier;
find_external_context(&loc, 1);
add_ref(loc.o);
pop_n_elems(args);
push_function(loc.o, loc.parent_identifier);
return;
}
|
13670c | 2015-05-25 | Martin Nilsson | | } else if((p->flags & PROGRAM_USES_PARENT) &&
|
f3c715 | 2001-04-14 | Fredrik Hübinette (Hubbe) | | PARENT_INFO(o)->parent &&
PARENT_INFO(o)->parent->prog)
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | {
|
f3c715 | 2001-04-14 | Fredrik Hübinette (Hubbe) | | INT32 id=PARENT_INFO(o)->parent_identifier;
o=PARENT_INFO(o)->parent;
|
0e8861 | 1998-04-16 | Fredrik Hübinette (Hubbe) | | add_ref(o);
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
|
c07fe5 | 2003-01-16 | Martin Stjernholm | | push_function(o, id);
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | return;
}
|
d22ebc | 2008-05-28 | Henrik Grubbström (Grubba) | | add_ref(p);
pop_n_elems(args);
push_program(p);
return;
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | |
pop_n_elems(args);
push_int(0);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
70c926 | 1999-12-22 | Henrik Grubbström (Grubba) | | node *fix_object_program_type(node *n)
{
node *nn;
|
ac0455 | 2001-02-20 | Henrik Grubbström (Grubba) | | struct pike_type *new_type = NULL;
|
70c926 | 1999-12-22 | Henrik Grubbström (Grubba) | |
if (!n->type) {
|
be6fec | 2001-04-01 | Henrik Grubbström (Grubba) | | copy_pike_type(n->type, program_type_string);
|
70c926 | 1999-12-22 | Henrik Grubbström (Grubba) | | }
if (!(nn = CDR(n))) return NULL;
if ((nn->token == F_ARG_LIST) && (!(nn = CAR(nn)))) return NULL;
if (!nn->type) return NULL;
new_type = object_type_to_program_type(nn->type);
if (new_type) {
|
d68a07 | 2001-02-20 | Henrik Grubbström (Grubba) | | free_type(n->type);
|
70c926 | 1999-12-22 | Henrik Grubbström (Grubba) | | n->type = new_type;
}
return NULL;
}
|
2b888e | 2008-01-29 | Henrik Grubbström (Grubba) | | |
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Reverses a string, array or int.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
2b888e | 2008-01-29 | Henrik Grubbström (Grubba) | | *! @param s
*! String to reverse.
*! @param a
*! Array to reverse.
*! @param i
*! Integer to reverse.
*! @param start
*! Optional start index of the range to reverse.
*! Default: @expr{0@} (zero).
*! @param end
*! Optional end index of the range to reverse.
*! Default for strings: @expr{sizeof(s)-1@}.
*! Default for arrays: @expr{sizeof(a)-1@}.
*! Default for integers: @expr{Pike.get_runtime_info()->int_size - 1@}.
*!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! This function reverses a string, char by char, an array, value
|
5b916d | 2002-09-29 | Martin Stjernholm | | *! by value or an int, bit by bit and returns the result. It's not
*! destructive on the input value.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Reversing strings can be particularly useful for parsing difficult
*! syntaxes which require scanning backwards.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[sscanf()]
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_reverse(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
2b888e | 2008-01-29 | Henrik Grubbström (Grubba) | | struct svalue *sv;
int start = 0, end = -1;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
2b888e | 2008-01-29 | Henrik Grubbström (Grubba) | | get_all_args("reverse", args, "%*.%d%d", &sv, &start, &end);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | switch(TYPEOF(*sv))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
case T_STRING:
{
INT32 e;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *s;
|
0ede07 | 2008-08-22 | Henrik Grubbström (Grubba) | | struct pike_string *orig = sv->u.string;;
|
2b888e | 2008-01-29 | Henrik Grubbström (Grubba) | | if (start < 0) {
start = 0;
|
0ede07 | 2008-08-22 | Henrik Grubbström (Grubba) | | } else if (start >= orig->len) {
|
2b888e | 2008-01-29 | Henrik Grubbström (Grubba) | |
pop_n_elems(args-1);
break;
}
|
0ede07 | 2008-08-22 | Henrik Grubbström (Grubba) | | if ((end < 0) || (end >= orig->len)) {
end = orig->len;
|
2b888e | 2008-01-29 | Henrik Grubbström (Grubba) | | } else if (end <= start) {
pop_n_elems(args-1);
break;
} else {
end++;
}
|
0ede07 | 2008-08-22 | Henrik Grubbström (Grubba) | | s=begin_wide_shared_string(orig->len, orig->size_shift);
if ((orig->len << orig->size_shift) >= 524288) {
THREADS_ALLOW();
switch(orig->size_shift)
{
case 0:
for(e=0;e<start;e++)
STR0(s)[e]=STR0(orig)[e];
for(;e<end;e++)
STR0(s)[e]=STR0(orig)[end-1-e-start];
for(;e<orig->len;e++)
STR0(s)[e]=STR0(orig)[e];
break;
case 1:
for(e=0;e<start;e++)
STR1(s)[e]=STR1(orig)[e];
for(;e<end;e++)
STR1(s)[e]=STR1(orig)[end-1-e-start];
for(;e<orig->len;e++)
STR1(s)[e]=STR1(orig)[e];
break;
case 2:
for(e=0;e<start;e++)
STR2(s)[e]=STR2(orig)[e];
for(;e<end;e++)
STR2(s)[e]=STR2(orig)[end-1-e-start];
for(;e<orig->len;e++)
STR2(s)[e]=STR2(orig)[e];
break;
}
THREADS_DISALLOW();
} else {
switch(orig->size_shift)
{
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | case 0:
|
2b888e | 2008-01-29 | Henrik Grubbström (Grubba) | | for(e=0;e<start;e++)
|
0ede07 | 2008-08-22 | Henrik Grubbström (Grubba) | | STR0(s)[e]=STR0(orig)[e];
|
2b888e | 2008-01-29 | Henrik Grubbström (Grubba) | | for(;e<end;e++)
|
0ede07 | 2008-08-22 | Henrik Grubbström (Grubba) | | STR0(s)[e]=STR0(orig)[end-1-e-start];
for(;e<orig->len;e++)
STR0(s)[e]=STR0(orig)[e];
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | break;
case 1:
|
2b888e | 2008-01-29 | Henrik Grubbström (Grubba) | | for(e=0;e<start;e++)
|
0ede07 | 2008-08-22 | Henrik Grubbström (Grubba) | | STR1(s)[e]=STR1(orig)[e];
|
2b888e | 2008-01-29 | Henrik Grubbström (Grubba) | | for(;e<end;e++)
|
0ede07 | 2008-08-22 | Henrik Grubbström (Grubba) | | STR1(s)[e]=STR1(orig)[end-1-e-start];
for(;e<orig->len;e++)
STR1(s)[e]=STR1(orig)[e];
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | break;
case 2:
|
2b888e | 2008-01-29 | Henrik Grubbström (Grubba) | | for(e=0;e<start;e++)
|
0ede07 | 2008-08-22 | Henrik Grubbström (Grubba) | | STR2(s)[e]=STR2(orig)[e];
|
2b888e | 2008-01-29 | Henrik Grubbström (Grubba) | | for(;e<end;e++)
|
0ede07 | 2008-08-22 | Henrik Grubbström (Grubba) | | STR2(s)[e]=STR2(orig)[end-1-e-start];
for(;e<orig->len;e++)
STR2(s)[e]=STR2(orig)[e];
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | break;
|
0ede07 | 2008-08-22 | Henrik Grubbström (Grubba) | | }
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | }
s=low_end_shared_string(s);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
push_string(s);
break;
}
case T_INT:
{
|
2b888e | 2008-01-29 | Henrik Grubbström (Grubba) | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | INT32 e;
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | e=Pike_sp[-args].u.integer;
|
5c8e89 | 1995-10-29 | Fredrik Hübinette (Hubbe) | | e=((e & 0x55555555UL)<<1) + ((e & 0xaaaaaaaaUL)>>1);
e=((e & 0x33333333UL)<<2) + ((e & 0xccccccccUL)>>2);
e=((e & 0x0f0f0f0fUL)<<4) + ((e & 0xf0f0f0f0UL)>>4);
e=((e & 0x00ff00ffUL)<<8) + ((e & 0xff00ff00UL)>>8);
e=((e & 0x0000ffffUL)<<16)+ ((e & 0xffff0000UL)>>16);
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | Pike_sp[-args].u.integer=e;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args-1);
break;
}
|
a63b36 | 2003-11-07 | Martin Stjernholm | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_ARRAY:
{
|
2b888e | 2008-01-29 | Henrik Grubbström (Grubba) | | struct array *a = sv->u.array;
a = reverse_array(a, start, (end < 0)?a->size:end);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
push_array(a);
break;
}
default:
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("reverse", 1, "string|int|array");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
7e97c3 | 1999-01-21 | Fredrik Hübinette (Hubbe) | |
|
3f268a | 2006-03-09 | Henrik Grubbström (Grubba) | |
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | int find_longest_prefix(char *str,
ptrdiff_t len,
int size_shift,
struct replace_many_tupel *v,
INT32 a,
INT32 b)
|
7e97c3 | 1999-01-21 | Fredrik Hübinette (Hubbe) | | {
|
66096f | 2008-07-04 | Martin Stjernholm | | INT32 c, match=-1, match_len=-1;
|
93b720 | 2000-08-14 | Henrik Grubbström (Grubba) | | ptrdiff_t tmp;
|
0fe670 | 2004-04-30 | Martin Stjernholm | | check_c_stack(2048);
|
7e97c3 | 1999-01-21 | Fredrik Hübinette (Hubbe) | | while(a<b)
{
c=(a+b)/2;
|
3f268a | 2006-03-09 | Henrik Grubbström (Grubba) | |
|
24e45c | 2006-03-11 | Henrik Grubbström (Grubba) | | if (v[c].ind->len <= match_len) {
b = c;
continue;
}
|
18d935 | 2006-03-10 | Henrik Grubbström (Grubba) | | tmp=generic_find_binary_prefix(v[c].ind->str,
v[c].ind->len,
v[c].ind->size_shift,
str,
MINIMUM(len,v[c].ind->len),
size_shift);
|
d8fc6f | 2006-03-10 | Henrik Grubbström (Grubba) | |
|
7e97c3 | 1999-01-21 | Fredrik Hübinette (Hubbe) | | if(tmp<0)
{
|
18d935 | 2006-03-10 | Henrik Grubbström (Grubba) | |
if (~tmp > match_len) {
|
3f268a | 2006-03-09 | Henrik Grubbström (Grubba) | |
int d = c;
|
18d935 | 2006-03-10 | Henrik Grubbström (Grubba) | | tmp = -tmp;
while (((d = v[d].prefix) >= a) && (v[d].ind->len > match_len)) {
if (v[d].ind->len < tmp) {
|
3f268a | 2006-03-09 | Henrik Grubbström (Grubba) | |
match = d;
match_len = v[d].ind->len;
break;
}
|
7e97c3 | 1999-01-21 | Fredrik Hübinette (Hubbe) | | }
}
|
3f268a | 2006-03-09 | Henrik Grubbström (Grubba) | | a = c+1;
|
7e97c3 | 1999-01-21 | Fredrik Hübinette (Hubbe) | | }
else if(tmp>0)
{
b=c;
|
28ab94 | 2006-03-13 | Henrik Grubbström (Grubba) | | while ((c = v[b].prefix) > a) {
if (v[c].ind->len < tmp) {
if (v[c].ind->len > match_len) {
match = c;
match_len = v[c].ind->len;
}
a = c+1;
break;
}
b = c;
}
|
7e97c3 | 1999-01-21 | Fredrik Hübinette (Hubbe) | | }
else
{
|
24e45c | 2006-03-11 | Henrik Grubbström (Grubba) | | if (!v[c].is_prefix) {
return c;
}
|
7e97c3 | 1999-01-21 | Fredrik Hübinette (Hubbe) | | a=c+1;
match=c;
|
3f268a | 2006-03-09 | Henrik Grubbström (Grubba) | | match_len = v[c].ind->len;
|
7e97c3 | 1999-01-21 | Fredrik Hübinette (Hubbe) | | }
}
return match;
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
7e97c3 | 1999-01-21 | Fredrik Hübinette (Hubbe) | |
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | static int replace_sortfun(struct replace_many_tupel *a,
struct replace_many_tupel *b)
|
70da5a | 2001-06-27 | Henrik Grubbström (Grubba) | | {
|
bd6739 | 2015-10-14 | Martin Nilsson | | return (int)my_quick_strcmp(a->ind, b->ind);
|
70da5a | 2001-06-27 | Henrik Grubbström (Grubba) | | }
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | void free_replace_many_context(struct replace_many_context *ctx)
|
0fe670 | 2004-04-30 | Martin Stjernholm | | {
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | if (ctx->v) {
if (ctx->flags) {
int e = ctx->num;
while (e--) {
free_string(ctx->v[e].ind);
free_string(ctx->v[e].val);
}
if (ctx->empty_repl) {
free_string(ctx->empty_repl);
}
}
|
0ec752 | 2014-04-27 | Martin Nilsson | | free (ctx->v);
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | ctx->v = NULL;
}
|
0fe670 | 2004-04-30 | Martin Stjernholm | | }
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | void compile_replace_many(struct replace_many_context *ctx,
struct array *from,
struct array *to,
int reference_strings)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
3f268a | 2006-03-09 | Henrik Grubbström (Grubba) | | INT32 e, num;
|
a8cdf9 | 2004-04-29 | Martin Nilsson | |
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | ctx->v = NULL;
ctx->empty_repl = NULL;
|
7f0f34 | 2006-03-09 | Henrik Grubbström (Grubba) | |
|
652b67 | 2008-05-01 | Martin Stjernholm | | #if INT32_MAX >= LONG_MAX
|
99e4f0 | 2004-10-15 | Henrik Grubbström (Grubba) | |
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | if (from->size > (ptrdiff_t)(LONG_MAX/sizeof(struct replace_many_tupel)))
|
99e4f0 | 2004-10-15 | Henrik Grubbström (Grubba) | | Pike_error("Array too large (size %" PRINTPTRDIFFT "d "
|
bd5e8b | 2004-10-16 | Marcus Agehall | | "exceeds %" PRINTSIZET "u).\n",
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | from->size,
(size_t)(LONG_MAX/sizeof(struct replace_many_tupel)));
|
652b67 | 2008-05-01 | Martin Stjernholm | | #endif
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | ctx->v = (struct replace_many_tupel *)
xalloc(sizeof(struct replace_many_tupel) * from->size);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | for(num=e=0;e<from->size;e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
24e45c | 2006-03-11 | Henrik Grubbström (Grubba) | | if (!ITEM(from)[e].u.string->len) {
if (ITEM(to)[e].u.string->len) {
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | ctx->empty_repl = ITEM(to)[e].u.string;
|
24e45c | 2006-03-11 | Henrik Grubbström (Grubba) | | }
continue;
}
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | ctx->v[num].ind=ITEM(from)[e].u.string;
ctx->v[num].val=ITEM(to)[e].u.string;
ctx->v[num].prefix=-2;
ctx->v[num].is_prefix=0;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | num++;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | ctx->flags = reference_strings;
if (reference_strings) {
if (ctx->empty_repl) add_ref(ctx->empty_repl);
for (e = 0; e < num; e++) {
add_ref(ctx->v[e].ind);
add_ref(ctx->v[e].val);
}
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | fsort((char *)ctx->v, num, sizeof(struct replace_many_tupel),
(fsortfun)replace_sortfun);
|
21b12a | 2014-09-03 | Martin Nilsson | | memset(ctx->set_start, 0, sizeof(ctx->set_start));
memset(ctx->set_end, 0, sizeof(ctx->set_end));
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | ctx->other_start = num;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | for(e=0;e<num;e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
24e45c | 2006-03-11 | Henrik Grubbström (Grubba) | | {
p_wchar2 x;
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | if (ctx->v[num-1-e].ind->len) {
x=index_shared_string(ctx->v[num-1-e].ind,0);
|
7489bb | 2008-06-29 | Martin Stjernholm | | if ((size_t) x < NELEM(ctx->set_start))
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | ctx->set_start[x]=num-e-1;
|
24e45c | 2006-03-11 | Henrik Grubbström (Grubba) | | else
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | ctx->other_start = num-e-1;
|
24e45c | 2006-03-11 | Henrik Grubbström (Grubba) | | }
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | if (ctx->v[e].ind->len) {
x=index_shared_string(ctx->v[e].ind,0);
|
7489bb | 2008-06-29 | Martin Stjernholm | | if ((size_t) x < NELEM(ctx->set_end))
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | ctx->set_end[x]=e+1;
|
24e45c | 2006-03-11 | Henrik Grubbström (Grubba) | | }
}
{
INT32 prefix = e-1;
if (prefix >= 0) {
ptrdiff_t tmp =
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | generic_find_binary_prefix(ctx->v[e].ind->str,
ctx->v[e].ind->len,
ctx->v[e].ind->size_shift,
ctx->v[prefix].ind->str,
ctx->v[prefix].ind->len,
ctx->v[prefix].ind->size_shift);
|
24e45c | 2006-03-11 | Henrik Grubbström (Grubba) | | if (!tmp) {
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | |
|
24e45c | 2006-03-11 | Henrik Grubbström (Grubba) | | } if (tmp == 1) {
prefix = -1;
} else {
|
d8fc6f | 2006-03-10 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
|
24e45c | 2006-03-11 | Henrik Grubbström (Grubba) | | if (tmp < 0) Pike_fatal("Sorting with replace_sortfunc failed.\n");
|
d8fc6f | 2006-03-10 | Henrik Grubbström (Grubba) | | #endif
|
18d935 | 2006-03-10 | Henrik Grubbström (Grubba) | |
|
24e45c | 2006-03-11 | Henrik Grubbström (Grubba) | |
while (prefix >= 0) {
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | if (ctx->v[prefix].ind->len < tmp) break;
prefix = ctx->v[prefix].prefix;
|
24e45c | 2006-03-11 | Henrik Grubbström (Grubba) | | }
}
if (prefix >= 0) {
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | ctx->v[prefix].is_prefix = 1;
|
d8fc6f | 2006-03-10 | Henrik Grubbström (Grubba) | | }
|
3f268a | 2006-03-09 | Henrik Grubbström (Grubba) | | }
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | ctx->v[e].prefix = prefix;
|
3f268a | 2006-03-09 | Henrik Grubbström (Grubba) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | ctx->num = num;
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | struct pike_string *execute_replace_many(struct replace_many_context *ctx,
struct pike_string *str)
{
struct string_builder ret;
ONERROR uwp;
init_string_builder(&ret, str->size_shift);
SET_ONERROR(uwp, free_string_builder, &ret);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
2a7ae6 | 2006-03-10 | Henrik Grubbström (Grubba) | |
|
d8fc6f | 2006-03-10 | Henrik Grubbström (Grubba) | |
|
007b46 | 2006-03-11 | Henrik Grubbström (Grubba) | | switch (str->size_shift) {
#define CASE(SZ) \
case (SZ): \
{ \
PIKE_CONCAT(p_wchar, SZ) *ss = \
PIKE_CONCAT(STR, SZ)(str); \
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | ptrdiff_t e, s, length = str->len; \
|
007b46 | 2006-03-11 | Henrik Grubbström (Grubba) | | for(e = s = 0;length > 0;) \
{ \
INT32 a, b; \
p_wchar2 ch; \
\
ch = ss[s]; \
if(OPT_IS_CHAR(ch)) { \
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | b = ctx->set_end[ch]; \
|
007b46 | 2006-03-11 | Henrik Grubbström (Grubba) | | if (!b) \
goto PIKE_CONCAT(next_char, SZ); \
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | a = ctx->set_start[ch]; \
|
007b46 | 2006-03-11 | Henrik Grubbström (Grubba) | | } else { \
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | b = ctx->num; \
a = ctx->other_start; \
|
007b46 | 2006-03-11 | Henrik Grubbström (Grubba) | | } \
if (a >= b) \
goto PIKE_CONCAT(next_char, SZ); \
\
a = find_longest_prefix((char *)(ss + s), \
length, \
SZ, \
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | ctx->v, a, b); \
|
007b46 | 2006-03-11 | Henrik Grubbström (Grubba) | | \
if(a >= 0) \
{ \
if (s != e) { \
PIKE_CONCAT(string_builder_binary_strcat, \
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | SZ)(&ret, ss+e, s-e); \
|
007b46 | 2006-03-11 | Henrik Grubbström (Grubba) | | } \
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | ch = ctx->v[a].ind->len; \
|
007b46 | 2006-03-11 | Henrik Grubbström (Grubba) | | s += ch; \
length -= ch; \
e = s; \
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | string_builder_shared_strcat(&ret, \
ctx->v[a].val); \
if (ctx->empty_repl && length) { \
|
007b46 | 2006-03-11 | Henrik Grubbström (Grubba) | | /* Append the replacement for \
* the empty string too. */ \
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | string_builder_shared_strcat(&ret, \
ctx->empty_repl); \
|
007b46 | 2006-03-11 | Henrik Grubbström (Grubba) | | } \
continue; \
} \
\
PIKE_CONCAT(next_char, SZ): \
s++; \
length--; \
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | if (ctx->empty_repl && length) { \
|
007b46 | 2006-03-11 | Henrik Grubbström (Grubba) | | /* We have a replace with the empty string, \
* and we're not on the last character \
* in the source string. \
*/ \
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | string_builder_putchar(&ret, ch); \
string_builder_shared_strcat(&ret, \
ctx->empty_repl); \
|
007b46 | 2006-03-11 | Henrik Grubbström (Grubba) | | e = s; \
} \
} \
if (e < s) { \
PIKE_CONCAT(string_builder_binary_strcat, SZ) \
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | (&ret, ss+e, s-e); \
|
007b46 | 2006-03-11 | Henrik Grubbström (Grubba) | | } \
} \
break
#define OPT_IS_CHAR(X) 1
CASE(0);
#undef OPT_IS_CHAR
|
7489bb | 2008-06-29 | Martin Stjernholm | | #define OPT_IS_CHAR(X) ((size_t) (X) < NELEM(ctx->set_end))
|
007b46 | 2006-03-11 | Henrik Grubbström (Grubba) | | CASE(1);
CASE(2);
#undef OPT_IS_CHAR
|
d8fc6f | 2006-03-10 | Henrik Grubbström (Grubba) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | UNSET_ONERROR(uwp);
return finish_string_builder(&ret);
}
static struct pike_string *replace_many(struct pike_string *str,
struct array *from,
struct array *to)
{
struct replace_many_context ctx;
ONERROR uwp;
struct pike_string *ret;
if(from->size != to->size)
Pike_error("Replace must have equal-sized from and to arrays.\n");
if(!from->size)
{
reference_shared_string(str);
return str;
}
if( (from->type_field & ~BIT_STRING) &&
(array_fix_type_field(from) & ~BIT_STRING) )
Pike_error("replace: from array not array(string).\n");
if( (to->type_field & ~BIT_STRING) &&
(array_fix_type_field(to) & ~BIT_STRING) )
Pike_error("replace: to array not array(string).\n");
if (from->size == 1) {
return string_replace(str, from->item[0].u.string, to->item[0].u.string);
}
compile_replace_many(&ctx, from, to, 0);
SET_ONERROR(uwp, free_replace_many_context, &ctx);
ret = execute_replace_many(&ctx, str);
CALL_AND_UNSET_ONERROR(uwp);
return ret;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | |
7f0f34 | 2006-03-09 | Henrik Grubbström (Grubba) | | *! @decl string replace(string s, array(string) from, string to)
|
bd33e7 | 2001-02-07 | Martin Nilsson | | *! @decl string replace(string s, mapping(string:string) replacements)
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *! @decl array replace(array a, mixed from, mixed to)
*! @decl mapping replace(mapping a, mixed from, mixed to)
*!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Generic replace function.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! This function can do several kinds replacement operations, the
*! different syntaxes do different things as follows:
|
13670c | 2015-05-25 | Martin Nilsson | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! If all the arguments are strings, a copy of @[s] with every
*! occurrence of @[from] replaced with @[to] will be returned.
*! Special case: @[to] will be inserted between every character in
*! @[s] if @[from] is the empty string.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! If the first argument is a string, and the others array(string), a string
*! with every occurrance of @[from][@i{i@}] in @[s] replaced with
*! @[to][@i{i@}] will be returned. Instead of the arrays @[from] and @[to]
|
f79bd8 | 2003-04-01 | Martin Nilsson | | *! a mapping equvivalent to @expr{@[mkmapping](@[from], @[to])@} can be
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! used.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! If the first argument is an array or mapping, the values of @[a] which
*! are @[`==()] with @[from] will be replaced with @[to] destructively.
*! @[a] will then be returned.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
*! @note
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Note that @[replace()] on arrays and mappings is a destructive operation.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_replace(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
if(args < 3)
|
f7a446 | 2000-10-31 | Mirar (Pontus Hagland) | | {
if (args==2 &&
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | TYPEOF(Pike_sp[-1]) == T_MAPPING)
|
f7a446 | 2000-10-31 | Mirar (Pontus Hagland) | | {
|
200bfd | 2004-05-14 | Martin Nilsson | | struct mapping *m = Pike_sp[-1].u.mapping;
if( (m->data->ind_types & ~BIT_STRING) ||
(m->data->val_types & ~BIT_STRING) ) {
mapping_fix_type_field(Pike_sp[-1].u.mapping);
if( (m->data->ind_types & ~BIT_STRING) ||
(m->data->val_types & ~BIT_STRING) ) {
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("replace", 2, "mapping(string:string)");
|
200bfd | 2004-05-14 | Martin Nilsson | | }
}
|
f7a446 | 2000-10-31 | Mirar (Pontus Hagland) | | stack_dup();
f_indices(1);
stack_swap();
f_values(1);
args++;
}
else
|
06bd61 | 2016-01-26 | Martin Nilsson | | SIMPLE_WRONG_NUM_ARGS_ERROR("replace", 3);
|
7f0f34 | 2006-03-09 | Henrik Grubbström (Grubba) | | } else if (args > 3) {
pop_n_elems(args-3);
args = 3;
|
f7a446 | 2000-10-31 | Mirar (Pontus Hagland) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | switch(TYPEOF(Pike_sp[-args]))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
case T_ARRAY:
{
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | array_replace(Pike_sp[-args].u.array,Pike_sp+1-args,Pike_sp+2-args);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args-1);
break;
}
case T_MAPPING:
{
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | mapping_replace(Pike_sp[-args].u.mapping,Pike_sp+1-args,Pike_sp+2-args);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args-1);
break;
}
case T_STRING:
{
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *s;
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | switch(TYPEOF(Pike_sp[1-args]))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
default:
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("replace", 2, "string|array");
|
a8cdf9 | 2004-04-29 | Martin Nilsson | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_STRING:
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[2-args]) != T_STRING)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("replace", 3, "string");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | s=string_replace(Pike_sp[-args].u.string,
Pike_sp[1-args].u.string,
Pike_sp[2-args].u.string);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_ARRAY:
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[2-args]) == T_STRING) {
|
7f0f34 | 2006-03-09 | Henrik Grubbström (Grubba) | | push_int(Pike_sp[1-args].u.array->size);
stack_swap();
f_allocate(2);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | } else if(TYPEOF(Pike_sp[2-args]) != T_ARRAY)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("replace", 3, "array|string");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | s=replace_many(Pike_sp[-args].u.string,
Pike_sp[1-args].u.array,
Pike_sp[2-args].u.array);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
pop_n_elems(args);
push_string(s);
break;
}
|
8b6378 | 1996-04-11 | Fredrik Hübinette (Hubbe) | |
default:
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("replace", 1, "array|mapping|string");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
637767 | 2001-06-01 | Henrik Grubbström (Grubba) | | node *optimize_replace(node *n)
{
node **arg0 = my_get_arg(&_CDR(n), 0);
struct pike_type *array_zero;
struct pike_type *mapping_zero;
|
5527f7 | 2008-01-13 | Henrik Grubbström (Grubba) | | if (!arg0) return NULL;
|
637767 | 2001-06-01 | Henrik Grubbström (Grubba) | | MAKE_CONSTANT_TYPE(array_zero, tArr(tZero));
MAKE_CONSTANT_TYPE(mapping_zero, tMap(tZero, tZero));
|
5527f7 | 2008-01-13 | Henrik Grubbström (Grubba) | | if ((pike_types_le(array_zero, (*arg0)->type) ||
|
637767 | 2001-06-01 | Henrik Grubbström (Grubba) | | pike_types_le(mapping_zero, (*arg0)->type))) {
n->node_info |= OPT_SIDE_EFFECT;
n->tree_info |= OPT_SIDE_EFFECT;
|
fed7de | 2001-06-28 | Henrik Grubbström (Grubba) | | } else {
|
229f69 | 2004-12-18 | Henrik Grubbström (Grubba) | | * It must thus be a string.
|
fed7de | 2001-06-28 | Henrik Grubbström (Grubba) | | */
node **arg1 = my_get_arg(&_CDR(n), 1);
node **arg2 = my_get_arg(&_CDR(n), 2);
|
52af79 | 2014-10-22 | Arne Goedeke | |
struct program * volatile replace_compiler = NULL;
|
fed7de | 2001-06-28 | Henrik Grubbström (Grubba) | |
|
dc384d | 2006-03-11 | Henrik Grubbström (Grubba) | | if (arg1 && ((pike_types_le((*arg1)->type, array_type_string) &&
arg2 &&
(pike_types_le((*arg2)->type, array_type_string) ||
pike_types_le((*arg2)->type, string_type_string))) ||
(pike_types_le((*arg1)->type, mapping_type_string)))) {
|
a842b2 | 2006-03-11 | Henrik Grubbström (Grubba) | | extern struct program *multi_string_replace_program;
replace_compiler = multi_string_replace_program;
} else if (arg1 && pike_types_le((*arg1)->type, string_type_string) &&
arg2 && pike_types_le((*arg2)->type, string_type_string)) {
extern struct program *single_string_replace_program;
replace_compiler = single_string_replace_program;
}
if (replace_compiler && !is_const(*arg0) && is_const(*arg1) &&
(!arg2 || is_const(*arg2))) {
struct svalue *save_sp = Pike_sp;
JMP_BUF tmp;
if (SETJMP(tmp)) {
|
1ab4ac | 2008-01-26 | Martin Stjernholm | | struct svalue thrown;
|
a842b2 | 2006-03-11 | Henrik Grubbström (Grubba) | | struct pike_string *s;
|
1ab4ac | 2008-01-26 | Martin Stjernholm | | move_svalue (&thrown, &throw_value);
mark_free_svalue (&throw_value);
|
a842b2 | 2006-03-11 | Henrik Grubbström (Grubba) | | pop_n_elems(Pike_sp - save_sp);
yywarning("Optimizer failure in replace().");
s = format_exception_for_error_msg (&thrown);
if (s) {
yywarning ("%S", s);
free_string (s);
}
free_svalue(&thrown);
} else {
INT16 lfun;
struct object *replace_obj;
node *ret = NULL;
INT32 args;
args = eval_low(*arg1, 1);
|
2e45e2 | 2008-01-23 | Henrik Grubbström (Grubba) | | if (args != 1) goto failed;
|
a842b2 | 2006-03-11 | Henrik Grubbström (Grubba) | | if (arg2) {
|
1759c4 | 2008-01-21 | Henrik Grubbström (Grubba) | | args += eval_low(*arg2, 1);
if (!args) {
|
2e45e2 | 2008-01-23 | Henrik Grubbström (Grubba) | | goto failed;
|
1759c4 | 2008-01-21 | Henrik Grubbström (Grubba) | | }
|
a842b2 | 2006-03-11 | Henrik Grubbström (Grubba) | | }
|
cbd1f2 | 2001-06-29 | Henrik Grubbström (Grubba) | |
|
a842b2 | 2006-03-11 | Henrik Grubbström (Grubba) | | replace_obj = clone_object(replace_compiler, args);
|
fed7de | 2001-06-28 | Henrik Grubbström (Grubba) | |
|
a842b2 | 2006-03-11 | Henrik Grubbström (Grubba) | | push_object(replace_obj);
if (replace_obj->prog &&
((lfun = FIND_LFUN(replace_obj->prog, LFUN_CALL)) != -1)) {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(Pike_sp[-1], PIKE_T_FUNCTION, lfun, object, replace_obj);
|
a842b2 | 2006-03-11 | Henrik Grubbström (Grubba) | | ADD_NODE_REF2(*arg0,
ret = mkapplynode(mkconstantsvaluenode(Pike_sp-1),
*arg0);
);
|
fed7de | 2001-06-28 | Henrik Grubbström (Grubba) | |
|
a842b2 | 2006-03-11 | Henrik Grubbström (Grubba) | | UNSETJMP(tmp);
pop_n_elems(Pike_sp - save_sp);
|
fed7de | 2001-06-28 | Henrik Grubbström (Grubba) | |
|
a842b2 | 2006-03-11 | Henrik Grubbström (Grubba) | | free_type(array_zero);
free_type(mapping_zero);
return ret;
|
fed7de | 2001-06-28 | Henrik Grubbström (Grubba) | | }
}
|
2e45e2 | 2008-01-23 | Henrik Grubbström (Grubba) | | failed:
|
a842b2 | 2006-03-11 | Henrik Grubbström (Grubba) | | UNSETJMP(tmp);
pop_n_elems(Pike_sp - save_sp);
|
fed7de | 2001-06-28 | Henrik Grubbström (Grubba) | | }
|
637767 | 2001-06-01 | Henrik Grubbström (Grubba) | | }
|
84bf7e | 2001-06-05 | Martin Stjernholm | |
free_type(array_zero);
free_type(mapping_zero);
|
637767 | 2001-06-01 | Henrik Grubbström (Grubba) | | return NULL;
}
|
e290f3 | 2006-01-27 | Henrik Grubbström (Grubba) | | |
dc9ca6 | 2001-12-12 | Martin Nilsson | | *! int|void major, int|void minor,@
*! program|void target, object|void placeholder)
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Compile a string to a program.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! This function takes a piece of Pike code as a string and
*! compiles it into a clonable program.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! The optional argument @[handler] is used to specify an alternative
*! error handler. If it is not specified the current master object will
*! be used.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! The optional arguments @[major] and @[minor] are used to tell the
*! compiler to attempt to be compatible with Pike @[major].@[minor].
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
*! @note
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Note that @[source] must contain the complete source for a program.
*! It is not possible to compile a single expression or statement.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Also note that @[compile()] does not preprocess the program.
*! To preprocess the program you can use @[compile_string()] or
*! call the preprocessor manually by calling @[cpp()].
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
e290f3 | 2006-01-27 | Henrik Grubbström (Grubba) | | *! @[compile_string()], @[compile_file()], @[cpp()], @[master()],
|
71d390 | 2008-06-01 | Henrik Grubbström (Grubba) | | *! @[CompilationHandler], @[DefaultCompilerEnvironment]
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_compile(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
41c915 | 2008-04-18 | Henrik Grubbström (Grubba) | | apply_low(compilation_environment, CE_COMPILE_FUN_NUM, args);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | |
|
937c46 | 2001-02-06 | Henrik Grubbström (Grubba) | | |
84bf7e | 2001-06-05 | Martin Stjernholm | | *! int state)
*!
*! Set the value @[m] to use weak or normal references in its
*! indices and/or values (whatever is applicable). @[state] is a
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! bitfield built by using @expr{|@} between the following flags:
|
13670c | 2015-05-25 | Martin Nilsson | | *!
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @int
*! @value Pike.WEAK_INDICES
|
84bf7e | 2001-06-05 | Martin Stjernholm | | *! Use weak references for indices. Only applicable for
*! multisets and mappings.
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @value Pike.WEAK_VALUES
|
84bf7e | 2001-06-05 | Martin Stjernholm | | *! Use weak references for values. Only applicable for arrays
*! and mappings.
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @value Pike.WEAK
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Shorthand for @expr{Pike.WEAK_INDICES|Pike.WEAK_VALUES@}.
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @endint
|
13670c | 2015-05-25 | Martin Nilsson | | *!
|
84bf7e | 2001-06-05 | Martin Stjernholm | | *! If a flag is absent, the corresponding field will use normal
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! references. @[state] can also be @expr{1@} as a compatibility
|
84bf7e | 2001-06-05 | Martin Stjernholm | | *! measure; it's treated like @[Pike.WEAK].
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
*! @returns
|
937c46 | 2001-02-06 | Henrik Grubbström (Grubba) | | *! @[m] will be returned.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | */
|
5f0624 | 1999-04-11 | Fredrik Hübinette (Hubbe) | | #define SETFLAG(FLAGS,FLAG,ONOFF) \
FLAGS = (FLAGS & ~FLAG) | ( ONOFF ? FLAG : 0 )
|
3b589f | 1999-02-04 | Fredrik Hübinette (Hubbe) | | void f_set_weak_flag(INT32 args)
{
|
5f0624 | 1999-04-11 | Fredrik Hübinette (Hubbe) | | struct svalue *s;
|
5665ab | 1999-07-28 | Henrik Grubbström (Grubba) | | INT_TYPE ret;
|
be08a8 | 2001-06-06 | Martin Stjernholm | | int flags;
|
5665ab | 1999-07-28 | Henrik Grubbström (Grubba) | |
|
5f0624 | 1999-04-11 | Fredrik Hübinette (Hubbe) | | get_all_args("set_weak_flag",args,"%*%i",&s,&ret);
|
84bf7e | 2001-06-05 | Martin Stjernholm | | if (ret == 1) ret = PIKE_WEAK_BOTH;
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | switch(TYPEOF(*s))
|
3b589f | 1999-02-04 | Fredrik Hübinette (Hubbe) | | {
|
5f0624 | 1999-04-11 | Fredrik Hübinette (Hubbe) | | case T_ARRAY:
|
be08a8 | 2001-06-06 | Martin Stjernholm | | flags = array_get_flags(s->u.array);
SETFLAG(flags,ARRAY_WEAK_FLAG,ret & PIKE_WEAK_VALUES);
s->u.array = array_set_flags(s->u.array, flags);
|
5f0624 | 1999-04-11 | Fredrik Hübinette (Hubbe) | | break;
|
be08a8 | 2001-06-06 | Martin Stjernholm | | case T_MAPPING:
flags = mapping_get_flags(s->u.mapping);
|
84bf7e | 2001-06-05 | Martin Stjernholm | | flags = (flags & ~PIKE_WEAK_BOTH) | (ret & PIKE_WEAK_BOTH);
|
880be6 | 2000-09-04 | Martin Stjernholm | | mapping_set_flags(s->u.mapping, flags);
|
5f0624 | 1999-04-11 | Fredrik Hübinette (Hubbe) | | break;
|
e99c7a | 1999-10-29 | Martin Stjernholm | | case T_MULTISET:
|
5b15bb | 2001-12-10 | Martin Stjernholm | | flags = multiset_get_flags (s->u.multiset);
flags = (flags & ~PIKE_WEAK_BOTH) | (ret & PIKE_WEAK_BOTH);
multiset_set_flags (s->u.multiset, flags);
|
e99c7a | 1999-10-29 | Martin Stjernholm | | break;
|
5f0624 | 1999-04-11 | Fredrik Hübinette (Hubbe) | | default:
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("set_weak_flag",1,"array|mapping|multiset");
|
3b589f | 1999-02-04 | Fredrik Hübinette (Hubbe) | | }
|
5f0624 | 1999-04-11 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args-1);
|
3b589f | 1999-02-04 | Fredrik Hübinette (Hubbe) | | }
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | |
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Returns @expr{1@} if @[arg] is an object, @expr{0@} (zero) otherwise.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[mappingp()], @[programp()], @[arrayp()], @[stringp()], @[functionp()],
*! @[multisetp()], @[floatp()], @[intp()]
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_objectp(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args!=1)
SIMPLE_WRONG_NUM_ARGS_ERROR("objectp", 1);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[-args]) != T_OBJECT || !Pike_sp[-args].u.object->prog
|
031171 | 2013-06-17 | Martin Nilsson | | || is_bignum_object(Pike_sp[-args].u.object))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
pop_n_elems(args);
push_int(0);
}else{
pop_n_elems(args);
push_int(1);
}
}
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | |
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Returns @expr{1@} if @[arg] is a function, @expr{0@} (zero) otherwise.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[mappingp()], @[programp()], @[arrayp()], @[stringp()], @[objectp()],
*! @[multisetp()], @[floatp()], @[intp()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_functionp(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
2e0443 | 2001-04-09 | Per Hedbor | | int res = 0;
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args!=1)
SIMPLE_WRONG_NUM_ARGS_ERROR("functionp", 1);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if( TYPEOF(Pike_sp[-args]) == T_FUNCTION &&
(SUBTYPEOF(Pike_sp[-args]) == FUNCTION_BUILTIN ||
Pike_sp[-args].u.object->prog))
|
2e0443 | 2001-04-09 | Per Hedbor | | res=1;
pop_n_elems(args);
push_int(res);
}
|
47bb04 | 2015-12-12 | Henrik Grubbström (Grubba) | | PMOD_EXPORT int callablep(struct svalue *s)
|
2e0443 | 2001-04-09 | Per Hedbor | | {
|
d47633 | 2013-12-14 | Martin Nilsson | | switch( TYPEOF(*s) )
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
2e0443 | 2001-04-09 | Per Hedbor | | case T_FUNCTION:
|
b8619b | 2013-12-14 | Henrik Grubbström (Grubba) | | if( SUBTYPEOF(*s) == FUNCTION_BUILTIN
|| s->u.object->prog)
|
479924 | 2015-12-14 | Martin Nilsson | | return 1;
|
2e0443 | 2001-04-09 | Per Hedbor | | break;
case T_PROGRAM:
|
479924 | 2015-12-14 | Martin Nilsson | | return 1;
|
2e0443 | 2001-04-09 | Per Hedbor | | break;
case T_OBJECT:
|
f54c78 | 2004-12-22 | Henrik Grubbström (Grubba) | | {
struct program *p;
|
d47633 | 2013-12-14 | Martin Nilsson | | if((p = s->u.object->prog) &&
FIND_LFUN(p->inherits[SUBTYPEOF(*s)].prog,
|
f54c78 | 2004-12-22 | Henrik Grubbström (Grubba) | | LFUN_CALL ) != -1)
|
479924 | 2015-12-14 | Martin Nilsson | | return 1;
|
f54c78 | 2004-12-22 | Henrik Grubbström (Grubba) | | }
|
e8a76d | 2003-10-30 | Martin Nilsson | | break;
case T_ARRAY:
|
479924 | 2015-12-14 | Martin Nilsson | | {
int ret = 0;
DECLARE_CYCLIC();
if (BEGIN_CYCLIC(s, NULL)) {
END_CYCLIC();
return 1;
}
SET_CYCLIC_RET((ptrdiff_t)1);
|
d47633 | 2013-12-14 | Martin Nilsson | | array_fix_type_field(s->u.array);
if( !s->u.array->type_field) {
|
b8619b | 2013-12-14 | Henrik Grubbström (Grubba) | | ret = 1;
|
a8cdf9 | 2004-04-29 | Martin Nilsson | | }
|
479924 | 2015-12-14 | Martin Nilsson | | else if( !(s->u.array->type_field & ~(BIT_CALLABLE|BIT_INT)) ) {
|
d47633 | 2013-12-14 | Martin Nilsson | | struct array *a = s->u.array;
|
a8cdf9 | 2004-04-29 | Martin Nilsson | | int i;
|
b8619b | 2013-12-14 | Henrik Grubbström (Grubba) | | ret = 1;
|
a8cdf9 | 2004-04-29 | Martin Nilsson | | for(i=0; i<a->size; i++)
|
479924 | 2015-12-14 | Martin Nilsson | | if( TYPEOF(ITEM(a)[i])!=T_INT && !callablep(&ITEM(a)[i]) )
{
ret = 0;
break;
}
|
a8cdf9 | 2004-04-29 | Martin Nilsson | | }
|
479924 | 2015-12-14 | Martin Nilsson | | END_CYCLIC();
return ret;
|
e8a76d | 2003-10-30 | Martin Nilsson | | break;
|
479924 | 2015-12-14 | Martin Nilsson | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
b8619b | 2013-12-14 | Henrik Grubbström (Grubba) | |
|
479924 | 2015-12-14 | Martin Nilsson | | return 0;
|
d47633 | 2013-12-14 | Martin Nilsson | | }
PMOD_EXPORT void f_callablep(INT32 args)
{
int res = 0;
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args!=1)
SIMPLE_WRONG_NUM_ARGS_ERROR("callablep", 1);
|
d47633 | 2013-12-14 | Martin Nilsson | |
res = callablep(&Pike_sp[-args]);
|
2e0443 | 2001-04-09 | Per Hedbor | | pop_n_elems(args);
push_int(res);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
89b072 | 1998-05-05 | Fredrik Hübinette (Hubbe) | | #ifndef HAVE_AND_USE_POLL
#undef HAVE_POLL
#endif
|
371406 | 2010-02-18 | Stephen R. van den Berg | | static void delaysleep(double delay, unsigned do_abort_on_signal,
unsigned do_microsleep)
|
cb2256 | 1995-10-11 | Fredrik Hübinette (Hubbe) | | {
|
371406 | 2010-02-18 | Stephen R. van den Berg | | #define POLL_SLEEP_LIMIT 0.02
|
aba79f | 2011-11-17 | Tobias S. Josefowitz | | struct timeval gtod_t0 = {0,0}, gtod_tv = {0,0};
|
e611d3 | 2011-03-31 | Martin Stjernholm | | cpu_time_t t0, tv;
|
bebcca | 2001-11-08 | Fredrik Hübinette (Hubbe) | |
|
371406 | 2010-02-18 | Stephen R. van den Berg | |
if(delay == 0.0)
{
check_threads_etc();
|
5d6371 | 2010-09-28 | Martin Stjernholm | |
pike_thread_yield();
|
371406 | 2010-02-18 | Stephen R. van den Berg | | return;
}
if(sizeof(FLOAT_TYPE)<sizeof(double))
delay += FLT_EPSILON*5;
|
bebcca | 2001-11-08 | Fredrik Hübinette (Hubbe) | |
|
e611d3 | 2011-03-31 | Martin Stjernholm | | t0 = tv = get_real_time();
if (t0 == -1) {
|
f01020 | 2011-11-16 | Tobias S. Josefowitz | | ACCURATE_GETTIMEOFDAY (>od_t0);
|
e611d3 | 2011-03-31 | Martin Stjernholm | | gtod_tv = gtod_t0;
}
|
bebcca | 2001-11-08 | Fredrik Hübinette (Hubbe) | |
|
e611d3 | 2011-03-31 | Martin Stjernholm | | #define FIX_LEFT() \
if (t0 == -1) { \
|
f01020 | 2011-11-16 | Tobias S. Josefowitz | | ACCURATE_GETTIMEOFDAY (>od_tv); \
|
e611d3 | 2011-03-31 | Martin Stjernholm | | left = delay - ((gtod_tv.tv_sec-gtod_t0.tv_sec) + \
(gtod_tv.tv_usec-gtod_t0.tv_usec)*1e-6); \
} \
else { \
tv = get_real_time(); \
left = delay - (tv - t0) * (1.0 / CPU_TIME_TICKS); \
} \
if (do_microsleep) left-=POLL_SLEEP_LIMIT;
|
371406 | 2010-02-18 | Stephen R. van den Berg | |
if (!do_microsleep || delay>POLL_SLEEP_LIMIT)
{
for(;;)
{
double left;
THREADS_ALLOW();
FIX_LEFT();
if(left>0.0)
sysleep(left);
THREADS_DISALLOW();
|
5f7450 | 2011-01-24 | Martin Stjernholm | | if(do_abort_on_signal) {
|
f01020 | 2011-11-16 | Tobias S. Josefowitz | | INVALIDATE_CURRENT_TIME();
|
371406 | 2010-02-18 | Stephen R. van den Berg | | return;
|
5f7450 | 2011-01-24 | Martin Stjernholm | | }
|
371406 | 2010-02-18 | Stephen R. van den Berg | | FIX_LEFT();
if(left<=0.0)
break;
check_threads_etc();
}
|
f01020 | 2011-11-16 | Tobias S. Josefowitz | | INVALIDATE_CURRENT_TIME();
|
371406 | 2010-02-18 | Stephen R. van den Berg | | }
|
e611d3 | 2011-03-31 | Martin Stjernholm | | if (do_microsleep) {
if (t0 == -1) {
while (delay> ((gtod_tv.tv_sec-gtod_t0.tv_sec) +
(gtod_tv.tv_usec-gtod_t0.tv_usec)*1e-6))
|
f01020 | 2011-11-16 | Tobias S. Josefowitz | | ACCURATE_GETTIMEOFDAY (>od_tv);
|
e611d3 | 2011-03-31 | Martin Stjernholm | | }
else {
while (delay> (tv - t0) * (1.0 / CPU_TIME_TICKS))
tv = get_real_time();
}
}
|
371406 | 2010-02-18 | Stephen R. van den Berg | | }
PMOD_EXPORT void f_sleep(INT32 args)
{
double delay=0.0;
unsigned do_abort_on_signal;
|
bebcca | 2001-11-08 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | switch(TYPEOF(Pike_sp[-args]))
|
bebcca | 2001-11-08 | Fredrik Hübinette (Hubbe) | | {
case T_INT:
delay=(double)Pike_sp[-args].u.integer;
break;
case T_FLOAT:
delay=(double)Pike_sp[-args].u.float_number;
break;
}
|
371406 | 2010-02-18 | Stephen R. van den Berg | | do_abort_on_signal = delay!=0.0 && args > 1
&& !UNSAFE_IS_ZERO(Pike_sp + 1-args);
|
bebcca | 2001-11-08 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
|
371406 | 2010-02-18 | Stephen R. van den Berg | | delaysleep(delay, do_abort_on_signal, 0);
|
bebcca | 2001-11-08 | Fredrik Hübinette (Hubbe) | | }
#undef FIX_LEFT
#undef TIME_ELAPSED
|
768f53 | 2002-11-25 | Martin Nilsson | | *! not called during delay. Beware that this function uses busy-waiting
|
7a5abc | 2001-11-27 | Martin Stjernholm | | *! to achieve the highest possible accuracy.
|
13670c | 2015-05-25 | Martin Nilsson | | *!
|
bebcca | 2001-11-08 | Fredrik Hübinette (Hubbe) | | *! @seealso
*! @[signal()], @[sleep()]
*/
PMOD_EXPORT void f_delay(INT32 args)
{
|
838017 | 1999-12-06 | Mirar (Pontus Hagland) | | double delay=0.0;
|
371406 | 2010-02-18 | Stephen R. van den Berg | | unsigned do_abort_on_signal;
|
0dbb5c | 2000-02-22 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | switch(TYPEOF(Pike_sp[-args]))
|
838017 | 1999-12-06 | Mirar (Pontus Hagland) | | {
case T_INT:
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | delay=(double)Pike_sp[-args].u.integer;
|
838017 | 1999-12-06 | Mirar (Pontus Hagland) | | break;
|
b48f28 | 1998-03-26 | Henrik Grubbström (Grubba) | |
|
838017 | 1999-12-06 | Mirar (Pontus Hagland) | | case T_FLOAT:
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | delay=(double)Pike_sp[-args].u.float_number;
|
838017 | 1999-12-06 | Mirar (Pontus Hagland) | | break;
}
|
cb2256 | 1995-10-11 | Fredrik Hübinette (Hubbe) | |
|
371406 | 2010-02-18 | Stephen R. van den Berg | | do_abort_on_signal = delay!=0.0 && args > 1
&& !UNSAFE_IS_ZERO(Pike_sp + 1-args);
|
838017 | 1999-12-06 | Mirar (Pontus Hagland) | | pop_n_elems(args);
|
371406 | 2010-02-18 | Stephen R. van den Berg | | delaysleep(delay, do_abort_on_signal, !do_abort_on_signal && delay<10);
|
cb2256 | 1995-10-11 | Fredrik Hübinette (Hubbe) | | }
|
937c46 | 2001-02-06 | Henrik Grubbström (Grubba) | | |
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Force garbage collection.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! This function checks all the memory for cyclic structures such
*! as arrays containing themselves and frees them if appropriate.
|
7a5abc | 2001-11-27 | Martin Stjernholm | | *! It also frees up destructed objects and things with only weak
|
5a0d5b | 2003-01-11 | Martin Stjernholm | | *! references.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Normally there is no need to call this function since Pike will
*! call it by itself every now and then. (Pike will try to predict
*! when 20% of all arrays/object/programs in memory is 'garbage'
*! and call this routine then.)
|
5a0d5b | 2003-01-11 | Martin Stjernholm | | *!
*! @returns
*! The amount of garbage is returned. This is the number of arrays,
*! mappings, multisets, objects and programs that had no nonweak
*! external references during the garbage collection. It's normally
*! the same as the number of freed things, but there might be some
*! difference since destroy() functions are called during freeing,
*! which can cause more things to be freed or allocated.
|
51adb8 | 2003-01-12 | Martin Stjernholm | | *!
*! @seealso
*! @[Pike.gc_parameters], @[Debug.gc_status]
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | */
|
624d09 | 1996-02-24 | Fredrik Hübinette (Hubbe) | | void f_gc(INT32 args)
{
pop_n_elems(args);
|
51adb8 | 2003-01-12 | Martin Stjernholm | | push_int(do_gc(NULL, 1));
|
624d09 | 1996-02-24 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #ifdef TYPEP
#undef TYPEP
#endif
|
aa73fc | 1999-10-21 | Fredrik Hübinette (Hubbe) | |
|
f54c78 | 2004-12-22 | Henrik Grubbström (Grubba) | | #define TYPEP(ID,NAME,TYPE,TYPE_NAME) \
PMOD_EXPORT void ID(INT32 args) \
{ \
int t; \
struct program *p; \
|
06bd61 | 2016-01-26 | Martin Nilsson | | if (args!=1) \
SIMPLE_WRONG_NUM_ARGS_ERROR(NAME, 1); \
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-args]) == T_OBJECT && \
|
f54c78 | 2004-12-22 | Henrik Grubbström (Grubba) | | (p = Pike_sp[-args].u.object->prog)) \
{ \
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | int fun = FIND_LFUN(p->inherits[SUBTYPEOF(Pike_sp[-args])].prog, \
|
f54c78 | 2004-12-22 | Henrik Grubbström (Grubba) | | LFUN__IS_TYPE); \
if (fun != -1) \
{ \
int id_level = \
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | p->inherits[SUBTYPEOF(Pike_sp[-args])].identifier_level; \
|
6a932b | 2014-08-18 | Martin Nilsson | | ref_push_string(literal_##TYPE_NAME##_string); \
|
f54c78 | 2004-12-22 | Henrik Grubbström (Grubba) | | apply_low(Pike_sp[-args-1].u.object, fun + id_level, 1); \
stack_unlink(args); \
return; \
} \
} \
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | t = TYPEOF(Pike_sp[-args]) == TYPE; \
|
f54c78 | 2004-12-22 | Henrik Grubbström (Grubba) | | pop_n_elems(args); \
push_int(t); \
}
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | |
|
e00952 | 2007-11-18 | Martin Nilsson | |
PMOD_EXPORT void f_undefinedp(INT32 args)
{
|
06bd61 | 2016-01-26 | Martin Nilsson | | if( args!=1 )
SIMPLE_WRONG_NUM_ARGS_ERROR("undefinedp", 1);
|
e00952 | 2007-11-18 | Martin Nilsson | | f_zero_type(args);
Pike_sp[-1].u.integer = ( Pike_sp[-1].u.integer == NUMBER_UNDEFINED);
}
PMOD_EXPORT void f_destructedp(INT32 args)
{
|
06bd61 | 2016-01-26 | Martin Nilsson | | if( args!=1 )
SIMPLE_WRONG_NUM_ARGS_ERROR("destructedp", 1);
|
e00952 | 2007-11-18 | Martin Nilsson | | f_zero_type(args);
Pike_sp[-1].u.integer = ( Pike_sp[-1].u.integer == NUMBER_DESTRUCTED);
}
|
3b0f9f | 1999-10-22 | Henrik Grubbström (Grubba) | |
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | |
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Returns @expr{1@} if @[arg] is a program, @expr{0@} (zero) otherwise.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[mappingp()], @[intp()], @[arrayp()], @[stringp()], @[objectp()],
*! @[multisetp()], @[floatp()], @[functionp()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_programp(INT32 args)
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | {
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args!=1)
SIMPLE_WRONG_NUM_ARGS_ERROR("programp", 1);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | switch(TYPEOF(Pike_sp[-args]))
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | {
case T_PROGRAM:
pop_n_elems(args);
push_int(1);
return;
case T_FUNCTION:
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | if(program_from_function(Pike_sp-args))
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | {
pop_n_elems(args);
push_int(1);
return;
}
|
a22fe1 | 2015-04-23 | Henrik Grubbström (Grubba) | |
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | |
default:
pop_n_elems(args);
push_int(0);
}
}
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | |
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Returns @expr{1@} if @[arg] is an int, @expr{0@} (zero) otherwise.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[mappingp()], @[programp()], @[arrayp()], @[stringp()], @[objectp()],
*! @[multisetp()], @[floatp()], @[functionp()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Returns @expr{1@} if @[arg] is a mapping, @expr{0@} (zero) otherwise.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[intp()], @[programp()], @[arrayp()], @[stringp()], @[objectp()],
*! @[multisetp()], @[floatp()], @[functionp()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Returns @expr{1@} if @[arg] is an array, @expr{0@} (zero) otherwise.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[intp()], @[programp()], @[mappingp()], @[stringp()], @[objectp()],
*! @[multisetp()], @[floatp()], @[functionp()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Returns @expr{1@} if @[arg] is a multiset, @expr{0@} (zero) otherwise.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[intp()], @[programp()], @[arrayp()], @[stringp()], @[objectp()],
*! @[mappingp()], @[floatp()], @[functionp()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Returns @expr{1@} if @[arg] is a string, @expr{0@} (zero) otherwise.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[intp()], @[programp()], @[arrayp()], @[multisetp()], @[objectp()],
*! @[mappingp()], @[floatp()], @[functionp()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Returns @expr{1@} if @[arg] is a float, @expr{0@} (zero) otherwise.
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[intp()], @[programp()], @[arrayp()], @[multisetp()], @[objectp()],
*! @[mappingp()], @[stringp()], @[functionp()]
|
9c1a7b | 2001-01-08 | Henrik Grubbström (Grubba) | | */
|
d9a93b | 2001-07-01 | Fredrik Hübinette (Hubbe) | |
|
6a932b | 2014-08-18 | Martin Nilsson | | TYPEP(f_intp, "intp", T_INT, int)
TYPEP(f_mappingp, "mappingp", T_MAPPING, mapping)
TYPEP(f_arrayp, "arrayp", T_ARRAY, array)
TYPEP(f_multisetp, "multisetp", T_MULTISET, multiset)
TYPEP(f_stringp, "stringp", T_STRING, string)
TYPEP(f_floatp, "floatp", T_FLOAT, float)
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | |
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Sort arrays destructively.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! This function sorts the array @[index] destructively. That means
*! that the array itself is changed and returned, no copy is created.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! If extra arguments are given, they are supposed to be arrays of the
*! same size as @[index]. Each of these arrays will be modified in the
*! same way as @[index]. I.e. if index 3 is moved to position 0 in @[index]
*! index 3 will be moved to position 0 in all the other arrays as well.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
0c4978 | 2003-04-27 | Martin Stjernholm | | *! The sort order is as follows:
*!
*! @ul
*! @item
*! Integers and floats are sorted in ascending order.
*! @item
*! Strings are sorted primarily on the first characters that are
*! different, and secondarily with shorter strings before longer.
*! Different characters are sorted in ascending order on the
*! character value. Thus the sort order is not locale dependent.
*! @item
*! Arrays are sorted recursively on the first element. Empty
*! arrays are sorted before nonempty ones.
*! @item
*! Multisets are sorted recursively on the first index. Empty
*! multisets are sorted before nonempty ones.
*! @item
*! Objects are sorted in ascending order according to @[`<()],
*! @[`>()] and @[`==()].
*! @item
*! Other types aren't reordered.
*! @item
*! Different types are sorted in this order: Arrays, mappings,
*! multisets, objects, functions, programs, strings, types,
*! integers and floats. Note however that objects can control
*! their ordering wrt other types with @[`<], @[`>] and @[`==],
*! so this ordering of types only applies to objects without
*! those functions.
*! @endul
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
*! @returns
|
0c4978 | 2003-04-27 | Martin Stjernholm | | *! The first argument is returned.
|
13670c | 2015-05-25 | Martin Nilsson | | *!
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *! @note
|
0c4978 | 2003-04-27 | Martin Stjernholm | | *! The sort is stable, i.e. elements that are compare-wise equal
*! aren't reordered.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
c30609 | 2003-02-16 | Martin Stjernholm | | *! @[Array.sort_array], @[reverse()]
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_sort(INT32 args)
|
ed70b7 | 1996-06-09 | Fredrik Hübinette (Hubbe) | | {
INT32 e,*order;
|
0c4978 | 2003-04-27 | Martin Stjernholm | | struct array *a;
|
ed70b7 | 1996-06-09 | Fredrik Hübinette (Hubbe) | |
|
bee430 | 1997-02-24 | Fredrik Hübinette (Hubbe) | | if(args < 1)
|
06bd61 | 2016-01-26 | Martin Nilsson | | SIMPLE_WRONG_NUM_ARGS_ERROR("sort", 1);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[-args]) != T_ARRAY)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("sort", 1, "array");
|
0c4978 | 2003-04-27 | Martin Stjernholm | | a = Pike_sp[-args].u.array;
|
ed70b7 | 1996-06-09 | Fredrik Hübinette (Hubbe) | |
|
0c4978 | 2003-04-27 | Martin Stjernholm | | for(e=1;e<args;e++)
|
ed70b7 | 1996-06-09 | Fredrik Hübinette (Hubbe) | | {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[e-args]) != T_ARRAY)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("sort", e+1, "array");
|
ed70b7 | 1996-06-09 | Fredrik Hübinette (Hubbe) | |
|
0c4978 | 2003-04-27 | Martin Stjernholm | | if(Pike_sp[e-args].u.array->size != a->size)
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | bad_arg_error("sort", Pike_sp-args, args, e+1, "array", Pike_sp+e-args,
|
d0d01b | 1999-03-20 | Henrik Grubbström (Grubba) | | "Argument %d has wrong size.\n", (e+1));
|
ed70b7 | 1996-06-09 | Fredrik Hübinette (Hubbe) | | }
|
3beb89 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | if(args > 1)
{
|
0c4978 | 2003-04-27 | Martin Stjernholm | | order = stable_sort_array_destructively(a);
for(e=1;e<args;e++) order_array(Pike_sp[e-args].u.array,order);
|
3beb89 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args-1);
|
0ec752 | 2014-04-27 | Martin Nilsson | | free(order);
|
0c4978 | 2003-04-27 | Martin Stjernholm | | }
else {
|
caa676 | 2003-04-27 | Martin Stjernholm | | array_fix_unfinished_type_field (a);
|
0c4978 | 2003-04-27 | Martin Stjernholm | | if (a->type_field & BIT_COMPLEX)
free (stable_sort_array_destructively (a));
else
sort_array_destructively (a);
|
3beb89 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | }
|
ed70b7 | 1996-06-09 | Fredrik Hübinette (Hubbe) | | }
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | |
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Select a set of rows from an array.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! This function is en optimized equivalent to:
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
f79bd8 | 2003-04-01 | Martin Nilsson | | *! @code
*! map(@[index], lambda(mixed x) { return @[data][x]; })
*! @endcode
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! That is, it indices data on every index in the array index and
*! returns an array with the results.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[column()]
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_rows(INT32 args)
|
ed70b7 | 1996-06-09 | Fredrik Hübinette (Hubbe) | | {
INT32 e;
struct array *a,*tmp;
|
d0d01b | 1999-03-20 | Henrik Grubbström (Grubba) | | struct svalue *val;
|
2523ce | 2003-04-28 | Martin Stjernholm | | TYPE_FIELD types;
|
ed70b7 | 1996-06-09 | Fredrik Hübinette (Hubbe) | |
|
d0d01b | 1999-03-20 | Henrik Grubbström (Grubba) | | get_all_args("rows", args, "%*%a", &val, &tmp);
|
ed70b7 | 1996-06-09 | Fredrik Hübinette (Hubbe) | |
|
866972 | 1999-08-02 | Fredrik Hübinette (Hubbe) | |
if(tmp->refs == 1)
{
struct svalue sval;
tmp->type_field = BIT_MIXED | BIT_UNFINISHED;
|
2523ce | 2003-04-28 | Martin Stjernholm | | types = 0;
|
866972 | 1999-08-02 | Fredrik Hübinette (Hubbe) | | for(e=0;e<tmp->size;e++)
{
index_no_free(&sval, val, ITEM(tmp)+e);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | types |= 1 << TYPEOF(sval);
|
866972 | 1999-08-02 | Fredrik Hübinette (Hubbe) | | free_svalue(ITEM(tmp)+e);
|
2523ce | 2003-04-28 | Martin Stjernholm | | move_svalue (ITEM(tmp) + e, &sval);
|
866972 | 1999-08-02 | Fredrik Hübinette (Hubbe) | | }
|
2523ce | 2003-04-28 | Martin Stjernholm | | tmp->type_field = types;
|
866972 | 1999-08-02 | Fredrik Hübinette (Hubbe) | | stack_swap();
pop_stack();
return;
}
|
ed70b7 | 1996-06-09 | Fredrik Hübinette (Hubbe) | |
|
866972 | 1999-08-02 | Fredrik Hübinette (Hubbe) | | push_array(a=allocate_array(tmp->size));
|
2523ce | 2003-04-28 | Martin Stjernholm | | types = 0;
for(e=0;e<a->size;e++) {
|
d0d01b | 1999-03-20 | Henrik Grubbström (Grubba) | | index_no_free(ITEM(a)+e, val, ITEM(tmp)+e);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | types |= 1 << TYPEOF(ITEM(a)[e]);
|
2523ce | 2003-04-28 | Martin Stjernholm | | }
a->type_field = types;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
edf4d0 | 2000-07-06 | Fredrik Hübinette (Hubbe) | | Pike_sp--;
dmalloc_touch_svalue(Pike_sp);
|
d0d01b | 1999-03-20 | Henrik Grubbström (Grubba) | | pop_n_elems(args);
|
ed70b7 | 1996-06-09 | Fredrik Hübinette (Hubbe) | | push_array(a);
}
|
768f53 | 2002-11-25 | Martin Nilsson | | |
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! Perform sanity checks.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! This function goes through most of the internal Pike structures and
*! generates a fatal error if one of them is found to be out of order.
*! It is only used for debugging.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
*! @note
|
50d97a | 2003-02-01 | Martin Stjernholm | | *! This function does a more thorough check if the Pike runtime has
*! been compiled with RTL debug.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f__verify_internals(INT32 args)
|
ed70b7 | 1996-06-09 | Fredrik Hübinette (Hubbe) | | {
|
05590d | 1998-04-23 | Fredrik Hübinette (Hubbe) | | INT32 tmp=d_flag;
|
811116 | 2003-09-07 | Martin Nilsson | |
|
20ee33 | 2003-09-08 | Martin Stjernholm | |
d_flag = 49;
|
50d97a | 2003-02-01 | Martin Stjernholm | | #ifdef PIKE_DEBUG
do_debug();
#else
|
7458da | 2003-02-02 | Martin Stjernholm | | do_gc(NULL, 1);
|
50d97a | 2003-02-01 | Martin Stjernholm | | #endif
|
ed70b7 | 1996-06-09 | Fredrik Hübinette (Hubbe) | | d_flag=tmp;
pop_n_elems(args);
}
|
fe9150 | 1998-07-26 | Peter J. Holzer | | static void encode_struct_tm(struct tm *tm)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
75367d | 2014-08-22 | Arne Goedeke | | push_static_text("sec");
|
3beb89 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | push_int(tm->tm_sec);
|
75367d | 2014-08-22 | Arne Goedeke | | push_static_text("min");
|
3beb89 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | push_int(tm->tm_min);
|
75367d | 2014-08-22 | Arne Goedeke | | push_static_text("hour");
|
3beb89 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | push_int(tm->tm_hour);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
|
75367d | 2014-08-22 | Arne Goedeke | | push_static_text("mday");
|
3beb89 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | push_int(tm->tm_mday);
|
75367d | 2014-08-22 | Arne Goedeke | | push_static_text("mon");
|
3beb89 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | push_int(tm->tm_mon);
|
75367d | 2014-08-22 | Arne Goedeke | | push_static_text("year");
|
3beb89 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | push_int(tm->tm_year);
|
75367d | 2014-08-22 | Arne Goedeke | | push_static_text("wday");
|
3beb89 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | push_int(tm->tm_wday);
|
75367d | 2014-08-22 | Arne Goedeke | | push_static_text("yday");
|
3beb89 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | push_int(tm->tm_yday);
|
75367d | 2014-08-22 | Arne Goedeke | | push_static_text("isdst");
|
3beb89 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | push_int(tm->tm_isdst);
|
fe9150 | 1998-07-26 | Peter J. Holzer | | }
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | |
df0f87 | 2003-04-14 | Martin Stjernholm | | *! Convert seconds since 00:00:00 UTC, Jan 1, 1970 into components.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! This function works like @[localtime()] but the result is
*! not adjusted for the local time zone.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[localtime()], @[time()], @[ctime()], @[mktime()]
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_gmtime(INT32 args)
|
fe9150 | 1998-07-26 | Peter J. Holzer | | {
|
1bf419 | 2006-07-02 | Martin Stjernholm | | #if defined (HAVE_GMTIME_R) || defined (HAVE_GMTIME_S)
struct tm tm_s;
#endif
|
fe9150 | 1998-07-26 | Peter J. Holzer | | struct tm *tm;
|
14f689 | 2008-04-22 | Martin Stjernholm | | LONGEST tt;
|
fe9150 | 1998-07-26 | Peter J. Holzer | | time_t t;
|
14f689 | 2008-04-22 | Martin Stjernholm | | get_all_args("gmtime", args, "%l", &tt);
#if SIZEOF_TIME_T < SIZEOF_LONGEST
if (tt > MAX_TIME_T || tt < MIN_TIME_T)
SIMPLE_ARG_ERROR ("gmtime", 1, "Timestamp outside valid range.");
#endif
t = (time_t) tt;
|
d0d01b | 1999-03-20 | Henrik Grubbström (Grubba) | |
|
1bf419 | 2006-07-02 | Martin Stjernholm | | #ifdef HAVE_GMTIME_R
tm = gmtime_r (&t, &tm_s);
#elif defined (HAVE_GMTIME_S)
|
8e71e5 | 2008-06-25 | Martin Stjernholm | | if (!gmtime_s (&tm_s, &t)) tm = &tm_s; else tm = NULL;
|
1bf419 | 2006-07-02 | Martin Stjernholm | | #else
|
d0d01b | 1999-03-20 | Henrik Grubbström (Grubba) | | tm = gmtime(&t);
|
1bf419 | 2006-07-02 | Martin Stjernholm | | #endif
|
f917a3 | 2002-10-03 | Martin Stjernholm | | if (!tm) Pike_error ("gmtime() on this system cannot handle "
|
8e71e5 | 2008-06-25 | Martin Stjernholm | | "the timestamp %"PRINTLONGEST"d.\n", (LONGEST) t);
|
fe9150 | 1998-07-26 | Peter J. Holzer | | pop_n_elems(args);
encode_struct_tm(tm);
|
75367d | 2014-08-22 | Arne Goedeke | | push_static_text("timezone");
|
fe9150 | 1998-07-26 | Peter J. Holzer | | push_int(0);
f_aggregate_mapping(20);
}
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | |
df0f87 | 2003-04-14 | Martin Stjernholm | | *! Convert seconds since 00:00:00 UTC, 1 Jan 1970 into components.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
*! @returns
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! This function returns a mapping with the following components:
*! @mapping
*! @member int(0..60) "sec"
*! Seconds over the minute.
*! @member int(0..59) "min"
*! Minutes over the hour.
*! @member int(0..23) "hour"
*! Hour of the day.
*! @member int(1..31) "mday"
*! Day of the month.
*! @member int(0..11) "mon"
*! Month of the year.
*! @member int(0..) "year"
*! Year since 1900.
*! @member int(0..6) "wday"
*! Day of week (0 = Sunday).
*! @member int(0..365) "yday"
*! Day of the year.
*! @member int(0..1) "isdst"
*! Is daylight savings time.
*! @member int "timezone"
|
69a342 | 2004-04-01 | Henrik Grubbström (Grubba) | | *! Offset from UTC, including daylight savings time adjustment.
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @endmapping
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
|
f917a3 | 2002-10-03 | Martin Stjernholm | | *! An error is thrown if the localtime(2) call failed on the system.
|
b5b1b2 | 2002-10-03 | Martin Stjernholm | | *! It's platform dependent what time ranges that function can handle,
*! e.g. Windows doesn't handle a negative @[timestamp].
*!
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *! @note
|
69a342 | 2004-04-01 | Henrik Grubbström (Grubba) | | *! Prior to Pike 7.5 the field @expr{"timezone"@} was sometimes not
*! present, and was sometimes not adjusted for daylight savings time.
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
554e22 | 2001-05-06 | Henrik Grubbström (Grubba) | | *! @[Calendar], @[gmtime()], @[time()], @[ctime()], @[mktime()]
|
ed1cc3 | 2001-01-09 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_localtime(INT32 args)
|
fe9150 | 1998-07-26 | Peter J. Holzer | | {
struct tm *tm;
|
14f689 | 2008-04-22 | Martin Stjernholm | | LONGEST tt;
|
fe9150 | 1998-07-26 | Peter J. Holzer | | time_t t;
|
14f689 | 2008-04-22 | Martin Stjernholm | | get_all_args("localtime", args, "%l", &tt);
#if SIZEOF_TIME_T < SIZEOF_LONGEST
if (tt > MAX_TIME_T || tt < MIN_TIME_T)
|
771209 | 2008-04-23 | Martin Stjernholm | | SIMPLE_ARG_ERROR ("localtime", 1, "Timestamp outside valid range.");
|
14f689 | 2008-04-22 | Martin Stjernholm | | #endif
t = (time_t) tt;
|
d0d01b | 1999-03-20 | Henrik Grubbström (Grubba) | |
tm = localtime(&t);
|
f917a3 | 2002-10-03 | Martin Stjernholm | | if (!tm) Pike_error ("localtime() on this system cannot handle "
"the timestamp %ld.\n", (long) t);
|
fe9150 | 1998-07-26 | Peter J. Holzer | | pop_n_elems(args);
encode_struct_tm(tm);
|
3beb89 | 1996-06-21 | Fredrik Hübinette (Hubbe) | |
|
75367d | 2014-08-22 | Arne Goedeke | | push_static_text("timezone");
|
69a342 | 2004-04-01 | Henrik Grubbström (Grubba) | | #ifdef STRUCT_TM_HAS_GMTOFF
|
47ba81 | 2002-03-21 | Henrik Grubbström (Grubba) | | push_int(-tm->tm_gmtoff);
|
69a342 | 2004-04-01 | Henrik Grubbström (Grubba) | | #elif defined(STRUCT_TM_HAS___TM_GMTOFF)
|
47ba81 | 2002-03-21 | Henrik Grubbström (Grubba) | | push_int(-tm->__tm_gmtoff);
|
69a342 | 2004-04-01 | Henrik Grubbström (Grubba) | | #elif defined(HAVE_EXTERNAL_TIMEZONE)
push_int(timezone - 3600*tm->tm_isdst);
|
3beb89 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | #else
|
69a342 | 2004-04-01 | Henrik Grubbström (Grubba) | |
push_int(-3600*tm->tm_isdst);
|
47ba81 | 2002-03-21 | Henrik Grubbström (Grubba) | | #endif
|
69a342 | 2004-04-01 | Henrik Grubbström (Grubba) | | f_aggregate_mapping(20);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
778568 | 2007-03-29 | Martin Stjernholm | |
#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
static const int mon_lengths[2][12] = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
static void normalize_date (struct tm *t)
{
int q, year, mon, mday, leap;
q = t->tm_mon / 12;
if (t->tm_mon < 0) q--;
t->tm_mon -= q * 12;
t->tm_year += q;
year = t->tm_year + 1900;
leap = isleap (year);
mon = t->tm_mon;
mday = t->tm_mday;
if (mday > 0) {
int mon_len = mon_lengths[leap][mon];
if (mday <= mon_len) return;
do {
mday -= mon_len;
if (++mon == 12) mon = 0, year++, leap = isleap (year);
} while (mday > (mon_len = mon_lengths[leap][mon]));
}
else
do {
if (mon == 0) mon = 11, year--, leap = isleap (year);
else mon--;
mday += mon_lengths[leap][mon];
} while (mday < 1);
t->tm_year = year - 1900;
t->tm_mon = mon;
t->tm_mday = mday;
}
#define CHECKED_DIFF_MULT(RES, A, B, MULT, OVERFLOW) do { \
RES = (A - B) * (MULT); \
if ((A > B) != (RES > 0)) {OVERFLOW;} \
} while (0)
#define CHECKED_ADD(ACC, DIFF, OVERFLOW) do { \
time_t res_ = ACC + DIFF; \
if ((ACC > 0) == (DIFF > 0) && (ACC > 0) != (res_ > 0)) \
{OVERFLOW;} \
else \
ACC = res_; \
} while (0)
|
a7c4d9 | 2004-01-30 | Henrik Grubbström (Grubba) | |
static time_t my_tm_diff(const struct tm *t1, const struct tm *t2)
{
|
778568 | 2007-03-29 | Martin Stjernholm | | time_t base, diff;
|
aac1c4 | 2004-12-22 | Henrik Grubbström (Grubba) | |
if (!t2) return -1;
|
778568 | 2007-03-29 | Martin Stjernholm | | CHECKED_DIFF_MULT (base, t1->tm_year, t2->tm_year, 60*60*24*31*12,
return base < 0 ? MAX_TIME_T : MIN_TIME_T);
|
86d9aa | 2004-12-13 | Martin Stjernholm | |
|
778568 | 2007-03-29 | Martin Stjernholm | |
diff =
(t1->tm_mon - t2->tm_mon) * (60*60*24*31) +
(t1->tm_mday - t2->tm_mday) * (60*60*24) +
(t1->tm_hour - t2->tm_hour) * (60*60) +
|
a7c4d9 | 2004-01-30 | Henrik Grubbström (Grubba) | | (t1->tm_min - t2->tm_min) * 60 +
(t1->tm_sec - t2->tm_sec);
|
86d9aa | 2004-12-13 | Martin Stjernholm | |
|
778568 | 2007-03-29 | Martin Stjernholm | | CHECKED_ADD (base, diff,
return diff < 0 ? MIN_TIME_T : MAX_TIME_T);
|
0083c1 | 2004-02-02 | Henrik Grubbström (Grubba) | | return base;
|
a7c4d9 | 2004-01-30 | Henrik Grubbström (Grubba) | | }
|
86d9aa | 2004-12-13 | Martin Stjernholm | | typedef struct tm *time_fn (const time_t *);
|
c3df66 | 2004-12-14 | Martin Stjernholm | | |
a7c4d9 | 2004-01-30 | Henrik Grubbström (Grubba) | < |