diff --git a/doc/scsh-manual/awk.tex b/doc/scsh-manual/awk.tex index e8ec358..6081289 100644 --- a/doc/scsh-manual/awk.tex +++ b/doc/scsh-manual/awk.tex @@ -42,7 +42,7 @@ characters. procedure is invoked as follows: % \codex{(\var{reader} \var{[port]}) $\longrightarrow$ - \textrm{\textit{{\str} or eof}}} + \textrm{\textit{{\str} or eof}}} % A record is a sequence of characters terminated by one of the characters in \var{delims} or eof. If \var{elide-delims?} is true, then a contiguous @@ -58,16 +58,16 @@ characters. The \var{handle-delim} argument controls what is done with the record's terminating delimiter. - \begin{inset} - \begin{tabular}{lp{0.6\linewidth}} - \ex{'trim} & Delimiters are trimmed. (The default)\\ - \ex{'split}& Reader returns delimiter string as a second argument. - If record is terminated by EOF, then the eof object is - returned as this second argument. \\ - \ex{'concat} & The record and its delimiter are returned as - a single string. - \end{tabular} - \end{inset} + \begin{inset} + \begin{tabular}{lp{0.6\linewidth}} + \ex{'trim} & Delimiters are trimmed. (The default)\\ + \ex{'split}& Reader returns delimiter string as a second argument. + If record is terminated by EOF, then the eof object is + returned as this second argument. \\ + \ex{'concat} & The record and its delimiter are returned as + a single string. + \end{tabular} + \end{inset} The reader procedure returned takes one optional argument, the port from which to read, which defaults to the current input port. It returns @@ -85,21 +85,21 @@ characters. \begin{desc} These functions return a parser function that can be used as follows: \codex{(\var{parser} \var{string} \var{[start]}) $\longrightarrow$ - \var{string-list}} + \var{string-list}} The returned parsers split strings into fields defined by regular expressions. You can parse by specifying a pattern that \emph{separates} fields, a pattern that \emph{terminates} fields, or a pattern that \emph{matches} fields: - \begin{inset} - \begin{tabular}{l@{\qquad}l} - Procedure & Pattern \\ \hline - \ex{field-splitter} & matches fields \\ - \ex{infix-splitter} & separates fields \\ - \ex{suffix-splitter}& terminates fields \\ - \ex{sloppy-suffix-splitter} & terminates fields - \end{tabular} - \end{inset} + \begin{inset} + \begin{tabular}{l@{\qquad}l} + Procedure & Pattern \\ \hline + \ex{field-splitter} & matches fields \\ + \ex{infix-splitter} & separates fields \\ + \ex{suffix-splitter}& terminates fields \\ + \ex{sloppy-suffix-splitter} & terminates fields + \end{tabular} + \end{inset} These parser generators are controlled by a range of options, so that you can precisely specify what kind of parsing you want. However, these @@ -109,7 +109,7 @@ These functions return a parser function that can be used as follows: \begin{tightinset} \begin{tabular}{l@{\quad=\quad }ll} \var{delim} & \ex{(rx (| (+ white) eos))} & (suffix delimiter: white space or eos) \\ - \multicolumn{1}{l}{} & \ex{(rx (+ white))} & (infix delimiter: white space) \\ + \multicolumn{1}{l}{} & \ex{(rx (+ white))} & (infix delimiter: white space) \\ \var{field} & \verb|(rx (+ (~ white)))| & (non-white-space) \\ @@ -147,10 +147,10 @@ These functions return a parser function that can be used as follows: The boolean \var{handle-delim} determines what to do with delimiters. \begin{tightinset}\begin{tabular}{ll} - \ex{'trim} & Delimiters are thrown away after parsing. (default) \\ - \ex{'concat} & Delimiters are appended to the field preceding them. \\ - \ex{'split} & Delimiters are returned as separate elements in - the field list. + \ex{'trim} & Delimiters are thrown away after parsing. (default) \\ + \ex{'concat} & Delimiters are appended to the field preceding them. \\ + \ex{'split} & Delimiters are returned as separate elements in + the field list. \end{tabular} \end{tightinset} @@ -165,10 +165,10 @@ These functions return a parser function that can be used as follows: The field parser produced is a procedure that can be employed as follows: - \codex{(\var{parse} \var{string} \var{[start]}) \evalto \var{string-list}} + \codex{(\var{parse} \var{string} \var{[start]}) \evalto \var{string-list}} The optional \var{start} argument (default 0) specifies where in the string to begin the parse. It is an error if - $\var{start} > \ex{(string-length \var{string})}$. + $\var{start} > \ex{(string-length \var{string})}$. The parsers returned by the four parser generators implement different kinds of field parsing: @@ -184,13 +184,13 @@ These functions return a parser function that can be used as follows: \ex{("foo")}, and \ex{"foo"} is an error. The syntax of suffix-delimited records is: - \begin{inset} - \begin{tabular}{lcll} - \synvar{record} & ::= & \ex{""} \qquad (Empty record) \\ - & $|$ & \synvar{element} \synvar{delim} + \begin{inset} + \begin{tabular}{lcll} + \synvar{record} & ::= & \ex{""} \qquad (Empty record) \\ + & $|$ & \synvar{element} \synvar{delim} \synvar{record} - \end{tabular} - \end{inset} + \end{tabular} + \end{inset} It is an error if a non-empty record does not end with a delimiter. To make the last delimiter optional, make sure the delimiter regexp @@ -202,16 +202,16 @@ These functions return a parser function that can be used as follows: record \ex{("foo" "")}. The syntax of infix-delimited records is: - \begin{inset} - \begin{tabular}{lcll} - \synvar{record} & ::= & \ex{""} \qquad (Forced to be empty record) \\ - & $|$ & \synvar{real-infix-record} \\ + \begin{inset} + \begin{tabular}{lcll} + \synvar{record} & ::= & \ex{""} \qquad (Forced to be empty record) \\ + & $|$ & \synvar{real-infix-record} \\ \\ - \synvar{real-infix-record} & ::= & \synvar{element} \synvar{delim} + \synvar{real-infix-record} & ::= & \synvar{element} \synvar{delim} \synvar{real-infix-record} \\ & $|$ & \synvar{element} - \end{tabular} - \end{inset} + \end{tabular} + \end{inset} Note that separator semantics doesn't really allow for empty records---the straightforward grammar (\ie, \synvar{real-infix-record}) @@ -221,7 +221,7 @@ These functions return a parser function that can be used as follows: and \ex{append} isomorphic. For example, \codex{((infix-splitter ":") (string-append \var{x} ":" \var{y}))} doesn't always equal -\begin{code} +\begin{code} (append ((infix-splitter ":") \var{x}) ((infix-splitter ":") \var{y}))\end{code} It fails when \var{x} or \var{y} are the empty string. @@ -252,9 +252,9 @@ These functions return a parser function that can be used as follows: \begin{tabular}{lllll} Record & : suffix & \verb!:|$! suffix & : infix & non-: field \\ \hline -\ex{""} & \ex{()} & \ex{()} & \ex{()} & \ex{()} \\ -\ex{":"} & \ex{("")} & \ex{("")} & \ex{("" "")} & \ex{()} \\ -\ex{"foo:"} & \ex{("foo")} & \ex{("foo")} & \ex{("foo" "")} & \ex{("foo")} \\ +\ex{""} & \ex{()} & \ex{()} & \ex{()} & \ex{()} \\ +\ex{":"} & \ex{("")} & \ex{("")} & \ex{("" "")} & \ex{()} \\ +\ex{"foo:"} & \ex{("foo")} & \ex{("foo")} & \ex{("foo" "")} & \ex{("foo")} \\ \ex{":foo"}& \emph{error} & \ex{("" "foo")}& \ex{("" "foo")}& \ex{("foo")} \\ \ex{"foo:bar"} & \emph{error} & \ex{("foo" "bar")} & \ex{("foo" "bar")} & \ex{("foo" "bar")} \end{tabular} @@ -294,7 +294,7 @@ Record & : suffix & \verb!:|$! suffix & : infix & non-: field \\ This utility returns a procedure that reads records with field structure from a port. The reader's interface is designed to make it useful in the \ex{awk} - loop macro (section~\ref{sec:awk}). + loop macro (section~\ref{sec:awk}). The reader is used as follows: \codex{(\var{reader} \var{[port]}) {\evalto} \var{[raw-record parsed-record]} or \var{[eof ()]}} @@ -313,7 +313,7 @@ Record & : suffix & \verb!:|$! suffix & : infix & non-: field \\ parsed value on eof is hardwired into the field reader. For example, if port \ex{p} is open on \ex{/etc/passwd}, then - \codex{((field-reader (infix-splitter ":" 7)) p)} + \codex{((field-reader (infix-splitter ":" 7)) p)} returns two values: {\small \begin{widecode} @@ -463,7 +463,7 @@ the entire line read, and a seven-element list of the split-out fields. So if the \synvar{next-record} form in an \ex{awk} expression is \ex{(read-passwd)}, then \synvar{record\&field-vars} must be a list of two variables, \eg, - \codex{(record field-vec)} + \codex{(record field-vec)} since \ex{read-passwd} returns two values. Note that \ex{awk} allows us to use \emph{any} record reader we want in the @@ -491,81 +491,81 @@ it checks them all. \begin{itemize} \itum{\ex{(\var{test} \vari{body}1 \vari{body}2 \ldots)}} - If \var{test} is true, execute the body forms. The last body form + If \var{test} is true, execute the body forms. The last body form is the value of the clause. The test and body forms are evaluated - in the scope of the record and state variables. + in the scope of the record and state variables. - The \var{test} form can be one of: - \begin{inset} + The \var{test} form can be one of: + \begin{inset} \begin{tabular}{lp{0.6\linewidth}} - \var{integer}: & The test is true for that iteration of the loop. + \var{integer}: & The test is true for that iteration of the loop. The first iteration is \#1. \\ - \var{sre}: & A regular expression, in SRE notation + \var{sre}: & A regular expression, in SRE notation (see chapter~\ref{chapt:sre}) can be used as - a test. The test is successful if the pattern + a test. The test is successful if the pattern matches the record. In particular, note that any string is an SRE. \\ - \ex{(when \var{expr})}: & - The body of a \ex{when} test is evaluated as a - Scheme boolean expression in the inner scope of the - \ex{awk} form. \\ + \ex{(when \var{expr})}: & + The body of a \ex{when} test is evaluated as a + Scheme boolean expression in the inner scope of the + \ex{awk} form. \\ - \var{expr}: & If the form is none of the above, it is treated as - a Scheme expression---in practice, the \ex{when} - keyword is only needed in cases where SRE/Scheme - expression ambiguity might occur. - \end{tabular} - \end{inset} + \var{expr}: & If the form is none of the above, it is treated as + a Scheme expression---in practice, the \ex{when} + keyword is only needed in cases where SRE/Scheme + expression ambiguity might occur. + \end{tabular} + \end{inset} \itum{\begin{tabular}[t]{l} -\ex{(range\ \ \ \var{start-test} \var{stop-test} \vari{body}1 \ldots)} \\ -\ex{(:range\ \ \var{start-test} \var{stop-test} \vari{body}1 \ldots)} \\ -\ex{(range:\ \ \var{start-test} \var{stop-test} \vari{body}1 \ldots)} \\ -\ex{(:range:\ \var{start-test} \var{stop-test} \vari{body}1 \ldots)} - \end{tabular}} +\ex{(range\ \ \ \var{start-test} \var{stop-test} \vari{body}1 \ldots)} \\ +\ex{(:range\ \ \var{start-test} \var{stop-test} \vari{body}1 \ldots)} \\ +\ex{(range:\ \ \var{start-test} \var{stop-test} \vari{body}1 \ldots)} \\ +\ex{(:range:\ \var{start-test} \var{stop-test} \vari{body}1 \ldots)} + \end{tabular}} % - These clauses become activated when \var{start-test} is true; + These clauses become activated when \var{start-test} is true; they stay active on all further iterations until \var{stop-test} is true. - So, to print out the first ten lines of a file, we use the clause: - \codex{(:range: 1 10 (display record))} + So, to print out the first ten lines of a file, we use the clause: + \codex{(:range: 1 10 (display record))} - The colons control whether or not the start and stop lines - are processed by the clause. For example: - \begin{inset}\begin{tabular}{l@{\qquad}l} - \ex{(range\ \ \ 1 5\ \ \ldots)} & Lines \phantom{1} 2 3 4 \\ - \ex{(:range\ \ 1 5\ \ \ldots)} & Lines 1 2 3 4 \\ - \ex{(range:\ \ 1 5\ \ \ldots)} & Lines \phantom{1} 2 3 4 5 \\ - \ex{(:range: 1 5\ \ \ldots)} & Lines 1 2 3 4 5 - \end{tabular} - \end{inset} + The colons control whether or not the start and stop lines + are processed by the clause. For example: + \begin{inset}\begin{tabular}{l@{\qquad}l} + \ex{(range\ \ \ 1 5\ \ \ldots)} & Lines \phantom{1} 2 3 4 \\ + \ex{(:range\ \ 1 5\ \ \ldots)} & Lines 1 2 3 4 \\ + \ex{(range:\ \ 1 5\ \ \ldots)} & Lines \phantom{1} 2 3 4 5 \\ + \ex{(:range: 1 5\ \ \ldots)} & Lines 1 2 3 4 5 + \end{tabular} + \end{inset} - A line can trigger both tests, either simultaneously starting and + A line can trigger both tests, either simultaneously starting and stopping an active region, or simultaneously stopping one and starting - a new one, so ranges can abut seamlessly. + a new one, so ranges can abut seamlessly. \itum{\ex{(else \vari{body}1 \vari{body}2 \ldots)}} If no other clause has executed since the top of the loop, or since the last \ex{else} clause, this clause executes. \itum{\ex{(\var{test} => \var{exp})}} - If evaluating \ex{test} produces a true value, + If evaluating \ex{test} produces a true value, apply \var{exp} to that value. - If \var{test} is a regular expression, then \var{exp} is applied - to the match data structure returned by the regexp match routine. + If \var{test} is a regular expression, then \var{exp} is applied + to the match data structure returned by the regexp match routine. \itum{\ex{(after \vari{body}1 \ldots)}} - This clause executes when the loop encounters EOF. The body forms - execute in the scope of the state vars and the record-count var, + This clause executes when the loop encounters EOF. The body forms + execute in the scope of the state vars and the record-count var, if there are any. The value of the last body form is the value - of the entire awk form. + of the entire awk form. - If there is no \ex{after} clause, \ex{awk} returns the loop's state - variables as multiple values. + If there is no \ex{after} clause, \ex{awk} returns the loop's state + variables as multiple values. \end{itemize} \subsection{Examples} @@ -573,7 +573,7 @@ Here are some examples of \ex{awk} being used to process various types of input stream. \begin{code} -(define $ nth) ; Saves typing. +(define $ list-ref) ; Saves typing. ;;; Print out the name and home-directory of everyone in /etc/passwd: (let ((read-passwd (field-reader (infix-splitter ":" 7)))) diff --git a/doc/scsh-manual/miscprocs.tex b/doc/scsh-manual/miscprocs.tex index 41217ed..925ee74 100644 --- a/doc/scsh-manual/miscprocs.tex +++ b/doc/scsh-manual/miscprocs.tex @@ -17,20 +17,6 @@ A left shift is $j > 0$; a right shift is $j < 0$. \end{desc} -\section{List procedures} -\dfn{nth}{list i}{object}{procedure \textbf{(obsolete)}} -\begin{desc} -Returns the $i^{\mathrm th}$ element of \var{list}. -The first element (the car) is \ex{(nth \var{list} 0)}, -the second element is \ex{(nth \var{list} 1)}, and so on. - -This procedure is provided as it is useful for accessing elements -from the lists returned by the field-readers (chapter~\ref{chapt:fr-awk}). - -The functionality of \ex{nth} is equivalent to that of \RnRS{}'s -\ex{list-ref}. Therefore, \ex{nth} will go away in a future release. -\end{desc} - \section{Password encryption} \defun {crypt} {key salt} {encrypted value}