pike.git/src/operators.c:1:
/*
|| This file is part of Pike. For copyright information see COPYRIGHT.
|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
|| for more information.
- || $Id: operators.c,v 1.211 2006/07/05 19:28:10 mast Exp $
+ || $Id: operators.c,v 1.212 2006/08/15 10:43:24 grubba Exp $
*/
#include "global.h"
#include <math.h>
#include "interpret.h"
#include "svalue.h"
#include "multiset.h"
#include "mapping.h"
#include "array.h"
#include "stralloc.h"
pike.git/src/operators.c:889: Inside #if defined(PIKE_DEBUG)
#ifdef PIKE_DEBUG
if(save_sp != sp)
Pike_fatal("Internal error: o_cast() left droppings on stack.\n");
#endif
free_svalue(sp-2);
sp[-2]=sp[-1];
sp--;
dmalloc_touch_svalue(sp);
}
+ int low_check_soft_cast(struct pike_type *type, struct object *o, int is_type)
+ {
+ int ret;
+ loop:
+ if (type->type == PIKE_T_MIXED) return 1;
+ if (!o->prog) {
+ /* In case o has been destructed during our check. */
+ if (type->type == PIKE_T_ZERO) return 1;
+ return 0;
+ }
+ switch(type->type) {
+ case PIKE_T_ZERO:
+ return 0;
+ case PIKE_T_ARRAY: case PIKE_T_MAPPING: case PIKE_T_MULTISET:
+ case PIKE_T_OBJECT: case PIKE_T_FUNCTION: case PIKE_T_PROGRAM:
+ case PIKE_T_STRING: case PIKE_T_TYPE: case PIKE_T_INT:
+ case PIKE_T_FLOAT:
+ case T_MANY:
+ push_text(get_name_of_type(type->type));
+ apply_low(o, is_type, 1);
+ ret = !UNSAFE_IS_ZERO(Pike_sp-1);
+ pop_stack();
+ return ret;
+ case PIKE_T_NAME:
+ break;
+ case T_NOT:
+ return !low_check_soft_cast(type->cdr, o, is_type);
+ case T_AND:
+ if (!low_check_soft_cast(type->car, o, is_type)) return 0;
+ break;
+ case T_OR:
+ if (low_check_soft_cast(type->car, o, is_type)) return 1;
+ break;
+ default:
+ return 0;
+ }
+ type = type->cdr;
+ goto loop;
+ }
+
+ void o_check_soft_cast(struct svalue *s, struct pike_type *type)
+ {
+ struct pike_type *sval_type;
+ if (s->type == T_OBJECT) {
+ int is_type;
+ struct object *o;
+ struct program *p;
+
+ o = s->u.object;
+ p = o->prog;
+ if (p && ((is_type = FIND_LFUN(p, LFUN__IS_TYPE)) != -1)) {
+ int ok = low_check_soft_cast(type, o, is_type);
+ if (ok) return;
+ }
+ }
+
+ sval_type = get_type_of_svalue(s);
+ if (!pike_types_le(sval_type, type)) {
+ /* get_type_from_svalue() doesn't return a fully specified type
+ * for array, mapping and multiset, so we perform a more lenient
+ * check for them.
+ */
+ if (!pike_types_le(sval_type, weak_type_string) ||
+ !match_types(sval_type, type)) {
+ struct pike_string *t1;
+ struct pike_string *t2;
+ char *fname = "__soft-cast";
+ ONERROR tmp1;
+ ONERROR tmp2;
+
+ if (Pike_fp->current_object && Pike_fp->context.prog &&
+ Pike_fp->current_object->prog) {
+ /* Look up the function-name */
+ struct pike_string *name =
+ ID_FROM_INT(Pike_fp->current_object->prog, Pike_fp->fun)->name;
+ if ((!name->size_shift) && (name->len < 100))
+ fname = name->str;
+ }
+
+ t1 = describe_type(type);
+ SET_ONERROR(tmp1, do_free_string, t1);
+
+ t2 = describe_type(sval_type);
+ SET_ONERROR(tmp2, do_free_string, t2);
+
+ free_type(sval_type);
+
+ bad_arg_error(NULL, Pike_sp-1, 1, 1, t1->str, Pike_sp-1,
+ "%s(): Soft cast failed. Expected %s, got %s\n",
+ fname, t1->str, t2->str);
+ /* NOT_REACHED */
+ UNSET_ONERROR(tmp2);
+ UNSET_ONERROR(tmp1);
+ free_string(t2);
+ free_string(t1);
+ }
+ }
+ free_type(sval_type);
+ }
+
#define COMPARISON(ID,NAME,FUN) \
PMOD_EXPORT void ID(INT32 args) \
{ \
int i; \
switch(args) \
{ \
case 0: case 1: \
SIMPLE_TOO_FEW_ARGS_ERROR(NAME, 2); \
case 2: \
i=FUN (sp-2,sp-1); \