home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / funnlweb / part09 < prev    next >
Encoding:
Text File  |  1993-04-10  |  130.3 KB  |  3,080 lines

  1. Newsgroups: comp.sources.unix
  2. From: ross@spam.adelaide.edu.au (Ross Williams)
  3. Subject: v26i129: funnelweb - a tool for literate programming in C, Part09/20
  4. Sender: unix-sources-moderator@vix.com
  5. Approved: paul@vix.com
  6.  
  7. Submitted-By: ross@spam.adelaide.edu.au (Ross Williams)
  8. Posting-Number: Volume 26, Issue 129
  9. Archive-Name: funnelweb/part09
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 9 (of 20)."
  18. # Contents:  admin/gnu2.txt answers/ex16.tex answers/wv02.tex
  19. #   hackman/h_ch2.tex hackman/h_ch4.tex sources/help_gnu.txt
  20. #   sources/tangle.c
  21. # Wrapped by vixie@gw.home.vix.com on Sun Apr 11 11:00:22 1993
  22. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  23. if test -f 'admin/gnu2.txt' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'admin/gnu2.txt'\"
  25. else
  26. echo shar: Extracting \"'admin/gnu2.txt'\" \(17977 characters\)
  27. sed "s/^X//" >'admin/gnu2.txt' <<'END_OF_FILE'
  28. X            GNU GENERAL PUBLIC LICENSE
  29. X               Version 2, June 1991
  30. X
  31. X Copyright (C) 1989, 1991 Free Software Foundation, Inc.
  32. X                          675 Mass Ave, Cambridge, MA 02139, USA
  33. X Everyone is permitted to copy and distribute verbatim copies
  34. X of this license document, but changing it is not allowed.
  35. X
  36. X                Preamble
  37. X
  38. X  The licenses for most software are designed to take away your
  39. freedom to share and change it.  By contrast, the GNU General Public
  40. License is intended to guarantee your freedom to share and change free
  41. software--to make sure the software is free for all its users.  This
  42. General Public License applies to most of the Free Software
  43. XFoundation's software and to any other program whose authors commit to
  44. using it.  (Some other Free Software Foundation software is covered by
  45. the GNU Library General Public License instead.)  You can apply it to
  46. your programs, too.
  47. X
  48. X  When we speak of free software, we are referring to freedom, not
  49. price.  Our General Public Licenses are designed to make sure that you
  50. have the freedom to distribute copies of free software (and charge for
  51. this service if you wish), that you receive source code or can get it
  52. if you want it, that you can change the software or use pieces of it
  53. in new free programs; and that you know you can do these things.
  54. X
  55. X  To protect your rights, we need to make restrictions that forbid
  56. anyone to deny you these rights or to ask you to surrender the rights.
  57. These restrictions translate to certain responsibilities for you if you
  58. distribute copies of the software, or if you modify it.
  59. X
  60. X  For example, if you distribute copies of such a program, whether
  61. gratis or for a fee, you must give the recipients all the rights that
  62. you have.  You must make sure that they, too, receive or can get the
  63. source code.  And you must show them these terms so they know their
  64. rights.
  65. X
  66. X  We protect your rights with two steps: (1) copyright the software, and
  67. X(2) offer you this license which gives you legal permission to copy,
  68. distribute and/or modify the software.
  69. X
  70. X  Also, for each author's protection and ours, we want to make certain
  71. that everyone understands that there is no warranty for this free
  72. software.  If the software is modified by someone else and passed on, we
  73. want its recipients to know that what they have is not the original, so
  74. that any problems introduced by others will not reflect on the original
  75. authors' reputations.
  76. X
  77. X  Finally, any free program is threatened constantly by software
  78. patents.  We wish to avoid the danger that redistributors of a free
  79. program will individually obtain patent licenses, in effect making the
  80. program proprietary.  To prevent this, we have made it clear that any
  81. patent must be licensed for everyone's free use or not licensed at all.
  82. X
  83. X  The precise terms and conditions for copying, distribution and
  84. modification follow.
  85. X
  86. X            GNU GENERAL PUBLIC LICENSE
  87. X   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
  88. X
  89. X  0. This License applies to any program or other work which contains
  90. a notice placed by the copyright holder saying it may be distributed
  91. under the terms of this General Public License.  The "Program", below,
  92. refers to any such program or work, and a "work based on the Program"
  93. means either the Program or any derivative work under copyright law:
  94. that is to say, a work containing the Program or a portion of it,
  95. either verbatim or with modifications and/or translated into another
  96. language.  (Hereinafter, translation is included without limitation in
  97. the term "modification".)  Each licensee is addressed as "you".
  98. X
  99. Activities other than copying, distribution and modification are not
  100. covered by this License; they are outside its scope.  The act of
  101. running the Program is not restricted, and the output from the Program
  102. is covered only if its contents constitute a work based on the
  103. Program (independent of having been made by running the Program).
  104. Whether that is true depends on what the Program does.
  105. X
  106. X  1. You may copy and distribute verbatim copies of the Program's
  107. source code as you receive it, in any medium, provided that you
  108. conspicuously and appropriately publish on each copy an appropriate
  109. copyright notice and disclaimer of warranty; keep intact all the
  110. notices that refer to this License and to the absence of any warranty;
  111. and give any other recipients of the Program a copy of this License
  112. along with the Program.
  113. X
  114. You may charge a fee for the physical act of transferring a copy, and
  115. you may at your option offer warranty protection in exchange for a fee.
  116. X
  117. X  2. You may modify your copy or copies of the Program or any portion
  118. of it, thus forming a work based on the Program, and copy and
  119. distribute such modifications or work under the terms of Section 1
  120. above, provided that you also meet all of these conditions:
  121. X
  122. X    a) You must cause the modified files to carry prominent notices
  123. X    stating that you changed the files and the date of any change.
  124. X
  125. X    b) You must cause any work that you distribute or publish, that in
  126. X    whole or in part contains or is derived from the Program or any
  127. X    part thereof, to be licensed as a whole at no charge to all third
  128. X    parties under the terms of this License.
  129. X
  130. X    c) If the modified program normally reads commands interactively
  131. X    when run, you must cause it, when started running for such
  132. X    interactive use in the most ordinary way, to print or display an
  133. X    announcement including an appropriate copyright notice and a
  134. X    notice that there is no warranty (or else, saying that you provide
  135. X    a warranty) and that users may redistribute the program under
  136. X    these conditions, and telling the user how to view a copy of this
  137. X    License.  (Exception: if the Program itself is interactive but
  138. X    does not normally print such an announcement, your work based on
  139. X    the Program is not required to print an announcement.)
  140. X
  141. These requirements apply to the modified work as a whole.  If
  142. identifiable sections of that work are not derived from the Program,
  143. and can be reasonably considered independent and separate works in
  144. themselves, then this License, and its terms, do not apply to those
  145. sections when you distribute them as separate works.  But when you
  146. distribute the same sections as part of a whole which is a work based
  147. on the Program, the distribution of the whole must be on the terms of
  148. this License, whose permissions for other licensees extend to the
  149. entire whole, and thus to each and every part regardless of who wrote it.
  150. X
  151. Thus, it is not the intent of this section to claim rights or contest
  152. your rights to work written entirely by you; rather, the intent is to
  153. exercise the right to control the distribution of derivative or
  154. collective works based on the Program.
  155. X
  156. In addition, mere aggregation of another work not based on the Program
  157. with the Program (or with a work based on the Program) on a volume of
  158. a storage or distribution medium does not bring the other work under
  159. the scope of this License.
  160. X
  161. X  3. You may copy and distribute the Program (or a work based on it,
  162. under Section 2) in object code or executable form under the terms of
  163. Sections 1 and 2 above provided that you also do one of the following:
  164. X
  165. X    a) Accompany it with the complete corresponding machine-readable
  166. X    source code, which must be distributed under the terms of Sections
  167. X    1 and 2 above on a medium customarily used for software interchange; or,
  168. X
  169. X    b) Accompany it with a written offer, valid for at least three
  170. X    years, to give any third party, for a charge no more than your
  171. X    cost of physically performing source distribution, a complete
  172. X    machine-readable copy of the corresponding source code, to be
  173. X    distributed under the terms of Sections 1 and 2 above on a medium
  174. X    customarily used for software interchange; or,
  175. X
  176. X    c) Accompany it with the information you received as to the offer
  177. X    to distribute corresponding source code.  (This alternative is
  178. X    allowed only for noncommercial distribution and only if you
  179. X    received the program in object code or executable form with such
  180. X    an offer, in accord with Subsection b above.)
  181. X
  182. The source code for a work means the preferred form of the work for
  183. making modifications to it.  For an executable work, complete source
  184. code means all the source code for all modules it contains, plus any
  185. associated interface definition files, plus the scripts used to
  186. control compilation and installation of the executable.  However, as a
  187. special exception, the source code distributed need not include
  188. anything that is normally distributed (in either source or binary
  189. form) with the major components (compiler, kernel, and so on) of the
  190. operating system on which the executable runs, unless that component
  191. itself accompanies the executable.
  192. X
  193. If distribution of executable or object code is made by offering
  194. access to copy from a designated place, then offering equivalent
  195. access to copy the source code from the same place counts as
  196. distribution of the source code, even though third parties are not
  197. compelled to copy the source along with the object code.
  198. X
  199. X  4. You may not copy, modify, sublicense, or distribute the Program
  200. except as expressly provided under this License.  Any attempt
  201. otherwise to copy, modify, sublicense or distribute the Program is
  202. void, and will automatically terminate your rights under this License.
  203. However, parties who have received copies, or rights, from you under
  204. this License will not have their licenses terminated so long as such
  205. parties remain in full compliance.
  206. X
  207. X  5. You are not required to accept this License, since you have not
  208. signed it.  However, nothing else grants you permission to modify or
  209. distribute the Program or its derivative works.  These actions are
  210. prohibited by law if you do not accept this License.  Therefore, by
  211. modifying or distributing the Program (or any work based on the
  212. Program), you indicate your acceptance of this License to do so, and
  213. all its terms and conditions for copying, distributing or modifying
  214. the Program or works based on it.
  215. X
  216. X  6. Each time you redistribute the Program (or any work based on the
  217. Program), the recipient automatically receives a license from the
  218. original licensor to copy, distribute or modify the Program subject to
  219. these terms and conditions.  You may not impose any further
  220. restrictions on the recipients' exercise of the rights granted herein.
  221. You are not responsible for enforcing compliance by third parties to
  222. this License.
  223. X
  224. X  7. If, as a consequence of a court judgment or allegation of patent
  225. infringement or for any other reason (not limited to patent issues),
  226. conditions are imposed on you (whether by court order, agreement or
  227. otherwise) that contradict the conditions of this License, they do not
  228. excuse you from the conditions of this License.  If you cannot
  229. distribute so as to satisfy simultaneously your obligations under this
  230. License and any other pertinent obligations, then as a consequence you
  231. may not distribute the Program at all.  For example, if a patent
  232. license would not permit royalty-free redistribution of the Program by
  233. all those who receive copies directly or indirectly through you, then
  234. the only way you could satisfy both it and this License would be to
  235. refrain entirely from distribution of the Program.
  236. X
  237. If any portion of this section is held invalid or unenforceable under
  238. any particular circumstance, the balance of the section is intended to
  239. apply and the section as a whole is intended to apply in other
  240. circumstances.
  241. X
  242. It is not the purpose of this section to induce you to infringe any
  243. patents or other property right claims or to contest validity of any
  244. such claims; this section has the sole purpose of protecting the
  245. integrity of the free software distribution system, which is
  246. implemented by public license practices.  Many people have made
  247. generous contributions to the wide range of software distributed
  248. through that system in reliance on consistent application of that
  249. system; it is up to the author/donor to decide if he or she is willing
  250. to distribute software through any other system and a licensee cannot
  251. impose that choice.
  252. X
  253. This section is intended to make thoroughly clear what is believed to
  254. be a consequence of the rest of this License.
  255. X
  256. X  8. If the distribution and/or use of the Program is restricted in
  257. certain countries either by patents or by copyrighted interfaces, the
  258. original copyright holder who places the Program under this License
  259. may add an explicit geographical distribution limitation excluding
  260. those countries, so that distribution is permitted only in or among
  261. countries not thus excluded.  In such case, this License incorporates
  262. the limitation as if written in the body of this License.
  263. X
  264. X  9. The Free Software Foundation may publish revised and/or new versions
  265. of the General Public License from time to time.  Such new versions will
  266. be similar in spirit to the present version, but may differ in detail to
  267. address new problems or concerns.
  268. X
  269. XEach version is given a distinguishing version number.  If the Program
  270. specifies a version number of this License which applies to it and "any
  271. later version", you have the option of following the terms and conditions
  272. either of that version or of any later version published by the Free
  273. Software Foundation.  If the Program does not specify a version number of
  274. this License, you may choose any version ever published by the Free Software
  275. XFoundation.
  276. X
  277. X  10. If you wish to incorporate parts of the Program into other free
  278. programs whose distribution conditions are different, write to the author
  279. to ask for permission.  For software which is copyrighted by the Free
  280. Software Foundation, write to the Free Software Foundation; we sometimes
  281. make exceptions for this.  Our decision will be guided by the two goals
  282. of preserving the free status of all derivatives of our free software and
  283. of promoting the sharing and reuse of software generally.
  284. X
  285. X                NO WARRANTY
  286. X
  287. X  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
  288. XFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
  289. OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
  290. PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
  291. OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  292. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
  293. TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
  294. PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
  295. REPAIR OR CORRECTION.
  296. X
  297. X  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
  298. WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
  299. REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
  300. INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
  301. OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
  302. TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
  303. YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
  304. PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
  305. POSSIBILITY OF SUCH DAMAGES.
  306. X
  307. X             END OF TERMS AND CONDITIONS
  308. X
  309. X    Appendix: How to Apply These Terms to Your New Programs
  310. X
  311. X  If you develop a new program, and you want it to be of the greatest
  312. possible use to the public, the best way to achieve this is to make it
  313. free software which everyone can redistribute and change under these terms.
  314. X
  315. X  To do so, attach the following notices to the program.  It is safest
  316. to attach them to the start of each source file to most effectively
  317. convey the exclusion of warranty; and each file should have at least
  318. the "copyright" line and a pointer to where the full notice is found.
  319. X
  320. X    <one line to give the program's name and a brief idea of what it does.>
  321. X    Copyright (C) 19yy  <name of author>
  322. X
  323. X    This program is free software; you can redistribute it and/or modify
  324. X    it under the terms of the GNU General Public License as published by
  325. X    the Free Software Foundation; either version 2 of the License, or
  326. X    (at your option) any later version.
  327. X
  328. X    This program is distributed in the hope that it will be useful,
  329. X    but WITHOUT ANY WARRANTY; without even the implied warranty of
  330. X    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  331. X    GNU General Public License for more details.
  332. X
  333. X    You should have received a copy of the GNU General Public License
  334. X    along with this program; if not, write to the Free Software
  335. X    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  336. X
  337. Also add information on how to contact you by electronic and paper mail.
  338. X
  339. If the program is interactive, make it output a short notice like this
  340. when it starts in an interactive mode:
  341. X
  342. X    Gnomovision version 69, Copyright (C) 19yy name of author
  343. X    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
  344. X    This is free software, and you are welcome to redistribute it
  345. X    under certain conditions; type `show c' for details.
  346. X
  347. The hypothetical commands `show w' and `show c' should show the appropriate
  348. parts of the General Public License.  Of course, the commands you use may
  349. be called something other than `show w' and `show c'; they could even be
  350. mouse-clicks or menu items--whatever suits your program.
  351. X
  352. You should also get your employer (if you work as a programmer) or your
  353. school, if any, to sign a "copyright disclaimer" for the program, if
  354. necessary.  Here is a sample; alter the names:
  355. X
  356. X  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
  357. X  `Gnomovision' (which makes passes at compilers) written by James Hacker.
  358. X
  359. X  <signature of Ty Coon>, 1 April 1989
  360. X  Ty Coon, President of Vice
  361. X
  362. This General Public License does not permit incorporating your program into
  363. proprietary programs.  If your program is a subroutine library, you may
  364. consider it more useful to permit linking proprietary applications with the
  365. library.  If this is what you want to do, use the GNU Library General
  366. Public License instead of this License.
  367. END_OF_FILE
  368. if test 17977 -ne `wc -c <'admin/gnu2.txt'`; then
  369.     echo shar: \"'admin/gnu2.txt'\" unpacked with wrong size!
  370. fi
  371. # end of 'admin/gnu2.txt'
  372. fi
  373. if test -f 'answers/ex16.tex' -a "${1}" != "-c" ; then 
  374.   echo shar: Will not clobber existing file \"'answers/ex16.tex'\"
  375. else
  376. echo shar: Extracting \"'answers/ex16.tex'\" \(18160 characters\)
  377. sed "s/^X//" >'answers/ex16.tex' <<'END_OF_FILE'
  378. X
  379. X%*******************************************************************************
  380. X%*                    START OF AUTOMATICALLY GENERATED TEX FILE                *
  381. X%*******************************************************************************
  382. X%*                                                                             *
  383. X%* This TeX file was automatically generated by the FunnelWeb preprocessor.    *
  384. X%* You can typeset this file to produce printed documentation by running it    *
  385. X%* through the TeX typesetter using a command such as:                         *
  386. X%*    tex thisfilename                                                         *
  387. X%* The resultant file thisfilename.dvi can be printed using a command such as: *
  388. X%*    lpr -Pcslw -d thisfilename.dvi                                           *
  389. X%*                                                                             *
  390. X%* FunnelWeb is a preprocessor that allows programmers to weave programs and   *
  391. X%* their documentation together in a single document. The FunnelWeb program    *
  392. X%* analyses such documents producing both program files and typeset            *
  393. X%* documentation such as this TeX file.                                        *
  394. X%* FunnelWeb was created by Ross Williams.                                     *
  395. X%*                                                                             *
  396. X%* For more information on FunnelWeb look in the following FTP archive:        *
  397. X%*    Machine  : sirius.itd.adelaide.edu.au [IP=129.127.40.3].                 *
  398. X%*    Directory: ~pub/funnelweb/                                               *
  399. X%*               (or some other appropriately named directory).                *
  400. X%* or email Ross Williams at ross@spam.adelaide.edu.au                         *
  401. X%*                                                                             *
  402. X%*******************************************************************************
  403. X
  404. X
  405. X%===================== Start of FunnelWeb TeX Definitions ======================
  406. X
  407. X
  408. X% Version
  409. X% -------
  410. X% This is FunnelWeb TeX Macro Library Version 1.0.
  411. X
  412. X
  413. X% Copyright
  414. X% ---------
  415. X% This set of FunnelWeb TeX definitions was written by Ross Williams and was
  416. X% originally Copyright (C) 1992 Ross N. Williams.  However, I, Ross Williams,
  417. X% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
  418. X% and hereby authorize that the set of TeX definitions pass into the public
  419. X% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
  420. X
  421. X
  422. X% Modification
  423. X% ------------
  424. X% Please record all modifications to these TeX definitions here. Unless
  425. X% otherwise specified, all modified definitions fall in the public domain too.
  426. X%
  427. X% Programmers:
  428. X%    RNW  Ross N. Williams  ross@spam.adelaide.edu.au
  429. X%
  430. X% Changes:
  431. X%    07-May-1992  RNW  Prepared this work for public domain release.
  432. X%
  433. X
  434. X
  435. X% General Comments
  436. X% ----------------
  437. X% This set of TeX definitions exists for two reasons:
  438. X%
  439. X%    1. To shorten and neaten the FunnelWeb TeX output.
  440. X%    2. To allow users to fiddle with the output format in their input files
  441. X%       (by inserting redefining "\def"s) without having to resort to
  442. X%       modifying the FunnelWeb code.
  443. X%
  444. X% The user is warned that these definitions may be changed from time to time
  445. X% (but probably not much). The user should not be too sneaky. In particular,
  446. X% users wishing to redefine some of these macros should do so in an explicitly
  447. X% defined section at the top of their input file. This will mean that in the
  448. X% event of problems, that section can simply be deleted or commented out to
  449. X% allow the document to at least be typeset in the default format. Users should
  450. X% limit themselves to redefining these macros in such a section and should
  451. X% refrain from using the macros throughout their documents.
  452. X
  453. X
  454. X% Environment Parameters
  455. X% ----------------------
  456. X% \tolerance tells TeX how tolerant it should be about making bad line and
  457. X% page breaks. Here we set it to it's maximum, as
  458. X%   1) Computer programs are likely to cause lots of bad breaks.
  459. X%   2) In most cases the user would probably rather get the TeX file through
  460. X%      TeX without any errors than fiddle with spacings for perfection.
  461. X\tolerance=10000
  462. X
  463. X% I don't like indentation as it makes the page look more busy. Instead,
  464. X% paragraphs are separated by a little space (see next).
  465. X\parindent=0pt
  466. X
  467. X% In many cases, users will produce documents with long runs of paragraphs.
  468. X% In order to space out these paragraphs, it is convenient to maintain a
  469. X% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
  470. X% that the skip becomes a problem in macro definitions which require no skip
  471. X% and so we have to turn the skip on and off. The following two macros
  472. X% simplify this process.
  473. X\def\fwparskipon{\parskip=\medskipamount}
  474. X\def\fwparskipoff{\parskip=0pt}
  475. X\fwparskipon
  476. X
  477. X% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
  478. X% page in order to better vertically align the rest of the page (e.g. skips
  479. X% won't stretch as much). It also means that headings are less likely to be
  480. X% isolated at the bottom of the page without any following text.
  481. X\raggedbottom
  482. X
  483. X
  484. X% Fonts
  485. X% -----
  486. X% Most of the typeset output is set in 10pt roman and 10pt tt font.
  487. X% The major extra font needs spring from titles and headings.
  488. X% For portability's sake we use only the following fonts:
  489. X%    cmr10
  490. X%    cmbx10
  491. X%    cmtt10
  492. X% and some enlargements of them. These fonts are all "standard" fonts
  493. X% in Plain TeX. See The TeXbook p.350.
  494. X\font\fwfontnote=cmr7
  495. X
  496. X\font\fwfontnorm=cmr10
  497. X\font\fwfontnorma=cmr10 scaled \magstep1
  498. X\font\fwfontnormb=cmr10 scaled \magstep2
  499. X
  500. X\font\fwfontbold=cmbx10
  501. X\font\fwfontbolda=cmbx10 scaled \magstep1
  502. X\font\fwfontboldb=cmbx10 scaled \magstep2
  503. X\font\fwfontboldc=cmbx10 scaled \magstep3
  504. X\font\fwfontboldd=cmbx10 scaled \magstep4
  505. X
  506. X
  507. X% Macros for Stylistic Details
  508. X% ----------------------------
  509. X% This section contains all the fiddly little macros for setting the details
  510. X% of each macro definition.
  511. X
  512. X% Macro definitions are sandwiched by calls to these macros which can be used
  513. X% to sort out the spacing before and after the macro definition.
  514. X\def\fwbeginmacro{\fwparskipoff\bigskip}
  515. X\def\fwendmacro{\fwparskipon\par}
  516. X
  517. X% These macros deal with the macro name and definition line.
  518. X\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
  519. X\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
  520. X\def\fwzero#1{{\bf Z}}
  521. X\def\fwmany#1{{\bf M}}
  522. X\def\fwequals{ $\equiv$}
  523. X\def\fwplusequals{ $+\equiv$}
  524. X
  525. X% Now for the actual body of the definition. It looks nice to have the tt
  526. X% code indented a little. Again, we use macros instead of writing direct TeX,
  527. X% so as to allow the user to fiddle this stuff to taste without having to
  528. X% modify the FunnelWeb C code.
  529. X\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
  530. X\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
  531. X\def\fwoquote{`}
  532. X\def\fwcquote{'}
  533. X\def\fwoparen{$($}
  534. X\def\fwcomma{$,$}
  535. X\def\fwcparen{$)$}
  536. X\def\fwparam#1{$\diamond #1$}
  537. X\def\fwparams#1{$(\diamond #1)$}
  538. X
  539. X% These macros deal with the notes that are appended at the end of each
  540. X% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
  541. X% have the same definition, they are given different names so as to allow the
  542. X% user to redefine these macros to typeset each kind of information differently
  543. X% if desired.
  544. X\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
  545. X\def\fwnote#1{{\fwfontnote #1}\par}
  546. X\def\fwisafile#1{\fwnote{#1}}
  547. X\def\fwusedin#1{\fwnote{#1}}
  548. X\def\fwseealso#1{\fwnote{#1}}
  549. X\def\fwendmacronotes{\endgroup}
  550. X
  551. X
  552. X% Macros to Typeset Program Code Verbatim
  553. X% ---------------------------------------
  554. X% This is by far the hairiest and most difficult part of the typesetting task
  555. X% because we have to turn off most of TeX's natural instincts in order to
  556. X% typeset the program text exactly as it appears in the input file.
  557. X% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
  558. X% Their code was inspired by the following sections of "The TeXbook":
  559. X%    Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
  560. X%    Appendix E: Example Formats, p.421.
  561. X% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
  562. X% The liberal use of "%" is because I don't understand TeX well enough to
  563. X% understand when an end of line will cause trouble, and I am playing it safe.
  564. X
  565. X% Before defining the main \fwbtx macro, we have to stash away some definitions
  566. X% in the hidden part of TeX's environment. Let's hope that these "hidden"
  567. X% definitions don't affect anything except what is desired to be affected.
  568. X
  569. X% The tt font in which we wish to set the text has two Latin lurking ligatures!
  570. X% These are ?` and !`. To disable them, we define the left quote when ACTIVE
  571. X% to be defined in such a way as to prevent ligatures. The main TeX text will
  572. X% normally not be exposed to this definition because normally the leftquote
  573. X% character is not active. The \fwbtx macro temporarily makes the left quote
  574. X% character active thus activating the deactivation of left quote ligatures.
  575. X% See The TeXbook p.381.
  576. X{\catcode`\`=\active \gdef`{\relax\lq}}
  577. X
  578. X% TeX is fairly carefree about spaces and so we have to make it more serious.
  579. X% To do so we pull the same trick as above, setting up a definition for active
  580. X% space, but only making space active during the span of the verbatim text.
  581. X% In Plain TeX the active space is defined to be simply a space, but here we
  582. X% define it to be a control space. This ensures that the space cannot
  583. X% be gobbled up by one of TeX's mysterious mechanisms when activated.
  584. X% See The TeXbook, p.381 and p.352.
  585. X{\obeyspaces\global\let =\ }
  586. X
  587. X% Here is the main \fwbtx verbatim text macro.
  588. X% Note: The order in which all these pieces of business have to be done is
  589. X% still a partial mystery to me. Don't fiddle with this stuff unless you
  590. X% think you know what you are doing.
  591. X\def\fwbtx[{%
  592. X%
  593. X% The funnies involved in getting verbatim output are safely housed inside
  594. X% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
  595. X% instead of curly braces because we have to be able to signal the end of
  596. X% this macro with a curly brace.
  597. X\begingroup%
  598. X%
  599. X% \pars at the end of empty lines in the verbatim text won't come out normally
  600. X% because TeX is in vertical mode and they get gobbled up. To prevent this,
  601. X% we force \par to exit vertical mode first. See The TeXbook p.381.
  602. X\def\par{\leavevmode\endgraf}%
  603. X%
  604. X% Activate the leftquote character so as to avoid ligatures (see above).
  605. X\catcode`\`=\active%
  606. X%
  607. X% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
  608. X% that TeX will treat each verbatim line as a new paragraph.
  609. X\obeylines%
  610. X%
  611. X% To get verbatim output, we have to desex all the special characters. This
  612. X% is explained in detail in The TeXbook p.380.
  613. X\def\do##1{\catcode`##1=12 }\dospecials%
  614. X%
  615. X% Activate the space character so as to make TeX treat blanks seriously.
  616. X% This activation invokes an eralier definition (see above).
  617. X\obeyspaces
  618. X%
  619. X% Interparagraph skips do not help the cause.
  620. X% Note: We have to preserve the indentation though, as the code is actually
  621. X% indented in the final output. See \fwodef in an earlier section.
  622. X\parskip=0pt%
  623. X%
  624. X% We typeset the verbatim text in tt font (courier on the Macintosh) for a
  625. X% number of reasons:
  626. X%    - tt font has the same horizontal spacing for each character.
  627. X%    - tt font covers the ASCII character set.
  628. X%    - tt font doesn't have many surprises (e.g. ligatures).
  629. X%    - tt font looks much what you might see on a computer terminal screen.
  630. X\tt%
  631. X%
  632. X% Having set up an environment for verbatim, we are ready to use it.
  633. X% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
  634. X% part of the parameter of \fwverbatimgobble) until it sees the termination
  635. X% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
  636. X% must never occur in the verbatim text).
  637. X\fwverbatimgobble}
  638. X
  639. X% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
  640. X\def\fwverbatimgobble#1]fwetx={#1\endgroup}
  641. X
  642. X
  643. X% Table of Contents
  644. X% -----------------
  645. X% The five levels of table of contents that FunnelWeb supports are identified
  646. X% by the five letters [A..E]. These are used throughout the following macros.
  647. X
  648. X% The following macros are utilities to the TOC macros to follow.
  649. X\def\fwrule{\medskip\hrule\medskip}
  650. X\def\fwqh{\hskip1.5em\relax}
  651. X\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
  652. X
  653. X% The following macros are used to typeset the table of contents.
  654. X\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
  655. X\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
  656. X\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
  657. X\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
  658. X\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
  659. X\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
  660. X\def\fwtocfinish#1{\fwrule}
  661. X
  662. X% The following "library" macros define five different strengths of headings
  663. X% which can be used later in the section macros.
  664. X\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
  665. X\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
  666. X\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
  667. X\def\fwlibd#1#2{\fwbeforesec{\bf          #1 #2}\penalty200}
  668. X\def\fwlibe#1#2{\fwbeforesec{\bf          #1 #2}}
  669. X
  670. X% Here are the macros that actually typeset the section headings throughout
  671. X% the document. The fwlib system has been employed so as to easily allow the
  672. X% user to redefine the strengths of headings to taste. For example, the
  673. X% user could insert in the input document a similar set of definitions to these
  674. X% but with the b..e headings set to \fwlibc. This would tone down the output.
  675. X\def\fwseca#1#2{\fwliba{#1}{#2}}
  676. X\def\fwsecb#1#2{\fwlibb{#1}{#2}}
  677. X\def\fwsecc#1#2{\fwlibc{#1}{#2}}
  678. X\def\fwsecd#1#2{\fwlibd{#1}{#2}}
  679. X\def\fwsece#1#2{\fwlibe{#1}{#2}}
  680. X
  681. X
  682. X% Support for Explicit Typesetting
  683. X% --------------------------------
  684. X% FunnelWeb supports pragmas and other constructs that allow
  685. X% typesetter-independent typesetting commands to be given. The
  686. X% following macros support these features.
  687. X
  688. X% The in-text literal @{sloth@} and emphasise @[walrus@] features.
  689. X\def\fwlit#1{{\tt #1}}
  690. X\def\fwemp#1{{\it #1}}
  691. X
  692. X% The "@p new_page" pragma.
  693. X\def\fwnewpage{\vfill\eject}
  694. X
  695. X% The "@p vskip Nmm" pragma.
  696. X\def\fwvskip#1{\null\vskip #1mm}
  697. X
  698. X% The "@p title <font> <align> <text>" pragma.
  699. X\def\fwfontnormal#1{{\fwfontnorm {#1}}}
  700. X\def\fwfonttitle#1{{\fwfontboldd {#1}}}
  701. X\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
  702. X\def\fwleftline#1{\leftline{#1}}
  703. X\def\fwcenterline#1{\centerline{#1}}
  704. X\def\fwrightline#1{\rightline{#1}}
  705. X
  706. X
  707. X% Support for Old FunnelWeb
  708. X% -------------------------
  709. X% The following macros were used extensively in the first version of
  710. X% FunnelWeb and are retained so that these older input files will still
  711. X% typeset cleanly.
  712. X\def\p#1{{\tt #1}}  % P for Program text.
  713. X\def\flagpage#1#2{
  714. X   \null
  715. X   \vfill
  716. X   \centerline{\fwfontboldd #1}
  717. X   \vskip 1cm
  718. X   \centerline{\fwfontboldd #2}
  719. X   \vfill
  720. X   \null
  721. X   \vfill
  722. X}
  723. X
  724. X%====================== End of FunnelWeb TeX Definitions =======================
  725. X
  726. X\fwvskip{40}
  727. X\fwcenterline{\fwfonttitle{Powers:}}
  728. X\fwcenterline{\fwfonttitle{An Example of}}
  729. X\fwcenterline{\fwfonttitle{A Short}}
  730. X\fwcenterline{\fwfonttitle{FunnelWeb .fw File}}
  731. X\fwvskip{10}
  732. X\fwcenterline{\fwfontsmalltitle{by Ross Williams}}
  733. X\fwcenterline{\fwfontsmalltitle{26 January 1992}}
  734. X\fwvskip{20}
  735. X
  736. X\fwtocstart{}
  737. X\fwtoca{1}{FunnelWeb Example Program}
  738. X\fwtocb{1.1}{ex16.out}
  739. X\fwtocb{1.2}{Pull in packages}
  740. X\fwtocb{1.3}{Write out the first p powers of i on a single line}
  741. X\fwtocfinish{}
  742. X
  743. X
  744. X\fwseca{1}{FunnelWeb Example Program}
  745. X
  746. This  program writes  out each  of the  first \fwlit{p}  powers of  the first  \fwlit{n}
  747. integers. These  constant parameters are located  here so that they  are easy to
  748. change.
  749. X
  750. X\fwbeginmacro
  751. X\fwmacroname{Constants}{1}\fwequals \fwodef \fwbtx[n : constant natural := 10;     -- How many numbers? (Ans: [1,n]).
  752. p : constant natural :=  5;     -- How many powers?  (Ans: [1,p]).]fwetx=%
  753. X\fwcdef 
  754. X\fwbeginmacronotes
  755. X\fwusedin{This macro is invoked in definition 2.}
  756. X\fwendmacronotes
  757. X\fwendmacro
  758. X
  759. X
  760. X\fwsecb{1.1}{ex16.out} Here is  the outline of the  program. This FunnelWeb file  generates a single
  761. Ada output file  called \fwlit{Power.ada}. The main program consists  of a loop that
  762. iterates once for each number to be written out.
  763. X
  764. X\fwbeginmacro
  765. X\fwfilename{ex16.out}{2}\fwequals \fwodef \fwmacroname{Pull in packages}{3}\fwbtx[
  766. X
  767. procedure example is
  768. X   ]fwetx=%
  769. X\fwmacroname{Constants}{1}\fwbtx[
  770. begin -- example
  771. X   for i in 1..n loop
  772. X      ]fwetx=%
  773. X\fwmacroname{Write out the first p powers of i on a single line}{4}\fwbtx[
  774. X   end loop;
  775. end example;
  776. X]fwetx=%
  777. X\fwcdef 
  778. X\fwbeginmacronotes
  779. X\fwisafile{This macro is attached to an output file.}
  780. X\fwendmacronotes
  781. X\fwendmacro
  782. X
  783. X
  784. X\fwsecb{1.2}{Pull in packages} In this section,  we pull in the packages that this program  needs to run. In
  785. fact, all we need is the IO package so that we can write out the results. To use
  786. the IO package, we first of all need  to haul it in (\fwlit{with text\_io}) and then
  787. we need to make all its identifiers visible at the top level (\fwlit{use text\_io}).
  788. X
  789. X\fwbeginmacro
  790. X\fwmacroname{Pull in packages}{3}\fwequals \fwodef \fwbtx[with text_io; use text_io;]fwetx=%
  791. X\fwcdef 
  792. X\fwbeginmacronotes
  793. X\fwusedin{This macro is invoked in definition 2.}
  794. X\fwendmacronotes
  795. X\fwendmacro
  796. X
  797. X
  798. 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
  799. values  are  calculated  incrementally  in  \fwlit{ip}  to  avoid  the  use  of  the
  800. exponentiation operator.
  801. X
  802. X\fwbeginmacro
  803. X\fwmacroname{Write out the first p powers of i on a single line}{4}\fwequals \fwodef \fwbtx[declare
  804. X   ip : natural := 1;
  805. begin
  806. X   for power in 1..p loop
  807. X      ip:=ip*i;
  808. X      put(natural'image(ip) & " ");
  809. X   end loop;
  810. X   new_line;
  811. end;]fwetx=%
  812. X\fwcdef 
  813. X\fwbeginmacronotes
  814. X\fwusedin{This macro is invoked in definition 2.}
  815. X\fwendmacronotes
  816. X\fwendmacro
  817. X
  818. X
  819. X\bye
  820. X
  821. X
  822. X%*******************************************************************************
  823. X%*                    END OF AUTOMATICALLY GENERATED TEX FILE                  *
  824. X%*******************************************************************************
  825. X
  826. END_OF_FILE
  827. if test 18160 -ne `wc -c <'answers/ex16.tex'`; then
  828.     echo shar: \"'answers/ex16.tex'\" unpacked with wrong size!
  829. fi
  830. # end of 'answers/ex16.tex'
  831. fi
  832. if test -f 'answers/wv02.tex' -a "${1}" != "-c" ; then 
  833.   echo shar: Will not clobber existing file \"'answers/wv02.tex'\"
  834. else
  835. echo shar: Extracting \"'answers/wv02.tex'\" \(17380 characters\)
  836. sed "s/^X//" >'answers/wv02.tex' <<'END_OF_FILE'
  837. X
  838. X%*******************************************************************************
  839. X%*                    START OF AUTOMATICALLY GENERATED TEX FILE                *
  840. X%*******************************************************************************
  841. X%*                                                                             *
  842. X%* This TeX file was automatically generated by the FunnelWeb preprocessor.    *
  843. X%* You can typeset this file to produce printed documentation by running it    *
  844. X%* through the TeX typesetter using a command such as:                         *
  845. X%*    tex thisfilename                                                         *
  846. X%* The resultant file thisfilename.dvi can be printed using a command such as: *
  847. X%*    lpr -Pcslw -d thisfilename.dvi                                           *
  848. X%*                                                                             *
  849. X%* FunnelWeb is a preprocessor that allows programmers to weave programs and   *
  850. X%* their documentation together in a single document. The FunnelWeb program    *
  851. X%* analyses such documents producing both program files and typeset            *
  852. X%* documentation such as this TeX file.                                        *
  853. X%* FunnelWeb was created by Ross Williams.                                     *
  854. X%*                                                                             *
  855. X%* For more information on FunnelWeb look in the following FTP archive:        *
  856. X%*    Machine  : sirius.itd.adelaide.edu.au [IP=129.127.40.3].                 *
  857. X%*    Directory: ~pub/funnelweb/                                               *
  858. X%*               (or some other appropriately named directory).                *
  859. X%* or email Ross Williams at ross@spam.adelaide.edu.au                         *
  860. X%*                                                                             *
  861. X%*******************************************************************************
  862. X
  863. X
  864. X%===================== Start of FunnelWeb TeX Definitions ======================
  865. X
  866. X
  867. X% Version
  868. X% -------
  869. X% This is FunnelWeb TeX Macro Library Version 1.0.
  870. X
  871. X
  872. X% Copyright
  873. X% ---------
  874. X% This set of FunnelWeb TeX definitions was written by Ross Williams and was
  875. X% originally Copyright (C) 1992 Ross N. Williams.  However, I, Ross Williams,
  876. X% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
  877. X% and hereby authorize that the set of TeX definitions pass into the public
  878. X% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
  879. X
  880. X
  881. X% Modification
  882. X% ------------
  883. X% Please record all modifications to these TeX definitions here. Unless
  884. X% otherwise specified, all modified definitions fall in the public domain too.
  885. X%
  886. X% Programmers:
  887. X%    RNW  Ross N. Williams  ross@spam.adelaide.edu.au
  888. X%
  889. X% Changes:
  890. X%    07-May-1992  RNW  Prepared this work for public domain release.
  891. X%
  892. X
  893. X
  894. X% General Comments
  895. X% ----------------
  896. X% This set of TeX definitions exists for two reasons:
  897. X%
  898. X%    1. To shorten and neaten the FunnelWeb TeX output.
  899. X%    2. To allow users to fiddle with the output format in their input files
  900. X%       (by inserting redefining "\def"s) without having to resort to
  901. X%       modifying the FunnelWeb code.
  902. X%
  903. X% The user is warned that these definitions may be changed from time to time
  904. X% (but probably not much). The user should not be too sneaky. In particular,
  905. X% users wishing to redefine some of these macros should do so in an explicitly
  906. X% defined section at the top of their input file. This will mean that in the
  907. X% event of problems, that section can simply be deleted or commented out to
  908. X% allow the document to at least be typeset in the default format. Users should
  909. X% limit themselves to redefining these macros in such a section and should
  910. X% refrain from using the macros throughout their documents.
  911. X
  912. X
  913. X% Environment Parameters
  914. X% ----------------------
  915. X% \tolerance tells TeX how tolerant it should be about making bad line and
  916. X% page breaks. Here we set it to it's maximum, as
  917. X%   1) Computer programs are likely to cause lots of bad breaks.
  918. X%   2) In most cases the user would probably rather get the TeX file through
  919. X%      TeX without any errors than fiddle with spacings for perfection.
  920. X\tolerance=10000
  921. X
  922. X% I don't like indentation as it makes the page look more busy. Instead,
  923. X% paragraphs are separated by a little space (see next).
  924. X\parindent=0pt
  925. X
  926. X% In many cases, users will produce documents with long runs of paragraphs.
  927. X% In order to space out these paragraphs, it is convenient to maintain a
  928. X% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
  929. X% that the skip becomes a problem in macro definitions which require no skip
  930. X% and so we have to turn the skip on and off. The following two macros
  931. X% simplify this process.
  932. X\def\fwparskipon{\parskip=\medskipamount}
  933. X\def\fwparskipoff{\parskip=0pt}
  934. X\fwparskipon
  935. X
  936. X% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
  937. X% page in order to better vertically align the rest of the page (e.g. skips
  938. X% won't stretch as much). It also means that headings are less likely to be
  939. X% isolated at the bottom of the page without any following text.
  940. X\raggedbottom
  941. X
  942. X
  943. X% Fonts
  944. X% -----
  945. X% Most of the typeset output is set in 10pt roman and 10pt tt font.
  946. X% The major extra font needs spring from titles and headings.
  947. X% For portability's sake we use only the following fonts:
  948. X%    cmr10
  949. X%    cmbx10
  950. X%    cmtt10
  951. X% and some enlargements of them. These fonts are all "standard" fonts
  952. X% in Plain TeX. See The TeXbook p.350.
  953. X\font\fwfontnote=cmr7
  954. X
  955. X\font\fwfontnorm=cmr10
  956. X\font\fwfontnorma=cmr10 scaled \magstep1
  957. X\font\fwfontnormb=cmr10 scaled \magstep2
  958. X
  959. X\font\fwfontbold=cmbx10
  960. X\font\fwfontbolda=cmbx10 scaled \magstep1
  961. X\font\fwfontboldb=cmbx10 scaled \magstep2
  962. X\font\fwfontboldc=cmbx10 scaled \magstep3
  963. X\font\fwfontboldd=cmbx10 scaled \magstep4
  964. X
  965. X
  966. X% Macros for Stylistic Details
  967. X% ----------------------------
  968. X% This section contains all the fiddly little macros for setting the details
  969. X% of each macro definition.
  970. X
  971. X% Macro definitions are sandwiched by calls to these macros which can be used
  972. X% to sort out the spacing before and after the macro definition.
  973. X\def\fwbeginmacro{\fwparskipoff\bigskip}
  974. X\def\fwendmacro{\fwparskipon\par}
  975. X
  976. X% These macros deal with the macro name and definition line.
  977. X\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
  978. X\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
  979. X\def\fwzero#1{{\bf Z}}
  980. X\def\fwmany#1{{\bf M}}
  981. X\def\fwequals{ $\equiv$}
  982. X\def\fwplusequals{ $+\equiv$}
  983. X
  984. X% Now for the actual body of the definition. It looks nice to have the tt
  985. X% code indented a little. Again, we use macros instead of writing direct TeX,
  986. X% so as to allow the user to fiddle this stuff to taste without having to
  987. X% modify the FunnelWeb C code.
  988. X\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
  989. X\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
  990. X\def\fwoquote{`}
  991. X\def\fwcquote{'}
  992. X\def\fwoparen{$($}
  993. X\def\fwcomma{$,$}
  994. X\def\fwcparen{$)$}
  995. X\def\fwparam#1{$\diamond #1$}
  996. X\def\fwparams#1{$(\diamond #1)$}
  997. X
  998. X% These macros deal with the notes that are appended at the end of each
  999. X% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
  1000. X% have the same definition, they are given different names so as to allow the
  1001. X% user to redefine these macros to typeset each kind of information differently
  1002. X% if desired.
  1003. X\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
  1004. X\def\fwnote#1{{\fwfontnote #1}\par}
  1005. X\def\fwisafile#1{\fwnote{#1}}
  1006. X\def\fwusedin#1{\fwnote{#1}}
  1007. X\def\fwseealso#1{\fwnote{#1}}
  1008. X\def\fwendmacronotes{\endgroup}
  1009. X
  1010. X
  1011. X% Macros to Typeset Program Code Verbatim
  1012. X% ---------------------------------------
  1013. X% This is by far the hairiest and most difficult part of the typesetting task
  1014. X% because we have to turn off most of TeX's natural instincts in order to
  1015. X% typeset the program text exactly as it appears in the input file.
  1016. X% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
  1017. X% Their code was inspired by the following sections of "The TeXbook":
  1018. X%    Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
  1019. X%    Appendix E: Example Formats, p.421.
  1020. X% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
  1021. X% The liberal use of "%" is because I don't understand TeX well enough to
  1022. X% understand when an end of line will cause trouble, and I am playing it safe.
  1023. X
  1024. X% Before defining the main \fwbtx macro, we have to stash away some definitions
  1025. X% in the hidden part of TeX's environment. Let's hope that these "hidden"
  1026. X% definitions don't affect anything except what is desired to be affected.
  1027. X
  1028. X% The tt font in which we wish to set the text has two Latin lurking ligatures!
  1029. X% These are ?` and !`. To disable them, we define the left quote when ACTIVE
  1030. X% to be defined in such a way as to prevent ligatures. The main TeX text will
  1031. X% normally not be exposed to this definition because normally the leftquote
  1032. X% character is not active. The \fwbtx macro temporarily makes the left quote
  1033. X% character active thus activating the deactivation of left quote ligatures.
  1034. X% See The TeXbook p.381.
  1035. X{\catcode`\`=\active \gdef`{\relax\lq}}
  1036. X
  1037. X% TeX is fairly carefree about spaces and so we have to make it more serious.
  1038. X% To do so we pull the same trick as above, setting up a definition for active
  1039. X% space, but only making space active during the span of the verbatim text.
  1040. X% In Plain TeX the active space is defined to be simply a space, but here we
  1041. X% define it to be a control space. This ensures that the space cannot
  1042. X% be gobbled up by one of TeX's mysterious mechanisms when activated.
  1043. X% See The TeXbook, p.381 and p.352.
  1044. X{\obeyspaces\global\let =\ }
  1045. X
  1046. X% Here is the main \fwbtx verbatim text macro.
  1047. X% Note: The order in which all these pieces of business have to be done is
  1048. X% still a partial mystery to me. Don't fiddle with this stuff unless you
  1049. X% think you know what you are doing.
  1050. X\def\fwbtx[{%
  1051. X%
  1052. X% The funnies involved in getting verbatim output are safely housed inside
  1053. X% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
  1054. X% instead of curly braces because we have to be able to signal the end of
  1055. X% this macro with a curly brace.
  1056. X\begingroup%
  1057. X%
  1058. X% \pars at the end of empty lines in the verbatim text won't come out normally
  1059. X% because TeX is in vertical mode and they get gobbled up. To prevent this,
  1060. X% we force \par to exit vertical mode first. See The TeXbook p.381.
  1061. X\def\par{\leavevmode\endgraf}%
  1062. X%
  1063. X% Activate the leftquote character so as to avoid ligatures (see above).
  1064. X\catcode`\`=\active%
  1065. X%
  1066. X% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
  1067. X% that TeX will treat each verbatim line as a new paragraph.
  1068. X\obeylines%
  1069. X%
  1070. X% To get verbatim output, we have to desex all the special characters. This
  1071. X% is explained in detail in The TeXbook p.380.
  1072. X\def\do##1{\catcode`##1=12 }\dospecials%
  1073. X%
  1074. X% Activate the space character so as to make TeX treat blanks seriously.
  1075. X% This activation invokes an eralier definition (see above).
  1076. X\obeyspaces
  1077. X%
  1078. X% Interparagraph skips do not help the cause.
  1079. X% Note: We have to preserve the indentation though, as the code is actually
  1080. X% indented in the final output. See \fwodef in an earlier section.
  1081. X\parskip=0pt%
  1082. X%
  1083. X% We typeset the verbatim text in tt font (courier on the Macintosh) for a
  1084. X% number of reasons:
  1085. X%    - tt font has the same horizontal spacing for each character.
  1086. X%    - tt font covers the ASCII character set.
  1087. X%    - tt font doesn't have many surprises (e.g. ligatures).
  1088. X%    - tt font looks much what you might see on a computer terminal screen.
  1089. X\tt%
  1090. X%
  1091. X% Having set up an environment for verbatim, we are ready to use it.
  1092. X% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
  1093. X% part of the parameter of \fwverbatimgobble) until it sees the termination
  1094. X% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
  1095. X% must never occur in the verbatim text).
  1096. X\fwverbatimgobble}
  1097. X
  1098. X% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
  1099. X\def\fwverbatimgobble#1]fwetx={#1\endgroup}
  1100. X
  1101. X
  1102. X% Table of Contents
  1103. X% -----------------
  1104. X% The five levels of table of contents that FunnelWeb supports are identified
  1105. X% by the five letters [A..E]. These are used throughout the following macros.
  1106. X
  1107. X% The following macros are utilities to the TOC macros to follow.
  1108. X\def\fwrule{\medskip\hrule\medskip}
  1109. X\def\fwqh{\hskip1.5em\relax}
  1110. X\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
  1111. X
  1112. X% The following macros are used to typeset the table of contents.
  1113. X\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
  1114. X\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
  1115. X\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
  1116. X\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
  1117. X\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
  1118. X\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
  1119. X\def\fwtocfinish#1{\fwrule}
  1120. X
  1121. X% The following "library" macros define five different strengths of headings
  1122. X% which can be used later in the section macros.
  1123. X\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
  1124. X\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
  1125. X\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
  1126. X\def\fwlibd#1#2{\fwbeforesec{\bf          #1 #2}\penalty200}
  1127. X\def\fwlibe#1#2{\fwbeforesec{\bf          #1 #2}}
  1128. X
  1129. X% Here are the macros that actually typeset the section headings throughout
  1130. X% the document. The fwlib system has been employed so as to easily allow the
  1131. X% user to redefine the strengths of headings to taste. For example, the
  1132. X% user could insert in the input document a similar set of definitions to these
  1133. X% but with the b..e headings set to \fwlibc. This would tone down the output.
  1134. X\def\fwseca#1#2{\fwliba{#1}{#2}}
  1135. X\def\fwsecb#1#2{\fwlibb{#1}{#2}}
  1136. X\def\fwsecc#1#2{\fwlibc{#1}{#2}}
  1137. X\def\fwsecd#1#2{\fwlibd{#1}{#2}}
  1138. X\def\fwsece#1#2{\fwlibe{#1}{#2}}
  1139. X
  1140. X
  1141. X% Support for Explicit Typesetting
  1142. X% --------------------------------
  1143. X% FunnelWeb supports pragmas and other constructs that allow
  1144. X% typesetter-independent typesetting commands to be given. The
  1145. X% following macros support these features.
  1146. X
  1147. X% The in-text literal @{sloth@} and emphasise @[walrus@] features.
  1148. X\def\fwlit#1{{\tt #1}}
  1149. X\def\fwemp#1{{\it #1}}
  1150. X
  1151. X% The "@p new_page" pragma.
  1152. X\def\fwnewpage{\vfill\eject}
  1153. X
  1154. X% The "@p vskip Nmm" pragma.
  1155. X\def\fwvskip#1{\null\vskip #1mm}
  1156. X
  1157. X% The "@p title <font> <align> <text>" pragma.
  1158. X\def\fwfontnormal#1{{\fwfontnorm {#1}}}
  1159. X\def\fwfonttitle#1{{\fwfontboldd {#1}}}
  1160. X\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
  1161. X\def\fwleftline#1{\leftline{#1}}
  1162. X\def\fwcenterline#1{\centerline{#1}}
  1163. X\def\fwrightline#1{\rightline{#1}}
  1164. X
  1165. X
  1166. X% Support for Old FunnelWeb
  1167. X% -------------------------
  1168. X% The following macros were used extensively in the first version of
  1169. X% FunnelWeb and are retained so that these older input files will still
  1170. X% typeset cleanly.
  1171. X\def\p#1{{\tt #1}}  % P for Program text.
  1172. X\def\flagpage#1#2{
  1173. X   \null
  1174. X   \vfill
  1175. X   \centerline{\fwfontboldd #1}
  1176. X   \vskip 1cm
  1177. X   \centerline{\fwfontboldd #2}
  1178. X   \vfill
  1179. X   \null
  1180. X   \vfill
  1181. X}
  1182. X
  1183. X%====================== End of FunnelWeb TeX Definitions =======================
  1184. WV05: Test typesetting features.
  1185. X
  1186. X\fwbeginmacro
  1187. X\fwfilename{wv05.out}{1}\fwequals \fwodef \fwbtx[
  1188. X]fwetx=%
  1189. X\fwcdef 
  1190. X\fwbeginmacronotes
  1191. X\fwisafile{This macro is attached to an output file.}
  1192. X\fwendmacronotes
  1193. X\fwendmacro
  1194. X
  1195. X
  1196. X1. Test all five levels of headings with explicit titles.
  1197. X
  1198. X\fwseca{1}{One}
  1199. X\fwsecb{1.1}{Two}
  1200. X\fwsecc{1.1.1}{Three}
  1201. X\fwsecd{1.1.1.1}{Four}
  1202. X\fwsece{1.1.1.1.1}{Five}
  1203. X
  1204. X2. Test all five levels of headings with implicit titles.
  1205. X
  1206. X\fwseca{2}{Macro at level one}
  1207. X\fwbeginmacro
  1208. X\fwmacroname{Macro at level one}{2}\fwzero{}\fwequals \fwodef \fwbtx[Sloth]fwetx=%
  1209. X\fwcdef 
  1210. X\fwbeginmacronotes
  1211. X\fwusedin{This macro is NEVER invoked.}
  1212. X\fwendmacronotes
  1213. X\fwendmacro
  1214. X
  1215. X
  1216. X\fwsecb{2.1}{Macro at level two}
  1217. X\fwbeginmacro
  1218. X\fwmacroname{Macro at level two}{3}\fwzero{}\fwequals \fwodef \fwbtx[Walrus]fwetx=%
  1219. X\fwcdef 
  1220. X\fwbeginmacronotes
  1221. X\fwusedin{This macro is NEVER invoked.}
  1222. X\fwendmacronotes
  1223. X\fwendmacro
  1224. X
  1225. X
  1226. X\fwsecc{2.1.1}{Macro at level three}
  1227. X\fwbeginmacro
  1228. X\fwmacroname{Macro at level three}{4}\fwzero{}\fwequals \fwodef \fwbtx[Aardvark]fwetx=%
  1229. X\fwcdef 
  1230. X\fwbeginmacronotes
  1231. X\fwusedin{This macro is NEVER invoked.}
  1232. X\fwendmacronotes
  1233. X\fwendmacro
  1234. X
  1235. X
  1236. X\fwsecd{2.1.1.1}{Macro at level four}
  1237. X\fwbeginmacro
  1238. X\fwmacroname{Macro at level four}{5}\fwzero{}\fwequals \fwodef \fwbtx[Teapot]fwetx=%
  1239. X\fwcdef 
  1240. X\fwbeginmacronotes
  1241. X\fwusedin{This macro is NEVER invoked.}
  1242. X\fwendmacronotes
  1243. X\fwendmacro
  1244. X
  1245. X
  1246. X\fwsece{2.1.1.1.1}{Macro at level five}
  1247. X\fwbeginmacro
  1248. X\fwmacroname{Macro at level five}{6}\fwzero{}\fwequals \fwodef \fwbtx[Emu]fwetx=%
  1249. X\fwcdef 
  1250. X\fwbeginmacronotes
  1251. X\fwusedin{This macro is NEVER invoked.}
  1252. X\fwendmacronotes
  1253. X\fwendmacro
  1254. X
  1255. X
  1256. X3. Test the table of contents directive.
  1257. X
  1258. X\fwtocstart{}
  1259. X\fwtoca{1}{One}
  1260. X\fwtocb{1.1}{Two}
  1261. X\fwtocc{1.1.1}{Three}
  1262. X\fwtocd{1.1.1.1}{Four}
  1263. X\fwtoce{1.1.1.1.1}{Five}
  1264. X\fwtoca{2}{Macro at level one}
  1265. X\fwtocb{2.1}{Macro at level two}
  1266. X\fwtocc{2.1.1}{Macro at level three}
  1267. X\fwtocd{2.1.1.1}{Macro at level four}
  1268. X\fwtoce{2.1.1.1.1}{Macro at level five}
  1269. X\fwtocfinish{}
  1270. X
  1271. X
  1272. X4. Test the newpage directive.
  1273. X
  1274. X\fwnewpage
  1275. X
  1276. X
  1277. X5. Test the vskip directive.
  1278. X\fwvskip{50}
  1279. X
  1280. X6. Test the title directive.
  1281. X\fwcenterline{\fwfonttitle{This is a test Title}}
  1282. X
  1283. X
  1284. X\bye
  1285. X
  1286. X
  1287. X%*******************************************************************************
  1288. X%*                    END OF AUTOMATICALLY GENERATED TEX FILE                  *
  1289. X%*******************************************************************************
  1290. X
  1291. END_OF_FILE
  1292. if test 17380 -ne `wc -c <'answers/wv02.tex'`; then
  1293.     echo shar: \"'answers/wv02.tex'\" unpacked with wrong size!
  1294. fi
  1295. # end of 'answers/wv02.tex'
  1296. fi
  1297. if test -f 'hackman/h_ch2.tex' -a "${1}" != "-c" ; then 
  1298.   echo shar: Will not clobber existing file \"'hackman/h_ch2.tex'\"
  1299. else
  1300. echo shar: Extracting \"'hackman/h_ch2.tex'\" \(18854 characters\)
  1301. sed "s/^X//" >'hackman/h_ch2.tex' <<'END_OF_FILE'
  1302. X%==============================================================================%
  1303. X%                              Start of Ch2.tex                                %
  1304. X%==============================================================================%
  1305. X%
  1306. X% Copyright
  1307. X% ---------
  1308. X% Copyright (C) 1992 Ross N. Williams.
  1309. X% This file contains a chapter of the FunnelWeb Hacker's Manual.
  1310. X% See the main TeX file for this manual for further information.
  1311. X%
  1312. X%==============================================================================%
  1313. X
  1314. X\chapter{FunnelWeb Implementation}
  1315. X\label{chapimplementation}\xx{FunnelWeb}{implementation}
  1316. X
  1317. X\section{Introduction}
  1318. X
  1319. This chapter contains notes on the actual C code that implements
  1320. XFunnelWeb~V3. This chapter is rather patchy. It has acted mainly as
  1321. a dumping ground for ideas that I bothered to write about during
  1322. development.
  1323. X
  1324. X\section{History of FunnelWeb Implementations}
  1325. X\xx{FunnelWeb}{history}\x{FunnelWeb version 1}\x{FunnelWeb version 2}%
  1326. X\x{FunnelWeb version 3}
  1327. X
  1328. The first implementation of FunnelWeb (FunnelWeb~V1) was written in
  1329. Ada\x{Ada}
  1330. in December 1986. The project was initially canned as requiring too
  1331. much time, but was resurrected when I decided to commit to
  1332. Ada\paper{USDOD83} and
  1333. realized that I needed a program to write to help me to learn Ada.
  1334. XFunnelWeb~V1 was, in fact, my first Ada program. It took about one
  1335. month to write.
  1336. X
  1337. XFunnelWeb~V1 was used intensively by myself to write Ada programs
  1338. from January~1986 to July~1989 at which time
  1339. I finished my Ph.D.\x{Ph.D.} and lost access to
  1340. the VAX. During this time at least twenty thousand lines of code were generated
  1341. using FunnelWeb. Hardly anyone but myself used
  1342. XFunnelWeb.\xx{FunnelWeb}{past use}
  1343. X
  1344. After losing access to Ada and the Vax (and hence to FunnelWeb), I was forced
  1345. back to programming the non-literate way. From time to time I found that I
  1346. needed to use some of my old programs that I had written using Ada and
  1347. XFunnelWeb. I knew that Ada would become available on more machines, but
  1348. certainly FunnelWeb wouldn't. I recognised a strong need for a portable
  1349. version of FunnelWeb written in~C but didn't have the time or energy
  1350. to create one.
  1351. X
  1352. About this time (late 1989), David Hulse,\xn{David}{Hulse}
  1353. at the time a student in
  1354. Computer Science at the University of Adelaide,\xx{University}{Adelaide}
  1355. volunteered to translate the 4000 line Ada version of FunnelWeb into~C.
  1356. To my knowledge this translation process took about three weeks
  1357. X(in December 1989). The result was called FunnelWeb~V2 and was
  1358. formally signed into the public domain on 5~May 1992.
  1359. X
  1360. In general, David Hulse did a good job. However, the resultant code
  1361. suffered from one or few serious defects, the most serious of which was
  1362. a lack of portability.
  1363. X
  1364. Lack of portability of the C~code, combined with the need for a rather
  1365. solid design review, combined with the need to
  1366. strengthen the program to bring it up to production standard, resulted
  1367. in my performing a complete reworking of the code. The C code was
  1368. entirely, but incrementally, replaced or reformatted.
  1369. The code was also strengthened and new features were added.
  1370. This process took about two months (November and December 1991).
  1371. A further two months (approx) were spent writing documentation, constructing
  1372. a regression test suite, porting the program to different machines,
  1373. and sorting out the legal issues involved in its release.
  1374. X
  1375. I would like to take this opportunity to record a debt of gratitude to
  1376. David Hulse who translated FunnelWeb from Ada to~C. Although my
  1377. reworking of his C~code obliterated most of his code,
  1378. his translation was pivotal to the development process.
  1379. Without his effort in moving from Ada to~C, I'm not sure that I
  1380. would have mustered the energy and time to complete the process and
  1381. bring FunnelWeb up to its current standard.
  1382. X
  1383. X\section{Why FunnelWeb Wasn't Used to Write Itself}
  1384. X\xx{FunnelWeb}{writing itself}
  1385. X
  1386. After Knuth created the Web literate preprocessing system, he
  1387. re-wrote it using Web and distributed the source code in Web source form.
  1388. To allow the Web source code to be tangled by users not yet having a
  1389. copy of Web, he also included the tangled Pascal code for the Tangler.
  1390. X
  1391. While this approach is heroic and serves to convey a commitment and
  1392. a confidence in literate programming, it seemed to me that writing FunnelWeb
  1393. in FunnelWeb would simply be asking for trouble.\xx{trouble}{asking for}
  1394. XFor a start, it would be
  1395. very hard to modify any feature of FunnelWeb that had been used to write
  1396. XFunnelWeb, and the thought of what would happen if the working executable
  1397. became inoperative for some reason does not bear thinking upon.
  1398. X
  1399. One million billion computer programs were written in the non-literate
  1400. style before FunnelWeb was created. Why not one more?
  1401. X
  1402. X\section{Coding Style}
  1403. X\xx{coding}{style}
  1404. X
  1405. Although FunnelWeb wasn't coded under any particular coding standard,
  1406. it was coded in accordance with a fairly strict personal style of C
  1407. which developed during the development of FunnelWeb. This style was
  1408. subsequently embodied in a real C coding standard prepared for the
  1409. South\x{South Australian Government Department of Lands}
  1410. Australian Government
  1411. Department of Lands.\footnote{The standard
  1412. is currently unavailable, but is likely to be released or
  1413. published eventually.} Unfortunately, FunnelWeb was not
  1414. formally developed under the standard and so some holes remain in
  1415. XFunnelWeb's coding style. This section aims to describe some of the more
  1416. important aspects of the coding style.
  1417. X
  1418. X\thing{Portability:} This\x{portability}
  1419. was a major goal of the FunnelWeb implementation.
  1420. Two excellent books guided this move to portability.
  1421. They were \paper{Rabinowitz90} (which deals with C code itself)
  1422. and \paper{Horton90} (which deals with the portability of various library
  1423. calls). Other works such as \paper{Kernighan88} and
  1424. X\paper{ANSI} were also helpful.
  1425. X
  1426. X\thing{Identifiers:} \paper{Rabinowitz90}\x{identifier}{length}
  1427. specifies that for
  1428. wide portability, identifiers of block and file scope should be unique to
  1429. eight characters, and identifiers of program scope should be unique to
  1430. six characters. I have gone further in FunnelWeb and actually made these
  1431. restrictions actual limits on identifier length.
  1432. X
  1433. Because names must be so short, a system of abbreviations was developed to
  1434. organize the identifiers used within FunnelWeb. Each abbreviation consists
  1435. of a letter pair. Here are \i{some} of the abbreviations
  1436. used:\xx{identifier}{abbreviations}
  1437. X
  1438. X\begin{verbatim}
  1439. bp - Body Part.
  1440. cm - Compare. Used to prefix comparison routines that return [-1,0,1].
  1441. dc - Document component.
  1442. dm - Dump package.
  1443. el - Element.
  1444. eq - Equal. Used to prefix comparison routines that return a boolean.
  1445. ex - Expression.
  1446. f  - Global files.
  1447. ll - List of lists.
  1448. ln - Line record.
  1449. ls - List Package.
  1450. lr - Lister package.
  1451. ma - Macro.
  1452. mc - Macro Call.
  1453. mn - Macro Name.
  1454. op - Options package.
  1455. pr - Parser.
  1456. ps - Position record.
  1457. sc - Scrap record.
  1458. sn - Section.
  1459. tb - Table package.
  1460. ty - Typesetter directive.
  1461. wf - Write file package.
  1462. wl - Write with EOL (misc.c).
  1463. wr - Write          (misc.c).
  1464. X\end{verbatim}
  1465. X
  1466. X\thing{Pointers:} Variables or types denoting
  1467. pointers\xx{pointers}{naming} start with \dqp{p\_}.
  1468. X
  1469. X\thing{Types:} Names denoting types end in \dqp{\_t}.
  1470. Thus, a type for a pointer to a table would be named
  1471. X\p{p\_tb\_t}.\xx{types}{naming}
  1472. X
  1473. X\thing{File names:} All files\xx{filenames}{length}
  1474. used in FunnelWeb have file names that are
  1475. from one to eight characters long and file extensions that are from one to
  1476. three characters long. This ensures that the files can be portably moved
  1477. to all kinds of machines, even MSDOS!\x{MSDOS}
  1478. X
  1479. X\section{Use of Memory}
  1480. X\xx{use of}{memory}
  1481. X
  1482. XFunnelWeb is not a memory-stressed program. However, during its development,
  1483. problems with the management of memory seemed to crop up again and again.
  1484. This section documents some of these problems and the solutions adopted.
  1485. X
  1486. There are three places where memory can be obtained: the heap, the stack,
  1487. and from static variables. The following three sections deal with each
  1488. of these areas.
  1489. X
  1490. X\section{The Heap}
  1491. X\xx{heap}{memory}
  1492. X
  1493. One of the great frustrations of being a user is to find that a computer
  1494. program is complaining about lack of memory when one knows full well that
  1495. one has allocated at least ten times as much memory to the program as it
  1496. would ever need to do its job. The reason for such error messages usually
  1497. has to do with the programmer setting a fixed \dq{reasonable} limit to
  1498. a particular data structure and then locking it up into an array whose
  1499. bound is specified by a constant. While the use of arrays can increase the
  1500. speed of a program, it also means that the user cannot increase the capacity
  1501. of the program without obtaining the source code and recompiling it,
  1502. which is usually a daunting option.
  1503. X
  1504. The alternative is to use the heap for all data structures that can
  1505. grow in proportion to the size of the user's input. This rule has been
  1506. followed rigorously in FunnelWeb. This means that as memory spaces
  1507. increase, users will be able to hand their version of FunnelWeb more
  1508. memory without having to recompile it.
  1509. X
  1510. X\topicbreak
  1511. X
  1512. Some problems arose early on the Macintosh\x{Macintosh}
  1513. in the use of the heap. It seems
  1514. that some of the allocations I was attempting to make were failing for some
  1515. obscure reason, possibly my fault. Whatever it was, it went away when I
  1516. replaced direct calls to \p{malloc}\x{malloc}
  1517. with calls to a mini package I wrote
  1518. X(called \p{memory}) that allocated large chunks of memory and then doled out
  1519. small pieces as required by the rest of the
  1520. program.\xx{memory}{package}
  1521. X
  1522. Having a package to manage all the memory allocation had two other benefits.
  1523. X
  1524. XFirst, only one check was required in the entire program to see if memory
  1525. had run out (in the memory package), and if that failed, the program could
  1526. be brought to a screaming halt. This organization was far preferable to
  1527. having each piece of code that needed to allocate memory having to check
  1528. to see if \p{malloc} had failed.
  1529. X
  1530. Second, the decision to construct a mini-shell within FunnelWeb to
  1531. support regression testing meant that FunnelWeb proper could be run
  1532. many times in any given invocation of FunnelWeb. As a consequence it was
  1533. necessary to make sure that there was no memory
  1534. leakage\xx{memory}{leakage} between invocations
  1535. of FunnelWeb proper. This was accomplished by reworking the memory package
  1536. to operate a watermark system. The user of the package, when requesting
  1537. memory, could request \dq{temporary} or \dq{permanent}. If permanent, the
  1538. memory package forgot that it had allocated the memory. If temporary, the
  1539. memory package places the allocated block on a list. There was then a
  1540. function in the memory package that could be called to deallocate all the
  1541. temporary memory. Thus, so long as all requests for memory within FunnelWeb
  1542. proper were for temporary memory, and that memory was freed at the end of
  1543. every run, one could be sure that there was no memory leakage.
  1544. X
  1545. X\section{The Stack}
  1546. X\xx{stack}{memory}\xx{stack}{size}
  1547. X
  1548. XFor a while during the development of FunnelWeb a particularly nasty bug
  1549. proved extremely hard to find. The symptom was that FunnelWeb would crash,
  1550. sometimes at random, but more often upon entering a particular function.
  1551. In the end about a day of specific debugging was required before the problem
  1552. was tracked down to a stack problem. It turned out that somehow
  1553. X(either the fault of the Macintosh or the THINK~C language system), only
  1554. X6K was being allocated for stack space!!!!!!!
  1555. X
  1556. This experience led me immediately to go through the entire program and
  1557. eliminate (or remove to the heap) any automatic variable declarations that
  1558. used more than one hundred or so bytes.
  1559. X
  1560. The lesson is clearly that C~programs that use more than a few thousand bytes of
  1561. stack space are risking their portability. All large data structures should be
  1562. placed in the heap.
  1563. X
  1564. X\section{Static Variables}
  1565. X\xx{memory}{static}\xx{static}{variables}
  1566. X
  1567. Static variables also proved a problem on the Macintosh.
  1568. It turns out that
  1569. the Macintosh\x{Macintosh} THINK~C compiler\xx{ThinkC}{compiler}
  1570. does not allow more than 32K of statics
  1571. X\i{in the entire program}. For a while this restriction was
  1572. a serious threat to the program as it was discovered that constant strings
  1573. were included in this total! However, some searching revealed a compiler
  1574. option that removed the strings from the static category.
  1575. X
  1576. Nevertheless, the 32K limit is rather severe. Again, it seems that for
  1577. portability reasons, C~programs that use a lot of static variables are risking
  1578. their portability. As a result, the FunnelWeb code avoids static variables
  1579. where possible in favour of the heap.
  1580. X
  1581. X\section{Implementing Text Indentation}
  1582. X\xx{text}{indentation}
  1583. X
  1584. At one point during the development of FunnelWeb, text indentation was
  1585. fully implemented. However, it was subsequently removed because it was
  1586. considered a dangerous feature. This section records the way in which
  1587. text indentation was implemented so that if the feature ever has to be put
  1588. back, this technique can be used again.
  1589. X
  1590. X
  1591. X1. Create a new field in the \p{sc\_t} record call \p{sc\_postn}.
  1592. X
  1593. X\begin{verbatim}
  1594. X      char *sc_postn; /* Pointer in the range [sc_first,sc_last+1].           */
  1595. X                      /* It is the minimum possible value of sc_postn for     */
  1596. X                      /* which EOL does not appear in *sc_postn..*sc_last.    */
  1597. X                      /* i.e. Points to the byte following the first EOL in   */
  1598. X                      /* the scrap or sc_first if EOL does not appear.        */
  1599. X\end{verbatim}
  1600. X
  1601. X2. Modify the scanner so that it generates this field.
  1602. Sendtext should be modified so that
  1603. it accepts an argument for the \p{p\_postn} value.
  1604. X
  1605. X\begin{verbatim}
  1606. LOCAL void sendtext P_((p_ps_t,char *,char *,char *,bool));
  1607. LOCAL void sendtext(p_tkps,p_first,p_last,p_postn,is_white)
  1608. X/* Appends a text token to the end of the token list.                         */
  1609. X/* IN: p_ps is a pointer to a position structure giving the position of the   */
  1610. X/*     first character of the token.                                          */
  1611. X/* IN: p_first and p_last point to the first and last byte of the text scrap. */
  1612. X/* IN: p_postn has the same definition as sc_postn (see fwdata.h).            */
  1613. X/* IN: is_white should be set to TRUE iff scrap is entirely whitespace.       */
  1614. p_ps_t p_tkps;
  1615. char  *p_first;
  1616. char  *p_last;
  1617. char  *p_postn;
  1618. bool   is_white;
  1619. X{
  1620. X tk_t token;
  1621. X /* Empty text scraps should never be generated. */
  1622. X assert(p_first<=p_last,"sendtext: Text scrap bounds are bad.");
  1623. X /* If ch=EOL then we should be scanning more text, not shipping it! */
  1624. X assert(ch!=EOL,"senttext: Shipping text while still more to scan.");
  1625. X
  1626. X /* Check that p_postn is in range. See definition in fwdata.h. */
  1627. X assert(p_first<=p_postn && p_postn<=p_last+1,
  1628. X        "sendtext: p_postn is out of range.");
  1629. X /* Debug: Check the p_postn field using a brute force check. */
  1630. X {
  1631. X  char *i,*j;
  1632. X  j=p_first;
  1633. X  for (i=p_first;i<=p_last;i++)
  1634. X     if (*i==EOL)
  1635. X        j=i+1;
  1636. X  assert(j==p_postn,"sendtext: sc_postn field is incorrect.");
  1637. X }
  1638. X
  1639. X /* Load the text token. */
  1640. X token.tk_kind        = TK_TEXT;
  1641. X ASSIGN(token.tk_ps,*p_tkps);
  1642. X token.tk_sc.sc_first = p_first;
  1643. X token.tk_sc.sc_last  = p_last;
  1644. X token.tk_sc.sc_postn = p_postn;
  1645. X token.tk_white       = is_white;
  1646. X token.tk_parno       = 0;
  1647. X ls_add(token_list,PV &token);   
  1648. X}
  1649. X\end{verbatim}
  1650. X
  1651. Then all the calls to sendtext have to be changed:
  1652. X
  1653. X\begin{verbatim}
  1654. X/* @ instructs FunnelWeb to replace the special construct with the */
  1655. X/* special character. Luckily one appears just before the @ !!     */
  1656. X/* Note: FALSE is OK because space is not a legal specialch.       */
  1657. X/* Note: Setting parameter p_postn to p_ch-1 is OK as EOL is not a */
  1658. X/*       legal specialch.                                          */
  1659. sendtext(&ps_spec,p_ch-1,p_ch-1,p_ch-1,FALSE);
  1660. break;
  1661. X
  1662. X/* + instructs FunnelWeb to insert an EOL. We can't look to the end of */
  1663. X/* the previous line to find an EOL as this might be the first line.   */
  1664. X/* Running ahead to the end of the line is expensive, and having the   */
  1665. X/* liner mini-package maintain a variable for it would be extra        */
  1666. X/* housekeeping. Instead of all this, we just point to a static.       */
  1667. X{CONST static char stateol = EOL;
  1668. X sendtext(&ps_spec,&stateol,&stateol,(&stateol)+1,TRUE);}
  1669. break;
  1670. X
  1671. X/* If we hit something that ends a text token */
  1672. X/* then we can transmit a white text token.   */
  1673. if (ch==specialch || ch==EOFCH)
  1674. X   {sendtext(&ps_start,p_first,p_ch-1,MAX(p_sol,p_first),TRUE); return;}
  1675. X    
  1676. X/* Otherwise we have some more (non-white) text to scan. */
  1677. X/* We can then send a non-white text token.              */
  1678. while (ch!=specialch && ch!=EOFCH)
  1679. X   NEXTCH;
  1680. sendtext(&ps_start,p_first,p_ch-1,MAX(p_sol,p_first),FALSE);
  1681. X\end{verbatim}
  1682. X
  1683. The dump code needs to be changed too!
  1684. X
  1685. X\begin{verbatim}
  1686. X        wf_str(p_wf,"\"");
  1687. assert(token->tk_sc.sc_first !=NULL,"dm_tkls: NULL ptr1.");
  1688. assert(token->tk_sc.sc_last  !=NULL,"dm_tkls: NULL ptr2.");
  1689. for (i=token->tk_sc.sc_first; i<=token->tk_sc.sc_last; i++)
  1690. X  {
  1691. X   if (i==token->tk_sc.sc_postn)
  1692. X      wf_str(p_wf,"<postn>");
  1693. X   if (*i=='\n')
  1694. X      wf_wl(p_wf,"");
  1695. X   else
  1696. X      dm_byte(p_wf,*((ubyte_ *) i));
  1697. X  }
  1698. if (i==token->tk_sc.sc_postn)
  1699. X   wf_str(p_wf,"<postn>");
  1700. wf_str(p_wf,"\"");
  1701. X}
  1702. X\end{verbatim}
  1703. X
  1704. X3. Over in the Tangle module, create a massive array of pointers to scraps
  1705. to be used as a stack. Maintain pointers into the stack called \p{current} and
  1706. X\i{base} (similar to the blank indentation variables). Implement the following:
  1707. X
  1708. X\begin{itemize}
  1709. X
  1710. X\item To write out a scrap, scan it byte by byte. Output each byte. When
  1711. you hit an EOL, pop the stack back to \p{base}. Then write out an EOL
  1712. followed by the stack contents but writing each scrap only from \p{postn} to
  1713. end end of each scrap.
  1714. When you have finished the new scrap, push it on the stack.
  1715. X
  1716. X\item When you hit a new macro to expand, save \p{base}. Restore it later.   
  1717. X
  1718. X\end{itemize}
  1719. X
  1720. The \p{postn} field solves the big problem of
  1721. how to cope with something like this:
  1722. X
  1723. X\begin{verbatim}
  1724. The rain in Spain
  1725. falls mainly @<on the plain@>
  1726. X\end{verbatim}
  1727. X
  1728. The trouble is that we want to text indent the lines in
  1729. X\p{@<on the plain@>} with
  1730. just \dqp{falls mainly~}. However, this string is only part of a scrap. The
  1731. solution is to get the scanner to record, in the \p{postn} field of each scrap,
  1732. the position of the first byte with a EOL-free run to the end of the scrap.
  1733. X
  1734. This scheme is very efficient because all we are doing is pushing and popping
  1735. pointers to scraps on a stack array. The main disadvantage is that the
  1736. array must necessarily be finite and would impose a limit on the depth
  1737. of indentation nesting (not a big problem).
  1738. X
  1739. X%==============================================================================%
  1740. X%                              Start of Ch2.tex                                %
  1741. X%==============================================================================%
  1742. END_OF_FILE
  1743. if test 18854 -ne `wc -c <'hackman/h_ch2.tex'`; then
  1744.     echo shar: \"'hackman/h_ch2.tex'\" unpacked with wrong size!
  1745. fi
  1746. # end of 'hackman/h_ch2.tex'
  1747. fi
  1748. if test -f 'hackman/h_ch4.tex' -a "${1}" != "-c" ; then 
  1749.   echo shar: Will not clobber existing file \"'hackman/h_ch4.tex'\"
  1750. else
  1751. echo shar: Extracting \"'hackman/h_ch4.tex'\" \(18004 characters\)
  1752. sed "s/^X//" >'hackman/h_ch4.tex' <<'END_OF_FILE'
  1753. X%==============================================================================%
  1754. X%                              Start of Ch4.tex                                %
  1755. X%==============================================================================%
  1756. X%
  1757. X% Copyright
  1758. X% ---------
  1759. X% Copyright (C) 1992 Ross N. Williams.
  1760. X% This file contains a chapter of the FunnelWeb Hacker's Manual.
  1761. X% See the main TeX file for this manual for further information.
  1762. X%
  1763. X%==============================================================================%
  1764. X
  1765. X\chapter{FunnelWeb Future}
  1766. X\label{chapfuture}\xx{FunnelWeb}{future}
  1767. X
  1768. Previous chapters have explained the design of FunnelWeb and given reasons
  1769. for why it is the way it is. This chapter goes through each of the
  1770. aspects of FunnelWeb, and explores their problems, how they can be solved,
  1771. and lists opportunities for improvement.
  1772. X
  1773. X\section{Documentation}
  1774. X\x{documentation}
  1775. X
  1776. X\thing{An official example:} A official example program written using
  1777. XFunnelWeb should be constructed and made available.\xx{official}{example}
  1778. X
  1779. X\thing{Index program:} In order to typeset the documentation, a portable
  1780. index sorting program is required. One should be written and added to the
  1781. distribution kit.\xx{index}{program} Perhaps this could be the official
  1782. example!
  1783. X
  1784. X\section{Command Line Interface}
  1785. X\xx{command}{interface}
  1786. X
  1787. X\thing{Buffer length:} Currently the FunnelWeb shell uses the
  1788. X\p{COMLINE\_MAX} constant to size its internal command line buffers.
  1789. This is untenable. The maximum length of a shell command line should
  1790. not be machine dependent.
  1791. X
  1792. X\thing{Antiquated Features:} As the FunnelWeb language develops, it is likely
  1793. that some changes will have to be made that will render one or more
  1794. language constructs obsolete. When this happens, it may be necessary to
  1795. add a command line option that has the power to turn on and off warnings or
  1796. errors flagging antiquated features.\xx{antiquated}{features}
  1797. X
  1798. X\section{Shell Interpreter}
  1799. X\xx{shell}{interpreter}\xx{command}{interpreter}
  1800. X
  1801. X\thing{SETALL command:} When writing FunnelWeb scripts, it is sometimes
  1802. desirable to set \i{all} of FunnelWeb's options\x{options}
  1803. to some particular value
  1804. so that the script is not vulnerable to changes in FunnelWeb's default
  1805. values which might occur from time to time. To this end, it may be worth
  1806. creating a \dqp{SETALL} command that is identical to the \dqp{SET} command
  1807. except that it will generate an error if the value of an option is not
  1808. specified explicitly.\xx{setall}{command}
  1809. X
  1810. X\thing{Recursion test:} A test should be added to test for recursive
  1811. invocation in a shellscript.\xx{recursion}{test}
  1812. X
  1813. X\thing{Diagnostic counting:} The code for counting diagnostics in the
  1814. script interpreter is rather messy and perhaps even buggy. It should be
  1815. cleaned up and commented.\xx{diagnostic}{counting}
  1816. X
  1817. X\thing{Argument counting:} In the \p{command.c} module, there is a variable
  1818. that counts the arguments to a command. Currently it takes the value of
  1819. the number of parameters including the command verb. This has turned out
  1820. to make the code less readable. It should be changed to be the number of
  1821. arguments to the command verb.
  1822. X
  1823. X\thing{Make facility:} It may be worth building some sort of make facility
  1824. into the script language so as to support machines such as the Macintosh
  1825. that do not already have this facility.\x{make}
  1826. X
  1827. X\thing{Signature file:} One problem with using FunnelWeb in conjunction with
  1828. an external \p{Make} facility is that a user might change a FunnelWeb source
  1829. file without making changes that will affect the files that it generates.
  1830. If FunnelWeb is then run and the \dqp{+D} option is on, then the output
  1831. files will be deleted (to avoid further \p{Make} propagations).
  1832. If \p{Make} then has a production linking the \p{.fw} file to its output
  1833. files, then it may conclude that the output files are still out of date.
  1834. To solve the problem, FunnelWeb could be changed to write a \p{.sig} file
  1835. whenever it processes a \p{.fw} file. The \p{Make} production could then
  1836. be wired up to link
  1837. the \p{.fw} file to the \p{.sig} file instead of to the output
  1838. files.\xx{signature}{file}
  1839. X  
  1840. X\section{Language Design}
  1841. X\xx{language}{design}
  1842. X
  1843. Some proposed changes to FunnelWeb do not correspond to
  1844. any particular component of FunnelWeb
  1845. and are really to do with the design of the input language.
  1846. X
  1847. X\thing{Output or file?:} The \dqp{@O} special sequence for defining an output
  1848. file is somewhat non-mnemonic and can be confused with zero (\dqp{0}). Perhaps
  1849. it should be replaced by the \dqp{@F} sequence.
  1850. X
  1851. X\thing{Syntax of section names:} Currently section names use
  1852. the same syntax as macro names. For example \dqp{@<Sloth@>}. It can be
  1853. argued that angle brackets should be reserved only for macro names and that
  1854. some other syntax should be found for delimiting section names. This is not
  1855. a clear issue. It could also be argued that they are both names, and that
  1856. because sections can inherit their names from the macros they contain, that
  1857. the names are of the same \dq{type}.\xx{section}{syntax}
  1858. X
  1859. X\thing{One macro per section:} One particular style of using FunnelWeb is
  1860. to have at most one macro definition per section. It may be worth adding
  1861. a pragma that instructs FunnelWeb to enforce this.
  1862. X
  1863. X\thing{Should @\{ suppress EOL?:} When defining a macro in FunnelWeb, it
  1864. seems to be rule rather than the exception that the
  1865. X\dqp{@\{} be followed by \dqp{@-}. This suppresses the EOL on the definition
  1866. line, allowing the first line of the macro to be placed immediately
  1867. above and in line with the other
  1868. lines without introducing an EOL at the start of the macro text.
  1869. One option is to introduce a pragma to determine whether to suppress EOLs
  1870. following \dqp{@\{}.
  1871. X
  1872. X\thing{Pragma syntax:} It is not clear how \dq{loose} the syntax of pragmas
  1873. should be. Perhaps they should be case insensitive.\xx{pragma}{syntax}
  1874. X
  1875. X\thing{Conditionals:} Depending on demand, it may be worth reintroducing
  1876. some sort of conditional feature into FunnelWeb. However, it would have to
  1877. be very simple to compete with the various ways in which conditionals
  1878. can already be fudged within FunnelWeb as it stands.\x{conditionals}
  1879. X
  1880. X\thing{File markers:} It might be worth modifying the language so that
  1881. a special syntactical marker is required at the start and end of files.
  1882. This will assist in detecting truncations and other
  1883. corruptions.\xx{file}{markers}
  1884. X
  1885. X\thing{Formal parameter lists:} It might be worth changing over to a
  1886. syntax for formal parameter lists that does not require the \p{@(} and
  1887. X\p{@)}. However, they could be retained as optional for backward
  1888. compatibility.\xx{parameter list}{formal}
  1889. X
  1890. X\section{Scanner/Mapper}
  1891. X\x{scanner}\x{mapper}
  1892. X
  1893. X\thing{All non-contiguous mappings:} Currently FunnelWeb requires that all
  1894. input files be mapped into a contiguous lump of memory. This caused problems
  1895. for two reasons. First, to do this, one has to allocate the memory first,
  1896. and to do that, you have to know how long the file is, and it turns out that
  1897. finding out the length of a file in a portable manner is very inefficient.
  1898. Second, although IBM PC compatibles may have megabytes of memory, it is
  1899. segmented into blocks of at most 64K. This means that FunnelWeb currently
  1900. cannot read a file longer than 64K on a PC.\xx{contiguous}{memory}
  1901. X
  1902. These problems could be avoided if the mapper and scanner were reorganized to
  1903. allow input files to be read in and stored as a linked list of chunks of text
  1904. rather than a contiguous block.
  1905. X
  1906. X\thing{EOL is unspecifiable:} FunnelWeb uses ASCII character decimal ten (10)
  1907. internally to represent logical end-of-line and is currently organized so that
  1908. if one of these is inserted into the text by the user using a
  1909. X\dqp{@\circumflex{}D(10)}, it will be written out as a logical end of line,
  1910. rather than as a single ASCII character 10. This should be
  1911. fixed.\xx{representation}{EOL}
  1912. X
  1913. X\thing{Allow mnemonics for unprintables:} FunnelWeb allows users to insert
  1914. unprintable characters into the output using the \dqp{@\circumflex{}D(ddd)}
  1915. special sequence. Perhaps it would be changed so that it understands ASCII
  1916. standard mnemonics such as \dqp{LF} as well as ASCII
  1917. numbers.\xx{ASCII}{mnemonics}
  1918. X
  1919. X\thing{Version pragma:} A \dqp{version} pragma should be added that allows
  1920. the user to specify in the input file the version of FunnelWeb that was
  1921. around when the input file was created. At a later date, such a construct
  1922. would be very useful for determining how an input file should be updated
  1923. if the FunnelWeb language has changed between
  1924. versions.\xx{version}{pragma}
  1925. X
  1926. X\section{Parser}
  1927. X\x{parser}
  1928. X
  1929. There are no proposals to change the parser except as a consequence of
  1930. other proposals.
  1931. X
  1932. X\section{Analyser}
  1933. X\x{analyser}
  1934. X
  1935. X\thing{Recursion detection:} Currently the FunnelWeb analyser flags, with
  1936. an error, all macros with an infinite expansion. This would be best
  1937. changed to flagging all macros that are directly or indirectly recursive.
  1938. To do this, Tarjan's algorithm\paper{Tarjan72}\xn{Robert Endre}{Tarjan}
  1939. for the detection of strong components should
  1940. be installed.\xx{recursion}{detection}
  1941. X
  1942. X\thing{Once only macros:} By default FunnelWeb prevents a macro from being
  1943. called more than once unless it has a \dqp{@M} associated with it. However,
  1944. XFunnelWeb does allow a macro that calls such a macro to be called more
  1945. than once. Perhaps this \dq{loophole} should be plugged somehow.
  1946. X
  1947. X  
  1948. X\section{Tangle}
  1949. X\x{tangle}
  1950. X
  1951. The Tangler is one of the cleanest components of FunnelWeb, as basically all it
  1952. has to do is expand some very well-defined macros.
  1953. X
  1954. X\thing{Text indentation:} Currently FunnelWeb supports \i{no indentation}
  1955. and \i{blank indentation}. A third form could be added if it was considered
  1956. necessary. \i{Text indentation} is the same as \i{blank indentation} except
  1957. that instead of indenting with blanks, FunnelWeb would indent with the
  1958. text to the left of the called macro. This facility could be useful for
  1959. commenting out large bodies of text in languages that do not have
  1960. multi-line comments (e.g. Ada). A discussion of the pros and cons of this
  1961. form of indentation appears earlier.\xx{text}{indentation}
  1962. X
  1963. X\section{Weave}
  1964. X\x{weave}
  1965. X
  1966. Perhaps FunnelWeb's weakest aspect is its typesetting facility.
  1967. X
  1968. X
  1969. X\thing{Align table of contents:} When FunnelWeb generates a table of contents,
  1970. the section numbers are not quite aligned with the start of the controlling
  1971. heading above them.\x{table of contents}
  1972. X
  1973. X\thing{Typesetting strength:} It should be possible to specify the
  1974. level of typesetting strength for headings so that short documents do not
  1975. look overdone when typeset. A new pragma would be good for
  1976. this.\xx{strength}{typesetting}
  1977. X
  1978. X\thing{Typeset a portion:} Sometimes it is desirable to typeset just a
  1979. portion of a program. A command line option could be added to do
  1980. this. The option could accept as its argument, a string containing a list
  1981. of section numbers or heading names.
  1982. X
  1983. X\thing{Generic typesetter option:} In addition to building in a number
  1984. of different versions of Weave, one for each popular typesetter, it would be
  1985. possible to add a special generic format where the typeset output is
  1986. expressed in terms of \i{FunnelWeb macros}. The user could then specify
  1987. macro definitions for a non-supported typesetter and run the output
  1988. through FunnelWeb Tangle to get a typeset file in a format suitable for the
  1989. unsupported typesetter.\xx{typesetter}{generic}
  1990. X
  1991. X\thing{Suppression of include files:} It should be possible to specify
  1992. in the input file that particular included files not appear in the
  1993. typeset output. Currently, the fact that an inclusion has occurred is
  1994. not even represented in the typeset output. Suppression of inclusions
  1995. is particularly necessary where a library of macros has been included
  1996. at the top of each of a group of source files.\xx{include file}{suppression}
  1997. X
  1998. X\thing{Cross reference of identifiers:} WEB provides a list of identifiers
  1999. and a list of all the definitions in which they are used. A similar
  2000. feature could be added to FunnelWeb.\xx{cross}{references}
  2001. X
  2002. X\thing{Support for non-printables:} Currently FunnelWeb does not provide
  2003. support for typesetting the special \dqp{@\circumflex(num)} sequences.
  2004. This should be added.
  2005. X
  2006. X\thing{Support for @+ sequences:} Currently Weave does not see \dqp{@+}
  2007. sequences as such. Instead it perceives them as ordinary EOLs. However,
  2008. there are arguments for typesetting them specially.
  2009. X
  2010. X\thing{Typeset text in macro bodies:} One of the much-loved features
  2011. of WEB is the way that it allows the user to switch recursively between
  2012. document and program formats. FunnelWeb does not allow this, but
  2013. should. In FunnelWeb, the delimiters \dqp{@\{} and \dqp{@\}} are already
  2014. used consistently to delimit macro text. The \dqp{@[} and \dqp{@]} sequences
  2015. have been reserved for the delimitation of documentation text.
  2016. X
  2017. X\thing{Non-tt typesetting:} The current version of FunnelWeb sets all its
  2018. macro text in \p{tt font}. This is both a blessing and a curse. It is a
  2019. blessing because it connects the reader directly to the code, with no
  2020. complicated intermediary. It is a curse because it looks ugly compared to
  2021. the beautifully typeset programs produced by other literate programming
  2022. tools.
  2023. X
  2024. The difficulty with adding such beautiful typesetting is that it is
  2025. necessarily language-specific. Keywords and syntax differ from language
  2026. to language and it would not be easy to come up with a set of language
  2027. independent rules.
  2028. X
  2029. One approach is to write a set of Weave back-ends, one for each language.
  2030. Another approach is to \i{generate} back ends. This is the approach
  2031. taken in the \i{Spider} system\paper{Ramsey89}.\x{spider}
  2032. In the \i{Spider} system,
  2033. the programmer writes production rules for converting lexical components
  2034. of the program text into typesetter instructions. The \i{Spider} program
  2035. reads these rules and generates a new version of WEB suited for the target
  2036. language.
  2037. X
  2038. XFor FunnelWeb a slightly different system is proposed in which Spider-like
  2039. rules appear in the input file and are used directly by Weave to perform the
  2040. typesetting. An intermediate abstract typesetting language could be used
  2041. so that the productions can be made language specific, but not typesetter
  2042. specific.
  2043. X
  2044. X\section{Lister}
  2045. X\x{lister}
  2046. X
  2047. X\thing{Glue factor:} A glue factor could be added that determines how many
  2048. lines can be in between two diagnostics in the listing before the two
  2049. groups of lines are joined together in the listing with no intervening
  2050. ellipsis.\xx{glue}{factor}
  2051. X
  2052. X\section{Diagnostics}
  2053. X\x{diagnostics}
  2054. X
  2055. X\thing{Advisory information:} Some of FunnelWeb's diagnostics provide
  2056. a detailed explanatory paragraph. While this information might be useful the
  2057. first time, it has the capacity to clog up a listing file if the user has
  2058. made the same error many times. To solve this problem, FunnelWeb could be
  2059. modified so that such explanations are only displayed the first time the
  2060. error occurs.
  2061. X
  2062. X\thing{Abort after n errors:} A facility could be added to prevent
  2063. XFunnelWeb's scanning, parsing, and analysing phases from continuing if
  2064. a certain number of errors have already been issued.
  2065. X
  2066. X
  2067. X\section{Speed}
  2068. X\x{speed}\x{efficiency}
  2069. X
  2070. X\thing{Measurement of speed:} Although FunnelWeb can generate a breakdown
  2071. of where it is spending its time, it does not give a final rating in
  2072. lines per minute. This should be added.
  2073. X
  2074. X\thing{Find the hot spots:} Although FunnelWeb has been designed to allow
  2075. high speed, not much effort has so far been made to make it fast. This should
  2076. be done.
  2077. X
  2078. X\thing{Change some declarations:} FunnelWeb is full of variable declarations
  2079. where the variables are wider than they need be. Replacing these might speed
  2080. it up.
  2081. X
  2082. X\section{Correctness}
  2083. X\x{correctness}
  2084. X
  2085. X\thing{Bounds analysis:} Not much effort has gone into the design of
  2086. XFunnelWeb's input boundaries. An analysis should be made of FunnelWeb's
  2087. behaviour when the following quantities are stretched:
  2088. X
  2089. X\begin{itemize}
  2090. X\item Input line length.
  2091. X\item Input file size.
  2092. X\item Number of macros.
  2093. X\item Length of macro.
  2094. X\end{itemize}
  2095. X
  2096. In particular, FunnelWeb's behaviour at 32K and 64K boundaries should be
  2097. observed.
  2098. X
  2099. X\thing{Stack detection:} Macintosh THINK-C provides just 6K of memory for
  2100. the stack. It might be worth adding checks to make sure that the stack is
  2101. not being blown.
  2102. X
  2103. X\section{Test Suite}
  2104. X\xx{test}{suite}
  2105. X
  2106. The following tests should be added to the test suite:
  2107. X
  2108. X\begin{verbatim}
  2109. Lister
  2110. X------
  2111. X   LR01: Test with a full listing with no diagnostics.
  2112. X   LR02: Test with a full listing with diagnostics.
  2113. X   LR03: Test with an abbreviated listing with no diagnostics.
  2114. X   LR04: Test with an abbreviated listing with diagnostics.
  2115. X   LR05: Test error context system with nearby diagnostics.
  2116. X
  2117. Boundary Cases
  2118. X--------------
  2119. Static analysis might preclude the need for most of these tests.
  2120. X   BC01: Test what happens when memory runs out.
  2121. X   BC02: Test on a file with a single line of a megabyte.
  2122. X   BC03: Test on a file of a megabyte of EOLs.
  2123. X   BC04: Generate an output file with an extremely long line.
  2124. X   BC05: Generate an output file with one million lines.
  2125. X   BC06: Test on a file with very many macros.
  2126. X
  2127. General
  2128. X-------
  2129. X   GN01: A large legal input file exercising as many features as possible.
  2130. X         1. Test listing file.
  2131. X         2. Test output files.
  2132. X         3. Test typeset file.
  2133. X   GN... A selection of ten real-life FunnelWeb files.
  2134. X\end{verbatim}
  2135. X
  2136. X\section{Machine-Specific Changes}
  2137. X
  2138. X\thing{Icon for the Macintosh:} Currently no icon is supplied for the
  2139. Macintosh version of FunnelWeb. An icon depicting a spider or a funnelled
  2140. web of some kind would seem appropriate.
  2141. X
  2142. X\section{Summary}
  2143. X
  2144. This chapter has describes some of the problems with FunnelWeb and some of the
  2145. opportunities that exist for improving it. The direction and speed in which
  2146. XFunnelWeb will develop will depend largely on user feedback. If you have any
  2147. strong feelings on where FunnelWeb should go, please email them to
  2148. Ross Williams (\p{ross@spam.adelaide.edu.au}).
  2149. X
  2150. X
  2151. X%==============================================================================%
  2152. X%                              Start of Ch4.tex                                %
  2153. X%==============================================================================%
  2154. END_OF_FILE
  2155. if test 18004 -ne `wc -c <'hackman/h_ch4.tex'`; then
  2156.     echo shar: \"'hackman/h_ch4.tex'\" unpacked with wrong size!
  2157. fi
  2158. # end of 'hackman/h_ch4.tex'
  2159. fi
  2160. if test -f 'sources/help_gnu.txt' -a "${1}" != "-c" ; then 
  2161.   echo shar: Will not clobber existing file \"'sources/help_gnu.txt'\"
  2162. else
  2163. echo shar: Extracting \"'sources/help_gnu.txt'\" \(17977 characters\)
  2164. sed "s/^X//" >'sources/help_gnu.txt' <<'END_OF_FILE'
  2165. X            GNU GENERAL PUBLIC LICENSE
  2166. X               Version 2, June 1991
  2167. X
  2168. X Copyright (C) 1989, 1991 Free Software Foundation, Inc.
  2169. X                          675 Mass Ave, Cambridge, MA 02139, USA
  2170. X Everyone is permitted to copy and distribute verbatim copies
  2171. X of this license document, but changing it is not allowed.
  2172. X
  2173. X                Preamble
  2174. X
  2175. X  The licenses for most software are designed to take away your
  2176. freedom to share and change it.  By contrast, the GNU General Public
  2177. License is intended to guarantee your freedom to share and change free
  2178. software--to make sure the software is free for all its users.  This
  2179. General Public License applies to most of the Free Software
  2180. XFoundation's software and to any other program whose authors commit to
  2181. using it.  (Some other Free Software Foundation software is covered by
  2182. the GNU Library General Public License instead.)  You can apply it to
  2183. your programs, too.
  2184. X
  2185. X  When we speak of free software, we are referring to freedom, not
  2186. price.  Our General Public Licenses are designed to make sure that you
  2187. have the freedom to distribute copies of free software (and charge for
  2188. this service if you wish), that you receive source code or can get it
  2189. if you want it, that you can change the software or use pieces of it
  2190. in new free programs; and that you know you can do these things.
  2191. X
  2192. X  To protect your rights, we need to make restrictions that forbid
  2193. anyone to deny you these rights or to ask you to surrender the rights.
  2194. These restrictions translate to certain responsibilities for you if you
  2195. distribute copies of the software, or if you modify it.
  2196. X
  2197. X  For example, if you distribute copies of such a program, whether
  2198. gratis or for a fee, you must give the recipients all the rights that
  2199. you have.  You must make sure that they, too, receive or can get the
  2200. source code.  And you must show them these terms so they know their
  2201. rights.
  2202. X
  2203. X  We protect your rights with two steps: (1) copyright the software, and
  2204. X(2) offer you this license which gives you legal permission to copy,
  2205. distribute and/or modify the software.
  2206. X
  2207. X  Also, for each author's protection and ours, we want to make certain
  2208. that everyone understands that there is no warranty for this free
  2209. software.  If the software is modified by someone else and passed on, we
  2210. want its recipients to know that what they have is not the original, so
  2211. that any problems introduced by others will not reflect on the original
  2212. authors' reputations.
  2213. X
  2214. X  Finally, any free program is threatened constantly by software
  2215. patents.  We wish to avoid the danger that redistributors of a free
  2216. program will individually obtain patent licenses, in effect making the
  2217. program proprietary.  To prevent this, we have made it clear that any
  2218. patent must be licensed for everyone's free use or not licensed at all.
  2219. X
  2220. X  The precise terms and conditions for copying, distribution and
  2221. modification follow.
  2222. X
  2223. X            GNU GENERAL PUBLIC LICENSE
  2224. X   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
  2225. X
  2226. X  0. This License applies to any program or other work which contains
  2227. a notice placed by the copyright holder saying it may be distributed
  2228. under the terms of this General Public License.  The "Program", below,
  2229. refers to any such program or work, and a "work based on the Program"
  2230. means either the Program or any derivative work under copyright law:
  2231. that is to say, a work containing the Program or a portion of it,
  2232. either verbatim or with modifications and/or translated into another
  2233. language.  (Hereinafter, translation is included without limitation in
  2234. the term "modification".)  Each licensee is addressed as "you".
  2235. X
  2236. Activities other than copying, distribution and modification are not
  2237. covered by this License; they are outside its scope.  The act of
  2238. running the Program is not restricted, and the output from the Program
  2239. is covered only if its contents constitute a work based on the
  2240. Program (independent of having been made by running the Program).
  2241. Whether that is true depends on what the Program does.
  2242. X
  2243. X  1. You may copy and distribute verbatim copies of the Program's
  2244. source code as you receive it, in any medium, provided that you
  2245. conspicuously and appropriately publish on each copy an appropriate
  2246. copyright notice and disclaimer of warranty; keep intact all the
  2247. notices that refer to this License and to the absence of any warranty;
  2248. and give any other recipients of the Program a copy of this License
  2249. along with the Program.
  2250. X
  2251. You may charge a fee for the physical act of transferring a copy, and
  2252. you may at your option offer warranty protection in exchange for a fee.
  2253. X
  2254. X  2. You may modify your copy or copies of the Program or any portion
  2255. of it, thus forming a work based on the Program, and copy and
  2256. distribute such modifications or work under the terms of Section 1
  2257. above, provided that you also meet all of these conditions:
  2258. X
  2259. X    a) You must cause the modified files to carry prominent notices
  2260. X    stating that you changed the files and the date of any change.
  2261. X
  2262. X    b) You must cause any work that you distribute or publish, that in
  2263. X    whole or in part contains or is derived from the Program or any
  2264. X    part thereof, to be licensed as a whole at no charge to all third
  2265. X    parties under the terms of this License.
  2266. X
  2267. X    c) If the modified program normally reads commands interactively
  2268. X    when run, you must cause it, when started running for such
  2269. X    interactive use in the most ordinary way, to print or display an
  2270. X    announcement including an appropriate copyright notice and a
  2271. X    notice that there is no warranty (or else, saying that you provide
  2272. X    a warranty) and that users may redistribute the program under
  2273. X    these conditions, and telling the user how to view a copy of this
  2274. X    License.  (Exception: if the Program itself is interactive but
  2275. X    does not normally print such an announcement, your work based on
  2276. X    the Program is not required to print an announcement.)
  2277. X
  2278. These requirements apply to the modified work as a whole.  If
  2279. identifiable sections of that work are not derived from the Program,
  2280. and can be reasonably considered independent and separate works in
  2281. themselves, then this License, and its terms, do not apply to those
  2282. sections when you distribute them as separate works.  But when you
  2283. distribute the same sections as part of a whole which is a work based
  2284. on the Program, the distribution of the whole must be on the terms of
  2285. this License, whose permissions for other licensees extend to the
  2286. entire whole, and thus to each and every part regardless of who wrote it.
  2287. X
  2288. Thus, it is not the intent of this section to claim rights or contest
  2289. your rights to work written entirely by you; rather, the intent is to
  2290. exercise the right to control the distribution of derivative or
  2291. collective works based on the Program.
  2292. X
  2293. In addition, mere aggregation of another work not based on the Program
  2294. with the Program (or with a work based on the Program) on a volume of
  2295. a storage or distribution medium does not bring the other work under
  2296. the scope of this License.
  2297. X
  2298. X  3. You may copy and distribute the Program (or a work based on it,
  2299. under Section 2) in object code or executable form under the terms of
  2300. Sections 1 and 2 above provided that you also do one of the following:
  2301. X
  2302. X    a) Accompany it with the complete corresponding machine-readable
  2303. X    source code, which must be distributed under the terms of Sections
  2304. X    1 and 2 above on a medium customarily used for software interchange; or,
  2305. X
  2306. X    b) Accompany it with a written offer, valid for at least three
  2307. X    years, to give any third party, for a charge no more than your
  2308. X    cost of physically performing source distribution, a complete
  2309. X    machine-readable copy of the corresponding source code, to be
  2310. X    distributed under the terms of Sections 1 and 2 above on a medium
  2311. X    customarily used for software interchange; or,
  2312. X
  2313. X    c) Accompany it with the information you received as to the offer
  2314. X    to distribute corresponding source code.  (This alternative is
  2315. X    allowed only for noncommercial distribution and only if you
  2316. X    received the program in object code or executable form with such
  2317. X    an offer, in accord with Subsection b above.)
  2318. X
  2319. The source code for a work means the preferred form of the work for
  2320. making modifications to it.  For an executable work, complete source
  2321. code means all the source code for all modules it contains, plus any
  2322. associated interface definition files, plus the scripts used to
  2323. control compilation and installation of the executable.  However, as a
  2324. special exception, the source code distributed need not include
  2325. anything that is normally distributed (in either source or binary
  2326. form) with the major components (compiler, kernel, and so on) of the
  2327. operating system on which the executable runs, unless that component
  2328. itself accompanies the executable.
  2329. X
  2330. If distribution of executable or object code is made by offering
  2331. access to copy from a designated place, then offering equivalent
  2332. access to copy the source code from the same place counts as
  2333. distribution of the source code, even though third parties are not
  2334. compelled to copy the source along with the object code.
  2335. X
  2336. X  4. You may not copy, modify, sublicense, or distribute the Program
  2337. except as expressly provided under this License.  Any attempt
  2338. otherwise to copy, modify, sublicense or distribute the Program is
  2339. void, and will automatically terminate your rights under this License.
  2340. However, parties who have received copies, or rights, from you under
  2341. this License will not have their licenses terminated so long as such
  2342. parties remain in full compliance.
  2343. X
  2344. X  5. You are not required to accept this License, since you have not
  2345. signed it.  However, nothing else grants you permission to modify or
  2346. distribute the Program or its derivative works.  These actions are
  2347. prohibited by law if you do not accept this License.  Therefore, by
  2348. modifying or distributing the Program (or any work based on the
  2349. Program), you indicate your acceptance of this License to do so, and
  2350. all its terms and conditions for copying, distributing or modifying
  2351. the Program or works based on it.
  2352. X
  2353. X  6. Each time you redistribute the Program (or any work based on the
  2354. Program), the recipient automatically receives a license from the
  2355. original licensor to copy, distribute or modify the Program subject to
  2356. these terms and conditions.  You may not impose any further
  2357. restrictions on the recipients' exercise of the rights granted herein.
  2358. You are not responsible for enforcing compliance by third parties to
  2359. this License.
  2360. X
  2361. X  7. If, as a consequence of a court judgment or allegation of patent
  2362. infringement or for any other reason (not limited to patent issues),
  2363. conditions are imposed on you (whether by court order, agreement or
  2364. otherwise) that contradict the conditions of this License, they do not
  2365. excuse you from the conditions of this License.  If you cannot
  2366. distribute so as to satisfy simultaneously your obligations under this
  2367. License and any other pertinent obligations, then as a consequence you
  2368. may not distribute the Program at all.  For example, if a patent
  2369. license would not permit royalty-free redistribution of the Program by
  2370. all those who receive copies directly or indirectly through you, then
  2371. the only way you could satisfy both it and this License would be to
  2372. refrain entirely from distribution of the Program.
  2373. X
  2374. If any portion of this section is held invalid or unenforceable under
  2375. any particular circumstance, the balance of the section is intended to
  2376. apply and the section as a whole is intended to apply in other
  2377. circumstances.
  2378. X
  2379. It is not the purpose of this section to induce you to infringe any
  2380. patents or other property right claims or to contest validity of any
  2381. such claims; this section has the sole purpose of protecting the
  2382. integrity of the free software distribution system, which is
  2383. implemented by public license practices.  Many people have made
  2384. generous contributions to the wide range of software distributed
  2385. through that system in reliance on consistent application of that
  2386. system; it is up to the author/donor to decide if he or she is willing
  2387. to distribute software through any other system and a licensee cannot
  2388. impose that choice.
  2389. X
  2390. This section is intended to make thoroughly clear what is believed to
  2391. be a consequence of the rest of this License.
  2392. X
  2393. X  8. If the distribution and/or use of the Program is restricted in
  2394. certain countries either by patents or by copyrighted interfaces, the
  2395. original copyright holder who places the Program under this License
  2396. may add an explicit geographical distribution limitation excluding
  2397. those countries, so that distribution is permitted only in or among
  2398. countries not thus excluded.  In such case, this License incorporates
  2399. the limitation as if written in the body of this License.
  2400. X
  2401. X  9. The Free Software Foundation may publish revised and/or new versions
  2402. of the General Public License from time to time.  Such new versions will
  2403. be similar in spirit to the present version, but may differ in detail to
  2404. address new problems or concerns.
  2405. X
  2406. XEach version is given a distinguishing version number.  If the Program
  2407. specifies a version number of this License which applies to it and "any
  2408. later version", you have the option of following the terms and conditions
  2409. either of that version or of any later version published by the Free
  2410. Software Foundation.  If the Program does not specify a version number of
  2411. this License, you may choose any version ever published by the Free Software
  2412. XFoundation.
  2413. X
  2414. X  10. If you wish to incorporate parts of the Program into other free
  2415. programs whose distribution conditions are different, write to the author
  2416. to ask for permission.  For software which is copyrighted by the Free
  2417. Software Foundation, write to the Free Software Foundation; we sometimes
  2418. make exceptions for this.  Our decision will be guided by the two goals
  2419. of preserving the free status of all derivatives of our free software and
  2420. of promoting the sharing and reuse of software generally.
  2421. X
  2422. X                NO WARRANTY
  2423. X
  2424. X  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
  2425. XFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
  2426. OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
  2427. PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
  2428. OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  2429. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
  2430. TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
  2431. PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
  2432. REPAIR OR CORRECTION.
  2433. X
  2434. X  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
  2435. WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
  2436. REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
  2437. INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
  2438. OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
  2439. TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
  2440. YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
  2441. PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
  2442. POSSIBILITY OF SUCH DAMAGES.
  2443. X
  2444. X             END OF TERMS AND CONDITIONS
  2445. X
  2446. X    Appendix: How to Apply These Terms to Your New Programs
  2447. X
  2448. X  If you develop a new program, and you want it to be of the greatest
  2449. possible use to the public, the best way to achieve this is to make it
  2450. free software which everyone can redistribute and change under these terms.
  2451. X
  2452. X  To do so, attach the following notices to the program.  It is safest
  2453. to attach them to the start of each source file to most effectively
  2454. convey the exclusion of warranty; and each file should have at least
  2455. the "copyright" line and a pointer to where the full notice is found.
  2456. X
  2457. X    <one line to give the program's name and a brief idea of what it does.>
  2458. X    Copyright (C) 19yy  <name of author>
  2459. X
  2460. X    This program is free software; you can redistribute it and/or modify
  2461. X    it under the terms of the GNU General Public License as published by
  2462. X    the Free Software Foundation; either version 2 of the License, or
  2463. X    (at your option) any later version.
  2464. X
  2465. X    This program is distributed in the hope that it will be useful,
  2466. X    but WITHOUT ANY WARRANTY; without even the implied warranty of
  2467. X    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2468. X    GNU General Public License for more details.
  2469. X
  2470. X    You should have received a copy of the GNU General Public License
  2471. X    along with this program; if not, write to the Free Software
  2472. X    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2473. X
  2474. Also add information on how to contact you by electronic and paper mail.
  2475. X
  2476. If the program is interactive, make it output a short notice like this
  2477. when it starts in an interactive mode:
  2478. X
  2479. X    Gnomovision version 69, Copyright (C) 19yy name of author
  2480. X    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
  2481. X    This is free software, and you are welcome to redistribute it
  2482. X    under certain conditions; type `show c' for details.
  2483. X
  2484. The hypothetical commands `show w' and `show c' should show the appropriate
  2485. parts of the General Public License.  Of course, the commands you use may
  2486. be called something other than `show w' and `show c'; they could even be
  2487. mouse-clicks or menu items--whatever suits your program.
  2488. X
  2489. You should also get your employer (if you work as a programmer) or your
  2490. school, if any, to sign a "copyright disclaimer" for the program, if
  2491. necessary.  Here is a sample; alter the names:
  2492. X
  2493. X  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
  2494. X  `Gnomovision' (which makes passes at compilers) written by James Hacker.
  2495. X
  2496. X  <signature of Ty Coon>, 1 April 1989
  2497. X  Ty Coon, President of Vice
  2498. X
  2499. This General Public License does not permit incorporating your program into
  2500. proprietary programs.  If your program is a subroutine library, you may
  2501. consider it more useful to permit linking proprietary applications with the
  2502. library.  If this is what you want to do, use the GNU Library General
  2503. Public License instead of this License.
  2504. END_OF_FILE
  2505. if test 17977 -ne `wc -c <'sources/help_gnu.txt'`; then
  2506.     echo shar: \"'sources/help_gnu.txt'\" unpacked with wrong size!
  2507. fi
  2508. # end of 'sources/help_gnu.txt'
  2509. fi
  2510. if test -f 'sources/tangle.c' -a "${1}" != "-c" ; then 
  2511.   echo shar: Will not clobber existing file \"'sources/tangle.c'\"
  2512. else
  2513. echo shar: Extracting \"'sources/tangle.c'\" \(18625 characters\)
  2514. sed "s/^X//" >'sources/tangle.c' <<'END_OF_FILE'
  2515. X/*##############################################################################
  2516. X
  2517. XFUNNNELWEB COPYRIGHT
  2518. X====================
  2519. XFunnelWeb is a literate-programming macro preprocessor.
  2520. X
  2521. Copyright (C) 1992 Ross N. Williams.
  2522. X
  2523. X   Ross N. Williams
  2524. X   ross@spam.adelaide.edu.au
  2525. X   16 Lerwick Avenue, Hazelwood Park 5066, Australia.
  2526. X
  2527. This program is free software; you can redistribute it and/or modify
  2528. it under the terms of Version 2 of the GNU General Public License as
  2529. published by the Free Software Foundation.
  2530. X
  2531. This program is distributed WITHOUT ANY WARRANTY; without even the implied
  2532. warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  2533. See Version 2 of the GNU General Public License for more details.
  2534. X
  2535. You should have received a copy of Version 2 of the GNU General Public
  2536. License along with this program. If not, you can FTP the license from
  2537. prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
  2538. XFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2539. X
  2540. Section 2a of the license requires that all changes to this file be
  2541. recorded prominently in this file. Please record all changes here.
  2542. X
  2543. Programmers:
  2544. X   RNW  Ross N. Williams  ross@spam.adelaide.edu.au
  2545. X
  2546. Changes:
  2547. X   07-May-1992  RNW  Program prepared for release under GNU GPL V2.
  2548. X
  2549. X##############################################################################*/
  2550. X
  2551. X
  2552. X/******************************************************************************/
  2553. X/*                                   TANGLE.C                                 */
  2554. X/******************************************************************************/
  2555. X
  2556. X/* Note: In this module, "ex_" at the start of a function name means "expand" */
  2557. X/*       rather than the standard meaning of "ex" of "expression.             */
  2558. X
  2559. X/******************************************************************************/
  2560. X
  2561. X#include "style.h"
  2562. X
  2563. X#include "as.h"
  2564. X#include "data.h"
  2565. X#include "lister.h"
  2566. X#include "memory.h"
  2567. X#include "misc.h"
  2568. X#include "table.h"
  2569. X#include "tangle.h"
  2570. X#include "writfile.h"
  2571. X
  2572. X/******************************************************************************/
  2573. X
  2574. X/* The following variable keeps track of the output line number. This is      */
  2575. X/* needed to report lines that are too long.                                  */
  2576. LOCVAR ulong lineno;
  2577. X
  2578. X/* Last line for which error message was generated.    */
  2579. LOCVAR ulong errlin;
  2580. X
  2581. X/* Number of too-long lines seen so far in this file. */
  2582. LOCVAR ulong numlong;
  2583. X/* Number of long line error messages we can tolerate per product file. */
  2584. X#define LONGMESS 5
  2585. X
  2586. X/* Note: An indentation of n means n blanks before current material.          */
  2587. X/* tgindent is a global variable set by the scanner. It is TRUE if blank      */
  2588. X/* indenting is required and FALSE if no indenting is required.               */
  2589. LOCVAR ulong ind_base;  /* Base indenting level of macro being expanded.      */
  2590. LOCVAR ulong ind_curr;  /* Current indenting position.                        */
  2591. X
  2592. LOCVAR char  *fn_targ;  /* Name of current (target) product file.             */
  2593. LOCVAR wf_t  f_o;       /* Current product file.                              */
  2594. X
  2595. X/******************************************************************************/
  2596. X
  2597. X/* The expression expansion function has to have a forward declaration. */
  2598. LOCAL void ex_ex P_((p_ells_t));
  2599. X
  2600. X/******************************************************************************/
  2601. X
  2602. LOCAL void eolblank P_((ulong));
  2603. LOCAL void eolblank(n)
  2604. X/* Writes an EOL followed by n blanks to the product file. Efficiently!       */
  2605. ulong n;
  2606. X{
  2607. X /* The whole aim of this routine is to write blanks EFFICIENTLY. In          */
  2608. X /* particular avoiding any per-char procedure call overhead (e.g. calls to   */
  2609. X /* wf_chr). The best way to avoid this is to create a static array of blanks */
  2610. X /* and write out large blocks of blanks all at once.                         */
  2611. X#define BLANKLEN 100             /* Number of BLANKS in blank array.          */
  2612. X STAVAR bool notinit=TRUE;       /* Has blank array been initialized?         */
  2613. X STAVAR char blanks[1+BLANKLEN]; /* EOL followed by BLANKLEN blanks.          */
  2614. X
  2615. X /* Set up the blank array. This only ever done once because of the static    */
  2616. X /* boolean. Note that use of an initialized static here does not make the    */
  2617. X /* code non-reentrant, as the state does not change after initialization.    */
  2618. X if (notinit)
  2619. X    {blanks[0]=EOL; memset(blanks+1,' ',(size_t) BLANKLEN); notinit=FALSE;}
  2620. X
  2621. X /* The most common case will be a small indentation. Do this case fast. */
  2622. X if (n<=BLANKLEN)
  2623. X    wf_blk(&f_o,&blanks[0],(size_t) n+1);
  2624. X else
  2625. X   {
  2626. X    /* We now know that n>=BLANKLEN. Write out a long line with \n at front. */
  2627. X    wf_blk(&f_o,&blanks[0],BLANKLEN+1); n-=BLANKLEN;
  2628. X
  2629. X    /* Now get into large scale blank production! */
  2630. X    while (n>0)
  2631. X      {
  2632. X       ulong len=MIN(n,BLANKLEN);
  2633. X       wf_blk(&f_o,&blanks[1],(size_t) len); n-=len;
  2634. X      }
  2635. X   }
  2636. X}
  2637. X
  2638. X/******************************************************************************/
  2639. X
  2640. X#define SENDLINE {wl_l(linet1); if (option.op_s_b) wl_sj(linet1);}
  2641. X
  2642. LOCAL void ex_sc P_((p_sc_t));
  2643. LOCAL void ex_sc(p_sc)
  2644. X/* This function writes the specified scrap to the product file. It also      */
  2645. X/* performs two other tasks:                                                  */
  2646. X/*    If tgindent==TRUE, inserts indentation at the start of each line.       */
  2647. X/*    If tglinmax>0, checks for product file lines longer than tglinmax.      */
  2648. X/* Note: The speed of this routine is fairly critical.                        */
  2649. p_sc_t p_sc;
  2650. X{
  2651. X /* Output of a scrap is straightforward if we are not inserting indentation  */
  2652. X /* or watching for lines that are too long. If neither of these tasks have   */
  2653. X /* to be performed, we can bang the scrap out directly with a wf_blk.        */
  2654. X if (!tgindent && tglinmax==TGMAXINF)
  2655. X   {
  2656. X    wf_blk(&f_o, p_sc->sc_first, (size_t) (p_sc->sc_last-p_sc->sc_first+1));
  2657. X    return;
  2658. X   }
  2659. X
  2660. X /* Otherwise it gets rather messy. Basically, we have to watch for end of    */
  2661. X /* lines and perform special actions there.                                  */
  2662. X /* ind_curr is the number of characters already written to the current line. */
  2663. X {
  2664. X  char *p      = p_sc->sc_first;
  2665. X  char *p_post = p_sc->sc_last+1;
  2666. X  while (TRUE)
  2667. X    {
  2668. X     char *p_sot = p;  /* SOT=Start of Text. */
  2669. X
  2670. X     /* Scan scrap until we hit either its end or an EOL. */
  2671. X     while (p!=p_post && *p!=EOL) p++;
  2672. X
  2673. X     /* Assert: p==p_post || (p_sot<=p<p_post && *p==EOL). */
  2674. X
  2675. X     /* If we scanned any non-EOL text, write out what we scanned. */
  2676. X     if (p>p_sot) {wf_blk(&f_o,p_sot,(size_t) (p-p_sot));ind_curr+=p-p_sot;}
  2677. X
  2678. X     /* Check that what we have written so far is not too long.            */
  2679. X     /* Performing this check here rather than with the EOL processing     */
  2680. X     /* means that we will detect overlong final non-EOL terminated lines. */
  2681. X     /* Use of errlin suppresses multiple errors on the same line.         */
  2682. X     /* Note: We assume that TGMAXINF is very large.                       */
  2683. X     if (ind_curr>tglinmax && lineno!=errlin)
  2684. X       {
  2685. X        numlong++;
  2686. X        if (numlong <= LONGMESS)
  2687. X          {
  2688. X           if (option.op_b7_b)
  2689. X              sprintf(linet1,
  2690. X                      "E: Product file line is too long (line %lu of \"%s\").",
  2691. X                             (ulong) lineno,SUPPNAME);
  2692. X           else
  2693. X              sprintf(linet1,
  2694. X                      "E: Product file line is too long (line %lu of \"%s\").",
  2695. X                             (ulong) lineno,fn_targ);
  2696. X           SENDLINE;
  2697. X           if (numlong==1)
  2698. X             {
  2699. X              sprintf(linet1,"   Product file line length limit is %lu characters.",
  2700. X                             (ulong) tglinmax);
  2701. X              SENDLINE;
  2702. X              sprintf(linet1,"   Note: You can change the limit by specifying.");
  2703. X              SENDLINE;
  2704. X              sprintf(linet1,"      @p maximum_output_line_length = <desired length>");
  2705. X              SENDLINE;
  2706. X              sprintf(linet1,"   somewhere in the input file.");
  2707. X              SENDLINE;
  2708. X             }
  2709. X           errlin=lineno;
  2710. X           num_err++;
  2711. X          }
  2712. X        if (numlong == LONGMESS+1)
  2713. X          {
  2714. X           sprintf(linet1,
  2715. X           "Further line-too-long warnings for file \"%s\" have been suppressed.",
  2716. X              fn_targ);
  2717. X           SENDLINE;
  2718. X          }
  2719. X       }
  2720. X
  2721. X     /* Exit if we hit the end of the scrap. */
  2722. X     if (p==p_post) break;
  2723. X
  2724. X     /* Move past the EOL and bump up the line counter. */
  2725. X     p++; lineno++;
  2726. X
  2727. X     /* Output an EOL with indentation if desired. */
  2728. X     if (tgindent)
  2729. X        eolblank(ind_base);
  2730. X     else
  2731. X        wf_chr(&f_o,EOL);
  2732. X     ind_curr=ind_base;
  2733. X    }
  2734. X }
  2735. X}
  2736. X
  2737. X/******************************************************************************/
  2738. X
  2739. LOCAL void ex_eltx P_((p_el_t));
  2740. LOCAL void ex_eltx(p_el)
  2741. X/* Writes the given text element to the product file. */
  2742. p_el_t p_el;
  2743. X{
  2744. X p_sc_t p_sc;
  2745. X
  2746. X /* Make sure that we have actually been handed a text element. */
  2747. X as_cold(p_el->el_kind==EL_TEXT,"ex_eltx: Not a text element!");
  2748. X
  2749. X /* Write all the scraps in the text list to the product file. */
  2750. X ls_fir(p_el->el_text);
  2751. X while (TRUE)
  2752. X   {
  2753. X    ls_nxt(p_el->el_text,PPV &p_sc);
  2754. X    if (p_sc==NULL) break;
  2755. X    ex_sc(p_sc);
  2756. X   }
  2757. X}
  2758. X
  2759. X/******************************************************************************/
  2760. X
  2761. LOCAL void ex_elpr P_((p_el_t));
  2762. LOCAL void ex_elpr(p_el)
  2763. X/* Write the expansion of the given parameter element to the product file. */
  2764. p_el_t p_el;
  2765. X{
  2766. X p_ell3_t  actn = p_el->el_which->ma_actn;
  2767. X p_elll_t *pp_parls;
  2768. X p_ells_t *pp_exp;
  2769. X ulong    ind_save;
  2770. X
  2771. X /* Make sure that we have been handed a parameter element. */
  2772. X as_cold(p_el->el_kind==EL_PARM,"ex_elpr: Not a parameter element!");
  2773. X
  2774. X /* Save the current indentation base and set it to the current level. */
  2775. X ind_save=ind_base;
  2776. X ind_base=ind_curr;
  2777. X
  2778. X /* Get a pointer to the most recent parameter list of the target macro. */
  2779. X ls_loo(actn,ls_len(actn),PPV &pp_parls);
  2780. X
  2781. X /* Get the expression corresponding to the el_parno'th parameter. */
  2782. X ls_loo(*pp_parls,p_el->el_parno,PPV &pp_exp);
  2783. X
  2784. X /* Expand that expression. */
  2785. X ex_ex(*pp_exp);
  2786. X
  2787. X /* Restore the indentation base. */
  2788. X ind_base=ind_save;
  2789. X}
  2790. X
  2791. X/******************************************************************************/
  2792. X
  2793. LOCAL void ex_elin P_((p_el_t));
  2794. LOCAL void ex_elin(p_el)
  2795. X/* Expand invocation element. */
  2796. p_el_t p_el;
  2797. X{
  2798. X p_ma_t p_ma;
  2799. X p_bp_t p_bp;
  2800. X ulong  ind_save;
  2801. X p_void p_mark;
  2802. X
  2803. X /* Make sure that we have been handed an invocation element. */
  2804. X as_cold(p_el->el_kind==EL_INVC,"ex_elin: Not an invocation element!");
  2805. X
  2806. X /* Save the current indentation base and set it to the current level. */
  2807. X ind_save=ind_base;
  2808. X ind_base=ind_curr;
  2809. X
  2810. X /* Grab a pointer to the macro being invoked. */
  2811. X p_ma=p_el->el_p_mac;
  2812. X
  2813. X /* Push the actual parameter list onto the invoked macro's activation list. */
  2814. X ls_add(p_ma->ma_actn,PV &p_el->el_parls);
  2815. X
  2816. X /* Expand each body part expression. */
  2817. X ls_fir(p_ma->ma_defn.md_body);
  2818. X while (TRUE)
  2819. X   {
  2820. X    ls_nxt(p_ma->ma_defn.md_body,PPV &p_bp);
  2821. X    if (p_bp==NULL) break;
  2822. X    p_mark=ls_mar(p_ma->ma_defn.md_body); /* Protect againt recursion. */
  2823. X    ex_ex(p_bp->bp_ex);
  2824. X    ls_set(p_ma->ma_defn.md_body,p_mark);
  2825. X   }
  2826. X
  2827. X /* Pop the activated macro's parameter list. */
  2828. X ls_lop(p_ma->ma_actn);
  2829. X
  2830. X /* Restore the indentation base. */
  2831. X ind_base=ind_save;
  2832. X}
  2833. X
  2834. X/******************************************************************************/
  2835. X
  2836. LOCAL void ex_ex(p_exp)
  2837. X/* Expand the specified expression. */
  2838. p_ells_t p_exp;
  2839. X{
  2840. X p_void p_mark;
  2841. X
  2842. X /* We need to save the current position in the expression list in case we    */
  2843. X /* are being recursively invoked (e.g. in @<X@>@(@"@<X@>@(@"sloth@"@)@"@).   */
  2844. X ls_fir(p_exp);
  2845. X while (TRUE)
  2846. X   {
  2847. X    p_el_t p_el;
  2848. X    ls_nxt(p_exp,PPV &p_el);
  2849. X    if (p_el==NULL) break;
  2850. X    p_mark=ls_mar(p_exp);
  2851. X    switch (p_el->el_kind)
  2852. X      {
  2853. X       case EL_TEXT: ex_eltx(p_el); break;
  2854. X       case EL_INVC: ex_elin(p_el); break;
  2855. X       case EL_PARM: ex_elpr(p_el); break;
  2856. X       default     : as_bomb("ex_ex: Case defaulted.");
  2857. X      }
  2858. X    ls_set(p_exp,p_mark);
  2859. X   }
  2860. X}
  2861. X
  2862. X/******************************************************************************/
  2863. X
  2864. LOCAL void ex_file P_((p_ma_t));
  2865. LOCAL void ex_file(p_ma)
  2866. X/* This function accepts a pointer to a macro. It creates a product file      */
  2867. X/* with the same name as the macro (inheriting any filename parts given in    */
  2868. X/* the command line) and expands the macro, writing the expansion to the      */
  2869. X/* product file.                                                              */
  2870. p_ma_t  p_ma;
  2871. X{
  2872. X fn_t  fn_tmp;  /* Name of temporary file.                                    */
  2873. X bool  renfil;   /* Do we wish to rename product file?                        */
  2874. X bool  istarg;   /* Does a target file already exist?                         */
  2875. X
  2876. X /* Writing product files differs to the other output files. With non         */
  2877. X /* critical files such as the listing file that are really just logs,        */
  2878. X /* generation of half a listing file is acceptable if not desirable. However */
  2879. X /* in the case of product files, it is very bad to generate half a product   */
  2880. X /* file; far better to generate none at all. For this reason, and also       */
  2881. X /* because of the presence of the D option (which prohibits the writing      */
  2882. X /* of product files identical to existing files (to prevent MAKE             */
  2883. X /* propagations)) it is best to write a temporary file and then rename it.   */
  2884. X
  2885. X /* Construct the target file name.                                           */
  2886. X strcpy(fn_targ,"");                /* Start with an empty name.              */
  2887. X fn_ins(fn_targ,&option.op_o_s[0]);
  2888. X fn_ins(fn_targ,&p_ma->ma_name[0]);
  2889. X
  2890. X /* The temporary file has to inherit too, because the output directory may   */
  2891. X /* not be the default directory and some computers can't rename across       */
  2892. X /* directories (and we have to rename it later).                             */
  2893. X strcpy(fn_tmp,fn_targ);
  2894. X fn_ins(fn_tmp,fn_temp());
  2895. X
  2896. X /* Expand the macro to the temporary file. */
  2897. X wf_ini(&f_o,TRUE);
  2898. X wf_ope(&f_o,fn_tmp);
  2899. X if (wf_err(&f_o))
  2900. X   {
  2901. X    sprintf(linet1,"Error creating temporary product file \"%s\".",&fn_tmp[0]);
  2902. X    wl_sjl(linet1);
  2903. X    (void) remove(fn_tmp);
  2904. X    goto severe;
  2905. X   }
  2906. X
  2907. X /* Now expand the target macro into the file. */
  2908. X {
  2909. X  el_t el;
  2910. X  el.el_kind  = EL_INVC;
  2911. X  el.el_p_mac = p_ma;
  2912. X  el.el_parls = ls_cre(sizeof(p_ells_t));
  2913. X  /* Note: We don't set el_pretx and el_postx as they are not used here. */
  2914. X  ind_base = 0;
  2915. X  ind_curr = 0;
  2916. X  lineno   = 1;
  2917. X  errlin   = 0;
  2918. X  numlong  = 0;
  2919. X  ex_elin(&el);
  2920. X }
  2921. X
  2922. X /* Make sure that there weren't any errors writing to the product file. */
  2923. X if (wf_err(&f_o))
  2924. X   {
  2925. X    sprintf(linet1,"S: Error writing to temporary product file \"%s\".",&fn_tmp[0]);
  2926. X    wl_sjl(linet1);
  2927. X    (void) remove(fn_tmp);
  2928. X    goto severe;
  2929. X   }
  2930. X
  2931. X /* Close the product file. */
  2932. X wf_clo(&f_o);
  2933. X if (wf_err(&f_o))
  2934. X   {
  2935. X    sprintf(linet1,"S: Error closing temporary product file \"%s\".",&fn_tmp[0]);
  2936. X    wl_sjl(linet1);
  2937. X    (void) remove(fn_tmp);
  2938. X    goto severe;
  2939. X   }
  2940. X
  2941. X /* The rest of the code in this function copes with the renaming. */
  2942. X
  2943. X /* By default, we wish to rename the temporary file. */
  2944. X renfil=TRUE;
  2945. X
  2946. X /* Deal with any existing file of the target name. */
  2947. X istarg=fexists(fn_targ);
  2948. X if (istarg && option.op_d_b)
  2949. X   {
  2950. X    /* A target already exists, and the D option is on. If the target is      */
  2951. X    /* identical to the temporary, we can simply delete the temporary!        */
  2952. X    char *errstr;
  2953. X    bool  same;
  2954. X    errstr=eq_files(fn_tmp,fn_targ,&same);
  2955. X    if (errstr != NULL)
  2956. X      {
  2957. X       wl_sjl("S: Error comparing temporary file with previous product file.");
  2958. X       wl_sjl("(A comparison was attempted because the D option was turned on.)");
  2959. X       wl_sjl("Error from comparison routine was as follows (first=temp):");
  2960. X       wr_sjl("   ");wl_sjl(errstr);
  2961. X       sprintf(linet1,"Temporary file name was \"%s\".",&fn_tmp[0]);
  2962. X       wl_sjl(linet1);
  2963. X       sprintf(linet1,"Product   file name was \"%s\".",fn_targ);
  2964. X       wl_sjl(linet1);
  2965. X       wl_sjl("FunnelWeb will leave both files intact so you can look at them.");
  2966. X       goto severe;
  2967. X      }
  2968. X    /* If the two files are the same, we can simply delete the temporary. */
  2969. X    if (same)
  2970. X      {
  2971. X       int status;
  2972. X       status=remove(fn_tmp);
  2973. X       if (status != REMOVE_S)
  2974. X {
  2975. X  sprintf(linet1,"S: Error deleting (under +D option) temporary file \"%s\".",&fn_tmp[0]);
  2976. X  wl_sjl(linet1);
  2977. X  goto severe;
  2978. X }
  2979. X       sprintf(linet1,"Deleted identical product file \"%s\".",fn_targ);
  2980. X       wl_sjl(linet1);
  2981. X       renfil=FALSE;
  2982. X      }
  2983. X   }
  2984. X
  2985. X if (renfil)
  2986. X   {
  2987. X    int status;
  2988. X    /* We need to delete any existing file of the target name. */
  2989. X    if (istarg)
  2990. X      {
  2991. X       status=remove(fn_targ);
  2992. X       if (status != REMOVE_S)
  2993. X {
  2994. X  sprintf(linet1,"S: Error deleting existing product file \"%s\".",fn_targ);
  2995. X  wl_sjl(linet1);
  2996. X  goto severe;
  2997. X }
  2998. X      }
  2999. X    /* Rename the temporary file to the product file. */
  3000. X    status=rename(fn_tmp,fn_targ);
  3001. X    if (status != RENAME_S)
  3002. X      {
  3003. X       wl_sjl("S: Error renaming temporary product file to product file.");
  3004. X       sprintf(linet1,"Temporary file name was \"%s\".",&fn_tmp[0]);
  3005. X       wl_sjl(linet1);
  3006. X       sprintf(linet1,"Product   file name was \"%s\".",fn_targ);
  3007. X       wl_sjl(linet1);
  3008. X       wl_sjl("FunnelWeb will leave both files intact so you can look at them.");
  3009. X       goto severe;
  3010. X      }
  3011. X   }
  3012. X
  3013. X /* Tell everyone that we have written a product file. */
  3014. X /* Note that we use the macro name. The full name is usually too messy. */
  3015. X sprintf(linet1,"Tangle: Completed %s.",&p_ma->ma_name[0]);
  3016. X wl_sjl(linet1);
  3017. X return;
  3018. X
  3019. X /* Jump here is a nasty file error occurs. */
  3020. X severe:
  3021. X sprintf(linet1,"A problem occurred during the generation of product file \"%s\".",&fn_targ[0]);
  3022. X wl_sjl(linet1);
  3023. X wl_sjl("S: Aborting...");
  3024. X num_sev++;
  3025. X return;
  3026. X
  3027. X}
  3028. X
  3029. X/******************************************************************************/
  3030. X
  3031. XEXPORT void tangle()
  3032. X{
  3033. X name_t dummyname;
  3034. X p_ma_t p_ma;
  3035. X
  3036. X /* Possibly decrease tglinmax if W option is turned on. */
  3037. X if (option.op_w_b)
  3038. X    tglinmax=MIN(tglinmax,option.op_w_i);
  3039. X
  3040. X /* Some compilers do not allow much space for statics so we allocate fn_targ */
  3041. X /* dynamically to save static space.                                         */
  3042. X fn_targ=(char *) mm_temp(sizeof(fn_t));
  3043. X
  3044. X /* Generate each file contained in the file table. */
  3045. X tb_fir(file_table);
  3046. X while (num_sev==0 && tb_rea(file_table,PV dummyname,PV &p_ma))
  3047. X    ex_file(p_ma);
  3048. X}
  3049. X
  3050. X/******************************************************************************/
  3051. X/*                               End of TANGLE.C                              */
  3052. X/******************************************************************************/
  3053. X
  3054. END_OF_FILE
  3055. if test 18625 -ne `wc -c <'sources/tangle.c'`; then
  3056.     echo shar: \"'sources/tangle.c'\" unpacked with wrong size!
  3057. fi
  3058. # end of 'sources/tangle.c'
  3059. fi
  3060. echo shar: End of archive 9 \(of 20\).
  3061. cp /dev/null ark9isdone
  3062. MISSING=""
  3063. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do
  3064.     if test ! -f ark${I}isdone ; then
  3065.     MISSING="${MISSING} ${I}"
  3066.     fi
  3067. done
  3068. if test "${MISSING}" = "" ; then
  3069.     echo You have unpacked all 20 archives.
  3070.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  3071. else
  3072.     echo You still need to unpack the following archives:
  3073.     echo "        " ${MISSING}
  3074. fi
  3075. ##  End of shell archive.
  3076. exit 0
  3077.