1
  
2
  
3
  
4
  
5
  
6
  
7
  
8
  
9
  
10
  
11
  
12
  
13
  
14
  
15
  
16
  
17
  
18
  
19
  
20
  
21
  
22
  
23
  
24
  
25
  
26
  
27
  
28
  
29
  
30
  
31
  
32
  
33
  
34
  
35
  
36
  
37
  
38
  
39
  
40
  
41
  
42
  
43
  
44
  
45
  
46
  
47
  
48
  
49
  
50
  
51
  
52
  
53
  
54
  
55
  
56
  
57
  
58
  
59
  
60
  
61
  
62
  
63
  
64
  
65
  
66
  
67
  
68
  
69
  
70
  
71
  
72
  
73
  
74
  
75
  
76
  
77
  
78
  
79
  
80
  
81
  
82
  
83
  
84
  
85
  
86
  
#pike __REAL_VERSION__ 
 
//! This wrapper can be placed around another object to get 
//! printouts about what is happening to it. Only a few LFUNs 
//! are currently supported. 
//! @example 
//!  > object x=Debug.Wrapper(Crypto.MD5()); 
//!  Debug.Wrapper is proxying ___Nettle.MD5_State() 
//!  > x->name(); 
//!  ___Nettle.MD5_State()->name 
//!  (1) Result: "md5" 
//!  > !x; 
//!  !___Nettle.MD5_State() 
//!  (2) Result: 0 
 
protected object wrappee; 
protected object compile_handler; 
 
//! 
void create(object x) { 
  werror("Debug.Wrapper is proxying %O\n", x); 
  wrappee = x; 
 
  compile_handler = class { 
    mapping(string:mixed) get_default_module() { 
      return all_constants() + ([ "wrappee":wrappee ]); 
    } 
  }(); 
} 
 
//! 
int(0..1) `!() 
{ 
  werror("!%O\n", wrappee); 
  return !wrappee; 
} 
 
//! 
mixed `[](mixed x, void|mixed y) { 
  if(undefinedp(y)) { 
    werror("%O[%O]\n", wrappee, x); 
    return wrappee[x]; 
  } 
  else { 
    werror("%O[%O..%O]\n", wrappee, x, y); 
    return wrappee[x..y]; 
  } 
} 
 
//! 
mixed `->(mixed x) { 
  if(stringp(x)) 
    werror("%O->%s\n", wrappee, x); 
  else 
    error("%O->`->(%O) doesn't work now.\n", wrappee, x); 
  return compile_string("mixed foo() { return wrappee->"+x+"; }", 
                        0, compile_handler)()->foo(); 
} 
 
//! 
array _indices() { 
  werror("indices(%O)\n", wrappee); 
  return indices(wrappee); 
} 
 
//! 
array _values() { 
  werror("values(%O)\n", wrappee); 
  return values(wrappee); 
} 
 
//! 
int _sizeof() { 
  werror("sizeof(%O)\n", wrappee); 
  return sizeof(wrappee); 
} 
 
//! 
string _sprintf(int c, mapping(string:mixed)|void attrs) 
{ 
  if (wrappee->_sprintf) 
    return sprintf("Debug.Wrapper(%s)", wrappee->_sprintf(c, attrs)); 
  return sprintf(sprintf("Debug.Wrapper(%%%c)", c), wrappee); 
}