Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

countgraphicsstack

12 views
Skip to first unread message

jdaw1

unread,
Nov 16, 2006, 10:06:58 PM11/16/06
to
Why isn't there a countgraphicsstack equivalent to the countdictstack?
At the end of a program can one check that unpopped gsave after gsave
haven't been left on the graphics stack?

François Robert

unread,
Nov 17, 2006, 5:23:04 AM11/17/06
to
"jdaw1" <jdawi...@gmail.com> wrote in
news:1163732818.3...@h54g2000cwb.googlegroups.com:

For the graphic stack, I don't think there is. For the 'save' depth,
'vmstatus' will do.
_______________________________________________________
François Robert
(to mail me, reverse character order in reply address)

Aandi Inston

unread,
Nov 17, 2006, 7:22:48 AM11/17/06
to
"jdaw1" <jdawi...@gmail.com> wrote:

>At the end of a program can one check that unpopped gsave after gsave
>haven't been left on the graphics stack?

You can repeatedly call grestore, but that won't tell you if it did
anything.

You could also "test to destruction": in a given implementation, there
is probably a hard limit, and you could find what it was at the start,
then again at the end.
----------------------------------------
Aandi Inston qu...@dial.pipex.com http://www.quite.com
Please support usenet! Post replies and follow-ups, don't e-mail them.

Chapman Flack

unread,
Nov 17, 2006, 9:22:31 AM11/17/06
to
> "jdaw1" <jdawi...@gmail.com> wrote:
>
> >At the end of a program can one check that unpopped gsave after gsave
> >haven't been left on the graphics stack?

One approach would be to prepend replacements for gsave
and grestore that increment/decrement a counter. If the
counter value is kept in local VM, it should also have the
correct interaction with save/restore, automagically.

-Chap

jdaw1

unread,
Nov 17, 2006, 12:08:35 PM11/17/06
to
Yuk-tastic all round. Currently I end code with something like

(pstack start) == pstack (pstack done) ==
(countdictstack = ) dup 17 countdictstack ( ) cvs
putinterval =
(countexecstack = ) dup 17 countexecstack ( ) cvs
putinterval =

just to check that things are behaving (though the countexecstack thing
isn't useful).

> One approach would be to prepend replacements for gsave
> and grestore that increment/decrement a counter. If the
> counter value is kept in local VM, it should also have the
> correct interaction with save/restore, automagically.

Would this be done by starting a program with
/gsave {/CountGsaveStack CountGsaveStack 1 add store gsave} bind def
/grestore {/CountGsaveStack CountGsaveStack 1 sub store gsave} bind def
/CountGsaveStack 0 def
and then ending with
(CountGsaveStack = ) dup 18 CountGsaveStack ( ) cvs
putinterval =
?

jdaw1

unread,
Nov 17, 2006, 2:23:28 PM11/17/06
to
Whoops: switch one of the gsave's to a grestore, and it seems to be
good. (And rename the variable to something better.)

% Used to check that every gsave is matched with a grestore
/gsave {/CountGraphicsStack CountGraphicsStack 1 add store gsave} bind
def
/grestore {/CountGraphicsStack CountGraphicsStack 1 sub store grestore}
bind def
/CountGraphicsStack 0 def

[ ... later, without the bad line breaks ... ]

(pstack start) == pstack (pstack done) ==
(countdictstack = ) dup 17 countdictstack ( ) cvs
putinterval =
(countexecstack = ) dup 17 countexecstack ( ) cvs
putinterval =

(CountGraphicsStack = ) dup 21 CountGraphicsStack ( ) cvs
putinterval =

and, amazingly, my code finished with "CountGraphicsStack = 0", about
which I can be pleased.

Francois Robert

unread,
Nov 17, 2006, 3:50:05 PM11/17/06
to
In article <1163773349.4...@f16g2000cwb.googlegroups.com>,
"Chapman Flack" <goo...@anastigmatix.net> wrote:

> > "jdaw1" <jdawi...@gmail.com> wrote:
> >
> > >At the end of a program can one check that unpopped gsave
> > > after gsave haven't been left on the graphics stack?
>
> One approach would be to prepend replacements for gsave
> and grestore that increment/decrement a counter.

... provided you never use 'setgstate'.
As soon as the '*gstate' operators were introduced in L2, the
gsave/grestore could no longer be assumed to always behave in a
stack-like fashion.
Having a unbalanced number of gsave and grestore is therefore not
necessarily an indication of an error. (Admittedly, code written in such
a way is probably confusing and hard to follow. But it can be correct
nonetheless)

--
________________________________________________________
Francois Robert

Chapman Flack

unread,
Nov 17, 2006, 5:14:28 PM11/17/06
to
Francois Robert wrote:
> In article <1163773349.4...@f16g2000cwb.googlegroups.com>,

> > > >At the end of a program can one check that unpopped gsave
> > > > after gsave haven't been left on the graphics stack?
>
> ... provided you never use 'setgstate'.
> As soon as the '*gstate' operators were introduced in L2, the
> gsave/grestore could no longer be assumed to always behave in a
> stack-like fashion.
> Having a unbalanced number of gsave and grestore is therefore not
> necessarily an indication of an error. (Admittedly, code written in such
> a way is probably confusing and hard to follow. But it can be correct

Well, granting that such code *could* be arbitrarily
weird, there's still a good chance it isn't. A given
piece of code has probably been designed *either* to
use a stack-like discipline with gsave/grestore, or
with some other discipline using *gstate. A program that
mixes the two probably comes about most often by
combining pieces, say new code using a stack
discipline calling into some library/resource code that
might do something else internally (and is presumably
well tested). In that case it can still be quite sensible to
want to know whether the new/calling/application code
is behaving according to its intended discipline.

-Chap

Francois Robert

unread,
Nov 18, 2006, 6:21:44 PM11/18/06
to
In article <1163801668....@k70g2000cwa.googlegroups.com>,
"Chapman Flack" <goo...@anastigmatix.net> wrote:

> ...it can still be quite sensible to


> want to know whether the new/calling/application code
> is behaving according to its intended discipline.

Agreed, from a programmer perspective.

The OP original question however was a design question (*Why* isn't
there a countgraphicsstack). From an interpreter perspective (or a
language designer perspective), I would therefore surmise that the
answer to the OP is : because you cannot impose a stack discipline to
the graphic states, thanks to the three *gstate operators. So there is
no stack depth to measure.

--
________________________________________________________
Francois Robert

jdaw1

unread,
Nov 19, 2006, 3:31:07 PM11/19/06
to
There is a stack. There is an alternative to using that stack, but it
exists nonetheless. So why not have an operator that returns its depth?

Aandi Inston

unread,
Nov 19, 2006, 3:50:06 PM11/19/06
to
"jdaw1" <jdawi...@gmail.com> wrote:

>There is a stack. There is an alternative to using that stack, but it
>exists nonetheless. So why not have an operator that returns its depth?

We can speculate as to reasons, but we (users, in some cases experts)
in PostScript still cannot really give any insight into Adobe's
thought processes unless they documented them (they didn't!)

jdaw1

unread,
Nov 20, 2006, 2:48:44 PM11/20/06
to
The following is slightly safer if the count initialisation is run more
than once.

/CountGraphicsStack where {pop}
{


/gsave {/CountGraphicsStack CountGraphicsStack 1 add store gsave
} bind def
/grestore {/CountGraphicsStack CountGraphicsStack 1 sub store
grestore} bind def
/CountGraphicsStack 0 def

} ifelse % /CountGraphicsStack where

Aandi Inston

unread,
Nov 20, 2006, 4:24:00 PM11/20/06
to
"jdaw1" <jdawi...@gmail.com> wrote:

>/CountGraphicsStack where {pop}
>{
> /gsave {/CountGraphicsStack CountGraphicsStack 1 add store gsave
>} bind def
> /grestore {/CountGraphicsStack CountGraphicsStack 1 sub store
>grestore} bind def
> /CountGraphicsStack 0 def
>} ifelse % /CountGraphicsStack where

Don't forget that save and restore also affect the stack, and a number
of things might affect it internally.

0 new messages