!--------------------------------------------------------------------------
! SHOWOBJ.H
! David Wagner
! Version 3
! 7-Nov-1995
! All rights given away.
!
! Defines the routines and grammar to create a debugging SHOWOBJ command,
! which will (to the best of its ability) reconstruct the definition of an
! object as it would appear in the Inform source code. This file is
! self-contained, so one could save this as a separate file and 'Include
! "showobj"' sometime after the parser has been Include'd.
!
! This requires that the DEBUG flag be set.
!
! Restrictions: Of course, it can't print out routine definitions, so it
! simply indicates that they exist by printing "[ ... ]". Also, it has to
! make guesses about whether objects are rooms, or daemons rather than
! timers, etc. and so it may get these wrong on occasion. Also, it only
! knows about those properties and attributes defined in the library
! (version 5/12), so you will have to modify it if you want your own
! properties / attributes printed (or if you using an earlier version of
! the libraries). Also, it doesn't know whether and object was originally
! defined using a "class" keyword.
!
! For the describe, description and short_name properties, this will
! actually call the routines to see what they print out; since calling
! routines can have unwanted side effects, this feature can be turned off
! by defining a constant SHOWOBJNOCALL before including this file.
!
! By default, it prints all the properties followed by all the attributes;
! this order can be reversed by defining a constant GARETH before including
! this file.
!--------------------------------------------------------------------------
#IFDEF DEBUG;
! Use up one global here. Sorry. This initialized to 0; it is set to 1 if
! the keyword 'with' has been printed and 2 if the keyword 'has' has been
! printed and 3 if both have been printed
Global ShowObjFlag;
!-----------------------------------------------------------------------
! PropertyType
! Determines the type of property. Slightly more informative than ZRegion
! (also ZRegion(addr) has problems if it is called when addr is obj.prop
! where the property is an array of values).
!
! Input: obj = object
! prop = property
! iprop = element number if the property is an array
!
! Returns: 0 = property doesn't exist
! 1 = property is a valid object number
! 2 = property is routine
! 3 = property is a string
! 4 = property is some other number
!
! Calls: UnsignedCompare
!
! Local: addr = address of the property in question
!-----------------------------------------------------------------------
[ PropertyType obj prop iprop addr;
if (obj.&prop == 0) return 0; ! property doesn't exist
if (obj.#prop == 1) return 4; ! one-byte long = pure number
addr = (obj.&prop)-->iprop;
if (addr == NULL) return 0;
if (addr == 0) return 4;
if (addr >= 1 && addr <= top_object) return 1;
if (UnsignedCompare(addr, #strings_offset)>=0) return 3;
if (UnsignedCompare(addr, #code_offset)>=0) return 2;
return 4;
];
!-----------------------------------------------------------------------
! PrintObjectProperty
! Prints one property for the noun object.
! Checks to see if the property exists first.
! Prints 'with' before printing the first property.
!
! Input: prop - the property to print
! propstring - the name of the property
!
! Called by: ShowObjSub
!
! Calls: PropertyType, RunRoutines
!
! Local: a - type of property (returned by PropertyType())
! nprop - size of the property
! iprop - loop counter
! addr - number or address of the string / routine
!-----------------------------------------------------------------------
[ PrintObjectProperty prop propstring a nprop iprop addr itemp;
! Does the property exist at all?
if (noun.&prop == 0) rfalse;
if (noun.#prop == 2 && noun.prop == NULL) rfalse;
! The property exists, so print its name (and "with" if it is the
! first)
! For found_in, we want to print the names of the room
if (prop == found_in && a == 1) {
PrintShortName(addr);
jump ENDLOOP;
}
! Some properties must always be routines:
if (prop == before or after or life ||
prop == react_before or react_after or orders ||
prop == grammar or daemon) {
print "[ ... ]";
jump ENDLOOP;
}
! Call the describe, description and short name routines to see
! what they say about the object; since routines can have
! side-effects, this can be compiled with SHOWOBJNOCALL defined to
! prevent this from happening.
if (prop == door_dir && a == 1) {
if (noun.door_dir == n_to) print "n_to";
if (noun.door_dir == ne_to) print "ne_to";
if (noun.door_dir == e_to) print "e_to";
if (noun.door_dir == se_to) print "se_to";
if (noun.door_dir == s_to) print "s_to";
if (noun.door_dir == sw_to) print "sw_to";
if (noun.door_dir == w_to) print "w_to";
if (noun.door_dir == nw_to) print "nw_to";
if (noun.door_dir == u_to) print "u_to";
if (noun.door_dir == d_to) print "d_to";
if (noun.door_dir == in_to) print "in_to";
if (noun.door_dir == out_to) print "out_to";
jump ENDLOOP;
}
! All other cases
if (a == 1 || a == 4) print addr;
if (a == 2) print "[ ... ]";
if (a == 3) { print "~", (string) addr, "~"; }
.ENDLOOP
}
rtrue;
];
!-----------------------------------------------------------------------
! PrintRoomProperty
! Prints one property for the noun object - assumes that noun is a room and
! prop is a direction; prints the name of the room that lies in that
! direction
!
! Input: prop - the property to print (must be a direction)
! propstring - the name of the property
!
! Called by: ShowObjSub
!
! Calls: ZRegion, PrintShortName
!
! Local: a - type of property (string or routine)
!-----------------------------------------------------------------------
[ PrintRoomProperty prop propstring a;
if (noun.prop == NULL) rfalse;
a = ZRegion(noun.prop);
if (a == 0) rfalse;
if ((ShowObjFlag & 1) == 0) {
print "^ with ";
ShowObjFlag = ShowObjFlag + 1;
}
else
print ",^ ";
print (string) propstring, " ";
if (a == 1) PrintShortName(noun.prop);
if (a == 2) print "[ ... ]";
if (a == 3) { print "~", (string) noun.prop, "~"; }
rtrue;
];
!-----------------------------------------------------------------------
! PrintObjectAttribute
! Prints one attribute for the noun object.
! The caller has already checked that the attribute is set
!
! Input: attr - attribute to test for
! text - name of the attribute
!
! Called by: ShowObjAttributes
!-----------------------------------------------------------------------
[ PrintObjectAttribute attr text;
if (noun hasnt attr) rfalse;
if ((ShowObjFlag & 2) == 0) {
if ((ShowObjFlag & 1) == 1) print ",";
print "^ has ";
ShowObjFlag = ShowObjFlag + 2;
}
print " ", (string) text;
rtrue;
];
!-----------------------------------------------------------------------
! ShowObjProperties
! Prints the properties of an object
!
! Called by: ShowObjSub
!
! Calls: PrintObjectProperty, PrintRoomProperty,
!-----------------------------------------------------------------------
[ ShowObjProperties;
! Since when_open == when_on == initial, guess which is meant
if (noun has switchable || noun has on)
PrintObjectProperty(when_on,"when_on");
else {
if (noun has open || noun has openable)
PrintObjectProperty(when_open,"when_open");
else
PrintObjectProperty(initial,"initial");
}
PrintObjectProperty(description,"description");
PrintObjectProperty(describe,"describe");
! Make the assumption that if the object isn't contained in something
! (or doesn't have a found_in property) then it is a room. This won't
! always be correct, though. PrintRoomProperty prints the directions