summaryrefslogtreecommitdiff
path: root/luatexbase-regs.dtx
blob: f3a29a85868d040a71efe0590d483c52abbb4230 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
% \iffalse meta-comment
%
% Copyright 2009, 2010 by Élie Roux <elie.roux@telecom-bretagne.eu>
% Copyright 2010, 2011 by Manuel Pégourié-Gonnard <mpg@elzevir.fr>
%
% This work is under the CC0 license.
%
% This work consists of the main source file luatexbase-regs.dtx
% and the derived files
%   luatexbase-regs.pdf luatexbase-regs.sty
%   test-regs-plain.tex test-regs-latex.tex
%
% Unpacking:
%    tex luatexbase-regs.dtx
% Documentation:
%    pdflatex luatexbase-regs.dtx
%
%<*ignore>
\begingroup
  \def\x{LaTeX2e}%
\expandafter\endgroup
\ifcase 0\ifx\install y1\fi\expandafter
         \ifx\csname processbatchFile\endcsname\relax\else1\fi
         \ifx\fmtname\x\else 1\fi\relax
\else\csname fi\endcsname
%</ignore>
%<*install>
\input docstrip.tex

\keepsilent
\askforoverwritefalse

\preamble

See the aforementioned source file(s) for copyright and licensing information.

\endpreamble

\generate{%
  \usedir{tex/luatex/luatexbase}%
  \file{luatexbase-regs.sty}{\from{luatexbase-regs.dtx}{texpackage}}%
}

\generate{%
  \usedir{doc/luatex/luatexbase}%
  \file{test-regs-plain.tex}{\from{luatexbase-regs.dtx}{testplain}}%
  \file{test-regs-latex.tex}{\from{luatexbase-regs.dtx}{testlatex}}%
}

\obeyspaces
\Msg{************************************************************************}
\Msg{*}
\Msg{* To finish the installation you have to move the following}
\Msg{* files into a directory searched by TeX:}
\Msg{*}
\Msg{*     luatexbase-regs.sty}
\Msg{*}
\Msg{* Happy TeXing!}
\Msg{*}
\Msg{************************************************************************}

\endbatchfile
%</install>
%<*ignore>
\fi
%</ignore>
%<*driver>
\NeedsTeXFormat{LaTeX2e}
\documentclass{ltxdoc}
\input lltxb-dtxstyle.tex
\EnableCrossrefs
\CodelineIndex
\begin{document}
  \DocInput{luatexbase-regs.dtx}%
\end{document}
%</driver>
% \fi
%
% \CheckSum{0}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
% \pkdate{luatexbase-regs}{2011/05/24 v0.4}
%
% \maketitle
%
% \begin{abstract}
% This package extends the register allocation scheme of \plaintex and
% \latex to take advantage of the increased number of registers available in
% \luatex.
% \end{abstract}
%
% \tableofcontents
%
% \section{Documentation}
%
% Since the \plaintex and \latex formats are both frozen, they fail to take
% into account the extended resources provided by newer \tex-like engines.
% This package focuses on the allocation scheme for registers. \texe provides
% $6$ kinds or registers: count, dimen, skip, muskip, box and toks and has
% $256$ registers of each kind. \eTeX\ and most of its descendants add one
% kind of register (marks) and offers $2^{15} = 32768$ of each kind. \luatex
% provides $2^{16} = 65536$ registers of each kind. (It also provides new
% register-like resources, but this package addresses only the resources
% inherited from \eTeX.)
%
% More precisely, \pk{luatexbase-regs} loads the \pk{etex} package (or
% makes sure it is preloaded in the format) and then adapts it to the new
% limits of \luatex. Thus, all macros defined by the \pk{etex} package are
% made available (most notably, |\loccount|, |\globcountblk|,
% |\loccountblk| and alike). However, if a register of some kind has been
% locally allocated before this package is loaded, then the number of
% allocatable registers of this kind will not be extended to $65536$. To avoid
% this, load \pk{luatexbase-regs} earlier.
%
% The \plaintex and \latex formats define a new kind of resource:
% \emph{inserts} which are merely a family (count, dimen, skip, box) of
% registers with the same number. Inserts allocation begins at $255$ and goes
% toward $0$. Thus we can make room for more inserts by making allocation of
% count-, dimen-, skip- and box-registers start from $256$. With real \etex,
% it may be a bad idea since registers with index greater than $256$ have
% degraded performance due to implementation details, but with \luatex the
% performance is uniform, so we just do it.
%
%    \section{Implementation}
%
%    \begin{macrocode}
%<*texpackage>
%    \end{macrocode}
%
%    \subsection{Preliminaries}
%
%    Catcode defenses and reload protection.
%
%    \begin{macrocode}
\begingroup\catcode61\catcode48\catcode32=10\relax% = and space
  \catcode123 1 % {
  \catcode125 2 % }
  \catcode 35 6 % #
  \toks0\expandafter{\expandafter\endlinechar\the\endlinechar}%
  \edef\x{\endlinechar13}%
  \def\y#1 #2 {%
    \toks0\expandafter{\the\toks0 \catcode#1 \the\catcode#1}%
    \edef\x{\x \catcode#1 #2}}%
  \y  13  5 % carriage return
  \y  61 12 % =
  \y  32 10 % space
  \y 123  1 % {
  \y 125  2 % }
  \y  35  6 % #
  \y  64 11 % @ (letter)
  \y  10 12 % new line ^^J
  \y  33 12 % !
  \y  36  3 % $ $ (in etex.sty)
  \y  39 12 % '
  \y  40 12 % (
  \y  41 12 % )
  \y  42 12 % * (in etex.sty)
  \y  43 12 % + (in etex.sty)
  \y  44 12 % , (in etex.sty)
  \y  45 12 % -
  \y  46 12 % .
  \y  47 12 % /
  \y  58 12 % :
  \y  60 12 % < (in etex.sty)
  \y  62 12 % > (in etex.sty)
  \y  91 12 % [
  \y  93 12 % ]
  \y  94  7 % ^
  \y  96 12 % `
  \toks0\expandafter{\the\toks0 \relax\noexpand\endinput}%
  \edef\y#1{\noexpand\expandafter\endgroup%
    \noexpand\ifx#1\relax \edef#1{\the\toks0}\x\relax%
    \noexpand\else \noexpand\expandafter\noexpand\endinput%
    \noexpand\fi}%
\expandafter\y\csname luatexbase@regs@sty@endinput\endcsname%
%    \end{macrocode}
%
%    Package declaration.
%
%    \begin{macrocode}
\begingroup
  \expandafter\ifx\csname ProvidesPackage\endcsname\relax
    \def\x#1[#2]{\immediate\write16{Package: #1 #2}}
  \else
    \let\x\ProvidesPackage
  \fi
\expandafter\endgroup
\x{luatexbase-regs}[2011/05/24 v0.4 Registers allocation for LuaTeX]
%    \end{macrocode}
%
%    Make sure \luatex is used.
%
%    \begin{macrocode}
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname RequirePackage\endcsname\relax
  \input ifluatex.sty
\else
  \RequirePackage{ifluatex}
\fi
\ifluatex\else
  \begingroup
    \expandafter\ifx\csname PackageError\endcsname\relax
      \def\x#1#2#3{\begingroup \newlinechar10
        \errhelp{#3}\errmessage{Package #1 error: #2}\endgroup}
    \else
      \let\x\PackageError
    \fi
  \expandafter\endgroup
  \x{luatexbase-regs}{LuaTeX is required for this package. Aborting.}{%
    This package can only be used with the LuaTeX engine^^J%
    (command `lualatex' or `luatex').^^J%
    Package loading has been stopped to prevent additional errors.}
  \expandafter\luatexbase@regs@sty@endinput%
\fi
%    \end{macrocode}
%
%    \subsection{Ensure etex.sty is loaded}
%
%    If running \latex, load \file{etex.sty}. If not, either
%    \file{etex.src} was loaded at format generation time, or we cannot do
%    anything.
%
%    \begin{macrocode}
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname RequirePackage\endcsname\relax \else
  \RequirePackage{etex}[1998/03/26]
\fi
%    \end{macrocode}
%
%    To the best of my (mpg) knowledge, all Plain-based formats built with
%    \etex-enabled engines in \texlive load \file{etex.src}. However,
%    let's be careful and check that \file{etex.sty} or \file{etex.src} is
%    loaded.
%
%    \begin{macrocode}
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname et@xins\endcsname\relax
  \begingroup
    \expandafter\ifx\csname PackageWarningNoLine\endcsname\relax
      \def\x#1#2{\begingroup\newlinechar10
        \immediate\write16{Package #1 warning: #2}\endgroup}
    \else
      \let\x\PackageWarningNoLine
    \fi
  \expandafter\endgroup
  \x{luatexbase-regs}{etex macros not loaded!^^J%
    Registers allocation scheme will not be extended.}
\else
%    \end{macrocode}
%
%    \subsection{Adapt range}
%
%    First, increase the upper bound for all kinds of registers. Copy code to
%    avoid defining a macro.
%
%    \begin{macrocode}
  \ifnum\count270=32768 \count270=65536 \fi
  \ifnum\count271=32768 \count271=65536 \fi
  \ifnum\count272=32768 \count272=65536 \fi
  \ifnum\count273=32768 \count272=65536 \fi
  \ifnum\count273=32768 \count273=65536 \fi
  \ifnum\count274=32768 \count274=65536 \fi
  \ifnum\count275=32768 \count275=65536 \fi
  \ifnum\count276=32768 \count276=65536 \fi
%    \end{macrocode}
%
%    \subsection{Patch macros that used \cs{mathchardef}}
%
%    |\box| registers and |\mark|s were previously defined
%    using |\mathchardef| since it had the biggest range under \etex
%    (15-bit number).  However, this is not enough for \luatex's extended
%    registers. Fortunately, |\chardef|'s range is extended, and now large
%    enough, so use it everywhere instead of |\mathchardef|. Do this
%    inside a group and use |\toks0| to store the list of actions.
%
%    \begin{macrocode}
  \begingroup \toks0{}
    \def\@namedef #1{\expandafter                  \def\csname#1\endcsname}
    \def\@outerdef#1{\expandafter\outer\expandafter\def\csname#1\endcsname}
%    \end{macrocode}
%
%    Notice that the auxiliary macros will automatically expand to the desired
%    level when necessary, see below.
%
%    First, here are the definitions from \file{etex.src}, in a form adapted
%    to our needs.
%
%    \begin{macrocode}
    \def\def@globbox   #1#2{\@outerdef{#1}{\et@xglob 4 \box    #2}}
    \def\def@locbox    #1#2{\@namedef {#1}{\et@xloc  4 \box    #2}}
    \def\def@globmarks #1#2{\@outerdef{#1}{\et@xglob 6 \marks  #2}}
    \def\def@locmarks  #1#2{\@namedef {#1}{\et@xloc  6 \marks  #2}}
    \def\def@et@xgblk#1#2{\@namedef{#1}##1##2##3##4%
      {\et@xchkblk ##1##2{##4}%
        {\allocationnumber=\count 26##1
          \global \advance \count 26##1 by ##4%
          \global #2##3=\allocationnumber
          \wlog {\string ##3=\string ##2blk{\number ##4}
            at \the \allocationnumber}%
          }%
        }}
    \def\def@et@xlblk#1#2{\@namedef{#1}##1##2##3##4%
      {\et@xchkblk ##1##2{##4}%
        {\advance \count 27##1 by -##4%
          \allocationnumber=\count 27##1
          #2##3=\allocationnumber
          \wlog {\string ##3=\string ##2blk{\number ##4}
            at \the \allocationnumber \space (local)%
            }%
          }%
        }}
%    \end{macrocode}
%
%    Then, the definitions from \file{etex.sty} since they are subtly
%    different (|\outer| status, but also optional spaces or |=|
%    signs).
%
%    \begin{macrocode}
    \def\alt@globbox   #1#2{\@namedef{#1}{\et@xglob 4\box    #2}}
    \def\alt@locbox    #1#2{\@namedef{#1}{\et@xloc  4\box    #2}}
    \def\alt@globmarks #1#2{\@namedef{#1}{\et@xglob 6\marks  #2}}
    \def\alt@locmarks  #1#2{\@namedef{#1}{\et@xloc  6\marks  #2}}
    \def\alt@et@xgblk#1#2{\@namedef{#1}##1##2##3##4%
      {\et@xchkblk##1##2{##4}%
        {\allocationnumber\count26##1%
          \global\advance\count26##1by##4%
          \global#2##3\allocationnumber
          \wlog{\string##3=\string##2blk{\number##4} at
            \the\allocationnumber}%
          }%
        }}
    \def\alt@et@xlblk#1#2{\@namedef{#1}##1##2##3##4%
      {\et@xchkblk##1##2{##4}%
        {\advance\count27##1-##4%
          \allocationnumber\count27##1%
          #2##3\allocationnumber
          \et@xwlog{\string##3=\string##2blk{\number##4} at
            \the\allocationnumber\space(local)}%
          }%
        }}
%    \end{macrocode}
%
%    Now, a macro checking the definitions, and making the appropriate
%    re-definition.
%
%    \begin{macrocode}
    \def\check@def#1{%
      \csname def@#1\endcsname{test@#1}\mathchardef
      \expandafter\ifx\csname test@#1\expandafter\endcsname
                      \csname #1\endcsname
        \expandafter\let\csname #1\endcsname\relax
        \toks0\expandafter{\the\toks0\csname def@#1\endcsname{#1}\chardef}
      \else
        \csname alt@#1\endcsname{test@#1}\mathchardef
        \expandafter\ifx\csname test@#1\expandafter\endcsname
                        \csname #1\endcsname
          \toks0\expandafter{\the\toks0\csname alt@#1\endcsname{#1}\chardef}
        \else
          \expandafter\show\csname BAD#1\endcsname
        \fi
      \fi}
%    \end{macrocode}
%
%    Now, actually do it.
%
%    \begin{macrocode}
    \check@def{globbox}
    \check@def{locbox}
    \check@def{globmarks}
    \check@def{locmarks}
    \check@def{et@xgblk}
    \check@def{et@xlblk}
  \expandafter \endgroup
  \the\toks0
%    \end{macrocode}
%
%    \subsection{Make room for inserts}
%
%    Finally, make allocation of |\count|, |\dimen|, |skip| and
%    |\box| start with numbers $>255$, in order to free the lower numbers
%    for insertions. Be careful with |\new...| macros which are
%    |\outer| in Plain, since we're in the middle of an |\if| test.
%
%    \begin{macrocode}
  \expandafter\let\csname newcount\endcsname\globcount
  \expandafter\let\csname newdimen\endcsname\globdimen
  \expandafter\let\csname newskip\endcsname\globskip
  \expandafter\let\csname newbox\endcsname\globbox
\fi
%    \end{macrocode}
%
%    That's all folks!
%
%    \begin{macrocode}
\luatexbase@regs@sty@endinput%
%</texpackage>
%    \end{macrocode}
%
%    \section{Test files}
%
%    Here we test only the two main formats: \plaintex (with \file{etex.src}
%    loaded) and \latex, both with the \luatex engine. Those correspond to
%    the \cmdname{luatex} and \cmdname{lualatex} commands in \texlive.
%
%    We want to make sure we can globally and locally allocate $30000$
%    registers of each kind, and still globally allocate $100$ |\insert|s.
%    Next we globally allocate a bloc of $3000$ registers of each kind, and
%    locally a block of $1000$. (Those numbers are not optimal, but they
%    should be enough for testing purposes.)
%
%    \begin{macrocode}
%<testplain>\input luatexbase-regs.sty
%<testlatex>\RequirePackage{luatexbase-regs}
%<*testplain,testlatex>
\def\checkregister#1{%
  \edef\newregister{\expandafter\noexpand\csname new#1\endcsname}%
  \edef\locregister{\expandafter\noexpand\csname loc#1\endcsname}%
  \count0 1
  \loop
    \newregister\dummy
    \locregister\dummy
  \ifnum\count0<30000
    \advance\count0 1
  \repeat}
\checkregister{count}
\checkregister{dimen}
\checkregister{skip}
\checkregister{muskip}
\checkregister{box}
\checkregister{toks}
\checkregister{marks}

\count0 1
\loop \ifnum\count0<100
  \csname newinsert\endcsname\dummy
  \advance\count0 1
\repeat

\globcountblk \dummy{3000}
\globdimenblk \dummy{3000}
\globskipblk  \dummy{3000}
\globmuskipblk\dummy{3000}
\globboxblk   \dummy{3000}
\globtoksblk  \dummy{3000}
\globmarksblk \dummy{3000}

\loccountblk  \dummy{1000}
\locdimenblk  \dummy{1000}
\locskipblk   \dummy{1000}
\locmuskipblk \dummy{1000}
\locboxblk    \dummy{1000}
\loctoksblk   \dummy{1000}
\locmarksblk  \dummy{1000}
%</testplain,testlatex>
%<testplain>\bye
%<testlatex>\stop
%    \end{macrocode}
%
%
% \Finale
\endinput