texlive[42506] Build/source/texk/web2c: Add new primitives

commits+kakuto at tug.org commits+kakuto at tug.org
Mon Nov 14 08:21:02 CET 2016


Revision: 42506
          http://tug.org/svn/texlive?view=revision&revision=42506
Author:   kakuto
Date:     2016-11-14 08:21:02 +0100 (Mon, 14 Nov 2016)
Log Message:
-----------
Add new primitives \pdfuniformdeviate etc. in eptex and euptex (from H. Kitagawa)

Modified Paths:
--------------
    trunk/Build/source/texk/web2c/ChangeLog
    trunk/Build/source/texk/web2c/eptexdir/ChangeLog
    trunk/Build/source/texk/web2c/eptexdir/eptex.ech
    trunk/Build/source/texk/web2c/eptexdir/eptex_version.h
    trunk/Build/source/texk/web2c/eptexdir/pdfutils.ch
    trunk/Build/source/texk/web2c/euptexdir/ChangeLog
    trunk/Build/source/texk/web2c/euptexdir/euptrip/texmf.cnf
    trunk/Build/source/texk/web2c/lib/ChangeLog
    trunk/Build/source/texk/web2c/lib/texmfmp.c
    trunk/Build/source/texk/web2c/texmfmp.h

Modified: trunk/Build/source/texk/web2c/ChangeLog
===================================================================
--- trunk/Build/source/texk/web2c/ChangeLog	2016-11-14 02:19:02 UTC (rev 42505)
+++ trunk/Build/source/texk/web2c/ChangeLog	2016-11-14 07:21:02 UTC (rev 42506)
@@ -1,3 +1,8 @@
+2016-11-14  Hironori Kitagawa  <h_kitagawa2001 at yahoo.co.jp>
+
+	* texmfmp.h : Change a condition to support new primitives in
+	eptex and euptex.
+
 2016-11-05  Karl Berry  <karl at tug.org>
 
 	* help.h (CWEAVEHELP) <-x>: mention section names,

Modified: trunk/Build/source/texk/web2c/eptexdir/ChangeLog
===================================================================
--- trunk/Build/source/texk/web2c/eptexdir/ChangeLog	2016-11-14 02:19:02 UTC (rev 42505)
+++ trunk/Build/source/texk/web2c/eptexdir/ChangeLog	2016-11-14 07:21:02 UTC (rev 42506)
@@ -1,3 +1,9 @@
+2016-11-14  Hironori Kitagawa  <h_kitagawa2001 at yahoo.co.jp>
+
+	* eptex.ech, eptex_version.h, pdfutils.ch: Add new primitives
+	\pdfuniformdeviate, \pdfnormaldeviate, \pdfrandomseed, \pdfsetrandomseed,
+	\pdfelapsedtime, \pdfresettimer.
+
 2016-10-31  Akira Kakuto  <kakuto at fuk.kindai.ac.jp>
 
 	* pdfutils.ch: Remove an unused variable to avoid a compiler warning.

Modified: trunk/Build/source/texk/web2c/eptexdir/eptex.ech
===================================================================
--- trunk/Build/source/texk/web2c/eptexdir/eptex.ech	2016-11-14 02:19:02 UTC (rev 42505)
+++ trunk/Build/source/texk/web2c/eptexdir/eptex.ech	2016-11-14 07:21:02 UTC (rev 42506)
@@ -19,7 +19,7 @@
 @y
 @d eTeX_version_string=='-2.6' {current \eTeX\ version}
 @#
- at d epTeX_version_string=='-161030'
+ at d epTeX_version_string=='-161114'
 @z
 
 @x e-pTeX: banner
@@ -309,7 +309,7 @@
 @d set_language_code=5 {command modifier for \.{\\setlanguage}}
 @y
 @d set_language_code=5 {command modifier for \.{\\setlanguage}}
- at d epTeX_input_encoding_code=7 {command modifier for \.{\\epTeXinputencoding}}
+ at d epTeX_input_encoding_code=6 {command modifier for \.{\\epTeXinputencoding}}
 @z
 
 @x

Modified: trunk/Build/source/texk/web2c/eptexdir/eptex_version.h
===================================================================
--- trunk/Build/source/texk/web2c/eptexdir/eptex_version.h	2016-11-14 02:19:02 UTC (rev 42505)
+++ trunk/Build/source/texk/web2c/eptexdir/eptex_version.h	2016-11-14 07:21:02 UTC (rev 42506)
@@ -1 +1 @@
-#define EPTEX_VERSION "161030"
+#define EPTEX_VERSION "161114"

Modified: trunk/Build/source/texk/web2c/eptexdir/pdfutils.ch
===================================================================
--- trunk/Build/source/texk/web2c/eptexdir/pdfutils.ch	2016-11-14 02:19:02 UTC (rev 42505)
+++ trunk/Build/source/texk/web2c/eptexdir/pdfutils.ch	2016-11-14 07:21:02 UTC (rev 42506)
@@ -19,8 +19,379 @@
 %%   \pdfmdfivesum {...}. (no conversion for \pdfmdfivesum file <filename>)
 %%
 %% \pdfprimitive and \ifpdfprimitive: for LaTeX3 (2015/07/15)
+%%
+%% \pdfuniformdeviate and co.: 
+%%  (\pdfnormaldeviate, \pdfrandomseed, \pdfsetrandomseed)
+%% 
+%% \pdfelapsedtime and \pdfresettimer
+%%
 
 @x
+@* \[8] Packed data.
+ at y
+@* \[7b] Random numbers.
+
+\font\tenlogo=logo10 % font used for the METAFONT logo
+\def\MP{{\tenlogo META}\-{\tenlogo POST}}
+
+This section is (almost) straight from MetaPost. I had to change
+the types (use |integer| instead of |fraction|), but that should
+not have any influence on the actual calculations (the original
+comments refer to quantities like |fraction_four| ($2^{30}$), and
+that is the same as the numeric representation of |maxdimen|).
+
+I've copied the low-level variables and routines that are needed, but
+only those (e.g. |m_log|), not the accompanying ones like |m_exp|. Most
+of the following low-level numeric routines are only needed within the
+calculation of |norm_rand|. I've been forced to rename |make_fraction|
+to |make_frac| because TeX already has a routine by that name with
+a wholly different function (it creates a |fraction_noad| for math
+typesetting) -- Taco
+
+And now let's complete our collection of numeric utility routines
+by considering random number generation.
+\MP\ generates pseudo-random numbers with the additive scheme recommended
+in Section 3.6 of {\sl The Art of Computer Programming}; however, the
+results are random fractions between 0 and |fraction_one-1|, inclusive.
+
+There's an auxiliary array |randoms| that contains 55 pseudo-random
+fractions. Using the recurrence $x_n=(x_{n-55}-x_{n-31})\bmod 2^{28}$,
+we generate batches of 55 new $x_n$'s at a time by calling |new_randoms|.
+The global variable |j_random| tells which element has most recently
+been consumed.
+
+@<Glob...@>=
+@!randoms:array[0..54] of integer; {the last 55 random values generated}
+@!j_random:0..54; {the number of unused |randoms|}
+@!random_seed:scaled; {the default random seed}
+
+@ A small bit of metafont is needed.
+
+ at d fraction_half==@'1000000000 {$2^{27}$, represents 0.50000000}
+ at d fraction_one==@'2000000000 {$2^{28}$, represents 1.00000000}
+ at d fraction_four==@'10000000000 {$2^{30}$, represents 4.00000000}
+ at d el_gordo == @'17777777777 {$2^{31}-1$, the largest value that \MP\ likes}
+ at d halfp(#)==(#) div 2
+ at d double(#) == #:=#+# {multiply a variable by two}
+
+@ The |make_frac| routine produces the |fraction| equivalent of
+|p/q|, given integers |p| and~|q|; it computes the integer
+$f=\lfloor2^{28}p/q+{1\over2}\rfloor$, when $p$ and $q$ are
+positive. If |p| and |q| are both of the same scaled type |t|,
+the ``type relation'' |make_frac(t,t)=fraction| is valid;
+and it's also possible to use the subroutine ``backwards,'' using
+the relation |make_frac(t,fraction)=t| between scaled types.
+
+If the result would have magnitude $2^{31}$ or more, |make_frac|
+sets |arith_error:=true|. Most of \MP's internal computations have
+been designed to avoid this sort of error.
+
+If this subroutine were programmed in assembly language on a typical
+machine, we could simply compute |(@t$2^{28}$@>*p)div q|, since a
+double-precision product can often be input to a fixed-point division
+instruction. But when we are restricted to \PASCAL\ arithmetic it
+is necessary either to resort to multiple-precision maneuvering
+or to use a simple but slow iteration. The multiple-precision technique
+would be about three times faster than the code adopted here, but it
+would be comparatively long and tricky, involving about sixteen
+additional multiplications and divisions.
+
+This operation is part of \MP's ``inner loop''; indeed, it will
+consume nearly 10\pct! of the running time (exclusive of input and output)
+if the code below is left unchanged. A machine-dependent recoding
+will therefore make \MP\ run faster. The present implementation
+is highly portable, but slow; it avoids multiplication and division
+except in the initial stage. System wizards should be careful to
+replace it with a routine that is guaranteed to produce identical
+results in all cases.
+@^system dependencies@>
+
+As noted below, a few more routines should also be replaced by machine-dependent
+code, for efficiency. But when a procedure is not part of the ``inner loop,''
+such changes aren't advisable; simplicity and robustness are
+preferable to trickery, unless the cost is too high.
+@^inner loop@>
+
+ at p function make_frac(@!p,@!q:integer):integer;
+var @!f:integer; {the fraction bits, with a leading 1 bit}
+@!n:integer; {the integer part of $\vert p/q\vert$}
+@!negative:boolean; {should the result be negated?}
+@!be_careful:integer; {disables certain compiler optimizations}
+begin if p>=0 then negative:=false
+else  begin negate(p); negative:=true;
+  end;
+if q<=0 then
+  begin debug if q=0 then confusion("/");@;@+gubed@;@/
+@:this can't happen /}{\quad \./@>
+  negate(q); negative:=not negative;
+  end;
+n:=p div q; p:=p mod q;
+if n>=8 then
+  begin arith_error:=true;
+  if negative then make_frac:=-el_gordo at +else make_frac:=el_gordo;
+  end
+else  begin n:=(n-1)*fraction_one;
+  @<Compute $f=\lfloor 2^{28}(1+p/q)+{1\over2}\rfloor$@>;
+  if negative then make_frac:=-(f+n)@+else make_frac:=f+n;
+  end;
+end;
+
+@ The |repeat| loop here preserves the following invariant relations
+between |f|, |p|, and~|q|:
+(i)~|0<=p<q|; (ii)~$fq+p=2^k(q+p_0)$, where $k$ is an integer and
+$p_0$ is the original value of~$p$.
+
+Notice that the computation specifies
+|(p-q)+p| instead of |(p+p)-q|, because the latter could overflow.
+Let us hope that optimizing compilers do not miss this point; a
+special variable |be_careful| is used to emphasize the necessary
+order of computation. Optimizing compilers should keep |be_careful|
+in a register, not store it in memory.
+@^inner loop@>
+
+@<Compute $f=\lfloor 2^{28}(1+p/q)+{1\over2}\rfloor$@>=
+f:=1;
+repeat be_careful:=p-q; p:=be_careful+p;
+if p>=0 then f:=f+f+1
+else  begin double(f); p:=p+q;
+  end;
+until f>=fraction_one;
+be_careful:=p-q;
+if be_careful+p>=0 then incr(f)
+
+@
+
+ at p function take_frac(@!q:integer;@!f:integer):integer;
+var @!p:integer; {the fraction so far}
+@!negative:boolean; {should the result be negated?}
+@!n:integer; {additional multiple of $q$}
+@!be_careful:integer; {disables certain compiler optimizations}
+begin @<Reduce to the case that |f>=0| and |q>0|@>;
+if f<fraction_one then n:=0
+else  begin n:=f div fraction_one; f:=f mod fraction_one;
+  if q<=el_gordo div n then n:=n*q
+  else  begin arith_error:=true; n:=el_gordo;
+    end;
+  end;
+f:=f+fraction_one;
+@<Compute $p=\lfloor qf/2^{28}+{1\over2}\rfloor-q$@>;
+be_careful:=n-el_gordo;
+if be_careful+p>0 then
+  begin arith_error:=true; n:=el_gordo-p;
+  end;
+if negative then take_frac:=-(n+p)
+else take_frac:=n+p;
+end;
+
+@ @<Reduce to the case that |f>=0| and |q>0|@>=
+if f>=0 then negative:=false
+else  begin negate(f); negative:=true;
+  end;
+if q<0 then
+  begin negate(q); negative:=not negative;
+  end;
+
+@ The invariant relations in this case are (i)~$\lfloor(qf+p)/2^k\rfloor
+=\lfloor qf_0/2^{28}+{1\over2}\rfloor$, where $k$ is an integer and
+$f_0$ is the original value of~$f$; (ii)~$2^k\L f<2^{k+1}$.
+@^inner loop@>
+
+@<Compute $p=\lfloor qf/2^{28}+{1\over2}\rfloor-q$@>=
+p:=fraction_half; {that's $2^{27}$; the invariants hold now with $k=28$}
+if q<fraction_four then
+  repeat if odd(f) then p:=halfp(p+q)@+else p:=halfp(p);
+  f:=halfp(f);
+  until f=1
+else  repeat if odd(f) then p:=p+halfp(q-p)@+else p:=halfp(p);
+  f:=halfp(f);
+  until f=1
+
+@ The subroutines for logarithm and exponential involve two tables.
+The first is simple: |two_to_the[k]| equals $2^k$. The second involves
+a bit more calculation, which the author claims to have done correctly:
+|spec_log[k]| is $2^{27}$ times $\ln\bigl(1/(1-2^{-k})\bigr)=
+2^{-k}+{1\over2}2^{-2k}+{1\over3}2^{-3k}+\cdots\,$, rounded to the
+nearest integer.
+
+@<Glob...@>=
+@!two_to_the:array[0..30] of integer; {powers of two}
+@!spec_log:array[1..28] of integer; {special logarithms}
+
+
+@ @<Set init...@>=
+two_to_the[0]:=1;
+for k:=1 to 30 do two_to_the[k]:=2*two_to_the[k-1];
+spec_log[1]:=93032640;
+spec_log[2]:=38612034;
+spec_log[3]:=17922280;
+spec_log[4]:=8662214;
+spec_log[5]:=4261238;
+spec_log[6]:=2113709;
+spec_log[7]:=1052693;
+spec_log[8]:=525315;
+spec_log[9]:=262400;
+spec_log[10]:=131136;
+spec_log[11]:=65552;
+spec_log[12]:=32772;
+spec_log[13]:=16385;
+for k:=14 to 27 do spec_log[k]:=two_to_the[27-k];
+spec_log[28]:=1;
+
+@
+
+ at p function m_log(@!x:integer):integer;
+var @!y,@!z:integer; {auxiliary registers}
+@!k:integer; {iteration counter}
+begin if x<=0 then @<Handle non-positive logarithm@>
+else  begin y:=1302456956+4-100; {$14\times2^{27}\ln2\approx1302456956.421063$}
+  z:=27595+6553600; {and $2^{16}\times .421063\approx 27595$}
+  while x<fraction_four do
+    begin double(x); y:=y-93032639; z:=z-48782;
+    end; {$2^{27}\ln2\approx 93032639.74436163$
+      and $2^{16}\times.74436163\approx 48782$}
+  y:=y+(z div unity); k:=2;
+  while x>fraction_four+4 do
+    @<Increase |k| until |x| can be multiplied by a
+      factor of $2^{-k}$, and adjust $y$ accordingly@>;
+  m_log:=y div 8;
+  end;
+end;
+
+@ @<Increase |k| until |x| can...@>=
+begin z:=((x-1) div two_to_the[k])+1; {$z=\lceil x/2^k\rceil$}
+while x<fraction_four+z do
+  begin z:=halfp(z+1); k:=k+1;
+  end;
+y:=y+spec_log[k]; x:=x-z;
+end
+
+@ @<Handle non-positive logarithm@>=
+begin print_err("Logarithm of ");
+ at .Logarithm...replaced by 0@>
+print_scaled(x); print(" has been replaced by 0");
+help2("Since I don't take logs of non-positive numbers,")@/
+  ("I'm zeroing this one. Proceed, with fingers crossed.");
+error; m_log:=0;
+end
+
+@ The following somewhat different subroutine tests rigorously if $ab$ is
+greater than, equal to, or less than~$cd$,
+given integers $(a,b,c,d)$. In most cases a quick decision is reached.
+The result is $+1$, 0, or~$-1$ in the three respective cases.
+
+ at d return_sign(#)==begin ab_vs_cd:=#; return;
+  end
+
+ at p function ab_vs_cd(@!a,b,c,d:integer):integer;
+label exit;
+var @!q,@!r:integer; {temporary registers}
+begin @<Reduce to the case that |a,c>=0|, |b,d>0|@>;
+loop at +  begin q := a div d; r := c div b;
+  if q<>r then
+    if q>r then return_sign(1)@+else return_sign(-1);
+  q := a mod d; r := c mod b;
+  if r=0 then
+    if q=0 then return_sign(0)@+else return_sign(1);
+  if q=0 then return_sign(-1);
+  a:=b; b:=q; c:=d; d:=r;
+  end; {now |a>d>0| and |c>b>0|}
+exit:end;
+
+@ @<Reduce to the case that |a...@>=
+if a<0 then
+  begin negate(a); negate(b);
+  end;
+if c<0 then
+  begin negate(c); negate(d);
+  end;
+if d<=0 then
+  begin if b>=0 then
+    if ((a=0)or(b=0))and((c=0)or(d=0)) then return_sign(0)
+    else return_sign(1);
+  if d=0 then
+    if a=0 then return_sign(0)@+else return_sign(-1);
+  q:=a; a:=c; c:=q; q:=-b; b:=-d; d:=q;
+  end
+else if b<=0 then
+  begin if b<0 then if a>0 then return_sign(-1);
+  if c=0 then return_sign(0) else return_sign(-1);
+  end
+
+@ To consume a random integer, the program below will say `|next_random|'
+and then it will fetch |randoms[j_random]|.
+
+ at d next_random==if j_random=0 then new_randoms
+  else decr(j_random)
+
+ at p procedure new_randoms;
+var @!k:0..54; {index into |randoms|}
+@!x:integer; {accumulator}
+begin for k:=0 to 23 do
+  begin x:=randoms[k]-randoms[k+31];
+  if x<0 then x:=x+fraction_one;
+  randoms[k]:=x;
+  end;
+for k:=24 to 54 do
+  begin x:=randoms[k]-randoms[k-24];
+  if x<0 then x:=x+fraction_one;
+  randoms[k]:=x;
+  end;
+j_random:=54;
+end;
+
+@ To initialize the |randoms| table, we call the following routine.
+
+ at p procedure init_randoms(@!seed:integer);
+var @!j,@!jj,@!k:integer; {more or less random integers}
+@!i:0..54; {index into |randoms|}
+begin j:=abs(seed);
+while j>=fraction_one do j:=halfp(j);
+k:=1;
+for i:=0 to 54 do
+  begin jj:=k; k:=j-k; j:=jj;
+  if k<0 then k:=k+fraction_one;
+  randoms[(i*21)mod 55]:=j;
+  end;
+new_randoms; new_randoms; new_randoms; {``warm up'' the array}
+end;
+
+@ To produce a uniform random number in the range |0<=u<x| or |0>=u>x|
+or |0=u=x|, given a |scaled| value~|x|, we proceed as shown here.
+
+Note that the call of |take_frac| will produce the values 0 and~|x|
+with about half the probability that it will produce any other particular
+values between 0 and~|x|, because it rounds its answers.
+
+ at p function unif_rand(@!x:integer):integer;
+var @!y:integer; {trial value}
+begin next_random; y:=take_frac(abs(x),randoms[j_random]);
+if y=abs(x) then unif_rand:=0
+else if x>0 then unif_rand:=y
+else unif_rand:=-y;
+end;
+
+@ Finally, a normal deviate with mean zero and unit standard deviation
+can readily be obtained with the ratio method (Algorithm 3.4.1R in
+{\sl The Art of Computer Programming\/}).
+
+ at p function norm_rand:integer;
+var @!x,@!u,@!l:integer; {what the book would call $2^{16}X$, $2^{28}U$,
+  and $-2^{24}\ln U$}
+begin repeat
+  repeat next_random;
+  x:=take_frac(112429,randoms[j_random]-fraction_half);
+    {$2^{16}\sqrt{8/e}\approx 112428.82793$}
+  next_random; u:=randoms[j_random];
+  until abs(x)<u;
+x:=make_frac(x,u);
+l:=139548960-m_log(u); {$2^{24}\cdot12\ln2\approx139548959.6165$}
+until ab_vs_cd(1024,l,x,x)>=0;
+norm_rand:=x;
+end;
+@* \[8] Packed data.
+ at z
+
+ at x
 @* \[12] Displaying boxes.
 @y
 @<Declare procedures that need to be declared forward for \pdfTeX@>@;
@@ -360,12 +731,14 @@
 @d pdf_last_x_pos_code=badness_code+1 {code for \.{\\pdflastxpos}}
 @d pdf_last_y_pos_code=pdf_last_x_pos_code+1 {code for \.{\\pdflastypos}}
 @d pdf_shell_escape_code=pdf_last_y_pos_code+1 {code for \.{\\pdflastypos}}
+ at d elapsed_time_code =pdf_shell_escape_code+1 {code for \.{\\pdfelapsedtime}}
+ at d random_seed_code=elapsed_time_code+1 {code for \.{\\pdfrandomseed}}
 @z
 
 @x
 @d eTeX_int=badness_code+1 {first of \eTeX\ codes for integers}
 @y
- at d eTeX_int=pdf_shell_escape_code+1 {first of \eTeX\ codes for integers}
+ at d eTeX_int=random_seed_code+1 {first of \eTeX\ codes for integers}
 @z
 
 @x \[if]pdfprimitive: scan_int
@@ -394,7 +767,9 @@
 @d pdf_file_size_code       = etex_convert_base+4 {command code for \.{\\pdffilesize}}
 @d pdf_mdfive_sum_code      = etex_convert_base+5 {command code for \.{\\pdfmdfivesum}}
 @d pdf_file_dump_code       = etex_convert_base+6 {command code for \.{\\pdffiledump}}
- at d etex_convert_codes=etex_convert_base+7 {end of \eTeX's command codes}
+ at d uniform_deviate_code     = etex_convert_base+7 {command code for \.{\\pdfuniformdeviate}}
+ at d normal_deviate_code      = etex_convert_base+8 {command code for \.{\\pdfnormaldeviate}}
+ at d etex_convert_codes=etex_convert_base+9 {end of \eTeX's command codes}
 @z
 
 @x
@@ -407,6 +782,8 @@
   pdf_file_size_code:     print_esc("pdffilesize");
   pdf_mdfive_sum_code:    print_esc("pdfmdfivesum");
   pdf_file_dump_code:     print_esc("pdffiledump");
+  uniform_deviate_code:   print_esc("pdfuniformdeviate");
+  normal_deviate_code:    print_esc("pdfnormaldeviate");
 @z
 
 @x
@@ -578,6 +955,8 @@
     restore_cur_string;
     return;
   end;
+uniform_deviate_code:     scan_int;
+normal_deviate_code:      do_nothing;
 @z
 
 @x
@@ -585,6 +964,8 @@
 @y
 eTeX_revision_code: print(eTeX_revision);
 pdf_strcmp_code: print_int(cur_val);
+uniform_deviate_code:     print_int(unif_rand(cur_val));
+normal_deviate_code:      print_int(norm_rand);
 @z
 
 @x \[if]pdfprimitive
@@ -680,14 +1061,17 @@
 @y
 fix_date_and_time;@/
 isprint_utf8:=false;
+random_seed:=(microseconds*1000)+(epochseconds mod 1000000);@/
+init_randoms(random_seed);@/
 @z
 
 @x
- at d set_language_code=5 {command modifier for \.{\\setlanguage}}
+ at d epTeX_input_encoding_code=6 {command modifier for \.{\\epTeXinputencoding}}
 @y
- at d set_language_code=5 {command modifier for \.{\\setlanguage}}
- at d TeX_extension_end=5
- at d pdf_save_pos_node=TeX_extension_end+1
+ at d epTeX_input_encoding_code=6 {command modifier for \.{\\epTeXinputencoding}}
+ at d pdf_save_pos_node=epTeX_input_encoding_code+1
+ at d set_random_seed_code=pdf_save_pos_node+1
+ at d reset_timer_code=set_random_seed_code+1
 @z
 
 @x
@@ -695,6 +1079,8 @@
 @y
   set_language_code:print_esc("setlanguage");
   pdf_save_pos_node: print_esc("pdfsavepos");
+  set_random_seed_code: print_esc("pdfsetrandomseed");
+  reset_timer_code: print_esc("pdfresettimer");
 @z
 
 @x
@@ -702,6 +1088,8 @@
 @y
 set_language_code:@<Implement \.{\\setlanguage}@>;
 pdf_save_pos_node: @<Implement \.{\\pdfsavepos}@>;
+set_random_seed_code: @<Implement \.{\\pdfsetrandomseed}@>;
+reset_timer_code: @<Implement \.{\\pdfresettimer}@>;
 @z
 
 @x \pdfsavepos
@@ -713,6 +1101,8 @@
   print_int(what_rhm(p)); print_char(")");
   end;
 pdf_save_pos_node: print_esc("pdfsavepos");
+set_random_seed_code: print_esc("pdfsetrandomseed");
+reset_timer_code: print_esc("pdfresettimer");
 @z
 
 @x \pdfsavepos
@@ -797,6 +1187,18 @@
 @!@:pdf_shell_escape_}{\.{\\pdfshellescape} primitive@>
 primitive("ifpdfprimitive",if_test,if_pdfprimitive_code);
 @!@:if_pdfprimitive_}{\.{\\ifpdfprimitive} primitive@>
+primitive("pdfuniformdeviate",convert,uniform_deviate_code);@/
+@!@:uniform_deviate_}{\.{\\pdfuniformdeviate} primitive@>
+primitive("pdfnormaldeviate",convert,normal_deviate_code);@/
+@!@:normal_deviate_}{\.{\\pdfnormaldeviate} primitive@>
+primitive("pdfrandomseed",last_item,random_seed_code);
+@!@:random_seed_}{\.{\\pdfrandomseed} primitive@>
+primitive("pdfsetrandomseed",extension,set_random_seed_code);@/
+@!@:set_random_seed_code}{\.{\\pdfsetrandomseed} primitive@>
+primitive("pdfelapsedtime",last_item,elapsed_time_code);
+@!@:elapsed_time_}{\.{\\pdfelapsedtime} primitive@>
+primitive("pdfresettimer",extension,reset_timer_code);@/
+@!@:reset_timer_}{\.{\\pdfresettimer} primitive@>
 @z
 
 @x
@@ -805,7 +1207,9 @@
 eTeX_version_code: print_esc("eTeXversion");
 pdf_last_x_pos_code:  print_esc("pdflastxpos");
 pdf_last_y_pos_code:  print_esc("pdflastypos");
+elapsed_time_code: print_esc("pdfelapsedtime");
 pdf_shell_escape_code: print_esc("pdfshellescape");
+random_seed_code:     print_esc("pdfrandomseed");
 @z
 
 @x
@@ -822,6 +1226,8 @@
   end
   else cur_val := 0;
   end;
+elapsed_time_code: cur_val := get_microinterval;
+random_seed_code:  cur_val := random_seed;
 @z
 
 @x
@@ -859,8 +1265,13 @@
 
 @<Glob...@>=
 @!isprint_utf8: boolean;
+@!epochseconds: integer;
+@!microseconds: integer;
 
-@ @<Declare procedures that need to be declared forward for \pdfTeX@>=
+@
+ at d max_integer == @"7FFFFFFF {$2^{31}-1$}
+
+@<Declare procedures that need to be declared forward for \pdfTeX@>=
 procedure pdf_error(t, p: str_number);
 begin
     normalize_selector;
@@ -874,6 +1285,18 @@
     succumb;
 end;
 
+function get_microinterval:integer;
+var s,@!m:integer; {seconds and microseconds}
+begin
+   seconds_and_micros(s,m);
+   if (s-epochseconds)>32767 then
+     get_microinterval := max_integer
+   else if (microseconds>m)  then
+     get_microinterval := ((s-1-epochseconds)*65536)+ (((m+1000000-microseconds)/100)*65536)/10000
+   else
+     get_microinterval := ((s-epochseconds)*65536)  + (((m-microseconds)/100)*65536)/10000;
+end;
+
 @ @<Declare procedures needed in |do_ext...@>=
 
 procedure compare_strings; {to implement \.{\\pdfstrcmp}}
@@ -1055,7 +1478,23 @@
 end;
 
 @ @<Set initial values of key variables@>=
+  seconds_and_micros(epochseconds,microseconds);
   init_start_time;
 
+@ Negative random seed values are silently converted to positive ones
+
+@<Implement \.{\\pdfsetrandomseed}@>=
+begin
+  scan_int;
+  if cur_val<0 then negate(cur_val);
+  random_seed := cur_val;
+  init_randoms(random_seed);
+end
+
+@ @<Implement \.{\\pdfresettimer}@>=
+begin
+  seconds_and_micros(epochseconds,microseconds);
+end
+
 @* \[54] System-dependent changes.
 @z

Modified: trunk/Build/source/texk/web2c/euptexdir/ChangeLog
===================================================================
--- trunk/Build/source/texk/web2c/euptexdir/ChangeLog	2016-11-14 02:19:02 UTC (rev 42505)
+++ trunk/Build/source/texk/web2c/euptexdir/ChangeLog	2016-11-14 07:21:02 UTC (rev 42506)
@@ -1,3 +1,7 @@
+2016-11-14  Hironori Kitagawa  <h_kitagawa2001 at yahoo.co.jp>
+
+	* euptrip/texmf.cnf: Increase pool_size.
+
 2016-10-30  Hironori Kitagawa  <h_kitagawa2001 at yahoo.co.jp>
 
 	* euptex.defines: Use initstarttime() to improve CreationDate.

Modified: trunk/Build/source/texk/web2c/euptexdir/euptrip/texmf.cnf
===================================================================
--- trunk/Build/source/texk/web2c/euptexdir/euptrip/texmf.cnf	2016-11-14 02:19:02 UTC (rev 42505)
+++ trunk/Build/source/texk/web2c/euptexdir/euptrip/texmf.cnf	2016-11-14 07:21:02 UTC (rev 42506)
@@ -10,7 +10,7 @@
 mem_bot          =    1
 main_memory      = 4500
 max_strings     = 3300
-pool_size       = 36000
+pool_size       = 40000
 
 string_vacancies = 8000
 

Modified: trunk/Build/source/texk/web2c/lib/ChangeLog
===================================================================
--- trunk/Build/source/texk/web2c/lib/ChangeLog	2016-11-14 02:19:02 UTC (rev 42505)
+++ trunk/Build/source/texk/web2c/lib/ChangeLog	2016-11-14 07:21:02 UTC (rev 42506)
@@ -1,3 +1,7 @@
+2016-11-14  Hironori Kitagawa  <h_kitagawa2001 at yahoo.co.jp>
+
+	* texmfmp.c: Change a condition to support new primitives in e(u)ptex.
+
 2016-06-12  Karl Berry  <karl at freefriends.org>
 
 	* texmfmp.c (get_date_and_time):

Modified: trunk/Build/source/texk/web2c/lib/texmfmp.c
===================================================================
--- trunk/Build/source/texk/web2c/lib/texmfmp.c	2016-11-14 02:19:02 UTC (rev 42505)
+++ trunk/Build/source/texk/web2c/lib/texmfmp.c	2016-11-14 07:21:02 UTC (rev 42506)
@@ -2305,7 +2305,7 @@
   }
 }
 

-#if defined(pdfTeX)
+#if defined(pdfTeX) || defined(epTeX) || defined(eupTeX)
 /*
  Getting a high resolution time.
  */

Modified: trunk/Build/source/texk/web2c/texmfmp.h
===================================================================
--- trunk/Build/source/texk/web2c/texmfmp.h	2016-11-14 02:19:02 UTC (rev 42505)
+++ trunk/Build/source/texk/web2c/texmfmp.h	2016-11-14 07:21:02 UTC (rev 42506)
@@ -220,7 +220,7 @@
 #define	dateandtime(i,j,k,l) get_date_and_time (&(i), &(j), &(k), &(l))
 extern void get_date_and_time (integer *, integer *, integer *, integer *);
 
-#if defined(pdfTeX)
+#if defined(pdfTeX) || defined(epTeX) || defined(eupTeX)
 /* Get high-res time info. */
 #define secondsandmicros(i,j) get_seconds_and_micros (&(i), &(j))
 extern void get_seconds_and_micros (integer *, integer *);



More information about the tex-live-commits mailing list