From: Sanjoy Mahajan <sanjoy@mrao.cam.ac.uk>
Subject: staticMPfigures can overrun output streams
Date: Sun, 24 Sep 2006 15:36:04 -0400 [thread overview]
Message-ID: <E1GRZlk-0004w5-MZ@approximate.corpus.cam.ac.uk> (raw)
The following minimal file overruns the available output streams
(version 2006.08.08 and context live):
\starttext
\dorecurse{16}{\startstaticMPfigure{\recurselevel}
fill fullcircle scaled 1cm withcolor red;
\stopstaticMPfigure}
\stoptext
At the end are the last few lines of the log. Here are the last few
lines of the last few lines:
! Bad number (16).
\openMPgraphicfile ...immediate \openout \MPwrite
\MPgraphicfile .mp\relax \...
After experiments and digging in the TeXbook I'm pretty sure the cause
is as follows:
The macro \openMPgraphicfile (supp-mps.tex) constructs the name of a new
output stream and allocates a new write to it:
\donetrue \@EA\@EA\csname newwrite\endcsname\csname\@@MPG\@@MPG\MPgraphicfile\endcsname
Then \MPwrite is set to this stream number:
\@EA\let\@EA\MPwrite\csname\@@MPG\@@MPG\MPgraphicfile\endcsname
And then it's opened:
\immediate\openout\MPwrite\MPgraphicfile.mp\relax
which is where TeX complains about the bad number (16).
The number gets that high because each static figure goes into a
separate file, and each file requires a \newwrite. I thought it would
not run out of streams because the allocation is all enclosed in
\bgroup..\egroup (in \startstaticMPgraphic) and the \egroup would pop
the write-stream allocation stack. But no such luck. The workhorse
\alloc (p.347 of the TeXBook) uses a \global assignment to the control
sequence.
Here's a possible solution that works here but is a hack and may make
unwarranted assumptions about control-sequence names. It require a new
if to say whether we are processing a static MP figure, and then using a
dedicated output stream for those writes.
======================== cut here ========================
\unprotect
\newif\ifinstaticMPfigure
\newwrite\MPstaticwrite
\long\def\startstaticMPgraphic#1#2\stopstaticMPgraphic
{\bgroup
\instaticMPfiguretrue % value is restored by the \egroup
\setMPrandomseedfalse
\def\MPgraphicfile{#1}% no \jobname here
\let\allocateMPslot \gobbleoneargument
\let\deallocateMPslot\gobbleoneargument
\let\runMPgraphic \gobbleoneargument
\runMPgraphicstrue
\enableincludeMPgraphics
\currentMPgraphic\plusone % hack, else no close
\startMPgraphic#2\stopMPgraphic
\executeMPgraphicfile
\egroup}
\def\openMPgraphicfile#1#2% #1=alwaysopen #2=message
{%\doifundefinedelse{\@@MPG\@@MPG\MPgraphicfile}
% {\donetrue
% \@EA\newwrite\csname\@@MPG\@@MPG\MPgraphicfile\endcsname}%
% {\ifcase#1\donefalse\else\donetrue\fi}%
\@EA\ifx\csname\@@MPG\@@MPG\MPgraphicfile\endcsname\relax
%\donetrue \@EA\newwrite\csname\@@MPG\@@MPG\MPgraphicfile\endcsname
% for the sake of plain usage
\donetrue
\ifinstaticMPfigure
\let\MPwrite\MPstaticwrite
\else
\@EA\@EA\csname newwrite\endcsname\csname\@@MPG\@@MPG\MPgraphicfile\endcsname
\fi
\doglobal\addtocommalist\MPgraphicfile\MPgraphicfiles
\else
\ifcase#1\relax\donefalse\else\donetrue\fi
\fi
\ifinstaticMPfigure
\else
\@EA\let\@EA\MPwrite\csname\@@MPG\@@MPG\MPgraphicfile\endcsname
\fi
\ifdone
\immediate\openout\MPwrite\MPgraphicfile.mp\relax
\ifx\MPinputtranslation\empty\else
\immediate\write\MPwrite{\MPinputtranslation}%
\immediate\write\MPwrite{verbatimtex \MPinputtranslation etex ;}%
\fi
\immediate\write\MPwrite{\letterpercent\space #2 graphics of job "\jobname"}%
\writeMPgraph
\setMPrandomseed
\fi}
\protect
\starttext
\dorecurse{16}{\startstaticMPfigure{\recurselevel}
fill fullcircle scaled 1cm withcolor red;
\stopstaticMPfigure}
\stoptext
======================== cut here ========================
As a diff:
======================== cut here ========================
--- a/supp-mps.tex 2006-07-22 11:26:47.000000000 -0400
+++ b/supp-mps.tex 2006-09-24 15:32:19.000000000 -0400
@@ -315,7 +315,9 @@
%D setting the next boolean to true.
\newwrite\MPwrite
+\newwrite\MPstaticwrite
+\newif\ifinstaticMPfigure
\newif\iflongMPlines \longMPlinestrue % we now have \obeyMPlines
\ifx \overlaywidth \undefined \def \overlaywidth {4cm} \fi
@@ -720,12 +722,20 @@
\@EA\ifx\csname\@@MPG\@@MPG\MPgraphicfile\endcsname\relax
%\donetrue \@EA\newwrite\csname\@@MPG\@@MPG\MPgraphicfile\endcsname
% for the sake of plain usage
- \donetrue \@EA\@EA\csname newwrite\endcsname\csname\@@MPG\@@MPG\MPgraphicfile\endcsname
+ \donetrue
+ \ifinstaticMPfigure
+ \let\MPwrite\MPstaticwrite
+ \else
+ \@EA\@EA\csname newwrite\endcsname\csname\@@MPG\@@MPG\MPgraphicfile\endcsname
+ \fi
\doglobal\addtocommalist\MPgraphicfile\MPgraphicfiles
\else
\ifcase#1\relax\donefalse\else\donetrue\fi
\fi
- \@EA\let\@EA\MPwrite\csname\@@MPG\@@MPG\MPgraphicfile\endcsname
+ \ifinstaticMPfigure
+ \else
+ \@EA\let\@EA\MPwrite\csname\@@MPG\@@MPG\MPgraphicfile\endcsname
+ \fi
\ifdone
\immediate\openout\MPwrite\MPgraphicfile.mp\relax
\ifx\MPinputtranslation\empty\else
@@ -1983,6 +1993,7 @@
\long\def\startstaticMPgraphic#1#2\stopstaticMPgraphic
{\bgroup
+ \instaticMPfiguretrue % value is restored by the \egroup
\setMPrandomseedfalse
\def\MPgraphicfile{#1}% no \jobname here
\let\allocateMPslot \gobbleoneargument
======================== cut here ========================
Which has left a minor puzzle. Without the patch, where did the warning
from plain TeX go? When you overrun the number of writes, it should
say:
! No room for (\write) \H.
e.g. try this file:
\starttext
\dorecurse{17}{\newwrite\H}
\stoptext
But with the staticMPfigure test file, the "No room for (\write)"
message didn't appear, and instead the TeX complained only when \openout
was tried on the resulting stream.
Meanwhile here's more of the original log:
======================== cut here ========================
\openout14 = `toomany-9.mp'.
\openout5 = `toomany-mpgraph.mpb'.
system(texmfstart --ifchanged=toomany-9.mp texexec --mpgraphic toomany-9.mp)...
executed.
color : currentcolor (def) is not defined
\openout15 = `toomany-10.mp'.
\openout5 = `toomany-mpgraph.mpb'.
system(texmfstart --ifchanged=toomany-10.mp texexec --mpgraphic toomany-10.mp).
..executed.
color : currentcolor (def) is not defined
! Bad number (16).
\openMPgraphicfile ...immediate \openout \MPwrite
\MPgraphicfile .mp\relax \...
\startwritingMPgraphic ...MPgraphicfile 1{runtime}
\theMPextensions \theMPinc...
\startMPgraphic ...aphic ->\startwritingMPgraphic
\writecheckedMPgraphic {#1...
\startstaticMPgraphic ...graphic #2\stopMPgraphic
\executeMPgraphicfile \egr...
\dostartstaticMPfigure ...}#2\stopstaticMPgraphic
\endgroup
\redorecurse ->\expandrecursecontent
\dodorecurse
...
l.20 \stopstaticMPfigure}
?
======================== cut here ========================
-Sanjoy
`A society of sheep must in time beget a government of wolves.'
-- Bertrand de Jouvenal
next reply other threads:[~2006-09-24 19:36 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-09-24 19:36 Sanjoy Mahajan [this message]
2006-09-24 21:04 ` Hans Hagen
2006-09-24 21:36 ` Sanjoy Mahajan
2006-09-25 7:53 ` Taco Hoekwater
2006-09-25 20:08 ` Sanjoy Mahajan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=E1GRZlk-0004w5-MZ@approximate.corpus.cam.ac.uk \
--to=sanjoy@mrao.cam.ac.uk \
--cc=ntg-context@ntg.nl \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).