Heiko Oberdiek wrote:
On Wed, Apr 15, 2009 at 08:02:42PM +0200, Taco Hoekwater wrote:
Heiko Oberdiek wrote:
If the next token is not a primitive, then it vanishes:
Behaviour in that case is undefined at the moment. Perhaps I should just
generate an error if the next token is not a primitive?
Yes, IMHO error message and ignoring itself (\pdfprimitive,
not the next token) as error recovery.
Updated patch attached.
Best wishes,
Taco
Index: src/texk/web2c/pdftexdir/pdftex.web
===================================================================
--- src/texk/web2c/pdftexdir/pdftex.web (revision 546)
+++ src/texk/web2c/pdftexdir/pdftex.web (working copy)
@@ -8923,9 +8923,40 @@
p:=get_avail; info(p):=cs_token_flag+frozen_primitive;
link(p):=loc; loc:=p; start:=p;
end;
+ end
+else begin
+ print_err("Missing primitive name");
+ help2("The control sequence marked <to be read again> does not")@/
+ ("represent any known primitive.");
+ back_error;
end;
end
+@ This block deals with unexpandable \.{\\primitive} appearing at a spot where
+an integer or an internal values should have been found. It fetches the
+next token then resets |cur_cmd|, |cur_cs|, and |cur_tok|, based on the
+primitive value of that token. No expansion takes place, because the
+next token may be all sorts of things. This could trigger further
+expansion creating new errors.
+
+@=
+begin
+get_token;
+cur_cs := prim_lookup(text(cur_cs));
+if cur_cs<>undefined_primitive then begin
+ cur_cmd := prim_eq_type(cur_cs);
+ cur_chr := prim_equiv(cur_cs);
+ cur_tok := (cur_cmd*@'400)+cur_chr;
+ end
+else begin
+ cur_cmd := relax;
+ cur_chr := 0;
+ cur_tok := cs_token_flag+frozen_relax;
+ cur_cs := frozen_relax;
+ end;
+goto restart;
+end
+
@ @=
begin print_err("Undefined control sequence");
@.Undefined control sequence@>
@@ -9571,13 +9602,13 @@
@p procedure scan_something_internal(@!level:small_number;@!negative:boolean);
{fetch an internal parameter}
-label exit;
+label exit, restart;
var m:halfword; {|chr_code| part of the operand token}
n, k: integer; {accumulators}
@!q:halfword; {general purpose index}
@!i:four_quarters; {character info}
@!p:0..nest_size; {index into |nest|}
-begin m:=cur_chr;
+begin restart: m:=cur_chr;
case cur_cmd of
def_code: @;
toks_register,assign_toks,def_family,set_font,def_font,letterspace_font,pdf_copy_font: @;
register: @;
last_item: @;
+ignore_spaces: {trap unexpandable primitives}
+ if cur_chr=1 then @;
othercases @
endcases;@/
while cur_val_level>level do @;
@@ -10082,7 +10115,7 @@
and that the decimal point has been backed up to be scanned again.
@p procedure scan_int; {sets |cur_val| to an integer}
-label done;
+label done, restart;
var negative:boolean; {should the answer be negated?}
@!m:integer; {|@t$2^{31}$@> div radix|, the threshold of danger}
@!d:small_number; {the digit just scanned}
@@ -10090,7 +10123,10 @@
@!OK_so_far:boolean; {has an error message been issued?}
begin radix:=0; OK_so_far:=true;@/
@;
+restart:
if cur_tok=alpha_token then @
+else if cur_tok=cs_token_flag+frozen_primitive then
+ @
else if (cur_cmd>=min_internal)and(cur_cmd<=max_internal) then
scan_something_internal(int_val,false)
else @;