#include // ---------------------------------------------------------------------------- class testclass { testclass(name) { Message("constructing: %s\n", name); this.name = name; } ~testclass() { Message("destructing: %s\n", this.name); } set_name(n) { Message("testclass.set_name -> old=%s new=%s\n", this.name, n); this.name = n; } get_name() { return this.name; } } class testclass_extender: testclass { testclass_extender(id): testclass('asdf') { this.id = id; } // Override a method and then call the base version set_name(n) { Message("testclass_extender-> %s\n", n); testclass::set_name(this, n); } } static f1(n) { auto o1 = testclass("object in f1()"); o1.set_name(n); } static f2() { auto o2 = testclass("object2 in main()"); Message("calling f1()\n"); f1("new object1 name"); Message("returned from f1()\n"); } static test_class_extender() { auto c = testclass_extender(123); c.set_name("hello"); print(c); } // ---------------------------------------------------------------------------- static walk_attributes() { auto attr_name; auto o = object(); o.attr1 = "value1"; o.attr2 = "value2"; for ( attr_name=firstattr(o); attr_name != 0; attr_name=nextattr(o, attr_name) ) Message("->%s: %s\n", attr_name, getattr(o, attr_name)); } // ---------------------------------------------------------------------------- class list { list() { this.__count = 0; } size() { return this.__count; } add(e) { this[this.__count++] = e; } } static test_list() { auto a = list(); a.add("hello"); a.add("world"); a.add(5); auto i; for (i=a.size()-1;i>=0;i--) print(a[i]); } // ---------------------------------------------------------------------------- static test_exceptions() { // variable to hold the exception information auto e; try { auto a = object(); // Try to read an invalid attribute: Message("a.name=%s\n", a.name); } catch ( e ) { Message("Exception occured. Exception dump follows:\n"); print(e); } } static call_test_exceptions() { test_exceptions(); } // ---------------------------------------------------------------------------- class attr_hook { attr_hook() { this.id = 1; } // setattr will trigger for every attribute assignment __setattr__(attr, value) { Message("setattr: %s->", attr); print(value); setattr(this, attr, value); } // getattr will only trigger for non-existing attributes __getattr__(attr) { Message("getattr: '%s'\n", attr); if ( attr == "magic" ) return 0x5f8103; // Ofcourse this will cause an exception since we try to fetch a non-existing attribute return getattr(this, attr); } } // ---------------------------------------------------------------------------- static test_attr_hook() { // create as a global variable so we continue experimenting from IDA command line extern x; x = attr_hook(); print(x); Message("x.a=%d\n", x.id); } static main() { }