@q
@program debug.muf
1 9999 d
i
  
( debug.muf    v1.0    Jessy @ FurryMUCK    8/01
  
  This coder utility lets you run commands in debug mode without having 
  to manually set and unset -- and perhaps to forget to un-set -- the D
  flag.
  
  For example, to print a stack trace to determine why your 'where'
  command is crashing when you type 'where jessy', you could type
  'debug where jessy'.
  
  INSTALLATION:
  
  Create a global exit with a name such as 'debug' and link it to the 
  program. The program needs to be set Wizard so that it can toggle the 
  D bit on programs not owned by the user.
  
  USE:
    
    debug < ......................... Run  in debug mode
    debug #allow <= .... Allow  to debug 
    debug #!allow <= ... Don't allow  to debug 
  
  Debug.muf may be freely ported. Please comment any changes.
)
  
(2345678901234567890123456789012345678901234567890123456789012345678901)
  
$define Tell me @ swap notify $enddef
  
$include $lib/reflist
  
lvar ourTrig
lvar ourArg
lvar ourProg
lvar ourState
lvar ourPlayer
  
: DoHelp  (  --  )                                (* show help screen *)
  
  "Debug.muf v1.0" Tell " " Tell
  
  "This coder's utility allows one to run a command in debug mode "
  "without having to manually set and unset (and perhaps forget to "
  "unset) the D flag." strcat strcat Tell " " Tell
  
  "By default, programs can only be debugged by wizards or their "
  "owners. You can allow others to debug your programs with the "
  "#allow option." strcat strcat Tell " " Tell
  
  "  %cmd < .......................... Run  in debug mode"
  command @ "%cmd" subst Tell
  "  %cmd #allow <= ..... Allow  to debug "
  command @ "%cmd" subst Tell
  "  %cmd #!allow <= .... Don't allow  to debug "
  command @ "%cmd" subst Tell " " Tell
;
  
: DoAllowUsage  (  --  )      (* display syntax of #allow and #!allow *)
  
  ">>  Usage: %cmd %opt <="
  command @ "%cmd" subst 
  ourTrig @ "%opt" subst Tell
;
  
: DoParseAllow  ( -- i )           (* parse arg for #allow or #!allow *)
                                         (* return true if successful *)
  
  ourArg @ "=" instr not if
    DoAllowUsage 0 exit
  then
  
  ourArg @ dup "=" instr strcut strip ourProg ! 
  
  dup strip strlen 1 - strcut pop strip ourPlayer !
  
  ourPlayer @ not ourProg @ not or if
    DoAllowUsage 0 exit
  then
  
  ourPlayer @ .pmatch ourPlayer !
  ourProg   @   match ourProg   !
  
  ourPlayer @ not if
    DoAllowUsage ">>  I can't find that player." Tell 0 exit
  then
  
  ourProg @ not if
    DoAllowUsage ">>  I can't find that command or program." Tell 0 exit
  then
  
  ourProg @ #-2 dbcmp if
    DoAllowUsage 
    ">>  I can't tell which command or program you mean!" Tell 0 exit
  then
  
  ourProg @ #-3 dbcmp if
    DoAllowUsage ">>  'Home' isn't a command or program." Tell 0 exit
  then
  
  ourProg @ exit? ourProg @ program? or not if
    DoAllowUsage ">>  That isn't a command or program." Tell 0 exit
  then
  
  ourProg @ exit? if
    ourProg @ getlink dup if
      ourProg !
    else
      ">>  That command isn't currently linked to a program." Tell 0 exit
    then
  then
  
  ourProg @ program? not if
    DoAllowUsage ">>  That isn't a command or program." Tell 0 exit
  then
  
  me @ ourProg @ controls not if
    ">>  Permission denied." Tell 0 exit
  then
  
  1
;
  
: DoAllow  (  --  )      (* set prop allowing player to debug command *)
  
  DoParseAllow not if exit then
  
  ourProg @ "_debug/list" ourPlayer @ REF-add
  
  ">>  Set. %name can now debug %prog."
  ourPlayer @ name "%name" subst 
  ourProg @ unparseobj "%prog" subst Tell
;
  
: DoNoAllow  (  --  ) (* remove prop allowing player to debug command *)
  
  DoParseAllow not if exit then
  
  ourProg @ "_debug/list" ourPlayer @ REF-add
  
  ourPlayer @ ourProg @ controls if
    ">>  Set." Tell
  else
    ">>  Set. %name now cannot debug %prog."
    ourPlayer @ name "%name" subst 
    ourProg @ unparseobj "%prog" subst Tell
  then
;
  
: DoParse  (  --  )                (* parse, getting command to debug *)
                                         (* return true if successful *)
  
  dup " " instr if
    dup " " instr strcut ourArg ! ourTrig !
  else
    ourTrig ! "" ourArg !
  then
  
  ourTrig @ strip ourTrig !
  
  "#help"   ourTrig @ strip stringpfx if DoHelp    0 exit then
  "#allow"  ourTrig @ strip stringpfx if DoAllow   0 exit then
  "#!allow" ourTrig @ strip stringpfx if DoNoAllow 0 exit then
  
  1
;
  
: DoMatch  (  --  )                 (* find #dbref of command to dbug *)
                                         (* return true if successful *)
  
  ourTrig @ match
  
  dup not if 
    ">>  Command %trig not found."
    ourTrig @ "%trig" subst Tell exit 0
  then
  
  dup #-2 dbcmp if
    ">>  I'm not sure which command you mean!" Tell exit 0
  then
  
  dup #-3 dbcmp if
    ">>  That's not a command." Tell exit 0
  then
  
  dup exit? not if
    ">>  That's not a command." Tell exit 0
  then
  
  ourTrig !
  
  ourTrig @ getlink
  
  dup not if
    ">>  That command is currently unlinked." Tell exit 0
  then
  
  dup program? not if
    ">>  That command is not currently linked to a program." Tell exit 0
  then
  
  ourProg !
  
  ourProg @ "D" flag? ourState !
  
  1
;
  
: DoCheck  (  -- i )   (* return true if user is allowed to debug cmd *)
  
  me @ ourProg @ controls
  ourProg @ "_debug/all" getprop or
  ourProg @ "_debug/list" me @ REF-inlist? or if 
    1 
  else 
    ">>  Permission denied." Tell 0 
  then
;
  
: DoDebug  (  --  )            (* run specified command in debug mode *)
  
  ourProg @ "D" set
  
  ourArg @ ourProg @ Call
  
  ourState @ not if
    ourProg @ "!D" set
  then
;
  
: main
  
  "me" match me !
  
  dup if
    
    DoParse not if exit then
  
    DoMatch not if exit then
  
    DoCheck not if exit then
    
    DoDebug 
    
  else
  
    ">>  Usage: %cmd <"
    command @ "%cmd" subst Tell
  
  then
;
.
c
q