summaryrefslogtreecommitdiff
path: root/Build
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2016-11-14 07:21:02 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2016-11-14 07:21:02 +0000
commit96679398651343a7668086d8a4bab8b66986be81 (patch)
tree23005f8876edee88f5fe0139903a2c03f5de3723 /Build
parente1ec4d21fd2fee5faf425a0b5804c35dd9c8e1b9 (diff)
Add new primitives \pdfuniformdeviate etc. in eptex and euptex (from H. Kitagawa)
git-svn-id: svn://tug.org/texlive/trunk@42506 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build')
-rw-r--r--Build/source/texk/web2c/ChangeLog5
-rw-r--r--Build/source/texk/web2c/eptexdir/ChangeLog6
-rw-r--r--Build/source/texk/web2c/eptexdir/eptex.ech4
-rw-r--r--Build/source/texk/web2c/eptexdir/eptex_version.h2
-rw-r--r--Build/source/texk/web2c/eptexdir/pdfutils.ch453
-rw-r--r--Build/source/texk/web2c/euptexdir/ChangeLog4
-rw-r--r--Build/source/texk/web2c/euptexdir/euptrip/texmf.cnf2
-rw-r--r--Build/source/texk/web2c/lib/ChangeLog4
-rw-r--r--Build/source/texk/web2c/lib/texmfmp.c2
-rw-r--r--Build/source/texk/web2c/texmfmp.h2
10 files changed, 471 insertions, 13 deletions
diff --git a/Build/source/texk/web2c/ChangeLog b/Build/source/texk/web2c/ChangeLog
index a860aac0a30..4da1409d324 100644
--- a/Build/source/texk/web2c/ChangeLog
+++ b/Build/source/texk/web2c/ChangeLog
@@ -1,3 +1,8 @@
+2016-11-14 Hironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
+
+ * texmfmp.h : Change a condition to support new primitives in
+ eptex and euptex.
+
2016-11-05 Karl Berry <karl@tug.org>
* help.h (CWEAVEHELP) <-x>: mention section names,
diff --git a/Build/source/texk/web2c/eptexdir/ChangeLog b/Build/source/texk/web2c/eptexdir/ChangeLog
index 880cc4f0ba3..6a3920dc74c 100644
--- a/Build/source/texk/web2c/eptexdir/ChangeLog
+++ b/Build/source/texk/web2c/eptexdir/ChangeLog
@@ -1,3 +1,9 @@
+2016-11-14 Hironori Kitagawa <h_kitagawa2001@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@fuk.kindai.ac.jp>
* pdfutils.ch: Remove an unused variable to avoid a compiler warning.
diff --git a/Build/source/texk/web2c/eptexdir/eptex.ech b/Build/source/texk/web2c/eptexdir/eptex.ech
index d0b64890b40..7d89f031ae0 100644
--- a/Build/source/texk/web2c/eptexdir/eptex.ech
+++ b/Build/source/texk/web2c/eptexdir/eptex.ech
@@ -19,7 +19,7 @@
@y
@d eTeX_version_string=='-2.6' {current \eTeX\ version}
@#
-@d epTeX_version_string=='-161030'
+@d epTeX_version_string=='-161114'
@z
@x e-pTeX: banner
@@ -309,7 +309,7 @@ if fm>0 then {drop \.{\\beginM} \.{\\endM} pair}
@d set_language_code=5 {command modifier for \.{\\setlanguage}}
@y
@d set_language_code=5 {command modifier for \.{\\setlanguage}}
-@d epTeX_input_encoding_code=7 {command modifier for \.{\\epTeXinputencoding}}
+@d epTeX_input_encoding_code=6 {command modifier for \.{\\epTeXinputencoding}}
@z
@x
diff --git a/Build/source/texk/web2c/eptexdir/eptex_version.h b/Build/source/texk/web2c/eptexdir/eptex_version.h
index 4e61c008190..f49a7579b98 100644
--- a/Build/source/texk/web2c/eptexdir/eptex_version.h
+++ b/Build/source/texk/web2c/eptexdir/eptex_version.h
@@ -1 +1 @@
-#define EPTEX_VERSION "161030"
+#define EPTEX_VERSION "161114"
diff --git a/Build/source/texk/web2c/eptexdir/pdfutils.ch b/Build/source/texk/web2c/eptexdir/pdfutils.ch
index 21a291e73ca..fdb49056bce 100644
--- a/Build/source/texk/web2c/eptexdir/pdfutils.ch
+++ b/Build/source/texk/web2c/eptexdir/pdfutils.ch
@@ -19,6 +19,377 @@
%% \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.
+@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.
+
+@d fraction_half==@'1000000000 {$2^{27}$, represents 0.50000000}
+@d fraction_one==@'2000000000 {$2^{28}$, represents 1.00000000}
+@d fraction_four==@'10000000000 {$2^{30}$, represents 4.00000000}
+@d el_gordo == @'17777777777 {$2^{31}-1$, the largest value that \MP\ likes}
+@d halfp(#)==(#) div 2
+@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@>
+
+@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@+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)
+
+@
+
+@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;
+
+@
+
+@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 ");
+@.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.
+
+@d return_sign(#)==begin ab_vs_cd:=#; return;
+ end
+
+@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@+ 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]|.
+
+@d next_random==if j_random=0 then new_randoms
+ else decr(j_random)
+
+@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.
+
+@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.
+
+@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\/}).
+
+@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.
+@z
@x
@* \[12] Displaying boxes.
@@ -360,12 +731,14 @@ ignore_spaces: {trap unexpandable primitives}
@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}}
+@d elapsed_time_code =pdf_shell_escape_code+1 {code for \.{\\pdfelapsedtime}}
+@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
-@d eTeX_int=pdf_shell_escape_code+1 {first of \eTeX\ codes for integers}
+@d eTeX_int=random_seed_code+1 {first of \eTeX\ codes for integers}
@z
@x \[if]pdfprimitive: scan_int
@@ -394,7 +767,9 @@ else if cur_tok=cs_token_flag+frozen_primitive then
@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}}
-@d etex_convert_codes=etex_convert_base+7 {end of \eTeX's command codes}
+@d uniform_deviate_code = etex_convert_base+7 {command code for \.{\\pdfuniformdeviate}}
+@d normal_deviate_code = etex_convert_base+8 {command code for \.{\\pdfnormaldeviate}}
+@d etex_convert_codes=etex_convert_base+9 {end of \eTeX's command codes}
@z
@x
@@ -407,6 +782,8 @@ else if cur_tok=cs_token_flag+frozen_primitive then
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 @@ pdf_file_dump_code:
restore_cur_string;
return;
end;
+uniform_deviate_code: scan_int;
+normal_deviate_code: do_nothing;
@z
@x
@@ -585,6 +964,8 @@ eTeX_revision_code: print(eTeX_revision);
@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 @@ fix_date_and_time;@/
@y
fix_date_and_time;@/
isprint_utf8:=false;
+random_seed:=(microseconds*1000)+(epochseconds mod 1000000);@/
+init_randoms(random_seed);@/
@z
@x
-@d set_language_code=5 {command modifier for \.{\\setlanguage}}
+@d epTeX_input_encoding_code=6 {command modifier for \.{\\epTeXinputencoding}}
@y
-@d set_language_code=5 {command modifier for \.{\\setlanguage}}
-@d TeX_extension_end=5
-@d pdf_save_pos_node=TeX_extension_end+1
+@d epTeX_input_encoding_code=6 {command modifier for \.{\\epTeXinputencoding}}
+@d pdf_save_pos_node=epTeX_input_encoding_code+1
+@d set_random_seed_code=pdf_save_pos_node+1
+@d reset_timer_code=set_random_seed_code+1
@z
@x
@@ -695,6 +1079,8 @@ isprint_utf8:=false;
@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 @@ set_language_code:@<Implement \.{\\setlanguage}@>;
@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 @@ pdf_save_pos_node: @<Implement \.{\\pdfsavepos}@>;
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 @@ primitive("pdfshellescape",last_item,pdf_shell_escape_code);
@!@: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");
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 @@ pdf_shell_escape_code:
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 @@ end;
@<Glob...@>=
@!isprint_utf8: boolean;
+@!epochseconds: integer;
+@!microseconds: integer;
-@ @<Declare procedures that need to be declared forward for \pdfTeX@>=
+@
+@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 @@ begin
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 @@ begin
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
diff --git a/Build/source/texk/web2c/euptexdir/ChangeLog b/Build/source/texk/web2c/euptexdir/ChangeLog
index 6d7a5e2a2a2..4f90f912499 100644
--- a/Build/source/texk/web2c/euptexdir/ChangeLog
+++ b/Build/source/texk/web2c/euptexdir/ChangeLog
@@ -1,3 +1,7 @@
+2016-11-14 Hironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
+
+ * euptrip/texmf.cnf: Increase pool_size.
+
2016-10-30 Hironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
* euptex.defines: Use initstarttime() to improve CreationDate.
diff --git a/Build/source/texk/web2c/euptexdir/euptrip/texmf.cnf b/Build/source/texk/web2c/euptexdir/euptrip/texmf.cnf
index 61739d6d58c..a113b69d2a0 100644
--- a/Build/source/texk/web2c/euptexdir/euptrip/texmf.cnf
+++ b/Build/source/texk/web2c/euptexdir/euptrip/texmf.cnf
@@ -10,7 +10,7 @@ max_print_line = 72
mem_bot = 1
main_memory = 4500
max_strings = 3300
-pool_size = 36000
+pool_size = 40000
string_vacancies = 8000
diff --git a/Build/source/texk/web2c/lib/ChangeLog b/Build/source/texk/web2c/lib/ChangeLog
index 729d5974740..024c62a3b30 100644
--- a/Build/source/texk/web2c/lib/ChangeLog
+++ b/Build/source/texk/web2c/lib/ChangeLog
@@ -1,3 +1,7 @@
+2016-11-14 Hironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
+
+ * texmfmp.c: Change a condition to support new primitives in e(u)ptex.
+
2016-06-12 Karl Berry <karl@freefriends.org>
* texmfmp.c (get_date_and_time):
diff --git a/Build/source/texk/web2c/lib/texmfmp.c b/Build/source/texk/web2c/lib/texmfmp.c
index ceb7094de61..540837ad62c 100644
--- a/Build/source/texk/web2c/lib/texmfmp.c
+++ b/Build/source/texk/web2c/lib/texmfmp.c
@@ -2305,7 +2305,7 @@ WARNING1 ("invalid value (expected 0 or 1) for environment variable $FORCE_SOURC
}
}
-#if defined(pdfTeX)
+#if defined(pdfTeX) || defined(epTeX) || defined(eupTeX)
/*
Getting a high resolution time.
*/
diff --git a/Build/source/texk/web2c/texmfmp.h b/Build/source/texk/web2c/texmfmp.h
index 571382294a6..874c0aeccc1 100644
--- a/Build/source/texk/web2c/texmfmp.h
+++ b/Build/source/texk/web2c/texmfmp.h
@@ -220,7 +220,7 @@ extern boolean input_line (FILE *);
#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 *);