home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-04-10 | 130.3 KB | 3,080 lines |
- Newsgroups: comp.sources.unix
- From: ross@spam.adelaide.edu.au (Ross Williams)
- Subject: v26i129: funnelweb - a tool for literate programming in C, Part09/20
- Sender: unix-sources-moderator@vix.com
- Approved: paul@vix.com
-
- Submitted-By: ross@spam.adelaide.edu.au (Ross Williams)
- Posting-Number: Volume 26, Issue 129
- Archive-Name: funnelweb/part09
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 9 (of 20)."
- # Contents: admin/gnu2.txt answers/ex16.tex answers/wv02.tex
- # hackman/h_ch2.tex hackman/h_ch4.tex sources/help_gnu.txt
- # sources/tangle.c
- # Wrapped by vixie@gw.home.vix.com on Sun Apr 11 11:00:22 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'admin/gnu2.txt' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'admin/gnu2.txt'\"
- else
- echo shar: Extracting \"'admin/gnu2.txt'\" \(17977 characters\)
- sed "s/^X//" >'admin/gnu2.txt' <<'END_OF_FILE'
- X GNU GENERAL PUBLIC LICENSE
- X Version 2, June 1991
- X
- X Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- X 675 Mass Ave, Cambridge, MA 02139, USA
- X Everyone is permitted to copy and distribute verbatim copies
- X of this license document, but changing it is not allowed.
- X
- X Preamble
- X
- X The licenses for most software are designed to take away your
- freedom to share and change it. By contrast, the GNU General Public
- License is intended to guarantee your freedom to share and change free
- software--to make sure the software is free for all its users. This
- General Public License applies to most of the Free Software
- XFoundation's software and to any other program whose authors commit to
- using it. (Some other Free Software Foundation software is covered by
- the GNU Library General Public License instead.) You can apply it to
- your programs, too.
- X
- X When we speak of free software, we are referring to freedom, not
- price. Our General Public Licenses are designed to make sure that you
- have the freedom to distribute copies of free software (and charge for
- this service if you wish), that you receive source code or can get it
- if you want it, that you can change the software or use pieces of it
- in new free programs; and that you know you can do these things.
- X
- X To protect your rights, we need to make restrictions that forbid
- anyone to deny you these rights or to ask you to surrender the rights.
- These restrictions translate to certain responsibilities for you if you
- distribute copies of the software, or if you modify it.
- X
- X For example, if you distribute copies of such a program, whether
- gratis or for a fee, you must give the recipients all the rights that
- you have. You must make sure that they, too, receive or can get the
- source code. And you must show them these terms so they know their
- rights.
- X
- X We protect your rights with two steps: (1) copyright the software, and
- X(2) offer you this license which gives you legal permission to copy,
- distribute and/or modify the software.
- X
- X Also, for each author's protection and ours, we want to make certain
- that everyone understands that there is no warranty for this free
- software. If the software is modified by someone else and passed on, we
- want its recipients to know that what they have is not the original, so
- that any problems introduced by others will not reflect on the original
- authors' reputations.
- X
- X Finally, any free program is threatened constantly by software
- patents. We wish to avoid the danger that redistributors of a free
- program will individually obtain patent licenses, in effect making the
- program proprietary. To prevent this, we have made it clear that any
- patent must be licensed for everyone's free use or not licensed at all.
- X
- X The precise terms and conditions for copying, distribution and
- modification follow.
- X
- X GNU GENERAL PUBLIC LICENSE
- X TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
- X
- X 0. This License applies to any program or other work which contains
- a notice placed by the copyright holder saying it may be distributed
- under the terms of this General Public License. The "Program", below,
- refers to any such program or work, and a "work based on the Program"
- means either the Program or any derivative work under copyright law:
- that is to say, a work containing the Program or a portion of it,
- either verbatim or with modifications and/or translated into another
- language. (Hereinafter, translation is included without limitation in
- the term "modification".) Each licensee is addressed as "you".
- X
- Activities other than copying, distribution and modification are not
- covered by this License; they are outside its scope. The act of
- running the Program is not restricted, and the output from the Program
- is covered only if its contents constitute a work based on the
- Program (independent of having been made by running the Program).
- Whether that is true depends on what the Program does.
- X
- X 1. You may copy and distribute verbatim copies of the Program's
- source code as you receive it, in any medium, provided that you
- conspicuously and appropriately publish on each copy an appropriate
- copyright notice and disclaimer of warranty; keep intact all the
- notices that refer to this License and to the absence of any warranty;
- and give any other recipients of the Program a copy of this License
- along with the Program.
- X
- You may charge a fee for the physical act of transferring a copy, and
- you may at your option offer warranty protection in exchange for a fee.
- X
- X 2. You may modify your copy or copies of the Program or any portion
- of it, thus forming a work based on the Program, and copy and
- distribute such modifications or work under the terms of Section 1
- above, provided that you also meet all of these conditions:
- X
- X a) You must cause the modified files to carry prominent notices
- X stating that you changed the files and the date of any change.
- X
- X b) You must cause any work that you distribute or publish, that in
- X whole or in part contains or is derived from the Program or any
- X part thereof, to be licensed as a whole at no charge to all third
- X parties under the terms of this License.
- X
- X c) If the modified program normally reads commands interactively
- X when run, you must cause it, when started running for such
- X interactive use in the most ordinary way, to print or display an
- X announcement including an appropriate copyright notice and a
- X notice that there is no warranty (or else, saying that you provide
- X a warranty) and that users may redistribute the program under
- X these conditions, and telling the user how to view a copy of this
- X License. (Exception: if the Program itself is interactive but
- X does not normally print such an announcement, your work based on
- X the Program is not required to print an announcement.)
- X
- These requirements apply to the modified work as a whole. If
- identifiable sections of that work are not derived from the Program,
- and can be reasonably considered independent and separate works in
- themselves, then this License, and its terms, do not apply to those
- sections when you distribute them as separate works. But when you
- distribute the same sections as part of a whole which is a work based
- on the Program, the distribution of the whole must be on the terms of
- this License, whose permissions for other licensees extend to the
- entire whole, and thus to each and every part regardless of who wrote it.
- X
- Thus, it is not the intent of this section to claim rights or contest
- your rights to work written entirely by you; rather, the intent is to
- exercise the right to control the distribution of derivative or
- collective works based on the Program.
- X
- In addition, mere aggregation of another work not based on the Program
- with the Program (or with a work based on the Program) on a volume of
- a storage or distribution medium does not bring the other work under
- the scope of this License.
- X
- X 3. You may copy and distribute the Program (or a work based on it,
- under Section 2) in object code or executable form under the terms of
- Sections 1 and 2 above provided that you also do one of the following:
- X
- X a) Accompany it with the complete corresponding machine-readable
- X source code, which must be distributed under the terms of Sections
- X 1 and 2 above on a medium customarily used for software interchange; or,
- X
- X b) Accompany it with a written offer, valid for at least three
- X years, to give any third party, for a charge no more than your
- X cost of physically performing source distribution, a complete
- X machine-readable copy of the corresponding source code, to be
- X distributed under the terms of Sections 1 and 2 above on a medium
- X customarily used for software interchange; or,
- X
- X c) Accompany it with the information you received as to the offer
- X to distribute corresponding source code. (This alternative is
- X allowed only for noncommercial distribution and only if you
- X received the program in object code or executable form with such
- X an offer, in accord with Subsection b above.)
- X
- The source code for a work means the preferred form of the work for
- making modifications to it. For an executable work, complete source
- code means all the source code for all modules it contains, plus any
- associated interface definition files, plus the scripts used to
- control compilation and installation of the executable. However, as a
- special exception, the source code distributed need not include
- anything that is normally distributed (in either source or binary
- form) with the major components (compiler, kernel, and so on) of the
- operating system on which the executable runs, unless that component
- itself accompanies the executable.
- X
- If distribution of executable or object code is made by offering
- access to copy from a designated place, then offering equivalent
- access to copy the source code from the same place counts as
- distribution of the source code, even though third parties are not
- compelled to copy the source along with the object code.
- X
- X 4. You may not copy, modify, sublicense, or distribute the Program
- except as expressly provided under this License. Any attempt
- otherwise to copy, modify, sublicense or distribute the Program is
- void, and will automatically terminate your rights under this License.
- However, parties who have received copies, or rights, from you under
- this License will not have their licenses terminated so long as such
- parties remain in full compliance.
- X
- X 5. You are not required to accept this License, since you have not
- signed it. However, nothing else grants you permission to modify or
- distribute the Program or its derivative works. These actions are
- prohibited by law if you do not accept this License. Therefore, by
- modifying or distributing the Program (or any work based on the
- Program), you indicate your acceptance of this License to do so, and
- all its terms and conditions for copying, distributing or modifying
- the Program or works based on it.
- X
- X 6. Each time you redistribute the Program (or any work based on the
- Program), the recipient automatically receives a license from the
- original licensor to copy, distribute or modify the Program subject to
- these terms and conditions. You may not impose any further
- restrictions on the recipients' exercise of the rights granted herein.
- You are not responsible for enforcing compliance by third parties to
- this License.
- X
- X 7. If, as a consequence of a court judgment or allegation of patent
- infringement or for any other reason (not limited to patent issues),
- conditions are imposed on you (whether by court order, agreement or
- otherwise) that contradict the conditions of this License, they do not
- excuse you from the conditions of this License. If you cannot
- distribute so as to satisfy simultaneously your obligations under this
- License and any other pertinent obligations, then as a consequence you
- may not distribute the Program at all. For example, if a patent
- license would not permit royalty-free redistribution of the Program by
- all those who receive copies directly or indirectly through you, then
- the only way you could satisfy both it and this License would be to
- refrain entirely from distribution of the Program.
- X
- If any portion of this section is held invalid or unenforceable under
- any particular circumstance, the balance of the section is intended to
- apply and the section as a whole is intended to apply in other
- circumstances.
- X
- It is not the purpose of this section to induce you to infringe any
- patents or other property right claims or to contest validity of any
- such claims; this section has the sole purpose of protecting the
- integrity of the free software distribution system, which is
- implemented by public license practices. Many people have made
- generous contributions to the wide range of software distributed
- through that system in reliance on consistent application of that
- system; it is up to the author/donor to decide if he or she is willing
- to distribute software through any other system and a licensee cannot
- impose that choice.
- X
- This section is intended to make thoroughly clear what is believed to
- be a consequence of the rest of this License.
- X
- X 8. If the distribution and/or use of the Program is restricted in
- certain countries either by patents or by copyrighted interfaces, the
- original copyright holder who places the Program under this License
- may add an explicit geographical distribution limitation excluding
- those countries, so that distribution is permitted only in or among
- countries not thus excluded. In such case, this License incorporates
- the limitation as if written in the body of this License.
- X
- X 9. The Free Software Foundation may publish revised and/or new versions
- of the General Public License from time to time. Such new versions will
- be similar in spirit to the present version, but may differ in detail to
- address new problems or concerns.
- X
- XEach version is given a distinguishing version number. If the Program
- specifies a version number of this License which applies to it and "any
- later version", you have the option of following the terms and conditions
- either of that version or of any later version published by the Free
- Software Foundation. If the Program does not specify a version number of
- this License, you may choose any version ever published by the Free Software
- XFoundation.
- X
- X 10. If you wish to incorporate parts of the Program into other free
- programs whose distribution conditions are different, write to the author
- to ask for permission. For software which is copyrighted by the Free
- Software Foundation, write to the Free Software Foundation; we sometimes
- make exceptions for this. Our decision will be guided by the two goals
- of preserving the free status of all derivatives of our free software and
- of promoting the sharing and reuse of software generally.
- X
- X NO WARRANTY
- X
- X 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
- XFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
- OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
- PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
- OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
- TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
- PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
- REPAIR OR CORRECTION.
- X
- X 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
- WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
- REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
- INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
- OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
- TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
- YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
- PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGES.
- X
- X END OF TERMS AND CONDITIONS
- X
- X Appendix: How to Apply These Terms to Your New Programs
- X
- X If you develop a new program, and you want it to be of the greatest
- possible use to the public, the best way to achieve this is to make it
- free software which everyone can redistribute and change under these terms.
- X
- X To do so, attach the following notices to the program. It is safest
- to attach them to the start of each source file to most effectively
- convey the exclusion of warranty; and each file should have at least
- the "copyright" line and a pointer to where the full notice is found.
- X
- X <one line to give the program's name and a brief idea of what it does.>
- X Copyright (C) 19yy <name of author>
- X
- X This program is free software; you can redistribute it and/or modify
- X it under the terms of the GNU General Public License as published by
- X the Free Software Foundation; either version 2 of the License, or
- X (at your option) any later version.
- X
- X This program is distributed in the hope that it will be useful,
- X but WITHOUT ANY WARRANTY; without even the implied warranty of
- X MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X GNU General Public License for more details.
- X
- X You should have received a copy of the GNU General Public License
- X along with this program; if not, write to the Free Software
- X Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- Also add information on how to contact you by electronic and paper mail.
- X
- If the program is interactive, make it output a short notice like this
- when it starts in an interactive mode:
- X
- X Gnomovision version 69, Copyright (C) 19yy name of author
- X Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- X This is free software, and you are welcome to redistribute it
- X under certain conditions; type `show c' for details.
- X
- The hypothetical commands `show w' and `show c' should show the appropriate
- parts of the General Public License. Of course, the commands you use may
- be called something other than `show w' and `show c'; they could even be
- mouse-clicks or menu items--whatever suits your program.
- X
- You should also get your employer (if you work as a programmer) or your
- school, if any, to sign a "copyright disclaimer" for the program, if
- necessary. Here is a sample; alter the names:
- X
- X Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- X `Gnomovision' (which makes passes at compilers) written by James Hacker.
- X
- X <signature of Ty Coon>, 1 April 1989
- X Ty Coon, President of Vice
- X
- This General Public License does not permit incorporating your program into
- proprietary programs. If your program is a subroutine library, you may
- consider it more useful to permit linking proprietary applications with the
- library. If this is what you want to do, use the GNU Library General
- Public License instead of this License.
- END_OF_FILE
- if test 17977 -ne `wc -c <'admin/gnu2.txt'`; then
- echo shar: \"'admin/gnu2.txt'\" unpacked with wrong size!
- fi
- # end of 'admin/gnu2.txt'
- fi
- if test -f 'answers/ex16.tex' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'answers/ex16.tex'\"
- else
- echo shar: Extracting \"'answers/ex16.tex'\" \(18160 characters\)
- sed "s/^X//" >'answers/ex16.tex' <<'END_OF_FILE'
- X
- X%*******************************************************************************
- X%* START OF AUTOMATICALLY GENERATED TEX FILE *
- X%*******************************************************************************
- X%* *
- X%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
- X%* You can typeset this file to produce printed documentation by running it *
- X%* through the TeX typesetter using a command such as: *
- X%* tex thisfilename *
- X%* The resultant file thisfilename.dvi can be printed using a command such as: *
- X%* lpr -Pcslw -d thisfilename.dvi *
- X%* *
- X%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
- X%* their documentation together in a single document. The FunnelWeb program *
- X%* analyses such documents producing both program files and typeset *
- X%* documentation such as this TeX file. *
- X%* FunnelWeb was created by Ross Williams. *
- X%* *
- X%* For more information on FunnelWeb look in the following FTP archive: *
- X%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
- X%* Directory: ~pub/funnelweb/ *
- X%* (or some other appropriately named directory). *
- X%* or email Ross Williams at ross@spam.adelaide.edu.au *
- X%* *
- X%*******************************************************************************
- X
- X
- X%===================== Start of FunnelWeb TeX Definitions ======================
- X
- X
- X% Version
- X% -------
- X% This is FunnelWeb TeX Macro Library Version 1.0.
- X
- X
- X% Copyright
- X% ---------
- X% This set of FunnelWeb TeX definitions was written by Ross Williams and was
- X% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
- X% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
- X% and hereby authorize that the set of TeX definitions pass into the public
- X% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
- X
- X
- X% Modification
- X% ------------
- X% Please record all modifications to these TeX definitions here. Unless
- X% otherwise specified, all modified definitions fall in the public domain too.
- X%
- X% Programmers:
- X% RNW Ross N. Williams ross@spam.adelaide.edu.au
- X%
- X% Changes:
- X% 07-May-1992 RNW Prepared this work for public domain release.
- X%
- X
- X
- X% General Comments
- X% ----------------
- X% This set of TeX definitions exists for two reasons:
- X%
- X% 1. To shorten and neaten the FunnelWeb TeX output.
- X% 2. To allow users to fiddle with the output format in their input files
- X% (by inserting redefining "\def"s) without having to resort to
- X% modifying the FunnelWeb code.
- X%
- X% The user is warned that these definitions may be changed from time to time
- X% (but probably not much). The user should not be too sneaky. In particular,
- X% users wishing to redefine some of these macros should do so in an explicitly
- X% defined section at the top of their input file. This will mean that in the
- X% event of problems, that section can simply be deleted or commented out to
- X% allow the document to at least be typeset in the default format. Users should
- X% limit themselves to redefining these macros in such a section and should
- X% refrain from using the macros throughout their documents.
- X
- X
- X% Environment Parameters
- X% ----------------------
- X% \tolerance tells TeX how tolerant it should be about making bad line and
- X% page breaks. Here we set it to it's maximum, as
- X% 1) Computer programs are likely to cause lots of bad breaks.
- X% 2) In most cases the user would probably rather get the TeX file through
- X% TeX without any errors than fiddle with spacings for perfection.
- X\tolerance=10000
- X
- X% I don't like indentation as it makes the page look more busy. Instead,
- X% paragraphs are separated by a little space (see next).
- X\parindent=0pt
- X
- X% In many cases, users will produce documents with long runs of paragraphs.
- X% In order to space out these paragraphs, it is convenient to maintain a
- X% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
- X% that the skip becomes a problem in macro definitions which require no skip
- X% and so we have to turn the skip on and off. The following two macros
- X% simplify this process.
- X\def\fwparskipon{\parskip=\medskipamount}
- X\def\fwparskipoff{\parskip=0pt}
- X\fwparskipon
- X
- X% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
- X% page in order to better vertically align the rest of the page (e.g. skips
- X% won't stretch as much). It also means that headings are less likely to be
- X% isolated at the bottom of the page without any following text.
- X\raggedbottom
- X
- X
- X% Fonts
- X% -----
- X% Most of the typeset output is set in 10pt roman and 10pt tt font.
- X% The major extra font needs spring from titles and headings.
- X% For portability's sake we use only the following fonts:
- X% cmr10
- X% cmbx10
- X% cmtt10
- X% and some enlargements of them. These fonts are all "standard" fonts
- X% in Plain TeX. See The TeXbook p.350.
- X\font\fwfontnote=cmr7
- X
- X\font\fwfontnorm=cmr10
- X\font\fwfontnorma=cmr10 scaled \magstep1
- X\font\fwfontnormb=cmr10 scaled \magstep2
- X
- X\font\fwfontbold=cmbx10
- X\font\fwfontbolda=cmbx10 scaled \magstep1
- X\font\fwfontboldb=cmbx10 scaled \magstep2
- X\font\fwfontboldc=cmbx10 scaled \magstep3
- X\font\fwfontboldd=cmbx10 scaled \magstep4
- X
- X
- X% Macros for Stylistic Details
- X% ----------------------------
- X% This section contains all the fiddly little macros for setting the details
- X% of each macro definition.
- X
- X% Macro definitions are sandwiched by calls to these macros which can be used
- X% to sort out the spacing before and after the macro definition.
- X\def\fwbeginmacro{\fwparskipoff\bigskip}
- X\def\fwendmacro{\fwparskipon\par}
- X
- X% These macros deal with the macro name and definition line.
- X\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
- X\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
- X\def\fwzero#1{{\bf Z}}
- X\def\fwmany#1{{\bf M}}
- X\def\fwequals{ $\equiv$}
- X\def\fwplusequals{ $+\equiv$}
- X
- X% Now for the actual body of the definition. It looks nice to have the tt
- X% code indented a little. Again, we use macros instead of writing direct TeX,
- X% so as to allow the user to fiddle this stuff to taste without having to
- X% modify the FunnelWeb C code.
- X\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
- X\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
- X\def\fwoquote{`}
- X\def\fwcquote{'}
- X\def\fwoparen{$($}
- X\def\fwcomma{$,$}
- X\def\fwcparen{$)$}
- X\def\fwparam#1{$\diamond #1$}
- X\def\fwparams#1{$(\diamond #1)$}
- X
- X% These macros deal with the notes that are appended at the end of each
- X% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
- X% have the same definition, they are given different names so as to allow the
- X% user to redefine these macros to typeset each kind of information differently
- X% if desired.
- X\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
- X\def\fwnote#1{{\fwfontnote #1}\par}
- X\def\fwisafile#1{\fwnote{#1}}
- X\def\fwusedin#1{\fwnote{#1}}
- X\def\fwseealso#1{\fwnote{#1}}
- X\def\fwendmacronotes{\endgroup}
- X
- X
- X% Macros to Typeset Program Code Verbatim
- X% ---------------------------------------
- X% This is by far the hairiest and most difficult part of the typesetting task
- X% because we have to turn off most of TeX's natural instincts in order to
- X% typeset the program text exactly as it appears in the input file.
- X% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
- X% Their code was inspired by the following sections of "The TeXbook":
- X% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
- X% Appendix E: Example Formats, p.421.
- X% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
- X% The liberal use of "%" is because I don't understand TeX well enough to
- X% understand when an end of line will cause trouble, and I am playing it safe.
- X
- X% Before defining the main \fwbtx macro, we have to stash away some definitions
- X% in the hidden part of TeX's environment. Let's hope that these "hidden"
- X% definitions don't affect anything except what is desired to be affected.
- X
- X% The tt font in which we wish to set the text has two Latin lurking ligatures!
- X% These are ?` and !`. To disable them, we define the left quote when ACTIVE
- X% to be defined in such a way as to prevent ligatures. The main TeX text will
- X% normally not be exposed to this definition because normally the leftquote
- X% character is not active. The \fwbtx macro temporarily makes the left quote
- X% character active thus activating the deactivation of left quote ligatures.
- X% See The TeXbook p.381.
- X{\catcode`\`=\active \gdef`{\relax\lq}}
- X
- X% TeX is fairly carefree about spaces and so we have to make it more serious.
- X% To do so we pull the same trick as above, setting up a definition for active
- X% space, but only making space active during the span of the verbatim text.
- X% In Plain TeX the active space is defined to be simply a space, but here we
- X% define it to be a control space. This ensures that the space cannot
- X% be gobbled up by one of TeX's mysterious mechanisms when activated.
- X% See The TeXbook, p.381 and p.352.
- X{\obeyspaces\global\let =\ }
- X
- X% Here is the main \fwbtx verbatim text macro.
- X% Note: The order in which all these pieces of business have to be done is
- X% still a partial mystery to me. Don't fiddle with this stuff unless you
- X% think you know what you are doing.
- X\def\fwbtx[{%
- X%
- X% The funnies involved in getting verbatim output are safely housed inside
- X% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
- X% instead of curly braces because we have to be able to signal the end of
- X% this macro with a curly brace.
- X\begingroup%
- X%
- X% \pars at the end of empty lines in the verbatim text won't come out normally
- X% because TeX is in vertical mode and they get gobbled up. To prevent this,
- X% we force \par to exit vertical mode first. See The TeXbook p.381.
- X\def\par{\leavevmode\endgraf}%
- X%
- X% Activate the leftquote character so as to avoid ligatures (see above).
- X\catcode`\`=\active%
- X%
- X% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
- X% that TeX will treat each verbatim line as a new paragraph.
- X\obeylines%
- X%
- X% To get verbatim output, we have to desex all the special characters. This
- X% is explained in detail in The TeXbook p.380.
- X\def\do##1{\catcode`##1=12 }\dospecials%
- X%
- X% Activate the space character so as to make TeX treat blanks seriously.
- X% This activation invokes an eralier definition (see above).
- X\obeyspaces
- X%
- X% Interparagraph skips do not help the cause.
- X% Note: We have to preserve the indentation though, as the code is actually
- X% indented in the final output. See \fwodef in an earlier section.
- X\parskip=0pt%
- X%
- X% We typeset the verbatim text in tt font (courier on the Macintosh) for a
- X% number of reasons:
- X% - tt font has the same horizontal spacing for each character.
- X% - tt font covers the ASCII character set.
- X% - tt font doesn't have many surprises (e.g. ligatures).
- X% - tt font looks much what you might see on a computer terminal screen.
- X\tt%
- X%
- X% Having set up an environment for verbatim, we are ready to use it.
- X% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
- X% part of the parameter of \fwverbatimgobble) until it sees the termination
- X% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
- X% must never occur in the verbatim text).
- X\fwverbatimgobble}
- X
- X% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
- X\def\fwverbatimgobble#1]fwetx={#1\endgroup}
- X
- X
- X% Table of Contents
- X% -----------------
- X% The five levels of table of contents that FunnelWeb supports are identified
- X% by the five letters [A..E]. These are used throughout the following macros.
- X
- X% The following macros are utilities to the TOC macros to follow.
- X\def\fwrule{\medskip\hrule\medskip}
- X\def\fwqh{\hskip1.5em\relax}
- X\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
- X
- X% The following macros are used to typeset the table of contents.
- X\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
- X\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
- X\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
- X\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
- X\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
- X\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
- X\def\fwtocfinish#1{\fwrule}
- X
- X% The following "library" macros define five different strengths of headings
- X% which can be used later in the section macros.
- X\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
- X\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
- X\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
- X\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
- X\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
- X
- X% Here are the macros that actually typeset the section headings throughout
- X% the document. The fwlib system has been employed so as to easily allow the
- X% user to redefine the strengths of headings to taste. For example, the
- X% user could insert in the input document a similar set of definitions to these
- X% but with the b..e headings set to \fwlibc. This would tone down the output.
- X\def\fwseca#1#2{\fwliba{#1}{#2}}
- X\def\fwsecb#1#2{\fwlibb{#1}{#2}}
- X\def\fwsecc#1#2{\fwlibc{#1}{#2}}
- X\def\fwsecd#1#2{\fwlibd{#1}{#2}}
- X\def\fwsece#1#2{\fwlibe{#1}{#2}}
- X
- X
- X% Support for Explicit Typesetting
- X% --------------------------------
- X% FunnelWeb supports pragmas and other constructs that allow
- X% typesetter-independent typesetting commands to be given. The
- X% following macros support these features.
- X
- X% The in-text literal @{sloth@} and emphasise @[walrus@] features.
- X\def\fwlit#1{{\tt #1}}
- X\def\fwemp#1{{\it #1}}
- X
- X% The "@p new_page" pragma.
- X\def\fwnewpage{\vfill\eject}
- X
- X% The "@p vskip Nmm" pragma.
- X\def\fwvskip#1{\null\vskip #1mm}
- X
- X% The "@p title <font> <align> <text>" pragma.
- X\def\fwfontnormal#1{{\fwfontnorm {#1}}}
- X\def\fwfonttitle#1{{\fwfontboldd {#1}}}
- X\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
- X\def\fwleftline#1{\leftline{#1}}
- X\def\fwcenterline#1{\centerline{#1}}
- X\def\fwrightline#1{\rightline{#1}}
- X
- X
- X% Support for Old FunnelWeb
- X% -------------------------
- X% The following macros were used extensively in the first version of
- X% FunnelWeb and are retained so that these older input files will still
- X% typeset cleanly.
- X\def\p#1{{\tt #1}} % P for Program text.
- X\def\flagpage#1#2{
- X \null
- X \vfill
- X \centerline{\fwfontboldd #1}
- X \vskip 1cm
- X \centerline{\fwfontboldd #2}
- X \vfill
- X \null
- X \vfill
- X}
- X
- X%====================== End of FunnelWeb TeX Definitions =======================
- X
- X\fwvskip{40}
- X\fwcenterline{\fwfonttitle{Powers:}}
- X\fwcenterline{\fwfonttitle{An Example of}}
- X\fwcenterline{\fwfonttitle{A Short}}
- X\fwcenterline{\fwfonttitle{FunnelWeb .fw File}}
- X\fwvskip{10}
- X\fwcenterline{\fwfontsmalltitle{by Ross Williams}}
- X\fwcenterline{\fwfontsmalltitle{26 January 1992}}
- X\fwvskip{20}
- X
- X\fwtocstart{}
- X\fwtoca{1}{FunnelWeb Example Program}
- X\fwtocb{1.1}{ex16.out}
- X\fwtocb{1.2}{Pull in packages}
- X\fwtocb{1.3}{Write out the first p powers of i on a single line}
- X\fwtocfinish{}
- X
- X
- X\fwseca{1}{FunnelWeb Example Program}
- X
- This program writes out each of the first \fwlit{p} powers of the first \fwlit{n}
- integers. These constant parameters are located here so that they are easy to
- change.
- X
- X\fwbeginmacro
- X\fwmacroname{Constants}{1}\fwequals \fwodef \fwbtx[n : constant natural := 10; -- How many numbers? (Ans: [1,n]).
- p : constant natural := 5; -- How many powers? (Ans: [1,p]).]fwetx=%
- X\fwcdef
- X\fwbeginmacronotes
- X\fwusedin{This macro is invoked in definition 2.}
- X\fwendmacronotes
- X\fwendmacro
- X
- X
- X\fwsecb{1.1}{ex16.out} Here is the outline of the program. This FunnelWeb file generates a single
- Ada output file called \fwlit{Power.ada}. The main program consists of a loop that
- iterates once for each number to be written out.
- X
- X\fwbeginmacro
- X\fwfilename{ex16.out}{2}\fwequals \fwodef \fwmacroname{Pull in packages}{3}\fwbtx[
- X
- procedure example is
- X ]fwetx=%
- X\fwmacroname{Constants}{1}\fwbtx[
- begin -- example
- X for i in 1..n loop
- X ]fwetx=%
- X\fwmacroname{Write out the first p powers of i on a single line}{4}\fwbtx[
- X end loop;
- end example;
- X]fwetx=%
- X\fwcdef
- X\fwbeginmacronotes
- X\fwisafile{This macro is attached to an output file.}
- X\fwendmacronotes
- X\fwendmacro
- X
- X
- X\fwsecb{1.2}{Pull in packages} In this section, we pull in the packages that this program needs to run. In
- fact, all we need is the IO package so that we can write out the results. To use
- the IO package, we first of all need to haul it in (\fwlit{with text\_io}) and then
- we need to make all its identifiers visible at the top level (\fwlit{use text\_io}).
- X
- X\fwbeginmacro
- X\fwmacroname{Pull in packages}{3}\fwequals \fwodef \fwbtx[with text_io; use text_io;]fwetx=%
- X\fwcdef
- X\fwbeginmacronotes
- X\fwusedin{This macro is invoked in definition 2.}
- X\fwendmacronotes
- X\fwendmacro
- X
- X
- X\fwsecb{1.3}{Write out the first p powers of i on a single line} Here is the bit that writes out the first \fwlit{p} powers of \fwlit{i}. The power
- values are calculated incrementally in \fwlit{ip} to avoid the use of the
- exponentiation operator.
- X
- X\fwbeginmacro
- X\fwmacroname{Write out the first p powers of i on a single line}{4}\fwequals \fwodef \fwbtx[declare
- X ip : natural := 1;
- begin
- X for power in 1..p loop
- X ip:=ip*i;
- X put(natural'image(ip) & " ");
- X end loop;
- X new_line;
- end;]fwetx=%
- X\fwcdef
- X\fwbeginmacronotes
- X\fwusedin{This macro is invoked in definition 2.}
- X\fwendmacronotes
- X\fwendmacro
- X
- X
- X\bye
- X
- X
- X%*******************************************************************************
- X%* END OF AUTOMATICALLY GENERATED TEX FILE *
- X%*******************************************************************************
- X
- END_OF_FILE
- if test 18160 -ne `wc -c <'answers/ex16.tex'`; then
- echo shar: \"'answers/ex16.tex'\" unpacked with wrong size!
- fi
- # end of 'answers/ex16.tex'
- fi
- if test -f 'answers/wv02.tex' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'answers/wv02.tex'\"
- else
- echo shar: Extracting \"'answers/wv02.tex'\" \(17380 characters\)
- sed "s/^X//" >'answers/wv02.tex' <<'END_OF_FILE'
- X
- X%*******************************************************************************
- X%* START OF AUTOMATICALLY GENERATED TEX FILE *
- X%*******************************************************************************
- X%* *
- X%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
- X%* You can typeset this file to produce printed documentation by running it *
- X%* through the TeX typesetter using a command such as: *
- X%* tex thisfilename *
- X%* The resultant file thisfilename.dvi can be printed using a command such as: *
- X%* lpr -Pcslw -d thisfilename.dvi *
- X%* *
- X%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
- X%* their documentation together in a single document. The FunnelWeb program *
- X%* analyses such documents producing both program files and typeset *
- X%* documentation such as this TeX file. *
- X%* FunnelWeb was created by Ross Williams. *
- X%* *
- X%* For more information on FunnelWeb look in the following FTP archive: *
- X%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
- X%* Directory: ~pub/funnelweb/ *
- X%* (or some other appropriately named directory). *
- X%* or email Ross Williams at ross@spam.adelaide.edu.au *
- X%* *
- X%*******************************************************************************
- X
- X
- X%===================== Start of FunnelWeb TeX Definitions ======================
- X
- X
- X% Version
- X% -------
- X% This is FunnelWeb TeX Macro Library Version 1.0.
- X
- X
- X% Copyright
- X% ---------
- X% This set of FunnelWeb TeX definitions was written by Ross Williams and was
- X% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
- X% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
- X% and hereby authorize that the set of TeX definitions pass into the public
- X% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
- X
- X
- X% Modification
- X% ------------
- X% Please record all modifications to these TeX definitions here. Unless
- X% otherwise specified, all modified definitions fall in the public domain too.
- X%
- X% Programmers:
- X% RNW Ross N. Williams ross@spam.adelaide.edu.au
- X%
- X% Changes:
- X% 07-May-1992 RNW Prepared this work for public domain release.
- X%
- X
- X
- X% General Comments
- X% ----------------
- X% This set of TeX definitions exists for two reasons:
- X%
- X% 1. To shorten and neaten the FunnelWeb TeX output.
- X% 2. To allow users to fiddle with the output format in their input files
- X% (by inserting redefining "\def"s) without having to resort to
- X% modifying the FunnelWeb code.
- X%
- X% The user is warned that these definitions may be changed from time to time
- X% (but probably not much). The user should not be too sneaky. In particular,
- X% users wishing to redefine some of these macros should do so in an explicitly
- X% defined section at the top of their input file. This will mean that in the
- X% event of problems, that section can simply be deleted or commented out to
- X% allow the document to at least be typeset in the default format. Users should
- X% limit themselves to redefining these macros in such a section and should
- X% refrain from using the macros throughout their documents.
- X
- X
- X% Environment Parameters
- X% ----------------------
- X% \tolerance tells TeX how tolerant it should be about making bad line and
- X% page breaks. Here we set it to it's maximum, as
- X% 1) Computer programs are likely to cause lots of bad breaks.
- X% 2) In most cases the user would probably rather get the TeX file through
- X% TeX without any errors than fiddle with spacings for perfection.
- X\tolerance=10000
- X
- X% I don't like indentation as it makes the page look more busy. Instead,
- X% paragraphs are separated by a little space (see next).
- X\parindent=0pt
- X
- X% In many cases, users will produce documents with long runs of paragraphs.
- X% In order to space out these paragraphs, it is convenient to maintain a
- X% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
- X% that the skip becomes a problem in macro definitions which require no skip
- X% and so we have to turn the skip on and off. The following two macros
- X% simplify this process.
- X\def\fwparskipon{\parskip=\medskipamount}
- X\def\fwparskipoff{\parskip=0pt}
- X\fwparskipon
- X
- X% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
- X% page in order to better vertically align the rest of the page (e.g. skips
- X% won't stretch as much). It also means that headings are less likely to be
- X% isolated at the bottom of the page without any following text.
- X\raggedbottom
- X
- X
- X% Fonts
- X% -----
- X% Most of the typeset output is set in 10pt roman and 10pt tt font.
- X% The major extra font needs spring from titles and headings.
- X% For portability's sake we use only the following fonts:
- X% cmr10
- X% cmbx10
- X% cmtt10
- X% and some enlargements of them. These fonts are all "standard" fonts
- X% in Plain TeX. See The TeXbook p.350.
- X\font\fwfontnote=cmr7
- X
- X\font\fwfontnorm=cmr10
- X\font\fwfontnorma=cmr10 scaled \magstep1
- X\font\fwfontnormb=cmr10 scaled \magstep2
- X
- X\font\fwfontbold=cmbx10
- X\font\fwfontbolda=cmbx10 scaled \magstep1
- X\font\fwfontboldb=cmbx10 scaled \magstep2
- X\font\fwfontboldc=cmbx10 scaled \magstep3
- X\font\fwfontboldd=cmbx10 scaled \magstep4
- X
- X
- X% Macros for Stylistic Details
- X% ----------------------------
- X% This section contains all the fiddly little macros for setting the details
- X% of each macro definition.
- X
- X% Macro definitions are sandwiched by calls to these macros which can be used
- X% to sort out the spacing before and after the macro definition.
- X\def\fwbeginmacro{\fwparskipoff\bigskip}
- X\def\fwendmacro{\fwparskipon\par}
- X
- X% These macros deal with the macro name and definition line.
- X\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
- X\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
- X\def\fwzero#1{{\bf Z}}
- X\def\fwmany#1{{\bf M}}
- X\def\fwequals{ $\equiv$}
- X\def\fwplusequals{ $+\equiv$}
- X
- X% Now for the actual body of the definition. It looks nice to have the tt
- X% code indented a little. Again, we use macros instead of writing direct TeX,
- X% so as to allow the user to fiddle this stuff to taste without having to
- X% modify the FunnelWeb C code.
- X\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
- X\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
- X\def\fwoquote{`}
- X\def\fwcquote{'}
- X\def\fwoparen{$($}
- X\def\fwcomma{$,$}
- X\def\fwcparen{$)$}
- X\def\fwparam#1{$\diamond #1$}
- X\def\fwparams#1{$(\diamond #1)$}
- X
- X% These macros deal with the notes that are appended at the end of each
- X% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
- X% have the same definition, they are given different names so as to allow the
- X% user to redefine these macros to typeset each kind of information differently
- X% if desired.
- X\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
- X\def\fwnote#1{{\fwfontnote #1}\par}
- X\def\fwisafile#1{\fwnote{#1}}
- X\def\fwusedin#1{\fwnote{#1}}
- X\def\fwseealso#1{\fwnote{#1}}
- X\def\fwendmacronotes{\endgroup}
- X
- X
- X% Macros to Typeset Program Code Verbatim
- X% ---------------------------------------
- X% This is by far the hairiest and most difficult part of the typesetting task
- X% because we have to turn off most of TeX's natural instincts in order to
- X% typeset the program text exactly as it appears in the input file.
- X% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
- X% Their code was inspired by the following sections of "The TeXbook":
- X% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
- X% Appendix E: Example Formats, p.421.
- X% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
- X% The liberal use of "%" is because I don't understand TeX well enough to
- X% understand when an end of line will cause trouble, and I am playing it safe.
- X
- X% Before defining the main \fwbtx macro, we have to stash away some definitions
- X% in the hidden part of TeX's environment. Let's hope that these "hidden"
- X% definitions don't affect anything except what is desired to be affected.
- X
- X% The tt font in which we wish to set the text has two Latin lurking ligatures!
- X% These are ?` and !`. To disable them, we define the left quote when ACTIVE
- X% to be defined in such a way as to prevent ligatures. The main TeX text will
- X% normally not be exposed to this definition because normally the leftquote
- X% character is not active. The \fwbtx macro temporarily makes the left quote
- X% character active thus activating the deactivation of left quote ligatures.
- X% See The TeXbook p.381.
- X{\catcode`\`=\active \gdef`{\relax\lq}}
- X
- X% TeX is fairly carefree about spaces and so we have to make it more serious.
- X% To do so we pull the same trick as above, setting up a definition for active
- X% space, but only making space active during the span of the verbatim text.
- X% In Plain TeX the active space is defined to be simply a space, but here we
- X% define it to be a control space. This ensures that the space cannot
- X% be gobbled up by one of TeX's mysterious mechanisms when activated.
- X% See The TeXbook, p.381 and p.352.
- X{\obeyspaces\global\let =\ }
- X
- X% Here is the main \fwbtx verbatim text macro.
- X% Note: The order in which all these pieces of business have to be done is
- X% still a partial mystery to me. Don't fiddle with this stuff unless you
- X% think you know what you are doing.
- X\def\fwbtx[{%
- X%
- X% The funnies involved in getting verbatim output are safely housed inside
- X% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
- X% instead of curly braces because we have to be able to signal the end of
- X% this macro with a curly brace.
- X\begingroup%
- X%
- X% \pars at the end of empty lines in the verbatim text won't come out normally
- X% because TeX is in vertical mode and they get gobbled up. To prevent this,
- X% we force \par to exit vertical mode first. See The TeXbook p.381.
- X\def\par{\leavevmode\endgraf}%
- X%
- X% Activate the leftquote character so as to avoid ligatures (see above).
- X\catcode`\`=\active%
- X%
- X% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
- X% that TeX will treat each verbatim line as a new paragraph.
- X\obeylines%
- X%
- X% To get verbatim output, we have to desex all the special characters. This
- X% is explained in detail in The TeXbook p.380.
- X\def\do##1{\catcode`##1=12 }\dospecials%
- X%
- X% Activate the space character so as to make TeX treat blanks seriously.
- X% This activation invokes an eralier definition (see above).
- X\obeyspaces
- X%
- X% Interparagraph skips do not help the cause.
- X% Note: We have to preserve the indentation though, as the code is actually
- X% indented in the final output. See \fwodef in an earlier section.
- X\parskip=0pt%
- X%
- X% We typeset the verbatim text in tt font (courier on the Macintosh) for a
- X% number of reasons:
- X% - tt font has the same horizontal spacing for each character.
- X% - tt font covers the ASCII character set.
- X% - tt font doesn't have many surprises (e.g. ligatures).
- X% - tt font looks much what you might see on a computer terminal screen.
- X\tt%
- X%
- X% Having set up an environment for verbatim, we are ready to use it.
- X% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
- X% part of the parameter of \fwverbatimgobble) until it sees the termination
- X% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
- X% must never occur in the verbatim text).
- X\fwverbatimgobble}
- X
- X% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
- X\def\fwverbatimgobble#1]fwetx={#1\endgroup}
- X
- X
- X% Table of Contents
- X% -----------------
- X% The five levels of table of contents that FunnelWeb supports are identified
- X% by the five letters [A..E]. These are used throughout the following macros.
- X
- X% The following macros are utilities to the TOC macros to follow.
- X\def\fwrule{\medskip\hrule\medskip}
- X\def\fwqh{\hskip1.5em\relax}
- X\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
- X
- X% The following macros are used to typeset the table of contents.
- X\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
- X\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
- X\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
- X\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
- X\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
- X\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
- X\def\fwtocfinish#1{\fwrule}
- X
- X% The following "library" macros define five different strengths of headings
- X% which can be used later in the section macros.
- X\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
- X\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
- X\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
- X\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
- X\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
- X
- X% Here are the macros that actually typeset the section headings throughout
- X% the document. The fwlib system has been employed so as to easily allow the
- X% user to redefine the strengths of headings to taste. For example, the
- X% user could insert in the input document a similar set of definitions to these
- X% but with the b..e headings set to \fwlibc. This would tone down the output.
- X\def\fwseca#1#2{\fwliba{#1}{#2}}
- X\def\fwsecb#1#2{\fwlibb{#1}{#2}}
- X\def\fwsecc#1#2{\fwlibc{#1}{#2}}
- X\def\fwsecd#1#2{\fwlibd{#1}{#2}}
- X\def\fwsece#1#2{\fwlibe{#1}{#2}}
- X
- X
- X% Support for Explicit Typesetting
- X% --------------------------------
- X% FunnelWeb supports pragmas and other constructs that allow
- X% typesetter-independent typesetting commands to be given. The
- X% following macros support these features.
- X
- X% The in-text literal @{sloth@} and emphasise @[walrus@] features.
- X\def\fwlit#1{{\tt #1}}
- X\def\fwemp#1{{\it #1}}
- X
- X% The "@p new_page" pragma.
- X\def\fwnewpage{\vfill\eject}
- X
- X% The "@p vskip Nmm" pragma.
- X\def\fwvskip#1{\null\vskip #1mm}
- X
- X% The "@p title <font> <align> <text>" pragma.
- X\def\fwfontnormal#1{{\fwfontnorm {#1}}}
- X\def\fwfonttitle#1{{\fwfontboldd {#1}}}
- X\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
- X\def\fwleftline#1{\leftline{#1}}
- X\def\fwcenterline#1{\centerline{#1}}
- X\def\fwrightline#1{\rightline{#1}}
- X
- X
- X% Support for Old FunnelWeb
- X% -------------------------
- X% The following macros were used extensively in the first version of
- X% FunnelWeb and are retained so that these older input files will still
- X% typeset cleanly.
- X\def\p#1{{\tt #1}} % P for Program text.
- X\def\flagpage#1#2{
- X \null
- X \vfill
- X \centerline{\fwfontboldd #1}
- X \vskip 1cm
- X \centerline{\fwfontboldd #2}
- X \vfill
- X \null
- X \vfill
- X}
- X
- X%====================== End of FunnelWeb TeX Definitions =======================
- WV05: Test typesetting features.
- X
- X\fwbeginmacro
- X\fwfilename{wv05.out}{1}\fwequals \fwodef \fwbtx[
- X]fwetx=%
- X\fwcdef
- X\fwbeginmacronotes
- X\fwisafile{This macro is attached to an output file.}
- X\fwendmacronotes
- X\fwendmacro
- X
- X
- X1. Test all five levels of headings with explicit titles.
- X
- X\fwseca{1}{One}
- X\fwsecb{1.1}{Two}
- X\fwsecc{1.1.1}{Three}
- X\fwsecd{1.1.1.1}{Four}
- X\fwsece{1.1.1.1.1}{Five}
- X
- X2. Test all five levels of headings with implicit titles.
- X
- X\fwseca{2}{Macro at level one}
- X\fwbeginmacro
- X\fwmacroname{Macro at level one}{2}\fwzero{}\fwequals \fwodef \fwbtx[Sloth]fwetx=%
- X\fwcdef
- X\fwbeginmacronotes
- X\fwusedin{This macro is NEVER invoked.}
- X\fwendmacronotes
- X\fwendmacro
- X
- X
- X\fwsecb{2.1}{Macro at level two}
- X\fwbeginmacro
- X\fwmacroname{Macro at level two}{3}\fwzero{}\fwequals \fwodef \fwbtx[Walrus]fwetx=%
- X\fwcdef
- X\fwbeginmacronotes
- X\fwusedin{This macro is NEVER invoked.}
- X\fwendmacronotes
- X\fwendmacro
- X
- X
- X\fwsecc{2.1.1}{Macro at level three}
- X\fwbeginmacro
- X\fwmacroname{Macro at level three}{4}\fwzero{}\fwequals \fwodef \fwbtx[Aardvark]fwetx=%
- X\fwcdef
- X\fwbeginmacronotes
- X\fwusedin{This macro is NEVER invoked.}
- X\fwendmacronotes
- X\fwendmacro
- X
- X
- X\fwsecd{2.1.1.1}{Macro at level four}
- X\fwbeginmacro
- X\fwmacroname{Macro at level four}{5}\fwzero{}\fwequals \fwodef \fwbtx[Teapot]fwetx=%
- X\fwcdef
- X\fwbeginmacronotes
- X\fwusedin{This macro is NEVER invoked.}
- X\fwendmacronotes
- X\fwendmacro
- X
- X
- X\fwsece{2.1.1.1.1}{Macro at level five}
- X\fwbeginmacro
- X\fwmacroname{Macro at level five}{6}\fwzero{}\fwequals \fwodef \fwbtx[Emu]fwetx=%
- X\fwcdef
- X\fwbeginmacronotes
- X\fwusedin{This macro is NEVER invoked.}
- X\fwendmacronotes
- X\fwendmacro
- X
- X
- X3. Test the table of contents directive.
- X
- X\fwtocstart{}
- X\fwtoca{1}{One}
- X\fwtocb{1.1}{Two}
- X\fwtocc{1.1.1}{Three}
- X\fwtocd{1.1.1.1}{Four}
- X\fwtoce{1.1.1.1.1}{Five}
- X\fwtoca{2}{Macro at level one}
- X\fwtocb{2.1}{Macro at level two}
- X\fwtocc{2.1.1}{Macro at level three}
- X\fwtocd{2.1.1.1}{Macro at level four}
- X\fwtoce{2.1.1.1.1}{Macro at level five}
- X\fwtocfinish{}
- X
- X
- X4. Test the newpage directive.
- X
- X\fwnewpage
- X
- X
- X5. Test the vskip directive.
- X\fwvskip{50}
- X
- X6. Test the title directive.
- X\fwcenterline{\fwfonttitle{This is a test Title}}
- X
- X
- X\bye
- X
- X
- X%*******************************************************************************
- X%* END OF AUTOMATICALLY GENERATED TEX FILE *
- X%*******************************************************************************
- X
- END_OF_FILE
- if test 17380 -ne `wc -c <'answers/wv02.tex'`; then
- echo shar: \"'answers/wv02.tex'\" unpacked with wrong size!
- fi
- # end of 'answers/wv02.tex'
- fi
- if test -f 'hackman/h_ch2.tex' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'hackman/h_ch2.tex'\"
- else
- echo shar: Extracting \"'hackman/h_ch2.tex'\" \(18854 characters\)
- sed "s/^X//" >'hackman/h_ch2.tex' <<'END_OF_FILE'
- X%==============================================================================%
- X% Start of Ch2.tex %
- X%==============================================================================%
- X%
- X% Copyright
- X% ---------
- X% Copyright (C) 1992 Ross N. Williams.
- X% This file contains a chapter of the FunnelWeb Hacker's Manual.
- X% See the main TeX file for this manual for further information.
- X%
- X%==============================================================================%
- X
- X\chapter{FunnelWeb Implementation}
- X\label{chapimplementation}\xx{FunnelWeb}{implementation}
- X
- X\section{Introduction}
- X
- This chapter contains notes on the actual C code that implements
- XFunnelWeb~V3. This chapter is rather patchy. It has acted mainly as
- a dumping ground for ideas that I bothered to write about during
- development.
- X
- X\section{History of FunnelWeb Implementations}
- X\xx{FunnelWeb}{history}\x{FunnelWeb version 1}\x{FunnelWeb version 2}%
- X\x{FunnelWeb version 3}
- X
- The first implementation of FunnelWeb (FunnelWeb~V1) was written in
- Ada\x{Ada}
- in December 1986. The project was initially canned as requiring too
- much time, but was resurrected when I decided to commit to
- Ada\paper{USDOD83} and
- realized that I needed a program to write to help me to learn Ada.
- XFunnelWeb~V1 was, in fact, my first Ada program. It took about one
- month to write.
- X
- XFunnelWeb~V1 was used intensively by myself to write Ada programs
- from January~1986 to July~1989 at which time
- I finished my Ph.D.\x{Ph.D.} and lost access to
- the VAX. During this time at least twenty thousand lines of code were generated
- using FunnelWeb. Hardly anyone but myself used
- XFunnelWeb.\xx{FunnelWeb}{past use}
- X
- After losing access to Ada and the Vax (and hence to FunnelWeb), I was forced
- back to programming the non-literate way. From time to time I found that I
- needed to use some of my old programs that I had written using Ada and
- XFunnelWeb. I knew that Ada would become available on more machines, but
- certainly FunnelWeb wouldn't. I recognised a strong need for a portable
- version of FunnelWeb written in~C but didn't have the time or energy
- to create one.
- X
- About this time (late 1989), David Hulse,\xn{David}{Hulse}
- at the time a student in
- Computer Science at the University of Adelaide,\xx{University}{Adelaide}
- volunteered to translate the 4000 line Ada version of FunnelWeb into~C.
- To my knowledge this translation process took about three weeks
- X(in December 1989). The result was called FunnelWeb~V2 and was
- formally signed into the public domain on 5~May 1992.
- X
- In general, David Hulse did a good job. However, the resultant code
- suffered from one or few serious defects, the most serious of which was
- a lack of portability.
- X
- Lack of portability of the C~code, combined with the need for a rather
- solid design review, combined with the need to
- strengthen the program to bring it up to production standard, resulted
- in my performing a complete reworking of the code. The C code was
- entirely, but incrementally, replaced or reformatted.
- The code was also strengthened and new features were added.
- This process took about two months (November and December 1991).
- A further two months (approx) were spent writing documentation, constructing
- a regression test suite, porting the program to different machines,
- and sorting out the legal issues involved in its release.
- X
- I would like to take this opportunity to record a debt of gratitude to
- David Hulse who translated FunnelWeb from Ada to~C. Although my
- reworking of his C~code obliterated most of his code,
- his translation was pivotal to the development process.
- Without his effort in moving from Ada to~C, I'm not sure that I
- would have mustered the energy and time to complete the process and
- bring FunnelWeb up to its current standard.
- X
- X\section{Why FunnelWeb Wasn't Used to Write Itself}
- X\xx{FunnelWeb}{writing itself}
- X
- After Knuth created the Web literate preprocessing system, he
- re-wrote it using Web and distributed the source code in Web source form.
- To allow the Web source code to be tangled by users not yet having a
- copy of Web, he also included the tangled Pascal code for the Tangler.
- X
- While this approach is heroic and serves to convey a commitment and
- a confidence in literate programming, it seemed to me that writing FunnelWeb
- in FunnelWeb would simply be asking for trouble.\xx{trouble}{asking for}
- XFor a start, it would be
- very hard to modify any feature of FunnelWeb that had been used to write
- XFunnelWeb, and the thought of what would happen if the working executable
- became inoperative for some reason does not bear thinking upon.
- X
- One million billion computer programs were written in the non-literate
- style before FunnelWeb was created. Why not one more?
- X
- X\section{Coding Style}
- X\xx{coding}{style}
- X
- Although FunnelWeb wasn't coded under any particular coding standard,
- it was coded in accordance with a fairly strict personal style of C
- which developed during the development of FunnelWeb. This style was
- subsequently embodied in a real C coding standard prepared for the
- South\x{South Australian Government Department of Lands}
- Australian Government
- Department of Lands.\footnote{The standard
- is currently unavailable, but is likely to be released or
- published eventually.} Unfortunately, FunnelWeb was not
- formally developed under the standard and so some holes remain in
- XFunnelWeb's coding style. This section aims to describe some of the more
- important aspects of the coding style.
- X
- X\thing{Portability:} This\x{portability}
- was a major goal of the FunnelWeb implementation.
- Two excellent books guided this move to portability.
- They were \paper{Rabinowitz90} (which deals with C code itself)
- and \paper{Horton90} (which deals with the portability of various library
- calls). Other works such as \paper{Kernighan88} and
- X\paper{ANSI} were also helpful.
- X
- X\thing{Identifiers:} \paper{Rabinowitz90}\x{identifier}{length}
- specifies that for
- wide portability, identifiers of block and file scope should be unique to
- eight characters, and identifiers of program scope should be unique to
- six characters. I have gone further in FunnelWeb and actually made these
- restrictions actual limits on identifier length.
- X
- Because names must be so short, a system of abbreviations was developed to
- organize the identifiers used within FunnelWeb. Each abbreviation consists
- of a letter pair. Here are \i{some} of the abbreviations
- used:\xx{identifier}{abbreviations}
- X
- X\begin{verbatim}
- bp - Body Part.
- cm - Compare. Used to prefix comparison routines that return [-1,0,1].
- dc - Document component.
- dm - Dump package.
- el - Element.
- eq - Equal. Used to prefix comparison routines that return a boolean.
- ex - Expression.
- f - Global files.
- ll - List of lists.
- ln - Line record.
- ls - List Package.
- lr - Lister package.
- ma - Macro.
- mc - Macro Call.
- mn - Macro Name.
- op - Options package.
- pr - Parser.
- ps - Position record.
- sc - Scrap record.
- sn - Section.
- tb - Table package.
- ty - Typesetter directive.
- wf - Write file package.
- wl - Write with EOL (misc.c).
- wr - Write (misc.c).
- X\end{verbatim}
- X
- X\thing{Pointers:} Variables or types denoting
- pointers\xx{pointers}{naming} start with \dqp{p\_}.
- X
- X\thing{Types:} Names denoting types end in \dqp{\_t}.
- Thus, a type for a pointer to a table would be named
- X\p{p\_tb\_t}.\xx{types}{naming}
- X
- X\thing{File names:} All files\xx{filenames}{length}
- used in FunnelWeb have file names that are
- from one to eight characters long and file extensions that are from one to
- three characters long. This ensures that the files can be portably moved
- to all kinds of machines, even MSDOS!\x{MSDOS}
- X
- X\section{Use of Memory}
- X\xx{use of}{memory}
- X
- XFunnelWeb is not a memory-stressed program. However, during its development,
- problems with the management of memory seemed to crop up again and again.
- This section documents some of these problems and the solutions adopted.
- X
- There are three places where memory can be obtained: the heap, the stack,
- and from static variables. The following three sections deal with each
- of these areas.
- X
- X\section{The Heap}
- X\xx{heap}{memory}
- X
- One of the great frustrations of being a user is to find that a computer
- program is complaining about lack of memory when one knows full well that
- one has allocated at least ten times as much memory to the program as it
- would ever need to do its job. The reason for such error messages usually
- has to do with the programmer setting a fixed \dq{reasonable} limit to
- a particular data structure and then locking it up into an array whose
- bound is specified by a constant. While the use of arrays can increase the
- speed of a program, it also means that the user cannot increase the capacity
- of the program without obtaining the source code and recompiling it,
- which is usually a daunting option.
- X
- The alternative is to use the heap for all data structures that can
- grow in proportion to the size of the user's input. This rule has been
- followed rigorously in FunnelWeb. This means that as memory spaces
- increase, users will be able to hand their version of FunnelWeb more
- memory without having to recompile it.
- X
- X\topicbreak
- X
- Some problems arose early on the Macintosh\x{Macintosh}
- in the use of the heap. It seems
- that some of the allocations I was attempting to make were failing for some
- obscure reason, possibly my fault. Whatever it was, it went away when I
- replaced direct calls to \p{malloc}\x{malloc}
- with calls to a mini package I wrote
- X(called \p{memory}) that allocated large chunks of memory and then doled out
- small pieces as required by the rest of the
- program.\xx{memory}{package}
- X
- Having a package to manage all the memory allocation had two other benefits.
- X
- XFirst, only one check was required in the entire program to see if memory
- had run out (in the memory package), and if that failed, the program could
- be brought to a screaming halt. This organization was far preferable to
- having each piece of code that needed to allocate memory having to check
- to see if \p{malloc} had failed.
- X
- Second, the decision to construct a mini-shell within FunnelWeb to
- support regression testing meant that FunnelWeb proper could be run
- many times in any given invocation of FunnelWeb. As a consequence it was
- necessary to make sure that there was no memory
- leakage\xx{memory}{leakage} between invocations
- of FunnelWeb proper. This was accomplished by reworking the memory package
- to operate a watermark system. The user of the package, when requesting
- memory, could request \dq{temporary} or \dq{permanent}. If permanent, the
- memory package forgot that it had allocated the memory. If temporary, the
- memory package places the allocated block on a list. There was then a
- function in the memory package that could be called to deallocate all the
- temporary memory. Thus, so long as all requests for memory within FunnelWeb
- proper were for temporary memory, and that memory was freed at the end of
- every run, one could be sure that there was no memory leakage.
- X
- X\section{The Stack}
- X\xx{stack}{memory}\xx{stack}{size}
- X
- XFor a while during the development of FunnelWeb a particularly nasty bug
- proved extremely hard to find. The symptom was that FunnelWeb would crash,
- sometimes at random, but more often upon entering a particular function.
- In the end about a day of specific debugging was required before the problem
- was tracked down to a stack problem. It turned out that somehow
- X(either the fault of the Macintosh or the THINK~C language system), only
- X6K was being allocated for stack space!!!!!!!
- X
- This experience led me immediately to go through the entire program and
- eliminate (or remove to the heap) any automatic variable declarations that
- used more than one hundred or so bytes.
- X
- The lesson is clearly that C~programs that use more than a few thousand bytes of
- stack space are risking their portability. All large data structures should be
- placed in the heap.
- X
- X\section{Static Variables}
- X\xx{memory}{static}\xx{static}{variables}
- X
- Static variables also proved a problem on the Macintosh.
- It turns out that
- the Macintosh\x{Macintosh} THINK~C compiler\xx{ThinkC}{compiler}
- does not allow more than 32K of statics
- X\i{in the entire program}. For a while this restriction was
- a serious threat to the program as it was discovered that constant strings
- were included in this total! However, some searching revealed a compiler
- option that removed the strings from the static category.
- X
- Nevertheless, the 32K limit is rather severe. Again, it seems that for
- portability reasons, C~programs that use a lot of static variables are risking
- their portability. As a result, the FunnelWeb code avoids static variables
- where possible in favour of the heap.
- X
- X\section{Implementing Text Indentation}
- X\xx{text}{indentation}
- X
- At one point during the development of FunnelWeb, text indentation was
- fully implemented. However, it was subsequently removed because it was
- considered a dangerous feature. This section records the way in which
- text indentation was implemented so that if the feature ever has to be put
- back, this technique can be used again.
- X
- X
- X1. Create a new field in the \p{sc\_t} record call \p{sc\_postn}.
- X
- X\begin{verbatim}
- X char *sc_postn; /* Pointer in the range [sc_first,sc_last+1]. */
- X /* It is the minimum possible value of sc_postn for */
- X /* which EOL does not appear in *sc_postn..*sc_last. */
- X /* i.e. Points to the byte following the first EOL in */
- X /* the scrap or sc_first if EOL does not appear. */
- X\end{verbatim}
- X
- X2. Modify the scanner so that it generates this field.
- Sendtext should be modified so that
- it accepts an argument for the \p{p\_postn} value.
- X
- X\begin{verbatim}
- LOCAL void sendtext P_((p_ps_t,char *,char *,char *,bool));
- LOCAL void sendtext(p_tkps,p_first,p_last,p_postn,is_white)
- X/* Appends a text token to the end of the token list. */
- X/* IN: p_ps is a pointer to a position structure giving the position of the */
- X/* first character of the token. */
- X/* IN: p_first and p_last point to the first and last byte of the text scrap. */
- X/* IN: p_postn has the same definition as sc_postn (see fwdata.h). */
- X/* IN: is_white should be set to TRUE iff scrap is entirely whitespace. */
- p_ps_t p_tkps;
- char *p_first;
- char *p_last;
- char *p_postn;
- bool is_white;
- X{
- X tk_t token;
- X
- X /* Empty text scraps should never be generated. */
- X assert(p_first<=p_last,"sendtext: Text scrap bounds are bad.");
- X
- X /* If ch=EOL then we should be scanning more text, not shipping it! */
- X assert(ch!=EOL,"senttext: Shipping text while still more to scan.");
- X
- X /* Check that p_postn is in range. See definition in fwdata.h. */
- X assert(p_first<=p_postn && p_postn<=p_last+1,
- X "sendtext: p_postn is out of range.");
- X
- X /* Debug: Check the p_postn field using a brute force check. */
- X {
- X char *i,*j;
- X j=p_first;
- X for (i=p_first;i<=p_last;i++)
- X if (*i==EOL)
- X j=i+1;
- X assert(j==p_postn,"sendtext: sc_postn field is incorrect.");
- X }
- X
- X /* Load the text token. */
- X token.tk_kind = TK_TEXT;
- X ASSIGN(token.tk_ps,*p_tkps);
- X token.tk_sc.sc_first = p_first;
- X token.tk_sc.sc_last = p_last;
- X token.tk_sc.sc_postn = p_postn;
- X token.tk_white = is_white;
- X token.tk_parno = 0;
- X ls_add(token_list,PV &token);
- X}
- X\end{verbatim}
- X
- Then all the calls to sendtext have to be changed:
- X
- X\begin{verbatim}
- X/* @ instructs FunnelWeb to replace the special construct with the */
- X/* special character. Luckily one appears just before the @ !! */
- X/* Note: FALSE is OK because space is not a legal specialch. */
- X/* Note: Setting parameter p_postn to p_ch-1 is OK as EOL is not a */
- X/* legal specialch. */
- sendtext(&ps_spec,p_ch-1,p_ch-1,p_ch-1,FALSE);
- break;
- X
- X/* + instructs FunnelWeb to insert an EOL. We can't look to the end of */
- X/* the previous line to find an EOL as this might be the first line. */
- X/* Running ahead to the end of the line is expensive, and having the */
- X/* liner mini-package maintain a variable for it would be extra */
- X/* housekeeping. Instead of all this, we just point to a static. */
- X{CONST static char stateol = EOL;
- X sendtext(&ps_spec,&stateol,&stateol,(&stateol)+1,TRUE);}
- break;
- X
- X/* If we hit something that ends a text token */
- X/* then we can transmit a white text token. */
- if (ch==specialch || ch==EOFCH)
- X {sendtext(&ps_start,p_first,p_ch-1,MAX(p_sol,p_first),TRUE); return;}
- X
- X/* Otherwise we have some more (non-white) text to scan. */
- X/* We can then send a non-white text token. */
- while (ch!=specialch && ch!=EOFCH)
- X NEXTCH;
- sendtext(&ps_start,p_first,p_ch-1,MAX(p_sol,p_first),FALSE);
- X\end{verbatim}
- X
- The dump code needs to be changed too!
- X
- X\begin{verbatim}
- X wf_str(p_wf,"\"");
- assert(token->tk_sc.sc_first !=NULL,"dm_tkls: NULL ptr1.");
- assert(token->tk_sc.sc_last !=NULL,"dm_tkls: NULL ptr2.");
- for (i=token->tk_sc.sc_first; i<=token->tk_sc.sc_last; i++)
- X {
- X if (i==token->tk_sc.sc_postn)
- X wf_str(p_wf,"<postn>");
- X if (*i=='\n')
- X wf_wl(p_wf,"");
- X else
- X dm_byte(p_wf,*((ubyte_ *) i));
- X }
- if (i==token->tk_sc.sc_postn)
- X wf_str(p_wf,"<postn>");
- wf_str(p_wf,"\"");
- X}
- X\end{verbatim}
- X
- X3. Over in the Tangle module, create a massive array of pointers to scraps
- to be used as a stack. Maintain pointers into the stack called \p{current} and
- X\i{base} (similar to the blank indentation variables). Implement the following:
- X
- X\begin{itemize}
- X
- X\item To write out a scrap, scan it byte by byte. Output each byte. When
- you hit an EOL, pop the stack back to \p{base}. Then write out an EOL
- followed by the stack contents but writing each scrap only from \p{postn} to
- end end of each scrap.
- When you have finished the new scrap, push it on the stack.
- X
- X\item When you hit a new macro to expand, save \p{base}. Restore it later.
- X
- X\end{itemize}
- X
- The \p{postn} field solves the big problem of
- how to cope with something like this:
- X
- X\begin{verbatim}
- The rain in Spain
- falls mainly @<on the plain@>
- X\end{verbatim}
- X
- The trouble is that we want to text indent the lines in
- X\p{@<on the plain@>} with
- just \dqp{falls mainly~}. However, this string is only part of a scrap. The
- solution is to get the scanner to record, in the \p{postn} field of each scrap,
- the position of the first byte with a EOL-free run to the end of the scrap.
- X
- This scheme is very efficient because all we are doing is pushing and popping
- pointers to scraps on a stack array. The main disadvantage is that the
- array must necessarily be finite and would impose a limit on the depth
- of indentation nesting (not a big problem).
- X
- X%==============================================================================%
- X% Start of Ch2.tex %
- X%==============================================================================%
- END_OF_FILE
- if test 18854 -ne `wc -c <'hackman/h_ch2.tex'`; then
- echo shar: \"'hackman/h_ch2.tex'\" unpacked with wrong size!
- fi
- # end of 'hackman/h_ch2.tex'
- fi
- if test -f 'hackman/h_ch4.tex' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'hackman/h_ch4.tex'\"
- else
- echo shar: Extracting \"'hackman/h_ch4.tex'\" \(18004 characters\)
- sed "s/^X//" >'hackman/h_ch4.tex' <<'END_OF_FILE'
- X%==============================================================================%
- X% Start of Ch4.tex %
- X%==============================================================================%
- X%
- X% Copyright
- X% ---------
- X% Copyright (C) 1992 Ross N. Williams.
- X% This file contains a chapter of the FunnelWeb Hacker's Manual.
- X% See the main TeX file for this manual for further information.
- X%
- X%==============================================================================%
- X
- X\chapter{FunnelWeb Future}
- X\label{chapfuture}\xx{FunnelWeb}{future}
- X
- Previous chapters have explained the design of FunnelWeb and given reasons
- for why it is the way it is. This chapter goes through each of the
- aspects of FunnelWeb, and explores their problems, how they can be solved,
- and lists opportunities for improvement.
- X
- X\section{Documentation}
- X\x{documentation}
- X
- X\thing{An official example:} A official example program written using
- XFunnelWeb should be constructed and made available.\xx{official}{example}
- X
- X\thing{Index program:} In order to typeset the documentation, a portable
- index sorting program is required. One should be written and added to the
- distribution kit.\xx{index}{program} Perhaps this could be the official
- example!
- X
- X\section{Command Line Interface}
- X\xx{command}{interface}
- X
- X\thing{Buffer length:} Currently the FunnelWeb shell uses the
- X\p{COMLINE\_MAX} constant to size its internal command line buffers.
- This is untenable. The maximum length of a shell command line should
- not be machine dependent.
- X
- X\thing{Antiquated Features:} As the FunnelWeb language develops, it is likely
- that some changes will have to be made that will render one or more
- language constructs obsolete. When this happens, it may be necessary to
- add a command line option that has the power to turn on and off warnings or
- errors flagging antiquated features.\xx{antiquated}{features}
- X
- X\section{Shell Interpreter}
- X\xx{shell}{interpreter}\xx{command}{interpreter}
- X
- X\thing{SETALL command:} When writing FunnelWeb scripts, it is sometimes
- desirable to set \i{all} of FunnelWeb's options\x{options}
- to some particular value
- so that the script is not vulnerable to changes in FunnelWeb's default
- values which might occur from time to time. To this end, it may be worth
- creating a \dqp{SETALL} command that is identical to the \dqp{SET} command
- except that it will generate an error if the value of an option is not
- specified explicitly.\xx{setall}{command}
- X
- X\thing{Recursion test:} A test should be added to test for recursive
- invocation in a shellscript.\xx{recursion}{test}
- X
- X\thing{Diagnostic counting:} The code for counting diagnostics in the
- script interpreter is rather messy and perhaps even buggy. It should be
- cleaned up and commented.\xx{diagnostic}{counting}
- X
- X\thing{Argument counting:} In the \p{command.c} module, there is a variable
- that counts the arguments to a command. Currently it takes the value of
- the number of parameters including the command verb. This has turned out
- to make the code less readable. It should be changed to be the number of
- arguments to the command verb.
- X
- X\thing{Make facility:} It may be worth building some sort of make facility
- into the script language so as to support machines such as the Macintosh
- that do not already have this facility.\x{make}
- X
- X\thing{Signature file:} One problem with using FunnelWeb in conjunction with
- an external \p{Make} facility is that a user might change a FunnelWeb source
- file without making changes that will affect the files that it generates.
- If FunnelWeb is then run and the \dqp{+D} option is on, then the output
- files will be deleted (to avoid further \p{Make} propagations).
- If \p{Make} then has a production linking the \p{.fw} file to its output
- files, then it may conclude that the output files are still out of date.
- To solve the problem, FunnelWeb could be changed to write a \p{.sig} file
- whenever it processes a \p{.fw} file. The \p{Make} production could then
- be wired up to link
- the \p{.fw} file to the \p{.sig} file instead of to the output
- files.\xx{signature}{file}
- X
- X\section{Language Design}
- X\xx{language}{design}
- X
- Some proposed changes to FunnelWeb do not correspond to
- any particular component of FunnelWeb
- and are really to do with the design of the input language.
- X
- X\thing{Output or file?:} The \dqp{@O} special sequence for defining an output
- file is somewhat non-mnemonic and can be confused with zero (\dqp{0}). Perhaps
- it should be replaced by the \dqp{@F} sequence.
- X
- X\thing{Syntax of section names:} Currently section names use
- the same syntax as macro names. For example \dqp{@<Sloth@>}. It can be
- argued that angle brackets should be reserved only for macro names and that
- some other syntax should be found for delimiting section names. This is not
- a clear issue. It could also be argued that they are both names, and that
- because sections can inherit their names from the macros they contain, that
- the names are of the same \dq{type}.\xx{section}{syntax}
- X
- X\thing{One macro per section:} One particular style of using FunnelWeb is
- to have at most one macro definition per section. It may be worth adding
- a pragma that instructs FunnelWeb to enforce this.
- X
- X\thing{Should @\{ suppress EOL?:} When defining a macro in FunnelWeb, it
- seems to be rule rather than the exception that the
- X\dqp{@\{} be followed by \dqp{@-}. This suppresses the EOL on the definition
- line, allowing the first line of the macro to be placed immediately
- above and in line with the other
- lines without introducing an EOL at the start of the macro text.
- One option is to introduce a pragma to determine whether to suppress EOLs
- following \dqp{@\{}.
- X
- X\thing{Pragma syntax:} It is not clear how \dq{loose} the syntax of pragmas
- should be. Perhaps they should be case insensitive.\xx{pragma}{syntax}
- X
- X\thing{Conditionals:} Depending on demand, it may be worth reintroducing
- some sort of conditional feature into FunnelWeb. However, it would have to
- be very simple to compete with the various ways in which conditionals
- can already be fudged within FunnelWeb as it stands.\x{conditionals}
- X
- X\thing{File markers:} It might be worth modifying the language so that
- a special syntactical marker is required at the start and end of files.
- This will assist in detecting truncations and other
- corruptions.\xx{file}{markers}
- X
- X\thing{Formal parameter lists:} It might be worth changing over to a
- syntax for formal parameter lists that does not require the \p{@(} and
- X\p{@)}. However, they could be retained as optional for backward
- compatibility.\xx{parameter list}{formal}
- X
- X\section{Scanner/Mapper}
- X\x{scanner}\x{mapper}
- X
- X\thing{All non-contiguous mappings:} Currently FunnelWeb requires that all
- input files be mapped into a contiguous lump of memory. This caused problems
- for two reasons. First, to do this, one has to allocate the memory first,
- and to do that, you have to know how long the file is, and it turns out that
- finding out the length of a file in a portable manner is very inefficient.
- Second, although IBM PC compatibles may have megabytes of memory, it is
- segmented into blocks of at most 64K. This means that FunnelWeb currently
- cannot read a file longer than 64K on a PC.\xx{contiguous}{memory}
- X
- These problems could be avoided if the mapper and scanner were reorganized to
- allow input files to be read in and stored as a linked list of chunks of text
- rather than a contiguous block.
- X
- X\thing{EOL is unspecifiable:} FunnelWeb uses ASCII character decimal ten (10)
- internally to represent logical end-of-line and is currently organized so that
- if one of these is inserted into the text by the user using a
- X\dqp{@\circumflex{}D(10)}, it will be written out as a logical end of line,
- rather than as a single ASCII character 10. This should be
- fixed.\xx{representation}{EOL}
- X
- X\thing{Allow mnemonics for unprintables:} FunnelWeb allows users to insert
- unprintable characters into the output using the \dqp{@\circumflex{}D(ddd)}
- special sequence. Perhaps it would be changed so that it understands ASCII
- standard mnemonics such as \dqp{LF} as well as ASCII
- numbers.\xx{ASCII}{mnemonics}
- X
- X\thing{Version pragma:} A \dqp{version} pragma should be added that allows
- the user to specify in the input file the version of FunnelWeb that was
- around when the input file was created. At a later date, such a construct
- would be very useful for determining how an input file should be updated
- if the FunnelWeb language has changed between
- versions.\xx{version}{pragma}
- X
- X\section{Parser}
- X\x{parser}
- X
- There are no proposals to change the parser except as a consequence of
- other proposals.
- X
- X\section{Analyser}
- X\x{analyser}
- X
- X\thing{Recursion detection:} Currently the FunnelWeb analyser flags, with
- an error, all macros with an infinite expansion. This would be best
- changed to flagging all macros that are directly or indirectly recursive.
- To do this, Tarjan's algorithm\paper{Tarjan72}\xn{Robert Endre}{Tarjan}
- for the detection of strong components should
- be installed.\xx{recursion}{detection}
- X
- X\thing{Once only macros:} By default FunnelWeb prevents a macro from being
- called more than once unless it has a \dqp{@M} associated with it. However,
- XFunnelWeb does allow a macro that calls such a macro to be called more
- than once. Perhaps this \dq{loophole} should be plugged somehow.
- X
- X
- X\section{Tangle}
- X\x{tangle}
- X
- The Tangler is one of the cleanest components of FunnelWeb, as basically all it
- has to do is expand some very well-defined macros.
- X
- X\thing{Text indentation:} Currently FunnelWeb supports \i{no indentation}
- and \i{blank indentation}. A third form could be added if it was considered
- necessary. \i{Text indentation} is the same as \i{blank indentation} except
- that instead of indenting with blanks, FunnelWeb would indent with the
- text to the left of the called macro. This facility could be useful for
- commenting out large bodies of text in languages that do not have
- multi-line comments (e.g. Ada). A discussion of the pros and cons of this
- form of indentation appears earlier.\xx{text}{indentation}
- X
- X\section{Weave}
- X\x{weave}
- X
- Perhaps FunnelWeb's weakest aspect is its typesetting facility.
- X
- X
- X\thing{Align table of contents:} When FunnelWeb generates a table of contents,
- the section numbers are not quite aligned with the start of the controlling
- heading above them.\x{table of contents}
- X
- X\thing{Typesetting strength:} It should be possible to specify the
- level of typesetting strength for headings so that short documents do not
- look overdone when typeset. A new pragma would be good for
- this.\xx{strength}{typesetting}
- X
- X\thing{Typeset a portion:} Sometimes it is desirable to typeset just a
- portion of a program. A command line option could be added to do
- this. The option could accept as its argument, a string containing a list
- of section numbers or heading names.
- X
- X\thing{Generic typesetter option:} In addition to building in a number
- of different versions of Weave, one for each popular typesetter, it would be
- possible to add a special generic format where the typeset output is
- expressed in terms of \i{FunnelWeb macros}. The user could then specify
- macro definitions for a non-supported typesetter and run the output
- through FunnelWeb Tangle to get a typeset file in a format suitable for the
- unsupported typesetter.\xx{typesetter}{generic}
- X
- X\thing{Suppression of include files:} It should be possible to specify
- in the input file that particular included files not appear in the
- typeset output. Currently, the fact that an inclusion has occurred is
- not even represented in the typeset output. Suppression of inclusions
- is particularly necessary where a library of macros has been included
- at the top of each of a group of source files.\xx{include file}{suppression}
- X
- X\thing{Cross reference of identifiers:} WEB provides a list of identifiers
- and a list of all the definitions in which they are used. A similar
- feature could be added to FunnelWeb.\xx{cross}{references}
- X
- X\thing{Support for non-printables:} Currently FunnelWeb does not provide
- support for typesetting the special \dqp{@\circumflex(num)} sequences.
- This should be added.
- X
- X\thing{Support for @+ sequences:} Currently Weave does not see \dqp{@+}
- sequences as such. Instead it perceives them as ordinary EOLs. However,
- there are arguments for typesetting them specially.
- X
- X\thing{Typeset text in macro bodies:} One of the much-loved features
- of WEB is the way that it allows the user to switch recursively between
- document and program formats. FunnelWeb does not allow this, but
- should. In FunnelWeb, the delimiters \dqp{@\{} and \dqp{@\}} are already
- used consistently to delimit macro text. The \dqp{@[} and \dqp{@]} sequences
- have been reserved for the delimitation of documentation text.
- X
- X\thing{Non-tt typesetting:} The current version of FunnelWeb sets all its
- macro text in \p{tt font}. This is both a blessing and a curse. It is a
- blessing because it connects the reader directly to the code, with no
- complicated intermediary. It is a curse because it looks ugly compared to
- the beautifully typeset programs produced by other literate programming
- tools.
- X
- The difficulty with adding such beautiful typesetting is that it is
- necessarily language-specific. Keywords and syntax differ from language
- to language and it would not be easy to come up with a set of language
- independent rules.
- X
- One approach is to write a set of Weave back-ends, one for each language.
- Another approach is to \i{generate} back ends. This is the approach
- taken in the \i{Spider} system\paper{Ramsey89}.\x{spider}
- In the \i{Spider} system,
- the programmer writes production rules for converting lexical components
- of the program text into typesetter instructions. The \i{Spider} program
- reads these rules and generates a new version of WEB suited for the target
- language.
- X
- XFor FunnelWeb a slightly different system is proposed in which Spider-like
- rules appear in the input file and are used directly by Weave to perform the
- typesetting. An intermediate abstract typesetting language could be used
- so that the productions can be made language specific, but not typesetter
- specific.
- X
- X\section{Lister}
- X\x{lister}
- X
- X\thing{Glue factor:} A glue factor could be added that determines how many
- lines can be in between two diagnostics in the listing before the two
- groups of lines are joined together in the listing with no intervening
- ellipsis.\xx{glue}{factor}
- X
- X\section{Diagnostics}
- X\x{diagnostics}
- X
- X\thing{Advisory information:} Some of FunnelWeb's diagnostics provide
- a detailed explanatory paragraph. While this information might be useful the
- first time, it has the capacity to clog up a listing file if the user has
- made the same error many times. To solve this problem, FunnelWeb could be
- modified so that such explanations are only displayed the first time the
- error occurs.
- X
- X\thing{Abort after n errors:} A facility could be added to prevent
- XFunnelWeb's scanning, parsing, and analysing phases from continuing if
- a certain number of errors have already been issued.
- X
- X
- X\section{Speed}
- X\x{speed}\x{efficiency}
- X
- X\thing{Measurement of speed:} Although FunnelWeb can generate a breakdown
- of where it is spending its time, it does not give a final rating in
- lines per minute. This should be added.
- X
- X\thing{Find the hot spots:} Although FunnelWeb has been designed to allow
- high speed, not much effort has so far been made to make it fast. This should
- be done.
- X
- X\thing{Change some declarations:} FunnelWeb is full of variable declarations
- where the variables are wider than they need be. Replacing these might speed
- it up.
- X
- X\section{Correctness}
- X\x{correctness}
- X
- X\thing{Bounds analysis:} Not much effort has gone into the design of
- XFunnelWeb's input boundaries. An analysis should be made of FunnelWeb's
- behaviour when the following quantities are stretched:
- X
- X\begin{itemize}
- X\item Input line length.
- X\item Input file size.
- X\item Number of macros.
- X\item Length of macro.
- X\end{itemize}
- X
- In particular, FunnelWeb's behaviour at 32K and 64K boundaries should be
- observed.
- X
- X\thing{Stack detection:} Macintosh THINK-C provides just 6K of memory for
- the stack. It might be worth adding checks to make sure that the stack is
- not being blown.
- X
- X\section{Test Suite}
- X\xx{test}{suite}
- X
- The following tests should be added to the test suite:
- X
- X\begin{verbatim}
- Lister
- X------
- X LR01: Test with a full listing with no diagnostics.
- X LR02: Test with a full listing with diagnostics.
- X LR03: Test with an abbreviated listing with no diagnostics.
- X LR04: Test with an abbreviated listing with diagnostics.
- X LR05: Test error context system with nearby diagnostics.
- X
- Boundary Cases
- X--------------
- Static analysis might preclude the need for most of these tests.
- X BC01: Test what happens when memory runs out.
- X BC02: Test on a file with a single line of a megabyte.
- X BC03: Test on a file of a megabyte of EOLs.
- X BC04: Generate an output file with an extremely long line.
- X BC05: Generate an output file with one million lines.
- X BC06: Test on a file with very many macros.
- X
- General
- X-------
- X GN01: A large legal input file exercising as many features as possible.
- X 1. Test listing file.
- X 2. Test output files.
- X 3. Test typeset file.
- X GN... A selection of ten real-life FunnelWeb files.
- X\end{verbatim}
- X
- X\section{Machine-Specific Changes}
- X
- X\thing{Icon for the Macintosh:} Currently no icon is supplied for the
- Macintosh version of FunnelWeb. An icon depicting a spider or a funnelled
- web of some kind would seem appropriate.
- X
- X\section{Summary}
- X
- This chapter has describes some of the problems with FunnelWeb and some of the
- opportunities that exist for improving it. The direction and speed in which
- XFunnelWeb will develop will depend largely on user feedback. If you have any
- strong feelings on where FunnelWeb should go, please email them to
- Ross Williams (\p{ross@spam.adelaide.edu.au}).
- X
- X
- X%==============================================================================%
- X% Start of Ch4.tex %
- X%==============================================================================%
- END_OF_FILE
- if test 18004 -ne `wc -c <'hackman/h_ch4.tex'`; then
- echo shar: \"'hackman/h_ch4.tex'\" unpacked with wrong size!
- fi
- # end of 'hackman/h_ch4.tex'
- fi
- if test -f 'sources/help_gnu.txt' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sources/help_gnu.txt'\"
- else
- echo shar: Extracting \"'sources/help_gnu.txt'\" \(17977 characters\)
- sed "s/^X//" >'sources/help_gnu.txt' <<'END_OF_FILE'
- X GNU GENERAL PUBLIC LICENSE
- X Version 2, June 1991
- X
- X Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- X 675 Mass Ave, Cambridge, MA 02139, USA
- X Everyone is permitted to copy and distribute verbatim copies
- X of this license document, but changing it is not allowed.
- X
- X Preamble
- X
- X The licenses for most software are designed to take away your
- freedom to share and change it. By contrast, the GNU General Public
- License is intended to guarantee your freedom to share and change free
- software--to make sure the software is free for all its users. This
- General Public License applies to most of the Free Software
- XFoundation's software and to any other program whose authors commit to
- using it. (Some other Free Software Foundation software is covered by
- the GNU Library General Public License instead.) You can apply it to
- your programs, too.
- X
- X When we speak of free software, we are referring to freedom, not
- price. Our General Public Licenses are designed to make sure that you
- have the freedom to distribute copies of free software (and charge for
- this service if you wish), that you receive source code or can get it
- if you want it, that you can change the software or use pieces of it
- in new free programs; and that you know you can do these things.
- X
- X To protect your rights, we need to make restrictions that forbid
- anyone to deny you these rights or to ask you to surrender the rights.
- These restrictions translate to certain responsibilities for you if you
- distribute copies of the software, or if you modify it.
- X
- X For example, if you distribute copies of such a program, whether
- gratis or for a fee, you must give the recipients all the rights that
- you have. You must make sure that they, too, receive or can get the
- source code. And you must show them these terms so they know their
- rights.
- X
- X We protect your rights with two steps: (1) copyright the software, and
- X(2) offer you this license which gives you legal permission to copy,
- distribute and/or modify the software.
- X
- X Also, for each author's protection and ours, we want to make certain
- that everyone understands that there is no warranty for this free
- software. If the software is modified by someone else and passed on, we
- want its recipients to know that what they have is not the original, so
- that any problems introduced by others will not reflect on the original
- authors' reputations.
- X
- X Finally, any free program is threatened constantly by software
- patents. We wish to avoid the danger that redistributors of a free
- program will individually obtain patent licenses, in effect making the
- program proprietary. To prevent this, we have made it clear that any
- patent must be licensed for everyone's free use or not licensed at all.
- X
- X The precise terms and conditions for copying, distribution and
- modification follow.
- X
- X GNU GENERAL PUBLIC LICENSE
- X TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
- X
- X 0. This License applies to any program or other work which contains
- a notice placed by the copyright holder saying it may be distributed
- under the terms of this General Public License. The "Program", below,
- refers to any such program or work, and a "work based on the Program"
- means either the Program or any derivative work under copyright law:
- that is to say, a work containing the Program or a portion of it,
- either verbatim or with modifications and/or translated into another
- language. (Hereinafter, translation is included without limitation in
- the term "modification".) Each licensee is addressed as "you".
- X
- Activities other than copying, distribution and modification are not
- covered by this License; they are outside its scope. The act of
- running the Program is not restricted, and the output from the Program
- is covered only if its contents constitute a work based on the
- Program (independent of having been made by running the Program).
- Whether that is true depends on what the Program does.
- X
- X 1. You may copy and distribute verbatim copies of the Program's
- source code as you receive it, in any medium, provided that you
- conspicuously and appropriately publish on each copy an appropriate
- copyright notice and disclaimer of warranty; keep intact all the
- notices that refer to this License and to the absence of any warranty;
- and give any other recipients of the Program a copy of this License
- along with the Program.
- X
- You may charge a fee for the physical act of transferring a copy, and
- you may at your option offer warranty protection in exchange for a fee.
- X
- X 2. You may modify your copy or copies of the Program or any portion
- of it, thus forming a work based on the Program, and copy and
- distribute such modifications or work under the terms of Section 1
- above, provided that you also meet all of these conditions:
- X
- X a) You must cause the modified files to carry prominent notices
- X stating that you changed the files and the date of any change.
- X
- X b) You must cause any work that you distribute or publish, that in
- X whole or in part contains or is derived from the Program or any
- X part thereof, to be licensed as a whole at no charge to all third
- X parties under the terms of this License.
- X
- X c) If the modified program normally reads commands interactively
- X when run, you must cause it, when started running for such
- X interactive use in the most ordinary way, to print or display an
- X announcement including an appropriate copyright notice and a
- X notice that there is no warranty (or else, saying that you provide
- X a warranty) and that users may redistribute the program under
- X these conditions, and telling the user how to view a copy of this
- X License. (Exception: if the Program itself is interactive but
- X does not normally print such an announcement, your work based on
- X the Program is not required to print an announcement.)
- X
- These requirements apply to the modified work as a whole. If
- identifiable sections of that work are not derived from the Program,
- and can be reasonably considered independent and separate works in
- themselves, then this License, and its terms, do not apply to those
- sections when you distribute them as separate works. But when you
- distribute the same sections as part of a whole which is a work based
- on the Program, the distribution of the whole must be on the terms of
- this License, whose permissions for other licensees extend to the
- entire whole, and thus to each and every part regardless of who wrote it.
- X
- Thus, it is not the intent of this section to claim rights or contest
- your rights to work written entirely by you; rather, the intent is to
- exercise the right to control the distribution of derivative or
- collective works based on the Program.
- X
- In addition, mere aggregation of another work not based on the Program
- with the Program (or with a work based on the Program) on a volume of
- a storage or distribution medium does not bring the other work under
- the scope of this License.
- X
- X 3. You may copy and distribute the Program (or a work based on it,
- under Section 2) in object code or executable form under the terms of
- Sections 1 and 2 above provided that you also do one of the following:
- X
- X a) Accompany it with the complete corresponding machine-readable
- X source code, which must be distributed under the terms of Sections
- X 1 and 2 above on a medium customarily used for software interchange; or,
- X
- X b) Accompany it with a written offer, valid for at least three
- X years, to give any third party, for a charge no more than your
- X cost of physically performing source distribution, a complete
- X machine-readable copy of the corresponding source code, to be
- X distributed under the terms of Sections 1 and 2 above on a medium
- X customarily used for software interchange; or,
- X
- X c) Accompany it with the information you received as to the offer
- X to distribute corresponding source code. (This alternative is
- X allowed only for noncommercial distribution and only if you
- X received the program in object code or executable form with such
- X an offer, in accord with Subsection b above.)
- X
- The source code for a work means the preferred form of the work for
- making modifications to it. For an executable work, complete source
- code means all the source code for all modules it contains, plus any
- associated interface definition files, plus the scripts used to
- control compilation and installation of the executable. However, as a
- special exception, the source code distributed need not include
- anything that is normally distributed (in either source or binary
- form) with the major components (compiler, kernel, and so on) of the
- operating system on which the executable runs, unless that component
- itself accompanies the executable.
- X
- If distribution of executable or object code is made by offering
- access to copy from a designated place, then offering equivalent
- access to copy the source code from the same place counts as
- distribution of the source code, even though third parties are not
- compelled to copy the source along with the object code.
- X
- X 4. You may not copy, modify, sublicense, or distribute the Program
- except as expressly provided under this License. Any attempt
- otherwise to copy, modify, sublicense or distribute the Program is
- void, and will automatically terminate your rights under this License.
- However, parties who have received copies, or rights, from you under
- this License will not have their licenses terminated so long as such
- parties remain in full compliance.
- X
- X 5. You are not required to accept this License, since you have not
- signed it. However, nothing else grants you permission to modify or
- distribute the Program or its derivative works. These actions are
- prohibited by law if you do not accept this License. Therefore, by
- modifying or distributing the Program (or any work based on the
- Program), you indicate your acceptance of this License to do so, and
- all its terms and conditions for copying, distributing or modifying
- the Program or works based on it.
- X
- X 6. Each time you redistribute the Program (or any work based on the
- Program), the recipient automatically receives a license from the
- original licensor to copy, distribute or modify the Program subject to
- these terms and conditions. You may not impose any further
- restrictions on the recipients' exercise of the rights granted herein.
- You are not responsible for enforcing compliance by third parties to
- this License.
- X
- X 7. If, as a consequence of a court judgment or allegation of patent
- infringement or for any other reason (not limited to patent issues),
- conditions are imposed on you (whether by court order, agreement or
- otherwise) that contradict the conditions of this License, they do not
- excuse you from the conditions of this License. If you cannot
- distribute so as to satisfy simultaneously your obligations under this
- License and any other pertinent obligations, then as a consequence you
- may not distribute the Program at all. For example, if a patent
- license would not permit royalty-free redistribution of the Program by
- all those who receive copies directly or indirectly through you, then
- the only way you could satisfy both it and this License would be to
- refrain entirely from distribution of the Program.
- X
- If any portion of this section is held invalid or unenforceable under
- any particular circumstance, the balance of the section is intended to
- apply and the section as a whole is intended to apply in other
- circumstances.
- X
- It is not the purpose of this section to induce you to infringe any
- patents or other property right claims or to contest validity of any
- such claims; this section has the sole purpose of protecting the
- integrity of the free software distribution system, which is
- implemented by public license practices. Many people have made
- generous contributions to the wide range of software distributed
- through that system in reliance on consistent application of that
- system; it is up to the author/donor to decide if he or she is willing
- to distribute software through any other system and a licensee cannot
- impose that choice.
- X
- This section is intended to make thoroughly clear what is believed to
- be a consequence of the rest of this License.
- X
- X 8. If the distribution and/or use of the Program is restricted in
- certain countries either by patents or by copyrighted interfaces, the
- original copyright holder who places the Program under this License
- may add an explicit geographical distribution limitation excluding
- those countries, so that distribution is permitted only in or among
- countries not thus excluded. In such case, this License incorporates
- the limitation as if written in the body of this License.
- X
- X 9. The Free Software Foundation may publish revised and/or new versions
- of the General Public License from time to time. Such new versions will
- be similar in spirit to the present version, but may differ in detail to
- address new problems or concerns.
- X
- XEach version is given a distinguishing version number. If the Program
- specifies a version number of this License which applies to it and "any
- later version", you have the option of following the terms and conditions
- either of that version or of any later version published by the Free
- Software Foundation. If the Program does not specify a version number of
- this License, you may choose any version ever published by the Free Software
- XFoundation.
- X
- X 10. If you wish to incorporate parts of the Program into other free
- programs whose distribution conditions are different, write to the author
- to ask for permission. For software which is copyrighted by the Free
- Software Foundation, write to the Free Software Foundation; we sometimes
- make exceptions for this. Our decision will be guided by the two goals
- of preserving the free status of all derivatives of our free software and
- of promoting the sharing and reuse of software generally.
- X
- X NO WARRANTY
- X
- X 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
- XFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
- OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
- PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
- OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
- TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
- PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
- REPAIR OR CORRECTION.
- X
- X 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
- WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
- REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
- INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
- OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
- TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
- YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
- PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGES.
- X
- X END OF TERMS AND CONDITIONS
- X
- X Appendix: How to Apply These Terms to Your New Programs
- X
- X If you develop a new program, and you want it to be of the greatest
- possible use to the public, the best way to achieve this is to make it
- free software which everyone can redistribute and change under these terms.
- X
- X To do so, attach the following notices to the program. It is safest
- to attach them to the start of each source file to most effectively
- convey the exclusion of warranty; and each file should have at least
- the "copyright" line and a pointer to where the full notice is found.
- X
- X <one line to give the program's name and a brief idea of what it does.>
- X Copyright (C) 19yy <name of author>
- X
- X This program is free software; you can redistribute it and/or modify
- X it under the terms of the GNU General Public License as published by
- X the Free Software Foundation; either version 2 of the License, or
- X (at your option) any later version.
- X
- X This program is distributed in the hope that it will be useful,
- X but WITHOUT ANY WARRANTY; without even the implied warranty of
- X MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X GNU General Public License for more details.
- X
- X You should have received a copy of the GNU General Public License
- X along with this program; if not, write to the Free Software
- X Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- Also add information on how to contact you by electronic and paper mail.
- X
- If the program is interactive, make it output a short notice like this
- when it starts in an interactive mode:
- X
- X Gnomovision version 69, Copyright (C) 19yy name of author
- X Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- X This is free software, and you are welcome to redistribute it
- X under certain conditions; type `show c' for details.
- X
- The hypothetical commands `show w' and `show c' should show the appropriate
- parts of the General Public License. Of course, the commands you use may
- be called something other than `show w' and `show c'; they could even be
- mouse-clicks or menu items--whatever suits your program.
- X
- You should also get your employer (if you work as a programmer) or your
- school, if any, to sign a "copyright disclaimer" for the program, if
- necessary. Here is a sample; alter the names:
- X
- X Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- X `Gnomovision' (which makes passes at compilers) written by James Hacker.
- X
- X <signature of Ty Coon>, 1 April 1989
- X Ty Coon, President of Vice
- X
- This General Public License does not permit incorporating your program into
- proprietary programs. If your program is a subroutine library, you may
- consider it more useful to permit linking proprietary applications with the
- library. If this is what you want to do, use the GNU Library General
- Public License instead of this License.
- END_OF_FILE
- if test 17977 -ne `wc -c <'sources/help_gnu.txt'`; then
- echo shar: \"'sources/help_gnu.txt'\" unpacked with wrong size!
- fi
- # end of 'sources/help_gnu.txt'
- fi
- if test -f 'sources/tangle.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sources/tangle.c'\"
- else
- echo shar: Extracting \"'sources/tangle.c'\" \(18625 characters\)
- sed "s/^X//" >'sources/tangle.c' <<'END_OF_FILE'
- X/*##############################################################################
- X
- XFUNNNELWEB COPYRIGHT
- X====================
- XFunnelWeb is a literate-programming macro preprocessor.
- X
- Copyright (C) 1992 Ross N. Williams.
- X
- X Ross N. Williams
- X ross@spam.adelaide.edu.au
- X 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
- X
- This program is free software; you can redistribute it and/or modify
- it under the terms of Version 2 of the GNU General Public License as
- published by the Free Software Foundation.
- X
- This program is distributed WITHOUT ANY WARRANTY; without even the implied
- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See Version 2 of the GNU General Public License for more details.
- X
- You should have received a copy of Version 2 of the GNU General Public
- License along with this program. If not, you can FTP the license from
- prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
- XFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- Section 2a of the license requires that all changes to this file be
- recorded prominently in this file. Please record all changes here.
- X
- Programmers:
- X RNW Ross N. Williams ross@spam.adelaide.edu.au
- X
- Changes:
- X 07-May-1992 RNW Program prepared for release under GNU GPL V2.
- X
- X##############################################################################*/
- X
- X
- X/******************************************************************************/
- X/* TANGLE.C */
- X/******************************************************************************/
- X
- X/* Note: In this module, "ex_" at the start of a function name means "expand" */
- X/* rather than the standard meaning of "ex" of "expression. */
- X
- X/******************************************************************************/
- X
- X#include "style.h"
- X
- X#include "as.h"
- X#include "data.h"
- X#include "lister.h"
- X#include "memory.h"
- X#include "misc.h"
- X#include "table.h"
- X#include "tangle.h"
- X#include "writfile.h"
- X
- X/******************************************************************************/
- X
- X/* The following variable keeps track of the output line number. This is */
- X/* needed to report lines that are too long. */
- LOCVAR ulong lineno;
- X
- X/* Last line for which error message was generated. */
- LOCVAR ulong errlin;
- X
- X/* Number of too-long lines seen so far in this file. */
- LOCVAR ulong numlong;
- X/* Number of long line error messages we can tolerate per product file. */
- X#define LONGMESS 5
- X
- X/* Note: An indentation of n means n blanks before current material. */
- X/* tgindent is a global variable set by the scanner. It is TRUE if blank */
- X/* indenting is required and FALSE if no indenting is required. */
- LOCVAR ulong ind_base; /* Base indenting level of macro being expanded. */
- LOCVAR ulong ind_curr; /* Current indenting position. */
- X
- LOCVAR char *fn_targ; /* Name of current (target) product file. */
- LOCVAR wf_t f_o; /* Current product file. */
- X
- X/******************************************************************************/
- X
- X/* The expression expansion function has to have a forward declaration. */
- LOCAL void ex_ex P_((p_ells_t));
- X
- X/******************************************************************************/
- X
- LOCAL void eolblank P_((ulong));
- LOCAL void eolblank(n)
- X/* Writes an EOL followed by n blanks to the product file. Efficiently! */
- ulong n;
- X{
- X /* The whole aim of this routine is to write blanks EFFICIENTLY. In */
- X /* particular avoiding any per-char procedure call overhead (e.g. calls to */
- X /* wf_chr). The best way to avoid this is to create a static array of blanks */
- X /* and write out large blocks of blanks all at once. */
- X#define BLANKLEN 100 /* Number of BLANKS in blank array. */
- X STAVAR bool notinit=TRUE; /* Has blank array been initialized? */
- X STAVAR char blanks[1+BLANKLEN]; /* EOL followed by BLANKLEN blanks. */
- X
- X /* Set up the blank array. This only ever done once because of the static */
- X /* boolean. Note that use of an initialized static here does not make the */
- X /* code non-reentrant, as the state does not change after initialization. */
- X if (notinit)
- X {blanks[0]=EOL; memset(blanks+1,' ',(size_t) BLANKLEN); notinit=FALSE;}
- X
- X /* The most common case will be a small indentation. Do this case fast. */
- X if (n<=BLANKLEN)
- X wf_blk(&f_o,&blanks[0],(size_t) n+1);
- X else
- X {
- X /* We now know that n>=BLANKLEN. Write out a long line with \n at front. */
- X wf_blk(&f_o,&blanks[0],BLANKLEN+1); n-=BLANKLEN;
- X
- X /* Now get into large scale blank production! */
- X while (n>0)
- X {
- X ulong len=MIN(n,BLANKLEN);
- X wf_blk(&f_o,&blanks[1],(size_t) len); n-=len;
- X }
- X }
- X}
- X
- X/******************************************************************************/
- X
- X#define SENDLINE {wl_l(linet1); if (option.op_s_b) wl_sj(linet1);}
- X
- LOCAL void ex_sc P_((p_sc_t));
- LOCAL void ex_sc(p_sc)
- X/* This function writes the specified scrap to the product file. It also */
- X/* performs two other tasks: */
- X/* If tgindent==TRUE, inserts indentation at the start of each line. */
- X/* If tglinmax>0, checks for product file lines longer than tglinmax. */
- X/* Note: The speed of this routine is fairly critical. */
- p_sc_t p_sc;
- X{
- X /* Output of a scrap is straightforward if we are not inserting indentation */
- X /* or watching for lines that are too long. If neither of these tasks have */
- X /* to be performed, we can bang the scrap out directly with a wf_blk. */
- X if (!tgindent && tglinmax==TGMAXINF)
- X {
- X wf_blk(&f_o, p_sc->sc_first, (size_t) (p_sc->sc_last-p_sc->sc_first+1));
- X return;
- X }
- X
- X /* Otherwise it gets rather messy. Basically, we have to watch for end of */
- X /* lines and perform special actions there. */
- X /* ind_curr is the number of characters already written to the current line. */
- X {
- X char *p = p_sc->sc_first;
- X char *p_post = p_sc->sc_last+1;
- X while (TRUE)
- X {
- X char *p_sot = p; /* SOT=Start of Text. */
- X
- X /* Scan scrap until we hit either its end or an EOL. */
- X while (p!=p_post && *p!=EOL) p++;
- X
- X /* Assert: p==p_post || (p_sot<=p<p_post && *p==EOL). */
- X
- X /* If we scanned any non-EOL text, write out what we scanned. */
- X if (p>p_sot) {wf_blk(&f_o,p_sot,(size_t) (p-p_sot));ind_curr+=p-p_sot;}
- X
- X /* Check that what we have written so far is not too long. */
- X /* Performing this check here rather than with the EOL processing */
- X /* means that we will detect overlong final non-EOL terminated lines. */
- X /* Use of errlin suppresses multiple errors on the same line. */
- X /* Note: We assume that TGMAXINF is very large. */
- X if (ind_curr>tglinmax && lineno!=errlin)
- X {
- X numlong++;
- X if (numlong <= LONGMESS)
- X {
- X if (option.op_b7_b)
- X sprintf(linet1,
- X "E: Product file line is too long (line %lu of \"%s\").",
- X (ulong) lineno,SUPPNAME);
- X else
- X sprintf(linet1,
- X "E: Product file line is too long (line %lu of \"%s\").",
- X (ulong) lineno,fn_targ);
- X SENDLINE;
- X if (numlong==1)
- X {
- X sprintf(linet1," Product file line length limit is %lu characters.",
- X (ulong) tglinmax);
- X SENDLINE;
- X sprintf(linet1," Note: You can change the limit by specifying.");
- X SENDLINE;
- X sprintf(linet1," @p maximum_output_line_length = <desired length>");
- X SENDLINE;
- X sprintf(linet1," somewhere in the input file.");
- X SENDLINE;
- X }
- X errlin=lineno;
- X num_err++;
- X }
- X if (numlong == LONGMESS+1)
- X {
- X sprintf(linet1,
- X "Further line-too-long warnings for file \"%s\" have been suppressed.",
- X fn_targ);
- X SENDLINE;
- X }
- X }
- X
- X /* Exit if we hit the end of the scrap. */
- X if (p==p_post) break;
- X
- X /* Move past the EOL and bump up the line counter. */
- X p++; lineno++;
- X
- X /* Output an EOL with indentation if desired. */
- X if (tgindent)
- X eolblank(ind_base);
- X else
- X wf_chr(&f_o,EOL);
- X ind_curr=ind_base;
- X }
- X }
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void ex_eltx P_((p_el_t));
- LOCAL void ex_eltx(p_el)
- X/* Writes the given text element to the product file. */
- p_el_t p_el;
- X{
- X p_sc_t p_sc;
- X
- X /* Make sure that we have actually been handed a text element. */
- X as_cold(p_el->el_kind==EL_TEXT,"ex_eltx: Not a text element!");
- X
- X /* Write all the scraps in the text list to the product file. */
- X ls_fir(p_el->el_text);
- X while (TRUE)
- X {
- X ls_nxt(p_el->el_text,PPV &p_sc);
- X if (p_sc==NULL) break;
- X ex_sc(p_sc);
- X }
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void ex_elpr P_((p_el_t));
- LOCAL void ex_elpr(p_el)
- X/* Write the expansion of the given parameter element to the product file. */
- p_el_t p_el;
- X{
- X p_ell3_t actn = p_el->el_which->ma_actn;
- X p_elll_t *pp_parls;
- X p_ells_t *pp_exp;
- X ulong ind_save;
- X
- X /* Make sure that we have been handed a parameter element. */
- X as_cold(p_el->el_kind==EL_PARM,"ex_elpr: Not a parameter element!");
- X
- X /* Save the current indentation base and set it to the current level. */
- X ind_save=ind_base;
- X ind_base=ind_curr;
- X
- X /* Get a pointer to the most recent parameter list of the target macro. */
- X ls_loo(actn,ls_len(actn),PPV &pp_parls);
- X
- X /* Get the expression corresponding to the el_parno'th parameter. */
- X ls_loo(*pp_parls,p_el->el_parno,PPV &pp_exp);
- X
- X /* Expand that expression. */
- X ex_ex(*pp_exp);
- X
- X /* Restore the indentation base. */
- X ind_base=ind_save;
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void ex_elin P_((p_el_t));
- LOCAL void ex_elin(p_el)
- X/* Expand invocation element. */
- p_el_t p_el;
- X{
- X p_ma_t p_ma;
- X p_bp_t p_bp;
- X ulong ind_save;
- X p_void p_mark;
- X
- X /* Make sure that we have been handed an invocation element. */
- X as_cold(p_el->el_kind==EL_INVC,"ex_elin: Not an invocation element!");
- X
- X /* Save the current indentation base and set it to the current level. */
- X ind_save=ind_base;
- X ind_base=ind_curr;
- X
- X /* Grab a pointer to the macro being invoked. */
- X p_ma=p_el->el_p_mac;
- X
- X /* Push the actual parameter list onto the invoked macro's activation list. */
- X ls_add(p_ma->ma_actn,PV &p_el->el_parls);
- X
- X /* Expand each body part expression. */
- X ls_fir(p_ma->ma_defn.md_body);
- X while (TRUE)
- X {
- X ls_nxt(p_ma->ma_defn.md_body,PPV &p_bp);
- X if (p_bp==NULL) break;
- X p_mark=ls_mar(p_ma->ma_defn.md_body); /* Protect againt recursion. */
- X ex_ex(p_bp->bp_ex);
- X ls_set(p_ma->ma_defn.md_body,p_mark);
- X }
- X
- X /* Pop the activated macro's parameter list. */
- X ls_lop(p_ma->ma_actn);
- X
- X /* Restore the indentation base. */
- X ind_base=ind_save;
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void ex_ex(p_exp)
- X/* Expand the specified expression. */
- p_ells_t p_exp;
- X{
- X p_void p_mark;
- X
- X /* We need to save the current position in the expression list in case we */
- X /* are being recursively invoked (e.g. in @<X@>@(@"@<X@>@(@"sloth@"@)@"@). */
- X ls_fir(p_exp);
- X while (TRUE)
- X {
- X p_el_t p_el;
- X ls_nxt(p_exp,PPV &p_el);
- X if (p_el==NULL) break;
- X p_mark=ls_mar(p_exp);
- X switch (p_el->el_kind)
- X {
- X case EL_TEXT: ex_eltx(p_el); break;
- X case EL_INVC: ex_elin(p_el); break;
- X case EL_PARM: ex_elpr(p_el); break;
- X default : as_bomb("ex_ex: Case defaulted.");
- X }
- X ls_set(p_exp,p_mark);
- X }
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void ex_file P_((p_ma_t));
- LOCAL void ex_file(p_ma)
- X/* This function accepts a pointer to a macro. It creates a product file */
- X/* with the same name as the macro (inheriting any filename parts given in */
- X/* the command line) and expands the macro, writing the expansion to the */
- X/* product file. */
- p_ma_t p_ma;
- X{
- X fn_t fn_tmp; /* Name of temporary file. */
- X bool renfil; /* Do we wish to rename product file? */
- X bool istarg; /* Does a target file already exist? */
- X
- X /* Writing product files differs to the other output files. With non */
- X /* critical files such as the listing file that are really just logs, */
- X /* generation of half a listing file is acceptable if not desirable. However */
- X /* in the case of product files, it is very bad to generate half a product */
- X /* file; far better to generate none at all. For this reason, and also */
- X /* because of the presence of the D option (which prohibits the writing */
- X /* of product files identical to existing files (to prevent MAKE */
- X /* propagations)) it is best to write a temporary file and then rename it. */
- X
- X /* Construct the target file name. */
- X strcpy(fn_targ,""); /* Start with an empty name. */
- X fn_ins(fn_targ,&option.op_o_s[0]);
- X fn_ins(fn_targ,&p_ma->ma_name[0]);
- X
- X /* The temporary file has to inherit too, because the output directory may */
- X /* not be the default directory and some computers can't rename across */
- X /* directories (and we have to rename it later). */
- X strcpy(fn_tmp,fn_targ);
- X fn_ins(fn_tmp,fn_temp());
- X
- X /* Expand the macro to the temporary file. */
- X wf_ini(&f_o,TRUE);
- X wf_ope(&f_o,fn_tmp);
- X if (wf_err(&f_o))
- X {
- X sprintf(linet1,"Error creating temporary product file \"%s\".",&fn_tmp[0]);
- X wl_sjl(linet1);
- X (void) remove(fn_tmp);
- X goto severe;
- X }
- X
- X /* Now expand the target macro into the file. */
- X {
- X el_t el;
- X el.el_kind = EL_INVC;
- X el.el_p_mac = p_ma;
- X el.el_parls = ls_cre(sizeof(p_ells_t));
- X /* Note: We don't set el_pretx and el_postx as they are not used here. */
- X ind_base = 0;
- X ind_curr = 0;
- X lineno = 1;
- X errlin = 0;
- X numlong = 0;
- X ex_elin(&el);
- X }
- X
- X /* Make sure that there weren't any errors writing to the product file. */
- X if (wf_err(&f_o))
- X {
- X sprintf(linet1,"S: Error writing to temporary product file \"%s\".",&fn_tmp[0]);
- X wl_sjl(linet1);
- X (void) remove(fn_tmp);
- X goto severe;
- X }
- X
- X /* Close the product file. */
- X wf_clo(&f_o);
- X if (wf_err(&f_o))
- X {
- X sprintf(linet1,"S: Error closing temporary product file \"%s\".",&fn_tmp[0]);
- X wl_sjl(linet1);
- X (void) remove(fn_tmp);
- X goto severe;
- X }
- X
- X /* The rest of the code in this function copes with the renaming. */
- X
- X /* By default, we wish to rename the temporary file. */
- X renfil=TRUE;
- X
- X /* Deal with any existing file of the target name. */
- X istarg=fexists(fn_targ);
- X if (istarg && option.op_d_b)
- X {
- X /* A target already exists, and the D option is on. If the target is */
- X /* identical to the temporary, we can simply delete the temporary! */
- X char *errstr;
- X bool same;
- X errstr=eq_files(fn_tmp,fn_targ,&same);
- X if (errstr != NULL)
- X {
- X wl_sjl("S: Error comparing temporary file with previous product file.");
- X wl_sjl("(A comparison was attempted because the D option was turned on.)");
- X wl_sjl("Error from comparison routine was as follows (first=temp):");
- X wr_sjl(" ");wl_sjl(errstr);
- X sprintf(linet1,"Temporary file name was \"%s\".",&fn_tmp[0]);
- X wl_sjl(linet1);
- X sprintf(linet1,"Product file name was \"%s\".",fn_targ);
- X wl_sjl(linet1);
- X wl_sjl("FunnelWeb will leave both files intact so you can look at them.");
- X goto severe;
- X }
- X /* If the two files are the same, we can simply delete the temporary. */
- X if (same)
- X {
- X int status;
- X status=remove(fn_tmp);
- X if (status != REMOVE_S)
- X {
- X sprintf(linet1,"S: Error deleting (under +D option) temporary file \"%s\".",&fn_tmp[0]);
- X wl_sjl(linet1);
- X goto severe;
- X }
- X sprintf(linet1,"Deleted identical product file \"%s\".",fn_targ);
- X wl_sjl(linet1);
- X renfil=FALSE;
- X }
- X }
- X
- X if (renfil)
- X {
- X int status;
- X /* We need to delete any existing file of the target name. */
- X if (istarg)
- X {
- X status=remove(fn_targ);
- X if (status != REMOVE_S)
- X {
- X sprintf(linet1,"S: Error deleting existing product file \"%s\".",fn_targ);
- X wl_sjl(linet1);
- X goto severe;
- X }
- X }
- X /* Rename the temporary file to the product file. */
- X status=rename(fn_tmp,fn_targ);
- X if (status != RENAME_S)
- X {
- X wl_sjl("S: Error renaming temporary product file to product file.");
- X sprintf(linet1,"Temporary file name was \"%s\".",&fn_tmp[0]);
- X wl_sjl(linet1);
- X sprintf(linet1,"Product file name was \"%s\".",fn_targ);
- X wl_sjl(linet1);
- X wl_sjl("FunnelWeb will leave both files intact so you can look at them.");
- X goto severe;
- X }
- X }
- X
- X /* Tell everyone that we have written a product file. */
- X /* Note that we use the macro name. The full name is usually too messy. */
- X sprintf(linet1,"Tangle: Completed %s.",&p_ma->ma_name[0]);
- X wl_sjl(linet1);
- X return;
- X
- X /* Jump here is a nasty file error occurs. */
- X severe:
- X sprintf(linet1,"A problem occurred during the generation of product file \"%s\".",&fn_targ[0]);
- X wl_sjl(linet1);
- X wl_sjl("S: Aborting...");
- X num_sev++;
- X return;
- X
- X}
- X
- X/******************************************************************************/
- X
- XEXPORT void tangle()
- X{
- X name_t dummyname;
- X p_ma_t p_ma;
- X
- X /* Possibly decrease tglinmax if W option is turned on. */
- X if (option.op_w_b)
- X tglinmax=MIN(tglinmax,option.op_w_i);
- X
- X /* Some compilers do not allow much space for statics so we allocate fn_targ */
- X /* dynamically to save static space. */
- X fn_targ=(char *) mm_temp(sizeof(fn_t));
- X
- X /* Generate each file contained in the file table. */
- X tb_fir(file_table);
- X while (num_sev==0 && tb_rea(file_table,PV dummyname,PV &p_ma))
- X ex_file(p_ma);
- X}
- X
- X/******************************************************************************/
- X/* End of TANGLE.C */
- X/******************************************************************************/
- X
- END_OF_FILE
- if test 18625 -ne `wc -c <'sources/tangle.c'`; then
- echo shar: \"'sources/tangle.c'\" unpacked with wrong size!
- fi
- # end of 'sources/tangle.c'
- fi
- echo shar: End of archive 9 \(of 20\).
- cp /dev/null ark9isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 20 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-