Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.postscript > #1793

debugger cracks loops

Newsgroups comp.lang.postscript
Date 2014-02-13 21:24 -0800
Message-ID <0c67addf-ee33-4159-877f-d20f0138c9be@googlegroups.com> (permalink)
Subject debugger cracks loops
From luser- -droog <mijoryx@yahoo.com>

Show all headers | View raw


This is a re-write of the debugger, simplified and condensed, and sorely
lacking useful comments. But it appears to solve the conundrum of 
interfacing into loops: treat them like any other overridden operator.


%/get {pstack/ = //get} def
%/oldifelse /ifelse load def
%/ifelse {pstack/ = oldifelse} def
%errordict/typecheck{ pstack }put

<<
/nextobject null
/stack 500 array
/ptr -1
/trace false
/step false
/steppstack true
/enddefbegin { currentdict 3 1 roll end def begin }
>> begin /dbdict currentdict def

% push and pop the dbdict<stack>
/pushs { % proc|file  pushs
    //dbdict /ptr 2 copy get 1 add put
    //dbdict /stack get //dbdict /ptr get 3 -1 roll put  % dbdict<stack>[++dbdict<ptr>] = _
} def
/pops {
    //dbdict /ptr get 0 ge {
        //dbdict /stack get //dbdict /ptr get get  % dbdict<stack>[dbdict<ptr>]
        dup type /filetype eq {closefile}{pop} ifelse
        //dbdict /ptr 2 copy get 1 sub put  % --dbdict<ptr>
    } if
} def

% executable source type handlers
/nametype {
    //pops exec
    true
} def
/filetype {
    token
} def
/stringtype {
    token {
        exch 
        //dbdict /stack get //dbdict /ptr get 3 -1 roll put
        true
    }{
        false
    } ifelse
} def
/arraytype {
    dup length 0 gt {
        dup 0 get exch
        dup length 1 gt {
            //dbdict /stack get //dbdict /ptr get 3 -1 roll
            1 1 index length 1 sub getinterval put
        }{
            pop
            //pops exec
        } ifelse
        true
    }{
        //pops exec
        false
    } ifelse
} def

/getnextobject {
    //dbdict /nextobject get
    dup null eq {
        pop
        //dbdict /ptr get 0 ge {
            //dbdict /stack get //dbdict /ptr get get
            //dbdict 1 index type get exec
        }{
            false
        } ifelse
    }{ true } ifelse
} def

/addoper { 1 index dup load type /operatortype eq { 1 index }{pop} ifelse } def
/operators <<
    /run { (r) file //pushs exec } addoper
    /if { exch { //pushs exec }{ pop } ifelse } addoper
    /ifelse { 3 2 roll not { exch } if pop //pushs exec } addoper
    /loop {
        /loop cvx //pushs exec
        dup 1 array astore cvx //pushs exec
        //pushs exec
    } addoper
    /repeat {
        exch dup 0 eq { pop pop }{
            /repeat cvx //pushs exec
            1 sub 2 copy exch 2 array astore cvx //pushs exec
            pop //pushs exec
        } ifelse
    } addoper
    /exit {
        %dumpstack
        {
            //dbdict /stack get //dbdict /ptr get -1 0 { % stack index
                2 copy get % stack index object
                dup /loop eq {
                    //dbdict /ptr 4 3 roll 1 sub put pop stop
                }{
                    dup /repeat eq {
                        //dbdict /ptr 4 3 roll 1 sub put pop stop
                    }{
                        pop
                    } ifelse
                } ifelse
                pop
            } for
        } stopped not { /exit cvx /unregistered signalerror } if
        pop
    } addoper
>> def

/debugheart {
    //operators 1 index known {
        //operators exch get exec
    }{
        load
        dup type /arraytype eq {
            dup length 0 eq { pop } //pushs ifelse
        }{
            exec
        } ifelse
    } ifelse
} def

/stepcommands <<
    (n) 0 get { %next
        /stepon load //pushs exec stepoff //debugheart exec }
    /default 1 index
    (c) 0 get { stepoff //debugheart exec } %continue
    (b) 0 get { pop skip } %bypass
    (s) 0 get //debugheart % :)
    (q) 0 get { pop exit } %quit
>> def
/stepheart {
    (step: )print dup ==only
    ( defined as ) print
    dup { load } stopped { pop (/undefined)= }{ == } ifelse
    (execute step? (continue|next|bypass|step|quit)?) print flush
    (%lineedit)(r){file}stopped{ %EOF
        pop ()= exit
    }{
        read { %something typed
            //stepcommands exch
            2 copy known not { pop /default } if
            get //stepcommands /default 2 index put
            exec
        }{ %blank line
            //stepcommands /default get exec
        }ifelse
    }ifelse
} def

/errmsg {
    (Error /) print
    $error /errorname get dup length string cvs print
    ( occurred attempting to execute ) print
} def

/handerr {
    $error /errorname get /invalidexit eq {
        exit
    }{
        (db:)print
        //errmsg exec
        //dbdict /nextobject get ==
        (Stack:\n)print pstack
        {
            (db-error>) print flush
            (%lineedit)(r) file cvx exec
        } stopped {
            $error /errorname get dup /invalidexit ne
            exch /undefinedfilename ne and {
                //errmsg exec (user command\n) print
            } if
        } if
    } ifelse
} def

/debugloop {
    //getnextobject exec
    {
        //dbdict /nextobject 3 -1 roll put
        {
            //dbdict /nextobject get
            //dbdict /trace get { dup ==only //dbdict /cstack get exec } if

            dup xcheck {
                dup type /arraytype ne {
                    //dbdict /step get
                        //stepheart
                        //debugheart
                    ifelse
                } if
            } if % else leave on stack

            //dbdict /nextobject null put
        } stopped //handerr if
    }{ % no objects
        //pops exec
        //dbdict /nextobject null put
        //dbdict /ptr get 0 lt { exit } if %% <------ 'exit'
    } ifelse
} def

/cstack { ( %|- )print
    count dup 1 add copy -1 1{ -1 roll ==only ( )print }for
    pop / = } def

/skip {
    //dbdict /nextobject null put
} enddefbegin

/traceon {
    //dbdict /trace true put
} enddefbegin

/traceoff {
    //dbdict /trace false put
} enddefbegin

/stepon {
    //dbdict /step true put
} enddefbegin

/stepoff {
    //dbdict /step false put
} enddefbegin

/debug { % source  debug  -
    //dbdict 1 index type known not { /debug cvx /typecheck signalerror } if
    //pushs exec
    //debugloop loop
} enddefbegin

/dumpstack {
    //dbdict /stack get
    0 1 //dbdict /ptr get {
        2 copy get ==
        pop
    } for
    pop
} enddefbegin

end

traceon
( 1 2 3 add add
  6 eq { 8 9 add = } { 9 10 add = } ifelse
  ) debug
/ =

stepon
{ 1 2 3 add add
  6 eq { 7 } if

 9 {
     5
     count 4 gt {
         exit
     } if
 } repeat

  { 55 exit } loop
  undefin

    (continuation) =

} debug


And a trace of an interactive session, executing the test fragments:

GPL Ghostscript 9.06 (2012-08-08)
Copyright (C) 2012 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
1 %|- 1 
2 %|- 1 2 
3 %|- 1 2 3 
add %|- 1 2 3 add 
add %|- 1 5 add 
6 %|- 6 6 
eq %|- 6 6 eq 
{8 9 add =} %|- true {8 9 add =} 
{9 10 add =} %|- true {8 9 add =} {9 10 add =} 
ifelse %|- true {8 9 add =} {9 10 add =} ifelse 
8 %|- 8 
9 %|- 8 9 
add %|- 8 9 add 
= %|- 17 = 
17

1 %|- 1 
2 %|- 1 2 
3 %|- 1 2 3 
add %|- 1 2 3 add 
step: add defined as --add--
execute step? (continue|next|bypass|step|quit)?c
add %|- 1 5 add 
6 %|- 6 6 
eq %|- 6 6 eq 
{7} %|- true {7} 
if %|- true {7} if 
7 %|- 7 
9 %|- 7 9 
{5 count 4 gt {exit} if} %|- 7 9 {5 count 4 gt {exit} if} 
repeat %|- 7 9 {5 count 4 gt {exit} if} repeat 
5 %|- 7 5 
count %|- 7 5 count 
4 %|- 7 5 2 4 
gt %|- 7 5 2 4 gt 
{exit} %|- 7 5 false {exit} 
if %|- 7 5 false {exit} if 
8 %|- 7 5 8 
{5 count 4 gt {exit} if} %|- 7 5 8 {5 count 4 gt {exit} if} 
repeat %|- 7 5 8 {5 count 4 gt {exit} if} repeat 
5 %|- 7 5 5 
count %|- 7 5 5 count 
4 %|- 7 5 5 3 4 
gt %|- 7 5 5 3 4 gt 
{exit} %|- 7 5 5 false {exit} 
if %|- 7 5 5 false {exit} if 
7 %|- 7 5 5 7 
{5 count 4 gt {exit} if} %|- 7 5 5 7 {5 count 4 gt {exit} if} 
repeat %|- 7 5 5 7 {5 count 4 gt {exit} if} repeat 
5 %|- 7 5 5 5 
count %|- 7 5 5 5 count 
4 %|- 7 5 5 5 4 4 
gt %|- 7 5 5 5 4 4 gt 
{exit} %|- 7 5 5 5 false {exit} 
if %|- 7 5 5 5 false {exit} if 
6 %|- 7 5 5 5 6 
{5 count 4 gt {exit} if} %|- 7 5 5 5 6 {5 count 4 gt {exit} if} 
repeat %|- 7 5 5 5 6 {5 count 4 gt {exit} if} repeat 
5 %|- 7 5 5 5 5 
count %|- 7 5 5 5 5 count 
4 %|- 7 5 5 5 5 5 4 
gt %|- 7 5 5 5 5 5 4 gt 
{exit} %|- 7 5 5 5 5 true {exit} 
if %|- 7 5 5 5 5 true {exit} if 
exit %|- 7 5 5 5 5 exit 
{55 exit} %|- 7 5 5 5 5 {55 exit} 
loop %|- 7 5 5 5 5 {55 exit} loop 
55 %|- 7 5 5 5 5 55 
exit %|- 7 5 5 5 5 55 exit 
undefin %|- 7 5 5 5 5 55 undefin 
db:Error /undefined occurred attempting to execute undefin
Stack:
undefin
55
5
5
5
5
7
db-error>skip
(continuation) %|- 7 5 5 5 5 55 undefin (continuation) 
= %|- 7 5 5 5 5 55 undefin (continuation) = 
continuation
GS<7>

Back to comp.lang.postscript | Previous | Next — Next in thread | Find similar | Unroll thread


Thread

debugger cracks loops luser- -droog <mijoryx@yahoo.com> - 2014-02-13 21:24 -0800
  Re: debugger cracks loops luser- -droog <mijoryx@yahoo.com> - 2014-02-14 11:17 -0800
    Re: debugger cracks loops luser- -droog <mijoryx@yahoo.com> - 2014-02-15 01:20 -0800
      Re: debugger cracks loops luser- -droog <mijoryx@yahoo.com> - 2014-02-15 11:45 -0800

csiph-web