summaryrefslogtreecommitdiff
path: root/info/digests/tex-implementors/message.04
diff options
context:
space:
mode:
Diffstat (limited to 'info/digests/tex-implementors/message.04')
-rw-r--r--info/digests/tex-implementors/message.04507
1 files changed, 507 insertions, 0 deletions
diff --git a/info/digests/tex-implementors/message.04 b/info/digests/tex-implementors/message.04
new file mode 100644
index 0000000000..0b67142a3a
--- /dev/null
+++ b/info/digests/tex-implementors/message.04
@@ -0,0 +1,507 @@
+Date: 29 May 88 Message No: 004
+
+To: TeX implementors and distributors
+
+From: Barbara Beeton
+
+Subject: TeX early-warning system: status report and TeX 2.92
+
+
+Owing to a number of problems and general lack of time, this mailing list
+has been moribund since the end of last year; the last message sent out
+was number 3, dated 24 Dec 87. There have now been some developments
+that should be communicated, so we'll try to get things started again.
+As it's been so long since the last message, there are some new names on
+the list, and I've also changed some addresses to try to keep up with
+changes to gateways and other mailer idosyncrasies, I'd appreciate it
+if you'd acknowledge your receipt of the message; the mailer doesn't
+always say that an address is unreachable, especially if it's going
+across network gateways.
+
+Last week I received the following message from Don Knuth:
+
+ Date: 25 May 88 1911 PDT
+ From: Don Knuth <DEK@SAIL.Stanford.EDU>
+ Subject: Tex, aka Humpty Dumpty
+
+ (are you ready for this?)
+ Today I repaired five (5) bugs in TeX and two (2) in METAFONT,
+ thereby making TeX version 2.92 and MF version 1.4.
+
+ Five. Yes, five. Plus two is seven.
+ Quite a blow to any feelings of confidence I once had...
+
+ Two TeX bugs were reported, one by Robert Messer and one by Peter
+ Breitenlohner. The Messer bug appeared last month in TeXhax, where it was
+ analyzed by Chris Thompson: When I'm scanning a file name, I use the string
+ pool as a buffer, and this conflicts with use of the string to define a
+ new control sequence (if the file name contains a macro call that has
+ parameters that are undefined control sequences).
+
+ Following DRF's dictum, I tried to think if any other bugs of a similar
+ nature could occur; and indeed I noticed that another case arises if
+ \string or \meaning or \the or suchlike occur as part of the file name
+ being scanned. (In previous versions of TeX, constructions like "\input
+ X\jobname" worked, but only by sheer luck... the `X' was lost and combined
+ with the \jobname and that whole thing was rescanned... very kludgy and
+ certainly not what I intended nor would it work with \expandafter.)
+
+ While testing that, I noticed another strange thing you could do with
+ TeX version 2.91: Try typing \input\romannumeral6 to the ** prompt,
+ then say \end on the next line; TeX tries to open file ".tex", then it
+ tells you it has written a transcript file called "viTEXPUT".
+
+ I needed to patch the make_name_string routine when fixing the latter bug.
+ This is one of the routines that's often in a change file, so people may
+ have to make a small update to their change file when they install 2.92.
+
+ In summary, I found three bugs because of what Messer reported; luckily
+ I had to pay for only one of them. What about the others? Well,
+ Breitenlohner noticed that \patterns would fail if a pattern starts with a
+ character whose \lccode is 1. While fixing that, I noticed a weird
+ circumstance that would arise only if an extremely nasty user tried very
+ hard to cause a range error; thus, five bugs total.
+
+ Both METAFONT bugs were found by Chris Thompson. One was a typo,
+ easily fixed; the other was craftily contrived in the TRIP/TRAP mold
+ (I mean, it was not the sort of thing any reasonable person would ever
+ run into, yet it produced a bug natheless). No bugs had been found in
+ METAFONT for almost two years, so I had pretty much forgotten how
+ to install a new version!
+
+ Breitenlohner also pointed out an infelicity in PLAIN.TEX; I've updated
+ that too. To top it all off, another typo in the MFbook was reported.
+
+ The new sources at SAIL have new versions of TEX.WEB, MF.WEB, PLAIN.TEX,
+ and all the TRIP and TRAP files. ...
+
+ I've kept ERRATA.TEX[tex,dek] up to date, except that I didn't bother
+ to show all the changes to indexes and mini-indexes.
+
+ The files TEX82.BUG[tex,dek] and MF84.BUG[mf,dek] are also up to date.
+ As far as I know, everything at SAIL is now bugfree and self-consistent.
+
+ No amount of apologies can suffice for my stupidities reflected in
+ all these booboos.
+
+ ...mumble seven new errors my my mumble seven SEVEN seven SEVEN my my
+ mumble seven...
+
+
+A note seems in order on the reference to SAIL. SAIL (SAIL.Stanford.Edu)
+is a DEC-10 running under the WAITS operating system; this is the system
+on which Knuth works, and the files here are always the most up-to-date.
+When Knuth sends out notice of a new version, the affected files are
+transported to SCORE (SCORE.Stanford.Edu), a DEC-20 running under TOPS-20;
+the generic distribution tape is generated here, as well as the TOPS-20
+distribution. The TeX system files at SCORE are maintained and updated
+by volunteers, who are not always able to react immediately to changes at
+SAIL. Both SAIL and SCORE support anonymous FTP, and a later message will
+provide more information on that.
+
+Today's information will consist of the new entries in the TeX82.BUG file,
+a comparison of the TeX.WEB files for version 2.92 and 2.9, and the changes
+in PLAIN.TeX.
+
+
+########################################################################
+
+Additions to TeX82.BUG
+
+338. \outer\def\a0{}\a\a shows temp_head list garbage (Silvio Levy, 20Apr88)
+@x module 391
+repeat if (info(r)>match_token+127)or(info(r)<match_token) then s:=null
+else begin match_chr:=info(r)-match_token; s:=link(r); r:=s;
+ p:=temp_head; link(p):=null; m:=0;
+@y
+repeat link(temp_head):=null;
+if (info(r)>match_token+127)or(info(r)<match_token) then s:=null
+else begin match_chr:=info(r)-match_token; s:=link(r); r:=s;
+ p:=temp_head; m:=0;
+@z
+
+339. \def\\#1{}\input a\\b failed (Robert Messer, 24Apr88)
+@x module 259
+var h:integer; {hash code}
+@y
+var h:integer; {hash code}
+@!d:integer; {number of characters in incomplete current string}
+@z
+@x module 260
+str_room(l);
+for k:=j to j+l-1 do append_char(buffer[k]);
+text(p):=make_string;
+@y
+str_room(l); d:=cur_length;
+while pool_ptr>str_start[str_ptr] do
+ begin decr(pool_ptr); str_pool[pool_ptr+l]:=str_pool[pool_ptr];
+ end; {move current string up to make room for another}
+for k:=j to j+l-1 do append_char(buffer[k]);
+text(p):=make_string; pool_ptr:=pool_ptr+d;
+@z
+
+340. Make patterns work when trie_min=0 (Peter Breitenlohner, 10May88)
+@x module 951
+trie_max:=128; trie_min:=128; trie_link(0):=1; trie_taken[0]:=false;
+@y
+trie_max:=128; trie_min:=128; trie_link(0):=1; trie_taken[0]:=false;
+trie_link(trie_size):=0; trie_back(0):=trie_size; {wrap around}
+@z
+@x module 953
+begin c:=trie_c[p]; {we have |c>0|}
+if c<trie_min then trie_min:=c;
+z:=trie_link(trie_min-1); {get the first conceivably good hole}
+@y
+begin c:=trie_c[p];
+if c<trie_min then trie_min:=c;
+if trie_min=0 then z:=trie_link(trie_size)
+else z:=trie_link(trie_min-1); {get the first conceivably good hole}
+@z
+@x module 966
+r:=0; {finally, we will zero out the holes}
+@y
+r:=trie_size; {finally, we will zero out the holes}
+@z
+
+341. Avoid possible trie_pointer out of range (24May88)
+@x module 923
+hc[0]:=127; hc[hn+1]:=127; hc[hn+2]:=256; {insert delimiters}
+@y
+hc[0]:=127; hc[hn+1]:=127; hc[hn+2]:=128; {insert delimiters}
+@z
+
+342. \input a\romannumeral1 etc.; similar to bug 339. (25May88)
+@x module 464
+@p function str_toks:pointer; {changes the current string to a token list}
+@y
+@p function str_toks(@!b:pool_pointer):pointer;
+ {changes the string |str_pool[b..pool_ptr]| to a token list}
+@z
+@x module 464, continued
+p:=temp_head; link(p):=null; k:=str_start[str_ptr];
+@y
+p:=temp_head; link(p):=null; k:=b;
+@z
+@x module 464, concluded
+pool_ptr:=str_start[str_ptr]; str_toks:=p;
+@y
+pool_ptr:=b; str_toks:=p;
+@z
+@x module 465
+begin get_x_token; scan_something_internal(tok_val,false);
+if cur_val_level>=ident_val then @<Copy the token list@>
+else begin old_setting:=selector; selector:=new_string;
+@y
+@!b:pool_pointer; {base of temporary string}
+begin get_x_token; scan_something_internal(tok_val,false);
+if cur_val_level>=ident_val then @<Copy the token list@>
+else begin old_setting:=selector; selector:=new_string; b:=pool_ptr;
+@z
+@x module 465, continued
+ selector:=old_setting; the_toks:=str_toks;
+@y
+ selector:=old_setting; the_toks:=str_toks(b);
+@z
+@x module 470
+begin c:=cur_chr; @<Scan the argument for command |c|@>;
+old_setting:=selector; selector:=new_string;
+@<Print the result of command |c|@>;
+selector:=old_setting; link(garbage):=str_toks; ins_list(link(temp_head));
+@y
+@!b:pool_pointer; {base of temporary string}
+begin c:=cur_chr; @<Scan the argument for command |c|@>;
+old_setting:=selector; selector:=new_string; b:=pool_ptr;
+@<Print the result of command |c|@>;
+selector:=old_setting; link(garbage):=str_toks(b); ins_list(link(temp_head));
+@z
+
+343. **\input\romannumeral6 confusion bypassed (25May88)
+@x module 525
+begin if (pool_ptr+name_length>pool_size)or(str_ptr=max_strings) then
+@y
+begin if (pool_ptr+name_length>pool_size)or(str_ptr=max_strings)or
+ (cur_length>0) then
+@z
+
+344. (I sincerely hope that there won't be any more)
+
+
+########################################################################
+
+Differences between TeX.WEB for 2.92 and for 2.9
+
+;COMPARISON OF TX:<TEX82.NEW>TEX-2-92.WEB.1 AND TX:<TEX82.NEW>TEX-2-9.WEB.1
+;OPTIONS ARE /E /3
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 1-28 (1880)
+% Version 2.91 fixes \outer\def\a0{}\a\a bug (April 1988).
+% Version 2.92 fixes \patterns, also file names with complex macros (May 1988).
+
+% A reward of $81.92 will be paid to the first finder of any remaining bug.
+% (This amount will double again in 1989.)
+
+% Although considerable effort has been expended to make the TeX program
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 1-29 (1882)
+
+% A reward of $40.96 will be paid to the first finder of any remaining bug.
+% (This amount will double again in 1988.)
+
+% Although considerable effort has been expended to make the TeX program
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 2-93 (9207)
+@d banner=='This is TeX, Version 2.92' {printed when \TeX\ starts}
+
+@ Different \PASCAL s have slightly different conventions, and the present
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 2-93 (9066)
+@d banner=='This is TeX, Version 2.9' {printed when \TeX\ starts}
+
+@ Different \PASCAL s have slightly different conventions, and the present
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 19-61 (240552)
+@!d:integer; {number of characters already in current string}
+@!p:pointer; {index in |hash| array}
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 19-61 (240410)
+@!p:pointer; {index in |hash| array}
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 19-88 (241492)
+str_room(l); d:=cur_length;
+while pool_ptr>str_start[str_ptr] do
+ begin decr(pool_ptr); str_pool[pool_ptr+l]:=str_pool[pool_ptr];
+ end; {move current string up to make room for another}
+for k:=j to j+l-1 do append_char(buffer[k]);
+text(p):=make_string; pool_ptr:=pool_ptr+d;
+@!stat incr(cs_count);@+tats@;@/
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 19-87 (241287)
+str_room(l);
+for k:=j to j+l-1 do append_char(buffer[k]);
+text(p):=make_string;
+@!stat incr(cs_count);@+tats@;@/
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 20-77 (255280)
+@!group_code=0..max_group_code; {|save_level| for a level boundary}
+
+@ The global variable |cur_group| keeps track of what sort of group we are
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 20-77 (254875)
+@!group_code=0..max_group_code; {|save_index| for a level boundary}
+
+@ The global variable |cur_group| keeps track of what sort of group we are
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 25-31 (308968)
+@!par_token:halfword; {token representing `\.{\\par}'}
+
+@ @<Put each...@>=
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 25-31 (308563)
+@!par_token:halfword; {token representing '\.{\\par}'}
+
+@ @<Put each...@>=
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 25-372 (322487)
+@ The present point in the program is reached only when the |expand|
+routine has inserted a special marker into the input. In this special
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 25-372 (322082)
+@ The present point in the program is reached only when the |no_expand|
+routine has inserted a special marker into the input. In this special
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 26-375 (343630)
+repeat link(temp_head):=null;
+if (info(r)>match_token+127)or(info(r)<match_token) then s:=null
+else begin match_chr:=info(r)-match_token; s:=link(r); r:=s;
+ p:=temp_head; m:=0;
+ end;
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 26-375 (343228)
+repeat if (info(r)>match_token+127)or(info(r)<match_token) then s:=null
+else begin match_chr:=info(r)-match_token; s:=link(r); r:=s;
+ p:=temp_head; link(p):=null; m:=0;
+ end;
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 27-675 (378115)
+ are |x| sp per unit; |goto attach_sign| if the units are internal@>;
+@<Scan an optional space@>;
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 27-675 (377704)
+ are |x| units per sp; |goto attach_sign| if the units are internal@>;
+@<Scan an optional space@>;
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 28-13 (388583)
+@p function str_toks(@!b:pool_pointer):pointer;
+ {changes the string |str_pool[b..pool_ptr]| to a token list}
+var p:pointer; {tail of the token list}
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 28-13 (388173)
+@p function str_toks:pointer; {changes the current string to a token list}
+var p:pointer; {tail of the token list}
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 28-20 (388915)
+p:=temp_head; link(p):=null; k:=b;
+while k<pool_ptr do
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 28-19 (388468)
+p:=temp_head; link(p):=null; k:=str_start[str_ptr];
+while k<pool_ptr do
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 28-28 (389103)
+pool_ptr:=b; str_toks:=p;
+end;
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 28-27 (388673)
+pool_ptr:=str_start[str_ptr]; str_toks:=p;
+end;
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 28-40 (389611)
+@!b:pool_pointer; {base of temporary string}
+begin get_x_token; scan_something_internal(tok_val,false);
+if cur_val_level>=ident_val then @<Copy the token list@>
+else begin old_setting:=selector; selector:=new_string; b:=pool_ptr;
+ case cur_val_level of
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 28-39 (389198)
+begin get_x_token; scan_something_internal(tok_val,false);
+if cur_val_level>=ident_val then @<Copy the token list@>
+else begin old_setting:=selector; selector:=new_string;
+ case cur_val_level of
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 28-53 (390161)
+ selector:=old_setting; the_toks:=str_toks(b);
+ end;
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 28-51 (389689)
+ selector:=old_setting; the_toks:=str_toks;
+ end;
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 28-117 (392508)
+@!b:pool_pointer; {base of temporary string}
+begin c:=cur_chr; @<Scan the argument for command |c|@>;
+old_setting:=selector; selector:=new_string; b:=pool_ptr;
+@<Print the result of command |c|@>;
+selector:=old_setting; link(garbage):=str_toks(b); ins_list(link(temp_head));
+end;
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 28-115 (392033)
+begin c:=cur_chr; @<Scan the argument for command |c|@>;
+old_setting:=selector; selector:=new_string;
+@<Print the result of command |c|@>;
+selector:=old_setting; link(garbage):=str_toks; ins_list(link(temp_head));
+end;
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 30-262 (427879)
+begin if (pool_ptr+name_length>pool_size)or(str_ptr=max_strings)or
+ (cur_length>0) then
+ make_name_string:="?"
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 30-262 (427342)
+begin if (pool_ptr+name_length>pool_size)or(str_ptr=max_strings) then
+ make_name_string:="?"
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 31-621 (464580)
+@d check_byte_range(#)==begin if (#<bc)or<(#>ec) then abort@+end
+@d current_character_being_worked_on==k+bc-fmem_ptr
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 31-621 (464024)
+@d check_byte_range(#)==begin if (#<bc)or(#>ec) then abort@+end
+@d current_character_being_worked_on==k+bc-fmem_ptr
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 35-281 (573403)
+`\.\_' or `\.\^' or `\./' or `\.\\' if |p| is descended from the |subscr|
+or |supscr| or |denominator| or |numerator| fields of noads. For example,
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 35-281 (572846)
+`\.[' or `\.(' or `\./' or `\.\\' if |p| is descended from the |subscr|
+or |supscr| or |denominator| or |numerator| fields of noads. For example,
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 43-68 (756339)
+to the impossible value 128, in order to guarantee that |hc[hn+3]| will
+never be fetched.
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 43-68 (755780)
+to the impossible value 256, in order to guarantee that |hc[hn+3]| will
+never be fetched.
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 43-75 (756649)
+hc[0]:=127; hc[hn+1]:=127; hc[hn+2]:=128; {insert delimiters}
+for j:=0 to hn-2 do
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 43-75 (756090)
+hc[0]:=127; hc[hn+1]:=127; hc[hn+2]:=256; {insert delimiters}
+for j:=0 to hn-2 do
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 43-196 (761319)
+until coming to a right brace; then |return|@>;
+exit:end;
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 43-196 (760760)
+until coming to a right brace; then skip an optional space and |return|@>;
+exit:end;
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 44-201 (773038)
+trie_link(trie_size):=0; trie_back(0):=trie_size; {wrap around}
+for p:=1 to 128 do
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 44-201 (772506)
+for p:=1 to 128 do
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 44-233 (774482)
+begin c:=trie_c[p];
+if c<trie_min then trie_min:=c;
+if trie_min=0 then z:=trie_link(trie_size)
+else z:=trie_link(trie_min-1); {get the first conceivably good hole}
+loop@+ begin if z<c then goto not_found;
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 44-232 (773885)
+begin c:=trie_c[p]; {we have |c>0|}
+if c<trie_min then trie_min:=c;
+z:=trie_link(trie_min-1); {get the first conceivably good hole}
+loop@+ begin if z<c then goto not_found;
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 44-345 (779179)
+ brace@>;
+trie_root:=compress_trie(trie_root); {compress the trie}
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 44-343 (778549)
+ brace; then skip an optional space@>;
+trie_root:=compress_trie(trie_root); {compress the trie}
+***************
+
+**** FILE TX:<TEX82.NEW>TEX-2-92.WEB.1, 44-443 (782387)
+r:=trie_size; {finally, we will zero out the holes}
+h.rh:=0; h.b0:=min_quarterword; h.b1:=0; {|trie_link:=0|,
+**** FILE TX:<TEX82.NEW>TEX-2-9.WEB.1, 44-441 (781786)
+r:=0; {finally, we will zero out the holes}
+h.rh:=0; h.b0:=min_quarterword; h.b1:=0; {|trie_link:=0|,
+***************
+
+
+########################################################################
+
+Differences between new and previous Plain.TeX
+
+;COMPARISON OF PS:<TEX.INPUTS>PLAIN.TEX.2 AND PS:<TEX.INPUTS>PLAIN.TEX.1
+;OPTIONS ARE /3
+
+**** FILE PS:<TEX.INPUTS>PLAIN.TEX.2, 6-244 (33253)
+\def\arrowvert{\delimiter"33C000 } % arrow without arrowheads
+\def\Arrowvert{\delimiter"33D000 } % double arrow without arrowheads
+\def\bracevert{\delimiter"33E000 } % the vertical bar that extends braces
+**** FILE PS:<TEX.INPUTS>PLAIN.TEX.1, 1-951 (33258)
+\def\arrowvert{\delimiter"33C } % arrow without arrowheads
+\def\Arrowvert{\delimiter"33D } % double arrow without arrowheads
+\def\bracevert{\delimiter"33E } % the vertical bar that extends braces
+***************
+
+**** FILE PS:<TEX.INPUTS>PLAIN.TEX.2, 8-22 (44482)
+\def\fmtname{plain}\def\fmtversion{2.92} % identifies the current format
+**** FILE PS:<TEX.INPUTS>PLAIN.TEX.1, 1-1220 (44480)
+\def\fmtname{plain}\def\fmtversion{2.3} % identifies the current format
+***************
+
+########################################################################
+
+[ end of message 004 ]
+-------
+