From:	CSBVAX::MRGATE!RELAY-INFO-VAX@CRVAX.SRI.COM@SMTP 15-SEP-1988 13:09
To:	ARISIA::EVERHART
Subj:	RNO-to-TeX (again)


Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Thu, 15 SEP 88 08:37:22 PDT
Received: from relay.ubc.ca by KL.SRI.COM with TCP; Thu, 15 Sep 88 08:16:02 PDT
Received: by relay.ubc.ca (5.59/1.14)
	id AA01160; Thu, 15 Sep 88 08:15:34 PDT
Date: 15 Sep 88 14:30 -0500
From: John Edgecombe <edgecombe%ccrs.cdn@relay.ubc.ca>
To: <tnieland@wpafb-aamrl.arpa>, <philmds!philtis!lcn@mcvax.cwi.nl>,
        <info-vax@kl.sri.com>
Message-Id: <15*edgecombe@ccrs.cdn>
Subject: RNO-to-TeX (again)

I have been getting more messages recently about the .INI file missing
(including Ted Nieland's to the net).  Although I posted the revised
share files, the volume implies that I shall have to do so again.
So here goes -- in five parts:


+-+-+-+ Beginning of part 5 +-+-+-+
XThe program does four tasks.  It will translate RUNOFF sectioning commands
Xto \LaTeX\ sectioning commands, translate RUNOFF flags to \LaTeX\ commands,
Xtranslate RUNOFF page directives to \LaTeX\ page directives and adjust
X\LaTeX\ counters by the same amount as RUNOFF counters are to be adjusted.
X
X\subsection{Conversion of Sectioning Commands}
X{\bf RNOTOTEX} converts RUNOFF sectioning commands to \LaTeX\ sectioning 
Xcommands. 
XThe output \LaTeX\ style is always {\tt report } in 10 point font.
XThe sectioning command are converted in table~\ref{section-commands}.
X\begin{table}
X\begin{tabular}{ll}
X{\lb RUNOFF }`009    & {\LaTeX\ \lb Command Generated} \\
X .HL1 text      & \verb+\chapter{text}+ \\
X .HL2 text      & \verb+\section{text}+ \\
X .HL3 text      & \verb+\subsection{text}+ \\
X .HL4 text      & \verb+\subsubsection{text}+ \\
X .HL5 text      & \verb+\paragraph{text}+ \\
X .HL6 text      & \verb+\subparagraph{text}+ \\
X\end{tabular}
X\caption{Conversion of RUNOFF Sectioning Commands\label{section-commands}}
X\end{table}
X
X\subsection{Conversion of RUNOFF Flags}
XRUNOFF flags are converted to \LaTeX\ commands by {\bf RNOTOTEX}.  
XThis is a direct
Xconversion process, i.e.~a RUNOFF underline command is converted to a
X\LaTeX\ underline command.  This does not always produce the prettiest
Xresults (as one can use {\bf bold} and {\it italic} fonts in \LaTeX\ ),
Xbut it is consistent.  The author regrets that {\bf RNOTOTEX} does not
Vhave the esthetic sense to decide when a font is more appropriate than \index{e
Xsthetic sense}
Xa converted RUNOFF command.  The conversion process for RUNOFF flags
Xis table~\ref{flag-commands}.
X\begin{table}
X\begin{tabular}{lcl}
X{\lb RUNOFF Flag } & {\lb Flag } & {\LaTeX\ \lb Command Generated} \\
X{\lb Name        } & {\lb Char } &`009`009\\
XAccept`009`009`009& \_`009`009   & \verb!\verb+?+! \\
XBold`009`009`009& *`009`009   & \verb+{\bf+$\cdots$\verb+}+ \\
XBreak`009`009`009& \verb+|+`009   & \verb+\\+ \\
XCapitalize`009`009& \verb+<+`009   & (see below) \\
XComment`009`009        &  !`009`009   & \% \\
XHyphenate`009`009& =`009`009   & \verb+\hyphenate{+$\cdots$\verb+}+ \\
XIndex`009`009`009& \verb+>+`009   & \verb+\index{+$\cdots$\verb+}+ \\
XLowercase`009`009& $\backslash`009$  & (see below) \\
XOverstrike`009`009& \%`009`009   & \verb+{\bf+$\cdots$\verb+}+ \\
XPeriod`009`009        & +`009`009   & \verb+\frenchspacing+ \\
XSpace`009`009`009& \#`009`009   & \verb*+\ + \\
XSubindex`009`009& \verb+>+         & \verb+\index{+$\cdots$\verb+}+ \\
XSubstitute`009`009& \$`009`009   & {\em not translated } \\
XUnderline`009`009& \&`009`009   & \verb+\underline{+$\cdots$\verb+}+ \\
XUppercase               & \verb+^+         & (see below) \\
X\end{tabular}
X\caption{Conversion of RUNOFF Flags\label{flag-commands}}
X\end{table}
X
XCharacters following CAPITALIZE, LOWERCASE or UPPERCASE flags are converted
Xto the appropriate case during the translation process by {\bf RNOTOTEX},
Xunless they are paired with other flags.  In these other cases, the flags in
XRUNOFF lock another flag on, such as the {\bf bold}ing flag described
Xin the DSR manual\cite{dsr-manual} on page 3-6.  {\bf RNOTOTEX} will lock the
Xappropriate flag to the state it is in and produce the appropriate 
X\LaTeX\ commands.  
X\pagebreak
XFor example, {\bf RNOTOTEX} will convert~:
X\begin{verbatim}
X
X ^*These words are in bold face.\*
X
X        to
X
X  {\bf These words are in bold face.}
X
X\end{verbatim}
X
X\subsection{Conversion of RUNOFF Directives}
XRNOTOTEX converts RUNOFF directives to \LaTeX\ directives.
XRUNOFF allows one to enable or disable flags and change the
Xdefault flag character for a flag.  {\bf RNOTOTEX} will recognize these
Xcommands and change the internal parsing setup so that the flag is
X(or is not) recognized by the character specified.  See the RUNOFF commands
X````ENABLE'', ````DISABLE'', ````FLAGS'' and ````NO FLAGS'' described in the
XRUNOFF manual.
X
VIn addition, {\bf RNOTOTEX} will translate RUNOFF commands such as ````NOFILL''
X,
V````INDENT'' and ````LIST'' in the manner described in table~\ref{directive-com
Xmands}.
X\begin{table}
X\begin{tabular}{ll}
X{\lb RUNOFF }`009`009    &  {\LaTeX\ \lb Command Generated} \\
X.APPENDIX`009`009    & \verb+\appendix+ \\
X.BLANK $n$`009`009    & \verb+\vspace{+$n$+\verb+}+ \\
X.BREAK`009`009`009    & \verb+\linebreak+ \\
X.CENTRE {\it text }         & \verb+\begin{centering}+ \\
X`009`009`009    &   {\it text } \\
X`009`009`009    & \verb+\end{centering}+ \\
X.FOOTNOTE {\it text}`009    & \verb+\footnote{+{\it text }\} \\
X.INDENT`009`009`009    & \verb+\indent+ \\
X.JUSTIFY`009`009    & \verb+\obeylines \obeyspaces+ \\
X.LIST $n$,````q''`009`009    & \verb+\begin{enumerate}+ \\
X.LITERAL`009`009    & \verb+\begin{verbatim}+ etc. \\
X.NOFILL`009`009`009    & \verb+\sloppy+ \\
X.PAGE`009`009`009    & \verb+\pagebreak[4]+ \\
X.SPACING`009`009    & \verb+\setlength{\baselineskip}{n}+ \\
X.SUBTITLE  {\it text}`009    & \verb+\pagestyle{myheadings}+ etc. \\
X.TITLE {\it text}`009    & \verb+\pagestyle{myheadings}+ etc. \\
X\end{tabular}
X\caption{Conversion of RUNOFF Directives\label{directive-commands}}
X\end{table}
X
X\subsection{Conversion of RUNOFF Counters}
X{\bf RNOTOTEX} converts the RUNOFF counter changes to \LaTeX\ counter
Xadjustment changes.  The conversion process in described in
Xtable~\ref{counter-commands}.
X\begin{table}
X\begin{tabular}{ll}
X{\lb RUNOFF}`009       & {\LaTeX\ \lb Command Generated} \\
X.NUMBER APPENDIX $n$   & \verb+\setcounter{\chapter}{+$n$\verb+}+ \\
X.NUMBER LEVEL    $s,n$ & \verb+\setcounter{s}{n}+ \\
X.NUMBER LIST     $n$   & \verb+\setcounter{\enumi}{n}+ \\
X.NUMBER PAGE     $n$   & \verb+\setcounter{\page}{n}+ \\
X\end{tabular}
X\caption{Conversion of RUNOFF Numbering\label{counter-commands}}
X\end{table}
X
X\section{The Conversion LOG File}
XEach time {\bf RNOTOTEX} is executed, it generates the file {\tt RNOTOTEX.LOG}.
XIt is a record of each conversion used to generate the output \LaTeX\ commands.
XIt is useful to users less familiar with \LaTeX\ and wish to learn by
Xtrial and error rather than by reading the manual.  It may also be
Xuseful to experienced \LaTeX\ users to quickly identify what \LaTeX\ will
Xproduce as output from the generated TEX file without going through
Xa complete printing.  
X
XIt is recommended that the log file be printed and deleted for each
Xexecution.  For example, the batch job~:
X\begin{verbatim}
X
X  $ @DCL:TEX_CONVERSION_SETUP
X  $ RNOTOTEX REPORT NEW_REPORT
X  $ PRINT/DELETE RNOTOTEX.LOG
X
X\end{verbatim}
Xgenerates the file NEW\_REPORT.TEX from the file REPORT.RNO and prints
Xthe log of the conversion process.  The user can the examine the printed
Xlog file and decide upon the editing required to produce a ````nice''
X\LaTeX\ output.
X
X
X\begin{thebibliography}{99}
X\addcontentsline{toc}{chapter}{Bibliography}
X
X\bibitem{latex-manual} Leslie Lamport {\em \LaTeX\ User Guide \& Reference} \\
XAddison-Wesley Publishing Company, 1986 
X
X\bibitem{tex-manual} Donald E.~Knuth {\em The \TeX book} \\
XAddison-Wesley Publishing Company, 1984 
X
X\bibitem{metafont-manual} Donald E.~Knuth {\em The METAFONT Book} \\
XAddison-Wesley Publishing Company, 1986
X
X\bibitem{dsr-manual} Digital Equipment Corporation {Digital Standard RUNOFF
X(DSR) Reference Manual } \\
XOrder \# AA-Z301B-TE, July 1985
X
X\end{thebibliography}
X\clearpage
X
X\setcounter{page}{0}
X\pagenumbering{roman}
X\tableofcontents
X\listoftables
X
X\end{document}
$ GOSUB UNPACK_FILE
$ FILE_IS = "SCREENHANDLERS.PAS"
$ CHECKSUM_IS = 860971282
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X{`009operations for input/output of data from the terminal.
X`009Randall Venhola`009`0095-May-1987 }
X
XMODULE screenhandlers;
X
X
XTYPE
X    wordinteger = [WORD] 0..65535;
X    byterange = [BYTE] 0..255;
X            
X
X
XVAR
Xterminalerror : [HIDDEN,STATIC] integer := 0; 
Xcursorrow     : [HIDDEN,STATIC] wordinteger := 1;
Xcursorcolumn  : [HIDDEN,STATIC] wordinteger := 1;
X
X
X
X[GLOBAL] PROCEDURE clearsubscreen( line, column : integer );
X 
X   FUNCTION LIB$ERASE_PAGE(lineno, colno : wordinteger) : integer; extern;
X
X   VAR
X     l, c : wordinteger;
X
XBEGIN
X  l := line;
X  c := column;
X  terminalerror := lib$erase_page(l,c);
XEND;
X
X
X
X
X[GLOBAL] PROCEDURE clearscreen;
X
XBEGIN
X   clearsubscreen(1,1);
XEND;
X
X
X
X
X[GLOBAL] PROCEDURE positioncursor( line, column : integer );
X
X   FUNCTION LIB$SET_CURSOR( lineno, colno : wordinteger ) : integer; extern;
X
X   VAR
X     l, c : wordinteger;
X
XBEGIN
X   l := line;
X   c := column;
X   terminalerror := lib$set_cursor(l,c);
X   cursorrow := line;
X   cursorcolumn := column
XEND;   
X
X
X[GLOBAL] PROCEDURE rollttyforward;
XBEGIN
X   positioncursor(cursorrow+1, cursorcolumn)
XEND;                                         
X
X
X[GLOBAL] PROCEDURE rollttyback;
XBEGIN
X   if cursorrow > 1 then
X      positioncursor(cursorrow-1, cursorcolumn)
XEND;
X
X
X[GLOBAL] PROCEDURE putstringtoterminal( string : VARYING [limit] of CHAR;
X`009`009`009`009`009   line, column : integer;
X`009`009`009`009`009   reversevideo : boolean;
X`009`009    `009`009`009   blinking : boolean);
XCONST
X  maxscreenwidth = 132;
X 
XVAR
X  l, c, flags, newcolumn : wordinteger;
X 
X  FUNCTION LIB$PUT_SCREEN(outtext : VARYING [C] OF CHAR;
X   `009     `009          lineno : wordinteger; colno : wordinteger;
X`009`009  `009  flags : wordinteger) : integer; extern;
X 
X 
XBEGIN
X    l := line;
X    c := column;
X    if reversevideo then
X      if blinking then
X          flags := 3
X      else
X          flags := 2
X    else
X      flags := 0;
X    terminalerror := lib$put_screen(string, l, c, flags);
X    newcolumn :=  1 + length(string) + cursorcolumn;
X    if newcolumn > maxscreenwidth then
X       positioncursor(cursorrow + 1, 1)
X    else
X       positioncursor( cursorrow, newcolumn)
XEND;
X
X
X[GLOBAL] PROCEDURE ttywriteln;
Xconst
X  carriagereturn = 13;
X  linefeed = 10;
X
Xvar
X   endofline : [STATIC] VARYING[2] of char;
XBEGIN                     
X  endofline.body[1] := chr(carriagereturn);
X  endofline.body[2] := chr(linefeed);   
X  endofline.length  := 2;
X  putstringtoterminal(endofline, cursorrow, cursorcolumn, false, false);
X  positioncursor(cursorrow + 1, 1) 
XEND;
X
X
X    
X
X[GLOBAL] PROCEDURE ttyreadln( VAR string : VARYING [limit] of char );
X
X   FUNCTION LIB$GET_SCREEN(VAR inputtext : VARYING [lim1] OF CHAR;
V   promptstring : VARYING [lim2] OF CHAR; VAR outlen : wordinteger := %IMMED 0)
X : integer; extern;
X
X   VAR
X     len : wordinteger;
X     prompt : [STATIC] VARYING [2] OF CHAR := '>';
X
XBEGIN
X   terminalerror := lib$get_screen(string, prompt, len);
X   ttywriteln
XEND;
X
X
X
X[GLOBAL] PROCEDURE findcursor( var line, column : integer );
X
XBEGIN
X   line := cursorrow;
X   column := cursorcolumn;
XEND;
X
X
X
X[GLOBAL] FUNCTION terminalerrorcode : integer;
X
XBEGIN
X   terminalerrorcode := terminalerror;
XEND;
X
X
X
X
X[GLOBAL] PROCEDURE ttywritestring( string : VARYING [limit] OF CHAR);
X
XBEGIN
X   putstringtoterminal(string, cursorrow, cursorcolumn, false, false);
XEND;
X                                   
X
X[GLOBAL] PROCEDURE ttywriteint( int : integer );
Xconst
X   maxintchars = 20;
Xvar
X  s : varying[maxintchars] of char;
XBEGIN
X  writev(s, int:1);
X  ttywritestring( s )
XEND;
X
X
X[GLOBAL] PROCEDURE ttywritereal( floating : real; fieldwidth, 
X`009                                            ndigits : integer);
Xconst
X  maxfieldwidth = 30;
Xvar
X s : varying[maxfieldwidth] of char;
XBEGIN
X   writev(s, floating:fieldwidth:ndigits);
X   ttywritestring( s )
XEND;
X
XEND.
X                          
X                 
$ GOSUB UNPACK_FILE
$ FILE_IS = "SETUP.COM"
$ CHECKSUM_IS = 1043937621
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X$ set command rnototex
X$ define init$rnototex rnototex.ini
$ GOSUB UNPACK_FILE
$ FILE_IS = "TREEANDLISTOPS.PAS"
$ CHECKSUM_IS = 894243433
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X{ TREE AND LIST OPERATIONS - VERSION CVF01A
X  `009                     RANDALL VENHOLA JUNE 30, 1987 
X`009                     DOCUMENTED IN MODULEAREA:TREEOPS.TEX }
X
X
X
X[INHERIT('SCREENHANDLERS','ARGOPS','UTILITYOPS')]
XMODULE TREEANDLISTOPS;              
X
X{ list and tree operations - requires the external declarations for
X  data structures                                                 
X
X`009        ARGUMENT           - the item of the list
X`009        COMPARISONS        - possible results of comparisons
X`009        SETOFCOMPARISONS - set of above ordinal type      
X
X  the package is to be copied to the area of the source code and
X  recompiled.  It expects to find the environment file for the above
X  data structures and at least the following routines :     
X
X    function compareargs( leftarg, rightarg : argument ) : comparisons;
X    function argtexindex( arg : argument ) : integer;  
X`009                                                    }
X
XCONST               
X
X    nulllist = NIL;
X    nulltree = NIL;                                   
X
XTYPE
X
Xarglist     = ^listnode;                 
X         
Xargtree     = ^treenode;
X
X          treenode   = record
X`009                   parentnode : argtree;
X`009                   contents    : arglist
X`009                end;
X
X         listnode    = record
X`009                   field       : argument;
X`009                   next        : arglist;    
X`009                   subtree     : argtree
X`009                end;
X
X
X                   
X
X[GLOBAL] FUNCTION nextinlist( list : arglist ) : arglist;
Xbegin
X   if list = nulllist then
X      errorexit('nextinlist','empty list')
X   else
X     nextinlist := list^.next
Xend;                                                         
X
X
X
X
X[GLOBAL] FUNCTION firstarg( list : arglist ) : argument;
Xbegin
X   if list = nulllist then
X      errorexit('firstlistpointer','empty list')
X   else
X     firstarg := list^.field
Xend;
X                                          
X
X[GLOBAL] FUNCTION arglistlength( list : arglist ) : integer;
Xbegin
X    if list = nulllist then
X        arglistlength := 0
X    else
X        arglistlength := arglistlength(nextinlist(list)) + 1
Xend;                                            
X                                        
X
X                                      
X
X                                          
X[GLOBAL] FUNCTION leadingnodesubtree( list : arglist ) : argtree;
Xbegin
X   if list = nulllist then
X      errorexit('listsubtree','empty list')
X   else
X      leadingnodesubtree := list^.subtree
Xend;
X
X
X
X
X                                                  
X[GLOBAL] FUNCTION listofargsattree( tree : argtree ) : arglist;
Xbegin
X  if tree = nulltree then
X     errorexit('listofargsattree','empty tree')
X  else
X     listofargsattree := tree^.contents
Xend;
X
X
X
X[GLOBAL] FUNCTION treeisroot( tree : argtree ) : boolean;
Xbegin
X   if tree = nulltree then
X     treeisroot := TRUE
X   else
X     treeisroot := tree^.parentnode = nulltree 
Xend;
X                                                                 
X                  
X
X
X[GLOBAL] FUNCTION parenttree( tree : argtree ) : argtree;
Xbegin
X   if treeisroot( tree ) then
X      errorexit('parenttree','tree is root')
X   else
X      parenttree := tree^.parentnode
Xend;
X                   
X
X              
X
X[GLOBAL] PROCEDURE insertarginsortedlist( var list : arglist; 
X`009 arg : argument; var pointertoarg : arglist );
X`009                   
Xtype
X   scanstates = (searching, atfrontoflist, positionfound, endoflist);
Xvar
X   state : scanstates;
X   p, prevp, newp : arglist;
X   comp : comparisons;
X   
X   procedure allocatenewp;
X   begin
X      new( newp );
X      newp^.next := nulllist;            
X      newp^.subtree := nulltree;
X      newp^.field := arg;
X      pointertoarg := newp
X   end;
X                                                            
Xbegin                                                                   
X    if list = nulllist then                                                 
X    begin
X       allocatenewp;
X       list := newp
X    end
X    else
X    begin                       
X       p := list;                
X       comp := compareargs(arg, firstarg(list));
X       if (comp = lessthan) or (comp = equal) then
X       `009 state := atfrontoflist
X       else
X       begin     
X         state := searching;
X         repeat         
X           prevp := p;
X           p := nextinlist(p);                    
X`009   if p = nulllist then
X`009      state := endoflist
X`009   else
X`009   begin
X`009     comp := compareargs(arg, firstarg(p));
X`009     if (comp = lessthan) or (comp = equal) then
X`009        state := positionfound
X`009   end
X         until state <> searching
X       end;    
X       if comp = equal then
X          warningmessage('insertarginsortedlist','already in list')
X       else
X         case state of          
X         atfrontoflist : begin
X`009                       allocatenewp;
X`009                       newp^.next := list;
X`009                       list := newp
X`009                    end;
X         positionfound   : begin
X`009                      allocatenewp;
X       `009                      newp^.next := p;
X`009                      prevp^.next := newp
X       `009                    end;        
X`009 endoflist      : begin
X`009                      allocatenewp;
X`009                      prevp^.next := newp
X`009                    end                    
X       end {case}
X    end {else}
Xend;
X    `009  
X
X
X
X[GLOBAL] PROCEDURE appendargonlist( var list : arglist; arg : argument );
Xvar
X  p, prevp, newp : arglist;
Xbegin
X    if list = nulllist then
X    begin
X        new( newp );
X`009newp^.subtree := nulltree;`009
X        newp^.field := arg;
X        newp^.next := nulllist;
X        list := newp
X    end     
X    else
X    begin
X `009p := list;
X        repeat
X`009   prevp := p;         
X           p := nextinlist(p)
X        until p = nulllist;
X        new( newp );
X        newp^.subtree := nulltree;
X        newp^.field := arg;
X`009newp^.next := nulllist;
X        prevp^.next := newp
X     end
Xend;                  
X         
X
X
X
X[GLOBAL] PROCEDURE preceedargonlist( var list : arglist; arg : argument );
Xvar
X  newl : arglist;
Xbegin
X   new(newl);
X   newl^.subtree := nulltree;
X   newl^.field := arg;
X   newl^.next := list;
X   list := newl
Xend;
X
X
X            
X[GLOBAL] FUNCTION listcopy( list: arglist ) : arglist;
Xvar      
X   l : arglist;
X   
X   procedure prec( list : arglist );
X   begin
X     if list = nulllist then
X       l := nulllist
X     else
X     begin  
X         prec( nextinlist(l) );
X         preceedargonlist( l, firstarg(l))
X     end
X   end;
X
Xbegin
X   if list = nulllist then
X     listcopy := nulllist
X   else
X   begin
X     prec( list );
X     listcopy := l
X   end
Xend;
X
X              
X         
X[GLOBAL] FUNCTION reverseoflist( list: arglist ) : arglist;
Xvar 
X   l : arglist;
X   
X   procedure app( list : arglist );
X   begin
X     if list = nulllist then               
X       l := nulllist
X     else
X     begin  
X         app( nextinlist(l) );
X         appendargonlist( l, firstarg(l))
X     end
X   end;
X
Xbegin
X   if list = nulllist then
X     reverseoflist := nulllist
X   else
X   begin
X     app( list );
X     reverseoflist := l
X   end
Xend;
X
X
X
X
X[GLOBAL] FUNCTION leadingnodehassubtree( list : arglist ) : boolean;
Xbegin
X   if list = nulllist then
X     leadingnodehassubtree := false
X   else
X     leadingnodehassubtree := list^.subtree <> nulltree
Xend;
X         
X
X
X
X                   
X
X[GLOBAL] PROCEDURE findarginsortedlist( list : arglist; arg : argument; 
X`009                           var found : boolean; 
X`009                           var pointertoarg : arglist );
X
Xtype
X  searchstates = (searching, positionfound, foundlessthanlocation, endoflist);
Xvar       
X  p : arglist;                                     
X  state : searchstates;
X  currentarg : argument;                  
X  comp : comparisons;
Xbegin
X   found := false;      
X   if list <> nulllist then
X   begin
X      p := list;
X      state:= searching;
X      repeat
X         currentarg := firstarg(p);
X`009 comp := compareargs(arg, currentarg);
X`009 case comp of
X         notvalid     : errorexit('findarginsortedlist','invalid-comparison');
X`009 lessthan     : state := foundlessthanlocation;
X         equal         : begin
X`009                   state := positionfound;
X`009                   pointertoarg := p;
X`009`009           found := true
X                         end;
X         greaterthan  : nullstatement
X         end; {case}
X         if not found then
X         begin
X`009    p := nextinlist(p);
X            if p = nulllist then 
X`009      state := endoflist
X`009 end
X      until state <> searching
X   end
Xend;         
X          
X          
X
X                            
X[GLOBAL] PROCEDURE findarginlist( list : arglist; arg : argument;
X`009                    var found : boolean; 
X`009                    var pointertoarg : arglist );
Xvar
X   p : arglist;
X   compare : comparisons;
Xbegin
X    found := false;                                                           
X    if list <> nulllist then
X    begin       
X      p := list;
X      repeat                 
X         compare := compareargs( arg, firstarg(p) );
X         if compare = equal then                 
X         begin
X            found := true; 
X`009    pointertoarg := p
X         end
X         else                                       
X            p := nextinlist(p)
X       until (p = nulllist) or (found)
X     end
Xend;
X
X
X
X
X
X[GLOBAL] FUNCTION nargsattreenode( tree : argtree ) : integer;
Xbegin
X   if tree = nulltree then
X     nargsattreenode := 0
X   else
X     nargsattreenode := arglistlength( tree^.contents )
Xend;                                     
X
X                                           
X    
X
X
X
X        
X
X
X[GLOBAL] PROCEDURE insertlistintotree( list : arglist; var tree : argtree);
X`009
Xprocedure subinsert( list : arglist; var tree : argtree;
X`009              parentpointer : arglist );
Xlabel
X  routineexit;                         
Xvar
X   newtree : argtree;                                          
X   found : boolean;                                                           
X   arg : argument;
X   pointertoarg : arglist;
Xbegin
X   if list = nulllist then
X      goto routineexit;                  
X   arg := firstarg(list);
X   if tree = nulltree then
X   begin
X      new( newtree );
X      newtree^.contents := nulllist;
X      appendargonlist(newtree^.contents, arg);         
X      if parentpointer = nulllist then
X        newtree^.parentnode := nulltree
X      else
X        newtree^.parentnode := parentpointer^.subtree;
V      subinsert(nextinlist(list), newtree^.contents^.subtree, newtree^.contents
X);
X      if parentpointer = nulllist then
X        tree := newtree
X      else
X`009parentpointer^.subtree := newtree;
X      goto routineexit
X   end;
X   findarginsortedlist( tree^.contents, arg, found, pointertoarg);
X   if not found then
X      insertarginsortedlist(tree^.contents, arg, pointertoarg);
X   subinsert( nextinlist(list), pointertoarg^.subtree, pointertoarg);
X   routineexit : nullstatement
Xend;
X                                       
Xbegin
X   subinsert( list, tree, nulllist)
Xend;
X  
X                                         
X
X[GLOBAL] PROCEDURE searchtreeforlist( tree : argtree; list : arglist;
X          var found : boolean; var indexfound, depthfoundat : integer);
X
X   procedure subsearch( tree : argtree; list : arglist );
X   label 
X      routineexit;
X   var                                         
X      findsuccessful : boolean;
X      arg: argument;                                                
X      pointertoarg : arglist;
X   begin
X      if tree = nulltree then
X         goto routineexit;
X      if list = nulllist then
X         goto routineexit;
X      arg := firstarg(list);
X      depthfoundat := depthfoundat + 1;
V      findarginsortedlist(listofargsattree(tree), arg, findsuccessful, pointert
Xoarg);
X      if findsuccessful then 
X      begin        
X        found := true;
X        indexfound := argtexindex(firstarg(pointertoarg));   
X        if leadingnodehassubtree(pointertoarg) then
X          subsearch(leadingnodesubtree(pointertoarg), nextinlist(list))
X      end;
X      routineexit : nullstatement
X   end;
X    
Xbegin {searchtree}
X   found := false;                                      
X   indexfound := indexofunknowntexcommand;
X   if list = nulllist then
X     warningmessage('searchtree','given empty list')
X   else                            
X      subsearch(tree, list)
Xend;
X                          
X                           
X
X
X
X
X[GLOBAL] PROCEDURE padwithnullarguments( var list : arglist; index : integer;
X`009                            requiredlength : integer );
Xvar
X  arg : argument;
X  i, ntoappend : integer;
Xbegin
X   initarg(arg, [nulltype], blank, index, TRUE);
X   ntoappend := requiredlength - arglistlength(list);
X   for i := 1 to ntoappend do
X      appendargonlist(list, arg)
Xend;
X
X
X                             
X
X[GLOBAL] PROCEDURE listtoarray(var list : arglist; index : integer;
V                                 var arr  : argarray; requiredlength :integer )
X;
Xvar                                                   
X  l : arglist;
X  i : integer;
Xbegin                                                                          
X  if requiredlength > maxargsinarray then
X    errorexit('listtoarray','array size exceeded');
X  padwithnullarguments( list, index, requiredlength);                 
X  l := list;
X  for i := 1 to requiredlength do                  
X  begin
X   arr[i] := firstarg(l);
X   l := nextinlist(l)
X  end
Xend;                                                  
X
X                          
X
X
X[GLOBAL] PROCEDURE dlist( var f : text; l : arglist );
Xconst
X  linelength = 75;
Xvar
X  nchars : integer;
X
X procedure dl( l : arglist );
X var
X   s : pckstr;
X begin
X   if l = nulllist then
X     writeln(f)
X   else
X   begin      
X      s := argliteral(firstarg(l), true);
X      if (length(s) + nchars + 1) > linelength then
X      begin
X         writeln(f);
X         nchars := 0
X      end;
X      nchars := nchars + length(s) + 1;
X      write(f, s, blank);
X      dl( nextinlist(l))                                 
X   end
Xend;                           
X
Xbegin
X  nchars := 0;
X  dl( l )
Xend;
X
X
X[GLOBAL] PROCEDURE dtree( var f : text; tree : argtree);
X
X  procedure dt( name : pckstr; tree : argtree );
X  var
X    l : arglist;
X    s : pckstr;
X  begin        
X    if tree <> nulltree then
X    begin            
X      writeln(f);                
X      writeln(f,'**** "',name,'" NODE HAS ****');
X      l := listofargsattree(tree);
X      dlist(f,l);
X      writeln(f,'**** ',name,' *************');
X      while l <> nulllist do
X      begin      
X        if leadingnodehassubtree(l) then
X        begin 
X          s := argliteral(firstarg(l), true);
X          dt(s, leadingnodesubtree(l))
X        end;
X        l := nextinlist(l)
X      end
X    end
X  end;
X                              
X begin
X   dt('<ROOT>', tree)
Xend;
X       
X
X
X[HIDDEN] PROCEDURE texwritearg( var f : text; arg : argument);
XEXTERN;
X
X
X
X[GLOBAL] PROCEDURE writeargarray( var f : text; arr : argarray );
Xvar
X  i : integer;
Xbegin         
X  for i := 1 to maxargsinarray do
X    if argclass(arr[i]) <> [nulltype] then
X       texwritearg(f, arr[i])
Xend;
X
X                              
X              
X
X[GLOBAL] PROCEDURE makenullarray( var arr : argarray );
Xvar
X  templist : arglist;
Xbegin                  
X  templist := nulllist;
X  padwithnullarguments(templist, indexofunknowntexcommand, maxargsinarray);
X  listtoarray( templist, indexofunknowntexcommand, arr, maxargsinarray)
Xend;
X  
X    
X   
XEND.
X         
$ GOSUB UNPACK_FILE
$ FILE_IS = "UTILITYOPS.PAS"
$ CHECKSUM_IS = 236858740
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X[INHERIT('SCREENHANDLERS')]
X
XMODULE UTILITYOPS;
X
XCONST
X   blank = ' ';    
X    
X
X
XPROCEDURE gotoendofprogram;
XEXTERN;
X
X          
X
X[GLOBAL] PROCEDURE errorexit( caller : varying[limit1] of char;
X`009                      message : varying[limit2] of char );
Xbegin
X   ttywriteln;
X   ttywritestring('?ERROR from ');
X   ttywritestring(caller);
X   ttywritestring(message);
X   ttywriteln;
X   gotoendofprogram
Xend;
X
X  
X
X
X[GLOBAL] PROCEDURE warningmessage( caller : varying[limit1] of char;
X`009                           message : varying[limit2] of char );
X      
Xbegin
X   ttywriteln;           
X   ttywritestring('%WARNING from procedure ');
X   ttywritestring(caller);                 
X   ttywritestring('"');
X   ttywritestring(message);
X   ttywritestring('"');
X   ttywriteln
Xend;
X
X
X
X
X[GLOBAL] PROCEDURE nullstatement;
Xbegin
Xend;
X
X
X
X
X[GLOBAL] FUNCTION capchar ( ch : char ) : char;
Xbegin
X  if ch in ['a'..'z'] then
X    capchar := chr(ord(ch) - 32)
X  else
X    capchar := ch
Xend;
X
X
X
X
X[GLOBAL] FUNCTION lcchar( ch : char ) : char;
Xbegin
X  if ch in ['A'..'Z'] then
X     lcchar := chr(ord(ch) + 32)
X  else
X     lcchar := ch
Xend;
X
X                                     
XEND.
$ GOSUB UNPACK_FILE
$ EXIT
-+-+-+-+-+ End of part 5 +-+-+-+-+-

