summaryrefslogtreecommitdiff
path: root/web/funnelAC
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /web/funnelAC
Initial commit
Diffstat (limited to 'web/funnelAC')
-rw-r--r--web/funnelAC/0readme.txt17
-rw-r--r--web/funnelAC/README.ABC15
-rw-r--r--web/funnelAC/admin/0readme.txt12
-rw-r--r--web/funnelAC/admin/ad.txt35
-rw-r--r--web/funnelAC/admin/fixeols.fws63
-rw-r--r--web/funnelAC/admin/gnu2.txt339
-rw-r--r--web/funnelAC/admin/makescript5
-rw-r--r--web/funnelAC/admin/vms_bld.com120
-rw-r--r--web/funnelAC/answers/0license.txt37
-rw-r--r--web/funnelAC/answers/an01.lis12
-rw-r--r--web/funnelAC/answers/an02.lis11
-rw-r--r--web/funnelAC/answers/an03.lis86
-rw-r--r--web/funnelAC/answers/an04.lis28
-rw-r--r--web/funnelAC/answers/ex01.lis12
-rw-r--r--web/funnelAC/answers/ex01.out1
-rw-r--r--web/funnelAC/answers/ex02.lis12
-rw-r--r--web/funnelAC/answers/ex02.out1
-rw-r--r--web/funnelAC/answers/ex03.lis50
-rw-r--r--web/funnelAC/answers/ex04.lis12
-rw-r--r--web/funnelAC/answers/ex04.out18
-rw-r--r--web/funnelAC/answers/ex05.lis12
-rw-r--r--web/funnelAC/answers/ex05.out18
-rw-r--r--web/funnelAC/answers/ex06.lis12
-rw-r--r--web/funnelAC/answers/ex06.out22
-rw-r--r--web/funnelAC/answers/ex07.lis12
-rw-r--r--web/funnelAC/answers/ex07.out24
-rw-r--r--web/funnelAC/answers/ex08.lis12
-rw-r--r--web/funnelAC/answers/ex08.out107
-rw-r--r--web/funnelAC/answers/ex09.lis12
-rw-r--r--web/funnelAC/answers/ex09.out6
-rw-r--r--web/funnelAC/answers/ex10.lis12
-rw-r--r--web/funnelAC/answers/ex10.out2
-rw-r--r--web/funnelAC/answers/ex11.lis12
-rw-r--r--web/funnelAC/answers/ex11.tex384
-rw-r--r--web/funnelAC/answers/ex12.lis12
-rw-r--r--web/funnelAC/answers/ex12.tex385
-rw-r--r--web/funnelAC/answers/ex13.lis12
-rw-r--r--web/funnelAC/answers/ex13.tex499
-rw-r--r--web/funnelAC/answers/ex14.lis12
-rw-r--r--web/funnelAC/answers/ex14.tex369
-rw-r--r--web/funnelAC/answers/ex15.lis12
-rw-r--r--web/funnelAC/answers/ex15.tex390
-rw-r--r--web/funnelAC/answers/ex16.lis13
-rw-r--r--web/funnelAC/answers/ex16.out18
-rw-r--r--web/funnelAC/answers/ex16.tex448
-rw-r--r--web/funnelAC/answers/generate.lis15
-rw-r--r--web/funnelAC/answers/hi01.lis12
-rw-r--r--web/funnelAC/answers/hi01.out9
-rw-r--r--web/funnelAC/answers/hi02.lis12
-rw-r--r--web/funnelAC/answers/hi02.out6
-rw-r--r--web/funnelAC/answers/hi03.lis12
-rw-r--r--web/funnelAC/answers/hi03.out6
-rw-r--r--web/funnelAC/answers/hi04.lis12
-rw-r--r--web/funnelAC/answers/hi04.out3
-rw-r--r--web/funnelAC/answers/hi05.lis12
-rw-r--r--web/funnelAC/answers/hi05.out7
-rw-r--r--web/funnelAC/answers/hi06.lis13
-rw-r--r--web/funnelAC/answers/hi06a.out3
-rw-r--r--web/funnelAC/answers/hi06b.out3
-rw-r--r--web/funnelAC/answers/hi07.lis13
-rw-r--r--web/funnelAC/answers/hi07a.out4
-rw-r--r--web/funnelAC/answers/hi07b.out4
-rw-r--r--web/funnelAC/answers/hi08.lis12
-rw-r--r--web/funnelAC/answers/hi08.out8
-rw-r--r--web/funnelAC/answers/hi09.lis12
-rw-r--r--web/funnelAC/answers/hi09.out98
-rw-r--r--web/funnelAC/answers/hi10.lis12
-rw-r--r--web/funnelAC/answers/hi10.out23
-rw-r--r--web/funnelAC/answers/pr01.lis457
-rw-r--r--web/funnelAC/answers/pr02.lis163
-rw-r--r--web/funnelAC/answers/pr03.lis469
-rw-r--r--web/funnelAC/answers/pr04.lis656
-rw-r--r--web/funnelAC/answers/pr05.lis1005
-rw-r--r--web/funnelAC/answers/pr06.lis698
-rw-r--r--web/funnelAC/answers/pr07.lis613
-rw-r--r--web/funnelAC/answers/pr08.lis1266
-rw-r--r--web/funnelAC/answers/pr09.lis2133
-rw-r--r--web/funnelAC/answers/pr10.lis396
-rw-r--r--web/funnelAC/answers/sc01.lis35
-rw-r--r--web/funnelAC/answers/sc02.lis57
-rw-r--r--web/funnelAC/answers/sc03.lis68
-rw-r--r--web/funnelAC/answers/sc04.lis71
-rw-r--r--web/funnelAC/answers/sc05.lis72
-rw-r--r--web/funnelAC/answers/sc06.lis91
-rw-r--r--web/funnelAC/answers/sc07.lis187
-rw-r--r--web/funnelAC/answers/sc08.lis104
-rw-r--r--web/funnelAC/answers/sc09.lis106
-rw-r--r--web/funnelAC/answers/sc10.lis864
-rw-r--r--web/funnelAC/answers/sc11.lis307
-rw-r--r--web/funnelAC/answers/sc12.lis77
-rw-r--r--web/funnelAC/answers/sc13.lis422
-rw-r--r--web/funnelAC/answers/sc14.lis477
-rw-r--r--web/funnelAC/answers/sc15.lis355
-rw-r--r--web/funnelAC/answers/sc16.lis456
-rw-r--r--web/funnelAC/answers/sc17.lis352
-rw-r--r--web/funnelAC/answers/sc18.lis261
-rw-r--r--web/funnelAC/answers/sc19.lis94
-rw-r--r--web/funnelAC/answers/sc20.lis112
-rw-r--r--web/funnelAC/answers/sc21.lis339
-rw-r--r--web/funnelAC/answers/sc22.lis165
-rw-r--r--web/funnelAC/answers/sc23.lis188
-rw-r--r--web/funnelAC/answers/sc24.lis162
-rw-r--r--web/funnelAC/answers/sc25.lis85
-rw-r--r--web/funnelAC/answers/sc26.lis87
-rw-r--r--web/funnelAC/answers/sc27.lis145
-rw-r--r--web/funnelAC/answers/sc28.lis253
-rw-r--r--web/funnelAC/answers/sc29.lis161
-rw-r--r--web/funnelAC/answers/tg01.lis12
-rw-r--r--web/funnelAC/answers/tg01.out3
-rw-r--r--web/funnelAC/answers/tg02.lis12
-rw-r--r--web/funnelAC/answers/tg02.out23
-rw-r--r--web/funnelAC/answers/tg03.lis12
-rw-r--r--web/funnelAC/answers/tg03.out21
-rw-r--r--web/funnelAC/answers/tg04.lis12
-rw-r--r--web/funnelAC/answers/tg04.out22
-rw-r--r--web/funnelAC/answers/tg05.lis17
-rw-r--r--web/funnelAC/answers/tg05.out4
-rw-r--r--web/funnelAC/answers/tg06.lis17
-rw-r--r--web/funnelAC/answers/tg06.out6
-rw-r--r--web/funnelAC/answers/tg07.lis12
-rw-r--r--web/funnelAC/answers/tg07.out2
-rw-r--r--web/funnelAC/answers/tg08.lis12
-rw-r--r--web/funnelAC/answers/tg08.out7
-rw-r--r--web/funnelAC/answers/tg09.lis12
-rw-r--r--web/funnelAC/answers/tg09.out23
-rw-r--r--web/funnelAC/answers/wv01.lis12
-rw-r--r--web/funnelAC/answers/wv01.tex367
-rw-r--r--web/funnelAC/answers/wv02.lis12
-rw-r--r--web/funnelAC/answers/wv02.tex454
-rw-r--r--web/funnelAC/answers/wv03.lis12
-rw-r--r--web/funnelAC/answers/wv03.tex568
-rw-r--r--web/funnelAC/answers/wv04.lis12
-rw-r--r--web/funnelAC/answers/wv04.tex397
-rw-r--r--web/funnelAC/answers/wv05.lis12
-rw-r--r--web/funnelAC/answers/wv05.tex442
-rw-r--r--web/funnelAC/answers/wv06.lis12
-rw-r--r--web/funnelAC/answers/wv06.tex443
-rw-r--r--web/funnelAC/contrib/README36
-rw-r--r--web/funnelAC/contrib/dek.fw264
-rw-r--r--web/funnelAC/contrib/dek2.fw263
-rw-r--r--web/funnelAC/contrib/rand_int.p4
-rw-r--r--web/funnelAC/fwACsrc/HTML.txt2379
-rw-r--r--web/funnelAC/fwACsrc/Makefile65
-rw-r--r--web/funnelAC/fwACsrc/Makefile.os268
-rw-r--r--web/funnelAC/fwACsrc/Makefile.unix61
-rw-r--r--web/funnelAC/fwACsrc/README.ABC347
-rw-r--r--web/funnelAC/fwACsrc/analyse.c326
-rw-r--r--web/funnelAC/fwACsrc/analyse.h61
-rw-r--r--web/funnelAC/fwACsrc/as.c72
-rw-r--r--web/funnelAC/fwACsrc/as.h119
-rw-r--r--web/funnelAC/fwACsrc/autoccln.fwi45
-rw-r--r--web/funnelAC/fwACsrc/ccline.fwi74
-rw-r--r--web/funnelAC/fwACsrc/clock.c125
-rw-r--r--web/funnelAC/fwACsrc/clock.h107
-rw-r--r--web/funnelAC/fwACsrc/command.c2147
-rw-r--r--web/funnelAC/fwACsrc/command.h61
-rw-r--r--web/funnelAC/fwACsrc/data.c50
-rw-r--r--web/funnelAC/fwACsrc/data.h684
-rw-r--r--web/funnelAC/fwACsrc/dump.c900
-rw-r--r--web/funnelAC/fwACsrc/dump.h78
-rw-r--r--web/funnelAC/fwACsrc/environ.h316
-rw-r--r--web/funnelAC/fwACsrc/err.status1
-rw-r--r--web/funnelAC/fwACsrc/fw-latex.sty327
-rw-r--r--web/funnelAC/fwACsrc/fw.def3
-rw-r--r--web/funnelAC/fwACsrc/fwmem.c371
-rw-r--r--web/funnelAC/fwACsrc/fwmem.h116
-rw-r--r--web/funnelAC/fwACsrc/fwtest.cmd5
-rw-r--r--web/funnelAC/fwACsrc/help.c631
-rw-r--r--web/funnelAC/fwACsrc/help.h164
-rw-r--r--web/funnelAC/fwACsrc/help_gnu.c105
-rw-r--r--web/funnelAC/fwACsrc/help_gnu.ctx339
-rw-r--r--web/funnelAC/fwACsrc/help_gnu.h58
-rw-r--r--web/funnelAC/fwACsrc/help_gnu.txt339
-rw-r--r--web/funnelAC/fwACsrc/htmlhead.c112
-rw-r--r--web/funnelAC/fwACsrc/htmlhead.cht42
-rw-r--r--web/funnelAC/fwACsrc/htmlhead.h125
-rw-r--r--web/funnelAC/fwACsrc/htmlhead.htm42
-rw-r--r--web/funnelAC/fwACsrc/list.c328
-rw-r--r--web/funnelAC/fwACsrc/list.h207
-rw-r--r--web/funnelAC/fwACsrc/lister.c370
-rw-r--r--web/funnelAC/fwACsrc/lister.h75
-rw-r--r--web/funnelAC/fwACsrc/machin.c355
-rw-r--r--web/funnelAC/fwACsrc/machin.h342
-rw-r--r--web/funnelAC/fwACsrc/main.c115
-rw-r--r--web/funnelAC/fwACsrc/mapper.c343
-rw-r--r--web/funnelAC/fwACsrc/mapper.h69
-rw-r--r--web/funnelAC/fwACsrc/misc.c235
-rw-r--r--web/funnelAC/fwACsrc/misc.h126
-rw-r--r--web/funnelAC/fwACsrc/option.c454
-rw-r--r--web/funnelAC/fwACsrc/option.h180
-rw-r--r--web/funnelAC/fwACsrc/parser.c1476
-rw-r--r--web/funnelAC/fwACsrc/parser.h65
-rw-r--r--web/funnelAC/fwACsrc/scanner.c2559
-rw-r--r--web/funnelAC/fwACsrc/scanner.h67
-rw-r--r--web/funnelAC/fwACsrc/section.c151
-rw-r--r--web/funnelAC/fwACsrc/section.h123
-rw-r--r--web/funnelAC/fwACsrc/style.h270
-rw-r--r--web/funnelAC/fwACsrc/table.c433
-rw-r--r--web/funnelAC/fwACsrc/table.h189
-rw-r--r--web/funnelAC/fwACsrc/tangle.c887
-rw-r--r--web/funnelAC/fwACsrc/tangle.h56
-rw-r--r--web/funnelAC/fwACsrc/texhead.c108
-rw-r--r--web/funnelAC/fwACsrc/texhead.ctx320
-rw-r--r--web/funnelAC/fwACsrc/texhead.h125
-rw-r--r--web/funnelAC/fwACsrc/texhead.tex320
-rw-r--r--web/funnelAC/fwACsrc/weave.c2330
-rw-r--r--web/funnelAC/fwACsrc/weave.h55
-rw-r--r--web/funnelAC/fwACsrc/writfile.c319
-rw-r--r--web/funnelAC/fwACsrc/writfile.h196
-rw-r--r--web/funnelAC/hackman/h_ch0.tex180
-rw-r--r--web/funnelAC/hackman/h_ch1.tex1107
-rw-r--r--web/funnelAC/hackman/h_ch2.tex443
-rw-r--r--web/funnelAC/hackman/h_ch3.tex549
-rw-r--r--web/funnelAC/hackman/h_ch4.tex401
-rw-r--r--web/funnelAC/hackman/h_cha.tex441
-rw-r--r--web/funnelAC/hackman/h_manual.aux80
-rw-r--r--web/funnelAC/hackman/h_manual.dvibin0 -> 181544 bytes
-rw-r--r--web/funnelAC/hackman/h_manual.idx326
-rw-r--r--web/funnelAC/hackman/h_manual.log213
-rw-r--r--web/funnelAC/hackman/h_manual.ps5210
-rw-r--r--web/funnelAC/hackman/h_manual.sin326
-rw-r--r--web/funnelAC/hackman/h_manual.tex283
-rw-r--r--web/funnelAC/hackman/h_manual.toc62
-rw-r--r--web/funnelAC/regform.txt30
-rw-r--r--web/funnelAC/results/0testres.dif8167
-rw-r--r--web/funnelAC/results/an01.lis11
-rw-r--r--web/funnelAC/results/an02.lis11
-rw-r--r--web/funnelAC/results/an03.lis86
-rw-r--r--web/funnelAC/results/an04.lis28
-rw-r--r--web/funnelAC/results/ex01.lis12
-rw-r--r--web/funnelAC/results/ex01.out1
-rw-r--r--web/funnelAC/results/ex02.lis12
-rw-r--r--web/funnelAC/results/ex02.out1
-rw-r--r--web/funnelAC/results/ex03.lis50
-rw-r--r--web/funnelAC/results/ex04.lis12
-rw-r--r--web/funnelAC/results/ex04.out18
-rw-r--r--web/funnelAC/results/ex05.lis12
-rw-r--r--web/funnelAC/results/ex05.out18
-rw-r--r--web/funnelAC/results/ex06.lis12
-rw-r--r--web/funnelAC/results/ex06.out22
-rw-r--r--web/funnelAC/results/ex07.lis12
-rw-r--r--web/funnelAC/results/ex07.out24
-rw-r--r--web/funnelAC/results/ex08.lis12
-rw-r--r--web/funnelAC/results/ex08.out107
-rw-r--r--web/funnelAC/results/ex09.lis12
-rw-r--r--web/funnelAC/results/ex09.out6
-rw-r--r--web/funnelAC/results/ex10.lis12
-rw-r--r--web/funnelAC/results/ex10.out2
-rw-r--r--web/funnelAC/results/ex11.lis12
-rw-r--r--web/funnelAC/results/ex11.tex384
-rw-r--r--web/funnelAC/results/ex12.lis12
-rw-r--r--web/funnelAC/results/ex12.tex385
-rw-r--r--web/funnelAC/results/ex13.lis12
-rw-r--r--web/funnelAC/results/ex13.tex499
-rw-r--r--web/funnelAC/results/ex14.lis12
-rw-r--r--web/funnelAC/results/ex14.tex369
-rw-r--r--web/funnelAC/results/ex15.lis12
-rw-r--r--web/funnelAC/results/ex15.tex390
-rw-r--r--web/funnelAC/results/ex16.lis13
-rw-r--r--web/funnelAC/results/ex16.out18
-rw-r--r--web/funnelAC/results/ex16.tex448
-rw-r--r--web/funnelAC/results/generate.lis15
-rw-r--r--web/funnelAC/results/hi01.lis12
-rw-r--r--web/funnelAC/results/hi01.out9
-rw-r--r--web/funnelAC/results/hi02.lis12
-rw-r--r--web/funnelAC/results/hi02.out6
-rw-r--r--web/funnelAC/results/hi03.lis12
-rw-r--r--web/funnelAC/results/hi03.out6
-rw-r--r--web/funnelAC/results/hi04.lis12
-rw-r--r--web/funnelAC/results/hi04.out3
-rw-r--r--web/funnelAC/results/hi05.lis12
-rw-r--r--web/funnelAC/results/hi05.out7
-rw-r--r--web/funnelAC/results/hi06.lis13
-rw-r--r--web/funnelAC/results/hi06a.out3
-rw-r--r--web/funnelAC/results/hi06b.out3
-rw-r--r--web/funnelAC/results/hi07.lis13
-rw-r--r--web/funnelAC/results/hi07a.out4
-rw-r--r--web/funnelAC/results/hi07b.out4
-rw-r--r--web/funnelAC/results/hi08.lis12
-rw-r--r--web/funnelAC/results/hi08.out8
-rw-r--r--web/funnelAC/results/hi09.lis12
-rw-r--r--web/funnelAC/results/hi09.out98
-rw-r--r--web/funnelAC/results/hi10.lis12
-rw-r--r--web/funnelAC/results/hi10.out23
-rw-r--r--web/funnelAC/results/pr01.lis544
-rw-r--r--web/funnelAC/results/pr02.lis249
-rw-r--r--web/funnelAC/results/pr03.lis557
-rw-r--r--web/funnelAC/results/pr04.lis751
-rw-r--r--web/funnelAC/results/pr05.lis1105
-rw-r--r--web/funnelAC/results/pr06.lis791
-rw-r--r--web/funnelAC/results/pr07.lis703
-rw-r--r--web/funnelAC/results/pr08.lis1360
-rw-r--r--web/funnelAC/results/pr09.lis2234
-rw-r--r--web/funnelAC/results/pr10.lis487
-rw-r--r--web/funnelAC/results/sc01.lis35
-rw-r--r--web/funnelAC/results/sc02.lis143
-rw-r--r--web/funnelAC/results/sc03.lis154
-rw-r--r--web/funnelAC/results/sc04.lis157
-rw-r--r--web/funnelAC/results/sc05.lis158
-rw-r--r--web/funnelAC/results/sc06.lis166
-rw-r--r--web/funnelAC/results/sc07.lis187
-rw-r--r--web/funnelAC/results/sc08.lis190
-rw-r--r--web/funnelAC/results/sc09.lis106
-rw-r--r--web/funnelAC/results/sc10.lis882
-rw-r--r--web/funnelAC/results/sc11.lis307
-rw-r--r--web/funnelAC/results/sc12.lis77
-rw-r--r--web/funnelAC/results/sc13.lis500
-rw-r--r--web/funnelAC/results/sc14.lis477
-rw-r--r--web/funnelAC/results/sc15.lis355
-rw-r--r--web/funnelAC/results/sc16.lis456
-rw-r--r--web/funnelAC/results/sc17.lis352
-rw-r--r--web/funnelAC/results/sc18.lis261
-rw-r--r--web/funnelAC/results/sc19.lis96
-rw-r--r--web/funnelAC/results/sc20.lis198
-rw-r--r--web/funnelAC/results/sc21.lis411
-rw-r--r--web/funnelAC/results/sc22.lis165
-rw-r--r--web/funnelAC/results/sc23.lis188
-rw-r--r--web/funnelAC/results/sc24.lis162
-rw-r--r--web/funnelAC/results/sc25.lis85
-rw-r--r--web/funnelAC/results/sc26.lis87
-rw-r--r--web/funnelAC/results/sc27.lis145
-rw-r--r--web/funnelAC/results/sc28.lis253
-rw-r--r--web/funnelAC/results/sc29.lis170
-rw-r--r--web/funnelAC/results/tg01.lis12
-rw-r--r--web/funnelAC/results/tg01.out3
-rw-r--r--web/funnelAC/results/tg02.lis12
-rw-r--r--web/funnelAC/results/tg02.out23
-rw-r--r--web/funnelAC/results/tg03.lis12
-rw-r--r--web/funnelAC/results/tg03.out21
-rw-r--r--web/funnelAC/results/tg04.lis12
-rw-r--r--web/funnelAC/results/tg04.out22
-rw-r--r--web/funnelAC/results/tg05.lis17
-rw-r--r--web/funnelAC/results/tg05.out4
-rw-r--r--web/funnelAC/results/tg06.lis17
-rw-r--r--web/funnelAC/results/tg06.out6
-rw-r--r--web/funnelAC/results/tg07.lis12
-rw-r--r--web/funnelAC/results/tg07.out2
-rw-r--r--web/funnelAC/results/tg08.lis12
-rw-r--r--web/funnelAC/results/tg08.out7
-rw-r--r--web/funnelAC/results/tg09.lis12
-rw-r--r--web/funnelAC/results/tg09.out23
-rw-r--r--web/funnelAC/results/wv01.lis12
-rw-r--r--web/funnelAC/results/wv01.tex367
-rw-r--r--web/funnelAC/results/wv02.lis12
-rw-r--r--web/funnelAC/results/wv02.tex454
-rw-r--r--web/funnelAC/results/wv03.lis12
-rw-r--r--web/funnelAC/results/wv03.tex568
-rw-r--r--web/funnelAC/results/wv04.lis12
-rw-r--r--web/funnelAC/results/wv04.tex397
-rw-r--r--web/funnelAC/results/wv05.lis12
-rw-r--r--web/funnelAC/results/wv05.tex442
-rw-r--r--web/funnelAC/results/wv06.lis12
-rw-r--r--web/funnelAC/results/wv06.tex443
-rw-r--r--web/funnelAC/scripts/0license.txt37
-rw-r--r--web/funnelAC/scripts/master.fws295
-rw-r--r--web/funnelAC/scripts/test_gen.fws58
-rw-r--r--web/funnelAC/scripts/test_l.fws50
-rw-r--r--web/funnelAC/scripts/test_ld.fws58
-rw-r--r--web/funnelAC/scripts/test_lo.fws53
-rw-r--r--web/funnelAC/scripts/test_lo2.fws59
-rw-r--r--web/funnelAC/scripts/test_lot.fws56
-rw-r--r--web/funnelAC/scripts/test_lt.fws53
-rw-r--r--web/funnelAC/sources/analyse.c296
-rw-r--r--web/funnelAC/sources/analyse.h61
-rw-r--r--web/funnelAC/sources/as.c60
-rw-r--r--web/funnelAC/sources/as.h119
-rw-r--r--web/funnelAC/sources/clock.c125
-rw-r--r--web/funnelAC/sources/clock.h107
-rw-r--r--web/funnelAC/sources/command.c2111
-rw-r--r--web/funnelAC/sources/command.h61
-rw-r--r--web/funnelAC/sources/data.c50
-rw-r--r--web/funnelAC/sources/data.h512
-rw-r--r--web/funnelAC/sources/dump.c816
-rw-r--r--web/funnelAC/sources/dump.h78
-rw-r--r--web/funnelAC/sources/environ.h231
-rw-r--r--web/funnelAC/sources/help.c605
-rw-r--r--web/funnelAC/sources/help.h161
-rw-r--r--web/funnelAC/sources/help_gnu.c105
-rw-r--r--web/funnelAC/sources/help_gnu.ctx339
-rw-r--r--web/funnelAC/sources/help_gnu.h58
-rw-r--r--web/funnelAC/sources/help_gnu.txt339
-rw-r--r--web/funnelAC/sources/list.c325
-rw-r--r--web/funnelAC/sources/list.h207
-rw-r--r--web/funnelAC/sources/lister.c368
-rw-r--r--web/funnelAC/sources/lister.h75
-rw-r--r--web/funnelAC/sources/machin.c345
-rw-r--r--web/funnelAC/sources/machin.h300
-rw-r--r--web/funnelAC/sources/main.c109
-rw-r--r--web/funnelAC/sources/mapper.c375
-rw-r--r--web/funnelAC/sources/mapper.h69
-rw-r--r--web/funnelAC/sources/memory.c338
-rw-r--r--web/funnelAC/sources/memory.h113
-rw-r--r--web/funnelAC/sources/misc.c232
-rw-r--r--web/funnelAC/sources/misc.h126
-rw-r--r--web/funnelAC/sources/option.c440
-rw-r--r--web/funnelAC/sources/option.h174
-rw-r--r--web/funnelAC/sources/parser.c1289
-rw-r--r--web/funnelAC/sources/parser.h65
-rw-r--r--web/funnelAC/sources/scanner.c1824
-rw-r--r--web/funnelAC/sources/scanner.h67
-rw-r--r--web/funnelAC/sources/section.c148
-rw-r--r--web/funnelAC/sources/section.h120
-rw-r--r--web/funnelAC/sources/style.h258
-rw-r--r--web/funnelAC/sources/table.c429
-rw-r--r--web/funnelAC/sources/table.h189
-rw-r--r--web/funnelAC/sources/tangle.c539
-rw-r--r--web/funnelAC/sources/tangle.h56
-rw-r--r--web/funnelAC/sources/texhead.c108
-rw-r--r--web/funnelAC/sources/texhead.ctx320
-rw-r--r--web/funnelAC/sources/texhead.h121
-rw-r--r--web/funnelAC/sources/texhead.tex320
-rw-r--r--web/funnelAC/sources/weave.c976
-rw-r--r--web/funnelAC/sources/weave.h55
-rw-r--r--web/funnelAC/sources/writfile.c299
-rw-r--r--web/funnelAC/sources/writfile.h189
-rw-r--r--web/funnelAC/tests/0license.txt37
-rw-r--r--web/funnelAC/tests/an01.fw2
-rw-r--r--web/funnelAC/tests/an02.fw3
-rw-r--r--web/funnelAC/tests/an03.fw48
-rw-r--r--web/funnelAC/tests/an04.fw14
-rw-r--r--web/funnelAC/tests/ex01.fw3
-rw-r--r--web/funnelAC/tests/ex02.fw8
-rw-r--r--web/funnelAC/tests/ex03.fw36
-rw-r--r--web/funnelAC/tests/ex04.fw35
-rw-r--r--web/funnelAC/tests/ex05.fw50
-rw-r--r--web/funnelAC/tests/ex06.fw57
-rw-r--r--web/funnelAC/tests/ex07.fw30
-rw-r--r--web/funnelAC/tests/ex08.fw39
-rw-r--r--web/funnelAC/tests/ex09.fw8
-rw-r--r--web/funnelAC/tests/ex09a.fwi2
-rw-r--r--web/funnelAC/tests/ex10.fw6
-rw-r--r--web/funnelAC/tests/ex10a.fwi4
-rw-r--r--web/funnelAC/tests/ex11.fw22
-rw-r--r--web/funnelAC/tests/ex12.fw17
-rw-r--r--web/funnelAC/tests/ex13.fw46
-rw-r--r--web/funnelAC/tests/ex14.fw7
-rw-r--r--web/funnelAC/tests/ex15.fw19
-rw-r--r--web/funnelAC/tests/ex16.fw66
-rw-r--r--web/funnelAC/tests/generate.fw61
-rw-r--r--web/funnelAC/tests/hi01.fw14
-rw-r--r--web/funnelAC/tests/hi02.fw25
-rw-r--r--web/funnelAC/tests/hi03.fw25
-rw-r--r--web/funnelAC/tests/hi04.fw23
-rw-r--r--web/funnelAC/tests/hi05.fw23
-rw-r--r--web/funnelAC/tests/hi06.fw22
-rw-r--r--web/funnelAC/tests/hi07.fw16
-rw-r--r--web/funnelAC/tests/hi08.fw20
-rw-r--r--web/funnelAC/tests/hi09.fw111
-rw-r--r--web/funnelAC/tests/hi10.fw83
-rw-r--r--web/funnelAC/tests/pr01.fw31
-rw-r--r--web/funnelAC/tests/pr02.fw14
-rw-r--r--web/funnelAC/tests/pr03.fw27
-rw-r--r--web/funnelAC/tests/pr04.fw33
-rw-r--r--web/funnelAC/tests/pr05.fw40
-rw-r--r--web/funnelAC/tests/pr06.fw39
-rw-r--r--web/funnelAC/tests/pr07.fw36
-rw-r--r--web/funnelAC/tests/pr08.fw61
-rw-r--r--web/funnelAC/tests/pr09.fw92
-rw-r--r--web/funnelAC/tests/pr10.fw28
-rw-r--r--web/funnelAC/tests/sc01_note.fw2
-rw-r--r--web/funnelAC/tests/sc02.fw0
-rw-r--r--web/funnelAC/tests/sc03.fw1
-rw-r--r--web/funnelAC/tests/sc04.fw2
-rw-r--r--web/funnelAC/tests/sc05.fw1
-rw-r--r--web/funnelAC/tests/sc06.fw4
-rw-r--r--web/funnelAC/tests/sc07.fw25
-rw-r--r--web/funnelAC/tests/sc08.fw6
-rw-r--r--web/funnelAC/tests/sc09.fw11
-rw-r--r--web/funnelAC/tests/sc10.fw116
-rw-r--r--web/funnelAC/tests/sc11.fw24
-rw-r--r--web/funnelAC/tests/sc12.fw6
-rw-r--r--web/funnelAC/tests/sc13.fw38
-rw-r--r--web/funnelAC/tests/sc13a.fwi0
-rw-r--r--web/funnelAC/tests/sc13b.fwi1
-rw-r--r--web/funnelAC/tests/sc13c.fwi2
-rw-r--r--web/funnelAC/tests/sc13d.fwi1
-rw-r--r--web/funnelAC/tests/sc13e.fwi4
-rw-r--r--web/funnelAC/tests/sc13f.fwi2
-rw-r--r--web/funnelAC/tests/sc14.fw6
-rw-r--r--web/funnelAC/tests/sc15.fw30
-rw-r--r--web/funnelAC/tests/sc15a.fwi25
-rw-r--r--web/funnelAC/tests/sc16.fw62
-rw-r--r--web/funnelAC/tests/sc17.fw24
-rw-r--r--web/funnelAC/tests/sc18.fw24
-rw-r--r--web/funnelAC/tests/sc19.fw10
-rw-r--r--web/funnelAC/tests/sc20.fw11
-rw-r--r--web/funnelAC/tests/sc21.fw31
-rw-r--r--web/funnelAC/tests/sc22.fw23
-rw-r--r--web/funnelAC/tests/sc23.fw26
-rw-r--r--web/funnelAC/tests/sc24.fw23
-rw-r--r--web/funnelAC/tests/sc25.fw8
-rw-r--r--web/funnelAC/tests/sc26.fw8
-rw-r--r--web/funnelAC/tests/sc27.fw20
-rw-r--r--web/funnelAC/tests/sc28.fw34
-rw-r--r--web/funnelAC/tests/sc29.fw23
-rw-r--r--web/funnelAC/tests/tg01.fw8
-rw-r--r--web/funnelAC/tests/tg02.fw71
-rw-r--r--web/funnelAC/tests/tg03.fw69
-rw-r--r--web/funnelAC/tests/tg04.fw30
-rw-r--r--web/funnelAC/tests/tg05.fw10
-rw-r--r--web/funnelAC/tests/tg06.fw11
-rw-r--r--web/funnelAC/tests/tg07.fw10
-rw-r--r--web/funnelAC/tests/tg08.fw14
-rw-r--r--web/funnelAC/tests/tg08a.fwi5
-rw-r--r--web/funnelAC/tests/tg09.fw37
-rw-r--r--web/funnelAC/tests/wv01.fw7
-rw-r--r--web/funnelAC/tests/wv02.fw43
-rw-r--r--web/funnelAC/tests/wv03.fw64
-rw-r--r--web/funnelAC/tests/wv04.fw20
-rw-r--r--web/funnelAC/tests/wv05.fw83
-rw-r--r--web/funnelAC/tests/wv06.fw85
-rw-r--r--web/funnelAC/userman/u_ch0.tex197
-rw-r--r--web/funnelAC/userman/u_ch1.tex1800
-rw-r--r--web/funnelAC/userman/u_ch2.tex1586
-rw-r--r--web/funnelAC/userman/u_ch3.tex2986
-rw-r--r--web/funnelAC/userman/u_ch4.tex468
-rw-r--r--web/funnelAC/userman/u_ch5.tex387
-rw-r--r--web/funnelAC/userman/u_cha.tex228
-rw-r--r--web/funnelAC/userman/u_manual.aux202
-rw-r--r--web/funnelAC/userman/u_manual.dvibin0 -> 442412 bytes
-rw-r--r--web/funnelAC/userman/u_manual.idx1020
-rw-r--r--web/funnelAC/userman/u_manual.log188
-rw-r--r--web/funnelAC/userman/u_manual.ps9876
-rw-r--r--web/funnelAC/userman/u_manual.sin1020
-rw-r--r--web/funnelAC/userman/u_manual.tex290
-rw-r--r--web/funnelAC/userman/u_manual.toc166
526 files changed, 126458 insertions, 0 deletions
diff --git a/web/funnelAC/0readme.txt b/web/funnelAC/0readme.txt
new file mode 100644
index 0000000000..4b1788960a
--- /dev/null
+++ b/web/funnelAC/0readme.txt
@@ -0,0 +1,17 @@
+FUNNELWEB 0README FILE
+======================
+This is the first file you should read after obtaining a copy of
+FunnelWeb.
+
+FunnelWeb is well documented and the best thing you can do at this
+stage to get started is to LaTeX and print out the FunnelWeb User's
+Manual. The LaTeX sources for the manual can be found in the directory
+
+...../fwdir/userman/
+
+The file to LaTeX is u_manual.tex. The FunnelWeb User's Manual
+contains full installation instructions.
+
+If you are in a hurry to install FunnelWeb, print out u_ch4.tex in
+text form and follow the instructions.
+
diff --git a/web/funnelAC/README.ABC b/web/funnelAC/README.ABC
new file mode 100644
index 0000000000..5a9aa4f12a
--- /dev/null
+++ b/web/funnelAC/README.ABC
@@ -0,0 +1,15 @@
+README FILE FOR FUNNELWEB AC 3.05
+=================================
+
+This is a combined FunnelWeb V3.0 and FunnelWeb AC 3.05 distribution.
+To make Ross William's original FunnelWeb V3.0, follow the directions
+in the user manual in the `userman' directory, and use the C source
+files in the `sources' directory. To make FunnelWeb AC 3.05 (an
+enhanced version of FunnelWeb, with HTML support and other
+extensions), use the source files in the `fwACsrc' directory, after
+first reading `fwACsrc/README.ABC'.
+
+Send any comments or error reports to `coates@physics.uq.edu.au'.
+
+A.B.Coates
+12/12/95
diff --git a/web/funnelAC/admin/0readme.txt b/web/funnelAC/admin/0readme.txt
new file mode 100644
index 0000000000..74b3bcc79c
--- /dev/null
+++ b/web/funnelAC/admin/0readme.txt
@@ -0,0 +1,12 @@
+
+FUNNELWEB INSTALLATION
+======================
+Chapter 4 of the FunnelWeb User's Manual contains full installation
+instructions for FunnelWeb in LaTeX format. Ideally you should print out
+the entire FunnelWeb User's Manual and then read the installation chapter
+for installation instructions. The LaTeX files for the User's Manual are in
+fwdir/userman/
+
+If you are in a hurry, print out fwdir/userman/u_ch4.tex in text form and
+follow the instructions within.
+
diff --git a/web/funnelAC/admin/ad.txt b/web/funnelAC/admin/ad.txt
new file mode 100644
index 0000000000..c552ad4f9a
--- /dev/null
+++ b/web/funnelAC/admin/ad.txt
@@ -0,0 +1,35 @@
+
+ANNOUNCING FUNNELWEB
+====================
+Author : Ross Williams (ross@spam.adelaide.edu.au).
+Date : 27-May-1992.
+
+FunnelWeb is a production-quality literate-programming tool that emphasises
+simplicity and reliability. It provides a macro facility, and assists in the
+production of typeset documentation. FunnelWeb runs on most popular machines
+(Sun, VAX, Mac, PC) and its highly portable source code in C is freely
+available under a GNU license.
+
+Features:
+ + Provides a simple macro preprocessor facility.
+ + Assists in the generation of typeset documentation.
+ + Runs on Sun, VMS VAX, Macintosh, and PC.
+ + Portable C source code distributed under GNU licence.
+ + Comprehensive user's manual (115 pages).
+ + Input programming language independent.
+ + Allows complete control over the output text.
+ + Regression test suite with over 200 tests.
+ - Requires TeX to produce typeset documentation.
+ - Typesets program code using TT font only.
+
+How to Obtain FunnelWeb
+-----------------------
+FunnelWeb can be obtained by anonymous FTP from:
+
+Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3].
+Directory: ~pub/funnelweb/ (or a directory of similar name).
+
+It is not clear at the time of writing whether FunnelWeb will be
+presented as a TAR file or as a directory tree or both.
+
+--<End of Announcement>--
diff --git a/web/funnelAC/admin/fixeols.fws b/web/funnelAC/admin/fixeols.fws
new file mode 100644
index 0000000000..0f502c6408
--- /dev/null
+++ b/web/funnelAC/admin/fixeols.fws
@@ -0,0 +1,63 @@
+! This scrip is useful for cleaning up the source code if you
+! already have a working version of FunnelWeb.
+
+trace on
+define 1 "slartibartfast:funnelweb:funnelweb-2:sources:"
+
+fixeols $1analyse.h
+fixeols $1analyse.c
+fixeols $1as.h
+fixeols $1as.c
+fixeols $1clock.h
+fixeols $1clock.c
+fixeols $1command.h
+fixeols $1command.c
+fixeols $1data.h
+fixeols $1data.c
+fixeols $1dump.h
+fixeols $1dump.c
+fixeols $1environ.h
+fixeols $1help.h
+fixeols $1help.c
+fixeols $1help_gnu.h
+fixeols $1help_gnu.c
+fixeols $1help_gnu.txt
+fixeols $1help_gnu.ctx
+fixeols $1list.h
+fixeols $1list.c
+fixeols $1lister.h
+fixeols $1lister.c
+fixeols $1machin.h
+fixeols $1machin.c
+fixeols $1main.c
+fixeols $1mapper.h
+fixeols $1mapper.c
+fixeols $1memory.h
+fixeols $1memory.c
+fixeols $1misc.h
+fixeols $1misc.c
+fixeols $1option.h
+fixeols $1option.c
+fixeols $1parser.h
+fixeols $1parser.c
+fixeols $1scanner.h
+fixeols $1scanner.c
+fixeols $1section.h
+fixeols $1section.c
+fixeols $1style.h
+fixeols $1table.h
+fixeols $1table.c
+fixeols $1tangle.h
+fixeols $1tangle.c
+fixeols $1texhead.h
+fixeols $1texhead.c
+fixeols $1texhead.ctx
+fixeols $1texhead.tex
+fixeols $1weave.h
+fixeols $1weave.c
+fixeols $1writfile.h
+fixeols $1writfile.c
+
+!Now for the test scripts.
+fixeols $1master.fws
+!The other scripts are cleaned just before they are run.
diff --git a/web/funnelAC/admin/gnu2.txt b/web/funnelAC/admin/gnu2.txt
new file mode 100644
index 0000000000..b8cf3a1ab2
--- /dev/null
+++ b/web/funnelAC/admin/gnu2.txt
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/web/funnelAC/admin/makescript b/web/funnelAC/admin/makescript
new file mode 100644
index 0000000000..a7f0316353
--- /dev/null
+++ b/web/funnelAC/admin/makescript
@@ -0,0 +1,5 @@
+#!/bin/csh
+# Choose betwen GNU C (gcc), or the default C (cc) on your system.
+gcc -o fw -g -Wall *.c
+#
+#cc -o fw -g *.c
diff --git a/web/funnelAC/admin/vms_bld.com b/web/funnelAC/admin/vms_bld.com
new file mode 100644
index 0000000000..6b74ce069b
--- /dev/null
+++ b/web/funnelAC/admin/vms_bld.com
@@ -0,0 +1,120 @@
+$! VMSBUILD.COM Build the Funnelweb program under VMS
+$!
+$! J Begg VSM Software Services 11-Feb-1992 jeremy@vsm.com.au
+$!
+$! set verify
+$ set noon
+$ say = "write sys$output"
+$ sts = 1
+$
+$!
+$! Make sure we are in the sources directory -- Assumes this procedure is in
+$! the same directory as the sources.
+$!
+$ cur_def = f$env("DEFAULT")
+$ proc = f$env("PROCEDURE")
+$ procnam = proc - f$parse(proc,,,"VERSION")
+$ procdir = proc - f$parse(proc,,,"NAME") -
+ - f$parse(proc,,,"TYPE") -
+ - f$parse(proc,,,"VERSION")
+$ sourcedir = procdir - "ADMIN]" + "SOURCES]"
+$ if f$search(sourcedir+"WEAVE.C").eqs.""
+$ then
+$ say "It would appear that the FunnelWeb sources have not been"
+$ say "loaded into the correct directory. Please move them into"
+$ say " ", procdir
+$ say "then re-execute this procedure."
+$ goto Exit
+$ endif
+$
+$ set default 'sourcedir'
+
+$ show default
+$
+$!
+$! Check for VAX C, use GNU C if VAX C is not found
+$!
+$ if f$search("SYS$SYSTEM:VAXC.EXE").nes.""
+$ then
+$ say " Using VAX C. If you prefer to use GNU C, edit the file"
+$ say " ",procnam
+$ say " as instructed therein."
+$ use_VAXC = "true"
+$ else
+$ say " VAX C not found -- using GNU C."
+$ use_VAXC = "false"
+$ endif
+$
+$!*************************************************************************
+$! UNCOMMENT the following line to force use of VAX C !*
+$! use_VAXC = "true" !*
+$! UNCOMMENT the following line to force use of GNU C !*
+$! use_VAXC = "false" !*
+$!*************************************************************************
+$!
+$! Set up the appropriate symbols
+$!
+$ if use_VAXC
+$ then
+$ cc = "CC"
+$ cflags = "/DEBUG/WARN/NOOPT/LIST"
+$ else
+$ cc = "GCC"
+$ cflags = " -g -Wall"
+$ endif
+$
+$ link = "link"
+$
+$!
+$! An object library is used to hold .OBJ files along the way.
+$!
+$ if f$search("FUNNELWEB.OLB").eqs."" then $ lib/cre/obj funnelweb.olb
+$
+$ if "''p1'" .eqs. "LINK" then $ goto Done_Compile
+$!
+$! Search for .C files, compiling same.
+$!
+$ old_src = ""
+$ filecount = 0
+$ skiptofile = ""
+$ if "''p1'" .nes. ""
+$ then
+$ skiptofile = "$USERS:[ROSS.FWDIR.SOURCES]''p1'"
+$ endif
+$Compile:
+$ src = f$search("*.C")
+$ if src.eqs."" then $ goto Done_Compile
+$ if src.eqs.old_src then $ goto Done_Compile
+$ srcnam = src - f$parse(src,,,"TYPE") - f$parse(src,,,"VERSION")
+$ if srcnam .lts. skiptofile
+$ then
+$ write sys$output "Skipping ''srcnam'"
+$ goto Compile
+$ endif
+$ say "Compiling ",srcnam
+$ 'cc 'cflags 'srcnam
+$ if .not.$status then $ goto Compile_Failed
+$ lib/repl funnelweb 'srcnam
+$ deletx 'srcnam'.obj;
+$ goto Compile
+$
+$Compile_Failed:
+$ sts = $status
+$ say "Build of FunnelWeb aborted because compile failed for file:"
+$ say src
+$ goto Exit
+$
+$Done_Compile:
+$ say "Linking..."
+$ cur_exe = f$search("FUNNELWEB.EXE")
+$ !Jeremy's link: link/debug/map/full funnelweb/opt
+$ link funnelweb/library/include=main,sys$input:/opt/exe='procdir'fw.exe
+sys$share:vaxcrtl/share
+$ if $status then $ goto Exit
+$ sts = $status
+$ say "Build of FunnelWeb aborted in Link phase"
+$ if f$search("FUNNELWEB.EXE").nes.cur_exe then $ delete funnelweb.exe;
+$
+$Exit:
+$ set default 'cur_def'
+$ exit sts
diff --git a/web/funnelAC/answers/0license.txt b/web/funnelAC/answers/0license.txt
new file mode 100644
index 0000000000..8c2fba8bec
--- /dev/null
+++ b/web/funnelAC/answers/0license.txt
@@ -0,0 +1,37 @@
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+The files in this directory are:
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+###############################################################################
+
diff --git a/web/funnelAC/answers/an01.lis b/web/funnelAC/answers/an01.lis
new file mode 100644
index 0000000000..5d3cbe8792
--- /dev/null
+++ b/web/funnelAC/answers/an01.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+E: No macros defined.
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+There were 2 Errors.
diff --git a/web/funnelAC/answers/an02.lis b/web/funnelAC/answers/an02.lis
new file mode 100644
index 0000000000..cb554e6d28
--- /dev/null
+++ b/web/funnelAC/answers/an02.lis
@@ -0,0 +1,11 @@
+FUNNELWEB LISTING FILE
+======================
+
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+There was 1 Error.
diff --git a/web/funnelAC/answers/an03.lis b/web/funnelAC/answers/an03.lis
new file mode 100644
index 0000000000..8cda130586
--- /dev/null
+++ b/web/funnelAC/answers/an03.lis
@@ -0,0 +1,86 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| AN03: Test semantics checking of macros.
+ 2 2|
+ 3 3| First define some macros to call.
+ 4 4| @$@<Zero@>@Z@M@{@}
+ 5 5| @$@<One@>@(@1@)@Z@M@{@}
+ 6 6| @$@<Two@>@(@2@)@Z@M@{@}
+ 7 7|
+ 8 8| 1. Test call to undefined macro.
+ 9 9| @$@<Sloth1@>@Z==@{@<Walrus@>@}
+ Error|...................^Call to undefined macro.
+ 10 10|
+ 11 11| 2. Test calls with wrong number of parameters.
+ 12 12| @$@<Sloth2@>@Z==@{
+ 13 13| @<Zero@>
+ 14 14| @<Zero@>@(@)
+ Error|.^Call has 1 parameter, but the macro
+ |.^definition at line 4 specifies 0 parameters.
+ |.^Note: If your call looks like this: @<Macro@>@(@) then you
+ |.^should be aware that FunnelWeb treats this as a call with
+ |.^a single parameter consisting of the empty string. This
+ |.^is a consequence of parameter delimiters @"@" being optional.
+ 15 15| @<Zero@>@(@,@)
+ Error|.^Call has 2 parameters, but the macro
+ |.^definition at line 4 specifies 0 parameters.
+ 16 16| @<One@>
+ Error|.^Call has 0 parameters, but the macro
+ |.^definition at line 5 specifies 1 parameter.
+ 17 17| @<One@>@(@)
+ 18 18| @<One@>@(Walrus@,@)
+ Error|.^Call has 2 parameters, but the macro
+ |.^definition at line 5 specifies 1 parameter.
+ 19 19| @<Two@>@(Sloth@)
+ Error|.^Call has 1 parameter, but the macro
+ |.^definition at line 6 specifies 2 parameters.
+ 20 20| @}
+ 21 21|
+ 22 22| 3. Test call to file macro.
+ 23 23| @O@<deleteme.txt@>@{@}
+ |.^This file macro is called one or more times.
+ |.^Each call has been flagged with an error message.
+ 24 24| @$@<Teapot@>@Z@{@<deleteme.txt@>@}
+ Error|.................^Calls to file macros are not allowed.
+ |.................^Reason: It should be possible to comment out a
+ |.................^file macro without a big fuss. Calling a file macro
+ |.................^just tangles it up in the macro structure,
+ |.................^making it more difficult to comment out later.
+ 25 25|
+ 26 26| 4. Test macro never used and has <special>Z.
+ 27 27| @$@<Elephant@>@Z@{@}
+ 28 28|
+ 29 29| 5. Test macro often used and has <special>M.
+ 30 30| @$@<Giraffe@>@M@{@}
+ 31 31| @$@<Use Giraffe@>@Z@{@<Giraffe@>@<Giraffe@>@}
+ 32 32|
+ 33 33| 6. Test macro never used and no <special>Z
+ 34 34| @$@<Zebra@>@{@}
+ Error|.^This macro is never used (and has no @Z).
+ 35 35|
+ 36 36| 7. Test multiply used and no <special>M.
+ 37 37| @$@<Monkey@>@{@}
+ Error|.^This macro is used more than once (and has no @M).
+ 38 38| @$@<Use Monkey@>@Z@{@<Monkey@>@<Monkey@>@}
+ 39 39|
+ 40 40| 8. Test directly recursive macro.
+ 41 41| @$@<Who do ya call?@>@{@<Who do ya call?@>@}
+ Error|.^This macro has an infinite expansion.
+ 42 42|
+ 43 43| 9. Test indirectly recursive macro.
+ 44 44| @$@<X@>@M@{@<Y@>@}
+ Error|.^This macro has an infinite expansion.
+ 45 45| @$@<Y@>@{@<X@>@}
+ Error|.^This macro has an infinite expansion.
+ 46 46|
+ 47 47| 10. Test callers of recursive macros.
+ 48 48| @$@<Z@>@Z@{@<X@>@}
+ Error|.^This macro has an infinite expansion.
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 13 Errors.
diff --git a/web/funnelAC/answers/an04.lis b/web/funnelAC/answers/an04.lis
new file mode 100644
index 0000000000..46c3409a8e
--- /dev/null
+++ b/web/funnelAC/answers/an04.lis
@@ -0,0 +1,28 @@
+FUNNELWEB LISTING FILE
+======================
+
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| AN04: Test document list checks.
+ 2 2|
+ 3 3| 1. Test for sections with no names.
+ 4 4|
+ 5 5| @A@<This section has both a name and a macro@>
+ 6 6| @$@<Sloth@>@Z@{@}
+ 7 7|
+ 8 8| @A@<This section has an explicit name but no macro@>
+ 9 9|
+ 10 10| @A
+ 11 11| @$@<This section has no explicit name but does have a macro@>@Z@{@}
+ 12 12|
+ 13 13| @A This section has no name and no macro to inherit one from.
+ Error|.^This section has no name.
+ |.^You can give it one explicitly (As in @A@<Sloth@>) or implicitly by
+ |.^defining a macro (whose name will be inherited) within the section.
+ 14 14|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 2 Errors.
diff --git a/web/funnelAC/answers/ex01.lis b/web/funnelAC/answers/ex01.lis
new file mode 100644
index 0000000000..9cb0a6b7c9
--- /dev/null
+++ b/web/funnelAC/answers/ex01.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex01.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/ex01.out b/web/funnelAC/answers/ex01.out
new file mode 100644
index 0000000000..557db03de9
--- /dev/null
+++ b/web/funnelAC/answers/ex01.out
@@ -0,0 +1 @@
+Hello World
diff --git a/web/funnelAC/answers/ex02.lis b/web/funnelAC/answers/ex02.lis
new file mode 100644
index 0000000000..1f31a5ff30
--- /dev/null
+++ b/web/funnelAC/answers/ex02.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex02.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/ex02.out b/web/funnelAC/answers/ex02.out
new file mode 100644
index 0000000000..557db03de9
--- /dev/null
+++ b/web/funnelAC/answers/ex02.out
@@ -0,0 +1 @@
+Hello World
diff --git a/web/funnelAC/answers/ex03.lis b/web/funnelAC/answers/ex03.lis
new file mode 100644
index 0000000000..beb06214aa
--- /dev/null
+++ b/web/funnelAC/answers/ex03.lis
@@ -0,0 +1,50 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| EX03: An example containing errors to do with the number of times
+ 2 2| that macros are called.
+ 3 3|
+ 4 4| @O@<ex03.out@>==@{@-
+ 5 5| @<Include Files@>
+ 6 6| @<Include Files@>
+ 7 7| @<Main Program@>
+ 8 8| @}
+ 9 9|
+ 10 10| @$@<Main Program@>==@{@-
+ 11 11| main()
+ 12 12| {
+ 13 13| doit();
+ 14 14| }
+ 15 15| @}
+ 16 16|
+ 17 17| @$@<Subroutine@>==@{@-
+ Error|.^This macro is never used (and has no @Z).
+ 18 18| void doit()
+ 19 19| {
+ 20 20| int i;
+ 21 21| for (i=0;i<10;i++)
+ 22 22| {
+ 23 23| @<Print@>
+ 24 24| @<Print@>
+ 25 25| }
+ 26 26| }@}
+ 27 27|
+ 28 28| @$@<Print@>==@{@-
+ Error|.^This macro is used more than once (and has no @M).
+ 29 29| printf("Hello World!");
+ 30 30| printf("\n");@}
+ 31 31|
+ 32 32| @$@<Scan@>==@{scanf@}
+ Error|.^This macro is never used (and has no @Z).
+ 33 33|
+ 34 34| @$@<Include Files@>==@{@-
+ Error|.^This macro is used more than once (and has no @M).
+ 35 35| #include <stdio.h>
+ 36 36| #include <stdlib.h>@}
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 4 Errors.
diff --git a/web/funnelAC/answers/ex04.lis b/web/funnelAC/answers/ex04.lis
new file mode 100644
index 0000000000..780c9c7f77
--- /dev/null
+++ b/web/funnelAC/answers/ex04.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex04.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/ex04.out b/web/funnelAC/answers/ex04.out
new file mode 100644
index 0000000000..939a0cdf82
--- /dev/null
+++ b/web/funnelAC/answers/ex04.out
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <stdlib.h>
+void doit()
+{
+ int i;
+ for (i=0;i<10;i++)
+ {
+ printf("Hello World!");
+ printf("\n");
+ printf("Hello World!");
+ printf("\n");
+ }
+}
+main()
+{
+ doit();
+}
+
diff --git a/web/funnelAC/answers/ex05.lis b/web/funnelAC/answers/ex05.lis
new file mode 100644
index 0000000000..a7e84fcdaa
--- /dev/null
+++ b/web/funnelAC/answers/ex05.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex05.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/ex05.out b/web/funnelAC/answers/ex05.out
new file mode 100644
index 0000000000..4a12476ca9
--- /dev/null
+++ b/web/funnelAC/answers/ex05.out
@@ -0,0 +1,18 @@
+program adt(input,output);
+type buffer_type =
+ record
+ length : integer;
+ buf : array[1..100] of char;
+ end;
+type complex_type = record r,i : real; end;
+
+bigbuf : buffer_type;
+
+procedure buf_init (var b : buffer_type ) {Body of buf_init}
+procedure buf_add (var b : buffer_type; ch : char) {Body of buf_add}
+procedure buf_get (var b : buffer_type; var ch : char) {Body of buf_get}
+procedure cm_set (var c: complex_type; a,b: real) {Body of cm_set}
+procedure cm_add (a,b: complex_type; var c: complex_type) {Body of cm_add}
+{Other procedures and functions}
+
+begin startproc; end.
diff --git a/web/funnelAC/answers/ex06.lis b/web/funnelAC/answers/ex06.lis
new file mode 100644
index 0000000000..5a2782517d
--- /dev/null
+++ b/web/funnelAC/answers/ex06.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex06.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/ex06.out b/web/funnelAC/answers/ex06.out
new file mode 100644
index 0000000000..03ac7feb13
--- /dev/null
+++ b/web/funnelAC/answers/ex06.out
@@ -0,0 +1,22 @@
+program adt(input,output);
+type buffer_type = record
+ length : integer;
+ buf : array[1..100] of char;
+ end;
+
+type complex_type = record r,i : real; end;
+
+
+bigbuf : buffer_type;
+
+
+procedure buf_init(var b : buffer_type) {Body of buf_init}
+procedure buf_add(var b : buffer_type; ch : char) {Body of buf_add}
+procedure buf_get(var b : buffer_type; var ch : char) {Body of buf_get}
+
+procedure cm_set(var c: complex_type; a,b : real) {Body of cm_set}
+procedure cm_add(a,b : complex_type; var c: complex_type) {Body of cm_add}
+{Other procedures and functions}
+
+
+begin startproc; end.
diff --git a/web/funnelAC/answers/ex07.lis b/web/funnelAC/answers/ex07.lis
new file mode 100644
index 0000000000..b354e7c18e
--- /dev/null
+++ b/web/funnelAC/answers/ex07.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex07.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/ex07.out b/web/funnelAC/answers/ex07.out
new file mode 100644
index 0000000000..b6e41eea63
--- /dev/null
+++ b/web/funnelAC/answers/ex07.out
@@ -0,0 +1,24 @@
+
+
+x=1;
+while (x<=10)
+ {
+ printf("X=%u\n",x);
+ }
+
+
+x:=1;
+while (x<=10)
+ {
+ printf("X=%u\n",x);
+ }
+
+
+x=1;
+while (x<=10)
+ {
+ printf("X=%u\n",x);
+ }
+
+
+
diff --git a/web/funnelAC/answers/ex08.lis b/web/funnelAC/answers/ex08.lis
new file mode 100644
index 0000000000..17d93d8838
--- /dev/null
+++ b/web/funnelAC/answers/ex08.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex08.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/ex08.out b/web/funnelAC/answers/ex08.out
new file mode 100644
index 0000000000..5820d58ba2
--- /dev/null
+++ b/web/funnelAC/answers/ex08.out
@@ -0,0 +1,107 @@
+The Twelve Bugs of Christmas
+----------------------------
+For the first bug of Christmas, my manager said to me
+ See if they can do it again.
+
+For the second bug of Christmas, my manager said to me
+ Ask them how they did it and
+ See if they can do it again.
+
+For the third bug of Christmas, my manager said to me
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+For the fourth bug of Christmas, my manager said to me
+ Run with the debugger
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+For the fifth bug of Christmas, my manager said to me
+ Ask for a dump
+ Run with the debugger
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+For the sixth bug of Christmas, my manager said to me
+ Reinstall the software
+ Ask for a dump
+ Run with the debugger
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+For the seventh bug of Christmas, my manager said to me
+ Say they need an upgrade
+ Reinstall the software
+ Ask for a dump
+ Run with the debugger
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+For the eighth bug of Christmas, my manager said to me
+ Find a way around it
+ Say they need an upgrade
+ Reinstall the software
+ Ask for a dump
+ Run with the debugger
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+For the ninth bug of Christmas, my manager said to me
+ Blame it on the hardware
+ Find a way around it
+ Say they need an upgrade
+ Reinstall the software
+ Ask for a dump
+ Run with the debugger
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+For the tenth bug of Christmas, my manager said to me
+ Change the documentation
+ Blame it on the hardware
+ Find a way around it
+ Say they need an upgrade
+ Reinstall the software
+ Ask for a dump
+ Run with the debugger
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+For the eleventh bug of Christmas, my manager said to me
+ Say it's not supported
+ Change the documentation
+ Blame it on the hardware
+ Find a way around it
+ Say they need an upgrade
+ Reinstall the software
+ Ask for a dump
+ Run with the debugger
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+For the twelfth bug of Christmas, my manager said to me
+ Tell them it's a feature
+ Say it's not supported
+ Change the documentation
+ Blame it on the hardware
+ Find a way around it
+ Say they need an upgrade
+ Reinstall the software
+ Ask for a dump
+ Run with the debugger
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+
+This song appeared in the internet newsgroup rec.humor.funny on 24-Dec-1991.
+It was contributed by Pat Scannell (scannell@darkstar.ma30.bull.com).
diff --git a/web/funnelAC/answers/ex09.lis b/web/funnelAC/answers/ex09.lis
new file mode 100644
index 0000000000..1fdc31299c
--- /dev/null
+++ b/web/funnelAC/answers/ex09.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex09.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/ex09.out b/web/funnelAC/answers/ex09.out
new file mode 100644
index 0000000000..80fbfc9f1f
--- /dev/null
+++ b/web/funnelAC/answers/ex09.out
@@ -0,0 +1,6 @@
+
+I like to go shooting, it's a whole lot of fun,
+'Cos I shoot with a camera instead of a gun.
+The animals flock to be petted and fed,
+Cos they know my camera isn't loaded with lead.
+- RNW, 04-Jan-1991.
diff --git a/web/funnelAC/answers/ex10.lis b/web/funnelAC/answers/ex10.lis
new file mode 100644
index 0000000000..613224af3d
--- /dev/null
+++ b/web/funnelAC/answers/ex10.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex10.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/ex10.out b/web/funnelAC/answers/ex10.out
new file mode 100644
index 0000000000..9672b09b88
--- /dev/null
+++ b/web/funnelAC/answers/ex10.out
@@ -0,0 +1,2 @@
+This is the text of the sloth macro.
+
diff --git a/web/funnelAC/answers/ex11.lis b/web/funnelAC/answers/ex11.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/answers/ex11.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/ex11.tex b/web/funnelAC/answers/ex11.tex
new file mode 100644
index 0000000000..b5e6714dd2
--- /dev/null
+++ b/web/funnelAC/answers/ex11.tex
@@ -0,0 +1,384 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+EX11: This example shows how FunnelWeb typesets macros, typesetter commands
+ and free text.
+
+You are reading some free text before the macro. Free text can consist
+of any text (not containing the FunnelWeb special character) including
+typesetter commands
+such as \$, \%, \#, and $\backslash$TeX$\{$$\}$ which
+will be typeset to appear exactly as they do in the input file!
+Look out! Here comes a macro!
+
+\fwbeginmacro
+\fwfilename{ex11.out}{1}\fwequals \fwodef \fwbtx[This text is part of
+a macro definition.
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+
+This is free text following the macro. This sentence contains
+two \fwlit{inline} typesetter \fwemp{directives}.
+Now here is a non-inline typesetting directive.
+
+
+\fwnewpage
+
+
+This sentence will appear on the next page.
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/answers/ex12.lis b/web/funnelAC/answers/ex12.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/answers/ex12.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/ex12.tex b/web/funnelAC/answers/ex12.tex
new file mode 100644
index 0000000000..145d1d111f
--- /dev/null
+++ b/web/funnelAC/answers/ex12.tex
@@ -0,0 +1,385 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+EX12: This example gives some simple headings and demonstrates heading name
+ inheritance.
+
+\fwbeginmacro
+\fwfilename{ex12.out}{1}\fwequals \fwodef \fwbtx[dummy text]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwseca{1}{Feed the Penguins and Save the World}
+\fwsecb{1.1}{Feed the Penguins}
+\fwsecc{1.1.1}{Feed the little penguins}
+\fwsecc{1.1.2}{Feed the big penguins}
+\fwsecb{1.2}{Save the World}
+\fwsecc{1.2.1}{Save Europe}
+\fwsecc{1.2.2}{Save Africa}
+
+\fwsecc{1.2.3}{Save the rest of the world} This heading hasn't been given an explicit name, but will inherit the
+name $\backslash$p$\{$Save the rest of the world$\}$ from the macro definition below.
+
+\fwbeginmacro
+\fwmacroname{Save the rest of the world}{2}\fwzero{}\fwequals \fwodef \fwbtx[...]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/answers/ex13.lis b/web/funnelAC/answers/ex13.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/answers/ex13.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/ex13.tex b/web/funnelAC/answers/ex13.tex
new file mode 100644
index 0000000000..835ae999e6
--- /dev/null
+++ b/web/funnelAC/answers/ex13.tex
@@ -0,0 +1,499 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+EX13: This example is used to generate typeset documentation which is
+ discussed in the tutorial in the FunnelWeb user's manual.
+
+
+\fwseca{1}{Table of Contents}
+
+
+\fwtocstart{}
+\fwtoca{1}{Table of Contents}
+\fwtoca{2}{Macros for Moral Support}
+\fwtoca{3}{An Extremely Imperative Stack Abstraction}
+\fwtocb{3.1}{Define the Stack}
+\fwtocb{3.2}{Push the Stack}
+\fwtocb{3.3}{Pop the Stack}
+\fwtocb{3.4}{Rough the Stack Up a Bit}
+\fwtocfinish{}
+
+
+\fwseca{2}{Macros for Moral Support}
+
+The following macro contain comments that provide moral support in the
+output code.
+
+\fwbeginmacro
+\fwmacroname{Programmer's Cheer}{1}\fwmany{}\fwequals \fwodef \fwbtx[
+-- Shift to the left!
+-- Shift to the right!
+-- Pop up, push down!
+-- Byte! Byte! Byte!
+-- (From "The New Hacker's Dictionary").
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is invoked in definitions 6 and 8.}
+\fwendmacronotes
+\fwendmacro
+
+
+The next macro is similar but is distributed throughout the program.
+\fwbeginmacro
+\fwmacroname{Hacker's Cheer}{2}\fwplusequals \fwodef \fwbtx[
+-- Pointer to the left
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 2, 3, 5, 7, and 9.}
+\fwusedin{This macro is invoked in definition 10.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwseca{3}{An Extremely Imperative Stack Abstraction}
+
+\fwsecb{3.1}{Define the Stack}
+\fwbeginmacro
+\fwmacroname{Hacker's Cheer}{3}\fwplusequals \fwodef \fwbtx[-- Pointer to the right
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 2, 3, 5, 7, and 9.}
+\fwusedin{This macro is invoked in definition 10.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Stack Type}{4}\fwzero{}\fwequals \fwodef \fwbtx[type stack = record ... end;]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsecb{3.2}{Push the Stack}
+\fwbeginmacro
+\fwmacroname{Hacker's Cheer}{5}\fwplusequals \fwodef \fwbtx[-- Hack that code
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 2, 3, 5, 7, and 9.}
+\fwusedin{This macro is invoked in definition 10.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Push Procedure}{6}\fwzero{}\fwequals \fwodef \fwbtx[procedure push(var b:stack; v:value); ]fwetx=%
+\fwmacroname{Programmer's Cheer}{1}\fwbtx[ {...}]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsecb{3.3}{Pop the Stack}
+\fwbeginmacro
+\fwmacroname{Hacker's Cheer}{7}\fwplusequals \fwodef \fwbtx[-- Tight! Tight! Tight!
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 2, 3, 5, 7, and 9.}
+\fwusedin{This macro is invoked in definition 10.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Pop Procedure}{8}\fwzero{}\fwequals \fwodef \fwbtx[procedure pop(var b:stack); ]fwetx=%
+\fwmacroname{Programmer's Cheer}{1}\fwbtx[ {...}]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsecb{3.4}{Rough the Stack Up a Bit}
+\fwbeginmacro
+\fwmacroname{Hacker's Cheer}{9}\fwplusequals \fwodef \fwbtx[-- (RNW, 04-Jan-1991).
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 2, 3, 5, 7, and 9.}
+\fwusedin{This macro is invoked in definition 10.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Rough Procedure}{10}\fwzero{}\fwequals \fwodef \fwbtx[procedure rough(var b:stack); ]fwetx=%
+\fwmacroname{Hacker's Cheer}{2}\fwbtx[ {...}]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwbeginmacro
+\fwfilename{dummy.txt}{11}\fwequals \fwodef \fwbtx[dummy
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/answers/ex14.lis b/web/funnelAC/answers/ex14.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/answers/ex14.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/ex14.tex b/web/funnelAC/answers/ex14.tex
new file mode 100644
index 0000000000..1de1e8756b
--- /dev/null
+++ b/web/funnelAC/answers/ex14.tex
@@ -0,0 +1,369 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+EX14: This example demonstrates the literal and emphasis typesetting constructs.
+
+The following procedure \fwlit{put\_sloth} writes the \fwlit{sloth} variable to
+the output file. Note: \fwemp{The output file must be opened for writing
+at this point or the program will crash!}
+
+\fwbeginmacro
+\fwfilename{ex14.out}{1}\fwequals \fwodef \fwbtx[dummy
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/answers/ex15.lis b/web/funnelAC/answers/ex15.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/answers/ex15.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/ex15.tex b/web/funnelAC/answers/ex15.tex
new file mode 100644
index 0000000000..a82b33d2f2
--- /dev/null
+++ b/web/funnelAC/answers/ex15.tex
@@ -0,0 +1,390 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+EX15: This example demonstrates some of FunnelWeb's generic typesetting
+ constructs.
+
+\fwvskip{40}
+\fwcenterline{\fwfonttitle{Hairy Wombat}}
+\fwcenterline{\fwfonttitle{Simulation}}
+\fwvskip{10}
+\fwcenterline{\fwfontsmalltitle{A Program in Six Parts}}
+\fwcenterline{\fwfontsmalltitle{Simulating the Life of Some Hairy Wombats}}
+\fwvskip{20}
+\fwleftline{\fwfontnormal{By Zqitzypbuswapzra Ypongtatoslrtzz}}
+
+\fwnewpage
+
+
+\fwtocstart{}
+\fwtoca{1}{Section One}
+\fwtoca{2}{Section Two}
+\fwtocfinish{}
+
+
+\fwnewpage
+
+
+\fwseca{1}{Section One}
+\fwseca{2}{Section Two}
+
+\fwbeginmacro
+\fwfilename{ex15.out}{1}\fwequals \fwodef \fwbtx[Dummy
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/answers/ex16.lis b/web/funnelAC/answers/ex16.lis
new file mode 100644
index 0000000000..46682a4458
--- /dev/null
+++ b/web/funnelAC/answers/ex16.lis
@@ -0,0 +1,13 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex16.out.
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/ex16.out b/web/funnelAC/answers/ex16.out
new file mode 100644
index 0000000000..a3b510afd9
--- /dev/null
+++ b/web/funnelAC/answers/ex16.out
@@ -0,0 +1,18 @@
+with text_io; use text_io;
+
+procedure example is
+ n : constant natural := 10; -- How many numbers? (Ans: [1,n]).
+ p : constant natural := 5; -- How many powers? (Ans: [1,p]).
+begin -- example
+ for i in 1..n loop
+ declare
+ ip : natural := 1;
+ begin
+ for power in 1..p loop
+ ip:=ip*i;
+ put(natural'image(ip) & " ");
+ end loop;
+ new_line;
+ end;
+ end loop;
+end example;
diff --git a/web/funnelAC/answers/ex16.tex b/web/funnelAC/answers/ex16.tex
new file mode 100644
index 0000000000..c29b4ce43e
--- /dev/null
+++ b/web/funnelAC/answers/ex16.tex
@@ -0,0 +1,448 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+
+\fwvskip{40}
+\fwcenterline{\fwfonttitle{Powers:}}
+\fwcenterline{\fwfonttitle{An Example of}}
+\fwcenterline{\fwfonttitle{A Short}}
+\fwcenterline{\fwfonttitle{FunnelWeb .fw File}}
+\fwvskip{10}
+\fwcenterline{\fwfontsmalltitle{by Ross Williams}}
+\fwcenterline{\fwfontsmalltitle{26 January 1992}}
+\fwvskip{20}
+
+\fwtocstart{}
+\fwtoca{1}{FunnelWeb Example Program}
+\fwtocb{1.1}{ex16.out}
+\fwtocb{1.2}{Pull in packages}
+\fwtocb{1.3}{Write out the first p powers of i on a single line}
+\fwtocfinish{}
+
+
+\fwseca{1}{FunnelWeb Example Program}
+
+This program writes out each of the first \fwlit{p} powers of the first \fwlit{n}
+integers. These constant parameters are located here so that they are easy to
+change.
+
+\fwbeginmacro
+\fwmacroname{Constants}{1}\fwequals \fwodef \fwbtx[n : constant natural := 10; -- How many numbers? (Ans: [1,n]).
+p : constant natural := 5; -- How many powers? (Ans: [1,p]).]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is invoked in definition 2.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsecb{1.1}{ex16.out} Here is the outline of the program. This FunnelWeb file generates a single
+Ada output file called \fwlit{Power.ada}. The main program consists of a loop that
+iterates once for each number to be written out.
+
+\fwbeginmacro
+\fwfilename{ex16.out}{2}\fwequals \fwodef \fwmacroname{Pull in packages}{3}\fwbtx[
+
+procedure example is
+ ]fwetx=%
+\fwmacroname{Constants}{1}\fwbtx[
+begin -- example
+ for i in 1..n loop
+ ]fwetx=%
+\fwmacroname{Write out the first p powers of i on a single line}{4}\fwbtx[
+ end loop;
+end example;
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsecb{1.2}{Pull in packages} In this section, we pull in the packages that this program needs to run. In
+fact, all we need is the IO package so that we can write out the results. To use
+the IO package, we first of all need to haul it in (\fwlit{with text\_io}) and then
+we need to make all its identifiers visible at the top level (\fwlit{use text\_io}).
+
+\fwbeginmacro
+\fwmacroname{Pull in packages}{3}\fwequals \fwodef \fwbtx[with text_io; use text_io;]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is invoked in definition 2.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsecb{1.3}{Write out the first p powers of i on a single line} Here is the bit that writes out the first \fwlit{p} powers of \fwlit{i}. The power
+values are calculated incrementally in \fwlit{ip} to avoid the use of the
+exponentiation operator.
+
+\fwbeginmacro
+\fwmacroname{Write out the first p powers of i on a single line}{4}\fwequals \fwodef \fwbtx[declare
+ ip : natural := 1;
+begin
+ for power in 1..p loop
+ ip:=ip*i;
+ put(natural'image(ip) & " ");
+ end loop;
+ new_line;
+end;]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is invoked in definition 2.}
+\fwendmacronotes
+\fwendmacro
+
+
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/answers/generate.lis b/web/funnelAC/answers/generate.lis
new file mode 100644
index 0000000000..8588c0fca9
--- /dev/null
+++ b/web/funnelAC/answers/generate.lis
@@ -0,0 +1,15 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed sc06.fw.
+Tangle: Completed sc08.fw.
+Tangle: Completed sc09.fw.
+Tangle: Completed sc13e.fwi.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/hi01.lis b/web/funnelAC/answers/hi01.lis
new file mode 100644
index 0000000000..58682d7c0d
--- /dev/null
+++ b/web/funnelAC/answers/hi01.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi01.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/hi01.out b/web/funnelAC/answers/hi01.out
new file mode 100644
index 0000000000..9ab646f4ff
--- /dev/null
+++ b/web/funnelAC/answers/hi01.out
@@ -0,0 +1,9 @@
+
+while the_walrus_is_sleepy do
+ begin
+ writeln('zzzzzzz');
+
+ wake_up_the_walrus(the_walrus);
+
+ writeln('Umpharumpha...');
+ end;
diff --git a/web/funnelAC/answers/hi02.lis b/web/funnelAC/answers/hi02.lis
new file mode 100644
index 0000000000..2c342e0954
--- /dev/null
+++ b/web/funnelAC/answers/hi02.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi02.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/hi02.out b/web/funnelAC/answers/hi02.out
new file mode 100644
index 0000000000..d1a9b3e8cf
--- /dev/null
+++ b/web/funnelAC/answers/hi02.out
@@ -0,0 +1,6 @@
+
+while sloth<walrus loop
+ assert(sloth<walrus,"AWK! sloth>=walrus!!!!!!!");
+ assert(timer<timermax,"AWK! timer>=timermax!!!");
+ inc(sloth);
+end loop
diff --git a/web/funnelAC/answers/hi03.lis b/web/funnelAC/answers/hi03.lis
new file mode 100644
index 0000000000..80014f814d
--- /dev/null
+++ b/web/funnelAC/answers/hi03.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi03.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/hi03.out b/web/funnelAC/answers/hi03.out
new file mode 100644
index 0000000000..5b1b66b552
--- /dev/null
+++ b/web/funnelAC/answers/hi03.out
@@ -0,0 +1,6 @@
+
+while sloth<walrus loop
+ assert(sloth<walrus,"AWK! sloth>=walrus!!!!!!!");
+ assert(timer<timermax,"AWK! timer>=timermax!!!");
+ inc(sloth);
+end loop
diff --git a/web/funnelAC/answers/hi04.lis b/web/funnelAC/answers/hi04.lis
new file mode 100644
index 0000000000..c215c0f14b
--- /dev/null
+++ b/web/funnelAC/answers/hi04.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi04.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/hi04.out b/web/funnelAC/answers/hi04.out
new file mode 100644
index 0000000000..7069503f68
--- /dev/null
+++ b/web/funnelAC/answers/hi04.out
@@ -0,0 +1,3 @@
+-------
+get_command_line(comline)
+-------
diff --git a/web/funnelAC/answers/hi05.lis b/web/funnelAC/answers/hi05.lis
new file mode 100644
index 0000000000..422de4e7eb
--- /dev/null
+++ b/web/funnelAC/answers/hi05.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi05.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/hi05.out b/web/funnelAC/answers/hi05.out
new file mode 100644
index 0000000000..d2143079f1
--- /dev/null
+++ b/web/funnelAC/answers/hi05.out
@@ -0,0 +1,7 @@
+Unreadable Postscript code
+/print { push pop pop push turn around and jump up and down and print it} def
+
+Unreadable Postscript code
+/zap { push pop pop push turn around and jump up and down and print it} def
+
+Unreadable Postscript code
diff --git a/web/funnelAC/answers/hi06.lis b/web/funnelAC/answers/hi06.lis
new file mode 100644
index 0000000000..e053ffc8bf
--- /dev/null
+++ b/web/funnelAC/answers/hi06.lis
@@ -0,0 +1,13 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi06a.out.
+Tangle: Completed hi06b.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/hi06a.out b/web/funnelAC/answers/hi06a.out
new file mode 100644
index 0000000000..b6645c6f7d
--- /dev/null
+++ b/web/funnelAC/answers/hi06a.out
@@ -0,0 +1,3 @@
+DCL commands
+copy printme.txt unixnode::
+DCL commands
diff --git a/web/funnelAC/answers/hi06b.out b/web/funnelAC/answers/hi06b.out
new file mode 100644
index 0000000000..d26ba0f49c
--- /dev/null
+++ b/web/funnelAC/answers/hi06b.out
@@ -0,0 +1,3 @@
+unix commands
+print printme.txt
+unix commands
diff --git a/web/funnelAC/answers/hi07.lis b/web/funnelAC/answers/hi07.lis
new file mode 100644
index 0000000000..5a23a3ee91
--- /dev/null
+++ b/web/funnelAC/answers/hi07.lis
@@ -0,0 +1,13 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi07a.out.
+Tangle: Completed hi07b.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/hi07a.out b/web/funnelAC/answers/hi07a.out
new file mode 100644
index 0000000000..052b1c079a
--- /dev/null
+++ b/web/funnelAC/answers/hi07a.out
@@ -0,0 +1,4 @@
+First lump of text shared by both documents.
+Text for first document
+Second lump of text shared by both documents.
+
diff --git a/web/funnelAC/answers/hi07b.out b/web/funnelAC/answers/hi07b.out
new file mode 100644
index 0000000000..8c94004628
--- /dev/null
+++ b/web/funnelAC/answers/hi07b.out
@@ -0,0 +1,4 @@
+First lump of text shared by both documents.
+Text for second document
+Second lump of text shared by both documents.
+
diff --git a/web/funnelAC/answers/hi08.lis b/web/funnelAC/answers/hi08.lis
new file mode 100644
index 0000000000..e0fa58dddb
--- /dev/null
+++ b/web/funnelAC/answers/hi08.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi08.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/hi08.out b/web/funnelAC/answers/hi08.out
new file mode 100644
index 0000000000..87b344c98f
--- /dev/null
+++ b/web/funnelAC/answers/hi08.out
@@ -0,0 +1,8 @@
+1992 ANNUAL REPORT TO Shareholders
+==================================
+This has been a very good year for The Very Big Corporation of America.
+With your help, we have been able to successfully
+screw the customers for every cent they have.
+With gross earnings approaching six trillion dollars, we have been able to
+increase dividends.
+We expect to have an even better year next year.
diff --git a/web/funnelAC/answers/hi09.lis b/web/funnelAC/answers/hi09.lis
new file mode 100644
index 0000000000..fb069219c0
--- /dev/null
+++ b/web/funnelAC/answers/hi09.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi09.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/hi09.out b/web/funnelAC/answers/hi09.out
new file mode 100644
index 0000000000..0f7aeebe64
--- /dev/null
+++ b/web/funnelAC/answers/hi09.out
@@ -0,0 +1,98 @@
+
+[inherit ('NaryTree'), environment ('NaryTreeSet')]
+
+module NaryTreeSet;
+
+type NaryTreeSet = ^NaryTreeSetRecord;
+ NaryTreeSetRecord = record
+ Member: NaryTree;
+ Next: NaryTreeSet;
+ end;
+
+procedure NullNaryTreeSet (var Result: NaryTreeSet);
+begin new (Result);
+Result^.Member := (- MaxInt)::NaryTree;
+Result^.Next := nil end;
+
+function IsNullNaryTreeSet (S: NaryTreeSet): boolean;
+begin IsNullNaryTreeSet := S^.Member::integer = - MaxInt end;
+
+procedure ForEachNaryTree (S: NaryTreeSet; procedure DoIt (i: NaryTree));
+var ThisS, NextS: NaryTreeSet;
+begin ThisS := S;
+while ThisS^.Member::integer <> - MaxInt do
+ begin NextS := ThisS^.Next;
+ DoIt (ThisS^.Member);
+ ThisS := NextS end;
+end;
+
+function FirstNaryTree (S: NaryTreeSet): NaryTree;
+begin FirstNaryTree := S^.Member end;
+
+function IsNaryTreeInSet (i: NaryTree; S: NaryTreeSet): boolean;
+ procedure TestEquals (j: NaryTree);
+ begin if EqualNaryTree (i, j) then IsNaryTreeInSet := true; end;
+begin IsNaryTreeInSet := false; ForEachNaryTree (S, TestEquals); end;
+
+function IncludesNaryTreeSet (S1, S2: NaryTreeSet): boolean;
+var Result: boolean;
+ procedure TestIfInS1 (i: NaryTree);
+ begin if Result then if not IsNaryTreeInSet (i, S1) then Result := false; end;
+begin Result := true;
+ForEachNaryTree (S2, TestIfInS1);
+IncludesNaryTreeSet := Result end;
+
+function DisjointNaryTreeSets (S1, S2: NaryTreeSet): boolean;
+var Result: boolean;
+ procedure TestIfInS1 (i: NaryTree);
+ begin if Result then if IsNaryTreeInSet (i, S1) then Result := false; end;
+begin Result := true;
+ForEachNaryTree (S2, TestIfInS1);
+DisjointNaryTreeSets := Result end;
+
+function EqualNaryTreeSet (S1, S2: NaryTreeSet): boolean;
+begin
+EqualNaryTreeSet := IncludesNaryTreeSet (S1, S2) and IncludesNaryTreeSet (S2, S1);
+end;
+
+procedure InsertNaryTree (i: NaryTree; var S: NaryTreeSet);
+var This, Pred, Succ: NaryTreeSet;
+begin
+if not IsNaryTreeInSet (i, S) then
+ begin
+ Pred := nil; Succ := S;
+ while Succ^.Member::integer > i::integer do begin
+ Pred := Succ; Succ := Succ^.Next end;
+ if Succ^.Member::integer < i::integer then begin
+ new (This); This^.Next := Succ; This^.Member := i;
+ if Pred <> nil then Pred^.Next := This else S := This;
+ end;
+ end;
+end;
+
+procedure InsertNaryTrees (S1: NaryTreeSet; var S2: NaryTreeSet);
+var This, Pred, Succ: NaryTreeSet;
+ procedure AddNaryTree (i: NaryTree);
+ begin InsertNaryTree (i, S2) end;
+begin
+ForEachNaryTree (S1, AddNaryTree);
+end;
+
+procedure RemoveNaryTree (i: NaryTree; var S: NaryTreeSet);
+var Pred, This: NaryTreeSet;
+begin
+Pred := nil; This := S;
+while not EqualNaryTree (This^.Member, i) do begin
+ Pred := This; This := This^.Next end;
+if Pred <> nil then Pred^.Next := This^.Next else S := This^.Next;
+Dispose (This);
+end;
+
+procedure DisposeNaryTreeSet (var S: NaryTreeSet);
+var Old: NaryTreeSet;
+begin
+while S <> nil do begin Old := S; S := S^.Next; Dispose (Old) end;
+end;
+
+end.
+
diff --git a/web/funnelAC/answers/hi10.lis b/web/funnelAC/answers/hi10.lis
new file mode 100644
index 0000000000..fbe12da983
--- /dev/null
+++ b/web/funnelAC/answers/hi10.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi10.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/hi10.out b/web/funnelAC/answers/hi10.out
new file mode 100644
index 0000000000..a7ec61c0f6
--- /dev/null
+++ b/web/funnelAC/answers/hi10.out
@@ -0,0 +1,23 @@
+
+/* Pre: sorted(b). */
+i=1; p=1;
+while (i != N)
+ {
+ /* Invariant: sorted(b) and 1<=i<=N and */
+ /* p is len of longest run in b[1..i]. */
+ i++; if (b[i] != b[i-p]) p++;
+ }
+/* Post: sorted(b) and p is the length of the longest run in b[1..N]. */
+
+
+bool comp(p,q)
+char *p,*q;
+{
+ while (TRUE)
+ {
+ if (*p != *q ) return FALSE;
+ if (*p == '\0') return TRUE;
+ p++; q++;
+ }
+}
+
diff --git a/web/funnelAC/answers/pr01.lis b/web/funnelAC/answers/pr01.lis
new file mode 100644
index 0000000000..140aba1cb0
--- /dev/null
+++ b/web/funnelAC/answers/pr01.lis
@@ -0,0 +1,457 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 30 31 3A 20 54 65 73 74 20 74 68 65 20 69 | PR01: Test the i |
+| 6E 6C 69 6E 65 20 74 79 70 65 73 65 74 74 69 6E | nline typesettin |
+| 67 20 66 65 61 74 75 72 65 73 2E 0A 0A 31 2E 20 | g features...1. |
+| 46 69 72 73 74 20 77 65 20 74 65 73 74 20 74 68 | First we test th |
+| 65 20 6C 65 67 61 6C 20 75 73 65 20 6F 66 20 74 | e legal use of t |
+| 68 65 20 40 7B 6C 69 74 65 72 61 6C 40 7D 20 63 | he @{literal@} c |
+| 6F 6E 73 74 72 75 63 74 2E 0A 0A 32 2E 54 65 73 | onstruct...2.Tes |
+| 74 20 40 7B 40 7D 20 28 69 6C 6C 65 67 61 6C 29 | t @{@} (illegal) |
+| 2E 0A 40 41 40 3C 45 72 72 6F 72 20 52 65 63 6F | ..@A@<Error Reco |
+| 76 65 72 79 20 50 6F 69 6E 74 40 3E 0A 0A 33 2E | very Point@>..3. |
+| 20 54 65 73 74 20 74 68 65 20 63 6F 6E 73 74 72 | Test the constr |
+| 75 63 74 20 40 7B 61 63 72 6F 73 73 0A 20 20 20 | uct @{across. |
+| 6D 6F 72 65 20 74 68 61 6E 20 6F 6E 65 20 6C 69 | more than one li |
+| 6E 65 40 7D 2E 0A 0A 34 2E 20 4E 6F 77 20 77 65 | ne@}...4. Now we |
+| 20 74 65 73 74 20 74 68 65 20 63 6F 6E 73 74 72 | test the constr |
+| 75 63 74 20 77 69 74 68 20 6E 6F 6E 2D 74 65 78 | uct with non-tex |
+| 74 20 66 6F 6C 6C 6F 77 69 6E 67 20 69 74 2E 0A | t following it.. |
+| 20 20 20 40 7B 40 3C 73 6C 6F 74 68 40 3E 40 7D | @{@<sloth@>@} |
+| 0A 40 41 40 3C 45 72 72 6F 72 20 52 65 63 6F 76 | .@A@<Error Recov |
+| 65 72 79 20 50 6F 69 6E 74 40 3E 0A 20 20 20 40 | ery Point@>. @ |
+| 7B 20 20 20 20 20 40 3E 20 20 20 40 7D 0A 40 41 | { @> @}.@A |
+| 40 3C 45 72 72 6F 72 20 52 65 63 6F 76 65 72 79 | @<Error Recovery |
+| 20 50 6F 69 6E 74 40 3E 0A 0A 35 2E 20 54 65 73 | Point@>..5. Tes |
+| 74 20 74 68 65 20 6C 65 67 61 6C 20 75 73 65 20 | t the legal use |
+| 6F 66 20 74 68 65 20 40 2F 65 6D 70 68 61 73 69 | of the @/emphasi |
+| 73 40 2F 20 63 6F 6E 73 74 72 75 63 74 2E 0A 0A | s@/ construct... |
+| 36 2E 54 65 73 74 20 40 2F 40 2F 20 28 69 6C 6C | 6.Test @/@/ (ill |
+| 65 67 61 6C 29 2E 0A 40 41 40 3C 45 72 72 6F 72 | egal)..@A@<Error |
+| 20 52 65 63 6F 76 65 72 79 20 50 6F 69 6E 74 40 | Recovery Point@ |
+| 3E 0A 0A 37 2E 20 54 65 73 74 20 74 68 65 20 63 | >..7. Test the c |
+| 6F 6E 73 74 72 75 63 74 20 40 2F 61 63 72 6F 73 | onstruct @/acros |
+| 73 0A 20 20 20 6D 6F 72 65 20 74 68 61 6E 20 6F | s. more than o |
+| 6E 65 20 6C 69 6E 65 40 2F 2E 0A 0A 38 2E 20 4E | ne line@/...8. N |
+| 6F 77 20 77 65 20 74 65 73 74 20 74 68 65 20 63 | ow we test the c |
+| 6F 6E 73 74 72 75 63 74 20 77 69 74 68 20 6E 6F | onstruct with no |
+| 6E 2D 74 65 78 74 20 66 6F 6C 6C 6F 77 69 6E 67 | n-text following |
+| 20 69 74 2E 0A 20 20 20 40 2F 40 3C 73 6C 6F 74 | it.. @/@<slot |
+| 68 40 3E 40 2F 0A 40 41 40 3C 45 72 72 6F 72 20 | h@>@/.@A@<Error |
+| 52 65 63 6F 76 65 72 79 20 50 6F 69 6E 74 40 3E | Recovery Point@> |
+| 0A 20 20 20 40 2F 20 20 20 20 20 40 3C 20 20 20 | . @/ @< |
+| 40 2F 0A 0A 0A 0A | @/.... |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR01: Test the inline typesetting features.<010>
+00002 00002| <010>
+00003 00003| 1. First we test the legal use of the @{literal@} construct.<010>
+00004 00004| <010>
+00005 00005| 2.Test @{@} (illegal).<010>
+00006 00006| @A@<Error Recovery Point@><010>
+00007 00007| <010>
+00008 00008| 3. Test the construct @{across<010>
+00009 00009| more than one line@}.<010>
+00010 00010| <010>
+00011 00011| 4. Now we test the construct with non-text following it.<010>
+00012 00012| @{@<sloth@>@}<010>
+00013 00013| @A@<Error Recovery Point@><010>
+00014 00014| @{ @> @}<010>
+00015 00015| @A@<Error Recovery Point@><010>
+00016 00016| <010>
+00017 00017| 5. Test the legal use of the @/emphasis@/ construct.<010>
+00018 00018| <010>
+00019 00019| 6.Test @/@/ (illegal).<010>
+00020 00020| @A@<Error Recovery Point@><010>
+00021 00021| <010>
+00022 00022| 7. Test the construct @/across<010>
+00023 00023| more than one line@/.<010>
+00024 00024| <010>
+00025 00025| 8. Now we test the construct with non-text following it.<010>
+00026 00026| @/@<sloth@>@/<010>
+00027 00027| @A@<Error Recovery Point@><010>
+00028 00028| @/ @< @/<010>
+00029 00029| <010>
+00030 00030| <010>
+00031 00031| <010>
+00032 00032| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 73 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR01: Test the inline typesetting features.<010>
+<010>
+1. First we test the legal use of the "
+0003[39]: @{ Open defn.
+0003[41]: Text. Text scrap[Grey]="literal"
+0003[48]: @} Close defn.
+0003[50]: Text. Text scrap[Grey]=" construct.<010>
+<010>
+2.Test "
+0005[08]: @{ Open defn.
+0005[10]: @} Close defn.
+0005[12]: Text. Text scrap[Grey]=" (illegal).<010>
+"
+0006[01]: @A New section (Level 1).
+0006[03]: @< Open name.
+0006[05]: Text. Text scrap[Grey]="Error Recovery Point"
+0006[25]: @> Close name.
+0006[27]: Text. Text scrap[Grey]="<010>
+<010>
+3. Test the construct "
+0008[23]: @{ Open defn.
+0008[25]: Text. Text scrap[Grey]="across<010>
+ more than one line"
+0009[22]: @} Close defn.
+0009[24]: Text. Text scrap[Grey]=".<010>
+<010>
+4. Now we test the construct with non-text following it.<010>
+ "
+0012[04]: @{ Open defn.
+0012[06]: @< Open name.
+0012[08]: Text. Text scrap[Grey]="sloth"
+0012[13]: @> Close name.
+0012[15]: @} Close defn.
+0012[17]: Text. Text scrap[White]="<010>
+"
+0013[01]: @A New section (Level 1).
+0013[03]: @< Open name.
+0013[05]: Text. Text scrap[Grey]="Error Recovery Point"
+0013[25]: @> Close name.
+0013[27]: Text. Text scrap[White]="<010>
+ "
+0014[04]: @{ Open defn.
+0014[06]: Text. Text scrap[White]=" "
+0014[11]: @> Close name.
+0014[13]: Text. Text scrap[White]=" "
+0014[16]: @} Close defn.
+0014[18]: Text. Text scrap[White]="<010>
+"
+0015[01]: @A New section (Level 1).
+0015[03]: @< Open name.
+0015[05]: Text. Text scrap[Grey]="Error Recovery Point"
+0015[25]: @> Close name.
+0015[27]: Text. Text scrap[Grey]="<010>
+<010>
+5. Test the legal use of the "
+0017[30]: @/ Emphasise.
+0017[32]: Text. Text scrap[Grey]="emphasis"
+0017[40]: @/ Emphasise.
+0017[42]: Text. Text scrap[Grey]=" construct.<010>
+<010>
+6.Test "
+0019[08]: @/ Emphasise.
+0019[10]: @/ Emphasise.
+0019[12]: Text. Text scrap[Grey]=" (illegal).<010>
+"
+0020[01]: @A New section (Level 1).
+0020[03]: @< Open name.
+0020[05]: Text. Text scrap[Grey]="Error Recovery Point"
+0020[25]: @> Close name.
+0020[27]: Text. Text scrap[Grey]="<010>
+<010>
+7. Test the construct "
+0022[23]: @/ Emphasise.
+0022[25]: Text. Text scrap[Grey]="across<010>
+ more than one line"
+0023[22]: @/ Emphasise.
+0023[24]: Text. Text scrap[Grey]=".<010>
+<010>
+8. Now we test the construct with non-text following it.<010>
+ "
+0026[04]: @/ Emphasise.
+0026[06]: @< Open name.
+0026[08]: Text. Text scrap[Grey]="sloth"
+0026[13]: @> Close name.
+0026[15]: @/ Emphasise.
+0026[17]: Text. Text scrap[White]="<010>
+"
+0027[01]: @A New section (Level 1).
+0027[03]: @< Open name.
+0027[05]: Text. Text scrap[Grey]="Error Recovery Point"
+0027[25]: @> Close name.
+0027[27]: Text. Text scrap[White]="<010>
+ "
+0028[04]: @/ Emphasise.
+0028[06]: Text. Text scrap[White]=" "
+0028[11]: @< Open name.
+0028[13]: Text. Text scrap[White]=" "
+0028[16]: @/ Emphasise.
+0028[18]: Text. Text scrap[White]="<010>
+<010>
+<010>
+<010>
+"
+0032[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR01: Test the inline typesetting features.<010>
+<010>
+1. First we test the legal use of the "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open literal.
+
+TEXT COMPONENT: Pos(L,C)=(3,41).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="literal"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Close literal.
+
+TEXT COMPONENT: Pos(L,C)=(3,50).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]=" construct.<010>
+<010>
+2.Test "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open literal.
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1", Section name="Error Recovery Point".
+
+TEXT COMPONENT: Pos(L,C)=(6,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+3. Test the construct "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open literal.
+
+TEXT COMPONENT: Pos(L,C)=(8,25).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="across<010>
+ more than one line"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Close literal.
+
+TEXT COMPONENT: Pos(L,C)=(9,24).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]=".<010>
+<010>
+4. Now we test the construct with non-text following it.<010>
+ "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open literal.
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="Error Recovery Point".
+
+TEXT COMPONENT: Pos(L,C)=(13,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+ "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open literal.
+
+TEXT COMPONENT: Pos(L,C)=(14,6).
+
+-- Start of Text Scrap List --
+Text scrap[White]=" "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "3", Section name="Error Recovery Point".
+
+TEXT COMPONENT: Pos(L,C)=(15,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+5. Test the legal use of the "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open emphasise.
+
+TEXT COMPONENT: Pos(L,C)=(17,32).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="emphasis"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Close emphasise.
+
+TEXT COMPONENT: Pos(L,C)=(17,42).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]=" construct.<010>
+<010>
+6.Test "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open emphasise.
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4", Section name="Error Recovery Point".
+
+TEXT COMPONENT: Pos(L,C)=(20,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+7. Test the construct "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open emphasise.
+
+TEXT COMPONENT: Pos(L,C)=(22,25).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="across<010>
+ more than one line"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Close emphasise.
+
+TEXT COMPONENT: Pos(L,C)=(23,24).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]=".<010>
+<010>
+8. Now we test the construct with non-text following it.<010>
+ "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open emphasise.
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "5", Section name="Error Recovery Point".
+
+TEXT COMPONENT: Pos(L,C)=(27,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+ "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open emphasise.
+
+TEXT COMPONENT: Pos(L,C)=(28,6).
+
+-- Start of Text Scrap List --
+Text scrap[White]=" "
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| PR01: Test the inline typesetting features.
+ 2 2|
+ 3 3| 1. First we test the legal use of the @{literal@} construct.
+ 4 4|
+ 5 5| 2.Test @{@} (illegal).
+ Error|..........^Text expected after open literal token "@{".
+ |..........^Sorry, empty literal strings are not allowed.
+ |..........^Skipping after error to the next major construct...
+ 6 6| @A@<Error Recovery Point@>
+ |.^...skipped to here after the error.
+ 7 7|
+ 8 8| 3. Test the construct @{across
+ 9 9| more than one line@}.
+ 10 10|
+ 11 11| 4. Now we test the construct with non-text following it.
+ 12 12| @{@<sloth@>@}
+ Error|......^Text expected after open literal token "@{".
+ |......^Skipping after error to the next major construct...
+ 13 13| @A@<Error Recovery Point@>
+ |.^...skipped to here after the error.
+ 14 14| @{ @> @}
+ Error|...........^Expecting '@}'.
+ |...........^Skipping after error to the next major construct...
+ 15 15| @A@<Error Recovery Point@>
+ |.^...skipped to here after the error.
+ 16 16|
+ 17 17| 5. Test the legal use of the @/emphasis@/ construct.
+ 18 18|
+ 19 19| 6.Test @/@/ (illegal).
+ Error|..........^Text expected after open emphasise token "@/".
+ |..........^Sorry, empty emphasised strings are not allowed.
+ |..........^Skipping after error to the next major construct...
+ 20 20| @A@<Error Recovery Point@>
+ |.^...skipped to here after the error.
+ 21 21|
+ 22 22| 7. Test the construct @/across
+ 23 23| more than one line@/.
+ 24 24|
+ 25 25| 8. Now we test the construct with non-text following it.
+ 26 26| @/@<sloth@>@/
+ Error|......^Text expected after open emphasise token "@/".
+ |......^Skipping after error to the next major construct...
+ 27 27| @A@<Error Recovery Point@>
+ |.^...skipped to here after the error.
+ 28 28| @/ @< @/
+ Error|...........^Expecting '@/'.
+ |...........^Skipping after error to the next major construct...
+ 29 29|
+ 30 30|
+ 31 31|
+ | <End-Of-File>
+ |.^...skipped to here after the error.
+------------+-------------------------------------------------------------------
+
+There were 6 Errors.
diff --git a/web/funnelAC/answers/pr02.lis b/web/funnelAC/answers/pr02.lis
new file mode 100644
index 0000000000..62f932c0a9
--- /dev/null
+++ b/web/funnelAC/answers/pr02.lis
@@ -0,0 +1,163 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 30 32 3A 20 54 65 73 74 20 74 68 65 20 70 | PR02: Test the p |
+| 61 72 73 69 6E 67 20 6F 66 20 74 79 70 65 73 65 | arsing of typese |
+| 74 74 65 72 20 64 69 72 65 63 74 69 76 65 73 2E | tter directives. |
+| 0A 0A 31 2E 20 54 65 73 74 20 70 61 72 73 69 6E | ..1. Test parsin |
+| 67 20 6F 66 20 6E 65 77 20 70 61 67 65 20 64 69 | g of new page di |
+| 72 65 63 74 69 76 65 2E 0A 40 74 20 6E 65 77 5F | rective..@t new_ |
+| 70 61 67 65 0A 0A 32 2E 20 54 65 73 74 20 70 61 | page..2. Test pa |
+| 72 73 69 6E 67 20 6F 66 20 74 61 62 6C 65 20 6F | rsing of table o |
+| 66 20 63 6F 6E 74 65 6E 74 73 20 64 69 72 65 63 | f contents direc |
+| 74 69 76 65 2E 0A 40 74 20 74 61 62 6C 65 5F 6F | tive..@t table_o |
+| 66 5F 63 6F 6E 74 65 6E 74 73 0A 0A 33 2E 20 54 | f_contents..3. T |
+| 65 73 74 20 70 61 72 73 69 6E 67 20 6F 66 20 76 | est parsing of v |
+| 73 6B 69 70 20 64 69 72 65 63 74 69 76 65 2E 0A | skip directive.. |
+| 40 74 20 76 73 6B 69 70 20 33 32 20 6D 6D 0A 0A | @t vskip 32 mm.. |
+| 34 2E 20 54 65 73 74 20 70 61 72 73 69 6E 67 20 | 4. Test parsing |
+| 6F 66 20 74 69 74 6C 65 20 64 69 72 65 63 74 69 | of title directi |
+| 76 65 2E 0A 40 74 20 74 69 74 6C 65 20 74 69 74 | ve..@t title tit |
+| 6C 65 66 6F 6E 74 20 6C 65 66 74 20 22 53 6C 6F | lefont left "Slo |
+| 74 68 22 0A 0A | th".. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR02: Test the parsing of typesetter directives.<010>
+00002 00002| <010>
+00003 00003| 1. Test parsing of new page directive.<010>
+00004 00004| @t new_page<010>
+00005 00005| <010>
+00006 00006| 2. Test parsing of table of contents directive.<010>
+00007 00007| @t table_of_contents<010>
+00008 00008| <010>
+00009 00009| 3. Test parsing of vskip directive.<010>
+00010 00010| @t vskip 32 mm<010>
+00011 00011| <010>
+00012 00012| 4. Test parsing of title directive.<010>
+00013 00013| @t title titlefont left "Sloth"<010>
+00014 00014| <010>
+00015 00015| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 10 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR02: Test the parsing of typesetter directives.<010>
+<010>
+1. Test parsing of new page directive.<010>
+"
+0004[01]: @t.. Newpage.
+0005[01]: Text. Text scrap[Grey]="<010>
+2. Test parsing of table of contents directive.<010>
+"
+0007[01]: @t.. TOC.
+0008[01]: Text. Text scrap[Grey]="<010>
+3. Test parsing of vskip directive.<010>
+"
+0010[01]: @t.. Vertical skip. Vertical space skipped=32mm.
+0011[01]: Text. Text scrap[Grey]="<010>
+4. Test parsing of title directive.<010>
+"
+0013[01]: @t.. Title. Font=Title, Alignment=Left. Title text follows:
+Text scrap[Grey]="Sloth"
+0014[01]: Text. Text scrap[White]="<010>
+"
+0015[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR02: Test the parsing of typesetter directives.<010>
+<010>
+1. Test parsing of new page directive.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: New page.
+
+TEXT COMPONENT: Pos(L,C)=(5,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+2. Test parsing of table of contents directive.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Table of contents.
+
+TEXT COMPONENT: Pos(L,C)=(8,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+3. Test parsing of vskip directive.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Vertical skip by 32 mm.
+
+TEXT COMPONENT: Pos(L,C)=(11,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+4. Test parsing of title directive.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Font=Title, Alignment=Left. Title text follows:
+Text scrap[Grey]="Sloth"
+
+TEXT COMPONENT: Pos(L,C)=(14,1).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+E: No macros defined.
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+There were 2 Errors.
diff --git a/web/funnelAC/answers/pr03.lis b/web/funnelAC/answers/pr03.lis
new file mode 100644
index 0000000000..437af4be44
--- /dev/null
+++ b/web/funnelAC/answers/pr03.lis
@@ -0,0 +1,469 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 30 33 3A 20 54 65 73 74 20 74 68 65 20 70 | PR03: Test the p |
+| 61 72 73 69 6E 67 20 61 6E 64 20 73 65 6D 61 6E | arsing and seman |
+| 74 69 63 73 20 6F 66 20 73 65 63 74 69 6F 6E 73 | tics of sections |
+| 2E 0A 0A 34 2E 20 54 65 73 74 20 66 69 72 73 74 | ...4. Test first |
+| 20 73 65 63 74 69 6F 6E 20 6F 66 20 64 6F 63 75 | section of docu |
+| 6D 65 6E 74 20 69 73 20 6E 6F 74 20 3C 73 70 65 | ment is not <spe |
+| 63 69 61 6C 3E 41 2E 0A 40 42 40 3C 54 68 69 73 | cial>A..@B@<This |
+| 20 73 65 63 74 69 6F 6E 20 69 73 20 6F 75 74 20 | section is out |
+| 6F 66 20 6F 72 64 65 72 20 28 61 6E 64 20 73 6F | of order (and so |
+| 20 69 73 20 74 68 69 73 20 74 65 73 74 21 29 40 | is this test!)@ |
+| 3E 0A 0A 31 2E 20 54 65 73 74 20 73 65 63 74 69 | >..1. Test secti |
+| 6F 6E 20 77 69 74 68 20 6E 6F 20 6E 61 6D 65 2E | on with no name. |
+| 0A 40 41 20 54 68 69 73 20 73 65 63 74 69 6F 6E | .@A This section |
+| 20 68 61 73 20 6E 6F 20 6E 61 6D 65 2E 0A 40 24 | has no name..@$ |
+| 40 3C 54 68 65 20 73 65 63 74 69 6F 6E 20 6E 61 | @<The section na |
+| 6D 65 20 69 6E 68 65 72 69 74 73 20 74 68 65 20 | me inherits the |
+| 6E 61 6D 65 20 6F 66 20 74 68 69 73 20 6D 61 63 | name of this mac |
+| 72 6F 40 3E 40 7B 57 61 6C 72 75 73 40 7D 0A 0A | ro@>@{Walrus@}.. |
+| 32 2E 20 54 65 73 74 20 73 65 63 74 69 6F 6E 20 | 2. Test section |
+| 77 69 74 68 20 61 20 6E 61 6D 65 0A 40 41 40 3C | with a name.@A@< |
+| 54 68 69 73 20 73 65 63 74 69 6F 6E 20 68 61 73 | This section has |
+| 20 6E 6F 20 6E 61 6D 65 2E 40 3E 0A 0A 33 2E 20 | no name.@>..3. |
+| 54 65 73 74 20 74 68 65 20 65 6E 74 69 72 65 20 | Test the entire |
+| 68 69 65 72 61 72 63 68 79 2E 0A 40 41 40 3C 4F | hierarchy..@A@<O |
+| 6E 65 40 3E 0A 40 42 40 3C 54 77 6F 40 3E 0A 40 | ne@>.@B@<Two@>.@ |
+| 43 40 3C 54 68 72 65 65 40 3E 0A 40 44 40 3C 46 | C@<Three@>.@D@<F |
+| 6F 75 72 40 3E 0A 40 45 40 3C 46 69 76 65 40 3E | our@>.@E@<Five@> |
+| 0A 0A 35 2E 20 54 65 73 74 20 64 65 74 65 63 74 | ..5. Test detect |
+| 69 6F 6E 20 6F 66 20 64 69 73 63 6F 6E 74 69 6E | ion of discontin |
+| 75 69 74 79 20 69 6E 20 6C 65 76 65 6C 73 2E 0A | uity in levels.. |
+| 40 41 40 3C 4F 6E 65 40 3E 0A 40 43 40 3C 54 68 | @A@<One@>.@C@<Th |
+| 72 65 65 40 3E 0A 40 45 40 3C 46 69 76 65 40 3E | ree@>.@E@<Five@> |
+| 0A 0A 40 41 40 3C 4F 6E 65 40 3E 0A 40 42 40 3C | ..@A@<One@>.@B@< |
+| 54 68 72 65 65 40 3E 0A 40 44 40 3C 46 69 76 65 | Three@>.@D@<Five |
+| 40 3E 0A | @>. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR03: Test the parsing and semantics of sections.<010>
+00002 00002| <010>
+00003 00003| 4. Test first section of document is not <special>A.<010>
+00004 00004| @B@<This section is out of order (and so is this test!)@><010>
+00005 00005| <010>
+00006 00006| 1. Test section with no name.<010>
+00007 00007| @A This section has no name.<010>
+00008 00008| @$@<The section name inherits the name of this macro@>@{Walrus@}<010>
+00009 00009| <010>
+00010 00010| 2. Test section with a name<010>
+00011 00011| @A@<This section has no name.@><010>
+00012 00012| <010>
+00013 00013| 3. Test the entire hierarchy.<010>
+00014 00014| @A@<One@><010>
+00015 00015| @B@<Two@><010>
+00016 00016| @C@<Three@><010>
+00017 00017| @D@<Four@><010>
+00018 00018| @E@<Five@><010>
+00019 00019| <010>
+00020 00020| 5. Test detection of discontinuity in levels.<010>
+00021 00021| @A@<One@><010>
+00022 00022| @C@<Three@><010>
+00023 00023| @E@<Five@><010>
+00024 00024| <010>
+00025 00025| @A@<One@><010>
+00026 00026| @B@<Three@><010>
+00027 00027| @D@<Five@><010>
+00028 00028| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 77 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR03: Test the parsing and semantics of sections.<010>
+<010>
+4. Test first section of document is not <special>A.<010>
+"
+0004[01]: @B New section (Level 2).
+0004[03]: @< Open name.
+0004[05]: Text. Text scrap[Grey]="This section is out of order (and so is this test!)"
+0004[56]: @> Close name.
+0004[58]: Text. Text scrap[Grey]="<010>
+<010>
+1. Test section with no name.<010>
+"
+0007[01]: @A New section (Level 1).
+0007[03]: Text. Text scrap[Grey]=" This section has no name.<010>
+"
+0008[01]: @$ Macro defn.
+0008[03]: @< Open name.
+0008[05]: Text. Text scrap[Grey]="The section name inherits the name of this macro"
+0008[53]: @> Close name.
+0008[55]: @{ Open defn.
+0008[57]: Text. Text scrap[Grey]="Walrus"
+0008[63]: @} Close defn.
+0008[65]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test section with a name<010>
+"
+0011[01]: @A New section (Level 1).
+0011[03]: @< Open name.
+0011[05]: Text. Text scrap[Grey]="This section has no name."
+0011[30]: @> Close name.
+0011[32]: Text. Text scrap[Grey]="<010>
+<010>
+3. Test the entire hierarchy.<010>
+"
+0014[01]: @A New section (Level 1).
+0014[03]: @< Open name.
+0014[05]: Text. Text scrap[Grey]="One"
+0014[08]: @> Close name.
+0014[10]: Text. Text scrap[White]="<010>
+"
+0015[01]: @B New section (Level 2).
+0015[03]: @< Open name.
+0015[05]: Text. Text scrap[Grey]="Two"
+0015[08]: @> Close name.
+0015[10]: Text. Text scrap[White]="<010>
+"
+0016[01]: @C New section (Level 3).
+0016[03]: @< Open name.
+0016[05]: Text. Text scrap[Grey]="Three"
+0016[10]: @> Close name.
+0016[12]: Text. Text scrap[White]="<010>
+"
+0017[01]: @D New section (Level 4).
+0017[03]: @< Open name.
+0017[05]: Text. Text scrap[Grey]="Four"
+0017[09]: @> Close name.
+0017[11]: Text. Text scrap[White]="<010>
+"
+0018[01]: @E New section (Level 5).
+0018[03]: @< Open name.
+0018[05]: Text. Text scrap[Grey]="Five"
+0018[09]: @> Close name.
+0018[11]: Text. Text scrap[Grey]="<010>
+<010>
+5. Test detection of discontinuity in levels.<010>
+"
+0021[01]: @A New section (Level 1).
+0021[03]: @< Open name.
+0021[05]: Text. Text scrap[Grey]="One"
+0021[08]: @> Close name.
+0021[10]: Text. Text scrap[White]="<010>
+"
+0022[01]: @C New section (Level 3).
+0022[03]: @< Open name.
+0022[05]: Text. Text scrap[Grey]="Three"
+0022[10]: @> Close name.
+0022[12]: Text. Text scrap[White]="<010>
+"
+0023[01]: @E New section (Level 5).
+0023[03]: @< Open name.
+0023[05]: Text. Text scrap[Grey]="Five"
+0023[09]: @> Close name.
+0023[11]: Text. Text scrap[White]="<010>
+<010>
+"
+0025[01]: @A New section (Level 1).
+0025[03]: @< Open name.
+0025[05]: Text. Text scrap[Grey]="One"
+0025[08]: @> Close name.
+0025[10]: Text. Text scrap[White]="<010>
+"
+0026[01]: @B New section (Level 2).
+0026[03]: @< Open name.
+0026[05]: Text. Text scrap[Grey]="Three"
+0026[10]: @> Close name.
+0026[12]: Text. Text scrap[White]="<010>
+"
+0027[01]: @D New section (Level 4).
+0027[03]: @< Open name.
+0027[05]: Text. Text scrap[Grey]="Five"
+0027[09]: @> Close name.
+0027[11]: Text. Text scrap[White]="<010>
+"
+0028[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "The section name inherits the name of this macro"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=1, Pos(L,C)=(8,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR03: Test the parsing and semantics of sections.<010>
+<010>
+4. Test first section of document is not <special>A.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1.2", Section name="This section is out of order (and so is this test!)".
+
+TEXT COMPONENT: Pos(L,C)=(4,58).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+1. Test section with no name.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="The section name inherits the name of this macro".
+
+TEXT COMPONENT: Pos(L,C)=(7,3).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]=" This section has no name.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(8,1).
+Part 1 of macro @<The section name inherits the name of this macro@>.
+
+TEXT COMPONENT: Pos(L,C)=(8,65).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+2. Test section with a name<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "3", Section name="This section has no name.".
+
+TEXT COMPONENT: Pos(L,C)=(11,32).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+3. Test the entire hierarchy.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4", Section name="One".
+
+TEXT COMPONENT: Pos(L,C)=(14,10).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4.1", Section name="Two".
+
+TEXT COMPONENT: Pos(L,C)=(15,10).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4.1.1", Section name="Three".
+
+TEXT COMPONENT: Pos(L,C)=(16,12).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4.1.1.1", Section name="Four".
+
+TEXT COMPONENT: Pos(L,C)=(17,11).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4.1.1.1.1", Section name="Five".
+
+TEXT COMPONENT: Pos(L,C)=(18,11).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+5. Test detection of discontinuity in levels.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "5", Section name="One".
+
+TEXT COMPONENT: Pos(L,C)=(21,10).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1.1.2", Section name="Three".
+
+TEXT COMPONENT: Pos(L,C)=(22,12).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1.1.1.1.2", Section name="Five".
+
+TEXT COMPONENT: Pos(L,C)=(23,11).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="One".
+
+TEXT COMPONENT: Pos(L,C)=(25,10).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2.1", Section name="Three".
+
+TEXT COMPONENT: Pos(L,C)=(26,12).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1.1.1.2", Section name="Five".
+
+TEXT COMPONENT: Pos(L,C)=(27,11).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| PR03: Test the parsing and semantics of sections.
+ 2 2|
+ 3 3| 4. Test first section of document is not <special>A.
+ 4 4| @B@<This section is out of order (and so is this test!)@>
+ Error|.^The first section in a document must be an @A section.
+ 5 5|
+ 6 6| 1. Test section with no name.
+ 7 7| @A This section has no name.
+ 8 8| @$@<The section name inherits the name of this macro@>@{Walrus@}
+ 9 9|
+ 10 10| 2. Test section with a name
+ 11 11| @A@<This section has no name.@>
+ 12 12|
+ 13 13| 3. Test the entire hierarchy.
+ 14 14| @A@<One@>
+ 15 15| @B@<Two@>
+ 16 16| @C@<Three@>
+ 17 17| @D@<Four@>
+ 18 18| @E@<Five@>
+ 19 19|
+ 20 20| 5. Test detection of discontinuity in levels.
+ 21 21| @A@<One@>
+ |.^The next section (at line 22) is too deep.
+ 22 22| @C@<Three@>
+ Error|.^This section is more than one level deeper than the last
+ |.^section (at line 21). Example: @B followed by @D is not allowed.
+ |.^The next section (at line 23) is too deep.
+ 23 23| @E@<Five@>
+ Error|.^This section is more than one level deeper than the last
+ |.^section (at line 22). Example: @B followed by @D is not allowed.
+ 24 24|
+ 25 25| @A@<One@>
+ 26 26| @B@<Three@>
+ |.^The next section (at line 27) is too deep.
+ 27 27| @D@<Five@>
+ Error|.^This section is more than one level deeper than the last
+ |.^section (at line 26). Example: @B followed by @D is not allowed.
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 4 Errors.
diff --git a/web/funnelAC/answers/pr04.lis b/web/funnelAC/answers/pr04.lis
new file mode 100644
index 0000000000..24419c1b15
--- /dev/null
+++ b/web/funnelAC/answers/pr04.lis
@@ -0,0 +1,656 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 30 34 3A 20 54 65 73 74 20 74 68 65 20 64 | PR04: Test the d |
+| 65 66 69 6E 69 74 69 6F 6E 20 6F 66 20 6F 72 64 | efinition of ord |
+| 69 6E 61 72 79 20 6D 61 63 72 6F 73 2E 0A 0A 31 | inary macros...1 |
+| 2E 20 54 65 73 74 20 61 6E 20 6F 72 64 69 6E 61 | . Test an ordina |
+| 72 79 20 6D 61 63 72 6F 20 64 65 66 69 6E 69 74 | ry macro definit |
+| 69 6F 6E 2E 0A 40 24 40 3C 4F 72 64 69 6E 61 72 | ion..@$@<Ordinar |
+| 79 40 3E 40 7B 54 68 65 20 74 65 78 74 20 6F 66 | y@>@{The text of |
+| 20 6F 72 64 69 6E 61 72 79 40 7D 0A 0A 32 2E 20 | ordinary@}..2. |
+| 54 65 73 74 20 61 6E 20 6F 72 64 69 6E 61 72 79 | Test an ordinary |
+| 20 64 65 66 69 6E 69 74 69 6F 6E 20 75 73 69 6E | definition usin |
+| 67 20 61 20 71 75 69 63 6B 6E 61 6D 65 2E 0A 40 | g a quickname..@ |
+| 24 40 23 7C 40 7B 54 68 65 20 74 65 78 74 20 6F | $@#|@{The text o |
+| 66 20 6F 72 64 69 6E 61 72 79 40 7D 0A 0A 33 2E | f ordinary@}..3. |
+| 20 54 65 73 74 20 61 20 6E 61 6D 65 20 74 68 61 | Test a name tha |
+| 74 20 69 6E 63 6C 75 64 65 73 20 45 4F 4C 2E 0A | t includes EOL.. |
+| 40 24 40 3C 54 68 69 73 20 6E 61 6D 65 20 69 73 | @$@<This name is |
+| 20 69 6C 6C 65 67 61 6C 20 62 65 63 61 75 73 65 | illegal because |
+| 0A 69 74 20 63 72 6F 73 73 65 73 20 61 20 6C 69 | .it crosses a li |
+| 6F 6E 40 3E 40 7B 41 6E 64 20 70 65 6F 70 6C 65 | on@>@{And people |
+| 20 77 68 6F 20 63 72 6F 73 73 20 6C 69 6F 6E 73 | who cross lions |
+| 20 74 65 6E 64 20 74 6F 20 67 65 74 20 65 61 74 | tend to get eat |
+| 65 6E 2E 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 | en.@}.@A@<Error |
+| 52 65 63 6F 76 65 72 79 20 50 6F 69 6E 74 40 3E | Recovery Point@> |
+| 0A 0A 34 2E 20 54 65 73 74 20 74 68 65 20 6D 69 | ..4. Test the mi |
+| 6E 69 6D 75 6D 20 6C 65 6E 67 74 68 20 6E 61 6D | nimum length nam |
+| 65 20 28 74 68 65 20 65 6D 70 74 79 20 6E 61 6D | e (the empty nam |
+| 65 29 2E 0A 40 24 40 3C 40 3E 40 7B 54 68 65 20 | e)..@$@<@>@{The |
+| 65 6D 70 74 79 20 6D 61 63 72 6F 20 6E 61 6D 65 | empty macro name |
+| 20 69 73 20 71 75 69 74 65 20 6C 65 67 61 6C 20 | is quite legal |
+| 69 6E 20 46 75 6E 6E 65 6C 57 65 62 2E 40 7D 0A | in FunnelWeb.@}. |
+| 0A 35 2E 20 54 65 73 74 20 61 20 6E 61 6D 65 20 | .5. Test a name |
+| 61 74 20 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E | at the maximum n |
+| 61 6D 65 20 6C 65 6E 67 74 68 20 6C 69 6D 69 74 | ame length limit |
+| 20 28 38 30 29 2E 0A 4F 4E 6C 79 20 74 68 65 20 | (80)..ONly the |
+| 73 65 63 6F 6E 64 20 6F 66 20 74 68 65 20 74 77 | second of the tw |
+| 6F 20 6D 61 63 72 6F 73 20 73 68 6F 75 6C 64 20 | o macros should |
+| 67 65 6E 65 72 61 74 65 20 61 6E 20 65 72 72 6F | generate an erro |
+| 72 2E 0A 40 70 20 6D 61 78 69 6D 75 6D 5F 69 6E | r..@p maximum_in |
+| 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 74 68 20 | put_line_length |
+| 3D 20 31 30 30 0A 40 24 40 3C 31 32 33 34 35 36 | = 100.@$@<123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 40 3E 40 7B 40 7D | 1234567890@>@{@} |
+| 0A 40 24 40 3C 31 32 33 34 35 36 37 38 39 30 31 | .@$@<12345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 40 3E 40 7B 40 7D 0A 40 41 40 | 678901@>@{@}.@A@ |
+| 3C 45 72 72 6F 72 20 52 65 63 6F 76 65 72 79 20 | <Error Recovery |
+| 50 6F 69 6E 74 40 3E 0A 0A 36 2E 20 54 65 73 74 | Point@>..6. Test |
+| 20 6E 61 6D 65 73 20 77 69 74 68 20 61 6C 6C 20 | names with all |
+| 6C 65 67 61 6C 20 63 68 61 72 61 63 74 65 72 73 | legal characters |
+| 2E 20 54 68 65 72 65 20 73 68 6F 75 6C 64 20 62 | . There should b |
+| 65 20 6E 6F 20 65 72 72 6F 72 73 2E 0A 40 24 40 | e no errors..@$@ |
+| 3C 20 21 22 23 24 25 27 28 29 2A 2B 2C 2D 2E 2F | < !"#$%'()*+,-./ |
+| 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F | 0123456789:;<=>? |
+| 40 3E 40 7B 40 7D 0A 40 24 40 3C 41 42 43 44 45 | @>@{@}.@$@<ABCDE |
+| 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 | FGHIJKLMNOPQRSTU |
+| 56 57 58 59 5A 5B 5C 5D 5E 5F 60 40 3E 40 7B 40 | VWXYZ[\]^_`@>@{@ |
+| 7D 0A 40 24 40 3C 61 62 63 64 65 66 67 68 69 6A | }.@$@<abcdefghij |
+| 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A | klmnopqrstuvwxyz |
+| 7B 7C 7D 7E 40 3E 40 7B 40 7D 0A 0A 37 2E 20 54 | {|}~@>@{@}..7. T |
+| 65 73 74 20 61 20 6E 61 6D 65 20 74 68 61 74 20 | est a name that |
+| 68 61 73 20 69 6E 73 65 72 74 65 64 20 74 65 78 | has inserted tex |
+| 74 20 73 65 71 75 65 6E 63 65 73 2E 0A 0A 40 24 | t sequences...@$ |
+| 40 3C 40 5E 44 28 30 36 35 29 40 40 40 3E 3D 3D | @<@^D(065)@@@>== |
+| 40 7B 40 7D 0A 0A 0A | @{@}... |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR04: Test the definition of ordinary macros.<010>
+00002 00002| <010>
+00003 00003| 1. Test an ordinary macro definition.<010>
+00004 00004| @$@<Ordinary@>@{The text of ordinary@}<010>
+00005 00005| <010>
+00006 00006| 2. Test an ordinary definition using a quickname.<010>
+00007 00007| @$@#|@{The text of ordinary@}<010>
+00008 00008| <010>
+00009 00009| 3. Test a name that includes EOL.<010>
+00010 00010| @$@<This name is illegal because<010>
+00011 00011| it crosses a lion@>@{And people who cross lions tend to get eaten.@}<010>
+00012 00012| @A@<Error Recovery Point@><010>
+00013 00013| <010>
+00014 00014| 4. Test the minimum length name (the empty name).<010>
+00015 00015| @$@<@>@{The empty macro name is quite legal in FunnelWeb.@}<010>
+00016 00016| <010>
+00017 00017| 5. Test a name at the maximum name length limit (80).<010>
+00018 00018| ONly the second of the two macros should generate an error.<010>
+00019 00019| @p maximum_input_line_length = 100<010>
+00020 00020| @$@<12345678901234567890123456789012345678901234567890123456789012345678901234567890@>@{@}<010>
+00021 00021| @$@<123456789012345678901234567890123456789012345678901234567890123456789012345678901@>@{@}<010>
+00022 00022| @A@<Error Recovery Point@><010>
+00023 00023| <010>
+00024 00024| 6. Test names with all legal characters. There should be no errors.<010>
+00025 00025| @$@< !"#$%'()*+,-./0123456789:;<=>?@>@{@}<010>
+00026 00026| @$@<ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`@>@{@}<010>
+00027 00027| @$@<abcdefghijklmnopqrstuvwxyz{|}~@>@{@}<010>
+00028 00028| <010>
+00029 00029| 7. Test a name that has inserted text sequences.<010>
+00030 00030| <010>
+00031 00031| @$@<@^D(065)@@@>==@{@}<010>
+00032 00032| <010>
+00033 00033| <010>
+00034 00034| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 85 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR04: Test the definition of ordinary macros.<010>
+<010>
+1. Test an ordinary macro definition.<010>
+"
+0004[01]: @$ Macro defn.
+0004[03]: @< Open name.
+0004[05]: Text. Text scrap[Grey]="Ordinary"
+0004[13]: @> Close name.
+0004[15]: @{ Open defn.
+0004[17]: Text. Text scrap[Grey]="The text of ordinary"
+0004[37]: @} Close defn.
+0004[39]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test an ordinary definition using a quickname.<010>
+"
+0007[01]: @$ Macro defn.
+0007[03]: @# Name. Character='|'.
+0007[06]: @{ Open defn.
+0007[08]: Text. Text scrap[Grey]="The text of ordinary"
+0007[28]: @} Close defn.
+0007[30]: Text. Text scrap[Grey]="<010>
+<010>
+3. Test a name that includes EOL.<010>
+"
+0010[01]: @$ Macro defn.
+0010[03]: @< Open name.
+0010[05]: Text. Text scrap[Grey]="This name is illegal because<010>
+it crosses a lion"
+0011[18]: @> Close name.
+0011[20]: @{ Open defn.
+0011[22]: Text. Text scrap[Grey]="And people who cross lions tend to get eaten."
+0011[67]: @} Close defn.
+0011[69]: Text. Text scrap[White]="<010>
+"
+0012[01]: @A New section (Level 1).
+0012[03]: @< Open name.
+0012[05]: Text. Text scrap[Grey]="Error Recovery Point"
+0012[25]: @> Close name.
+0012[27]: Text. Text scrap[Grey]="<010>
+<010>
+4. Test the minimum length name (the empty name).<010>
+"
+0015[01]: @$ Macro defn.
+0015[03]: @< Open name.
+0015[05]: @> Close name.
+0015[07]: @{ Open defn.
+0015[09]: Text. Text scrap[Grey]="The empty macro name is quite legal in FunnelWeb."
+0015[58]: @} Close defn.
+0015[60]: Text. Text scrap[Grey]="<010>
+<010>
+5. Test a name at the maximum name length limit (80).<010>
+ONly the second of the two macros should generate an error.<010>
+"
+0020[01]: @$ Macro defn.
+0020[03]: @< Open name.
+0020[05]: Text. Text scrap[Grey]="12345678901234567890123456789012345678901234567890123456789012345678901234567890"
+0020[85]: @> Close name.
+0020[87]: @{ Open defn.
+0020[89]: @} Close defn.
+0020[91]: Text. Text scrap[White]="<010>
+"
+0021[01]: @$ Macro defn.
+0021[03]: @< Open name.
+0021[05]: Text. Text scrap[Grey]="123456789012345678901234567890123456789012345678901234567890123456789012345678901"
+0021[86]: @> Close name.
+0021[88]: @{ Open defn.
+0021[90]: @} Close defn.
+0021[92]: Text. Text scrap[White]="<010>
+"
+0022[01]: @A New section (Level 1).
+0022[03]: @< Open name.
+0022[05]: Text. Text scrap[Grey]="Error Recovery Point"
+0022[25]: @> Close name.
+0022[27]: Text. Text scrap[Grey]="<010>
+<010>
+6. Test names with all legal characters. There should be no errors.<010>
+"
+0025[01]: @$ Macro defn.
+0025[03]: @< Open name.
+0025[05]: Text. Text scrap[Grey]=" !"#$%'()*+,-./0123456789:;<=>?"
+0025[36]: @> Close name.
+0025[38]: @{ Open defn.
+0025[40]: @} Close defn.
+0025[42]: Text. Text scrap[White]="<010>
+"
+0026[01]: @$ Macro defn.
+0026[03]: @< Open name.
+0026[05]: Text. Text scrap[Grey]="ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`"
+0026[37]: @> Close name.
+0026[39]: @{ Open defn.
+0026[41]: @} Close defn.
+0026[43]: Text. Text scrap[White]="<010>
+"
+0027[01]: @$ Macro defn.
+0027[03]: @< Open name.
+0027[05]: Text. Text scrap[Grey]="abcdefghijklmnopqrstuvwxyz{|}~"
+0027[35]: @> Close name.
+0027[37]: @{ Open defn.
+0027[39]: @} Close defn.
+0027[41]: Text. Text scrap[Grey]="<010>
+<010>
+7. Test a name that has inserted text sequences.<010>
+<010>
+"
+0031[01]: @$ Macro defn.
+0031[03]: @< Open name.
+0031[05]: Text. Text scrap[Grey]="A"
+0031[13]: Text. Text scrap[Grey]="@"
+0031[15]: @> Close name.
+0031[17]: Text. Text scrap[Grey]="=="
+0031[19]: @{ Open defn.
+0031[21]: @} Close defn.
+0031[23]: Text. Text scrap[White]="<010>
+<010>
+<010>
+"
+0034[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : ""
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=3, Pos(L,C)=(15,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="The empty macro name is quite legal in FunnelWeb."
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : " !"#$%'()*+,-./0123456789:;<=>?"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=5, Pos(L,C)=(25,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=4, Pos(L,C)=(20,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "A@"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=8, Pos(L,C)=(31,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=6, Pos(L,C)=(26,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Ordinary"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=1, Pos(L,C)=(4,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="The text of ordinary"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "abcdefghijklmnopqrstuvwxyz{|}~"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=7, Pos(L,C)=(27,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "|"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=2, Pos(L,C)=(7,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="The text of ordinary"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR04: Test the definition of ordinary macros.<010>
+<010>
+1. Test an ordinary macro definition.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(4,1).
+Part 1 of macro @<Ordinary@>.
+
+TEXT COMPONENT: Pos(L,C)=(4,39).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+2. Test an ordinary definition using a quickname.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(7,1).
+Part 1 of macro @<|@>.
+
+TEXT COMPONENT: Pos(L,C)=(7,30).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+3. Test a name that includes EOL.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1", Section name="Error Recovery Point".
+
+TEXT COMPONENT: Pos(L,C)=(12,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+4. Test the minimum length name (the empty name).<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(15,1).
+Part 1 of macro @<@>.
+
+TEXT COMPONENT: Pos(L,C)=(15,60).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+5. Test a name at the maximum name length limit (80).<010>
+ONly the second of the two macros should generate an error.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(20,1).
+Part 1 of macro @<12345678901234567890123456789012345678901234567890123456789012345678901234567890@>.
+
+TEXT COMPONENT: Pos(L,C)=(20,91).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="Error Recovery Point".
+
+TEXT COMPONENT: Pos(L,C)=(22,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+6. Test names with all legal characters. There should be no errors.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(25,1).
+Part 1 of macro @< !"#$%'()*+,-./0123456789:;<=>?@>.
+
+TEXT COMPONENT: Pos(L,C)=(25,42).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(26,1).
+Part 1 of macro @<ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`@>.
+
+TEXT COMPONENT: Pos(L,C)=(26,43).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(27,1).
+Part 1 of macro @<abcdefghijklmnopqrstuvwxyz{|}~@>.
+
+TEXT COMPONENT: Pos(L,C)=(27,41).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+7. Test a name that has inserted text sequences.<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(31,1).
+Part 1 of macro @<A@@>.
+
+TEXT COMPONENT: Pos(L,C)=(31,23).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| PR04: Test the definition of ordinary macros.
+ 2 2|
+ 3 3| 1. Test an ordinary macro definition.
+ 4 4| @$@<Ordinary@>@{The text of ordinary@}
+ 5 5|
+ 6 6| 2. Test an ordinary definition using a quickname.
+ 7 7| @$@#|@{The text of ordinary@}
+ 8 8|
+ 9 9| 3. Test a name that includes EOL.
+ 10 10| @$@<This name is illegal because
+ Error|.....^Names cannot cross lines.
+ |.....^Skipping after error to the next major construct...
+ 11 11| it crosses a lion@>@{And people who cross lions tend to get eaten.@}
+ 12 12| @A@<Error Recovery Point@>
+ |.^...skipped to here after the error.
+ 13 13|
+ 14 14| 4. Test the minimum length name (the empty name).
+ 15 15| @$@<@>@{The empty macro name is quite legal in FunnelWeb.@}
+ 16 16|
+ 17 17| 5. Test a name at the maximum name length limit (80).
+ 18 18| ONly the second of the two macros should generate an error.
+ 19 19| @p maximum_input_line_length = 100
+ 20 20| @$@<12345678901234567890123456789012345678901234567890123456789012345678901234567890@>@{@}
+ 21 21| @$@<123456789012345678901234567890123456789012345678901234567890123456789012345678901@>@{@}
+ Error|.....^Name is too long.
+ |.....^The maximum length of a legal name is 80 characters.
+ |.....^Skipping after error to the next major construct...
+ 22 22| @A@<Error Recovery Point@>
+ |.^...skipped to here after the error.
+ 23 23|
+ 24 24| 6. Test names with all legal characters. There should be no errors.
+ 25 25| @$@< !"#$%'()*+,-./0123456789:;<=>?@>@{@}
+ 26 26| @$@<ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`@>@{@}
+ 27 27| @$@<abcdefghijklmnopqrstuvwxyz{|}~@>@{@}
+ 28 28|
+ 29 29| 7. Test a name that has inserted text sequences.
+ 30 30|
+ 31 31| @$@<@^D(065)@@@>==@{@}
+ 32 32|
+ 33 33|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 2 Errors.
diff --git a/web/funnelAC/answers/pr05.lis b/web/funnelAC/answers/pr05.lis
new file mode 100644
index 0000000000..5e1d211586
--- /dev/null
+++ b/web/funnelAC/answers/pr05.lis
@@ -0,0 +1,1005 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 30 35 3A 20 54 65 73 74 20 74 68 65 20 70 | PR05: Test the p |
+| 61 72 73 69 6E 67 20 6F 66 20 66 6F 72 6D 61 6C | arsing of formal |
+| 20 70 61 72 61 6D 65 74 65 72 20 6C 69 73 74 73 | parameter lists |
+| 2E 0A 0A 46 69 72 73 74 20 74 72 69 70 20 74 68 | ...First trip th |
+| 65 20 70 61 72 73 65 72 20 73 6F 20 77 65 20 64 | e parser so we d |
+| 6F 6E 27 74 20 67 65 74 20 70 61 73 74 20 74 68 | on't get past th |
+| 65 20 70 61 72 73 65 72 2E 0A 40 3E 0A 0A 31 2E | e parser..@>..1. |
+| 20 54 65 73 74 20 6D 61 63 72 6F 20 64 65 66 69 | Test macro defi |
+| 6E 69 74 69 6F 6E 20 77 69 74 68 20 6E 6F 20 66 | nition with no f |
+| 6F 72 6D 61 6C 20 70 61 72 61 6D 65 74 65 72 73 | ormal parameters |
+| 2E 0A 40 24 40 3C 53 6C 6F 74 68 40 3E 40 7B 53 | ..@$@<Sloth@>@{S |
+| 6C 6F 74 68 74 65 78 74 40 7D 0A 0A 32 2E 20 54 | lothtext@}..2. T |
+| 65 73 74 20 6D 61 63 72 6F 20 64 65 66 69 6E 69 | est macro defini |
+| 74 69 6F 6E 20 77 69 74 68 20 6F 6E 65 20 66 6F | tion with one fo |
+| 72 6D 61 6C 20 70 61 72 61 6D 65 74 65 72 2E 0A | rmal parameter.. |
+| 40 24 40 3C 53 6C 6F 74 68 20 77 69 74 68 20 6F | @$@<Sloth with o |
+| 6E 65 40 3E 40 28 40 31 40 29 40 7B 53 6C 6F 74 | ne@>@(@1@)@{Slot |
+| 68 74 65 78 74 40 7D 0A 0A 33 2E 20 54 65 73 74 | htext@}..3. Test |
+| 20 6D 61 63 72 6F 20 64 65 66 69 6E 69 74 69 6F | macro definitio |
+| 6E 20 77 69 74 68 20 6D 61 6E 79 20 66 6F 72 6D | n with many form |
+| 61 6C 20 70 61 72 61 6D 65 74 65 72 73 2E 0A 40 | al parameters..@ |
+| 24 40 3C 53 6C 6F 74 68 20 77 69 74 68 20 32 40 | $@<Sloth with 2@ |
+| 3E 40 28 40 32 40 29 40 7B 53 6C 6F 74 68 74 65 | >@(@2@)@{Slothte |
+| 78 74 40 7D 0A 40 24 40 3C 53 6C 6F 74 68 20 77 | xt@}.@$@<Sloth w |
+| 69 74 68 20 33 40 3E 40 28 40 33 40 29 40 7B 53 | ith 3@>@(@3@)@{S |
+| 6C 6F 74 68 74 65 78 74 40 7D 0A 40 24 40 3C 53 | lothtext@}.@$@<S |
+| 6C 6F 74 68 20 77 69 74 68 20 34 40 3E 40 28 40 | loth with 4@>@(@ |
+| 34 40 29 40 7B 53 6C 6F 74 68 74 65 78 74 40 7D | 4@)@{Slothtext@} |
+| 0A 40 24 40 3C 53 6C 6F 74 68 20 77 69 74 68 20 | .@$@<Sloth with |
+| 35 40 3E 40 28 40 35 40 29 40 7B 53 6C 6F 74 68 | 5@>@(@5@)@{Sloth |
+| 74 65 78 74 40 7D 0A 40 24 40 3C 53 6C 6F 74 68 | text@}.@$@<Sloth |
+| 20 77 69 74 68 20 36 40 3E 40 28 40 36 40 29 40 | with 6@>@(@6@)@ |
+| 7B 53 6C 6F 74 68 74 65 78 74 40 7D 0A 40 24 40 | {Slothtext@}.@$@ |
+| 3C 53 6C 6F 74 68 20 77 69 74 68 20 37 40 3E 40 | <Sloth with 7@>@ |
+| 28 40 37 40 29 40 7B 53 6C 6F 74 68 74 65 78 74 | (@7@)@{Slothtext |
+| 40 7D 0A 40 24 40 3C 53 6C 6F 74 68 20 77 69 74 | @}.@$@<Sloth wit |
+| 68 20 38 40 3E 40 28 40 38 40 29 40 7B 53 6C 6F | h 8@>@(@8@)@{Slo |
+| 74 68 74 65 78 74 40 7D 0A 40 24 40 3C 53 6C 6F | thtext@}.@$@<Slo |
+| 74 68 20 77 69 74 68 20 39 40 3E 40 28 40 39 40 | th with 9@>@(@9@ |
+| 29 40 7B 53 6C 6F 74 68 74 65 78 74 40 7D 0A 0A | )@{Slothtext@}.. |
+| 34 2E 20 54 65 73 74 20 77 69 74 68 20 73 79 6E | 4. Test with syn |
+| 74 61 78 20 65 72 72 6F 72 73 20 69 6E 20 74 68 | tax errors in th |
+| 65 20 70 61 72 61 6D 65 74 65 72 20 6C 69 73 74 | e parameter list |
+| 2E 0A 0A 40 24 40 3C 53 6C 6F 74 68 20 61 40 3E | ...@$@<Sloth a@> |
+| 40 28 40 2B 40 39 40 29 40 7B 53 6C 6F 74 68 74 | @(@+@9@)@{Slotht |
+| 65 78 74 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 | ext@}.@A@<Error |
+| 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 40 3E | recovery point@> |
+| 0A 0A 40 24 40 3C 53 6C 6F 74 68 20 62 40 3E 40 | ..@$@<Sloth b@>@ |
+| 39 40 29 40 7B 53 6C 6F 74 68 74 65 78 74 40 7D | 9@)@{Slothtext@} |
+| 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 | .@A@<Error recov |
+| 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 40 24 40 | ery point@>..@$@ |
+| 3C 53 6C 6F 74 68 20 63 40 3E 40 28 39 40 29 40 | <Sloth c@>@(9@)@ |
+| 7B 53 6C 6F 74 68 74 65 78 74 40 7D 0A 40 41 40 | {Slothtext@}.@A@ |
+| 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 | <Error recovery |
+| 70 6F 69 6E 74 40 3E 0A 0A 40 24 40 3C 53 6C 6F | point@>..@$@<Slo |
+| 74 68 20 64 40 3E 40 39 40 29 40 7B 53 6C 6F 74 | th d@>@9@)@{Slot |
+| 68 74 65 78 74 40 7D 0A 40 41 40 3C 45 72 72 6F | htext@}.@A@<Erro |
+| 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 | r recovery point |
+| 40 3E 0A 0A 40 24 40 3C 53 6C 6F 74 68 20 65 40 | @>..@$@<Sloth e@ |
+| 3E 40 28 40 39 40 29 40 29 40 7B 53 6C 6F 74 68 | >@(@9@)@)@{Sloth |
+| 74 65 78 74 40 7D 0A 40 41 40 3C 45 72 72 6F 72 | text@}.@A@<Error |
+| 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 40 | recovery point@ |
+| 3E 0A 0A 0A 0A | >.... |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR05: Test the parsing of formal parameter lists.<010>
+00002 00002| <010>
+00003 00003| First trip the parser so we don't get past the parser.<010>
+00004 00004| @><010>
+00005 00005| <010>
+00006 00006| 1. Test macro definition with no formal parameters.<010>
+00007 00007| @$@<Sloth@>@{Slothtext@}<010>
+00008 00008| <010>
+00009 00009| 2. Test macro definition with one formal parameter.<010>
+00010 00010| @$@<Sloth with one@>@(@1@)@{Slothtext@}<010>
+00011 00011| <010>
+00012 00012| 3. Test macro definition with many formal parameters.<010>
+00013 00013| @$@<Sloth with 2@>@(@2@)@{Slothtext@}<010>
+00014 00014| @$@<Sloth with 3@>@(@3@)@{Slothtext@}<010>
+00015 00015| @$@<Sloth with 4@>@(@4@)@{Slothtext@}<010>
+00016 00016| @$@<Sloth with 5@>@(@5@)@{Slothtext@}<010>
+00017 00017| @$@<Sloth with 6@>@(@6@)@{Slothtext@}<010>
+00018 00018| @$@<Sloth with 7@>@(@7@)@{Slothtext@}<010>
+00019 00019| @$@<Sloth with 8@>@(@8@)@{Slothtext@}<010>
+00020 00020| @$@<Sloth with 9@>@(@9@)@{Slothtext@}<010>
+00021 00021| <010>
+00022 00022| 4. Test with syntax errors in the parameter list.<010>
+00023 00023| <010>
+00024 00024| @$@<Sloth a@>@(@+@9@)@{Slothtext@}<010>
+00025 00025| @A@<Error recovery point@><010>
+00026 00026| <010>
+00027 00027| @$@<Sloth b@>@9@)@{Slothtext@}<010>
+00028 00028| @A@<Error recovery point@><010>
+00029 00029| <010>
+00030 00030| @$@<Sloth c@>@(9@)@{Slothtext@}<010>
+00031 00031| @A@<Error recovery point@><010>
+00032 00032| <010>
+00033 00033| @$@<Sloth d@>@9@)@{Slothtext@}<010>
+00034 00034| @A@<Error recovery point@><010>
+00035 00035| <010>
+00036 00036| @$@<Sloth e@>@(@9@)@)@{Slothtext@}<010>
+00037 00037| @A@<Error recovery point@><010>
+00038 00038| <010>
+00039 00039| <010>
+00040 00040| <010>
+00041 00041| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 191 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR05: Test the parsing of formal parameter lists.<010>
+<010>
+First trip the parser so we don't get past the parser.<010>
+"
+0004[01]: @> Close name.
+0004[03]: Text. Text scrap[Grey]="<010>
+<010>
+1. Test macro definition with no formal parameters.<010>
+"
+0007[01]: @$ Macro defn.
+0007[03]: @< Open name.
+0007[05]: Text. Text scrap[Grey]="Sloth"
+0007[10]: @> Close name.
+0007[12]: @{ Open defn.
+0007[14]: Text. Text scrap[Grey]="Slothtext"
+0007[23]: @} Close defn.
+0007[25]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test macro definition with one formal parameter.<010>
+"
+0010[01]: @$ Macro defn.
+0010[03]: @< Open name.
+0010[05]: Text. Text scrap[Grey]="Sloth with one"
+0010[19]: @> Close name.
+0010[21]: @( Open param.
+0010[23]: @n Parameter. Parameterno=1.
+0010[25]: @} Close param.
+0010[27]: @{ Open defn.
+0010[29]: Text. Text scrap[Grey]="Slothtext"
+0010[38]: @} Close defn.
+0010[40]: Text. Text scrap[Grey]="<010>
+<010>
+3. Test macro definition with many formal parameters.<010>
+"
+0013[01]: @$ Macro defn.
+0013[03]: @< Open name.
+0013[05]: Text. Text scrap[Grey]="Sloth with 2"
+0013[17]: @> Close name.
+0013[19]: @( Open param.
+0013[21]: @n Parameter. Parameterno=2.
+0013[23]: @} Close param.
+0013[25]: @{ Open defn.
+0013[27]: Text. Text scrap[Grey]="Slothtext"
+0013[36]: @} Close defn.
+0013[38]: Text. Text scrap[White]="<010>
+"
+0014[01]: @$ Macro defn.
+0014[03]: @< Open name.
+0014[05]: Text. Text scrap[Grey]="Sloth with 3"
+0014[17]: @> Close name.
+0014[19]: @( Open param.
+0014[21]: @n Parameter. Parameterno=3.
+0014[23]: @} Close param.
+0014[25]: @{ Open defn.
+0014[27]: Text. Text scrap[Grey]="Slothtext"
+0014[36]: @} Close defn.
+0014[38]: Text. Text scrap[White]="<010>
+"
+0015[01]: @$ Macro defn.
+0015[03]: @< Open name.
+0015[05]: Text. Text scrap[Grey]="Sloth with 4"
+0015[17]: @> Close name.
+0015[19]: @( Open param.
+0015[21]: @n Parameter. Parameterno=4.
+0015[23]: @} Close param.
+0015[25]: @{ Open defn.
+0015[27]: Text. Text scrap[Grey]="Slothtext"
+0015[36]: @} Close defn.
+0015[38]: Text. Text scrap[White]="<010>
+"
+0016[01]: @$ Macro defn.
+0016[03]: @< Open name.
+0016[05]: Text. Text scrap[Grey]="Sloth with 5"
+0016[17]: @> Close name.
+0016[19]: @( Open param.
+0016[21]: @n Parameter. Parameterno=5.
+0016[23]: @} Close param.
+0016[25]: @{ Open defn.
+0016[27]: Text. Text scrap[Grey]="Slothtext"
+0016[36]: @} Close defn.
+0016[38]: Text. Text scrap[White]="<010>
+"
+0017[01]: @$ Macro defn.
+0017[03]: @< Open name.
+0017[05]: Text. Text scrap[Grey]="Sloth with 6"
+0017[17]: @> Close name.
+0017[19]: @( Open param.
+0017[21]: @n Parameter. Parameterno=6.
+0017[23]: @} Close param.
+0017[25]: @{ Open defn.
+0017[27]: Text. Text scrap[Grey]="Slothtext"
+0017[36]: @} Close defn.
+0017[38]: Text. Text scrap[White]="<010>
+"
+0018[01]: @$ Macro defn.
+0018[03]: @< Open name.
+0018[05]: Text. Text scrap[Grey]="Sloth with 7"
+0018[17]: @> Close name.
+0018[19]: @( Open param.
+0018[21]: @n Parameter. Parameterno=7.
+0018[23]: @} Close param.
+0018[25]: @{ Open defn.
+0018[27]: Text. Text scrap[Grey]="Slothtext"
+0018[36]: @} Close defn.
+0018[38]: Text. Text scrap[White]="<010>
+"
+0019[01]: @$ Macro defn.
+0019[03]: @< Open name.
+0019[05]: Text. Text scrap[Grey]="Sloth with 8"
+0019[17]: @> Close name.
+0019[19]: @( Open param.
+0019[21]: @n Parameter. Parameterno=8.
+0019[23]: @} Close param.
+0019[25]: @{ Open defn.
+0019[27]: Text. Text scrap[Grey]="Slothtext"
+0019[36]: @} Close defn.
+0019[38]: Text. Text scrap[White]="<010>
+"
+0020[01]: @$ Macro defn.
+0020[03]: @< Open name.
+0020[05]: Text. Text scrap[Grey]="Sloth with 9"
+0020[17]: @> Close name.
+0020[19]: @( Open param.
+0020[21]: @n Parameter. Parameterno=9.
+0020[23]: @} Close param.
+0020[25]: @{ Open defn.
+0020[27]: Text. Text scrap[Grey]="Slothtext"
+0020[36]: @} Close defn.
+0020[38]: Text. Text scrap[Grey]="<010>
+<010>
+4. Test with syntax errors in the parameter list.<010>
+<010>
+"
+0024[01]: @$ Macro defn.
+0024[03]: @< Open name.
+0024[05]: Text. Text scrap[Grey]="Sloth a"
+0024[12]: @> Close name.
+0024[14]: @( Open param.
+0024[16]: Text. Text scrap[White]="<010>
+"
+0024[18]: @n Parameter. Parameterno=9.
+0024[20]: @} Close param.
+0024[22]: @{ Open defn.
+0024[24]: Text. Text scrap[Grey]="Slothtext"
+0024[33]: @} Close defn.
+0024[35]: Text. Text scrap[White]="<010>
+"
+0025[01]: @A New section (Level 1).
+0025[03]: @< Open name.
+0025[05]: Text. Text scrap[Grey]="Error recovery point"
+0025[25]: @> Close name.
+0025[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0027[01]: @$ Macro defn.
+0027[03]: @< Open name.
+0027[05]: Text. Text scrap[Grey]="Sloth b"
+0027[12]: @> Close name.
+0027[14]: @n Parameter. Parameterno=9.
+0027[16]: @} Close param.
+0027[18]: @{ Open defn.
+0027[20]: Text. Text scrap[Grey]="Slothtext"
+0027[29]: @} Close defn.
+0027[31]: Text. Text scrap[White]="<010>
+"
+0028[01]: @A New section (Level 1).
+0028[03]: @< Open name.
+0028[05]: Text. Text scrap[Grey]="Error recovery point"
+0028[25]: @> Close name.
+0028[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0030[01]: @$ Macro defn.
+0030[03]: @< Open name.
+0030[05]: Text. Text scrap[Grey]="Sloth c"
+0030[12]: @> Close name.
+0030[14]: @( Open param.
+0030[16]: Text. Text scrap[Grey]="9"
+0030[17]: @} Close param.
+0030[19]: @{ Open defn.
+0030[21]: Text. Text scrap[Grey]="Slothtext"
+0030[30]: @} Close defn.
+0030[32]: Text. Text scrap[White]="<010>
+"
+0031[01]: @A New section (Level 1).
+0031[03]: @< Open name.
+0031[05]: Text. Text scrap[Grey]="Error recovery point"
+0031[25]: @> Close name.
+0031[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0033[01]: @$ Macro defn.
+0033[03]: @< Open name.
+0033[05]: Text. Text scrap[Grey]="Sloth d"
+0033[12]: @> Close name.
+0033[14]: @n Parameter. Parameterno=9.
+0033[16]: @} Close param.
+0033[18]: @{ Open defn.
+0033[20]: Text. Text scrap[Grey]="Slothtext"
+0033[29]: @} Close defn.
+0033[31]: Text. Text scrap[White]="<010>
+"
+0034[01]: @A New section (Level 1).
+0034[03]: @< Open name.
+0034[05]: Text. Text scrap[Grey]="Error recovery point"
+0034[25]: @> Close name.
+0034[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0036[01]: @$ Macro defn.
+0036[03]: @< Open name.
+0036[05]: Text. Text scrap[Grey]="Sloth e"
+0036[12]: @> Close name.
+0036[14]: @( Open param.
+0036[16]: @n Parameter. Parameterno=9.
+0036[18]: @} Close param.
+0036[20]: @} Close param.
+0036[22]: @{ Open defn.
+0036[24]: Text. Text scrap[Grey]="Slothtext"
+0036[33]: @} Close defn.
+0036[35]: Text. Text scrap[White]="<010>
+"
+0037[01]: @A New section (Level 1).
+0037[03]: @< Open name.
+0037[05]: Text. Text scrap[Grey]="Error recovery point"
+0037[25]: @> Close name.
+0037[27]: Text. Text scrap[White]="<010>
+<010>
+<010>
+<010>
+"
+0041[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=1, Pos(L,C)=(7,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth a"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth b"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth c"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth d"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth e"
+Defined? : Yes.
+Parameters : 9
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with 2"
+Defined? : Yes.
+Parameters : 2
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=3, Pos(L,C)=(13,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with 3"
+Defined? : Yes.
+Parameters : 3
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=4, Pos(L,C)=(14,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with 4"
+Defined? : Yes.
+Parameters : 4
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=5, Pos(L,C)=(15,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with 5"
+Defined? : Yes.
+Parameters : 5
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=6, Pos(L,C)=(16,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with 6"
+Defined? : Yes.
+Parameters : 6
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=7, Pos(L,C)=(17,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with 7"
+Defined? : Yes.
+Parameters : 7
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=8, Pos(L,C)=(18,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with 8"
+Defined? : Yes.
+Parameters : 8
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=9, Pos(L,C)=(19,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with 9"
+Defined? : Yes.
+Parameters : 9
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=10, Pos(L,C)=(20,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with one"
+Defined? : Yes.
+Parameters : 1
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=2, Pos(L,C)=(10,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR05: Test the parsing of formal parameter lists.<010>
+<010>
+First trip the parser so we don't get past the parser.<010>
+"
+--- End of Text Scrap List ---
+
+
+TEXT COMPONENT: Pos(L,C)=(4,3).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+1. Test macro definition with no formal parameters.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(7,1).
+Part 1 of macro @<Sloth@>.
+
+TEXT COMPONENT: Pos(L,C)=(7,25).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+2. Test macro definition with one formal parameter.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(10,1).
+Part 1 of macro @<Sloth with one@>.
+
+TEXT COMPONENT: Pos(L,C)=(10,40).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+3. Test macro definition with many formal parameters.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(13,1).
+Part 1 of macro @<Sloth with 2@>.
+
+TEXT COMPONENT: Pos(L,C)=(13,38).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(14,1).
+Part 1 of macro @<Sloth with 3@>.
+
+TEXT COMPONENT: Pos(L,C)=(14,38).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(15,1).
+Part 1 of macro @<Sloth with 4@>.
+
+TEXT COMPONENT: Pos(L,C)=(15,38).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(16,1).
+Part 1 of macro @<Sloth with 5@>.
+
+TEXT COMPONENT: Pos(L,C)=(16,38).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(17,1).
+Part 1 of macro @<Sloth with 6@>.
+
+TEXT COMPONENT: Pos(L,C)=(17,38).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(18,1).
+Part 1 of macro @<Sloth with 7@>.
+
+TEXT COMPONENT: Pos(L,C)=(18,38).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(19,1).
+Part 1 of macro @<Sloth with 8@>.
+
+TEXT COMPONENT: Pos(L,C)=(19,38).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(20,1).
+Part 1 of macro @<Sloth with 9@>.
+
+TEXT COMPONENT: Pos(L,C)=(20,38).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+4. Test with syntax errors in the parameter list.<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(25,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(28,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "3", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(31,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(34,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "5", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(37,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| PR05: Test the parsing of formal parameter lists.
+ 2 2|
+ 3 3| First trip the parser so we don't get past the parser.
+ 4 4| @>
+ Error|.^The parser was at the top level and was expecting
+ |.^one of: {Directive, Text, Macro definition, EOF}.
+ 5 5|
+ 6 6| 1. Test macro definition with no formal parameters.
+ 7 7| @$@<Sloth@>@{Slothtext@}
+ 8 8|
+ 9 9| 2. Test macro definition with one formal parameter.
+ 10 10| @$@<Sloth with one@>@(@1@)@{Slothtext@}
+ 11 11|
+ 12 12| 3. Test macro definition with many formal parameters.
+ 13 13| @$@<Sloth with 2@>@(@2@)@{Slothtext@}
+ 14 14| @$@<Sloth with 3@>@(@3@)@{Slothtext@}
+ 15 15| @$@<Sloth with 4@>@(@4@)@{Slothtext@}
+ 16 16| @$@<Sloth with 5@>@(@5@)@{Slothtext@}
+ 17 17| @$@<Sloth with 6@>@(@6@)@{Slothtext@}
+ 18 18| @$@<Sloth with 7@>@(@7@)@{Slothtext@}
+ 19 19| @$@<Sloth with 8@>@(@8@)@{Slothtext@}
+ 20 20| @$@<Sloth with 9@>@(@9@)@{Slothtext@}
+ 21 21|
+ 22 22| 4. Test with syntax errors in the parameter list.
+ 23 23|
+ 24 24| @$@<Sloth a@>@(@+@9@)@{Slothtext@}
+ Error|................^Expecting one of [@1..@9].
+ |................^Skipping after error to the next major construct...
+ 25 25| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 26 26|
+ 27 27| @$@<Sloth b@>@9@)@{Slothtext@}
+ Error|..............^Expecting '@{'.
+ |..............^Skipping after error to the next major construct...
+ 28 28| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 29 29|
+ 30 30| @$@<Sloth c@>@(9@)@{Slothtext@}
+ Error|................^Expecting one of [@1..@9].
+ |................^Skipping after error to the next major construct...
+ 31 31| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 32 32|
+ 33 33| @$@<Sloth d@>@9@)@{Slothtext@}
+ Error|..............^Expecting '@{'.
+ |..............^Skipping after error to the next major construct...
+ 34 34| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 35 35|
+ 36 36| @$@<Sloth e@>@(@9@)@)@{Slothtext@}
+ Error|....................^Expecting '@{'.
+ |....................^Skipping after error to the next major construct...
+ 37 37| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 38 38|
+ 39 39|
+ 40 40|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 6 Errors.
diff --git a/web/funnelAC/answers/pr06.lis b/web/funnelAC/answers/pr06.lis
new file mode 100644
index 0000000000..2a7d80d8d9
--- /dev/null
+++ b/web/funnelAC/answers/pr06.lis
@@ -0,0 +1,698 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 30 36 3A 20 54 65 73 74 20 74 68 65 20 70 | PR06: Test the p |
+| 61 72 73 69 6E 67 20 6F 6E 20 69 6E 76 6F 63 61 | arsing on invoca |
+| 74 69 6F 6E 20 6E 75 6D 62 65 72 20 63 6F 6E 73 | tion number cons |
+| 74 72 61 69 6E 74 73 2E 0A 0A 54 72 69 70 20 74 | traints...Trip t |
+| 68 65 20 70 61 72 73 65 72 20 73 6F 20 77 65 20 | he parser so we |
+| 64 6F 6E 27 74 20 67 65 74 20 70 61 73 74 20 69 | don't get past i |
+| 74 2E 0A 40 3E 0A 0A 31 2E 20 54 65 73 74 20 77 | t..@>..1. Test w |
+| 69 74 68 20 6E 6F 20 7A 65 72 6F 20 61 6E 64 20 | ith no zero and |
+| 6E 6F 20 6D 61 6E 79 2E 0A 40 24 40 3C 53 6C 6F | no many..@$@<Slo |
+| 74 68 40 3E 40 7B 4E 6F 20 7A 65 72 6F 20 61 6E | th@>@{No zero an |
+| 64 20 6E 6F 20 6D 61 6E 79 20 69 6E 20 74 68 69 | d no many in thi |
+| 73 20 6D 61 63 72 6F 40 7D 0A 0A 32 2E 20 54 65 | s macro@}..2. Te |
+| 73 74 20 77 69 74 68 20 61 20 7A 65 72 6F 2E 0A | st with a zero.. |
+| 40 24 40 3C 53 6C 6F 74 68 20 7A 65 72 6F 40 3E | @$@<Sloth zero@> |
+| 40 5A 40 7B 43 61 6E 20 62 65 20 63 61 6C 6C 65 | @Z@{Can be calle |
+| 64 20 66 72 6F 6D 20 30 20 74 6F 20 31 20 74 69 | d from 0 to 1 ti |
+| 6D 65 73 2E 40 7D 0A 0A 33 2E 20 54 65 73 74 20 | mes.@}..3. Test |
+| 77 69 74 68 20 61 20 6D 61 6E 79 2E 0A 40 24 40 | with a many..@$@ |
+| 3C 53 6C 6F 74 68 20 6D 61 6E 79 40 3E 40 4D 40 | <Sloth many@>@M@ |
+| 7B 43 61 6E 20 62 65 20 63 61 6C 6C 65 64 20 66 | {Can be called f |
+| 72 6F 6D 20 31 20 74 6F 20 69 6E 66 69 6E 69 74 | rom 1 to infinit |
+| 79 20 74 69 6D 65 73 2E 40 7D 0A 0A 34 2E 20 54 | y times.@}..4. T |
+| 65 73 74 20 77 69 74 68 20 61 20 7A 65 72 6F 20 | est with a zero |
+| 61 6E 64 20 61 20 6D 61 6E 79 2E 0A 40 24 40 3C | and a many..@$@< |
+| 53 6C 6F 74 68 20 7A 65 72 6F 6D 61 6E 79 40 3E | Sloth zeromany@> |
+| 40 5A 40 4D 40 7B 43 61 6E 20 62 65 20 63 61 6C | @Z@M@{Can be cal |
+| 6C 65 64 20 66 72 6F 6D 20 30 20 74 6F 20 69 6E | led from 0 to in |
+| 66 69 6E 69 74 79 20 74 69 6D 65 73 2E 40 7D 0A | finity times.@}. |
+| 0A 35 2E 20 54 65 73 74 20 77 69 74 68 20 61 20 | .5. Test with a |
+| 7A 65 72 6F 20 61 6E 64 20 61 20 6D 61 6E 79 20 | zero and a many |
+| 62 75 74 20 6F 75 74 20 6F 66 20 6F 72 64 65 72 | but out of order |
+| 20 28 73 68 6F 75 6C 64 20 67 69 76 65 20 65 72 | (should give er |
+| 72 6F 72 29 2E 0A 40 24 40 3C 53 6C 6F 74 68 20 | ror)..@$@<Sloth |
+| 6D 61 6E 79 7A 65 72 6F 40 3E 40 4D 40 5A 40 7B | manyzero@>@M@Z@{ |
+| 4F 6F 70 73 2E 40 7D 0A 40 41 40 3C 45 72 72 6F | Oops.@}.@A@<Erro |
+| 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 | r recovery point |
+| 40 3E 0A 0A 36 2E 20 54 65 73 74 20 77 69 74 68 | @>..6. Test with |
+| 20 73 79 6E 74 61 63 74 69 63 20 65 72 72 6F 72 | syntactic error |
+| 73 2E 0A 0A 40 24 40 3C 53 6C 6F 74 68 20 61 40 | s...@$@<Sloth a@ |
+| 3E 20 40 4D 20 40 5A 20 40 7B 4F 6F 70 73 2E 40 | > @M @Z @{Oops.@ |
+| 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F | }.@A@<Error reco |
+| 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 40 24 | very point@>..@$ |
+| 40 3C 53 6C 6F 74 68 20 62 40 3E 40 5A 40 5A 40 | @<Sloth b@>@Z@Z@ |
+| 7B 4F 6F 70 73 2E 40 7D 0A 40 41 40 3C 45 72 72 | {Oops.@}.@A@<Err |
+| 6F 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E | or recovery poin |
+| 74 40 3E 0A 0A 40 24 40 3C 53 6C 6F 74 68 20 63 | t@>..@$@<Sloth c |
+| 40 5A 40 3E 40 7B 4F 6F 70 73 2E 40 7D 0A 40 41 | @Z@>@{Oops.@}.@A |
+| 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 | @<Error recovery |
+| 20 70 6F 69 6E 74 40 3E 0A 0A 40 24 40 3C 53 6C | point@>..@$@<Sl |
+| 6F 74 68 20 64 40 3E 5A 40 7B 4F 6F 70 73 2E 40 | oth d@>Z@{Oops.@ |
+| 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F | }.@A@<Error reco |
+| 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 40 24 | very point@>..@$ |
+| 40 3C 53 6C 6F 74 68 20 64 40 3E 40 5A 4D 40 7B | @<Sloth d@>@ZM@{ |
+| 4F 6F 70 73 2E 40 7D 0A 40 41 40 3C 45 72 72 6F | Oops.@}.@A@<Erro |
+| 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 | r recovery point |
+| 40 3E 0A 0A 0A | @>... |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR06: Test the parsing on invocation number constraints.<010>
+00002 00002| <010>
+00003 00003| Trip the parser so we don't get past it.<010>
+00004 00004| @><010>
+00005 00005| <010>
+00006 00006| 1. Test with no zero and no many.<010>
+00007 00007| @$@<Sloth@>@{No zero and no many in this macro@}<010>
+00008 00008| <010>
+00009 00009| 2. Test with a zero.<010>
+00010 00010| @$@<Sloth zero@>@Z@{Can be called from 0 to 1 times.@}<010>
+00011 00011| <010>
+00012 00012| 3. Test with a many.<010>
+00013 00013| @$@<Sloth many@>@M@{Can be called from 1 to infinity times.@}<010>
+00014 00014| <010>
+00015 00015| 4. Test with a zero and a many.<010>
+00016 00016| @$@<Sloth zeromany@>@Z@M@{Can be called from 0 to infinity times.@}<010>
+00017 00017| <010>
+00018 00018| 5. Test with a zero and a many but out of order (should give error).<010>
+00019 00019| @$@<Sloth manyzero@>@M@Z@{Oops.@}<010>
+00020 00020| @A@<Error recovery point@><010>
+00021 00021| <010>
+00022 00022| 6. Test with syntactic errors.<010>
+00023 00023| <010>
+00024 00024| @$@<Sloth a@> @M @Z @{Oops.@}<010>
+00025 00025| @A@<Error recovery point@><010>
+00026 00026| <010>
+00027 00027| @$@<Sloth b@>@Z@Z@{Oops.@}<010>
+00028 00028| @A@<Error recovery point@><010>
+00029 00029| <010>
+00030 00030| @$@<Sloth c@Z@>@{Oops.@}<010>
+00031 00031| @A@<Error recovery point@><010>
+00032 00032| <010>
+00033 00033| @$@<Sloth d@>Z@{Oops.@}<010>
+00034 00034| @A@<Error recovery point@><010>
+00035 00035| <010>
+00036 00036| @$@<Sloth d@>@ZM@{Oops.@}<010>
+00037 00037| @A@<Error recovery point@><010>
+00038 00038| <010>
+00039 00039| <010>
+00040 00040| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 131 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR06: Test the parsing on invocation number constraints.<010>
+<010>
+Trip the parser so we don't get past it.<010>
+"
+0004[01]: @> Close name.
+0004[03]: Text. Text scrap[Grey]="<010>
+<010>
+1. Test with no zero and no many.<010>
+"
+0007[01]: @$ Macro defn.
+0007[03]: @< Open name.
+0007[05]: Text. Text scrap[Grey]="Sloth"
+0007[10]: @> Close name.
+0007[12]: @{ Open defn.
+0007[14]: Text. Text scrap[Grey]="No zero and no many in this macro"
+0007[47]: @} Close defn.
+0007[49]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test with a zero.<010>
+"
+0010[01]: @$ Macro defn.
+0010[03]: @< Open name.
+0010[05]: Text. Text scrap[Grey]="Sloth zero"
+0010[15]: @> Close name.
+0010[17]: @Z Zero calls.
+0010[19]: @{ Open defn.
+0010[21]: Text. Text scrap[Grey]="Can be called from 0 to 1 times."
+0010[53]: @} Close defn.
+0010[55]: Text. Text scrap[Grey]="<010>
+<010>
+3. Test with a many.<010>
+"
+0013[01]: @$ Macro defn.
+0013[03]: @< Open name.
+0013[05]: Text. Text scrap[Grey]="Sloth many"
+0013[15]: @> Close name.
+0013[17]: @M Many calls.
+0013[19]: @{ Open defn.
+0013[21]: Text. Text scrap[Grey]="Can be called from 1 to infinity times."
+0013[60]: @} Close defn.
+0013[62]: Text. Text scrap[Grey]="<010>
+<010>
+4. Test with a zero and a many.<010>
+"
+0016[01]: @$ Macro defn.
+0016[03]: @< Open name.
+0016[05]: Text. Text scrap[Grey]="Sloth zeromany"
+0016[19]: @> Close name.
+0016[21]: @Z Zero calls.
+0016[23]: @M Many calls.
+0016[25]: @{ Open defn.
+0016[27]: Text. Text scrap[Grey]="Can be called from 0 to infinity times."
+0016[66]: @} Close defn.
+0016[68]: Text. Text scrap[Grey]="<010>
+<010>
+5. Test with a zero and a many but out of order (should give error).<010>
+"
+0019[01]: @$ Macro defn.
+0019[03]: @< Open name.
+0019[05]: Text. Text scrap[Grey]="Sloth manyzero"
+0019[19]: @> Close name.
+0019[21]: @M Many calls.
+0019[23]: @Z Zero calls.
+0019[25]: @{ Open defn.
+0019[27]: Text. Text scrap[Grey]="Oops."
+0019[32]: @} Close defn.
+0019[34]: Text. Text scrap[White]="<010>
+"
+0020[01]: @A New section (Level 1).
+0020[03]: @< Open name.
+0020[05]: Text. Text scrap[Grey]="Error recovery point"
+0020[25]: @> Close name.
+0020[27]: Text. Text scrap[Grey]="<010>
+<010>
+6. Test with syntactic errors.<010>
+<010>
+"
+0024[01]: @$ Macro defn.
+0024[03]: @< Open name.
+0024[05]: Text. Text scrap[Grey]="Sloth a"
+0024[12]: @> Close name.
+0024[14]: Text. Text scrap[White]=" "
+0024[15]: @M Many calls.
+0024[17]: Text. Text scrap[White]=" "
+0024[18]: @Z Zero calls.
+0024[20]: Text. Text scrap[White]=" "
+0024[21]: @{ Open defn.
+0024[23]: Text. Text scrap[Grey]="Oops."
+0024[28]: @} Close defn.
+0024[30]: Text. Text scrap[White]="<010>
+"
+0025[01]: @A New section (Level 1).
+0025[03]: @< Open name.
+0025[05]: Text. Text scrap[Grey]="Error recovery point"
+0025[25]: @> Close name.
+0025[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0027[01]: @$ Macro defn.
+0027[03]: @< Open name.
+0027[05]: Text. Text scrap[Grey]="Sloth b"
+0027[12]: @> Close name.
+0027[14]: @Z Zero calls.
+0027[16]: @Z Zero calls.
+0027[18]: @{ Open defn.
+0027[20]: Text. Text scrap[Grey]="Oops."
+0027[25]: @} Close defn.
+0027[27]: Text. Text scrap[White]="<010>
+"
+0028[01]: @A New section (Level 1).
+0028[03]: @< Open name.
+0028[05]: Text. Text scrap[Grey]="Error recovery point"
+0028[25]: @> Close name.
+0028[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0030[01]: @$ Macro defn.
+0030[03]: @< Open name.
+0030[05]: Text. Text scrap[Grey]="Sloth c"
+0030[12]: @Z Zero calls.
+0030[14]: @> Close name.
+0030[16]: @{ Open defn.
+0030[18]: Text. Text scrap[Grey]="Oops."
+0030[23]: @} Close defn.
+0030[25]: Text. Text scrap[White]="<010>
+"
+0031[01]: @A New section (Level 1).
+0031[03]: @< Open name.
+0031[05]: Text. Text scrap[Grey]="Error recovery point"
+0031[25]: @> Close name.
+0031[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0033[01]: @$ Macro defn.
+0033[03]: @< Open name.
+0033[05]: Text. Text scrap[Grey]="Sloth d"
+0033[12]: @> Close name.
+0033[14]: Text. Text scrap[Grey]="Z"
+0033[15]: @{ Open defn.
+0033[17]: Text. Text scrap[Grey]="Oops."
+0033[22]: @} Close defn.
+0033[24]: Text. Text scrap[White]="<010>
+"
+0034[01]: @A New section (Level 1).
+0034[03]: @< Open name.
+0034[05]: Text. Text scrap[Grey]="Error recovery point"
+0034[25]: @> Close name.
+0034[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0036[01]: @$ Macro defn.
+0036[03]: @< Open name.
+0036[05]: Text. Text scrap[Grey]="Sloth d"
+0036[12]: @> Close name.
+0036[14]: @Z Zero calls.
+0036[16]: Text. Text scrap[Grey]="M"
+0036[17]: @{ Open defn.
+0036[19]: Text. Text scrap[Grey]="Oops."
+0036[24]: @} Close defn.
+0036[26]: Text. Text scrap[White]="<010>
+"
+0037[01]: @A New section (Level 1).
+0037[03]: @< Open name.
+0037[05]: Text. Text scrap[Grey]="Error recovery point"
+0037[25]: @> Close name.
+0037[27]: Text. Text scrap[White]="<010>
+<010>
+<010>
+"
+0040[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=1, Pos(L,C)=(7,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="No zero and no many in this macro"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth a"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth b"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth d"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth many"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : Yes.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=3, Pos(L,C)=(13,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Can be called from 1 to infinity times."
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth manyzero"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : Yes.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth zero"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=2, Pos(L,C)=(10,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Can be called from 0 to 1 times."
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth zeromany"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=4, Pos(L,C)=(16,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Can be called from 0 to infinity times."
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR06: Test the parsing on invocation number constraints.<010>
+<010>
+Trip the parser so we don't get past it.<010>
+"
+--- End of Text Scrap List ---
+
+
+TEXT COMPONENT: Pos(L,C)=(4,3).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+1. Test with no zero and no many.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(7,1).
+Part 1 of macro @<Sloth@>.
+
+TEXT COMPONENT: Pos(L,C)=(7,49).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+2. Test with a zero.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(10,1).
+Part 1 of macro @<Sloth zero@>.
+
+TEXT COMPONENT: Pos(L,C)=(10,55).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+3. Test with a many.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(13,1).
+Part 1 of macro @<Sloth many@>.
+
+TEXT COMPONENT: Pos(L,C)=(13,62).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+4. Test with a zero and a many.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(16,1).
+Part 1 of macro @<Sloth zeromany@>.
+
+TEXT COMPONENT: Pos(L,C)=(16,68).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+5. Test with a zero and a many but out of order (should give error).<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(20,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+6. Test with syntactic errors.<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(25,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "3", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(28,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(31,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "5", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(34,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "6", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(37,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| PR06: Test the parsing on invocation number constraints.
+ 2 2|
+ 3 3| Trip the parser so we don't get past it.
+ 4 4| @>
+ Error|.^The parser was at the top level and was expecting
+ |.^one of: {Directive, Text, Macro definition, EOF}.
+ 5 5|
+ 6 6| 1. Test with no zero and no many.
+ 7 7| @$@<Sloth@>@{No zero and no many in this macro@}
+ 8 8|
+ 9 9| 2. Test with a zero.
+ 10 10| @$@<Sloth zero@>@Z@{Can be called from 0 to 1 times.@}
+ 11 11|
+ 12 12| 3. Test with a many.
+ 13 13| @$@<Sloth many@>@M@{Can be called from 1 to infinity times.@}
+ 14 14|
+ 15 15| 4. Test with a zero and a many.
+ 16 16| @$@<Sloth zeromany@>@Z@M@{Can be called from 0 to infinity times.@}
+ 17 17|
+ 18 18| 5. Test with a zero and a many but out of order (should give error).
+ 19 19| @$@<Sloth manyzero@>@M@Z@{Oops.@}
+ Error|.......................^Expecting '@{'.
+ |.......................^Skipping after error to the next major construct...
+ 20 20| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 21 21|
+ 22 22| 6. Test with syntactic errors.
+ 23 23|
+ 24 24| @$@<Sloth a@> @M @Z @{Oops.@}
+ Error|..............^Expecting "==@{" or "+=@{" or just "@{".
+ |..............^(or @Z or @M if they have not already appeared).
+ |..............^Note: FunnelWeb is intolerant of spaces at this point.
+ |...............^Skipping after error to the next major construct...
+ 25 25| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 26 26|
+ 27 27| @$@<Sloth b@>@Z@Z@{Oops.@}
+ Error|................^Expecting '@{'.
+ |................^Skipping after error to the next major construct...
+ 28 28| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 29 29|
+ 30 30| @$@<Sloth c@Z@>@{Oops.@}
+ Error|............^Illegal character or symbol in name.
+ |............^Skipping after error to the next major construct...
+ 31 31| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 32 32|
+ 33 33| @$@<Sloth d@>Z@{Oops.@}
+ Error|..............^Expecting "==@{" or "+=@{" or just "@{".
+ |..............^(or @Z or @M if they have not already appeared).
+ |..............^Note: FunnelWeb is intolerant of spaces at this point.
+ |...............^Skipping after error to the next major construct...
+ 34 34| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 35 35|
+ 36 36| @$@<Sloth d@>@ZM@{Oops.@}
+ Error|................^Expecting "==@{" or "+=@{" or just "@{".
+ |................^(or @Z or @M if they have not already appeared).
+ |................^Note: FunnelWeb is intolerant of spaces at this point.
+ |.................^Skipping after error to the next major construct...
+ 37 37| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 38 38|
+ 39 39|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 7 Errors.
diff --git a/web/funnelAC/answers/pr07.lis b/web/funnelAC/answers/pr07.lis
new file mode 100644
index 0000000000..d0f47f77c6
--- /dev/null
+++ b/web/funnelAC/answers/pr07.lis
@@ -0,0 +1,613 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 30 37 3A 20 54 65 73 74 20 74 68 65 20 70 | PR07: Test the p |
+| 61 72 73 69 6E 67 20 6F 66 20 3D 3D 20 61 6E 64 | arsing of == and |
+| 20 2B 3D 20 69 6E 20 6D 61 63 72 6F 20 64 65 66 | += in macro def |
+| 69 6E 69 74 69 6F 6E 73 2E 0A 0A 54 72 69 70 20 | initions...Trip |
+| 74 68 65 20 70 61 72 73 65 72 20 73 6F 20 77 65 | the parser so we |
+| 20 64 6F 6E 27 74 20 67 65 74 20 61 6E 79 20 66 | don't get any f |
+| 75 72 74 68 65 72 2E 0A 40 3E 0A 0A 31 2E 20 54 | urther..@>..1. T |
+| 65 73 74 20 77 69 74 68 20 6E 6F 20 65 71 75 61 | est with no equa |
+| 6C 73 2E 0A 40 24 40 3C 53 6C 6F 74 68 40 3E 40 | ls..@$@<Sloth@>@ |
+| 7B 4E 6F 20 65 71 75 61 6C 73 20 69 6E 20 74 68 | {No equals in th |
+| 69 73 20 6D 61 63 72 6F 20 64 65 66 69 6E 69 74 | is macro definit |
+| 69 6F 6E 2E 40 7D 0A 0A 32 2E 20 54 65 73 74 20 | ion.@}..2. Test |
+| 77 69 74 68 20 3D 3D 2E 0A 40 24 40 3C 53 6C 6F | with ==..@$@<Slo |
+| 74 68 20 77 69 74 68 20 65 71 75 61 6C 73 40 3E | th with equals@> |
+| 3D 3D 40 7B 4E 6F 20 65 71 75 61 6C 73 20 69 6E | ==@{No equals in |
+| 20 74 68 69 73 20 6D 61 63 72 6F 20 64 65 66 69 | this macro defi |
+| 6E 69 74 69 6F 6E 2E 40 7D 0A 0A 33 2E 20 54 65 | nition.@}..3. Te |
+| 73 74 20 77 69 74 68 20 2B 3D 2E 0A 40 24 40 3C | st with +=..@$@< |
+| 53 6C 6F 74 68 20 77 69 74 68 20 70 6C 75 73 40 | Sloth with plus@ |
+| 3E 2B 3D 40 7B 4E 6F 20 65 71 75 61 6C 73 20 69 | >+=@{No equals i |
+| 6E 20 74 68 69 73 20 6D 61 63 72 6F 20 64 65 66 | n this macro def |
+| 69 6E 69 74 69 6F 6E 2E 40 7D 0A 0A 34 2E 20 54 | inition.@}..4. T |
+| 65 73 74 20 77 69 74 68 20 73 79 6E 74 61 78 20 | est with syntax |
+| 65 72 72 6F 72 73 2E 0A 0A 40 24 40 3C 45 72 72 | errors...@$@<Err |
+| 6F 72 31 40 3E 2B 2B 40 7B 4E 6F 20 65 71 75 61 | or1@>++@{No equa |
+| 6C 73 20 69 6E 20 74 68 69 73 20 6D 61 63 72 6F | ls in this macro |
+| 20 64 65 66 69 6E 69 74 69 6F 6E 2E 40 7D 0A 40 | definition.@}.@ |
+| 41 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 72 | A@<Error recover |
+| 79 20 70 6F 69 6E 74 40 3E 0A 0A 40 24 40 3C 45 | y point@>..@$@<E |
+| 72 72 6F 72 32 40 3E 40 2B 3D 40 7B 4E 6F 20 65 | rror2@>@+=@{No e |
+| 71 75 61 6C 73 20 69 6E 20 74 68 69 73 20 6D 61 | quals in this ma |
+| 63 72 6F 20 64 65 66 69 6E 69 74 69 6F 6E 2E 40 | cro definition.@ |
+| 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F | }.@A@<Error reco |
+| 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 40 24 | very point@>..@$ |
+| 40 3C 45 72 72 6F 72 33 40 3E 2B 3D 3D 2B 40 7B | @<Error3@>+==+@{ |
+| 4E 6F 20 65 71 75 61 6C 73 20 69 6E 20 74 68 69 | No equals in thi |
+| 73 20 6D 61 63 72 6F 20 64 65 66 69 6E 69 74 69 | s macro definiti |
+| 6F 6E 2E 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 | on.@}.@A@<Error |
+| 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 40 3E | recovery point@> |
+| 0A 0A 40 24 40 3C 45 72 72 6F 72 34 40 3E 3D 2B | ..@$@<Error4@>=+ |
+| 40 7B 4E 6F 20 65 71 75 61 6C 73 20 69 6E 20 74 | @{No equals in t |
+| 68 69 73 20 6D 61 63 72 6F 20 64 65 66 69 6E 69 | his macro defini |
+| 74 69 6F 6E 2E 40 7D 0A 40 41 40 3C 45 72 72 6F | tion.@}.@A@<Erro |
+| 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 | r recovery point |
+| 40 3E 0A 0A 40 24 40 3C 45 72 72 6F 72 34 40 3E | @>..@$@<Error4@> |
+| 40 3D 40 3D 40 7B 4E 6F 20 65 71 75 61 6C 73 20 | @=@=@{No equals |
+| 69 6E 20 74 68 69 73 20 6D 61 63 72 6F 20 64 65 | in this macro de |
+| 66 69 6E 69 74 69 6F 6E 2E 40 7D 0A 40 41 40 3C | finition.@}.@A@< |
+| 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 70 | Error recovery p |
+| 6F 69 6E 74 40 3E 0A 0A 40 24 40 3C 45 72 72 6F | oint@>..@$@<Erro |
+| 72 34 40 3E 40 2B 40 3D 40 7B 4E 6F 20 65 71 75 | r4@>@+@=@{No equ |
+| 61 6C 73 20 69 6E 20 74 68 69 73 20 6D 61 63 72 | als in this macr |
+| 6F 20 64 65 66 69 6E 69 74 69 6F 6E 2E 40 7D 0A | o definition.@}. |
+| 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 | @A@<Error recove |
+| 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 0A 0A | ry point@>.... |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR07: Test the parsing of == and += in macro definitions.<010>
+00002 00002| <010>
+00003 00003| Trip the parser so we don't get any further.<010>
+00004 00004| @><010>
+00005 00005| <010>
+00006 00006| 1. Test with no equals.<010>
+00007 00007| @$@<Sloth@>@{No equals in this macro definition.@}<010>
+00008 00008| <010>
+00009 00009| 2. Test with ==.<010>
+00010 00010| @$@<Sloth with equals@>==@{No equals in this macro definition.@}<010>
+00011 00011| <010>
+00012 00012| 3. Test with +=.<010>
+00013 00013| @$@<Sloth with plus@>+=@{No equals in this macro definition.@}<010>
+00014 00014| <010>
+00015 00015| 4. Test with syntax errors.<010>
+00016 00016| <010>
+00017 00017| @$@<Error1@>++@{No equals in this macro definition.@}<010>
+00018 00018| @A@<Error recovery point@><010>
+00019 00019| <010>
+00020 00020| @$@<Error2@>@+=@{No equals in this macro definition.@}<010>
+00021 00021| @A@<Error recovery point@><010>
+00022 00022| <010>
+00023 00023| @$@<Error3@>+==+@{No equals in this macro definition.@}<010>
+00024 00024| @A@<Error recovery point@><010>
+00025 00025| <010>
+00026 00026| @$@<Error4@>=+@{No equals in this macro definition.@}<010>
+00027 00027| @A@<Error recovery point@><010>
+00028 00028| <010>
+00029 00029| @$@<Error4@>@=@=@{No equals in this macro definition.@}<010>
+00030 00030| @A@<Error recovery point@><010>
+00031 00031| <010>
+00032 00032| @$@<Error4@>@+@=@{No equals in this macro definition.@}<010>
+00033 00033| @A@<Error recovery point@><010>
+00034 00034| <010>
+00035 00035| <010>
+00036 00036| <010>
+00037 00037| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 114 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR07: Test the parsing of == and += in macro definitions.<010>
+<010>
+Trip the parser so we don't get any further.<010>
+"
+0004[01]: @> Close name.
+0004[03]: Text. Text scrap[Grey]="<010>
+<010>
+1. Test with no equals.<010>
+"
+0007[01]: @$ Macro defn.
+0007[03]: @< Open name.
+0007[05]: Text. Text scrap[Grey]="Sloth"
+0007[10]: @> Close name.
+0007[12]: @{ Open defn.
+0007[14]: Text. Text scrap[Grey]="No equals in this macro definition."
+0007[49]: @} Close defn.
+0007[51]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test with ==.<010>
+"
+0010[01]: @$ Macro defn.
+0010[03]: @< Open name.
+0010[05]: Text. Text scrap[Grey]="Sloth with equals"
+0010[22]: @> Close name.
+0010[24]: Text. Text scrap[Grey]="=="
+0010[26]: @{ Open defn.
+0010[28]: Text. Text scrap[Grey]="No equals in this macro definition."
+0010[63]: @} Close defn.
+0010[65]: Text. Text scrap[Grey]="<010>
+<010>
+3. Test with +=.<010>
+"
+0013[01]: @$ Macro defn.
+0013[03]: @< Open name.
+0013[05]: Text. Text scrap[Grey]="Sloth with plus"
+0013[20]: @> Close name.
+0013[22]: Text. Text scrap[Grey]="+="
+0013[24]: @{ Open defn.
+0013[26]: Text. Text scrap[Grey]="No equals in this macro definition."
+0013[61]: @} Close defn.
+0013[63]: Text. Text scrap[Grey]="<010>
+<010>
+4. Test with syntax errors.<010>
+<010>
+"
+0017[01]: @$ Macro defn.
+0017[03]: @< Open name.
+0017[05]: Text. Text scrap[Grey]="Error1"
+0017[11]: @> Close name.
+0017[13]: Text. Text scrap[Grey]="++"
+0017[15]: @{ Open defn.
+0017[17]: Text. Text scrap[Grey]="No equals in this macro definition."
+0017[52]: @} Close defn.
+0017[54]: Text. Text scrap[White]="<010>
+"
+0018[01]: @A New section (Level 1).
+0018[03]: @< Open name.
+0018[05]: Text. Text scrap[Grey]="Error recovery point"
+0018[25]: @> Close name.
+0018[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0020[01]: @$ Macro defn.
+0020[03]: @< Open name.
+0020[05]: Text. Text scrap[Grey]="Error2"
+0020[11]: @> Close name.
+0020[13]: Text. Text scrap[White]="<010>
+"
+0020[15]: Text. Text scrap[Grey]="="
+0020[16]: @{ Open defn.
+0020[18]: Text. Text scrap[Grey]="No equals in this macro definition."
+0020[53]: @} Close defn.
+0020[55]: Text. Text scrap[White]="<010>
+"
+0021[01]: @A New section (Level 1).
+0021[03]: @< Open name.
+0021[05]: Text. Text scrap[Grey]="Error recovery point"
+0021[25]: @> Close name.
+0021[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0023[01]: @$ Macro defn.
+0023[03]: @< Open name.
+0023[05]: Text. Text scrap[Grey]="Error3"
+0023[11]: @> Close name.
+0023[13]: Text. Text scrap[Grey]="+==+"
+0023[17]: @{ Open defn.
+0023[19]: Text. Text scrap[Grey]="No equals in this macro definition."
+0023[54]: @} Close defn.
+0023[56]: Text. Text scrap[White]="<010>
+"
+0024[01]: @A New section (Level 1).
+0024[03]: @< Open name.
+0024[05]: Text. Text scrap[Grey]="Error recovery point"
+0024[25]: @> Close name.
+0024[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0026[01]: @$ Macro defn.
+0026[03]: @< Open name.
+0026[05]: Text. Text scrap[Grey]="Error4"
+0026[11]: @> Close name.
+0026[13]: Text. Text scrap[Grey]="=+"
+0026[15]: @{ Open defn.
+0026[17]: Text. Text scrap[Grey]="No equals in this macro definition."
+0026[52]: @} Close defn.
+0026[54]: Text. Text scrap[White]="<010>
+"
+0027[01]: @A New section (Level 1).
+0027[03]: @< Open name.
+0027[05]: Text. Text scrap[Grey]="Error recovery point"
+0027[25]: @> Close name.
+0027[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0029[01]: @$ Macro defn.
+0029[03]: @< Open name.
+0029[05]: Text. Text scrap[Grey]="Error4"
+0029[11]: @> Close name.
+0029[16]: Text. Text scrap[Grey]="="
+0029[17]: @{ Open defn.
+0029[19]: Text. Text scrap[Grey]="No equals in this macro definition."
+0029[54]: @} Close defn.
+0029[56]: Text. Text scrap[White]="<010>
+"
+0030[01]: @A New section (Level 1).
+0030[03]: @< Open name.
+0030[05]: Text. Text scrap[Grey]="Error recovery point"
+0030[25]: @> Close name.
+0030[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0032[01]: @$ Macro defn.
+0032[03]: @< Open name.
+0032[05]: Text. Text scrap[Grey]="Error4"
+0032[11]: @> Close name.
+0032[13]: Text. Text scrap[White]="<010>
+"
+0032[18]: Text. Text scrap[Grey]="{No equals in this macro definition."
+0032[54]: @} Close defn.
+0032[56]: Text. Text scrap[White]="<010>
+"
+0033[01]: @A New section (Level 1).
+0033[03]: @< Open name.
+0033[05]: Text. Text scrap[Grey]="Error recovery point"
+0033[25]: @> Close name.
+0033[27]: Text. Text scrap[White]="<010>
+<010>
+<010>
+<010>
+"
+0037[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error1"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error2"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error3"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error4"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=1, Pos(L,C)=(7,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="No equals in this macro definition."
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with equals"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=2, Pos(L,C)=(10,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="No equals in this macro definition."
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with plus"
+Defined? : Yes.
+Parameters : 0
+Additive? : Yes.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=3, Pos(L,C)=(13,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="No equals in this macro definition."
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR07: Test the parsing of == and += in macro definitions.<010>
+<010>
+Trip the parser so we don't get any further.<010>
+"
+--- End of Text Scrap List ---
+
+
+TEXT COMPONENT: Pos(L,C)=(4,3).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+1. Test with no equals.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(7,1).
+Part 1 of macro @<Sloth@>.
+
+TEXT COMPONENT: Pos(L,C)=(7,51).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+2. Test with ==.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(10,1).
+Part 1 of macro @<Sloth with equals@>.
+
+TEXT COMPONENT: Pos(L,C)=(10,65).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+3. Test with +=.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(13,1).
+Part 1 of macro @<Sloth with plus@>.
+
+TEXT COMPONENT: Pos(L,C)=(13,63).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+4. Test with syntax errors.<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(18,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(21,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "3", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(24,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(27,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "5", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(30,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "6", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(33,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| PR07: Test the parsing of == and += in macro definitions.
+ 2 2|
+ 3 3| Trip the parser so we don't get any further.
+ 4 4| @>
+ Error|.^The parser was at the top level and was expecting
+ |.^one of: {Directive, Text, Macro definition, EOF}.
+ 5 5|
+ 6 6| 1. Test with no equals.
+ 7 7| @$@<Sloth@>@{No equals in this macro definition.@}
+ 8 8|
+ 9 9| 2. Test with ==.
+ 10 10| @$@<Sloth with equals@>==@{No equals in this macro definition.@}
+ 11 11|
+ 12 12| 3. Test with +=.
+ 13 13| @$@<Sloth with plus@>+=@{No equals in this macro definition.@}
+ 14 14|
+ 15 15| 4. Test with syntax errors.
+ 16 16|
+ 17 17| @$@<Error1@>++@{No equals in this macro definition.@}
+ Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+ |.............^(or @Z or @M if they have not already appeared).
+ |.............^Note: FunnelWeb is intolerant of spaces at this point.
+ |...............^Skipping after error to the next major construct...
+ 18 18| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 19 19|
+ 20 20| @$@<Error2@>@+=@{No equals in this macro definition.@}
+ Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+ |.............^(or @Z or @M if they have not already appeared).
+ |.............^Note: FunnelWeb is intolerant of spaces at this point.
+ |................^Skipping after error to the next major construct...
+ 21 21| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 22 22|
+ 23 23| @$@<Error3@>+==+@{No equals in this macro definition.@}
+ Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+ |.............^(or @Z or @M if they have not already appeared).
+ |.............^Note: FunnelWeb is intolerant of spaces at this point.
+ |.................^Skipping after error to the next major construct...
+ 24 24| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 25 25|
+ 26 26| @$@<Error4@>=+@{No equals in this macro definition.@}
+ Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+ |.............^(or @Z or @M if they have not already appeared).
+ |.............^Note: FunnelWeb is intolerant of spaces at this point.
+ |...............^Skipping after error to the next major construct...
+ 27 27| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 28 28|
+ 29 29| @$@<Error4@>@=@=@{No equals in this macro definition.@}
+ Error|................^Expecting "==@{" or "+=@{" or just "@{".
+ |................^(or @Z or @M if they have not already appeared).
+ |................^Note: FunnelWeb is intolerant of spaces at this point.
+ |.................^Skipping after error to the next major construct...
+ 30 30| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 31 31|
+ 32 32| @$@<Error4@>@+@=@{No equals in this macro definition.@}
+ Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+ |.............^(or @Z or @M if they have not already appeared).
+ |.............^Note: FunnelWeb is intolerant of spaces at this point.
+ |......................................................^Skipping after error to the next major construct...
+ 33 33| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 34 34|
+ 35 35|
+ 36 36|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 7 Errors.
diff --git a/web/funnelAC/answers/pr08.lis b/web/funnelAC/answers/pr08.lis
new file mode 100644
index 0000000000..8d765756ad
--- /dev/null
+++ b/web/funnelAC/answers/pr08.lis
@@ -0,0 +1,1266 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 30 38 3A 20 54 65 73 74 20 73 65 6D 61 6E | PR08: Test seman |
+| 74 69 63 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 | tic checking of |
+| 6D 61 63 72 6F 20 64 65 66 69 6E 69 74 69 6F 6E | macro definition |
+| 73 2E 0A 0A 54 72 69 70 20 70 61 72 73 65 72 20 | s...Trip parser |
+| 74 6F 20 62 65 20 73 75 72 65 20 74 68 61 74 20 | to be sure that |
+| 77 65 20 77 6F 6E 27 74 20 67 65 74 20 61 6E 79 | we won't get any |
+| 20 6F 75 74 70 75 74 20 66 69 6C 65 73 21 0A 40 | output files!.@ |
+| 3E 0A 0A 31 2E 20 46 69 6C 65 20 6D 61 63 72 6F | >..1. File macro |
+| 20 68 61 73 20 70 61 72 61 6D 65 74 65 72 73 2E | has parameters. |
+| 20 45 72 72 6F 72 2E 0A 40 4F 40 3C 53 6C 6F 74 | Error..@O@<Slot |
+| 68 20 31 40 3E 40 28 40 33 40 29 40 7B 57 61 6C | h 1@>@(@3@)@{Wal |
+| 72 75 73 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 | rus@}.@A@<Error |
+| 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 40 3E | recovery point@> |
+| 0A 0A 32 2E 20 46 69 6C 65 20 6D 61 63 72 6F 20 | ..2. File macro |
+| 69 73 20 61 64 64 69 74 69 76 65 2E 20 45 72 72 | is additive. Err |
+| 6F 72 2E 0A 40 4F 40 3C 53 6C 6F 74 68 20 32 40 | or..@O@<Sloth 2@ |
+| 3E 2B 3D 40 7B 57 61 6C 72 75 73 40 7D 0A 40 41 | >+=@{Walrus@}.@A |
+| 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 | @<Error recovery |
+| 20 70 6F 69 6E 74 40 3E 0A 0A 33 2E 20 46 69 6C | point@>..3. Fil |
+| 65 20 6D 61 63 72 6F 20 68 61 73 20 74 6F 6F 20 | e macro has too |
+| 6C 6F 6E 67 20 61 20 6E 61 6D 65 2E 20 54 68 65 | long a name. The |
+| 20 74 65 73 74 20 6E 61 6D 65 20 68 61 73 20 31 | test name has 1 |
+| 32 30 30 20 63 68 61 72 61 63 74 65 72 73 2E 20 | 200 characters. |
+| 45 72 72 2E 0A 4E 6F 74 65 3A 20 54 68 69 73 20 | Err..Note: This |
+| 74 65 73 74 20 63 61 6E 27 74 20 74 65 73 74 20 | test can't test |
+| 74 68 65 20 65 72 72 6F 72 20 6D 65 73 73 61 67 | the error messag |
+| 65 20 69 66 20 74 68 65 20 6D 61 78 69 6D 75 6D | e if the maximum |
+| 20 6C 65 6E 67 74 68 20 6F 66 20 61 0A 6D 61 63 | length of a.mac |
+| 72 6F 20 6E 61 6D 65 20 69 73 20 6C 65 73 73 20 | ro name is less |
+| 74 68 61 6E 20 74 68 65 20 6D 61 78 69 6D 75 6D | than the maximum |
+| 20 6C 65 6E 67 74 68 20 6F 66 20 61 20 66 69 6C | length of a fil |
+| 65 20 6E 61 6D 65 20 61 73 20 74 68 65 20 6E 61 | e name as the na |
+| 6D 65 0A 65 72 72 6F 72 20 69 73 20 63 61 75 67 | me.error is caug |
+| 68 74 20 66 69 72 73 74 2E 0A 40 70 20 6D 61 78 | ht first..@p max |
+| 69 6D 75 6D 5F 69 6E 70 75 74 5F 6C 69 6E 65 5F | imum_input_line_ |
+| 6C 65 6E 67 74 68 20 3D 20 69 6E 66 69 6E 69 74 | length = infinit |
+| 79 0A 40 4F 40 3C 31 32 33 34 35 36 37 38 39 30 | y.@O@<1234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 40 3E 40 7B 40 7D 0A 40 41 40 | 567890@>@{@}.@A@ |
+| 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 | <Error recovery |
+| 70 6F 69 6E 74 40 3E 0A 0A 34 2E 20 46 69 6C 65 | point@>..4. File |
+| 20 6D 61 63 72 6F 20 68 61 73 20 7A 65 72 6F 20 | macro has zero |
+| 6F 72 20 6D 61 6E 79 20 61 74 74 72 69 62 75 74 | or many attribut |
+| 65 73 2E 20 45 72 72 6F 72 2E 0A 40 4F 40 3C 53 | es. Error..@O@<S |
+| 6C 6F 74 68 20 33 40 3E 40 5A 40 7B 57 61 6C 72 | loth 3@>@Z@{Walr |
+| 75 73 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 | us@}.@A@<Error r |
+| 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A | ecovery point@>. |
+| 0A 40 4F 40 3C 53 6C 6F 74 68 20 34 40 3E 40 4D | .@O@<Sloth 4@>@M |
+| 40 7B 57 61 6C 72 75 73 40 7D 0A 40 41 40 3C 45 | @{Walrus@}.@A@<E |
+| 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 70 6F | rror recovery po |
+| 69 6E 74 40 3E 0A 0A 40 4F 40 3C 53 6C 6F 74 68 | int@>..@O@<Sloth |
+| 20 35 40 3E 40 5A 40 4D 40 7B 57 61 6C 72 75 73 | 5@>@Z@M@{Walrus |
+| 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 | @}.@A@<Error rec |
+| 6F 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 35 | overy point@>..5 |
+| 2E 20 50 72 65 76 69 6F 75 73 20 64 65 66 69 6E | . Previous defin |
+| 69 74 69 6F 6E 20 69 73 20 66 75 6C 6C 2C 20 63 | ition is full, c |
+| 75 72 72 65 6E 74 20 69 73 20 61 64 64 69 74 69 | urrent is additi |
+| 76 65 2E 0A 40 24 40 3C 57 61 6C 72 75 73 20 31 | ve..@$@<Walrus 1 |
+| 40 3E 3D 3D 40 7B 53 6C 6F 74 68 40 7D 0A 40 24 | @>==@{Sloth@}.@$ |
+| 40 3C 57 61 6C 72 75 73 20 31 40 3E 2B 3D 40 7B | @<Walrus 1@>+=@{ |
+| 41 61 72 64 76 61 72 6B 40 7D 0A 40 41 40 3C 45 | Aardvark@}.@A@<E |
+| 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 70 6F | rror recovery po |
+| 69 6E 74 40 3E 0A 0A 36 2E 20 50 72 65 76 69 6F | int@>..6. Previo |
+| 75 73 20 64 65 66 69 6E 69 74 69 6F 6E 20 69 73 | us definition is |
+| 20 61 64 64 69 74 69 76 65 2C 20 63 75 72 72 65 | additive, curre |
+| 6E 74 20 69 73 20 66 75 6C 6C 2E 0A 40 24 40 3C | nt is full..@$@< |
+| 57 61 6C 72 75 73 20 32 40 3E 2B 3D 40 7B 53 6C | Walrus 2@>+=@{Sl |
+| 6F 74 68 40 7D 0A 40 24 40 3C 57 61 6C 72 75 73 | oth@}.@$@<Walrus |
+| 20 32 40 3E 3D 3D 40 7B 41 61 72 64 76 61 72 6B | 2@>==@{Aardvark |
+| 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 | @}.@A@<Error rec |
+| 6F 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 37 | overy point@>..7 |
+| 2E 20 4E 6F 6E 2D 66 69 72 73 74 20 62 6F 64 79 | . Non-first body |
+| 20 70 61 72 74 20 6F 66 20 70 61 72 74 69 61 6C | part of partial |
+| 20 68 61 73 20 70 61 72 61 6D 65 74 65 72 2E 0A | has parameter.. |
+| 40 24 40 3C 55 6E 69 63 6F 72 6E 40 3E 40 28 40 | @$@<Unicorn@>@(@ |
+| 33 40 29 2B 3D 40 7B 54 75 72 6B 65 79 40 7D 0A | 3@)+=@{Turkey@}. |
+| 40 24 40 3C 55 6E 69 63 6F 72 6E 40 3E 40 28 40 | @$@<Unicorn@>@(@ |
+| 33 40 29 2B 3D 40 7B 54 75 72 6B 65 79 40 7D 0A | 3@)+=@{Turkey@}. |
+| 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 | @A@<Error recove |
+| 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 38 2E 20 5A | ry point@>..8. Z |
+| 65 72 6F 20 6F 72 20 6D 61 6E 79 20 61 74 74 72 | ero or many attr |
+| 69 62 75 74 65 73 20 6F 6E 20 6E 6F 6E 2D 66 69 | ibutes on non-fi |
+| 72 73 74 20 62 6F 64 79 20 70 61 72 74 20 6F 66 | rst body part of |
+| 20 61 64 64 69 74 69 76 65 2E 0A 40 24 40 3C 45 | additive..@$@<E |
+| 6C 65 70 68 61 6E 74 40 3E 40 5A 40 4D 2B 3D 40 | lephant@>@Z@M+=@ |
+| 7B 54 75 72 6B 65 79 40 7D 0A 40 24 40 3C 45 6C | {Turkey@}.@$@<El |
+| 65 70 68 61 6E 74 40 3E 40 5A 40 4D 2B 3D 40 7B | ephant@>@Z@M+=@{ |
+| 54 75 72 6B 65 79 40 7D 0A 40 41 40 3C 45 72 72 | Turkey@}.@A@<Err |
+| 6F 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E | or recovery poin |
+| 74 40 3E 0A 0A 39 2E 20 43 68 65 63 6B 20 74 68 | t@>..9. Check th |
+| 61 74 20 6E 6F 6E 2D 65 78 69 73 74 65 6E 74 20 | at non-existent |
+| 66 6F 72 6D 61 6C 20 70 61 72 61 6D 65 74 65 72 | formal parameter |
+| 73 20 61 72 65 20 63 61 75 67 68 74 2E 0A 0A 40 | s are caught...@ |
+| 24 40 3C 5A 65 72 6F 40 3E 40 5A 40 7B 53 6C 6F | $@<Zero@>@Z@{Slo |
+| 74 68 40 31 57 61 6C 72 75 73 40 7D 0A 40 41 40 | th@1Walrus@}.@A@ |
+| 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 | <Error recovery |
+| 70 6F 69 6E 74 40 3E 0A 0A 40 24 40 3C 4F 6E 65 | point@>..@$@<One |
+| 40 3E 40 28 40 31 40 29 40 5A 40 7B 53 6C 6F 74 | @>@(@1@)@Z@{Slot |
+| 68 40 32 57 61 6C 72 75 73 40 7D 0A 40 41 40 3C | h@2Walrus@}.@A@< |
+| 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 70 | Error recovery p |
+| 6F 69 6E 74 40 3E 0A 0A 40 24 40 3C 4D 61 6E 79 | oint@>..@$@<Many |
+| 40 3E 40 28 40 37 40 29 40 5A 40 7B 53 6C 6F 74 | @>@(@7@)@Z@{Slot |
+| 68 40 38 57 61 6C 72 75 73 40 7D 0A 40 41 40 3C | h@8Walrus@}.@A@< |
+| 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 70 | Error recovery p |
+| 6F 69 6E 74 40 3E 0A | oint@>. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR08: Test semantic checking of macro definitions.<010>
+00002 00002| <010>
+00003 00003| Trip parser to be sure that we won't get any output files!<010>
+00004 00004| @><010>
+00005 00005| <010>
+00006 00006| 1. File macro has parameters. Error.<010>
+00007 00007| @O@<Sloth 1@>@(@3@)@{Walrus@}<010>
+00008 00008| @A@<Error recovery point@><010>
+00009 00009| <010>
+00010 00010| 2. File macro is additive. Error.<010>
+00011 00011| @O@<Sloth 2@>+=@{Walrus@}<010>
+00012 00012| @A@<Error recovery point@><010>
+00013 00013| <010>
+00014 00014| 3. File macro has too long a name. The test name has 1200 characters. Err.<010>
+00015 00015| Note: This test can't test the error message if the maximum length of a<010>
+00016 00016| macro name is less than the maximum length of a file name as the name<010>
+00017 00017| error is caught first.<010>
+00018 00018| @p maximum_input_line_length = infinity<010>
+00019 00019| @O@<123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890@>@{@}<010>
+00020 00020| @A@<Error recovery point@><010>
+00021 00021| <010>
+00022 00022| 4. File macro has zero or many attributes. Error.<010>
+00023 00023| @O@<Sloth 3@>@Z@{Walrus@}<010>
+00024 00024| @A@<Error recovery point@><010>
+00025 00025| <010>
+00026 00026| @O@<Sloth 4@>@M@{Walrus@}<010>
+00027 00027| @A@<Error recovery point@><010>
+00028 00028| <010>
+00029 00029| @O@<Sloth 5@>@Z@M@{Walrus@}<010>
+00030 00030| @A@<Error recovery point@><010>
+00031 00031| <010>
+00032 00032| 5. Previous definition is full, current is additive.<010>
+00033 00033| @$@<Walrus 1@>==@{Sloth@}<010>
+00034 00034| @$@<Walrus 1@>+=@{Aardvark@}<010>
+00035 00035| @A@<Error recovery point@><010>
+00036 00036| <010>
+00037 00037| 6. Previous definition is additive, current is full.<010>
+00038 00038| @$@<Walrus 2@>+=@{Sloth@}<010>
+00039 00039| @$@<Walrus 2@>==@{Aardvark@}<010>
+00040 00040| @A@<Error recovery point@><010>
+00041 00041| <010>
+00042 00042| 7. Non-first body part of partial has parameter.<010>
+00043 00043| @$@<Unicorn@>@(@3@)+=@{Turkey@}<010>
+00044 00044| @$@<Unicorn@>@(@3@)+=@{Turkey@}<010>
+00045 00045| @A@<Error recovery point@><010>
+00046 00046| <010>
+00047 00047| 8. Zero or many attributes on non-first body part of additive.<010>
+00048 00048| @$@<Elephant@>@Z@M+=@{Turkey@}<010>
+00049 00049| @$@<Elephant@>@Z@M+=@{Turkey@}<010>
+00050 00050| @A@<Error recovery point@><010>
+00051 00051| <010>
+00052 00052| 9. Check that non-existent formal parameters are caught.<010>
+00053 00053| <010>
+00054 00054| @$@<Zero@>@Z@{Sloth@1Walrus@}<010>
+00055 00055| @A@<Error recovery point@><010>
+00056 00056| <010>
+00057 00057| @$@<One@>@(@1@)@Z@{Sloth@2Walrus@}<010>
+00058 00058| @A@<Error recovery point@><010>
+00059 00059| <010>
+00060 00060| @$@<Many@>@(@7@)@Z@{Sloth@8Walrus@}<010>
+00061 00061| @A@<Error recovery point@><010>
+00062 00062| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 245 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR08: Test semantic checking of macro definitions.<010>
+<010>
+Trip parser to be sure that we won't get any output files!<010>
+"
+0004[01]: @> Close name.
+0004[03]: Text. Text scrap[Grey]="<010>
+<010>
+1. File macro has parameters. Error.<010>
+"
+0007[01]: @F File defn.
+0007[03]: @< Open name.
+0007[05]: Text. Text scrap[Grey]="Sloth 1"
+0007[12]: @> Close name.
+0007[14]: @( Open param.
+0007[16]: @n Parameter. Parameterno=3.
+0007[18]: @} Close param.
+0007[20]: @{ Open defn.
+0007[22]: Text. Text scrap[Grey]="Walrus"
+0007[28]: @} Close defn.
+0007[30]: Text. Text scrap[White]="<010>
+"
+0008[01]: @A New section (Level 1).
+0008[03]: @< Open name.
+0008[05]: Text. Text scrap[Grey]="Error recovery point"
+0008[25]: @> Close name.
+0008[27]: Text. Text scrap[Grey]="<010>
+<010>
+2. File macro is additive. Error.<010>
+"
+0011[01]: @F File defn.
+0011[03]: @< Open name.
+0011[05]: Text. Text scrap[Grey]="Sloth 2"
+0011[12]: @> Close name.
+0011[14]: Text. Text scrap[Grey]="+="
+0011[16]: @{ Open defn.
+0011[18]: Text. Text scrap[Grey]="Walrus"
+0011[24]: @} Close defn.
+0011[26]: Text. Text scrap[White]="<010>
+"
+0012[01]: @A New section (Level 1).
+0012[03]: @< Open name.
+0012[05]: Text. Text scrap[Grey]="Error recovery point"
+0012[25]: @> Close name.
+0012[27]: Text. Text scrap[Grey]="<010>
+<010>
+3. File macro has too long a name. The test name has 1200 characters. Err.<010>
+Note: This test can't test the error message if the maximum length of a<010>
+macro name is less than the maximum length of a file name as the name<010>
+error is caught first.<010>
+"
+0019[01]: @F File defn.
+0019[03]: @< Open name.
+0019[05]: Text. Text scrap[Grey]="123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
+0019[1205]: @> Close name.
+0019[1207]: @{ Open defn.
+0019[1209]: @} Close defn.
+0019[1211]: Text. Text scrap[White]="<010>
+"
+0020[01]: @A New section (Level 1).
+0020[03]: @< Open name.
+0020[05]: Text. Text scrap[Grey]="Error recovery point"
+0020[25]: @> Close name.
+0020[27]: Text. Text scrap[Grey]="<010>
+<010>
+4. File macro has zero or many attributes. Error.<010>
+"
+0023[01]: @F File defn.
+0023[03]: @< Open name.
+0023[05]: Text. Text scrap[Grey]="Sloth 3"
+0023[12]: @> Close name.
+0023[14]: @Z Zero calls.
+0023[16]: @{ Open defn.
+0023[18]: Text. Text scrap[Grey]="Walrus"
+0023[24]: @} Close defn.
+0023[26]: Text. Text scrap[White]="<010>
+"
+0024[01]: @A New section (Level 1).
+0024[03]: @< Open name.
+0024[05]: Text. Text scrap[Grey]="Error recovery point"
+0024[25]: @> Close name.
+0024[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0026[01]: @F File defn.
+0026[03]: @< Open name.
+0026[05]: Text. Text scrap[Grey]="Sloth 4"
+0026[12]: @> Close name.
+0026[14]: @M Many calls.
+0026[16]: @{ Open defn.
+0026[18]: Text. Text scrap[Grey]="Walrus"
+0026[24]: @} Close defn.
+0026[26]: Text. Text scrap[White]="<010>
+"
+0027[01]: @A New section (Level 1).
+0027[03]: @< Open name.
+0027[05]: Text. Text scrap[Grey]="Error recovery point"
+0027[25]: @> Close name.
+0027[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0029[01]: @F File defn.
+0029[03]: @< Open name.
+0029[05]: Text. Text scrap[Grey]="Sloth 5"
+0029[12]: @> Close name.
+0029[14]: @Z Zero calls.
+0029[16]: @M Many calls.
+0029[18]: @{ Open defn.
+0029[20]: Text. Text scrap[Grey]="Walrus"
+0029[26]: @} Close defn.
+0029[28]: Text. Text scrap[White]="<010>
+"
+0030[01]: @A New section (Level 1).
+0030[03]: @< Open name.
+0030[05]: Text. Text scrap[Grey]="Error recovery point"
+0030[25]: @> Close name.
+0030[27]: Text. Text scrap[Grey]="<010>
+<010>
+5. Previous definition is full, current is additive.<010>
+"
+0033[01]: @$ Macro defn.
+0033[03]: @< Open name.
+0033[05]: Text. Text scrap[Grey]="Walrus 1"
+0033[13]: @> Close name.
+0033[15]: Text. Text scrap[Grey]="=="
+0033[17]: @{ Open defn.
+0033[19]: Text. Text scrap[Grey]="Sloth"
+0033[24]: @} Close defn.
+0033[26]: Text. Text scrap[White]="<010>
+"
+0034[01]: @$ Macro defn.
+0034[03]: @< Open name.
+0034[05]: Text. Text scrap[Grey]="Walrus 1"
+0034[13]: @> Close name.
+0034[15]: Text. Text scrap[Grey]="+="
+0034[17]: @{ Open defn.
+0034[19]: Text. Text scrap[Grey]="Aardvark"
+0034[27]: @} Close defn.
+0034[29]: Text. Text scrap[White]="<010>
+"
+0035[01]: @A New section (Level 1).
+0035[03]: @< Open name.
+0035[05]: Text. Text scrap[Grey]="Error recovery point"
+0035[25]: @> Close name.
+0035[27]: Text. Text scrap[Grey]="<010>
+<010>
+6. Previous definition is additive, current is full.<010>
+"
+0038[01]: @$ Macro defn.
+0038[03]: @< Open name.
+0038[05]: Text. Text scrap[Grey]="Walrus 2"
+0038[13]: @> Close name.
+0038[15]: Text. Text scrap[Grey]="+="
+0038[17]: @{ Open defn.
+0038[19]: Text. Text scrap[Grey]="Sloth"
+0038[24]: @} Close defn.
+0038[26]: Text. Text scrap[White]="<010>
+"
+0039[01]: @$ Macro defn.
+0039[03]: @< Open name.
+0039[05]: Text. Text scrap[Grey]="Walrus 2"
+0039[13]: @> Close name.
+0039[15]: Text. Text scrap[Grey]="=="
+0039[17]: @{ Open defn.
+0039[19]: Text. Text scrap[Grey]="Aardvark"
+0039[27]: @} Close defn.
+0039[29]: Text. Text scrap[White]="<010>
+"
+0040[01]: @A New section (Level 1).
+0040[03]: @< Open name.
+0040[05]: Text. Text scrap[Grey]="Error recovery point"
+0040[25]: @> Close name.
+0040[27]: Text. Text scrap[Grey]="<010>
+<010>
+7. Non-first body part of partial has parameter.<010>
+"
+0043[01]: @$ Macro defn.
+0043[03]: @< Open name.
+0043[05]: Text. Text scrap[Grey]="Unicorn"
+0043[12]: @> Close name.
+0043[14]: @( Open param.
+0043[16]: @n Parameter. Parameterno=3.
+0043[18]: @} Close param.
+0043[20]: Text. Text scrap[Grey]="+="
+0043[22]: @{ Open defn.
+0043[24]: Text. Text scrap[Grey]="Turkey"
+0043[30]: @} Close defn.
+0043[32]: Text. Text scrap[White]="<010>
+"
+0044[01]: @$ Macro defn.
+0044[03]: @< Open name.
+0044[05]: Text. Text scrap[Grey]="Unicorn"
+0044[12]: @> Close name.
+0044[14]: @( Open param.
+0044[16]: @n Parameter. Parameterno=3.
+0044[18]: @} Close param.
+0044[20]: Text. Text scrap[Grey]="+="
+0044[22]: @{ Open defn.
+0044[24]: Text. Text scrap[Grey]="Turkey"
+0044[30]: @} Close defn.
+0044[32]: Text. Text scrap[White]="<010>
+"
+0045[01]: @A New section (Level 1).
+0045[03]: @< Open name.
+0045[05]: Text. Text scrap[Grey]="Error recovery point"
+0045[25]: @> Close name.
+0045[27]: Text. Text scrap[Grey]="<010>
+<010>
+8. Zero or many attributes on non-first body part of additive.<010>
+"
+0048[01]: @$ Macro defn.
+0048[03]: @< Open name.
+0048[05]: Text. Text scrap[Grey]="Elephant"
+0048[13]: @> Close name.
+0048[15]: @Z Zero calls.
+0048[17]: @M Many calls.
+0048[19]: Text. Text scrap[Grey]="+="
+0048[21]: @{ Open defn.
+0048[23]: Text. Text scrap[Grey]="Turkey"
+0048[29]: @} Close defn.
+0048[31]: Text. Text scrap[White]="<010>
+"
+0049[01]: @$ Macro defn.
+0049[03]: @< Open name.
+0049[05]: Text. Text scrap[Grey]="Elephant"
+0049[13]: @> Close name.
+0049[15]: @Z Zero calls.
+0049[17]: @M Many calls.
+0049[19]: Text. Text scrap[Grey]="+="
+0049[21]: @{ Open defn.
+0049[23]: Text. Text scrap[Grey]="Turkey"
+0049[29]: @} Close defn.
+0049[31]: Text. Text scrap[White]="<010>
+"
+0050[01]: @A New section (Level 1).
+0050[03]: @< Open name.
+0050[05]: Text. Text scrap[Grey]="Error recovery point"
+0050[25]: @> Close name.
+0050[27]: Text. Text scrap[Grey]="<010>
+<010>
+9. Check that non-existent formal parameters are caught.<010>
+<010>
+"
+0054[01]: @$ Macro defn.
+0054[03]: @< Open name.
+0054[05]: Text. Text scrap[Grey]="Zero"
+0054[09]: @> Close name.
+0054[11]: @Z Zero calls.
+0054[13]: @{ Open defn.
+0054[15]: Text. Text scrap[Grey]="Sloth"
+0054[20]: @n Parameter. Parameterno=1.
+0054[22]: Text. Text scrap[Grey]="Walrus"
+0054[28]: @} Close defn.
+0054[30]: Text. Text scrap[White]="<010>
+"
+0055[01]: @A New section (Level 1).
+0055[03]: @< Open name.
+0055[05]: Text. Text scrap[Grey]="Error recovery point"
+0055[25]: @> Close name.
+0055[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0057[01]: @$ Macro defn.
+0057[03]: @< Open name.
+0057[05]: Text. Text scrap[Grey]="One"
+0057[08]: @> Close name.
+0057[10]: @( Open param.
+0057[12]: @n Parameter. Parameterno=1.
+0057[14]: @} Close param.
+0057[16]: @Z Zero calls.
+0057[18]: @{ Open defn.
+0057[20]: Text. Text scrap[Grey]="Sloth"
+0057[25]: @n Parameter. Parameterno=2.
+0057[27]: Text. Text scrap[Grey]="Walrus"
+0057[33]: @} Close defn.
+0057[35]: Text. Text scrap[White]="<010>
+"
+0058[01]: @A New section (Level 1).
+0058[03]: @< Open name.
+0058[05]: Text. Text scrap[Grey]="Error recovery point"
+0058[25]: @> Close name.
+0058[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0060[01]: @$ Macro defn.
+0060[03]: @< Open name.
+0060[05]: Text. Text scrap[Grey]="Many"
+0060[09]: @> Close name.
+0060[11]: @( Open param.
+0060[13]: @n Parameter. Parameterno=7.
+0060[15]: @} Close param.
+0060[17]: @Z Zero calls.
+0060[19]: @{ Open defn.
+0060[21]: Text. Text scrap[Grey]="Sloth"
+0060[26]: @n Parameter. Parameterno=8.
+0060[28]: Text. Text scrap[Grey]="Walrus"
+0060[34]: @} Close defn.
+0060[36]: Text. Text scrap[White]="<010>
+"
+0061[01]: @A New section (Level 1).
+0061[03]: @< Open name.
+0061[05]: Text. Text scrap[Grey]="Error recovery point"
+0061[25]: @> Close name.
+0061[27]: Text. Text scrap[White]="<010>
+"
+0062[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Elephant"
+Defined? : Yes.
+Parameters : 0
+Additive? : Yes.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=4, Pos(L,C)=(48,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Turkey"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Many"
+Defined? : Yes.
+Parameters : 7
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=7, Pos(L,C)=(60,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Sloth"
+------ End Text Element ------
+
+
+-- Start Parameter Element --
+Parameter number=8.
+Parameter is of macro "Many".
+--- End Parameter Element ---
+
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "One"
+Defined? : Yes.
+Parameters : 1
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=6, Pos(L,C)=(57,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Sloth"
+------ End Text Element ------
+
+
+-- Start Parameter Element --
+Parameter number=2.
+Parameter is of macro "One".
+--- End Parameter Element ---
+
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth 1"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth 2"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth 3"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth 4"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth 5"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Unicorn"
+Defined? : Yes.
+Parameters : 3
+Additive? : Yes.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=3, Pos(L,C)=(43,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Turkey"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Walrus 1"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=1, Pos(L,C)=(33,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Sloth"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Walrus 2"
+Defined? : Yes.
+Parameters : 0
+Additive? : Yes.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=2, Pos(L,C)=(38,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Sloth"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Zero"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=5, Pos(L,C)=(54,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Sloth"
+------ End Text Element ------
+
+
+-- Start Parameter Element --
+Parameter number=1.
+Parameter is of macro "Zero".
+--- End Parameter Element ---
+
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR08: Test semantic checking of macro definitions.<010>
+<010>
+Trip parser to be sure that we won't get any output files!<010>
+"
+--- End of Text Scrap List ---
+
+
+TEXT COMPONENT: Pos(L,C)=(4,3).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+1. File macro has parameters. Error.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(8,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+2. File macro is additive. Error.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(12,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+3. File macro has too long a name. The test name has 1200 characters. Err.<010>
+Note: This test can't test the error message if the maximum length of a<010>
+macro name is less than the maximum length of a file name as the name<010>
+error is caught first.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "3", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(20,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+4. File macro has zero or many attributes. Error.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(24,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "5", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(27,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "6", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(30,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+5. Previous definition is full, current is additive.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(33,1).
+Part 1 of macro @<Walrus 1@>.
+
+TEXT COMPONENT: Pos(L,C)=(33,26).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "7", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(35,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+6. Previous definition is additive, current is full.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(38,1).
+Part 1 of macro @<Walrus 2@>.
+
+TEXT COMPONENT: Pos(L,C)=(38,26).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "8", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(40,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+7. Non-first body part of partial has parameter.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(43,1).
+Part 1 of macro @<Unicorn@>.
+
+TEXT COMPONENT: Pos(L,C)=(43,32).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "9", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(45,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+8. Zero or many attributes on non-first body part of additive.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(48,1).
+Part 1 of macro @<Elephant@>.
+
+TEXT COMPONENT: Pos(L,C)=(48,31).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "10", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(50,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+9. Check that non-existent formal parameters are caught.<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(54,1).
+Part 1 of macro @<Zero@>.
+
+TEXT COMPONENT: Pos(L,C)=(54,30).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "11", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(55,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(57,1).
+Part 1 of macro @<One@>.
+
+TEXT COMPONENT: Pos(L,C)=(57,35).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "12", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(58,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(60,1).
+Part 1 of macro @<Many@>.
+
+TEXT COMPONENT: Pos(L,C)=(60,36).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "13", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(61,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| PR08: Test semantic checking of macro definitions.
+ 2 2|
+ 3 3| Trip parser to be sure that we won't get any output files!
+ 4 4| @>
+ Error|.^The parser was at the top level and was expecting
+ |.^one of: {Directive, Text, Macro definition, EOF}.
+ 5 5|
+ 6 6| 1. File macro has parameters. Error.
+ 7 7| @O@<Sloth 1@>@(@3@)@{Walrus@}
+ |...^Macro definition ignored.
+ Error|................^Macros attached to output files cannot be parameterized.
+ |................^Reason: No actual parameters would be available during
+ |................^ output file generation.
+ |....................^Skipping after error to the next major construct...
+ 8 8| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 9 9|
+ 10 10| 2. File macro is additive. Error.
+ 11 11| @O@<Sloth 2@>+=@{Walrus@}
+ |...^Macro definition ignored.
+ Error|..............^Macros attached to output files cannot be additive.
+ |..............^Reason: Preventing this makes it easy to find output
+ |..............^file macros later, because there will be exactly one
+ |..............^@O declaration in the input file for each output file.
+ |..............^To do what you are trying to do, just create an additive
+ |..............^bridging macro, like this:
+ |..............^ @O@<prog.c@>@{@<Bridge@>@}
+ |..............^ @$@<Bridge@>+=@{void stringhack()...@}
+ |..............^ @$@<Bridge@>+=@{main()...@}
+ |................^Skipping after error to the next major construct...
+ 12 12| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 13 13|
+ 14 14| 3. File macro has too long a name. The test name has 1200 characters. Err.
+ 15 15| Note: This test can't test the error message if the maximum length of a
+ 16 16| macro name is less than the maximum length of a file name as the name
+ 17 17| error is caught first.
+ 18 18| @p maximum_input_line_length = infinity
+ 19 19| @O@<123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890@>@{@}
+ Error|.....^Name is too long.
+ |.....^The maximum length of a legal name is 80 characters.
+ |.....^Skipping after error to the next major construct...
+ 20 20| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 21 21|
+ 22 22| 4. File macro has zero or many attributes. Error.
+ 23 23| @O@<Sloth 3@>@Z@{Walrus@}
+ |...^Macro definition ignored.
+ Error|..............^Macros attached to output files cannot have @Z or @M.
+ |..............^Reason: They are always called once to generate their
+ |..............^output file and they cannot be called from other macros.
+ |..............^Hence they are always called exactly once and so there
+ |..............^can be no need for @Z or @M in their declarations.
+ |................^Skipping after error to the next major construct...
+ 24 24| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 25 25|
+ 26 26| @O@<Sloth 4@>@M@{Walrus@}
+ |...^Macro definition ignored.
+ Error|..............^Macros attached to output files cannot have @Z or @M.
+ |..............^Reason: They are always called once to generate their
+ |..............^output file and they cannot be called from other macros.
+ |..............^Hence they are always called exactly once and so there
+ |..............^can be no need for @Z or @M in their declarations.
+ |................^Skipping after error to the next major construct...
+ 27 27| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 28 28|
+ 29 29| @O@<Sloth 5@>@Z@M@{Walrus@}
+ |...^Macro definition ignored.
+ Error|..............^Macros attached to output files cannot have @Z or @M.
+ |..............^Reason: They are always called once to generate their
+ |..............^output file and they cannot be called from other macros.
+ |..............^Hence they are always called exactly once and so there
+ |..............^can be no need for @Z or @M in their declarations.
+ |..................^Skipping after error to the next major construct...
+ 30 30| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 31 31|
+ 32 32| 5. Previous definition is full, current is additive.
+ 33 33| @$@<Walrus 1@>==@{Sloth@}
+ 34 34| @$@<Walrus 1@>+=@{Aardvark@}
+ Error|...^A full definition of this macro appears at line 33.
+ |...^Full and additive definitions of the same macro cannot coexist.
+ |...^Macro definition ignored.
+ |.................^Skipping after error to the next major construct...
+ 35 35| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 36 36|
+ 37 37| 6. Previous definition is additive, current is full.
+ 38 38| @$@<Walrus 2@>+=@{Sloth@}
+ 39 39| @$@<Walrus 2@>==@{Aardvark@}
+ Error|...^An additive definition of this macro appears at line 38.
+ |...^Full and additive definitions of the same macro cannot coexist.
+ |...^Macro definition ignored.
+ |.................^Skipping after error to the next major construct...
+ 40 40| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 41 41|
+ 42 42| 7. Non-first body part of partial has parameter.
+ 43 43| @$@<Unicorn@>@(@3@)+=@{Turkey@}
+ 44 44| @$@<Unicorn@>@(@3@)+=@{Turkey@}
+ |...^Macro definition ignored.
+ Error|................^The formal parameter list of an additive macro
+ |................^must be placed only in the first definition part.
+ |................^The first part of this macro appears at line 43.
+ |......................^Skipping after error to the next major construct...
+ 45 45| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 46 46|
+ 47 47| 8. Zero or many attributes on non-first body part of additive.
+ 48 48| @$@<Elephant@>@Z@M+=@{Turkey@}
+ 49 49| @$@<Elephant@>@Z@M+=@{Turkey@}
+ |...^Macro definition ignored.
+ Error|...............^@Z and @M modifiers for additive macros must
+ |...............^be placed only in the first definition part.
+ |...............^The first part of this macro appears at line 48.
+ |.....................^Skipping after error to the next major construct...
+ 50 50| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 51 51|
+ 52 52| 9. Check that non-existent formal parameters are caught.
+ 53 53|
+ 54 54| @$@<Zero@>@Z@{Sloth@1Walrus@}
+ Error|....................^Macro being defined has only 0 parameters.
+ 55 55| @A@<Error recovery point@>
+ 56 56|
+ 57 57| @$@<One@>@(@1@)@Z@{Sloth@2Walrus@}
+ Error|.........................^Macro being defined has only 1 parameter.
+ 58 58| @A@<Error recovery point@>
+ 59 59|
+ 60 60| @$@<Many@>@(@7@)@Z@{Sloth@8Walrus@}
+ Error|..........................^Macro being defined has only 7 parameters.
+ 61 61| @A@<Error recovery point@>
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 14 Errors.
diff --git a/web/funnelAC/answers/pr09.lis b/web/funnelAC/answers/pr09.lis
new file mode 100644
index 0000000000..a7aab08edb
--- /dev/null
+++ b/web/funnelAC/answers/pr09.lis
@@ -0,0 +1,2133 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 30 39 3A 20 54 65 73 74 20 63 61 6C 6C 73 | PR09: Test calls |
+| 20 61 6E 64 20 61 63 74 75 61 6C 20 70 61 72 61 | and actual para |
+| 6D 65 74 65 72 20 6C 69 73 74 73 2E 0A 0A 46 69 | meter lists...Fi |
+| 72 73 74 20 74 72 69 70 20 75 70 20 74 68 65 20 | rst trip up the |
+| 70 61 72 73 65 72 20 73 6F 20 77 65 20 64 6F 6E | parser so we don |
+| 27 74 20 67 65 74 20 61 6E 79 20 66 75 72 74 68 | 't get any furth |
+| 65 72 2E 0A 40 3E 0A 0A 4E 6F 77 20 64 65 66 69 | er..@>..Now defi |
+| 6E 65 20 73 6F 6D 65 20 6D 61 63 72 6F 73 20 74 | ne some macros t |
+| 6F 20 63 61 6C 6C 2E 20 4E 6F 20 65 72 72 6F 72 | o call. No error |
+| 2E 0A 0A 40 24 40 3C 5A 65 72 6F 40 3E 40 7B 40 | ...@$@<Zero@>@{@ |
+| 7D 0A 40 24 40 3C 4F 6E 65 40 3E 40 28 40 31 40 | }.@$@<One@>@(@1@ |
+| 29 40 7B 40 7D 0A 40 24 40 3C 54 77 6F 40 3E 40 | )@{@}.@$@<Two@>@ |
+| 28 40 32 40 29 40 7B 40 7D 0A 40 24 40 3C 54 68 | (@2@)@{@}.@$@<Th |
+| 72 65 65 40 3E 40 28 40 33 40 29 40 7B 40 7D 0A | ree@>@(@3@)@{@}. |
+| 40 24 40 3C 4E 69 6E 65 40 3E 40 28 40 39 40 29 | @$@<Nine@>@(@9@) |
+| 40 7B 40 7D 0A 40 24 40 23 22 40 7B 40 7D 0A 0A | @{@}.@$@#"@{@}.. |
+| 54 68 65 20 66 6F 6C 6C 6F 77 69 6E 67 20 74 65 | The following te |
+| 73 74 20 63 61 6C 6C 73 20 73 68 6F 75 6C 64 20 | st calls should |
+| 4E 4F 54 20 67 65 6E 65 72 61 74 65 20 61 6E 79 | NOT generate any |
+| 20 65 72 72 6F 72 73 2E 0A 0A 40 24 40 3C 4D 61 | errors...@$@<Ma |
+| 63 72 6F 20 63 6F 6E 74 61 69 6E 69 6E 67 20 74 | cro containing t |
+| 68 65 20 74 65 73 74 20 6D 61 63 72 6F 20 63 61 | he test macro ca |
+| 6C 6C 73 2E 40 3E 3D 3D 40 7B 0A 31 2E 20 54 65 | lls.@>==@{.1. Te |
+| 73 74 20 6D 61 63 72 6F 20 63 61 6C 6C 20 77 69 | st macro call wi |
+| 74 68 20 6E 6F 20 70 61 72 61 6D 65 74 65 72 20 | th no parameter |
+| 6C 69 73 74 2E 0A 40 3C 5A 65 72 6F 40 3E 0A 0A | list..@<Zero@>.. |
+| 32 2E 20 54 65 73 74 20 6D 61 63 72 6F 20 63 61 | 2. Test macro ca |
+| 6C 6C 20 77 69 74 68 20 71 75 69 63 6B 20 6E 61 | ll with quick na |
+| 6D 65 2E 0A 40 23 22 0A 0A 33 2E 20 54 65 73 74 | me..@#"..3. Test |
+| 20 6D 61 63 72 6F 20 63 61 6C 6C 20 77 69 74 68 | macro call with |
+| 20 6F 6E 65 20 70 61 72 61 6D 65 74 65 72 2E 0A | one parameter.. |
+| 40 3C 4F 6E 65 40 3E 40 28 54 6F 75 63 61 6E 40 | @<One@>@(Toucan@ |
+| 29 0A 0A 34 2E 20 54 65 73 74 20 6D 61 63 72 6F | )..4. Test macro |
+| 20 63 61 6C 6C 20 77 69 74 68 20 6D 61 6E 79 20 | call with many |
+| 70 61 72 61 6D 65 74 65 72 73 2E 0A 40 3C 54 77 | parameters..@<Tw |
+| 6F 40 3E 40 28 54 6F 75 63 61 6E 40 2C 54 65 61 | o@>@(Toucan@,Tea |
+| 70 6F 74 40 29 0A 40 3C 54 68 72 65 65 40 3E 40 | pot@).@<Three@>@ |
+| 28 54 6F 75 63 61 6E 40 2C 54 65 61 70 6F 74 40 | (Toucan@,Teapot@ |
+| 2C 57 61 6C 72 75 73 40 29 0A 40 3C 4E 69 6E 65 | ,Walrus@).@<Nine |
+| 40 3E 40 28 54 6F 75 63 61 6E 40 2C 54 65 61 70 | @>@(Toucan@,Teap |
+| 6F 74 40 2C 57 61 6C 72 75 73 40 2C 0A 20 20 20 | ot@,Walrus@,. |
+| 20 20 20 20 20 20 20 54 6F 75 63 61 6E 40 2C 54 | Toucan@,T |
+| 65 61 70 6F 74 40 2C 57 61 6C 72 75 73 40 2C 0A | eapot@,Walrus@,. |
+| 20 20 20 20 20 20 20 20 20 20 54 6F 75 63 61 6E | Toucan |
+| 40 2C 54 65 61 70 6F 74 40 2C 57 61 6C 72 75 73 | @,Teapot@,Walrus |
+| 40 29 0A 0A 35 2E 20 54 65 73 74 20 6D 61 63 72 | @)..5. Test macr |
+| 6F 20 63 61 6C 6C 73 20 77 69 74 68 20 64 6F 75 | o calls with dou |
+| 62 6C 65 20 71 75 6F 74 65 73 20 6F 6E 20 70 61 | ble quotes on pa |
+| 72 61 6D 65 74 65 72 73 2E 0A 40 3C 4F 6E 65 40 | rameters..@<One@ |
+| 3E 40 28 20 40 22 54 6F 75 63 61 6E 40 22 40 29 | >@( @"Toucan@"@) |
+| 0A 40 3C 54 77 6F 40 3E 40 28 40 22 54 6F 75 63 | .@<Two@>@(@"Touc |
+| 61 6E 40 22 20 20 20 40 2C 20 20 20 40 22 54 65 | an@" @, @"Te |
+| 61 70 6F 74 40 22 40 29 0A 40 3C 54 68 72 65 65 | apot@"@).@<Three |
+| 40 3E 40 28 40 22 54 6F 75 63 61 6E 40 22 20 40 | @>@(@"Toucan@" @ |
+| 2C 0A 20 20 20 20 20 20 20 20 20 20 20 40 22 54 | ,. @"T |
+| 65 61 70 6F 74 40 22 20 40 2C 0A 20 20 20 20 20 | eapot@" @,. |
+| 20 20 20 20 20 20 40 22 57 61 6C 72 75 73 40 22 | @"Walrus@" |
+| 20 40 29 0A 40 3C 4E 69 6E 65 40 3E 40 28 20 40 | @).@<Nine@>@( @ |
+| 22 54 6F 75 63 61 6E 40 22 20 40 2C 20 40 22 54 | "Toucan@" @, @"T |
+| 65 61 70 6F 74 40 22 20 40 2C 20 40 22 57 61 6C | eapot@" @, @"Wal |
+| 72 75 73 40 22 20 40 2C 0A 20 20 20 20 20 20 20 | rus@" @,. |
+| 20 20 20 20 40 22 54 6F 75 63 61 6E 40 22 20 40 | @"Toucan@" @ |
+| 2C 20 40 22 54 65 61 70 6F 74 40 22 20 40 2C 20 | , @"Teapot@" @, |
+| 40 22 57 61 6C 72 75 73 40 22 20 40 2C 0A 20 20 | @"Walrus@" @,. |
+| 20 20 20 20 20 20 20 20 20 40 22 54 6F 75 63 61 | @"Touca |
+| 6E 40 22 20 40 2C 20 40 22 54 65 61 70 6F 74 40 | n@" @, @"Teapot@ |
+| 22 20 40 2C 20 40 22 57 61 6C 72 75 73 40 22 20 | " @, @"Walrus@" |
+| 40 29 0A 0A 37 2E 20 54 65 73 74 20 6D 61 63 72 | @)..7. Test macr |
+| 6F 20 63 61 6C 6C 73 20 77 69 74 68 20 6D 69 78 | o calls with mix |
+| 65 64 20 64 6F 75 62 6C 65 20 71 75 6F 74 65 73 | ed double quotes |
+| 20 6F 6E 20 70 61 72 61 6D 65 74 65 72 73 2E 0A | on parameters.. |
+| 40 3C 54 77 6F 40 3E 40 28 40 22 54 6F 75 63 61 | @<Two@>@(@"Touca |
+| 6E 40 22 20 20 20 40 2C 54 65 61 70 6F 74 40 29 | n@" @,Teapot@) |
+| 0A 40 3C 54 68 72 65 65 40 3E 40 28 40 22 54 6F | .@<Three@>@(@"To |
+| 75 63 61 6E 40 22 20 40 2C 0A 20 20 20 20 20 20 | ucan@" @,. |
+| 20 20 20 20 20 40 22 54 65 61 70 6F 74 40 22 20 | @"Teapot@" |
+| 40 2C 57 61 6C 72 75 73 40 29 0A 40 3C 4E 69 6E | @,Walrus@).@<Nin |
+| 65 40 3E 40 28 20 40 22 54 6F 75 63 61 6E 40 22 | e@>@( @"Toucan@" |
+| 20 40 2C 20 40 22 54 65 61 70 6F 74 40 22 20 40 | @, @"Teapot@" @ |
+| 2C 20 20 20 57 61 6C 72 75 73 20 20 20 40 2C 0A | , Walrus @,. |
+| 20 20 20 20 20 20 20 20 20 20 20 40 22 54 6F 75 | @"Tou |
+| 63 61 6E 40 22 20 40 2C 20 20 20 54 65 61 70 6F | can@" @, Teapo |
+| 74 20 20 20 40 2C 20 40 22 57 61 6C 72 75 73 40 | t @, @"Walrus@ |
+| 22 20 40 2C 0A 20 20 20 20 20 20 20 20 20 20 20 | " @,. |
+| 40 22 54 6F 75 63 61 6E 40 22 20 40 2C 20 40 22 | @"Toucan@" @, @" |
+| 54 65 61 70 6F 74 40 22 20 40 2C 20 40 22 57 61 | Teapot@" @, @"Wa |
+| 6C 72 75 73 40 22 20 40 29 0A 0A 40 7D 20 40 21 | lrus@" @)..@} @! |
+| 20 45 6E 64 20 6F 66 20 6D 61 63 72 6F 20 64 65 | End of macro de |
+| 66 69 6E 69 74 69 6F 6E 20 65 6E 63 6C 6F 73 69 | finition enclosi |
+| 6E 67 20 61 6C 6C 20 74 68 65 73 65 20 6C 65 67 | ng all these leg |
+| 61 6C 20 74 65 73 74 73 2E 0A 0A 38 2E 20 54 65 | al tests...8. Te |
+| 73 74 20 6D 61 63 72 6F 20 63 61 6C 6C 73 20 77 | st macro calls w |
+| 69 74 68 20 61 20 76 61 72 69 65 74 79 20 6F 66 | ith a variety of |
+| 20 73 79 6E 74 61 78 20 65 72 72 6F 72 73 20 69 | syntax errors i |
+| 6E 20 70 61 72 61 6D 65 74 65 72 20 6C 69 73 74 | n parameter list |
+| 2E 0A 40 24 40 3C 45 72 72 6F 72 31 40 3E 40 7B | ..@$@<Error1@>@{ |
+| 0A 40 3C 5A 65 72 6F 40 3E 40 28 0A 40 7D 0A 40 | .@<Zero@>@(.@}.@ |
+| 41 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 72 | A@<Error recover |
+| 79 20 70 6F 69 6E 74 40 3E 0A 0A 40 24 40 3C 45 | y point@>..@$@<E |
+| 72 72 6F 72 32 40 3E 40 7B 0A 40 3C 5A 65 72 6F | rror2@>@{.@<Zero |
+| 40 3E 40 29 0A 40 7D 0A 40 41 40 3C 45 72 72 6F | @>@).@}.@A@<Erro |
+| 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 | r recovery point |
+| 40 3E 0A 0A 40 24 40 3C 45 72 72 6F 72 33 40 3E | @>..@$@<Error3@> |
+| 40 7B 0A 40 3C 4F 6E 65 40 3E 40 28 40 22 54 6F | @{.@<One@>@(@"To |
+| 75 63 61 6E 40 29 0A 40 7D 0A 40 41 40 3C 45 72 | ucan@).@}.@A@<Er |
+| 72 6F 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 | ror recovery poi |
+| 6E 74 40 3E 0A 0A 40 24 40 3C 45 72 72 6F 72 34 | nt@>..@$@<Error4 |
+| 40 3E 40 7B 0A 40 3C 4F 6E 65 40 3E 40 28 40 22 | @>@{.@<One@>@(@" |
+| 54 6F 75 63 61 6E 40 22 40 22 53 6C 6F 74 68 40 | Toucan@"@"Sloth@ |
+| 22 40 29 0A 40 7D 0A 40 41 40 3C 45 72 72 6F 72 | "@).@}.@A@<Error |
+| 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 40 | recovery point@ |
+| 3E 0A 0A 40 24 40 3C 45 72 72 6F 72 35 40 3E 40 | >..@$@<Error5@>@ |
+| 7B 0A 40 3C 54 77 6F 40 3E 40 28 40 22 54 6F 75 | {.@<Two@>@(@"Tou |
+| 63 61 6E 40 22 54 65 61 70 6F 74 40 29 0A 40 7D | can@"Teapot@).@} |
+| 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 | .@A@<Error recov |
+| 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 40 24 40 | ery point@>..@$@ |
+| 3C 45 72 72 6F 72 36 40 3E 40 7B 0A 40 3C 54 77 | <Error6@>@{.@<Tw |
+| 6F 40 3E 40 28 40 22 54 6F 75 63 61 6E 40 22 54 | o@>@(@"Toucan@"T |
+| 65 61 70 6F 74 0A 40 7D 0A 40 41 40 3C 45 72 72 | eapot.@}.@A@<Err |
+| 6F 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E | or recovery poin |
+| 74 40 3E 0A 0A 40 24 40 3C 45 72 72 6F 72 37 40 | t@>..@$@<Error7@ |
+| 3E 40 7B 0A 40 3C 54 77 6F 40 3E 40 28 40 22 54 | >@{.@<Two@>@(@"T |
+| 6F 75 63 61 6E 40 22 54 65 61 70 6F 74 0A 40 3C | oucan@"Teapot.@< |
+| 54 68 72 65 65 40 3E 40 28 54 6F 75 63 61 6E 40 | Three@>@(Toucan@ |
+| 2C 0A 20 20 20 20 20 20 20 20 20 20 20 40 22 54 | ,. @"T |
+| 65 61 70 6F 74 40 2C 57 61 6C 72 75 73 0A 0A 40 | eapot@,Walrus..@ |
+| 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F | }.@A@<Error reco |
+| 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A | very point@>.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR09: Test calls and actual parameter lists.<010>
+00002 00002| <010>
+00003 00003| First trip up the parser so we don't get any further.<010>
+00004 00004| @><010>
+00005 00005| <010>
+00006 00006| Now define some macros to call. No error.<010>
+00007 00007| <010>
+00008 00008| @$@<Zero@>@{@}<010>
+00009 00009| @$@<One@>@(@1@)@{@}<010>
+00010 00010| @$@<Two@>@(@2@)@{@}<010>
+00011 00011| @$@<Three@>@(@3@)@{@}<010>
+00012 00012| @$@<Nine@>@(@9@)@{@}<010>
+00013 00013| @$@#"@{@}<010>
+00014 00014| <010>
+00015 00015| The following test calls should NOT generate any errors.<010>
+00016 00016| <010>
+00017 00017| @$@<Macro containing the test macro calls.@>==@{<010>
+00018 00018| 1. Test macro call with no parameter list.<010>
+00019 00019| @<Zero@><010>
+00020 00020| <010>
+00021 00021| 2. Test macro call with quick name.<010>
+00022 00022| @#"<010>
+00023 00023| <010>
+00024 00024| 3. Test macro call with one parameter.<010>
+00025 00025| @<One@>@(Toucan@)<010>
+00026 00026| <010>
+00027 00027| 4. Test macro call with many parameters.<010>
+00028 00028| @<Two@>@(Toucan@,Teapot@)<010>
+00029 00029| @<Three@>@(Toucan@,Teapot@,Walrus@)<010>
+00030 00030| @<Nine@>@(Toucan@,Teapot@,Walrus@,<010>
+00031 00031| Toucan@,Teapot@,Walrus@,<010>
+00032 00032| Toucan@,Teapot@,Walrus@)<010>
+00033 00033| <010>
+00034 00034| 5. Test macro calls with double quotes on parameters.<010>
+00035 00035| @<One@>@( @"Toucan@"@)<010>
+00036 00036| @<Two@>@(@"Toucan@" @, @"Teapot@"@)<010>
+00037 00037| @<Three@>@(@"Toucan@" @,<010>
+00038 00038| @"Teapot@" @,<010>
+00039 00039| @"Walrus@" @)<010>
+00040 00040| @<Nine@>@( @"Toucan@" @, @"Teapot@" @, @"Walrus@" @,<010>
+00041 00041| @"Toucan@" @, @"Teapot@" @, @"Walrus@" @,<010>
+00042 00042| @"Toucan@" @, @"Teapot@" @, @"Walrus@" @)<010>
+00043 00043| <010>
+00044 00044| 7. Test macro calls with mixed double quotes on parameters.<010>
+00045 00045| @<Two@>@(@"Toucan@" @,Teapot@)<010>
+00046 00046| @<Three@>@(@"Toucan@" @,<010>
+00047 00047| @"Teapot@" @,Walrus@)<010>
+00048 00048| @<Nine@>@( @"Toucan@" @, @"Teapot@" @, Walrus @,<010>
+00049 00049| @"Toucan@" @, Teapot @, @"Walrus@" @,<010>
+00050 00050| @"Toucan@" @, @"Teapot@" @, @"Walrus@" @)<010>
+00051 00051| <010>
+00052 00052| @} @! End of macro definition enclosing all these legal tests.<010>
+00053 00053| <010>
+00054 00054| 8. Test macro calls with a variety of syntax errors in parameter list.<010>
+00055 00055| @$@<Error1@>@{<010>
+00056 00056| @<Zero@>@(<010>
+00057 00057| @}<010>
+00058 00058| @A@<Error recovery point@><010>
+00059 00059| <010>
+00060 00060| @$@<Error2@>@{<010>
+00061 00061| @<Zero@>@)<010>
+00062 00062| @}<010>
+00063 00063| @A@<Error recovery point@><010>
+00064 00064| <010>
+00065 00065| @$@<Error3@>@{<010>
+00066 00066| @<One@>@(@"Toucan@)<010>
+00067 00067| @}<010>
+00068 00068| @A@<Error recovery point@><010>
+00069 00069| <010>
+00070 00070| @$@<Error4@>@{<010>
+00071 00071| @<One@>@(@"Toucan@"@"Sloth@"@)<010>
+00072 00072| @}<010>
+00073 00073| @A@<Error recovery point@><010>
+00074 00074| <010>
+00075 00075| @$@<Error5@>@{<010>
+00076 00076| @<Two@>@(@"Toucan@"Teapot@)<010>
+00077 00077| @}<010>
+00078 00078| @A@<Error recovery point@><010>
+00079 00079| <010>
+00080 00080| @$@<Error6@>@{<010>
+00081 00081| @<Two@>@(@"Toucan@"Teapot<010>
+00082 00082| @}<010>
+00083 00083| @A@<Error recovery point@><010>
+00084 00084| <010>
+00085 00085| @$@<Error7@>@{<010>
+00086 00086| @<Two@>@(@"Toucan@"Teapot<010>
+00087 00087| @<Three@>@(Toucan@,<010>
+00088 00088| @"Teapot@,Walrus<010>
+00089 00089| <010>
+00090 00090| @}<010>
+00091 00091| @A@<Error recovery point@><010>
+00092 00092| <010>
+00093 00093| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 467 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR09: Test calls and actual parameter lists.<010>
+<010>
+First trip up the parser so we don't get any further.<010>
+"
+0004[01]: @> Close name.
+0004[03]: Text. Text scrap[Grey]="<010>
+<010>
+Now define some macros to call. No error.<010>
+<010>
+"
+0008[01]: @$ Macro defn.
+0008[03]: @< Open name.
+0008[05]: Text. Text scrap[Grey]="Zero"
+0008[09]: @> Close name.
+0008[11]: @{ Open defn.
+0008[13]: @} Close defn.
+0008[15]: Text. Text scrap[White]="<010>
+"
+0009[01]: @$ Macro defn.
+0009[03]: @< Open name.
+0009[05]: Text. Text scrap[Grey]="One"
+0009[08]: @> Close name.
+0009[10]: @( Open param.
+0009[12]: @n Parameter. Parameterno=1.
+0009[14]: @} Close param.
+0009[16]: @{ Open defn.
+0009[18]: @} Close defn.
+0009[20]: Text. Text scrap[White]="<010>
+"
+0010[01]: @$ Macro defn.
+0010[03]: @< Open name.
+0010[05]: Text. Text scrap[Grey]="Two"
+0010[08]: @> Close name.
+0010[10]: @( Open param.
+0010[12]: @n Parameter. Parameterno=2.
+0010[14]: @} Close param.
+0010[16]: @{ Open defn.
+0010[18]: @} Close defn.
+0010[20]: Text. Text scrap[White]="<010>
+"
+0011[01]: @$ Macro defn.
+0011[03]: @< Open name.
+0011[05]: Text. Text scrap[Grey]="Three"
+0011[10]: @> Close name.
+0011[12]: @( Open param.
+0011[14]: @n Parameter. Parameterno=3.
+0011[16]: @} Close param.
+0011[18]: @{ Open defn.
+0011[20]: @} Close defn.
+0011[22]: Text. Text scrap[White]="<010>
+"
+0012[01]: @$ Macro defn.
+0012[03]: @< Open name.
+0012[05]: Text. Text scrap[Grey]="Nine"
+0012[09]: @> Close name.
+0012[11]: @( Open param.
+0012[13]: @n Parameter. Parameterno=9.
+0012[15]: @} Close param.
+0012[17]: @{ Open defn.
+0012[19]: @} Close defn.
+0012[21]: Text. Text scrap[White]="<010>
+"
+0013[01]: @$ Macro defn.
+0013[03]: @# Name. Character='"'.
+0013[06]: @{ Open defn.
+0013[08]: @} Close defn.
+0013[10]: Text. Text scrap[Grey]="<010>
+<010>
+The following test calls should NOT generate any errors.<010>
+<010>
+"
+0017[01]: @$ Macro defn.
+0017[03]: @< Open name.
+0017[05]: Text. Text scrap[Grey]="Macro containing the test macro calls."
+0017[43]: @> Close name.
+0017[45]: Text. Text scrap[Grey]="=="
+0017[47]: @{ Open defn.
+0017[49]: Text. Text scrap[Grey]="<010>
+1. Test macro call with no parameter list.<010>
+"
+0019[01]: @< Open name.
+0019[03]: Text. Text scrap[Grey]="Zero"
+0019[07]: @> Close name.
+0019[09]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test macro call with quick name.<010>
+"
+0022[01]: @# Name. Character='"'.
+0022[04]: Text. Text scrap[Grey]="<010>
+<010>
+3. Test macro call with one parameter.<010>
+"
+0025[01]: @< Open name.
+0025[03]: Text. Text scrap[Grey]="One"
+0025[06]: @> Close name.
+0025[08]: @( Open param.
+0025[10]: Text. Text scrap[Grey]="Toucan"
+0025[16]: @} Close param.
+0025[18]: Text. Text scrap[Grey]="<010>
+<010>
+4. Test macro call with many parameters.<010>
+"
+0028[01]: @< Open name.
+0028[03]: Text. Text scrap[Grey]="Two"
+0028[06]: @> Close name.
+0028[08]: @( Open param.
+0028[10]: Text. Text scrap[Grey]="Toucan"
+0028[16]: @, Comma.
+0028[18]: Text. Text scrap[Grey]="Teapot"
+0028[24]: @} Close param.
+0028[26]: Text. Text scrap[White]="<010>
+"
+0029[01]: @< Open name.
+0029[03]: Text. Text scrap[Grey]="Three"
+0029[08]: @> Close name.
+0029[10]: @( Open param.
+0029[12]: Text. Text scrap[Grey]="Toucan"
+0029[18]: @, Comma.
+0029[20]: Text. Text scrap[Grey]="Teapot"
+0029[26]: @, Comma.
+0029[28]: Text. Text scrap[Grey]="Walrus"
+0029[34]: @} Close param.
+0029[36]: Text. Text scrap[White]="<010>
+"
+0030[01]: @< Open name.
+0030[03]: Text. Text scrap[Grey]="Nine"
+0030[07]: @> Close name.
+0030[09]: @( Open param.
+0030[11]: Text. Text scrap[Grey]="Toucan"
+0030[17]: @, Comma.
+0030[19]: Text. Text scrap[Grey]="Teapot"
+0030[25]: @, Comma.
+0030[27]: Text. Text scrap[Grey]="Walrus"
+0030[33]: @, Comma.
+0030[35]: Text. Text scrap[Grey]="<010>
+ Toucan"
+0031[17]: @, Comma.
+0031[19]: Text. Text scrap[Grey]="Teapot"
+0031[25]: @, Comma.
+0031[27]: Text. Text scrap[Grey]="Walrus"
+0031[33]: @, Comma.
+0031[35]: Text. Text scrap[Grey]="<010>
+ Toucan"
+0032[17]: @, Comma.
+0032[19]: Text. Text scrap[Grey]="Teapot"
+0032[25]: @, Comma.
+0032[27]: Text. Text scrap[Grey]="Walrus"
+0032[33]: @} Close param.
+0032[35]: Text. Text scrap[Grey]="<010>
+<010>
+5. Test macro calls with double quotes on parameters.<010>
+"
+0035[01]: @< Open name.
+0035[03]: Text. Text scrap[Grey]="One"
+0035[06]: @> Close name.
+0035[08]: @( Open param.
+0035[10]: Text. Text scrap[White]=" "
+0035[11]: @" Quote.
+0035[13]: Text. Text scrap[Grey]="Toucan"
+0035[19]: @" Quote.
+0035[21]: @} Close param.
+0035[23]: Text. Text scrap[White]="<010>
+"
+0036[01]: @< Open name.
+0036[03]: Text. Text scrap[Grey]="Two"
+0036[06]: @> Close name.
+0036[08]: @( Open param.
+0036[10]: @" Quote.
+0036[12]: Text. Text scrap[Grey]="Toucan"
+0036[18]: @" Quote.
+0036[20]: Text. Text scrap[White]=" "
+0036[23]: @, Comma.
+0036[25]: Text. Text scrap[White]=" "
+0036[28]: @" Quote.
+0036[30]: Text. Text scrap[Grey]="Teapot"
+0036[36]: @" Quote.
+0036[38]: @} Close param.
+0036[40]: Text. Text scrap[White]="<010>
+"
+0037[01]: @< Open name.
+0037[03]: Text. Text scrap[Grey]="Three"
+0037[08]: @> Close name.
+0037[10]: @( Open param.
+0037[12]: @" Quote.
+0037[14]: Text. Text scrap[Grey]="Toucan"
+0037[20]: @" Quote.
+0037[22]: Text. Text scrap[White]=" "
+0037[23]: @, Comma.
+0037[25]: Text. Text scrap[White]="<010>
+ "
+0038[12]: @" Quote.
+0038[14]: Text. Text scrap[Grey]="Teapot"
+0038[20]: @" Quote.
+0038[22]: Text. Text scrap[White]=" "
+0038[23]: @, Comma.
+0038[25]: Text. Text scrap[White]="<010>
+ "
+0039[12]: @" Quote.
+0039[14]: Text. Text scrap[Grey]="Walrus"
+0039[20]: @" Quote.
+0039[22]: Text. Text scrap[White]=" "
+0039[23]: @} Close param.
+0039[25]: Text. Text scrap[White]="<010>
+"
+0040[01]: @< Open name.
+0040[03]: Text. Text scrap[Grey]="Nine"
+0040[07]: @> Close name.
+0040[09]: @( Open param.
+0040[11]: Text. Text scrap[White]=" "
+0040[12]: @" Quote.
+0040[14]: Text. Text scrap[Grey]="Toucan"
+0040[20]: @" Quote.
+0040[22]: Text. Text scrap[White]=" "
+0040[23]: @, Comma.
+0040[25]: Text. Text scrap[White]=" "
+0040[26]: @" Quote.
+0040[28]: Text. Text scrap[Grey]="Teapot"
+0040[34]: @" Quote.
+0040[36]: Text. Text scrap[White]=" "
+0040[37]: @, Comma.
+0040[39]: Text. Text scrap[White]=" "
+0040[40]: @" Quote.
+0040[42]: Text. Text scrap[Grey]="Walrus"
+0040[48]: @" Quote.
+0040[50]: Text. Text scrap[White]=" "
+0040[51]: @, Comma.
+0040[53]: Text. Text scrap[White]="<010>
+ "
+0041[12]: @" Quote.
+0041[14]: Text. Text scrap[Grey]="Toucan"
+0041[20]: @" Quote.
+0041[22]: Text. Text scrap[White]=" "
+0041[23]: @, Comma.
+0041[25]: Text. Text scrap[White]=" "
+0041[26]: @" Quote.
+0041[28]: Text. Text scrap[Grey]="Teapot"
+0041[34]: @" Quote.
+0041[36]: Text. Text scrap[White]=" "
+0041[37]: @, Comma.
+0041[39]: Text. Text scrap[White]=" "
+0041[40]: @" Quote.
+0041[42]: Text. Text scrap[Grey]="Walrus"
+0041[48]: @" Quote.
+0041[50]: Text. Text scrap[White]=" "
+0041[51]: @, Comma.
+0041[53]: Text. Text scrap[White]="<010>
+ "
+0042[12]: @" Quote.
+0042[14]: Text. Text scrap[Grey]="Toucan"
+0042[20]: @" Quote.
+0042[22]: Text. Text scrap[White]=" "
+0042[23]: @, Comma.
+0042[25]: Text. Text scrap[White]=" "
+0042[26]: @" Quote.
+0042[28]: Text. Text scrap[Grey]="Teapot"
+0042[34]: @" Quote.
+0042[36]: Text. Text scrap[White]=" "
+0042[37]: @, Comma.
+0042[39]: Text. Text scrap[White]=" "
+0042[40]: @" Quote.
+0042[42]: Text. Text scrap[Grey]="Walrus"
+0042[48]: @" Quote.
+0042[50]: Text. Text scrap[White]=" "
+0042[51]: @} Close param.
+0042[53]: Text. Text scrap[Grey]="<010>
+<010>
+7. Test macro calls with mixed double quotes on parameters.<010>
+"
+0045[01]: @< Open name.
+0045[03]: Text. Text scrap[Grey]="Two"
+0045[06]: @> Close name.
+0045[08]: @( Open param.
+0045[10]: @" Quote.
+0045[12]: Text. Text scrap[Grey]="Toucan"
+0045[18]: @" Quote.
+0045[20]: Text. Text scrap[White]=" "
+0045[23]: @, Comma.
+0045[25]: Text. Text scrap[Grey]="Teapot"
+0045[31]: @} Close param.
+0045[33]: Text. Text scrap[White]="<010>
+"
+0046[01]: @< Open name.
+0046[03]: Text. Text scrap[Grey]="Three"
+0046[08]: @> Close name.
+0046[10]: @( Open param.
+0046[12]: @" Quote.
+0046[14]: Text. Text scrap[Grey]="Toucan"
+0046[20]: @" Quote.
+0046[22]: Text. Text scrap[White]=" "
+0046[23]: @, Comma.
+0046[25]: Text. Text scrap[White]="<010>
+ "
+0047[12]: @" Quote.
+0047[14]: Text. Text scrap[Grey]="Teapot"
+0047[20]: @" Quote.
+0047[22]: Text. Text scrap[White]=" "
+0047[23]: @, Comma.
+0047[25]: Text. Text scrap[Grey]="Walrus"
+0047[31]: @} Close param.
+0047[33]: Text. Text scrap[White]="<010>
+"
+0048[01]: @< Open name.
+0048[03]: Text. Text scrap[Grey]="Nine"
+0048[07]: @> Close name.
+0048[09]: @( Open param.
+0048[11]: Text. Text scrap[White]=" "
+0048[12]: @" Quote.
+0048[14]: Text. Text scrap[Grey]="Toucan"
+0048[20]: @" Quote.
+0048[22]: Text. Text scrap[White]=" "
+0048[23]: @, Comma.
+0048[25]: Text. Text scrap[White]=" "
+0048[26]: @" Quote.
+0048[28]: Text. Text scrap[Grey]="Teapot"
+0048[34]: @" Quote.
+0048[36]: Text. Text scrap[White]=" "
+0048[37]: @, Comma.
+0048[39]: Text. Text scrap[Grey]=" Walrus "
+0048[51]: @, Comma.
+0048[53]: Text. Text scrap[White]="<010>
+ "
+0049[12]: @" Quote.
+0049[14]: Text. Text scrap[Grey]="Toucan"
+0049[20]: @" Quote.
+0049[22]: Text. Text scrap[White]=" "
+0049[23]: @, Comma.
+0049[25]: Text. Text scrap[Grey]=" Teapot "
+0049[37]: @, Comma.
+0049[39]: Text. Text scrap[White]=" "
+0049[40]: @" Quote.
+0049[42]: Text. Text scrap[Grey]="Walrus"
+0049[48]: @" Quote.
+0049[50]: Text. Text scrap[White]=" "
+0049[51]: @, Comma.
+0049[53]: Text. Text scrap[White]="<010>
+ "
+0050[12]: @" Quote.
+0050[14]: Text. Text scrap[Grey]="Toucan"
+0050[20]: @" Quote.
+0050[22]: Text. Text scrap[White]=" "
+0050[23]: @, Comma.
+0050[25]: Text. Text scrap[White]=" "
+0050[26]: @" Quote.
+0050[28]: Text. Text scrap[Grey]="Teapot"
+0050[34]: @" Quote.
+0050[36]: Text. Text scrap[White]=" "
+0050[37]: @, Comma.
+0050[39]: Text. Text scrap[White]=" "
+0050[40]: @" Quote.
+0050[42]: Text. Text scrap[Grey]="Walrus"
+0050[48]: @" Quote.
+0050[50]: Text. Text scrap[White]=" "
+0050[51]: @} Close param.
+0050[53]: Text. Text scrap[White]="<010>
+<010>
+"
+0052[01]: @} Close defn.
+0052[03]: Text. Text scrap[White]=" "
+0053[01]: Text. Text scrap[Grey]="<010>
+8. Test macro calls with a variety of syntax errors in parameter list.<010>
+"
+0055[01]: @$ Macro defn.
+0055[03]: @< Open name.
+0055[05]: Text. Text scrap[Grey]="Error1"
+0055[11]: @> Close name.
+0055[13]: @{ Open defn.
+0055[15]: Text. Text scrap[White]="<010>
+"
+0056[01]: @< Open name.
+0056[03]: Text. Text scrap[Grey]="Zero"
+0056[07]: @> Close name.
+0056[09]: @( Open param.
+0056[11]: Text. Text scrap[White]="<010>
+"
+0057[01]: @} Close defn.
+0057[03]: Text. Text scrap[White]="<010>
+"
+0058[01]: @A New section (Level 1).
+0058[03]: @< Open name.
+0058[05]: Text. Text scrap[Grey]="Error recovery point"
+0058[25]: @> Close name.
+0058[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0060[01]: @$ Macro defn.
+0060[03]: @< Open name.
+0060[05]: Text. Text scrap[Grey]="Error2"
+0060[11]: @> Close name.
+0060[13]: @{ Open defn.
+0060[15]: Text. Text scrap[White]="<010>
+"
+0061[01]: @< Open name.
+0061[03]: Text. Text scrap[Grey]="Zero"
+0061[07]: @> Close name.
+0061[09]: @} Close param.
+0061[11]: Text. Text scrap[White]="<010>
+"
+0062[01]: @} Close defn.
+0062[03]: Text. Text scrap[White]="<010>
+"
+0063[01]: @A New section (Level 1).
+0063[03]: @< Open name.
+0063[05]: Text. Text scrap[Grey]="Error recovery point"
+0063[25]: @> Close name.
+0063[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0065[01]: @$ Macro defn.
+0065[03]: @< Open name.
+0065[05]: Text. Text scrap[Grey]="Error3"
+0065[11]: @> Close name.
+0065[13]: @{ Open defn.
+0065[15]: Text. Text scrap[White]="<010>
+"
+0066[01]: @< Open name.
+0066[03]: Text. Text scrap[Grey]="One"
+0066[06]: @> Close name.
+0066[08]: @( Open param.
+0066[10]: @" Quote.
+0066[12]: Text. Text scrap[Grey]="Toucan"
+0066[18]: @} Close param.
+0066[20]: Text. Text scrap[White]="<010>
+"
+0067[01]: @} Close defn.
+0067[03]: Text. Text scrap[White]="<010>
+"
+0068[01]: @A New section (Level 1).
+0068[03]: @< Open name.
+0068[05]: Text. Text scrap[Grey]="Error recovery point"
+0068[25]: @> Close name.
+0068[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0070[01]: @$ Macro defn.
+0070[03]: @< Open name.
+0070[05]: Text. Text scrap[Grey]="Error4"
+0070[11]: @> Close name.
+0070[13]: @{ Open defn.
+0070[15]: Text. Text scrap[White]="<010>
+"
+0071[01]: @< Open name.
+0071[03]: Text. Text scrap[Grey]="One"
+0071[06]: @> Close name.
+0071[08]: @( Open param.
+0071[10]: @" Quote.
+0071[12]: Text. Text scrap[Grey]="Toucan"
+0071[18]: @" Quote.
+0071[20]: @" Quote.
+0071[22]: Text. Text scrap[Grey]="Sloth"
+0071[27]: @" Quote.
+0071[29]: @} Close param.
+0071[31]: Text. Text scrap[White]="<010>
+"
+0072[01]: @} Close defn.
+0072[03]: Text. Text scrap[White]="<010>
+"
+0073[01]: @A New section (Level 1).
+0073[03]: @< Open name.
+0073[05]: Text. Text scrap[Grey]="Error recovery point"
+0073[25]: @> Close name.
+0073[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0075[01]: @$ Macro defn.
+0075[03]: @< Open name.
+0075[05]: Text. Text scrap[Grey]="Error5"
+0075[11]: @> Close name.
+0075[13]: @{ Open defn.
+0075[15]: Text. Text scrap[White]="<010>
+"
+0076[01]: @< Open name.
+0076[03]: Text. Text scrap[Grey]="Two"
+0076[06]: @> Close name.
+0076[08]: @( Open param.
+0076[10]: @" Quote.
+0076[12]: Text. Text scrap[Grey]="Toucan"
+0076[18]: @" Quote.
+0076[20]: Text. Text scrap[Grey]="Teapot"
+0076[26]: @} Close param.
+0076[28]: Text. Text scrap[White]="<010>
+"
+0077[01]: @} Close defn.
+0077[03]: Text. Text scrap[White]="<010>
+"
+0078[01]: @A New section (Level 1).
+0078[03]: @< Open name.
+0078[05]: Text. Text scrap[Grey]="Error recovery point"
+0078[25]: @> Close name.
+0078[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0080[01]: @$ Macro defn.
+0080[03]: @< Open name.
+0080[05]: Text. Text scrap[Grey]="Error6"
+0080[11]: @> Close name.
+0080[13]: @{ Open defn.
+0080[15]: Text. Text scrap[White]="<010>
+"
+0081[01]: @< Open name.
+0081[03]: Text. Text scrap[Grey]="Two"
+0081[06]: @> Close name.
+0081[08]: @( Open param.
+0081[10]: @" Quote.
+0081[12]: Text. Text scrap[Grey]="Toucan"
+0081[18]: @" Quote.
+0081[20]: Text. Text scrap[Grey]="Teapot<010>
+"
+0082[01]: @} Close defn.
+0082[03]: Text. Text scrap[White]="<010>
+"
+0083[01]: @A New section (Level 1).
+0083[03]: @< Open name.
+0083[05]: Text. Text scrap[Grey]="Error recovery point"
+0083[25]: @> Close name.
+0083[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0085[01]: @$ Macro defn.
+0085[03]: @< Open name.
+0085[05]: Text. Text scrap[Grey]="Error7"
+0085[11]: @> Close name.
+0085[13]: @{ Open defn.
+0085[15]: Text. Text scrap[White]="<010>
+"
+0086[01]: @< Open name.
+0086[03]: Text. Text scrap[Grey]="Two"
+0086[06]: @> Close name.
+0086[08]: @( Open param.
+0086[10]: @" Quote.
+0086[12]: Text. Text scrap[Grey]="Toucan"
+0086[18]: @" Quote.
+0086[20]: Text. Text scrap[Grey]="Teapot<010>
+"
+0087[01]: @< Open name.
+0087[03]: Text. Text scrap[Grey]="Three"
+0087[08]: @> Close name.
+0087[10]: @( Open param.
+0087[12]: Text. Text scrap[Grey]="Toucan"
+0087[18]: @, Comma.
+0087[20]: Text. Text scrap[White]="<010>
+ "
+0088[12]: @" Quote.
+0088[14]: Text. Text scrap[Grey]="Teapot"
+0088[20]: @, Comma.
+0088[22]: Text. Text scrap[Grey]="Walrus<010>
+<010>
+"
+0090[01]: @} Close defn.
+0090[03]: Text. Text scrap[White]="<010>
+"
+0091[01]: @A New section (Level 1).
+0091[03]: @< Open name.
+0091[05]: Text. Text scrap[Grey]="Error recovery point"
+0091[25]: @> Close name.
+0091[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0093[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : """
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+ Call 1: Parameters=0, Sequence num=7, Position(L,C)=(22,1).
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=6, Pos(L,C)=(13,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error1"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error2"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error3"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error4"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error5"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=8, Pos(L,C)=(75,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Two@>
+This invocation has 1 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error6"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error7"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Macro containing the test macro calls."
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=7, Pos(L,C)=(17,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="<010>
+1. Test macro call with no parameter list.<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Zero@>
+No actual parameters.
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[Grey]="<010>
+<010>
+2. Test macro call with quick name.<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<"@>
+No actual parameters.
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[Grey]="<010>
+<010>
+3. Test macro call with one parameter.<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<One@>
+This invocation has 1 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[Grey]="<010>
+<010>
+4. Test macro call with many parameters.<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Two@>
+This invocation has 2 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 2:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Three@>
+This invocation has 3 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 2:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 3:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Nine@>
+This invocation has 9 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 2:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 3:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 4:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="<010>
+ Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 5:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 6:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 7:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="<010>
+ Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 8:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 9:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[Grey]="<010>
+<010>
+5. Test macro calls with double quotes on parameters.<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<One@>
+This invocation has 1 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Two@>
+This invocation has 2 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 2:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Three@>
+This invocation has 3 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 2:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 3:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Nine@>
+This invocation has 9 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 2:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 3:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 4:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 5:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 6:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 7:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 8:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 9:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[Grey]="<010>
+<010>
+7. Test macro calls with mixed double quotes on parameters.<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Two@>
+This invocation has 2 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 2:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Three@>
+This invocation has 3 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 2:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 3:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Nine@>
+This invocation has 9 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 2:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 3:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]=" Walrus "
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 4:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 5:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]=" Teapot "
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 6:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 7:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 8:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 9:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+<010>
+"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Nine"
+Defined? : Yes.
+Parameters : 9
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+ Call 1: Parameters=9, Sequence num=7, Position(L,C)=(30,1).
+ Call 2: Parameters=9, Sequence num=7, Position(L,C)=(40,1).
+ Call 3: Parameters=9, Sequence num=7, Position(L,C)=(48,1).
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=5, Pos(L,C)=(12,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "One"
+Defined? : Yes.
+Parameters : 1
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+ Call 1: Parameters=1, Sequence num=7, Position(L,C)=(25,1).
+ Call 2: Parameters=1, Sequence num=7, Position(L,C)=(35,1).
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=2, Pos(L,C)=(9,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Three"
+Defined? : Yes.
+Parameters : 3
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+ Call 1: Parameters=3, Sequence num=7, Position(L,C)=(29,1).
+ Call 2: Parameters=3, Sequence num=7, Position(L,C)=(37,1).
+ Call 3: Parameters=3, Sequence num=7, Position(L,C)=(46,1).
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=4, Pos(L,C)=(11,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Two"
+Defined? : Yes.
+Parameters : 2
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+ Call 1: Parameters=2, Sequence num=7, Position(L,C)=(28,1).
+ Call 2: Parameters=2, Sequence num=7, Position(L,C)=(36,1).
+ Call 3: Parameters=2, Sequence num=7, Position(L,C)=(45,1).
+ Call 4: Parameters=1, Sequence num=8, Position(L,C)=(76,1).
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=3, Pos(L,C)=(10,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Zero"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+ Call 1: Parameters=0, Sequence num=7, Position(L,C)=(19,1).
+ Call 2: Parameters=0, Sequence num=8, Position(L,C)=(61,1).
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=1, Pos(L,C)=(8,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR09: Test calls and actual parameter lists.<010>
+<010>
+First trip up the parser so we don't get any further.<010>
+"
+--- End of Text Scrap List ---
+
+
+TEXT COMPONENT: Pos(L,C)=(4,3).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+Now define some macros to call. No error.<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(8,1).
+Part 1 of macro @<Zero@>.
+
+TEXT COMPONENT: Pos(L,C)=(8,15).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(9,1).
+Part 1 of macro @<One@>.
+
+TEXT COMPONENT: Pos(L,C)=(9,20).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(10,1).
+Part 1 of macro @<Two@>.
+
+TEXT COMPONENT: Pos(L,C)=(10,20).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(11,1).
+Part 1 of macro @<Three@>.
+
+TEXT COMPONENT: Pos(L,C)=(11,22).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(12,1).
+Part 1 of macro @<Nine@>.
+
+TEXT COMPONENT: Pos(L,C)=(12,21).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(13,1).
+Part 1 of macro @<"@>.
+
+TEXT COMPONENT: Pos(L,C)=(13,10).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+The following test calls should NOT generate any errors.<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(17,1).
+Part 1 of macro @<Macro containing the test macro calls.@>.
+
+TEXT COMPONENT: Pos(L,C)=(52,3).
+
+-- Start of Text Scrap List --
+Text scrap[White]=" "
+Text scrap[Grey]="<010>
+8. Test macro calls with a variety of syntax errors in parameter list.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(58,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(63,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "3", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(68,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(73,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(75,1).
+Part 1 of macro @<Error5@>.
+
+TEXT COMPONENT: Pos(L,C)=(77,3).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "5", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(78,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "6", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(83,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "7", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(91,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| PR09: Test calls and actual parameter lists.
+ 2 2|
+ 3 3| First trip up the parser so we don't get any further.
+ 4 4| @>
+ Error|.^The parser was at the top level and was expecting
+ |.^one of: {Directive, Text, Macro definition, EOF}.
+ 5 5|
+ 6 6| Now define some macros to call. No error.
+ 7 7|
+ 8 8| @$@<Zero@>@{@}
+ 9 9| @$@<One@>@(@1@)@{@}
+ 10 10| @$@<Two@>@(@2@)@{@}
+ 11 11| @$@<Three@>@(@3@)@{@}
+ 12 12| @$@<Nine@>@(@9@)@{@}
+ 13 13| @$@#"@{@}
+ 14 14|
+ 15 15| The following test calls should NOT generate any errors.
+ 16 16|
+ 17 17| @$@<Macro containing the test macro calls.@>==@{
+ 18 18| 1. Test macro call with no parameter list.
+ 19 19| @<Zero@>
+ 20 20|
+ 21 21| 2. Test macro call with quick name.
+ 22 22| @#"
+ 23 23|
+ 24 24| 3. Test macro call with one parameter.
+ 25 25| @<One@>@(Toucan@)
+ 26 26|
+ 27 27| 4. Test macro call with many parameters.
+ 28 28| @<Two@>@(Toucan@,Teapot@)
+ 29 29| @<Three@>@(Toucan@,Teapot@,Walrus@)
+ 30 30| @<Nine@>@(Toucan@,Teapot@,Walrus@,
+ 31 31| Toucan@,Teapot@,Walrus@,
+ 32 32| Toucan@,Teapot@,Walrus@)
+ 33 33|
+ 34 34| 5. Test macro calls with double quotes on parameters.
+ 35 35| @<One@>@( @"Toucan@"@)
+ 36 36| @<Two@>@(@"Toucan@" @, @"Teapot@"@)
+ 37 37| @<Three@>@(@"Toucan@" @,
+ 38 38| @"Teapot@" @,
+ 39 39| @"Walrus@" @)
+ 40 40| @<Nine@>@( @"Toucan@" @, @"Teapot@" @, @"Walrus@" @,
+ 41 41| @"Toucan@" @, @"Teapot@" @, @"Walrus@" @,
+ 42 42| @"Toucan@" @, @"Teapot@" @, @"Walrus@" @)
+ 43 43|
+ 44 44| 7. Test macro calls with mixed double quotes on parameters.
+ 45 45| @<Two@>@(@"Toucan@" @,Teapot@)
+ 46 46| @<Three@>@(@"Toucan@" @,
+ 47 47| @"Teapot@" @,Walrus@)
+ 48 48| @<Nine@>@( @"Toucan@" @, @"Teapot@" @, Walrus @,
+ 49 49| @"Toucan@" @, Teapot @, @"Walrus@" @,
+ 50 50| @"Toucan@" @, @"Teapot@" @, @"Walrus@" @)
+ 51 51|
+ 52 52| @} @! End of macro definition enclosing all these legal tests.
+ 53 53|
+ 54 54| 8. Test macro calls with a variety of syntax errors in parameter list.
+ 55 55| @$@<Error1@>@{
+ 56 56| @<Zero@>@(
+ 57 57| @}
+ Error|.^Expecting @" or @, or @).
+ |.^Skipping after error to the next major construct...
+ 58 58| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 59 59|
+ 60 60| @$@<Error2@>@{
+ 61 61| @<Zero@>@)
+ Error|.........^Expecting '@}'.
+ |.........^Skipping after error to the next major construct...
+ 62 62| @}
+ 63 63| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 64 64|
+ 65 65| @$@<Error3@>@{
+ 66 66| @<One@>@(@"Toucan@)
+ Error|..................^Expecting '@"'.
+ |..................^Skipping after error to the next major construct...
+ 67 67| @}
+ 68 68| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 69 69|
+ 70 70| @$@<Error4@>@{
+ 71 71| @<One@>@(@"Toucan@"@"Sloth@"@)
+ Error|....................^Expecting @, or @).
+ |....................^Skipping after error to the next major construct...
+ 72 72| @}
+ 73 73| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 74 74|
+ 75 75| @$@<Error5@>@{
+ 76 76| @<Two@>@(@"Toucan@"Teapot@)
+ Error|....................^Expecting whitespace text.
+ 77 77| @}
+ 78 78| @A@<Error recovery point@>
+ 79 79|
+ 80 80| @$@<Error6@>@{
+ 81 81| @<Two@>@(@"Toucan@"Teapot
+ Error|....................^Expecting whitespace text.
+ 82 82| @}
+ Error|.^Expecting @, or @).
+ |.^Skipping after error to the next major construct...
+ 83 83| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 84 84|
+ 85 85| @$@<Error7@>@{
+ 86 86| @<Two@>@(@"Toucan@"Teapot
+ Error|....................^Expecting whitespace text.
+ 87 87| @<Three@>@(Toucan@,
+ Error|.^Expecting @, or @).
+ |.^Skipping after error to the next major construct...
+ 88 88| @"Teapot@,Walrus
+ 89 89|
+ 90 90| @}
+ 91 91| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 92 92|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 10 Errors.
diff --git a/web/funnelAC/answers/pr10.lis b/web/funnelAC/answers/pr10.lis
new file mode 100644
index 0000000000..f6d03439d5
--- /dev/null
+++ b/web/funnelAC/answers/pr10.lis
@@ -0,0 +1,396 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 31 30 3A 20 54 65 73 74 20 73 79 6E 74 61 | PR10: Test synta |
+| 63 74 69 63 20 65 72 72 6F 72 20 72 65 63 6F 76 | ctic error recov |
+| 65 72 79 2E 0A 0A 31 2E 20 54 65 73 74 20 72 65 | ery...1. Test re |
+| 63 6F 76 65 72 79 20 61 74 20 74 6F 70 20 70 61 | covery at top pa |
+| 72 73 69 6E 67 20 6C 65 76 65 6C 2E 0A 40 3C 0A | rsing level..@<. |
+| 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 | .@A@<Error recov |
+| 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 32 2E 20 | ery point@>..2. |
+| 54 65 73 74 20 72 65 63 6F 76 65 72 79 20 69 6E | Test recovery in |
+| 73 69 64 65 20 6D 61 63 72 6F 20 64 65 66 69 6E | side macro defin |
+| 69 74 69 6F 6E 2E 0A 0A 40 24 40 3C 53 6C 6F 74 | ition...@$@<Slot |
+| 68 31 40 3E 40 3E 3D 3D 40 7B 0A 57 61 6C 72 75 | h1@>@>==@{.Walru |
+| 73 40 7D 0A 0A 40 24 40 3C 53 6C 6F 74 68 32 40 | s@}..@$@<Sloth2@ |
+| 3E 3D 3D 40 7B 0A 40 3C 57 61 6C 72 75 73 40 3C | >==@{.@<Walrus@< |
+| 0A 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 | .@}.@A@<Error re |
+| 63 6F 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A | covery point@>.. |
+| 33 2E 20 54 65 73 74 20 72 65 63 6F 76 65 72 79 | 3. Test recovery |
+| 20 69 6E 73 69 64 65 20 61 63 74 75 61 6C 20 70 | inside actual p |
+| 61 72 61 6D 65 74 65 72 20 6C 69 73 74 20 69 6E | arameter list in |
+| 20 6D 61 63 72 6F 20 64 65 66 69 6E 69 74 69 6F | macro definitio |
+| 6E 2E 0A 40 24 40 3C 53 6C 6F 74 68 33 40 3E 3D | n..@$@<Sloth3@>= |
+| 3D 40 7B 0A 40 3C 57 61 6C 72 75 73 40 3E 40 28 | =@{.@<Walrus@>@( |
+| 40 22 61 61 72 64 76 61 72 6B 40 3E 0A 40 7D 0A | @"aardvark@>.@}. |
+| 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 | @A@<Error recove |
+| 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 34 2E 20 54 | ry point@>..4. T |
+| 65 73 74 20 45 4F 46 20 69 6E 20 74 68 65 20 6D | est EOF in the m |
+| 69 64 64 6C 65 20 6F 66 20 61 20 63 6F 6D 70 6C | iddle of a compl |
+| 69 63 61 74 65 64 20 63 6F 6E 73 74 72 75 63 74 | icated construct |
+| 2E 0A 54 68 65 20 66 6F 6C 6C 6F 77 69 6E 67 20 | ..The following |
+| 6D 61 6B 65 73 20 74 68 65 20 65 6E 64 20 6F 66 | makes the end of |
+| 20 74 68 65 20 66 69 6C 65 20 6C 6F 6F 6B 65 64 | the file looked |
+| 20 63 68 6F 70 70 65 64 20 6F 66 66 2C 20 62 75 | chopped off, bu |
+| 74 20 69 74 20 69 73 0A 61 63 74 75 61 6C 6C 79 | t it is.actually |
+| 20 69 6E 74 65 6E 74 69 6F 6E 61 6C 2E 0A 40 24 | intentional..@$ |
+| 40 3C 53 6C 6F 74 68 34 40 3E 3D 3D 40 7B 0A 40 | @<Sloth4@>==@{.@ |
+| 3C 57 61 6C 72 75 73 40 3E 40 28 40 22 61 61 72 | <Walrus@>@(@"aar |
+| 64 76 61 0A | dva. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR10: Test syntactic error recovery.<010>
+00002 00002| <010>
+00003 00003| 1. Test recovery at top parsing level.<010>
+00004 00004| @<<010>
+00005 00005| <010>
+00006 00006| @A@<Error recovery point@><010>
+00007 00007| <010>
+00008 00008| 2. Test recovery inside macro definition.<010>
+00009 00009| <010>
+00010 00010| @$@<Sloth1@>@>==@{<010>
+00011 00011| Walrus@}<010>
+00012 00012| <010>
+00013 00013| @$@<Sloth2@>==@{<010>
+00014 00014| @<Walrus@<<010>
+00015 00015| @}<010>
+00016 00016| @A@<Error recovery point@><010>
+00017 00017| <010>
+00018 00018| 3. Test recovery inside actual parameter list in macro definition.<010>
+00019 00019| @$@<Sloth3@>==@{<010>
+00020 00020| @<Walrus@>@(@"aardvark@><010>
+00021 00021| @}<010>
+00022 00022| @A@<Error recovery point@><010>
+00023 00023| <010>
+00024 00024| 4. Test EOF in the middle of a complicated construct.<010>
+00025 00025| The following makes the end of the file looked chopped off, but it is<010>
+00026 00026| actually intentional.<010>
+00027 00027| @$@<Sloth4@>==@{<010>
+00028 00028| @<Walrus@>@(@"aardva<010>
+00029 00029| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 72 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR10: Test syntactic error recovery.<010>
+<010>
+1. Test recovery at top parsing level.<010>
+"
+0004[01]: @< Open name.
+0004[03]: Text. Text scrap[White]="<010>
+<010>
+"
+0006[01]: @A New section (Level 1).
+0006[03]: @< Open name.
+0006[05]: Text. Text scrap[Grey]="Error recovery point"
+0006[25]: @> Close name.
+0006[27]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test recovery inside macro definition.<010>
+<010>
+"
+0010[01]: @$ Macro defn.
+0010[03]: @< Open name.
+0010[05]: Text. Text scrap[Grey]="Sloth1"
+0010[11]: @> Close name.
+0010[13]: @> Close name.
+0010[15]: Text. Text scrap[Grey]="=="
+0010[17]: @{ Open defn.
+0010[19]: Text. Text scrap[Grey]="<010>
+Walrus"
+0011[07]: @} Close defn.
+0011[09]: Text. Text scrap[White]="<010>
+<010>
+"
+0013[01]: @$ Macro defn.
+0013[03]: @< Open name.
+0013[05]: Text. Text scrap[Grey]="Sloth2"
+0013[11]: @> Close name.
+0013[13]: Text. Text scrap[Grey]="=="
+0013[15]: @{ Open defn.
+0013[17]: Text. Text scrap[White]="<010>
+"
+0014[01]: @< Open name.
+0014[03]: Text. Text scrap[Grey]="Walrus"
+0014[09]: @< Open name.
+0014[11]: Text. Text scrap[White]="<010>
+"
+0015[01]: @} Close defn.
+0015[03]: Text. Text scrap[White]="<010>
+"
+0016[01]: @A New section (Level 1).
+0016[03]: @< Open name.
+0016[05]: Text. Text scrap[Grey]="Error recovery point"
+0016[25]: @> Close name.
+0016[27]: Text. Text scrap[Grey]="<010>
+<010>
+3. Test recovery inside actual parameter list in macro definition.<010>
+"
+0019[01]: @$ Macro defn.
+0019[03]: @< Open name.
+0019[05]: Text. Text scrap[Grey]="Sloth3"
+0019[11]: @> Close name.
+0019[13]: Text. Text scrap[Grey]="=="
+0019[15]: @{ Open defn.
+0019[17]: Text. Text scrap[White]="<010>
+"
+0020[01]: @< Open name.
+0020[03]: Text. Text scrap[Grey]="Walrus"
+0020[09]: @> Close name.
+0020[11]: @( Open param.
+0020[13]: @" Quote.
+0020[15]: Text. Text scrap[Grey]="aardvark"
+0020[23]: @> Close name.
+0020[25]: Text. Text scrap[White]="<010>
+"
+0021[01]: @} Close defn.
+0021[03]: Text. Text scrap[White]="<010>
+"
+0022[01]: @A New section (Level 1).
+0022[03]: @< Open name.
+0022[05]: Text. Text scrap[Grey]="Error recovery point"
+0022[25]: @> Close name.
+0022[27]: Text. Text scrap[Grey]="<010>
+<010>
+4. Test EOF in the middle of a complicated construct.<010>
+The following makes the end of the file looked chopped off, but it is<010>
+actually intentional.<010>
+"
+0027[01]: @$ Macro defn.
+0027[03]: @< Open name.
+0027[05]: Text. Text scrap[Grey]="Sloth4"
+0027[11]: @> Close name.
+0027[13]: Text. Text scrap[Grey]="=="
+0027[15]: @{ Open defn.
+0027[17]: Text. Text scrap[White]="<010>
+"
+0028[01]: @< Open name.
+0028[03]: Text. Text scrap[Grey]="Walrus"
+0028[09]: @> Close name.
+0028[11]: @( Open param.
+0028[13]: @" Quote.
+0028[15]: Text. Text scrap[Grey]="aardva<010>
+"
+0029[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth1"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth2"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth3"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth4"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR10: Test syntactic error recovery.<010>
+<010>
+1. Test recovery at top parsing level.<010>
+"
+--- End of Text Scrap List ---
+
+
+TEXT COMPONENT: Pos(L,C)=(4,3).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(6,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+2. Test recovery inside macro definition.<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(16,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+3. Test recovery inside actual parameter list in macro definition.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "3", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(22,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+4. Test EOF in the middle of a complicated construct.<010>
+The following makes the end of the file looked chopped off, but it is<010>
+actually intentional.<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| PR10: Test syntactic error recovery.
+ 2 2|
+ 3 3| 1. Test recovery at top parsing level.
+ 4 4| @<
+ Error|.^The parser was at the top level and was expecting
+ |.^one of: {Directive, Text, Macro definition, EOF}.
+ 5 5|
+ 6 6| @A@<Error recovery point@>
+ 7 7|
+ 8 8| 2. Test recovery inside macro definition.
+ 9 9|
+ 10 10| @$@<Sloth1@>@>==@{
+ Error|.............^Expecting '@{'.
+ |.............^Skipping after error to the next major construct...
+ 11 11| Walrus@}
+ 12 12|
+ 13 13| @$@<Sloth2@>==@{
+ |.^...skipped to here after the error.
+ 14 14| @<Walrus@<
+ Error|.........^Illegal character or symbol in name.
+ |.........^Skipping after error to the next major construct...
+ 15 15| @}
+ 16 16| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 17 17|
+ 18 18| 3. Test recovery inside actual parameter list in macro definition.
+ 19 19| @$@<Sloth3@>==@{
+ 20 20| @<Walrus@>@(@"aardvark@>
+ Error|.......................^Expecting '@"'.
+ |.......................^Skipping after error to the next major construct...
+ 21 21| @}
+ 22 22| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 23 23|
+ 24 24| 4. Test EOF in the middle of a complicated construct.
+ 25 25| The following makes the end of the file looked chopped off, but it is
+ 26 26| actually intentional.
+ 27 27| @$@<Sloth4@>==@{
+ 28 28| @<Walrus@>@(@"aardva
+ | <End-Of-File>
+ Error|.^Expecting '@"'.
+ |.^Skipping after error to the next major construct...
+ |.^...skipped to here after the error.
+------------+-------------------------------------------------------------------
+
+There were 5 Errors.
diff --git a/web/funnelAC/answers/sc01.lis b/web/funnelAC/answers/sc01.lis
new file mode 100644
index 0000000000..63a28eb6b6
--- /dev/null
+++ b/web/funnelAC/answers/sc01.lis
@@ -0,0 +1,35 @@
+FUNNELWEB LISTING FILE
+======================
+
+S: Error opening input file "<<Suppressed>>".
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 1 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+There was 1 Severe error.
diff --git a/web/funnelAC/answers/sc02.lis b/web/funnelAC/answers/sc02.lis
new file mode 100644
index 0000000000..7f0317cff0
--- /dev/null
+++ b/web/funnelAC/answers/sc02.lis
@@ -0,0 +1,57 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 1 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+E: No macros defined.
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ | <End-Of-File>
+ Warning|.^Input file is empty (not a byte in syte)!
+------------+-------------------------------------------------------------------
+
+There were 2 Errors and 1 Warning.
diff --git a/web/funnelAC/answers/sc03.lis b/web/funnelAC/answers/sc03.lis
new file mode 100644
index 0000000000..a00b57f003
--- /dev/null
+++ b/web/funnelAC/answers/sc03.lis
@@ -0,0 +1,68 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 0A | . |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| <010>
+00002 00002| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 2 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[White]="<010>
+"
+0002[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+E: No macros defined.
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+There were 2 Errors.
diff --git a/web/funnelAC/answers/sc04.lis b/web/funnelAC/answers/sc04.lis
new file mode 100644
index 0000000000..e2f5906b5e
--- /dev/null
+++ b/web/funnelAC/answers/sc04.lis
@@ -0,0 +1,71 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 0A 0A | .. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| <010>
+00002 00002| <010>
+00003 00003| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 2 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[White]="<010>
+<010>
+"
+0003[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+E: No macros defined.
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+There were 2 Errors.
diff --git a/web/funnelAC/answers/sc05.lis b/web/funnelAC/answers/sc05.lis
new file mode 100644
index 0000000000..efb602b4d6
--- /dev/null
+++ b/web/funnelAC/answers/sc05.lis
@@ -0,0 +1,72 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 30 35 3A 20 54 68 69 73 20 69 6E 70 75 74 | SC05: This input |
+| 20 66 69 6C 65 20 63 6F 6E 74 61 69 6E 73 20 61 | file contains a |
+| 20 73 69 6E 67 6C 65 20 6C 69 6E 65 20 63 6F 6E | single line con |
+| 74 61 69 6E 69 6E 67 20 74 68 69 73 20 74 65 78 | taining this tex |
+| 74 21 0A | t!. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC05: This input file contains a single line containing this text!<010>
+00002 00002| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 2 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC05: This input file contains a single line containing this text!<010>
+"
+0002[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="SC05: This input file contains a single line containing this text!<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+E: No macros defined.
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+There were 2 Errors.
diff --git a/web/funnelAC/answers/sc06.lis b/web/funnelAC/answers/sc06.lis
new file mode 100644
index 0000000000..a03421049e
--- /dev/null
+++ b/web/funnelAC/answers/sc06.lis
@@ -0,0 +1,91 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 30 36 3A 20 54 65 73 74 20 46 75 6E 6E 65 | SC06: Test Funne |
+| 6C 57 65 62 20 6F 6E 20 61 20 66 69 6C 65 20 77 | lWeb on a file w |
+| 68 6F 73 65 20 6C 61 73 74 20 6C 69 6E 65 20 69 | hose last line i |
+| 73 20 6E 6F 74 20 74 65 72 6D 69 6E 61 74 65 64 | s not terminated |
+| 20 70 72 6F 70 65 72 6C 79 0A 77 69 74 68 20 61 | properly.with a |
+| 6E 20 65 6E 64 20 6F 66 20 6C 69 6E 65 20 6D 61 | n end of line ma |
+| 72 6B 65 72 2E 0A 0A 48 65 72 65 20 69 73 20 74 | rker...Here is t |
+| 68 65 20 69 6D 70 72 6F 70 65 72 20 74 65 72 6D | he improper term |
+| 69 6E 61 74 69 6F 6E 21 2D 2D 2D 2D 3E | ination!----> |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC06: Test FunnelWeb on a file whose last line is not terminated properly<010>
+00002 00002| with an end of line marker.<010>
+00003 00003| <010>
+00004 00004| Here is the improper termination!----><010>
+00005 00005| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 2 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC06: Test FunnelWeb on a file whose last line is not terminated properly<010>
+with an end of line marker.<010>
+<010>
+Here is the improper termination!----><010>
+"
+0005[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="SC06: Test FunnelWeb on a file whose last line is not terminated properly<010>
+with an end of line marker.<010>
+<010>
+Here is the improper termination!----><010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+E: No macros defined.
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC06: Test FunnelWeb on a file whose last line is not terminated properly
+ 2 2| with an end of line marker.
+ 3 3|
+ 4 4| Here is the improper termination!---->
+ | <End-Of-File>
+ Warning|.^The last line of the input file was terminated by EOF.
+ |.^An EOL was inserted at the end of the last line.
+------------+-------------------------------------------------------------------
+
+There were 2 Errors and 1 Warning.
diff --git a/web/funnelAC/answers/sc07.lis b/web/funnelAC/answers/sc07.lis
new file mode 100644
index 0000000000..b4f069ddcf
--- /dev/null
+++ b/web/funnelAC/answers/sc07.lis
@@ -0,0 +1,187 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 30 37 3A 20 50 72 6F 63 65 73 73 69 6E 67 | SC07: Processing |
+| 20 6F 66 20 6C 6F 6E 67 20 6C 69 6E 65 73 2E 0A | of long lines.. |
+| 0A 53 43 30 37 2E 31 3A 20 44 65 74 65 63 74 69 | .SC07.1: Detecti |
+| 6F 6E 20 6F 66 20 61 20 6C 69 6E 65 20 6C 6F 6E | on of a line lon |
+| 67 65 72 20 74 68 61 6E 20 74 68 65 20 64 65 66 | ger than the def |
+| 61 75 6C 74 20 6C 69 6D 69 74 2E 0A 0A 54 68 65 | ault limit...The |
+| 20 64 65 66 61 75 6C 74 20 6C 69 6D 69 74 20 69 | default limit i |
+| 73 20 38 30 20 63 68 61 72 61 63 74 65 72 73 20 | s 80 characters |
+| 73 6F 20 77 65 20 77 69 6C 6C 20 74 65 73 74 20 | so we will test |
+| 6F 6E 20 65 69 74 68 65 72 20 73 69 64 65 20 6F | on either side o |
+| 66 0A 74 68 61 74 3A 0A 20 20 20 20 20 20 20 20 | f.that:. |
+| 20 31 20 20 20 20 20 20 20 20 20 32 20 20 20 20 | 1 2 |
+| 20 20 20 20 20 33 20 20 20 20 20 20 20 20 20 34 | 3 4 |
+| 20 20 20 20 20 20 20 20 20 35 20 20 20 20 20 20 | 5 |
+| 20 20 20 36 20 20 20 20 20 20 20 20 20 37 20 20 | 6 7 |
+| 20 20 20 20 20 20 20 38 0A 31 32 33 34 35 36 37 | 8.1234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 0A 54 68 65 20 61 62 | 234567890.The ab |
+| 6F 76 65 20 73 68 6F 75 6C 64 20 6E 6F 74 20 74 | ove should not t |
+| 72 69 67 67 65 72 20 61 20 22 6C 69 6E 65 20 74 | rigger a "line t |
+| 6F 6F 20 6C 6F 6E 67 20 65 72 72 6F 72 22 2E 20 | oo long error". |
+| 42 75 74 20 74 68 69 73 20 6C 69 6E 65 20 73 68 | But this line sh |
+| 6F 75 6C 64 21 2D 2D 2D 2D 2D 2D 0A 0A 53 43 30 | ould!------..SC0 |
+| 37 2E 33 3A 20 54 65 73 74 20 74 68 65 20 6C 69 | 7.3: Test the li |
+| 6D 69 74 20 73 65 74 20 61 74 20 69 6E 66 69 6E | mit set at infin |
+| 69 74 79 2E 0A 0A 40 70 20 6D 61 78 69 6D 75 6D | ity...@p maximum |
+| 5F 69 6E 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 | _input_line_leng |
+| 74 68 20 3D 20 69 6E 66 69 6E 69 74 79 0A 0A 20 | th = infinity.. |
+| 20 20 20 20 20 20 20 20 31 20 20 20 20 20 20 20 | 1 |
+| 20 20 32 20 20 20 20 20 20 20 20 20 33 20 20 20 | 2 3 |
+| 20 20 20 20 20 20 34 20 20 20 20 20 20 20 20 20 | 4 |
+| 35 20 20 20 20 20 20 20 20 20 36 20 20 20 20 20 | 5 6 |
+| 20 20 20 20 37 20 20 20 20 20 20 20 20 20 38 0A | 7 8. |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 0A 54 68 65 20 61 62 6F 76 65 20 73 68 6F 75 6C | .The above shoul |
+| 64 20 6E 6F 74 20 74 72 69 67 67 65 72 20 61 20 | d not trigger a |
+| 22 6C 69 6E 65 20 74 6F 6F 20 6C 6F 6E 67 20 65 | "line too long e |
+| 72 72 6F 72 22 2E 20 4E 6F 72 20 73 68 6F 75 6C | rror". Nor shoul |
+| 64 20 74 68 69 73 20 6F 6E 65 21 2D 2D 2D 2D 2D | d this one!----- |
+| 2D 2D 0A 0A 53 43 30 37 2E 33 3A 20 54 65 73 74 | --..SC07.3: Test |
+| 20 74 68 65 20 6C 69 6D 69 74 20 73 65 74 20 6C | the limit set l |
+| 6F 77 65 72 2E 0A 0A 40 70 20 6D 61 78 69 6D 75 | ower...@p maximu |
+| 6D 5F 69 6E 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E | m_input_line_len |
+| 67 74 68 20 3D 20 35 30 0A 0A 20 20 20 20 20 20 | gth = 50.. |
+| 20 20 20 31 20 20 20 20 20 20 20 20 20 32 20 20 | 1 2 |
+| 20 20 20 20 20 20 20 33 20 20 20 20 20 20 20 20 | 3 |
+| 20 34 20 20 20 20 20 20 20 20 20 35 0A 31 32 33 | 4 5.123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 0A | 678901234567890. |
+| 4E 6F 20 65 72 72 6F 72 20 66 6F 72 20 74 68 65 | No error for the |
+| 20 61 62 6F 76 65 20 62 75 74 20 74 68 69 73 20 | above but this |
+| 6C 69 6E 65 20 77 69 6C 6C 21 2D 2D 2D 2D 2D 2D | line will!------ |
+| 2D 2D 2D 0A | ---. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC07: Processing of long lines.<010>
+00002 00002| <010>
+00003 00003| SC07.1: Detection of a line longer than the default limit.<010>
+00004 00004| <010>
+00005 00005| The default limit is 80 characters so we will test on either side of<010>
+00006 00006| that:<010>
+00007 00007| 1 2 3 4 5 6 7 8<010>
+00008 00008| 12345678901234567890123456789012345678901234567890123456789012345678901234567890<010>
+00009 00009| The above should not trigger a "line too long error". But this line should!------<010>
+00010 00010| <010>
+00011 00011| SC07.3: Test the limit set at infinity.<010>
+00012 00012| <010>
+00013 00013| @p maximum_input_line_length = infinity<010>
+00014 00014| <010>
+00015 00015| 1 2 3 4 5 6 7 8<010>
+00016 00016| 12345678901234567890123456789012345678901234567890123456789012345678901234567890<010>
+00017 00017| The above should not trigger a "line too long error". Nor should this one!-------<010>
+00018 00018| <010>
+00019 00019| SC07.3: Test the limit set lower.<010>
+00020 00020| <010>
+00021 00021| @p maximum_input_line_length = 50<010>
+00022 00022| <010>
+00023 00023| 1 2 3 4 5<010>
+00024 00024| 12345678901234567890123456789012345678901234567890<010>
+00025 00025| No error for the above but this line will!---------<010>
+00026 00026| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 4 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC07: Processing of long lines.<010>
+<010>
+SC07.1: Detection of a line longer than the default limit.<010>
+<010>
+The default limit is 80 characters so we will test on either side of<010>
+that:<010>
+ 1 2 3 4 5 6 7 8<010>
+12345678901234567890123456789012345678901234567890123456789012345678901234567890<010>
+The above should not trigger a "line too long error". But this line should!------<010>
+<010>
+SC07.3: Test the limit set at infinity.<010>
+<010>
+"
+0014[01]: Text. Text scrap[Grey]="<010>
+ 1 2 3 4 5 6 7 8<010>
+12345678901234567890123456789012345678901234567890123456789012345678901234567890<010>
+The above should not trigger a "line too long error". Nor should this one!-------<010>
+<010>
+SC07.3: Test the limit set lower.<010>
+<010>
+"
+0022[01]: Text. Text scrap[Grey]="<010>
+ 1 2 3 4 5<010>
+12345678901234567890123456789012345678901234567890<010>
+No error for the above but this line will!---------<010>
+"
+0026[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC07: Processing of long lines.
+ 2 2|
+ 3 3| SC07.1: Detection of a line longer than the default limit.
+ 4 4|
+ 5 5| The default limit is 80 characters so we will test on either side of
+ 6 6| that:
+ 7 7| 1 2 3 4 5 6 7 8
+ 8 8| 12345678901234567890123456789012345678901234567890123456789012345678901234567890
+ 9 9| The above should not trigger a "line too long error". But this line should!------
+ Error|.................................................................................^Input line is too long (this character is the first offender).
+ |.................................................................................^Currently, the maximum allowable input line length is 80.
+ |.................................................................................^Note: You can change this using a pragma directive (@p).
+ 10 10|
+ 11 11| SC07.3: Test the limit set at infinity.
+ 12 12|
+ 13 13| @p maximum_input_line_length = infinity
+ 14 14|
+ 15 15| 1 2 3 4 5 6 7 8
+ 16 16| 12345678901234567890123456789012345678901234567890123456789012345678901234567890
+ 17 17| The above should not trigger a "line too long error". Nor should this one!-------
+ 18 18|
+ 19 19| SC07.3: Test the limit set lower.
+ 20 20|
+ 21 21| @p maximum_input_line_length = 50
+ 22 22|
+ 23 23| 1 2 3 4 5
+ 24 24| 12345678901234567890123456789012345678901234567890
+ 25 25| No error for the above but this line will!---------
+ Error|...................................................^Input line is too long (this character is the first offender).
+ |...................................................^Currently, the maximum allowable input line length is 50.
+ |...................................................^Note: You can change this using a pragma directive (@p).
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 2 Errors.
diff --git a/web/funnelAC/answers/sc08.lis b/web/funnelAC/answers/sc08.lis
new file mode 100644
index 0000000000..b12e7d8c30
--- /dev/null
+++ b/web/funnelAC/answers/sc08.lis
@@ -0,0 +1,104 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 30 38 3A 20 44 65 74 65 63 74 69 6F 6E 20 | SC08: Detection |
+| 6F 66 20 74 72 61 69 6C 69 6E 67 20 73 70 61 63 | of trailing spac |
+| 65 73 2E 0A 0A 54 68 69 73 20 6C 69 6E 65 20 68 | es...This line h |
+| 61 73 20 7A 65 72 6F 20 20 74 72 61 69 6C 69 6E | as zero trailin |
+| 67 20 73 70 61 63 65 73 20 7C 0A 54 68 69 73 20 | g spaces |.This |
+| 6C 69 6E 65 20 68 61 73 20 6F 6E 65 20 20 20 74 | line has one t |
+| 72 61 69 6C 69 6E 67 20 73 70 61 63 65 20 20 7C | railing space | |
+| 20 0A 54 68 69 73 20 6C 69 6E 65 20 68 61 73 20 | .This line has |
+| 74 77 6F 20 20 20 74 72 61 69 6C 69 6E 67 20 73 | two trailing s |
+| 70 61 63 65 73 20 7C 20 20 0A 54 68 69 73 20 6C | paces | .This l |
+| 69 6E 65 20 68 61 73 20 74 68 72 65 65 20 74 72 | ine has three tr |
+| 61 69 6C 69 6E 67 20 73 70 61 63 65 73 20 7C 20 | ailing spaces | |
+| 20 20 0A | . |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC08: Detection of trailing spaces.<010>
+00002 00002| <010>
+00003 00003| This line has zero trailing spaces |<010>
+00004 00004| This line has one trailing space | <010>
+00005 00005| This line has two trailing spaces | <010>
+00006 00006| This line has three trailing spaces | <010>
+00007 00007| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 2 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC08: Detection of trailing spaces.<010>
+<010>
+This line has zero trailing spaces |<010>
+This line has one trailing space | <010>
+This line has two trailing spaces | <010>
+This line has three trailing spaces | <010>
+"
+0007[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="SC08: Detection of trailing spaces.<010>
+<010>
+This line has zero trailing spaces |<010>
+This line has one trailing space | <010>
+This line has two trailing spaces | <010>
+This line has three trailing spaces | <010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+E: No macros defined.
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC08: Detection of trailing spaces.
+ 2 2|
+ 3 3| This line has zero trailing spaces |
+ 4 4| This line has one trailing space |
+ Warning|......................................^Line has trailing spaces up to and including this space.
+ 5 5| This line has two trailing spaces |
+ Warning|.......................................^Line has trailing spaces up to and including this space.
+ 6 6| This line has three trailing spaces |
+ Warning|........................................^Line has trailing spaces up to and including this space.
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 2 Errors and 3 Warnings.
diff --git a/web/funnelAC/answers/sc09.lis b/web/funnelAC/answers/sc09.lis
new file mode 100644
index 0000000000..eeea2f8c82
--- /dev/null
+++ b/web/funnelAC/answers/sc09.lis
@@ -0,0 +1,106 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 30 39 3A 20 44 65 74 65 63 74 69 6F 6E 20 | SC09: Detection |
+| 6F 66 20 63 6F 6E 74 72 6F 6C 20 63 68 61 72 61 | of control chara |
+| 63 74 65 72 73 2E 0A 0A 53 43 30 39 2E 31 20 54 | cters...SC09.1 T |
+| 65 73 74 20 74 68 61 74 20 63 6F 6E 74 72 6F 6C | est that control |
+| 20 63 68 61 72 61 63 74 65 72 73 20 61 72 65 20 | characters are |
+| 64 65 74 65 63 74 65 64 20 61 6E 64 20 72 65 70 | detected and rep |
+| 6C 61 63 65 64 20 62 79 20 22 3F 22 2E 0A 53 43 | laced by "?"..SC |
+| 30 39 2E 32 20 54 65 73 74 20 6E 6F 6E 20 70 72 | 09.2 Test non pr |
+| 69 6E 74 61 62 6C 65 20 74 68 61 74 20 68 61 73 | intable that has |
+| 20 61 20 6D 6E 65 6D 6F 6E 69 63 2E 0A 0A 54 68 | a mnemonic...Th |
+| 65 72 65 20 69 73 20 61 20 74 61 62 20 62 65 74 | ere is a tab bet |
+| 77 65 65 6E 20 74 68 65 73 65 20 74 77 6F 20 62 | ween these two b |
+| 61 72 73 20 7C 09 7C 20 77 68 69 63 68 20 73 68 | ars |.| which sh |
+| 6F 75 6C 64 20 63 6F 6D 65 20 6F 75 74 20 61 73 | ould come out as |
+| 20 22 3F 22 2E 0A 54 68 65 20 61 62 6F 76 65 20 | "?"..The above |
+| 65 72 72 6F 72 20 6D 65 73 73 61 67 65 20 73 68 | error message sh |
+| 6F 75 6C 64 20 63 6F 6E 74 61 69 6E 20 74 68 65 | ould contain the |
+| 20 6D 6E 65 6D 6F 6E 69 63 20 22 48 54 22 2E 0A | mnemonic "HT".. |
+| 0A 53 43 30 39 2E 33 20 54 65 73 74 20 6E 6F 6E | .SC09.3 Test non |
+| 20 70 72 69 6E 74 61 62 6C 65 20 74 68 61 74 20 | printable that |
+| 68 61 73 20 6E 6F 20 6D 6E 65 6D 6F 6E 69 63 2E | has no mnemonic. |
+| 0A 0A 54 68 65 72 65 20 69 73 20 61 20 6E 6F 6E | ..There is a non |
+| 2D 6D 6E 65 6D 6F 6E 69 63 20 63 6F 6E 74 72 6F | -mnemonic contro |
+| 6C 20 63 68 61 72 61 63 74 65 72 20 62 65 74 77 | l character betw |
+| 65 65 6E 20 74 68 65 73 65 20 62 61 72 73 20 7C | een these bars | |
+| EA 7C 2E 0A | .|.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC09: Detection of control characters.<010>
+00002 00002| <010>
+00003 00003| SC09.1 Test that control characters are detected and replaced by "?".<010>
+00004 00004| SC09.2 Test non printable that has a mnemonic.<010>
+00005 00005| <010>
+00006 00006| There is a tab between these two bars |?| which should come out as "?".<010>
+00007 00007| The above error message should contain the mnemonic "HT".<010>
+00008 00008| <010>
+00009 00009| SC09.3 Test non printable that has no mnemonic.<010>
+00010 00010| <010>
+00011 00011| There is a non-mnemonic control character between these bars |?|.<010>
+00012 00012| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 2 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC09: Detection of control characters.<010>
+<010>
+SC09.1 Test that control characters are detected and replaced by "?".<010>
+SC09.2 Test non printable that has a mnemonic.<010>
+<010>
+There is a tab between these two bars |?| which should come out as "?".<010>
+The above error message should contain the mnemonic "HT".<010>
+<010>
+SC09.3 Test non printable that has no mnemonic.<010>
+<010>
+There is a non-mnemonic control character between these bars |?|.<010>
+"
+0012[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC09: Detection of control characters.
+ 2 2|
+ 3 3| SC09.1 Test that control characters are detected and replaced by "?".
+ 4 4| SC09.2 Test non printable that has a mnemonic.
+ 5 5|
+ 6 6| There is a tab between these two bars |?| which should come out as "?".
+ Error|........................................^Non printable character (Sym=HT, Dec=009, Hex=09, Oct=011).
+ 7 7| The above error message should contain the mnemonic "HT".
+ 8 8|
+ 9 9| SC09.3 Test non printable that has no mnemonic.
+ 10 10|
+ 11 11| There is a non-mnemonic control character between these bars |?|.
+ Error|...............................................................^Non printable character (Sym=<none>, Dec=234, Hex=EA, Oct=352).
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 2 Errors.
diff --git a/web/funnelAC/answers/sc10.lis b/web/funnelAC/answers/sc10.lis
new file mode 100644
index 0000000000..91c73ab487
--- /dev/null
+++ b/web/funnelAC/answers/sc10.lis
@@ -0,0 +1,864 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 63 61 6E 6E 65 72 20 54 65 73 74 3A 20 53 70 | Scanner Test: Sp |
+| 65 63 69 61 6C 20 53 65 71 75 65 6E 63 65 20 52 | ecial Sequence R |
+| 65 63 6F 67 6E 69 74 69 6F 6E 0A 3D 3D 3D 3D 3D | ecognition.===== |
+| 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D | ================ |
+| 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D | ================ |
+| 3D 3D 3D 3D 3D 0A 54 68 69 73 20 74 65 73 74 20 | =====.This test |
+| 74 65 73 74 73 20 74 6F 20 73 65 65 20 74 68 61 | tests to see tha |
+| 74 20 46 75 6E 6E 65 6C 57 65 62 20 69 73 20 72 | t FunnelWeb is r |
+| 65 63 6F 67 6E 69 73 69 6E 67 20 74 68 65 20 66 | ecognising the f |
+| 75 6C 6C 20 73 65 74 20 6F 66 20 73 70 65 63 69 | ull set of speci |
+| 61 6C 0A 73 65 71 75 65 6E 63 65 73 2E 0A 0A 54 | al.sequences...T |
+| 75 72 6E 20 4F 66 66 20 74 68 65 20 50 61 72 73 | urn Off the Pars |
+| 65 72 0A 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D | er.------------- |
+| 2D 2D 2D 2D 2D 2D 0A 46 69 72 73 74 20 77 65 20 | ------.First we |
+| 63 61 75 73 65 20 61 20 64 65 6C 69 62 65 72 61 | cause a delibera |
+| 74 65 20 73 63 61 6E 6E 65 72 20 65 72 72 6F 72 | te scanner error |
+| 20 73 6F 20 61 73 20 74 6F 20 70 72 65 76 65 6E | so as to preven |
+| 74 20 74 68 65 20 70 61 72 73 65 72 20 66 72 6F | t the parser fro |
+| 6D 0A 67 65 6E 65 72 61 74 69 6E 67 20 6C 6F 74 | m.generating lot |
+| 73 20 6F 66 20 65 72 72 6F 72 73 20 6F 76 65 72 | s of errors over |
+| 20 74 68 65 20 73 79 6E 74 61 63 74 69 63 20 72 | the syntactic r |
+| 75 62 62 69 73 68 20 70 72 65 73 65 6E 74 65 64 | ubbish presented |
+| 20 68 65 72 65 2E 0A 0A 20 20 20 40 20 0A 0A 4C | here... @ ..L |
+| 69 73 74 20 6F 66 20 41 6C 6C 20 50 6F 73 73 69 | ist of All Possi |
+| 62 6C 65 20 53 70 65 63 69 61 6C 20 53 65 71 75 | ble Special Sequ |
+| 65 6E 63 65 73 0A 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D | ences.---------- |
+| 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D | ---------------- |
+| 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 0A 54 68 65 | ------------.The |
+| 20 66 6F 6C 6C 6F 77 69 6E 67 20 69 73 20 61 20 | following is a |
+| 6C 69 73 74 20 6F 66 20 74 68 65 20 64 65 66 61 | list of the defa |
+| 75 6C 74 20 73 70 65 63 69 61 6C 20 63 68 61 72 | ult special char |
+| 61 63 74 65 72 20 66 6F 6C 6C 6F 77 65 64 20 62 | acter followed b |
+| 79 20 65 61 63 68 20 6F 66 0A 74 68 65 20 41 53 | y each of.the AS |
+| 43 49 49 20 70 72 69 6E 74 61 62 6C 65 73 2E 0A | CII printables.. |
+| 30 30 30 20 74 6F 20 30 33 31 20 61 72 65 20 75 | 000 to 031 are u |
+| 6E 70 72 69 6E 74 61 62 6C 65 20 63 6F 6E 74 72 | nprintable contr |
+| 6F 6C 20 63 68 61 72 61 63 74 65 72 73 2E 0A 0A | ol characters... |
+| 30 33 32 20 20 40 20 20 20 20 2D 20 49 4C 4C 45 | 032 @ - ILLE |
+| 47 41 4C 2E 20 20 28 4E 6F 74 65 3A 20 48 79 70 | GAL. (Note: Hyp |
+| 68 65 6E 20 69 73 20 6E 65 65 64 65 64 20 74 6F | hen is needed to |
+| 20 61 76 6F 69 64 20 74 72 61 69 6C 69 6E 67 20 | avoid trailing |
+| 62 6C 61 6E 6B 73 20 65 72 72 6F 72 2E 29 0A 30 | blanks error.).0 |
+| 33 33 20 20 40 21 20 20 20 2D 20 43 6F 6D 6D 65 | 33 @! - Comme |
+| 6E 74 2E 0A 30 33 34 20 20 40 22 20 20 20 2D 20 | nt..034 @" - |
+| 50 61 72 61 6D 65 74 65 72 20 64 65 6C 69 6D 65 | Parameter delime |
+| 74 65 72 2E 0A 30 33 35 20 20 40 23 58 20 20 2D | ter..035 @#X - |
+| 20 53 68 6F 72 74 20 6E 61 6D 65 20 73 65 71 75 | Short name sequ |
+| 65 6E 63 65 2E 0A 40 24 20 20 20 30 33 36 20 20 | ence..@$ 036 |
+| 2D 20 44 65 66 69 6E 65 20 6D 61 63 72 6F 2E 20 | - Define macro. |
+| 48 61 73 20 74 6F 20 62 65 20 61 74 20 73 74 61 | Has to be at sta |
+| 72 74 20 6F 66 20 6C 69 6E 65 2E 0A 30 33 37 20 | rt of line..037 |
+| 20 40 25 20 20 20 2D 20 49 4C 4C 45 47 41 4C 2E | @% - ILLEGAL. |
+| 0A 30 33 38 20 20 40 26 20 20 20 2D 20 49 4C 4C | .038 @& - ILL |
+| 45 47 41 4C 2E 0A 30 33 39 20 20 40 27 20 20 20 | EGAL..039 @' |
+| 2D 20 49 4C 4C 45 47 41 4C 2E 0A 30 34 30 20 20 | - ILLEGAL..040 |
+| 40 28 20 20 20 2D 20 4F 70 65 6E 20 70 61 72 61 | @( - Open para |
+| 6D 65 74 65 72 20 6C 69 73 74 2E 0A 30 34 31 20 | meter list..041 |
+| 20 40 29 20 20 20 2D 20 43 6C 6F 73 65 20 70 61 | @) - Close pa |
+| 72 61 6D 65 74 65 72 20 6C 69 73 74 2E 0A 30 34 | rameter list..04 |
+| 32 0A 40 2A 20 20 20 20 20 20 20 20 2D 20 4F 6C | 2.@* - Ol |
+| 64 20 66 61 73 68 69 6F 6E 65 64 20 73 65 63 74 | d fashioned sect |
+| 69 6F 6E 20 6D 61 72 6B 65 72 20 28 68 61 73 20 | ion marker (has |
+| 74 6F 20 62 65 20 61 74 20 73 74 61 72 74 20 6F | to be at start o |
+| 66 20 61 20 6C 69 6E 65 2E 29 2E 0A 30 34 33 20 | f a line.)..043 |
+| 20 40 2B 20 20 20 2D 20 49 6E 73 65 72 74 20 6E | @+ - Insert n |
+| 65 77 6C 69 6E 65 2E 0A 30 34 34 20 20 40 2C 20 | ewline..044 @, |
+| 20 20 2D 20 50 61 72 61 6D 65 74 65 72 20 73 65 | - Parameter se |
+| 70 61 72 61 74 6F 72 2E 0A 30 34 35 20 20 40 2D | parator..045 @- |
+| 0A 20 20 20 20 20 20 20 20 20 20 2D 20 49 67 6E | . - Ign |
+| 6F 72 65 20 65 6E 64 20 6F 66 20 6C 69 6E 65 20 | ore end of line |
+| 6D 61 72 6B 65 72 20 28 68 61 73 20 74 6F 20 62 | marker (has to b |
+| 65 20 61 74 20 65 6E 64 20 6F 66 20 6C 69 6E 65 | e at end of line |
+| 29 2E 0A 30 34 36 20 20 40 2E 20 20 20 2D 20 49 | )..046 @. - I |
+| 4C 4C 45 47 41 4C 2E 0A 30 34 37 20 20 40 2F 20 | LLEGAL..047 @/ |
+| 20 20 2D 20 45 6D 70 68 61 73 69 73 65 64 20 74 | - Emphasised t |
+| 65 78 74 2E 0A 30 34 38 20 20 40 30 20 20 20 2D | ext..048 @0 - |
+| 20 49 4C 4C 45 47 41 4C 2E 0A 30 34 39 20 20 40 | ILLEGAL..049 @ |
+| 31 20 20 20 2D 20 46 6F 72 6D 61 6C 20 70 61 72 | 1 - Formal par |
+| 61 6D 65 74 65 72 20 31 2E 0A 30 35 30 20 20 40 | ameter 1..050 @ |
+| 32 20 20 20 2D 20 46 6F 72 6D 61 6C 20 70 61 72 | 2 - Formal par |
+| 61 6D 65 74 65 72 20 32 2E 0A 30 35 31 20 20 40 | ameter 2..051 @ |
+| 33 20 20 20 2D 20 46 6F 72 6D 61 6C 20 70 61 72 | 3 - Formal par |
+| 61 6D 65 74 65 72 20 33 2E 0A 30 35 32 20 20 40 | ameter 3..052 @ |
+| 34 20 20 20 2D 20 46 6F 72 6D 61 6C 20 70 61 72 | 4 - Formal par |
+| 61 6D 65 74 65 72 20 34 2E 0A 30 35 33 20 20 40 | ameter 4..053 @ |
+| 35 20 20 20 2D 20 46 6F 72 6D 61 6C 20 70 61 72 | 5 - Formal par |
+| 61 6D 65 74 65 72 20 35 2E 0A 30 35 34 20 20 40 | ameter 5..054 @ |
+| 36 20 20 20 2D 20 46 6F 72 6D 61 6C 20 70 61 72 | 6 - Formal par |
+| 61 6D 65 74 65 72 20 36 2E 0A 30 35 35 20 20 40 | ameter 6..055 @ |
+| 37 20 20 20 2D 20 46 6F 72 6D 61 6C 20 70 61 72 | 7 - Formal par |
+| 61 6D 65 74 65 72 20 37 2E 0A 30 35 36 20 20 40 | ameter 7..056 @ |
+| 38 20 20 20 2D 20 46 6F 72 6D 61 6C 20 70 61 72 | 8 - Formal par |
+| 61 6D 65 74 65 72 20 38 2E 0A 30 35 37 20 20 40 | ameter 8..057 @ |
+| 39 20 20 20 2D 20 46 6F 72 6D 61 6C 20 70 61 72 | 9 - Formal par |
+| 61 6D 65 74 65 72 20 39 2E 0A 30 35 38 20 20 40 | ameter 9..058 @ |
+| 3A 20 20 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 30 | : - ILLEGAL..0 |
+| 35 39 20 20 40 3B 20 20 20 2D 20 49 4C 4C 45 47 | 59 @; - ILLEG |
+| 41 4C 2E 0A 30 36 30 20 20 40 3C 20 20 20 2D 20 | AL..060 @< - |
+| 4F 70 65 6E 20 6D 61 63 72 6F 20 6E 61 6D 65 2E | Open macro name. |
+| 0A 30 36 31 20 20 40 3D 40 20 20 2D 20 53 65 74 | .061 @=@ - Set |
+| 20 73 70 65 63 69 61 6C 20 63 68 61 72 61 63 74 | special charact |
+| 65 72 2E 0A 30 36 32 20 20 40 3E 20 20 20 2D 20 | er..062 @> - |
+| 43 6C 6F 73 65 20 6D 61 63 72 6F 20 6E 61 6D 65 | Close macro name |
+| 2E 0A 30 36 33 20 20 40 3F 20 20 20 2D 20 49 4C | ..063 @? - IL |
+| 4C 45 47 41 4C 2E 0A 30 36 34 20 20 40 40 20 20 | LEGAL..064 @@ |
+| 20 2D 20 49 6E 73 65 72 74 20 73 70 65 63 69 61 | - Insert specia |
+| 6C 20 63 68 61 72 61 63 74 65 72 20 69 6E 74 6F | l character into |
+| 20 74 65 78 74 2E 0A 40 41 20 20 30 36 35 20 20 | text..@A 065 |
+| 20 2D 20 4E 65 77 20 73 65 63 74 69 6F 6E 20 28 | - New section ( |
+| 6C 65 76 65 6C 20 31 29 2E 20 4D 75 73 74 20 62 | level 1). Must b |
+| 65 20 61 74 20 73 74 61 72 74 20 6F 66 20 61 20 | e at start of a |
+| 6C 69 6E 65 2E 0A 40 42 20 20 30 36 36 20 20 20 | line..@B 066 |
+| 2D 20 4E 65 77 20 73 65 63 74 69 6F 6E 20 28 6C | - New section (l |
+| 65 76 65 6C 20 32 29 2E 20 4D 75 73 74 20 62 65 | evel 2). Must be |
+| 20 61 74 20 73 74 61 72 74 20 6F 66 20 61 20 6C | at start of a l |
+| 69 6E 65 2E 0A 40 43 20 20 30 36 37 20 20 20 2D | ine..@C 067 - |
+| 20 4E 65 77 20 73 65 63 74 69 6F 6E 20 28 6C 65 | New section (le |
+| 76 65 6C 20 33 29 2E 20 4D 75 73 74 20 62 65 20 | vel 3). Must be |
+| 61 74 20 73 74 61 72 74 20 6F 66 20 61 20 6C 69 | at start of a li |
+| 6E 65 2E 0A 40 44 20 20 30 36 38 20 20 20 2D 20 | ne..@D 068 - |
+| 4E 65 77 20 73 65 63 74 69 6F 6E 20 28 6C 65 76 | New section (lev |
+| 65 6C 20 34 29 2E 20 4D 75 73 74 20 62 65 20 61 | el 4). Must be a |
+| 74 20 73 74 61 72 74 20 6F 66 20 61 20 6C 69 6E | t start of a lin |
+| 65 2E 0A 40 45 20 20 30 36 39 20 20 20 2D 20 4E | e..@E 069 - N |
+| 65 77 20 73 65 63 74 69 6F 6E 20 28 6C 65 76 65 | ew section (leve |
+| 6C 20 35 29 2E 20 4D 75 73 74 20 62 65 20 61 74 | l 5). Must be at |
+| 20 73 74 61 72 74 20 6F 66 20 61 20 6C 69 6E 65 | start of a line |
+| 2E 0A 30 37 30 20 20 40 46 20 20 20 2D 20 49 4C | ..070 @F - IL |
+| 4C 45 47 41 4C 2E 0A 30 37 31 20 20 40 47 20 20 | LEGAL..071 @G |
+| 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 30 37 32 20 | - ILLEGAL..072 |
+| 20 40 48 20 20 20 2D 20 49 4C 4C 45 47 41 4C 2E | @H - ILLEGAL. |
+| 0A 30 37 33 20 20 40 49 20 20 20 2D 20 49 6E 63 | .073 @I - Inc |
+| 6C 75 64 65 20 66 69 6C 65 2E 20 57 69 6C 6C 20 | lude file. Will |
+| 70 72 6F 76 6F 6B 65 20 61 6E 20 65 72 72 6F 72 | provoke an error |
+| 20 68 65 72 65 20 74 68 6F 75 67 68 2E 0A 30 37 | here though..07 |
+| 34 20 20 40 4A 20 20 20 2D 20 49 4C 4C 45 47 41 | 4 @J - ILLEGA |
+| 4C 2E 0A 30 37 35 20 20 40 4B 20 20 20 2D 20 49 | L..075 @K - I |
+| 4C 4C 45 47 41 4C 2E 0A 30 37 36 20 20 40 4C 20 | LLEGAL..076 @L |
+| 20 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 30 37 37 | - ILLEGAL..077 |
+| 20 20 40 4D 20 20 20 2D 20 54 61 67 73 20 6D 61 | @M - Tags ma |
+| 63 72 6F 20 61 73 20 62 65 69 6E 67 20 61 6C 6C | cro as being all |
+| 6F 77 65 64 20 74 6F 20 62 65 20 63 61 6C 6C 65 | owed to be calle |
+| 64 20 6D 61 6E 79 20 74 69 6D 65 73 2E 0A 30 37 | d many times..07 |
+| 38 20 20 40 4E 20 20 20 2D 20 49 4C 4C 45 47 41 | 8 @N - ILLEGA |
+| 4C 2E 0A 40 4F 20 20 20 30 37 39 20 20 2D 20 4E | L..@O 079 - N |
+| 65 77 20 6D 61 63 72 6F 20 61 74 74 61 63 68 65 | ew macro attache |
+| 64 20 74 6F 20 6F 75 74 70 75 74 20 66 69 6C 65 | d to output file |
+| 2E 20 48 61 73 20 74 6F 20 62 65 20 61 74 20 73 | . Has to be at s |
+| 74 61 72 74 20 6F 66 20 6C 69 6E 65 2E 0A 30 38 | tart of line..08 |
+| 30 20 20 40 50 20 20 20 2D 20 50 72 61 67 6D 61 | 0 @P - Pragma |
+| 2E 20 57 69 6C 6C 20 63 61 75 73 65 20 65 72 72 | . Will cause err |
+| 6F 72 20 68 65 72 65 20 74 68 6F 75 67 68 2E 0A | or here though.. |
+| 30 38 31 20 20 40 51 20 20 20 2D 20 49 4C 4C 45 | 081 @Q - ILLE |
+| 47 41 4C 2E 0A 30 38 32 20 20 40 52 20 20 20 2D | GAL..082 @R - |
+| 20 49 4C 4C 45 47 41 4C 2E 0A 30 38 33 20 20 40 | ILLEGAL..083 @ |
+| 53 20 20 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 30 | S - ILLEGAL..0 |
+| 38 34 20 20 40 54 20 20 20 2D 20 54 79 70 65 73 | 84 @T - Types |
+| 65 74 74 65 72 20 64 69 72 65 63 74 69 76 65 2E | etter directive. |
+| 20 57 69 6C 6C 20 63 61 75 73 65 20 61 6E 20 65 | Will cause an e |
+| 72 72 6F 72 20 68 65 72 65 20 74 68 6F 75 67 68 | rror here though |
+| 2E 0A 30 38 35 20 20 40 55 20 20 20 2D 20 49 4C | ..085 @U - IL |
+| 4C 45 47 41 4C 2E 0A 30 38 36 20 20 40 56 20 20 | LEGAL..086 @V |
+| 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 30 38 37 20 | - ILLEGAL..087 |
+| 20 40 57 20 20 20 2D 20 49 4C 4C 45 47 41 4C 2E | @W - ILLEGAL. |
+| 0A 30 38 38 20 20 40 58 20 20 20 2D 20 49 4C 4C | .088 @X - ILL |
+| 45 47 41 4C 2E 0A 30 38 39 20 20 40 59 20 20 20 | EGAL..089 @Y |
+| 2D 20 49 4C 4C 45 47 41 4C 2E 0A 30 39 30 20 20 | - ILLEGAL..090 |
+| 40 5A 20 20 20 2D 20 54 61 67 73 20 6D 61 63 72 | @Z - Tags macr |
+| 6F 20 61 73 20 62 65 69 6E 67 20 61 6C 6C 6F 77 | o as being allow |
+| 65 64 20 74 6F 20 62 65 20 63 61 6C 6C 65 64 20 | ed to be called |
+| 7A 65 72 6F 20 74 69 6D 65 73 2E 0A 30 39 31 20 | zero times..091 |
+| 20 40 5B 20 20 20 2D 20 49 4C 4C 45 47 41 4C 2E | @[ - ILLEGAL. |
+| 0A 30 39 32 20 20 40 5C 20 20 20 2D 20 49 4C 4C | .092 @\ - ILL |
+| 45 47 41 4C 2E 0A 30 39 33 20 20 40 5D 20 20 20 | EGAL..093 @] |
+| 2D 20 49 4C 4C 45 47 41 4C 2E 0A 30 39 34 20 20 | - ILLEGAL..094 |
+| 40 5E 44 28 30 36 35 29 20 2D 20 49 6E 73 65 72 | @^D(065) - Inser |
+| 74 20 63 6F 6E 74 72 6F 6C 20 63 68 61 72 61 63 | t control charac |
+| 74 65 72 20 69 6E 74 6F 20 74 65 78 74 0A 30 39 | ter into text.09 |
+| 35 20 20 40 5F 20 20 20 2D 20 49 4C 4C 45 47 41 | 5 @_ - ILLEGA |
+| 4C 2E 0A 30 39 36 20 20 40 60 20 20 20 2D 20 49 | L..096 @` - I |
+| 4C 4C 45 47 41 4C 2E 0A 40 61 20 20 20 30 39 37 | LLEGAL..@a 097 |
+| 20 20 2D 20 4E 65 77 20 73 65 63 74 69 6F 6E 20 | - New section |
+| 28 6C 65 76 65 6C 20 31 29 2E 20 4D 75 73 74 20 | (level 1). Must |
+| 62 65 20 61 74 20 73 74 61 72 74 20 6F 66 20 61 | be at start of a |
+| 20 6C 69 6E 65 2E 0A 40 62 20 20 20 30 39 38 20 | line..@b 098 |
+| 20 2D 20 4E 65 77 20 73 65 63 74 69 6F 6E 20 28 | - New section ( |
+| 6C 65 76 65 6C 20 31 29 2E 20 4D 75 73 74 20 62 | level 1). Must b |
+| 65 20 61 74 20 73 74 61 72 74 20 6F 66 20 61 20 | e at start of a |
+| 6C 69 6E 65 2E 0A 40 63 20 20 20 30 39 39 20 20 | line..@c 099 |
+| 2D 20 4E 65 77 20 73 65 63 74 69 6F 6E 20 28 6C | - New section (l |
+| 65 76 65 6C 20 31 29 2E 20 4D 75 73 74 20 62 65 | evel 1). Must be |
+| 20 61 74 20 73 74 61 72 74 20 6F 66 20 61 20 6C | at start of a l |
+| 69 6E 65 2E 0A 40 64 20 20 20 31 30 30 20 20 2D | ine..@d 100 - |
+| 20 4E 65 77 20 73 65 63 74 69 6F 6E 20 28 6C 65 | New section (le |
+| 76 65 6C 20 31 29 2E 20 4D 75 73 74 20 62 65 20 | vel 1). Must be |
+| 61 74 20 73 74 61 72 74 20 6F 66 20 61 20 6C 69 | at start of a li |
+| 6E 65 2E 0A 40 65 20 20 20 31 30 31 20 20 2D 20 | ne..@e 101 - |
+| 4E 65 77 20 73 65 63 74 69 6F 6E 20 28 6C 65 76 | New section (lev |
+| 65 6C 20 31 29 2E 20 4D 75 73 74 20 62 65 20 61 | el 1). Must be a |
+| 74 20 73 74 61 72 74 20 6F 66 20 61 20 6C 69 6E | t start of a lin |
+| 65 2E 0A 31 30 32 20 20 40 66 20 20 20 2D 20 49 | e..102 @f - I |
+| 4C 4C 45 47 41 4C 2E 0A 31 30 33 20 20 40 67 20 | LLEGAL..103 @g |
+| 20 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 31 30 34 | - ILLEGAL..104 |
+| 20 20 40 68 20 20 20 2D 20 49 4C 4C 45 47 41 4C | @h - ILLEGAL |
+| 2E 0A 31 30 35 20 20 40 69 20 20 20 2D 20 49 6E | ..105 @i - In |
+| 63 6C 75 64 65 20 66 69 6C 65 2E 20 57 69 6C 6C | clude file. Will |
+| 20 70 72 6F 76 6F 6B 65 20 61 6E 20 65 72 72 6F | provoke an erro |
+| 72 20 68 65 72 65 20 74 68 6F 75 67 68 2E 0A 31 | r here though..1 |
+| 30 36 20 20 40 6A 20 20 20 2D 20 49 4C 4C 45 47 | 06 @j - ILLEG |
+| 41 4C 2E 0A 31 30 37 20 20 40 6B 20 20 20 2D 20 | AL..107 @k - |
+| 49 4C 4C 45 47 41 4C 2E 0A 31 30 38 20 20 40 6C | ILLEGAL..108 @l |
+| 20 20 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 31 30 | - ILLEGAL..10 |
+| 39 20 20 40 6D 20 20 20 2D 20 54 61 67 73 20 6D | 9 @m - Tags m |
+| 61 63 72 6F 20 61 73 20 62 65 69 6E 67 20 61 6C | acro as being al |
+| 6C 6F 77 65 64 20 74 6F 20 62 65 20 63 61 6C 6C | lowed to be call |
+| 65 64 20 6D 61 6E 79 20 74 69 6D 65 73 2E 0A 31 | ed many times..1 |
+| 31 30 20 20 40 6E 20 20 20 2D 20 49 4C 4C 45 47 | 10 @n - ILLEG |
+| 41 4C 2E 0A 40 4F 20 20 20 31 31 31 20 20 2D 20 | AL..@O 111 - |
+| 4E 65 77 20 6D 61 63 72 6F 20 61 74 74 61 63 68 | New macro attach |
+| 65 64 20 74 6F 20 6F 75 74 70 75 74 20 66 69 6C | ed to output fil |
+| 65 2E 20 48 61 73 20 74 6F 20 62 65 20 61 74 20 | e. Has to be at |
+| 73 74 61 72 74 20 6F 66 20 6C 69 6E 65 2E 0A 31 | start of line..1 |
+| 31 32 20 20 40 70 20 20 20 2D 20 50 72 61 67 6D | 12 @p - Pragm |
+| 61 2E 20 57 69 6C 6C 20 63 61 75 73 65 20 65 72 | a. Will cause er |
+| 72 6F 72 20 68 65 72 65 20 74 68 6F 75 67 68 2E | ror here though. |
+| 0A 31 31 33 20 20 40 71 20 20 20 2D 20 49 4C 4C | .113 @q - ILL |
+| 45 47 41 4C 2E 0A 31 31 34 20 20 40 72 20 20 20 | EGAL..114 @r |
+| 2D 20 49 4C 4C 45 47 41 4C 2E 0A 31 31 35 20 20 | - ILLEGAL..115 |
+| 40 73 20 20 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A | @s - ILLEGAL.. |
+| 31 31 36 20 20 40 74 20 20 20 2D 20 54 79 70 65 | 116 @t - Type |
+| 73 65 74 74 65 72 20 64 69 72 65 63 74 69 76 65 | setter directive |
+| 2E 20 57 69 6C 6C 20 63 61 75 73 65 20 61 6E 20 | . Will cause an |
+| 65 72 72 6F 72 20 68 65 72 65 20 74 68 6F 75 67 | error here thoug |
+| 68 2E 0A 31 31 37 20 20 40 75 20 20 20 2D 20 49 | h..117 @u - I |
+| 4C 4C 45 47 41 4C 2E 0A 31 31 38 20 20 40 76 20 | LLEGAL..118 @v |
+| 20 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 31 31 39 | - ILLEGAL..119 |
+| 20 20 40 77 20 20 20 2D 20 49 4C 4C 45 47 41 4C | @w - ILLEGAL |
+| 2E 0A 31 32 30 20 20 40 78 20 20 20 2D 20 49 4C | ..120 @x - IL |
+| 4C 45 47 41 4C 2E 0A 31 32 31 20 20 40 79 20 20 | LEGAL..121 @y |
+| 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 31 32 32 20 | - ILLEGAL..122 |
+| 20 40 7A 20 20 20 2D 20 54 61 67 73 20 6D 61 63 | @z - Tags mac |
+| 72 6F 20 61 73 20 62 65 69 6E 67 20 61 6C 6C 6F | ro as being allo |
+| 77 65 64 20 74 6F 20 62 65 20 63 61 6C 6C 65 64 | wed to be called |
+| 20 7A 65 72 6F 20 74 69 6D 65 73 2E 0A 31 32 33 | zero times..123 |
+| 20 20 40 7B 20 20 20 2D 20 4F 70 65 6E 20 6D 61 | @{ - Open ma |
+| 63 72 6F 20 62 6F 64 79 2E 0A 31 32 34 20 20 40 | cro body..124 @ |
+| 7C 20 20 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 31 | | - ILLEGAL..1 |
+| 32 35 20 20 40 7D 20 20 20 2D 20 43 6C 6F 73 65 | 25 @} - Close |
+| 20 6D 61 63 72 6F 20 62 6F 64 79 2E 0A 31 32 36 | macro body..126 |
+| 20 20 40 7E 20 20 20 2D 20 49 4C 4C 45 47 41 4C | @~ - ILLEGAL |
+| 2E 0A 31 32 37 20 74 6F 20 32 35 35 20 61 72 65 | ..127 to 255 are |
+| 20 6E 6F 74 20 73 74 61 6E 64 61 72 64 20 70 72 | not standard pr |
+| 69 6E 74 61 62 6C 65 20 41 53 43 49 49 20 63 68 | intable ASCII ch |
+| 61 72 61 63 74 65 72 73 2E 0A | aracters.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| Scanner Test: Special Sequence Recognition<010>
+00002 00002| ==========================================<010>
+00003 00003| This test tests to see that FunnelWeb is recognising the full set of special<010>
+00004 00004| sequences.<010>
+00005 00005| <010>
+00006 00006| Turn Off the Parser<010>
+00007 00007| -------------------<010>
+00008 00008| First we cause a deliberate scanner error so as to prevent the parser from<010>
+00009 00009| generating lots of errors over the syntactic rubbish presented here.<010>
+00010 00010| <010>
+00011 00011| @ <010>
+00012 00012| <010>
+00013 00013| List of All Possible Special Sequences<010>
+00014 00014| --------------------------------------<010>
+00015 00015| The following is a list of the default special character followed by each of<010>
+00016 00016| the ASCII printables.<010>
+00017 00017| 000 to 031 are unprintable control characters.<010>
+00018 00018| <010>
+00019 00019| 032 @ - ILLEGAL. (Note: Hyphen is needed to avoid trailing blanks error.)<010>
+00020 00020| 033 @! - Comment.<010>
+00021 00021| 034 @" - Parameter delimeter.<010>
+00022 00022| 035 @#X - Short name sequence.<010>
+00023 00023| @$ 036 - Define macro. Has to be at start of line.<010>
+00024 00024| 037 @% - ILLEGAL.<010>
+00025 00025| 038 @& - ILLEGAL.<010>
+00026 00026| 039 @' - ILLEGAL.<010>
+00027 00027| 040 @( - Open parameter list.<010>
+00028 00028| 041 @) - Close parameter list.<010>
+00029 00029| 042<010>
+00030 00030| @* - Old fashioned section marker (has to be at start of a line.).<010>
+00031 00031| 043 @+ - Insert newline.<010>
+00032 00032| 044 @, - Parameter separator.<010>
+00033 00033| 045 @-<010>
+00034 00034| - Ignore end of line marker (has to be at end of line).<010>
+00035 00035| 046 @. - ILLEGAL.<010>
+00036 00036| 047 @/ - Emphasised text.<010>
+00037 00037| 048 @0 - ILLEGAL.<010>
+00038 00038| 049 @1 - Formal parameter 1.<010>
+00039 00039| 050 @2 - Formal parameter 2.<010>
+00040 00040| 051 @3 - Formal parameter 3.<010>
+00041 00041| 052 @4 - Formal parameter 4.<010>
+00042 00042| 053 @5 - Formal parameter 5.<010>
+00043 00043| 054 @6 - Formal parameter 6.<010>
+00044 00044| 055 @7 - Formal parameter 7.<010>
+00045 00045| 056 @8 - Formal parameter 8.<010>
+00046 00046| 057 @9 - Formal parameter 9.<010>
+00047 00047| 058 @: - ILLEGAL.<010>
+00048 00048| 059 @; - ILLEGAL.<010>
+00049 00049| 060 @< - Open macro name.<010>
+00050 00050| 061 @=@ - Set special character.<010>
+00051 00051| 062 @> - Close macro name.<010>
+00052 00052| 063 @? - ILLEGAL.<010>
+00053 00053| 064 @@ - Insert special character into text.<010>
+00054 00054| @A 065 - New section (level 1). Must be at start of a line.<010>
+00055 00055| @B 066 - New section (level 2). Must be at start of a line.<010>
+00056 00056| @C 067 - New section (level 3). Must be at start of a line.<010>
+00057 00057| @D 068 - New section (level 4). Must be at start of a line.<010>
+00058 00058| @E 069 - New section (level 5). Must be at start of a line.<010>
+00059 00059| 070 @F - ILLEGAL.<010>
+00060 00060| 071 @G - ILLEGAL.<010>
+00061 00061| 072 @H - ILLEGAL.<010>
+00062 00062| 073 @I - Include file. Will provoke an error here though.<010>
+00063 00063| 074 @J - ILLEGAL.<010>
+00064 00064| 075 @K - ILLEGAL.<010>
+00065 00065| 076 @L - ILLEGAL.<010>
+00066 00066| 077 @M - Tags macro as being allowed to be called many times.<010>
+00067 00067| 078 @N - ILLEGAL.<010>
+00068 00068| @O 079 - New macro attached to output file. Has to be at start of line.<010>
+00069 00069| 080 @P - Pragma. Will cause error here though.<010>
+00070 00070| 081 @Q - ILLEGAL.<010>
+00071 00071| 082 @R - ILLEGAL.<010>
+00072 00072| 083 @S - ILLEGAL.<010>
+00073 00073| 084 @T - Typesetter directive. Will cause an error here though.<010>
+00074 00074| 085 @U - ILLEGAL.<010>
+00075 00075| 086 @V - ILLEGAL.<010>
+00076 00076| 087 @W - ILLEGAL.<010>
+00077 00077| 088 @X - ILLEGAL.<010>
+00078 00078| 089 @Y - ILLEGAL.<010>
+00079 00079| 090 @Z - Tags macro as being allowed to be called zero times.<010>
+00080 00080| 091 @[ - ILLEGAL.<010>
+00081 00081| 092 @\ - ILLEGAL.<010>
+00082 00082| 093 @] - ILLEGAL.<010>
+00083 00083| 094 @^D(065) - Insert control character into text<010>
+00084 00084| 095 @_ - ILLEGAL.<010>
+00085 00085| 096 @` - ILLEGAL.<010>
+00086 00086| @a 097 - New section (level 1). Must be at start of a line.<010>
+00087 00087| @b 098 - New section (level 1). Must be at start of a line.<010>
+00088 00088| @c 099 - New section (level 1). Must be at start of a line.<010>
+00089 00089| @d 100 - New section (level 1). Must be at start of a line.<010>
+00090 00090| @e 101 - New section (level 1). Must be at start of a line.<010>
+00091 00091| 102 @f - ILLEGAL.<010>
+00092 00092| 103 @g - ILLEGAL.<010>
+00093 00093| 104 @h - ILLEGAL.<010>
+00094 00094| 105 @i - Include file. Will provoke an error here though.<010>
+00095 00095| 106 @j - ILLEGAL.<010>
+00096 00096| 107 @k - ILLEGAL.<010>
+00097 00097| 108 @l - ILLEGAL.<010>
+00098 00098| 109 @m - Tags macro as being allowed to be called many times.<010>
+00099 00099| 110 @n - ILLEGAL.<010>
+00100 00100| @O 111 - New macro attached to output file. Has to be at start of line.<010>
+00101 00101| 112 @p - Pragma. Will cause error here though.<010>
+00102 00102| 113 @q - ILLEGAL.<010>
+00103 00103| 114 @r - ILLEGAL.<010>
+00104 00104| 115 @s - ILLEGAL.<010>
+00105 00105| 116 @t - Typesetter directive. Will cause an error here though.<010>
+00106 00106| 117 @u - ILLEGAL.<010>
+00107 00107| 118 @v - ILLEGAL.<010>
+00108 00108| 119 @w - ILLEGAL.<010>
+00109 00109| 120 @x - ILLEGAL.<010>
+00110 00110| 121 @y - ILLEGAL.<010>
+00111 00111| 122 @z - Tags macro as being allowed to be called zero times.<010>
+00112 00112| 123 @{ - Open macro body.<010>
+00113 00113| 124 @| - ILLEGAL.<010>
+00114 00114| 125 @} - Close macro body.<010>
+00115 00115| 126 @~ - ILLEGAL.<010>
+00116 00116| 127 to 255 are not standard printable ASCII characters.<010>
+00117 00117| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 137 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="Scanner Test: Special Sequence Recognition<010>
+==========================================<010>
+This test tests to see that FunnelWeb is recognising the full set of special<010>
+sequences.<010>
+<010>
+Turn Off the Parser<010>
+-------------------<010>
+First we cause a deliberate scanner error so as to prevent the parser from<010>
+generating lots of errors over the syntactic rubbish presented here.<010>
+<010>
+ "
+0011[06]: Text. Text scrap[Grey]="<010>
+<010>
+List of All Possible Special Sequences<010>
+--------------------------------------<010>
+The following is a list of the default special character followed by each of<010>
+the ASCII printables.<010>
+000 to 031 are unprintable control characters.<010>
+<010>
+032 "
+0019[08]: Text. Text scrap[Grey]=" - ILLEGAL. (Note: Hyphen is needed to avoid trailing blanks error.)<010>
+033 "
+0021[01]: Text. Text scrap[Grey]="034 "
+0021[06]: @" Quote.
+0021[08]: Text. Text scrap[Grey]=" - Parameter delimeter.<010>
+035 "
+0022[06]: @# Name. Character='X'.
+0022[09]: Text. Text scrap[Grey]=" - Short name sequence.<010>
+"
+0023[01]: @$ Macro defn.
+0023[03]: Text. Text scrap[Grey]=" 036 - Define macro. Has to be at start of line.<010>
+037 "
+0024[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+038 "
+0025[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+039 "
+0026[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+040 "
+0027[06]: @( Open param.
+0027[08]: Text. Text scrap[Grey]=" - Open parameter list.<010>
+041 "
+0028[06]: @} Close param.
+0028[08]: Text. Text scrap[Grey]=" - Close parameter list.<010>
+042<010>
+"
+0030[03]: Text. Text scrap[Grey]=" - Old fashioned section marker (has to be at start of a line.).<010>
+043 "
+0031[06]: Text. Text scrap[White]="<010>
+"
+0031[08]: Text. Text scrap[Grey]=" - Insert newline.<010>
+044 "
+0032[06]: @, Comma.
+0032[08]: Text. Text scrap[Grey]=" - Parameter separator.<010>
+045 "
+0034[01]: Text. Text scrap[Grey]=" - Ignore end of line marker (has to be at end of line).<010>
+046 "
+0035[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+047 "
+0036[06]: @/ Emphasise.
+0036[08]: Text. Text scrap[Grey]=" - Emphasised text.<010>
+048 "
+0037[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+049 "
+0038[06]: @n Parameter. Parameterno=1.
+0038[08]: Text. Text scrap[Grey]=" - Formal parameter 1.<010>
+050 "
+0039[06]: @n Parameter. Parameterno=2.
+0039[08]: Text. Text scrap[Grey]=" - Formal parameter 2.<010>
+051 "
+0040[06]: @n Parameter. Parameterno=3.
+0040[08]: Text. Text scrap[Grey]=" - Formal parameter 3.<010>
+052 "
+0041[06]: @n Parameter. Parameterno=4.
+0041[08]: Text. Text scrap[Grey]=" - Formal parameter 4.<010>
+053 "
+0042[06]: @n Parameter. Parameterno=5.
+0042[08]: Text. Text scrap[Grey]=" - Formal parameter 5.<010>
+054 "
+0043[06]: @n Parameter. Parameterno=6.
+0043[08]: Text. Text scrap[Grey]=" - Formal parameter 6.<010>
+055 "
+0044[06]: @n Parameter. Parameterno=7.
+0044[08]: Text. Text scrap[Grey]=" - Formal parameter 7.<010>
+056 "
+0045[06]: @n Parameter. Parameterno=8.
+0045[08]: Text. Text scrap[Grey]=" - Formal parameter 8.<010>
+057 "
+0046[06]: @n Parameter. Parameterno=9.
+0046[08]: Text. Text scrap[Grey]=" - Formal parameter 9.<010>
+058 "
+0047[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+059 "
+0048[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+060 "
+0049[06]: @< Open name.
+0049[08]: Text. Text scrap[Grey]=" - Open macro name.<010>
+061 "
+0050[09]: Text. Text scrap[Grey]=" - Set special character.<010>
+062 "
+0051[06]: @> Close name.
+0051[08]: Text. Text scrap[Grey]=" - Close macro name.<010>
+063 "
+0052[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+064 "
+0053[06]: Text. Text scrap[Grey]="@"
+0053[08]: Text. Text scrap[Grey]=" - Insert special character into text.<010>
+"
+0054[01]: @A New section (Level 1).
+0054[03]: Text. Text scrap[Grey]=" 065 - New section (level 1). Must be at start of a line.<010>
+"
+0055[01]: @B New section (Level 2).
+0055[03]: Text. Text scrap[Grey]=" 066 - New section (level 2). Must be at start of a line.<010>
+"
+0056[01]: @C New section (Level 3).
+0056[03]: Text. Text scrap[Grey]=" 067 - New section (level 3). Must be at start of a line.<010>
+"
+0057[01]: @D New section (Level 4).
+0057[03]: Text. Text scrap[Grey]=" 068 - New section (level 4). Must be at start of a line.<010>
+"
+0058[01]: @E New section (Level 5).
+0058[03]: Text. Text scrap[Grey]=" 069 - New section (level 5). Must be at start of a line.<010>
+070 "
+0059[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+071 "
+0060[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+072 "
+0061[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+073 "
+0063[01]: Text. Text scrap[Grey]="074 "
+0063[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+075 "
+0064[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+076 "
+0065[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+077 "
+0066[06]: @M Many calls.
+0066[08]: Text. Text scrap[Grey]=" - Tags macro as being allowed to be called many times.<010>
+078 "
+0067[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+"
+0068[01]: @F File defn.
+0068[03]: Text. Text scrap[Grey]=" 079 - New macro attached to output file. Has to be at start of line.<010>
+080 "
+0070[01]: Text. Text scrap[Grey]="081 "
+0070[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+082 "
+0071[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+083 "
+0072[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+084 "
+0074[01]: Text. Text scrap[Grey]="085 "
+0074[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+086 "
+0075[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+087 "
+0076[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+088 "
+0077[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+089 "
+0078[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+090 "
+0079[06]: @Z Zero calls.
+0079[08]: Text. Text scrap[Grey]=" - Tags macro as being allowed to be called zero times.<010>
+091 "
+0080[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+092 "
+0081[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+093 "
+0082[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+094 "
+0083[06]: Text. Text scrap[Grey]="A"
+0083[14]: Text. Text scrap[Grey]=" - Insert control character into text<010>
+095 "
+0084[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+096 "
+0085[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+"
+0086[01]: @A New section (Level 1).
+0086[03]: Text. Text scrap[Grey]=" 097 - New section (level 1). Must be at start of a line.<010>
+"
+0087[01]: @B New section (Level 2).
+0087[03]: Text. Text scrap[Grey]=" 098 - New section (level 1). Must be at start of a line.<010>
+"
+0088[01]: @C New section (Level 3).
+0088[03]: Text. Text scrap[Grey]=" 099 - New section (level 1). Must be at start of a line.<010>
+"
+0089[01]: @D New section (Level 4).
+0089[03]: Text. Text scrap[Grey]=" 100 - New section (level 1). Must be at start of a line.<010>
+"
+0090[01]: @E New section (Level 5).
+0090[03]: Text. Text scrap[Grey]=" 101 - New section (level 1). Must be at start of a line.<010>
+102 "
+0091[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+103 "
+0092[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+104 "
+0093[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+105 "
+0095[01]: Text. Text scrap[Grey]="106 "
+0095[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+107 "
+0096[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+108 "
+0097[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+109 "
+0098[06]: @M Many calls.
+0098[08]: Text. Text scrap[Grey]=" - Tags macro as being allowed to be called many times.<010>
+110 "
+0099[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+"
+0100[01]: @F File defn.
+0100[03]: Text. Text scrap[Grey]=" 111 - New macro attached to output file. Has to be at start of line.<010>
+112 "
+0102[01]: Text. Text scrap[Grey]="113 "
+0102[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+114 "
+0103[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+115 "
+0104[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+116 "
+0106[01]: Text. Text scrap[Grey]="117 "
+0106[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+118 "
+0107[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+119 "
+0108[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+120 "
+0109[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+121 "
+0110[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+122 "
+0111[06]: @Z Zero calls.
+0111[08]: Text. Text scrap[Grey]=" - Tags macro as being allowed to be called zero times.<010>
+123 "
+0112[06]: @{ Open defn.
+0112[08]: Text. Text scrap[Grey]=" - Open macro body.<010>
+124 "
+0113[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+125 "
+0114[06]: @} Close defn.
+0114[08]: Text. Text scrap[Grey]=" - Close macro body.<010>
+126 "
+0115[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+127 to 255 are not standard printable ASCII characters.<010>
+"
+0117[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| Scanner Test: Special Sequence Recognition
+ 2 2| ==========================================
+ 3 3| This test tests to see that FunnelWeb is recognising the full set of special
+ 4 4| sequences.
+ 5 5|
+ 6 6| Turn Off the Parser
+ 7 7| -------------------
+ 8 8| First we cause a deliberate scanner error so as to prevent the parser from
+ 9 9| generating lots of errors over the syntactic rubbish presented here.
+ 10 10|
+ 11 11| @
+ Error|....^<special><space> is not a legal special sequence.
+ Warning|.....^Line has trailing spaces up to and including this space.
+ 12 12|
+ 13 13| List of All Possible Special Sequences
+ 14 14| --------------------------------------
+ 15 15| The following is a list of the default special character followed by each of
+ 16 16| the ASCII printables.
+ 17 17| 000 to 031 are unprintable control characters.
+ 18 18|
+ 19 19| 032 @ - ILLEGAL. (Note: Hyphen is needed to avoid trailing blanks error.)
+ Error|......^<special><space> is not a legal special sequence.
+ 20 20| 033 @! - Comment.
+ 21 21| 034 @" - Parameter delimeter.
+ 22 22| 035 @#X - Short name sequence.
+ 23 23| @$ 036 - Define macro. Has to be at start of line.
+ 24 24| 037 @% - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 25 25| 038 @& - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 26 26| 039 @' - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 27 27| 040 @( - Open parameter list.
+ 28 28| 041 @) - Close parameter list.
+ 29 29| 042
+ 30 30| @* - Old fashioned section marker (has to be at start of a line.).
+ Error|.^Unknown special sequence.
+ 31 31| 043 @+ - Insert newline.
+ 32 32| 044 @, - Parameter separator.
+ 33 33| 045 @-
+ 34 34| - Ignore end of line marker (has to be at end of line).
+ 35 35| 046 @. - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 36 36| 047 @/ - Emphasised text.
+ 37 37| 048 @0 - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 38 38| 049 @1 - Formal parameter 1.
+ 39 39| 050 @2 - Formal parameter 2.
+ 40 40| 051 @3 - Formal parameter 3.
+ 41 41| 052 @4 - Formal parameter 4.
+ 42 42| 053 @5 - Formal parameter 5.
+ 43 43| 054 @6 - Formal parameter 6.
+ 44 44| 055 @7 - Formal parameter 7.
+ 45 45| 056 @8 - Formal parameter 8.
+ 46 46| 057 @9 - Formal parameter 9.
+ 47 47| 058 @: - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 48 48| 059 @; - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 49 49| 060 @< - Open macro name.
+ 50 50| 061 @=@ - Set special character.
+ 51 51| 062 @> - Close macro name.
+ 52 52| 063 @? - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 53 53| 064 @@ - Insert special character into text.
+ 54 54| @A 065 - New section (level 1). Must be at start of a line.
+ 55 55| @B 066 - New section (level 2). Must be at start of a line.
+ 56 56| @C 067 - New section (level 3). Must be at start of a line.
+ 57 57| @D 068 - New section (level 4). Must be at start of a line.
+ 58 58| @E 069 - New section (level 5). Must be at start of a line.
+ 59 59| 070 @F - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 60 60| 071 @G - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 61 61| 072 @H - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 62 62| 073 @I - Include file. Will provoke an error here though.
+ Error|......^Include sequence must be at the beginning of a line.
+ |......^Include ignored.
+ 63 63| 074 @J - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 64 64| 075 @K - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 65 65| 076 @L - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 66 66| 077 @M - Tags macro as being allowed to be called many times.
+ 67 67| 078 @N - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 68 68| @O 079 - New macro attached to output file. Has to be at start of line.
+ 69 69| 080 @P - Pragma. Will cause error here though.
+ Error|......^Pragma sequence @p must be at the start of a line.
+ |......^The rest of this line will be ignored.
+ Error|......^Unrecognised pragma. Possible legal pragmas are:
+ |......^ @p indentation = none | blank
+ |......^ @p maximum_input_line_length = <num>|infinity
+ |......^ @p maximum_output_line_length = <num>|infinity
+ |......^ @p typesetter = none | tex
+ |......^The blanks between arguments are important.
+ |......^Pragma ignored.
+ 70 70| 081 @Q - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 71 71| 082 @R - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 72 72| 083 @S - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 73 73| 084 @T - Typesetter directive. Will cause an error here though.
+ Error|......^Typesetter directive @t must be at the start of a line.
+ |......^The rest of this line will be ignored.
+ Error|......^Unrecognised typesetter directive. Legal ones are:
+ |......^ @t new_page
+ |......^ @t table_of_contents
+ |......^ @t title <font> <align> <string>
+ |......^ @t vskip <num> mm
+ |......^The blanks between arguments are important.
+ |......^Typesetter directive ignored.
+ 74 74| 085 @U - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 75 75| 086 @V - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 76 76| 087 @W - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 77 77| 088 @X - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 78 78| 089 @Y - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 79 79| 090 @Z - Tags macro as being allowed to be called zero times.
+ 80 80| 091 @[ - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 81 81| 092 @\ - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 82 82| 093 @] - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 83 83| 094 @^D(065) - Insert control character into text
+ 84 84| 095 @_ - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 85 85| 096 @` - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 86 86| @a 097 - New section (level 1). Must be at start of a line.
+ 87 87| @b 098 - New section (level 1). Must be at start of a line.
+ 88 88| @c 099 - New section (level 1). Must be at start of a line.
+ 89 89| @d 100 - New section (level 1). Must be at start of a line.
+ 90 90| @e 101 - New section (level 1). Must be at start of a line.
+ 91 91| 102 @f - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 92 92| 103 @g - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 93 93| 104 @h - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 94 94| 105 @i - Include file. Will provoke an error here though.
+ Error|......^Include sequence must be at the beginning of a line.
+ |......^Include ignored.
+ 95 95| 106 @j - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 96 96| 107 @k - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 97 97| 108 @l - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 98 98| 109 @m - Tags macro as being allowed to be called many times.
+ 99 99| 110 @n - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 100 100| @O 111 - New macro attached to output file. Has to be at start of line.
+ 101 101| 112 @p - Pragma. Will cause error here though.
+ Error|......^Pragma sequence @p must be at the start of a line.
+ |......^The rest of this line will be ignored.
+ Error|......^Unrecognised pragma. Possible legal pragmas are:
+ |......^ @p indentation = none | blank
+ |......^ @p maximum_input_line_length = <num>|infinity
+ |......^ @p maximum_output_line_length = <num>|infinity
+ |......^ @p typesetter = none | tex
+ |......^The blanks between arguments are important.
+ |......^Pragma ignored.
+ 102 102| 113 @q - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 103 103| 114 @r - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 104 104| 115 @s - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 105 105| 116 @t - Typesetter directive. Will cause an error here though.
+ Error|......^Typesetter directive @t must be at the start of a line.
+ |......^The rest of this line will be ignored.
+ Error|......^Unrecognised typesetter directive. Legal ones are:
+ |......^ @t new_page
+ |......^ @t table_of_contents
+ |......^ @t title <font> <align> <string>
+ |......^ @t vskip <num> mm
+ |......^The blanks between arguments are important.
+ |......^Typesetter directive ignored.
+ 106 106| 117 @u - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 107 107| 118 @v - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 108 108| 119 @w - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 109 109| 120 @x - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 110 110| 121 @y - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 111 111| 122 @z - Tags macro as being allowed to be called zero times.
+ 112 112| 123 @{ - Open macro body.
+ 113 113| 124 @| - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 114 114| 125 @} - Close macro body.
+ 115 115| 126 @~ - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 116 116| 127 to 255 are not standard printable ASCII characters.
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 58 Errors and 1 Warning.
diff --git a/web/funnelAC/answers/sc11.lis b/web/funnelAC/answers/sc11.lis
new file mode 100644
index 0000000000..6082c059c4
--- /dev/null
+++ b/web/funnelAC/answers/sc11.lis
@@ -0,0 +1,307 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 31 3A 20 53 79 6E 74 61 78 20 6F 66 20 | SC11: Syntax of |
+| 74 68 65 20 69 6E 63 6C 75 64 65 20 70 72 61 67 | the include prag |
+| 6D 61 2E 0A 0A 31 2E 20 54 65 73 74 20 69 6E 63 | ma...1. Test inc |
+| 6C 75 64 65 20 70 72 61 67 6D 61 20 6E 6F 74 20 | lude pragma not |
+| 61 74 20 73 74 61 72 74 20 6F 66 20 6C 69 6E 65 | at start of line |
+| 2E 0A 0A 20 20 20 40 69 0A 0A 32 2E 20 54 65 73 | ... @i..2. Tes |
+| 74 20 41 54 69 20 6E 6F 74 20 66 6F 6C 6C 6F 77 | t ATi not follow |
+| 65 64 20 62 79 20 61 20 62 6C 61 6E 6B 2E 0A 0A | ed by a blank... |
+| 40 69 78 0A 0A 33 2E 20 54 65 73 74 20 69 6E 63 | @ix..3. Test inc |
+| 6C 75 64 65 20 66 69 6C 65 6E 61 6D 65 20 69 73 | lude filename is |
+| 20 74 6F 6F 20 6C 6F 6E 67 2E 20 54 68 65 20 6D | too long. The m |
+| 61 78 69 6D 75 6D 20 6F 6E 20 74 68 65 20 4D 61 | aximum on the Ma |
+| 63 69 6E 74 6F 73 68 20 69 73 0A 20 20 20 32 35 | cintosh is. 25 |
+| 35 20 62 75 74 20 77 65 20 77 69 6C 6C 20 75 73 | 5 but we will us |
+| 65 20 61 20 66 69 6C 65 6E 61 6D 65 20 6F 66 20 | e a filename of |
+| 6F 76 65 72 20 31 30 32 34 20 63 68 61 72 61 63 | over 1024 charac |
+| 74 65 72 73 20 73 6F 20 61 73 20 74 6F 20 6D 61 | ters so as to ma |
+| 6B 65 0A 20 20 20 74 68 65 20 74 65 73 74 20 70 | ke. the test p |
+| 6F 72 74 61 62 6C 65 2E 20 54 68 65 20 61 63 74 | ortable. The act |
+| 75 61 6C 20 6C 65 6E 67 74 68 20 75 73 65 64 20 | ual length used |
+| 69 73 20 31 31 30 30 20 63 68 61 72 61 63 74 65 | is 1100 characte |
+| 72 73 20 69 6E 20 74 68 65 0A 20 20 20 66 69 6C | rs in the. fil |
+| 65 6E 61 6D 65 2E 0A 0A 20 20 20 20 20 20 20 20 | ename... |
+| 20 20 20 20 31 20 20 20 20 20 20 20 20 20 32 20 | 1 2 |
+| 20 20 20 20 20 20 20 20 33 20 20 20 20 20 20 20 | 3 |
+| 20 20 34 20 20 20 20 20 20 20 20 20 35 20 20 20 | 4 5 |
+| 20 20 20 20 20 20 36 20 20 20 20 20 20 20 20 20 | 6 |
+| 37 20 20 20 20 20 20 20 20 20 38 20 20 20 20 20 | 7 8 |
+| 20 20 20 20 39 20 20 20 20 20 20 20 20 20 30 20 | 9 0 |
+| 20 20 20 20 20 20 20 20 31 20 20 20 20 20 20 20 | 1 |
+| 20 20 32 20 20 20 20 20 20 20 20 20 33 20 20 20 | 2 3 |
+| 20 20 20 20 20 20 34 20 20 20 20 20 20 20 20 20 | 4 |
+| 35 20 20 20 20 20 20 20 20 20 36 20 20 20 20 20 | 5 6 |
+| 20 20 20 20 37 20 20 20 20 20 20 20 20 20 38 20 | 7 8 |
+| 20 20 20 20 20 20 20 20 39 20 20 20 20 20 20 20 | 9 |
+| 20 20 30 20 20 20 20 20 20 20 20 20 31 20 20 20 | 0 1 |
+| 20 20 20 20 20 20 32 20 20 20 20 20 20 20 20 20 | 2 |
+| 33 20 20 20 20 20 20 20 20 20 34 20 20 20 20 20 | 3 4 |
+| 20 20 20 20 35 20 20 20 20 20 20 20 20 20 36 20 | 5 6 |
+| 20 20 20 20 20 20 20 20 37 20 20 20 20 20 20 20 | 7 |
+| 20 20 38 20 20 20 20 20 20 20 20 20 39 20 20 20 | 8 9 |
+| 20 20 20 20 20 20 30 20 20 20 20 20 20 20 20 20 | 0 |
+| 31 20 20 20 20 20 20 20 20 20 32 20 20 20 20 20 | 1 2 |
+| 20 20 20 20 33 20 20 20 20 20 20 20 20 20 34 20 | 3 4 |
+| 20 20 20 20 20 20 20 20 35 20 20 20 20 20 20 20 | 5 |
+| 20 20 36 20 20 20 20 20 20 20 20 20 37 20 20 20 | 6 7 |
+| 20 20 20 20 20 20 38 20 20 20 20 20 20 20 20 20 | 8 |
+| 39 20 20 20 20 20 20 20 20 20 30 20 20 20 20 20 | 9 0 |
+| 20 20 20 20 31 20 20 20 20 20 20 20 20 20 32 20 | 1 2 |
+| 20 20 20 20 20 20 20 20 33 20 20 20 20 20 20 20 | 3 |
+| 20 20 34 20 20 20 20 20 20 20 20 20 35 20 20 20 | 4 5 |
+| 20 20 20 20 20 20 36 20 20 20 20 20 20 20 20 20 | 6 |
+| 37 20 20 20 20 20 20 20 20 20 38 20 20 20 20 20 | 7 8 |
+| 20 20 20 20 39 20 20 20 20 20 20 20 20 20 30 20 | 9 0 |
+| 20 20 20 20 20 20 20 20 31 20 20 20 20 20 20 20 | 1 |
+| 20 20 32 20 20 20 20 20 20 20 20 20 33 20 20 20 | 2 3 |
+| 20 20 20 20 20 20 34 20 20 20 20 20 20 20 20 20 | 4 |
+| 35 20 20 20 20 20 20 20 20 20 36 20 20 20 20 20 | 5 6 |
+| 20 20 20 20 37 20 20 20 20 20 20 20 20 20 38 20 | 7 8 |
+| 20 20 20 20 20 20 20 20 39 20 20 20 20 20 20 20 | 9 |
+| 20 20 30 20 20 20 20 20 20 20 20 20 31 20 20 20 | 0 1 |
+| 20 20 20 20 20 20 32 20 20 20 20 20 20 20 20 20 | 2 |
+| 33 20 20 20 20 20 20 20 20 20 34 20 20 20 20 20 | 3 4 |
+| 20 20 20 20 35 20 20 20 20 20 20 20 20 20 36 20 | 5 6 |
+| 20 20 20 20 20 20 20 20 37 20 20 20 20 20 20 20 | 7 |
+| 20 20 38 20 20 20 20 20 20 20 20 20 39 20 20 20 | 8 9 |
+| 20 20 20 20 20 20 30 20 20 20 20 20 20 20 20 20 | 0 |
+| 31 20 20 20 20 20 20 20 20 20 32 20 20 20 20 20 | 1 2 |
+| 20 20 20 20 33 20 20 20 20 20 20 20 20 20 34 20 | 3 4 |
+| 20 20 20 20 20 20 20 20 35 20 20 20 20 20 20 20 | 5 |
+| 20 20 36 20 20 20 20 20 20 20 20 20 37 20 20 20 | 6 7 |
+| 20 20 20 20 20 20 38 20 20 20 20 20 20 20 20 20 | 8 |
+| 39 20 20 20 20 20 20 20 20 20 30 20 20 20 20 20 | 9 0 |
+| 20 20 20 20 31 20 20 20 20 20 20 20 20 20 32 20 | 1 2 |
+| 20 20 20 20 20 20 20 20 33 20 20 20 20 20 20 20 | 3 |
+| 20 20 34 20 20 20 20 20 20 20 20 20 35 20 20 20 | 4 5 |
+| 20 20 20 20 20 20 36 20 20 20 20 20 20 20 20 20 | 6 |
+| 37 20 20 20 20 20 20 20 20 20 38 20 20 20 20 20 | 7 8 |
+| 20 20 20 20 39 20 20 20 20 20 20 20 20 20 30 20 | 9 0 |
+| 20 20 20 20 20 20 20 20 31 20 20 20 20 20 20 20 | 1 |
+| 20 20 32 20 20 20 20 20 20 20 20 20 33 20 20 20 | 2 3 |
+| 20 20 20 20 20 20 34 20 20 20 20 20 20 20 20 20 | 4 |
+| 35 20 20 20 20 20 20 20 20 20 36 20 20 20 20 20 | 5 6 |
+| 20 20 20 20 37 20 20 20 20 20 20 20 20 20 38 20 | 7 8 |
+| 20 20 20 20 20 20 20 20 39 20 20 20 20 20 20 20 | 9 |
+| 20 20 30 20 20 20 20 20 20 20 20 20 31 20 20 20 | 0 1 |
+| 20 20 20 20 20 20 32 20 20 20 20 20 20 20 20 20 | 2 |
+| 33 20 20 20 20 20 20 20 20 20 34 20 20 20 20 20 | 3 4 |
+| 20 20 20 20 35 20 20 20 20 20 20 20 20 20 36 20 | 5 6 |
+| 20 20 20 20 20 20 20 20 37 20 20 20 20 20 20 20 | 7 |
+| 20 20 38 20 20 20 20 20 20 20 20 20 39 20 20 20 | 8 9 |
+| 20 20 20 20 20 20 30 0A 40 69 20 31 32 33 34 35 | 0.@i 12345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 0A 0A 34 2E 20 49 6E 63 6C | 4567890..4. Incl |
+| 75 64 65 20 70 72 61 67 6D 61 20 68 61 73 20 61 | ude pragma has a |
+| 6E 20 65 6D 70 74 79 20 66 69 6C 65 6E 61 6D 65 | n empty filename |
+| 2E 20 4E 6F 74 65 3A 20 42 65 63 61 75 73 65 20 | . Note: Because |
+| 74 68 65 20 41 54 69 20 68 61 73 20 74 6F 20 62 | the ATi has to b |
+| 65 0A 20 20 20 66 6F 6C 6C 6F 77 65 64 20 62 79 | e. followed by |
+| 20 61 20 62 6C 61 6E 6B 2C 20 77 65 20 68 61 76 | a blank, we hav |
+| 65 20 74 6F 20 69 6E 63 75 72 20 61 20 74 72 61 | e to incur a tra |
+| 69 6C 69 6E 67 20 62 6C 61 6E 6B 20 65 72 72 6F | iling blank erro |
+| 72 20 68 65 72 65 20 69 6E 0A 20 20 20 6F 72 64 | r here in. ord |
+| 65 72 20 74 6F 20 70 72 6F 76 6F 6B 65 20 74 68 | er to provoke th |
+| 65 20 65 72 72 6F 72 20 77 65 20 72 65 61 6C 6C | e error we reall |
+| 79 20 77 61 6E 74 20 74 6F 20 73 65 65 2E 0A 0A | y want to see... |
+| 40 69 20 0A 0A | @i .. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC11: Syntax of the include pragma.<010>
+00002 00002| <010>
+00003 00003| 1. Test include pragma not at start of line.<010>
+00004 00004| <010>
+00005 00005| @i<010>
+00006 00006| <010>
+00007 00007| 2. Test ATi not followed by a blank.<010>
+00008 00008| <010>
+00009 00009| @ix<010>
+00010 00010| <010>
+00011 00011| 3. Test include filename is too long. The maximum on the Macintosh is<010>
+00012 00012| 255 but we will use a filename of over 1024 characters so as to make<010>
+00013 00013| the test portable. The actual length used is 1100 characters in the<010>
+00014 00014| filename.<010>
+00015 00015| <010>
+00016 00016| 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0<010>
+00017 00017| @i 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890<010>
+00018 00018| <010>
+00019 00019| 4. Include pragma has an empty filename. Note: Because the ATi has to be<010>
+00020 00020| followed by a blank, we have to incur a trailing blank error here in<010>
+00021 00021| order to provoke the error we really want to see.<010>
+00022 00022| <010>
+00023 00023| @i <010>
+00024 00024| <010>
+00025 00025| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 6 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC11: Syntax of the include pragma.<010>
+<010>
+1. Test include pragma not at start of line.<010>
+<010>
+ "
+0006[01]: Text. Text scrap[Grey]="<010>
+2. Test ATi not followed by a blank.<010>
+<010>
+"
+0010[01]: Text. Text scrap[Grey]="<010>
+3. Test include filename is too long. The maximum on the Macintosh is<010>
+ 255 but we will use a filename of over 1024 characters so as to make<010>
+ the test portable. The actual length used is 1100 characters in the<010>
+ filename.<010>
+<010>
+ 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0<010>
+"
+0018[01]: Text. Text scrap[Grey]="<010>
+4. Include pragma has an empty filename. Note: Because the ATi has to be<010>
+ followed by a blank, we have to incur a trailing blank error here in<010>
+ order to provoke the error we really want to see.<010>
+<010>
+"
+0024[01]: Text. Text scrap[White]="<010>
+"
+0025[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC11: Syntax of the include pragma.
+ 2 2|
+ 3 3| 1. Test include pragma not at start of line.
+ 4 4|
+ 5 5| @i
+ Error|....^Include sequence must be at the beginning of a line.
+ |....^Include ignored.
+ 6 6|
+ 7 7| 2. Test ATi not followed by a blank.
+ 8 8|
+ 9 9| @ix
+ Error|...^Include sequence (@i) must be followed by a blank.
+ |...^Example include: @i macros.fwi
+ |...^Include ignored.
+ 10 10|
+ 11 11| 3. Test include filename is too long. The maximum on the Macintosh is
+ 12 12| 255 but we will use a filename of over 1024 characters so as to make
+ 13 13| the test portable. The actual length used is 1100 characters in the
+ 14 14| filename.
+ 15 15|
+ 16 16| 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
+ Error|.................................................................................^Input line is too long (this character is the first offender).
+ |.................................................................................^Currently, the maximum allowable input line length is 80.
+ |.................................................................................^Note: You can change this using a pragma directive (@p).
+ 17 17| @i 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
+ Error|.^This include command's file specification is too long.
+ |.^The maximum file name length is <<Suppressed>> characters.
+ |.^Include ignored.
+ Error|.................................................................................^Input line is too long (this character is the first offender).
+ |.................................................................................^Currently, the maximum allowable input line length is 80.
+ |.................................................................................^Note: You can change this using a pragma directive (@p).
+ 18 18|
+ 19 19| 4. Include pragma has an empty filename. Note: Because the ATi has to be
+ 20 20| followed by a blank, we have to incur a trailing blank error here in
+ 21 21| order to provoke the error we really want to see.
+ 22 22|
+ 23 23| @i
+ Warning|...^Line has trailing spaces up to and including this space.
+ Error|....^Expecting the name of a file to include.
+ 24 24|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 6 Errors and 1 Warning.
diff --git a/web/funnelAC/answers/sc12.lis b/web/funnelAC/answers/sc12.lis
new file mode 100644
index 0000000000..1421eacfbc
--- /dev/null
+++ b/web/funnelAC/answers/sc12.lis
@@ -0,0 +1,77 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 32 3A 20 49 6E 63 6C 75 64 65 20 66 69 | SC12: Include fi |
+| 6C 65 20 63 61 6E 6E 6F 74 20 62 65 20 66 6F 75 | le cannot be fou |
+| 6E 64 2E 0A 54 65 73 74 20 70 65 72 73 6F 6E 3A | nd..Test person: |
+| 20 44 4F 4E 54 20 63 72 65 61 74 65 20 73 63 31 | DONT create sc1 |
+| 32 61 2E 69 6E 63 2E 20 49 74 20 69 73 20 6E 6F | 2a.inc. It is no |
+| 74 20 73 75 70 70 6F 73 65 64 20 74 6F 20 65 78 | t supposed to ex |
+| 69 73 74 21 0A 54 68 65 20 66 6F 6C 6C 6F 77 69 | ist!.The followi |
+| 6E 67 20 69 6E 63 6C 75 64 65 20 73 68 6F 75 6C | ng include shoul |
+| 64 20 79 69 65 6C 64 20 61 20 22 66 69 6C 65 20 | d yield a "file |
+| 6E 6F 74 20 66 6F 75 6E 64 20 65 72 72 6F 72 2E | not found error. |
+| 22 0A 0A 40 69 20 73 63 31 32 61 2E 69 6E 63 0A | "..@i sc12a.inc. |
+| 0A | . |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC12: Include file cannot be found.<010>
+00002 00002| Test person: DONT create sc12a.inc. It is not supposed to exist!<010>
+00003 00003| The following include should yield a "file not found error."<010>
+00004 00004| <010>
+00005 00005| @i sc12a.inc<010>
+00006 00006| <010>
+00007 00007| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 3 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC12: Include file cannot be found.<010>
+Test person: DONT create sc12a.inc. It is not supposed to exist!<010>
+The following include should yield a "file not found error."<010>
+<010>
+"
+0006[01]: Text. Text scrap[White]="<010>
+"
+0007[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC12: Include file cannot be found.
+ 2 2| Test person: DONT create sc12a.inc. It is not supposed to exist!
+ 3 3| The following include should yield a "file not found error."
+ 4 4|
+ 5 5| @i sc12a.inc
+ Error|....^Error opening include file.
+ |....^The include file's expanded name was "<<Suppressed>>".
+ 6 6|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There was 1 Error.
diff --git a/web/funnelAC/answers/sc13.lis b/web/funnelAC/answers/sc13.lis
new file mode 100644
index 0000000000..7876c45446
--- /dev/null
+++ b/web/funnelAC/answers/sc13.lis
@@ -0,0 +1,422 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 33 3A 20 56 61 72 69 6F 75 73 20 6B 69 | SC13: Various ki |
+| 6E 64 73 20 6F 66 20 69 6E 63 6C 75 64 65 20 66 | nds of include f |
+| 69 6C 65 2E 0A 0A 31 2E 20 49 6E 63 6C 75 64 65 | ile...1. Include |
+| 20 66 69 6C 65 20 69 73 20 65 6D 70 74 79 2E 0A | file is empty.. |
+| 42 65 66 6F 72 65 20 69 6E 63 6C 75 64 65 0A 40 | Before include.@ |
+| 69 20 73 63 31 33 61 0A 41 66 74 65 72 20 69 6E | i sc13a.After in |
+| 63 6C 75 64 65 0A 0A 32 2E 20 49 6E 63 6C 75 64 | clude..2. Includ |
+| 65 20 66 69 6C 65 20 63 6F 6E 74 61 69 6E 73 20 | e file contains |
+| 61 20 73 69 6E 67 6C 65 20 62 6C 61 6E 6B 20 6C | a single blank l |
+| 69 6E 65 2E 0A 42 65 66 6F 72 65 20 69 6E 63 6C | ine..Before incl |
+| 75 64 65 0A 40 69 20 73 63 31 33 62 0A 41 66 74 | ude.@i sc13b.Aft |
+| 65 72 20 69 6E 63 6C 75 64 65 0A 0A 33 2E 20 49 | er include..3. I |
+| 6E 63 6C 75 64 65 20 66 69 6C 65 20 63 6F 6E 74 | nclude file cont |
+| 61 69 6E 73 20 74 77 6F 20 62 6C 61 6E 6B 20 6C | ains two blank l |
+| 69 6E 65 73 2E 0A 42 65 66 6F 72 65 20 69 6E 63 | ines..Before inc |
+| 6C 75 64 65 0A 40 69 20 73 63 31 33 63 0A 41 66 | lude.@i sc13c.Af |
+| 74 65 72 20 69 6E 63 6C 75 64 65 0A 0A 34 2E 20 | ter include..4. |
+| 49 6E 63 6C 75 64 65 20 66 69 6C 65 20 63 6F 6E | Include file con |
+| 74 61 69 6E 73 20 61 20 73 69 6E 67 6C 65 20 6C | tains a single l |
+| 69 6E 65 20 77 69 74 68 20 74 65 78 74 20 6F 6E | ine with text on |
+| 20 69 74 2E 0A 42 65 66 6F 72 65 20 69 6E 63 6C | it..Before incl |
+| 75 64 65 0A 40 69 20 73 63 31 33 64 0A 41 66 74 | ude.@i sc13d.Aft |
+| 65 72 20 69 6E 63 6C 75 64 65 0A 0A 35 2E 20 49 | er include..5. I |
+| 6E 63 6C 75 64 65 20 66 69 6C 65 27 73 20 6C 61 | nclude file's la |
+| 73 74 20 6C 69 6E 65 20 69 73 20 6E 6F 74 20 70 | st line is not p |
+| 72 6F 70 65 72 6C 79 20 74 65 72 6D 69 6E 61 74 | roperly terminat |
+| 65 64 2E 0A 42 65 66 6F 72 65 20 69 6E 63 6C 75 | ed..Before inclu |
+| 64 65 0A 40 69 20 73 63 31 33 65 0A 41 66 74 65 | de.@i sc13e.Afte |
+| 72 20 69 6E 63 6C 75 64 65 0A 0A 36 2E 20 49 6E | r include..6. In |
+| 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 6F 72 | clude file is or |
+| 64 69 6E 61 72 79 2E 0A 42 65 66 6F 72 65 20 69 | dinary..Before i |
+| 6E 63 6C 75 64 65 0A 40 69 20 73 63 31 33 66 0A | nclude.@i sc13f. |
+| 41 66 74 65 72 20 69 6E 63 6C 75 64 65 0A 0A 37 | After include..7 |
+| 2E 20 54 65 73 74 20 75 70 70 65 72 20 63 61 73 | . Test upper cas |
+| 65 20 49 20 61 6E 64 20 66 69 6C 65 20 65 78 74 | e I and file ext |
+| 65 6E 73 69 6F 6E 20 69 6E 68 65 72 69 74 61 6E | ension inheritan |
+| 63 65 2E 0A 42 65 66 6F 72 65 20 69 6E 63 6C 75 | ce..Before inclu |
+| 64 65 0A 40 49 20 73 63 31 33 66 0A 41 66 74 65 | de.@I sc13f.Afte |
+| 72 20 69 6E 63 6C 75 64 65 0A 0A 45 6E 64 20 6F | r include..End o |
+| 66 20 74 65 73 74 20 46 69 6C 65 2E 0A | f test File.. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 0A | . |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 0A 0A | .. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 54 68 69 73 20 69 73 20 74 68 65 20 69 6E 63 6C | This is the incl |
+| 75 64 65 20 66 69 6C 65 20 66 6F 72 20 74 65 73 | ude file for tes |
+| 74 20 53 43 31 33 64 2E 20 4A 75 73 74 20 61 20 | t SC13d. Just a |
+| 66 69 6C 65 20 63 6F 6E 74 61 69 6E 69 6E 67 20 | file containing |
+| 6F 6E 65 20 6C 69 6E 65 2E 0A | one line.. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 54 68 69 73 20 69 73 20 74 68 65 20 69 6E 63 6C | This is the incl |
+| 75 64 65 20 66 69 6C 65 20 66 6F 72 20 74 65 73 | ude file for tes |
+| 74 20 53 43 31 33 65 2E 20 54 68 65 20 74 65 73 | t SC13e. The tes |
+| 74 20 69 73 20 74 6F 20 73 65 65 20 68 6F 77 20 | t is to see how |
+| 46 75 6E 6E 65 6C 57 65 62 0A 63 6F 70 65 73 20 | FunnelWeb.copes |
+| 77 69 74 68 20 61 6E 20 69 6E 63 6C 75 64 65 20 | with an include |
+| 66 69 6C 65 20 74 68 61 74 20 68 61 73 20 61 6E | file that has an |
+| 20 69 6D 70 72 6F 70 65 72 6C 79 20 74 65 72 6D | improperly term |
+| 69 6E 61 74 65 64 20 6C 61 73 74 20 6C 69 6E 65 | inated last line |
+| 2E 0A 0A 48 65 72 65 20 69 73 20 74 68 65 20 69 | ...Here is the i |
+| 6D 70 72 6F 70 65 72 20 74 65 72 6D 69 6E 61 74 | mproper terminat |
+| 69 6F 6E 21 2D 2D 2D 2D 3E | ion!----> |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 54 68 69 73 20 69 73 20 74 68 65 20 69 6E 63 6C | This is the incl |
+| 75 64 65 20 66 69 6C 65 20 66 6F 72 20 74 65 73 | ude file for tes |
+| 74 73 20 53 43 31 33 2E 36 20 61 6E 64 20 53 43 | ts SC13.6 and SC |
+| 31 33 2E 37 2E 0A 54 68 65 72 65 20 61 72 65 20 | 13.7..There are |
+| 6F 6E 6C 79 20 74 77 6F 20 6C 69 6E 65 73 2C 20 | only two lines, |
+| 61 6E 64 20 74 68 69 73 20 69 73 20 74 68 65 20 | and this is the |
+| 73 65 63 6F 6E 64 20 6F 6E 65 2E 0A | second one.. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 54 68 69 73 20 69 73 20 74 68 65 20 69 6E 63 6C | This is the incl |
+| 75 64 65 20 66 69 6C 65 20 66 6F 72 20 74 65 73 | ude file for tes |
+| 74 73 20 53 43 31 33 2E 36 20 61 6E 64 20 53 43 | ts SC13.6 and SC |
+| 31 33 2E 37 2E 0A 54 68 65 72 65 20 61 72 65 20 | 13.7..There are |
+| 6F 6E 6C 79 20 74 77 6F 20 6C 69 6E 65 73 2C 20 | only two lines, |
+| 61 6E 64 20 74 68 69 73 20 69 73 20 74 68 65 20 | and this is the |
+| 73 65 63 6F 6E 64 20 6F 6E 65 2E 0A | second one.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC13: Various kinds of include file.<010>
+00002 00002| <010>
+00003 00003| 1. Include file is empty.<010>
+00004 00004| Before include<010>
+00005 00005| @i sc13a<010>
+00006 00006| After include<010>
+00007 00007| <010>
+00008 00008| 2. Include file contains a single blank line.<010>
+00009 00009| Before include<010>
+00010 00010| @i sc13b<010>
+00011 00001| <010>
+00012 00011| After include<010>
+00013 00012| <010>
+00014 00013| 3. Include file contains two blank lines.<010>
+00015 00014| Before include<010>
+00016 00015| @i sc13c<010>
+00017 00001| <010>
+00018 00002| <010>
+00019 00016| After include<010>
+00020 00017| <010>
+00021 00018| 4. Include file contains a single line with text on it.<010>
+00022 00019| Before include<010>
+00023 00020| @i sc13d<010>
+00024 00001| This is the include file for test SC13d. Just a file containing one line.<010>
+00025 00021| After include<010>
+00026 00022| <010>
+00027 00023| 5. Include file's last line is not properly terminated.<010>
+00028 00024| Before include<010>
+00029 00025| @i sc13e<010>
+00030 00001| This is the include file for test SC13e. The test is to see how FunnelWeb<010>
+00031 00002| copes with an include file that has an improperly terminated last line.<010>
+00032 00003| <010>
+00033 00004| Here is the improper termination!----><010>
+00034 00026| After include<010>
+00035 00027| <010>
+00036 00028| 6. Include file is ordinary.<010>
+00037 00029| Before include<010>
+00038 00030| @i sc13f<010>
+00039 00001| This is the include file for tests SC13.6 and SC13.7.<010>
+00040 00002| There are only two lines, and this is the second one.<010>
+00041 00031| After include<010>
+00042 00032| <010>
+00043 00033| 7. Test upper case I and file extension inheritance.<010>
+00044 00034| Before include<010>
+00045 00035| @I sc13f<010>
+00046 00001| This is the include file for tests SC13.6 and SC13.7.<010>
+00047 00002| There are only two lines, and this is the second one.<010>
+00048 00036| After include<010>
+00049 00037| <010>
+00050 00038| End of test File.<010>
+00051 00039| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 15 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC13: Various kinds of include file.<010>
+<010>
+1. Include file is empty.<010>
+Before include<010>
+"
+0006[01]: Text. Text scrap[Grey]="After include<010>
+<010>
+2. Include file contains a single blank line.<010>
+Before include<010>
+"
+0011[01]: Text. Text scrap[White]="<010>
+"
+0012[01]: Text. Text scrap[Grey]="After include<010>
+<010>
+3. Include file contains two blank lines.<010>
+Before include<010>
+"
+0017[01]: Text. Text scrap[White]="<010>
+<010>
+"
+0019[01]: Text. Text scrap[Grey]="After include<010>
+<010>
+4. Include file contains a single line with text on it.<010>
+Before include<010>
+"
+0024[01]: Text. Text scrap[Grey]="This is the include file for test SC13d. Just a file containing one line.<010>
+"
+0025[01]: Text. Text scrap[Grey]="After include<010>
+<010>
+5. Include file's last line is not properly terminated.<010>
+Before include<010>
+"
+0030[01]: Text. Text scrap[Grey]="This is the include file for test SC13e. The test is to see how FunnelWeb<010>
+copes with an include file that has an improperly terminated last line.<010>
+<010>
+Here is the improper termination!----><010>
+"
+0034[01]: Text. Text scrap[Grey]="After include<010>
+<010>
+6. Include file is ordinary.<010>
+Before include<010>
+"
+0039[01]: Text. Text scrap[Grey]="This is the include file for tests SC13.6 and SC13.7.<010>
+There are only two lines, and this is the second one.<010>
+"
+0041[01]: Text. Text scrap[Grey]="After include<010>
+<010>
+7. Test upper case I and file extension inheritance.<010>
+Before include<010>
+"
+0046[01]: Text. Text scrap[Grey]="This is the include file for tests SC13.6 and SC13.7.<010>
+There are only two lines, and this is the second one.<010>
+"
+0048[01]: Text. Text scrap[Grey]="After include<010>
+<010>
+End of test File.<010>
+"
+0051[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="SC13: Various kinds of include file.<010>
+<010>
+1. Include file is empty.<010>
+Before include<010>
+"
+Text scrap[Grey]="After include<010>
+<010>
+2. Include file contains a single blank line.<010>
+Before include<010>
+"
+Text scrap[White]="<010>
+"
+Text scrap[Grey]="After include<010>
+<010>
+3. Include file contains two blank lines.<010>
+Before include<010>
+"
+Text scrap[White]="<010>
+<010>
+"
+Text scrap[Grey]="After include<010>
+<010>
+4. Include file contains a single line with text on it.<010>
+Before include<010>
+"
+Text scrap[Grey]="This is the include file for test SC13d. Just a file containing one line.<010>
+"
+Text scrap[Grey]="After include<010>
+<010>
+5. Include file's last line is not properly terminated.<010>
+Before include<010>
+"
+Text scrap[Grey]="This is the include file for test SC13e. The test is to see how FunnelWeb<010>
+copes with an include file that has an improperly terminated last line.<010>
+<010>
+Here is the improper termination!----><010>
+"
+Text scrap[Grey]="After include<010>
+<010>
+6. Include file is ordinary.<010>
+Before include<010>
+"
+Text scrap[Grey]="This is the include file for tests SC13.6 and SC13.7.<010>
+There are only two lines, and this is the second one.<010>
+"
+Text scrap[Grey]="After include<010>
+<010>
+7. Test upper case I and file extension inheritance.<010>
+Before include<010>
+"
+Text scrap[Grey]="This is the include file for tests SC13.6 and SC13.7.<010>
+There are only two lines, and this is the second one.<010>
+"
+Text scrap[Grey]="After include<010>
+<010>
+End of test File.<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+E: No macros defined.
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC13: Various kinds of include file.
+ 2 2|
+ 3 3| 1. Include file is empty.
+ 4 4| Before include
+ 5 5| @i sc13a
+ Warning|.^Include file is empty (not a byte in syte)!
+ 6 6| After include
+ 7 7|
+ 8 8| 2. Include file contains a single blank line.
+ 9 9| Before include
+ 10 10| @i sc13b
+ 11 1|
+ 12 11| After include
+ 13 12|
+ 14 13| 3. Include file contains two blank lines.
+ 15 14| Before include
+ 16 15| @i sc13c
+ 17 1|
+ 18 2|
+ 19 16| After include
+ 20 17|
+ 21 18| 4. Include file contains a single line with text on it.
+ 22 19| Before include
+ 23 20| @i sc13d
+ 24 1| This is the include file for test SC13d. Just a file containing one line.
+ 25 21| After include
+ 26 22|
+ 27 23| 5. Include file's last line is not properly terminated.
+ 28 24| Before include
+ 29 25| @i sc13e
+ 30 1| This is the include file for test SC13e. The test is to see how FunnelWeb
+ 31 2| copes with an include file that has an improperly terminated last line.
+ 32 3|
+ 33 4| Here is the improper termination!---->
+ 34 26| After include
+ Warning|.^The last line of the include file was terminated by EOF.
+ |.^An EOL was inserted at the end of the last line.
+ 35 27|
+ 36 28| 6. Include file is ordinary.
+ 37 29| Before include
+ 38 30| @i sc13f
+ 39 1| This is the include file for tests SC13.6 and SC13.7.
+ 40 2| There are only two lines, and this is the second one.
+ 41 31| After include
+ 42 32|
+ 43 33| 7. Test upper case I and file extension inheritance.
+ 44 34| Before include
+ 45 35| @I sc13f
+ 46 1| This is the include file for tests SC13.6 and SC13.7.
+ 47 2| There are only two lines, and this is the second one.
+ 48 36| After include
+ 49 37|
+ 50 38| End of test File.
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 2 Errors and 2 Warnings.
diff --git a/web/funnelAC/answers/sc14.lis b/web/funnelAC/answers/sc14.lis
new file mode 100644
index 0000000000..228c6c5f64
--- /dev/null
+++ b/web/funnelAC/answers/sc14.lis
@@ -0,0 +1,477 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00002 00002| This is most easily done with a recursive inclusion.<010>
+00003 00003| <010>
+00004 00004| Before the include<010>
+00005 00005| @i sc14.fw<010>
+00006 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00007 00002| This is most easily done with a recursive inclusion.<010>
+00008 00003| <010>
+00009 00004| Before the include<010>
+00010 00005| @i sc14.fw<010>
+00011 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00012 00002| This is most easily done with a recursive inclusion.<010>
+00013 00003| <010>
+00014 00004| Before the include<010>
+00015 00005| @i sc14.fw<010>
+00016 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00017 00002| This is most easily done with a recursive inclusion.<010>
+00018 00003| <010>
+00019 00004| Before the include<010>
+00020 00005| @i sc14.fw<010>
+00021 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00022 00002| This is most easily done with a recursive inclusion.<010>
+00023 00003| <010>
+00024 00004| Before the include<010>
+00025 00005| @i sc14.fw<010>
+00026 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00027 00002| This is most easily done with a recursive inclusion.<010>
+00028 00003| <010>
+00029 00004| Before the include<010>
+00030 00005| @i sc14.fw<010>
+00031 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00032 00002| This is most easily done with a recursive inclusion.<010>
+00033 00003| <010>
+00034 00004| Before the include<010>
+00035 00005| @i sc14.fw<010>
+00036 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00037 00002| This is most easily done with a recursive inclusion.<010>
+00038 00003| <010>
+00039 00004| Before the include<010>
+00040 00005| @i sc14.fw<010>
+00041 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00042 00002| This is most easily done with a recursive inclusion.<010>
+00043 00003| <010>
+00044 00004| Before the include<010>
+00045 00005| @i sc14.fw<010>
+00046 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00047 00002| This is most easily done with a recursive inclusion.<010>
+00048 00003| <010>
+00049 00004| Before the include<010>
+00050 00005| @i sc14.fw<010>
+00051 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00052 00002| This is most easily done with a recursive inclusion.<010>
+00053 00003| <010>
+00054 00004| Before the include<010>
+00055 00005| @i sc14.fw<010>
+00056 00006| After the include<010>
+00057 00006| After the include<010>
+00058 00006| After the include<010>
+00059 00006| After the include<010>
+00060 00006| After the include<010>
+00061 00006| After the include<010>
+00062 00006| After the include<010>
+00063 00006| After the include<010>
+00064 00006| After the include<010>
+00065 00006| After the include<010>
+00066 00006| After the include<010>
+00067 00007| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 23 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0006[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0011[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0016[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0021[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0026[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0031[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0036[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0041[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0046[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0051[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0056[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0057[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0058[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0059[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0060[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0061[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0062[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0063[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0064[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0065[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0066[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0067[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC14: Test that the maximum number of levels of include file is 10.
+ 2 2| This is most easily done with a recursive inclusion.
+ 3 3|
+ 4 4| Before the include
+ 5 5| @i sc14.fw
+ 6 1| SC14: Test that the maximum number of levels of include file is 10.
+ 7 2| This is most easily done with a recursive inclusion.
+ 8 3|
+ 9 4| Before the include
+ 10 5| @i sc14.fw
+ 11 1| SC14: Test that the maximum number of levels of include file is 10.
+ 12 2| This is most easily done with a recursive inclusion.
+ 13 3|
+ 14 4| Before the include
+ 15 5| @i sc14.fw
+ 16 1| SC14: Test that the maximum number of levels of include file is 10.
+ 17 2| This is most easily done with a recursive inclusion.
+ 18 3|
+ 19 4| Before the include
+ 20 5| @i sc14.fw
+ 21 1| SC14: Test that the maximum number of levels of include file is 10.
+ 22 2| This is most easily done with a recursive inclusion.
+ 23 3|
+ 24 4| Before the include
+ 25 5| @i sc14.fw
+ 26 1| SC14: Test that the maximum number of levels of include file is 10.
+ 27 2| This is most easily done with a recursive inclusion.
+ 28 3|
+ 29 4| Before the include
+ 30 5| @i sc14.fw
+ 31 1| SC14: Test that the maximum number of levels of include file is 10.
+ 32 2| This is most easily done with a recursive inclusion.
+ 33 3|
+ 34 4| Before the include
+ 35 5| @i sc14.fw
+ 36 1| SC14: Test that the maximum number of levels of include file is 10.
+ 37 2| This is most easily done with a recursive inclusion.
+ 38 3|
+ 39 4| Before the include
+ 40 5| @i sc14.fw
+ 41 1| SC14: Test that the maximum number of levels of include file is 10.
+ 42 2| This is most easily done with a recursive inclusion.
+ 43 3|
+ 44 4| Before the include
+ 45 5| @i sc14.fw
+ 46 1| SC14: Test that the maximum number of levels of include file is 10.
+ 47 2| This is most easily done with a recursive inclusion.
+ 48 3|
+ 49 4| Before the include
+ 50 5| @i sc14.fw
+ 51 1| SC14: Test that the maximum number of levels of include file is 10.
+ 52 2| This is most easily done with a recursive inclusion.
+ 53 3|
+ 54 4| Before the include
+ 55 5| @i sc14.fw
+ Error|.^This include file is nested too deeply. It's probably recursive.
+ |.^The maximum level of nested includes is 10.
+ |.^Include ignored.
+ 56 6| After the include
+ 57 6| After the include
+ 58 6| After the include
+ 59 6| After the include
+ 60 6| After the include
+ 61 6| After the include
+ 62 6| After the include
+ 63 6| After the include
+ 64 6| After the include
+ 65 6| After the include
+ 66 6| After the include
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There was 1 Error.
diff --git a/web/funnelAC/answers/sc15.lis b/web/funnelAC/answers/sc15.lis
new file mode 100644
index 0000000000..317e9453cc
--- /dev/null
+++ b/web/funnelAC/answers/sc15.lis
@@ -0,0 +1,355 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 35 3A 20 54 65 73 74 20 74 68 61 74 20 | SC15: Test that |
+| 63 65 72 74 61 69 6E 20 61 74 74 72 69 62 75 74 | certain attribut |
+| 65 73 20 61 72 65 20 73 61 76 65 64 20 61 63 72 | es are saved acr |
+| 6F 73 73 20 69 6E 63 6C 75 73 69 6F 6E 73 2E 0A | oss inclusions.. |
+| 0A 31 2E 20 4D 61 78 69 6D 75 6D 20 69 6E 70 75 | .1. Maximum inpu |
+| 74 20 6C 69 6E 65 20 6C 65 6E 67 74 68 2E 0A 32 | t line length..2 |
+| 2E 20 53 70 65 63 69 61 6C 20 63 68 61 72 61 63 | . Special charac |
+| 74 65 72 2E 0A 33 2E 20 4C 6F 63 61 6C 20 6C 69 | ter..3. Local li |
+| 6E 65 20 6E 75 6D 62 65 72 2E 0A 0A 54 6F 20 74 | ne number...To t |
+| 65 73 74 20 74 68 69 73 2C 20 77 65 20 66 69 72 | est this, we fir |
+| 73 74 20 73 65 74 20 74 68 65 20 66 69 72 73 74 | st set the first |
+| 20 74 77 6F 20 61 74 74 72 69 62 75 74 65 73 20 | two attributes |
+| 61 77 61 79 20 66 72 6F 6D 20 74 68 65 0A 64 65 | away from the.de |
+| 66 61 75 6C 74 2E 20 54 68 69 73 20 77 69 6C 6C | fault. This will |
+| 20 65 6E 61 62 6C 65 20 75 73 20 74 6F 20 62 65 | enable us to be |
+| 20 73 75 72 65 20 74 68 61 74 20 77 68 65 6E 20 | sure that when |
+| 74 68 65 79 20 61 72 65 20 72 65 73 74 6F 72 65 | they are restore |
+| 64 20 74 68 61 74 0A 74 68 65 79 20 61 72 65 20 | d that.they are |
+| 62 65 69 6E 67 20 72 65 73 74 6F 72 65 64 20 74 | being restored t |
+| 6F 20 74 68 65 69 72 20 66 6F 72 6D 65 72 20 76 | o their former v |
+| 61 6C 75 65 73 20 61 6E 64 20 6E 6F 74 20 6A 75 | alues and not ju |
+| 73 74 20 73 65 74 20 74 6F 20 74 68 65 0A 64 65 | st set to the.de |
+| 66 61 75 6C 74 2E 0A 0A 40 3D 2A 20 20 20 2A 21 | fault...@=* *! |
+| 20 43 68 61 6E 67 65 20 74 68 65 20 73 70 65 63 | Change the spec |
+| 69 61 6C 20 63 68 61 72 61 63 74 65 72 2E 0A 2A | ial character..* |
+| 70 20 6D 61 78 69 6D 75 6D 5F 69 6E 70 75 74 5F | p maximum_input_ |
+| 6C 69 6E 65 5F 6C 65 6E 67 74 68 20 3D 20 37 35 | line_length = 75 |
+| 0A 0A 42 65 66 6F 72 65 20 69 6E 63 6C 75 64 65 | ..Before include |
+| 2E 0A 2A 69 20 73 63 31 35 61 0A 41 66 74 65 72 | ..*i sc15a.After |
+| 20 69 6E 63 6C 75 64 65 2E 0A 0A 49 66 20 74 68 | include...If th |
+| 65 20 6D 61 78 69 6D 75 6D 20 69 6E 70 75 74 20 | e maximum input |
+| 6C 69 6E 65 20 6C 65 6E 67 74 68 20 68 61 73 20 | line length has |
+| 62 65 65 6E 20 63 6F 72 72 65 63 74 6C 79 20 72 | been correctly r |
+| 65 73 74 6F 72 65 64 20 74 68 65 6E 20 74 68 65 | estored then the |
+| 0A 73 65 63 6F 6E 64 20 6F 66 20 74 68 65 20 66 | .second of the f |
+| 6F 6C 6C 6F 77 69 6E 67 20 74 77 6F 20 6C 69 6E | ollowing two lin |
+| 65 73 20 73 68 6F 75 6C 64 20 67 69 76 65 20 61 | es should give a |
+| 6E 20 65 72 72 6F 72 2C 20 62 75 74 20 6E 6F 74 | n error, but not |
+| 20 74 68 65 20 66 69 72 73 74 2E 0A 31 32 33 34 | the first..1234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 0A 31 32 33 34 35 36 37 38 | 9012345.12345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 0A 0A 49 66 20 74 68 65 20 73 70 65 | 3456..If the spe |
+| 63 69 61 6C 20 63 68 61 72 61 63 74 65 72 20 68 | cial character h |
+| 61 73 20 62 65 65 6E 20 70 72 65 73 65 72 76 65 | as been preserve |
+| 64 2C 20 74 68 65 6E 20 74 68 65 20 66 6F 6C 6C | d, then the foll |
+| 6F 77 69 6E 67 20 73 68 6F 75 6C 64 0A 67 65 6E | owing should.gen |
+| 65 72 61 74 65 20 61 6E 20 65 72 72 6F 72 2E 0A | erate an error.. |
+| 0A 2A 20 20 20 2D 20 54 68 69 73 20 73 68 6F 75 | .* - This shou |
+| 6C 64 20 67 65 6E 65 72 61 74 65 20 61 6E 20 65 | ld generate an e |
+| 72 72 6F 72 20 69 66 20 61 6C 6C 20 69 73 20 77 | rror if all is w |
+| 65 6C 6C 2E 0A 0A 50 72 65 73 65 72 76 61 74 69 | ell...Preservati |
+| 6F 6E 20 6F 66 20 74 68 65 20 6C 6F 63 61 6C 20 | on of the local |
+| 6C 69 6E 65 20 6E 75 6D 62 65 72 20 63 61 6E 20 | line number can |
+| 62 65 20 63 68 65 63 6B 65 64 20 62 79 20 6C 6F | be checked by lo |
+| 6F 6B 69 6E 67 20 61 74 20 74 68 65 0A 6C 69 73 | oking at the.lis |
+| 74 69 6E 67 20 66 69 6C 65 2E 0A | ting file.. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 54 68 69 73 20 69 73 20 74 68 65 20 69 6E 63 6C | This is the incl |
+| 75 64 65 20 66 69 6C 65 20 66 6F 72 20 74 65 73 | ude file for tes |
+| 74 20 53 43 31 35 2E 20 54 68 65 20 53 43 31 35 | t SC15. The SC15 |
+| 20 74 65 73 74 20 63 68 65 63 6B 73 20 74 6F 20 | test checks to |
+| 6D 61 6B 65 0A 73 75 72 65 20 74 68 61 74 20 46 | make.sure that F |
+| 75 6E 6E 65 6C 57 65 62 20 69 73 20 73 61 76 69 | unnelWeb is savi |
+| 6E 67 20 61 6E 64 20 72 65 73 74 6F 72 69 6E 67 | ng and restoring |
+| 20 74 68 72 65 65 20 73 63 61 6E 6E 69 6E 67 0A | three scanning. |
+| 61 74 74 72 69 62 75 74 65 73 20 61 63 72 6F 73 | attributes acros |
+| 73 20 69 6E 63 6C 75 64 65 20 66 69 6C 65 73 2E | s include files. |
+| 20 57 65 20 61 6C 73 6F 20 77 61 6E 74 20 74 6F | We also want to |
+| 20 6D 61 6B 65 20 73 75 72 65 0A 74 68 61 74 20 | make sure.that |
+| 74 68 65 20 73 63 61 6E 6E 65 72 20 69 73 20 69 | the scanner is i |
+| 6E 69 74 69 61 6C 69 7A 69 6E 67 20 74 68 65 73 | nitializing thes |
+| 65 20 61 74 74 72 69 62 75 74 65 73 20 63 6F 72 | e attributes cor |
+| 72 65 63 74 6C 79 20 77 69 74 68 69 6E 0A 74 68 | rectly within.th |
+| 65 20 69 6E 63 6C 75 64 65 20 66 69 6C 65 2E 0A | e include file.. |
+| 0A 53 43 31 35 2E 34 3A 20 4D 61 6B 65 20 73 75 | .SC15.4: Make su |
+| 72 65 20 74 68 61 74 20 74 68 65 20 73 70 65 63 | re that the spec |
+| 69 61 6C 20 63 68 61 72 61 63 74 65 72 20 69 73 | ial character is |
+| 20 41 54 20 61 74 20 74 68 65 20 73 74 61 72 74 | AT at the start |
+| 20 6F 66 0A 69 6E 63 6C 75 64 65 20 66 69 6C 65 | of.include file |
+| 73 2E 0A 0A 40 20 20 20 20 2D 20 54 68 69 73 20 | s...@ - This |
+| 73 68 6F 75 6C 64 20 79 69 65 6C 64 20 61 6E 20 | should yield an |
+| 65 72 72 6F 72 2E 0A 0A 53 43 31 35 2E 35 20 45 | error...SC15.5 E |
+| 6E 73 75 72 65 20 74 68 61 74 20 74 68 65 20 6D | nsure that the m |
+| 61 78 69 6D 75 6D 20 69 6E 70 75 74 20 6C 69 6E | aximum input lin |
+| 65 20 6C 65 6E 67 74 68 20 69 73 20 38 30 20 61 | e length is 80 a |
+| 74 20 74 68 65 20 73 74 61 72 74 0A 6F 66 20 61 | t the start.of a |
+| 6E 20 69 6E 63 6C 75 64 65 20 66 69 6C 65 2E 20 | n include file. |
+| 49 66 20 61 6C 6C 20 69 73 20 77 65 6C 6C 2C 20 | If all is well, |
+| 6F 6E 6C 79 20 74 68 65 20 73 65 63 6F 6E 64 20 | only the second |
+| 6F 66 20 74 68 65 20 66 6F 6C 6C 6F 77 69 6E 67 | of the following |
+| 20 74 77 6F 0A 6C 69 6E 65 73 20 77 69 6C 6C 20 | two.lines will |
+| 70 72 6F 76 6F 6B 65 20 61 20 22 6C 69 6E 65 20 | provoke a "line |
+| 74 6F 6F 20 6C 6F 6E 67 22 20 65 72 72 6F 72 2E | too long" error. |
+| 0A 0A 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | ..12345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 0A 31 32 33 34 35 36 37 38 39 30 31 32 33 | 90.1234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 0A 0A 4E 6F 77 20 74 68 61 74 20 77 | 8901..Now that w |
+| 65 20 68 61 76 65 20 63 68 65 63 6B 65 64 20 74 | e have checked t |
+| 68 65 20 64 65 66 61 75 6C 74 20 61 74 74 72 69 | he default attri |
+| 62 75 74 65 73 20 6F 6E 20 65 6E 74 65 72 69 6E | butes on enterin |
+| 67 20 61 6E 20 69 6E 63 6C 75 64 65 20 66 69 6C | g an include fil |
+| 65 2C 0A 77 65 20 77 61 6E 74 20 74 6F 20 73 74 | e,.we want to st |
+| 75 66 66 20 74 68 65 6D 20 75 70 20 73 6F 20 61 | uff them up so a |
+| 73 20 74 6F 20 6D 61 6B 65 20 73 75 72 65 20 74 | s to make sure t |
+| 68 61 74 20 74 68 65 20 61 74 74 72 69 62 75 74 | hat the attribut |
+| 65 73 0A 70 72 65 76 61 69 6C 69 6E 67 20 77 68 | es.prevailing wh |
+| 65 6E 20 74 68 65 20 69 6E 63 6C 75 64 65 20 77 | en the include w |
+| 61 73 20 68 69 74 20 61 72 65 20 72 65 73 74 6F | as hit are resto |
+| 72 65 64 2E 0A 0A 40 70 20 6D 61 78 69 6D 75 6D | red...@p maximum |
+| 5F 69 6E 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 | _input_line_leng |
+| 74 68 20 3D 20 36 35 0A 40 3D 2B 0A 0A | th = 65.@=+.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC15: Test that certain attributes are saved across inclusions.<010>
+00002 00002| <010>
+00003 00003| 1. Maximum input line length.<010>
+00004 00004| 2. Special character.<010>
+00005 00005| 3. Local line number.<010>
+00006 00006| <010>
+00007 00007| To test this, we first set the first two attributes away from the<010>
+00008 00008| default. This will enable us to be sure that when they are restored that<010>
+00009 00009| they are being restored to their former values and not just set to the<010>
+00010 00010| default.<010>
+00011 00011| <010>
+00012 00012| @=* *! Change the special character.<010>
+00013 00013| *p maximum_input_line_length = 75<010>
+00014 00014| <010>
+00015 00015| Before include.<010>
+00016 00016| *i sc15a<010>
+00017 00001| This is the include file for test SC15. The SC15 test checks to make<010>
+00018 00002| sure that FunnelWeb is saving and restoring three scanning<010>
+00019 00003| attributes across include files. We also want to make sure<010>
+00020 00004| that the scanner is initializing these attributes correctly within<010>
+00021 00005| the include file.<010>
+00022 00006| <010>
+00023 00007| SC15.4: Make sure that the special character is AT at the start of<010>
+00024 00008| include files.<010>
+00025 00009| <010>
+00026 00010| @ - This should yield an error.<010>
+00027 00011| <010>
+00028 00012| SC15.5 Ensure that the maximum input line length is 80 at the start<010>
+00029 00013| of an include file. If all is well, only the second of the following two<010>
+00030 00014| lines will provoke a "line too long" error.<010>
+00031 00015| <010>
+00032 00016| 12345678901234567890123456789012345678901234567890123456789012345678901234567890<010>
+00033 00017| 123456789012345678901234567890123456789012345678901234567890123456789012345678901<010>
+00034 00018| <010>
+00035 00019| Now that we have checked the default attributes on entering an include file,<010>
+00036 00020| we want to stuff them up so as to make sure that the attributes<010>
+00037 00021| prevailing when the include was hit are restored.<010>
+00038 00022| <010>
+00039 00023| @p maximum_input_line_length = 65<010>
+00040 00024| @=+<010>
+00041 00025| <010>
+00042 00017| After include.<010>
+00043 00018| <010>
+00044 00019| If the maximum input line length has been correctly restored then the<010>
+00045 00020| second of the following two lines should give an error, but not the first.<010>
+00046 00021| 123456789012345678901234567890123456789012345678901234567890123456789012345<010>
+00047 00022| 1234567890123456789012345678901234567890123456789012345678901234567890123456<010>
+00048 00023| <010>
+00049 00024| If the special character has been preserved, then the following should<010>
+00050 00025| generate an error.<010>
+00051 00026| <010>
+00052 00027| * - This should generate an error if all is well.<010>
+00053 00028| <010>
+00054 00029| Preservation of the local line number can be checked by looking at the<010>
+00055 00030| listing file.<010>
+00056 00031| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 9 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC15: Test that certain attributes are saved across inclusions.<010>
+<010>
+1. Maximum input line length.<010>
+2. Special character.<010>
+3. Local line number.<010>
+<010>
+To test this, we first set the first two attributes away from the<010>
+default. This will enable us to be sure that when they are restored that<010>
+they are being restored to their former values and not just set to the<010>
+default.<010>
+<010>
+"
+0012[04]: Text. Text scrap[White]=" "
+0014[01]: Text. Text scrap[Grey]="<010>
+Before include.<010>
+"
+0017[01]: Text. Text scrap[Grey]="This is the include file for test SC15. The SC15 test checks to make<010>
+sure that FunnelWeb is saving and restoring three scanning<010>
+attributes across include files. We also want to make sure<010>
+that the scanner is initializing these attributes correctly within<010>
+the include file.<010>
+<010>
+SC15.4: Make sure that the special character is AT at the start of<010>
+include files.<010>
+<010>
+"
+0026[03]: Text. Text scrap[Grey]=" - This should yield an error.<010>
+<010>
+SC15.5 Ensure that the maximum input line length is 80 at the start<010>
+of an include file. If all is well, only the second of the following two<010>
+lines will provoke a "line too long" error.<010>
+<010>
+12345678901234567890123456789012345678901234567890123456789012345678901234567890<010>
+123456789012345678901234567890123456789012345678901234567890123456789012345678901<010>
+<010>
+Now that we have checked the default attributes on entering an include file,<010>
+we want to stuff them up so as to make sure that the attributes<010>
+prevailing when the include was hit are restored.<010>
+<010>
+"
+0040[04]: Text. Text scrap[White]="<010>
+<010>
+"
+0042[01]: Text. Text scrap[Grey]="After include.<010>
+<010>
+If the maximum input line length has been correctly restored then the<010>
+second of the following two lines should give an error, but not the first.<010>
+123456789012345678901234567890123456789012345678901234567890123456789012345<010>
+1234567890123456789012345678901234567890123456789012345678901234567890123456<010>
+<010>
+If the special character has been preserved, then the following should<010>
+generate an error.<010>
+<010>
+"
+0052[03]: Text. Text scrap[Grey]=" - This should generate an error if all is well.<010>
+<010>
+Preservation of the local line number can be checked by looking at the<010>
+listing file.<010>
+"
+0056[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC15: Test that certain attributes are saved across inclusions.
+ 2 2|
+ 3 3| 1. Maximum input line length.
+ 4 4| 2. Special character.
+ 5 5| 3. Local line number.
+ 6 6|
+ 7 7| To test this, we first set the first two attributes away from the
+ 8 8| default. This will enable us to be sure that when they are restored that
+ 9 9| they are being restored to their former values and not just set to the
+ 10 10| default.
+ 11 11|
+ 12 12| @=* *! Change the special character.
+ 13 13| *p maximum_input_line_length = 75
+ 14 14|
+ 15 15| Before include.
+ 16 16| *i sc15a
+ 17 1| This is the include file for test SC15. The SC15 test checks to make
+ 18 2| sure that FunnelWeb is saving and restoring three scanning
+ 19 3| attributes across include files. We also want to make sure
+ 20 4| that the scanner is initializing these attributes correctly within
+ 21 5| the include file.
+ 22 6|
+ 23 7| SC15.4: Make sure that the special character is AT at the start of
+ 24 8| include files.
+ 25 9|
+ 26 10| @ - This should yield an error.
+ Error|.^<special><space> is not a legal special sequence.
+ 27 11|
+ 28 12| SC15.5 Ensure that the maximum input line length is 80 at the start
+ 29 13| of an include file. If all is well, only the second of the following two
+ 30 14| lines will provoke a "line too long" error.
+ 31 15|
+ 32 16| 12345678901234567890123456789012345678901234567890123456789012345678901234567890
+ 33 17| 123456789012345678901234567890123456789012345678901234567890123456789012345678901
+ Error|.................................................................................^Input line is too long (this character is the first offender).
+ |.................................................................................^Currently, the maximum allowable input line length is 80.
+ |.................................................................................^Note: You can change this using a pragma directive (@p).
+ 34 18|
+ 35 19| Now that we have checked the default attributes on entering an include file,
+ 36 20| we want to stuff them up so as to make sure that the attributes
+ 37 21| prevailing when the include was hit are restored.
+ 38 22|
+ 39 23| @p maximum_input_line_length = 65
+ 40 24| @=+
+ 41 25|
+ 42 17| After include.
+ 43 18|
+ 44 19| If the maximum input line length has been correctly restored then the
+ 45 20| second of the following two lines should give an error, but not the first.
+ 46 21| 123456789012345678901234567890123456789012345678901234567890123456789012345
+ 47 22| 1234567890123456789012345678901234567890123456789012345678901234567890123456
+ Error|............................................................................^Input line is too long (this character is the first offender).
+ |............................................................................^Currently, the maximum allowable input line length is 75.
+ |............................................................................^Note: You can change this using a pragma directive (@p).
+ 48 23|
+ 49 24| If the special character has been preserved, then the following should
+ 50 25| generate an error.
+ 51 26|
+ 52 27| * - This should generate an error if all is well.
+ Error|.^<special><space> is not a legal special sequence.
+ 53 28|
+ 54 29| Preservation of the local line number can be checked by looking at the
+ 55 30| listing file.
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 4 Errors.
diff --git a/web/funnelAC/answers/sc16.lis b/web/funnelAC/answers/sc16.lis
new file mode 100644
index 0000000000..3170ba293f
--- /dev/null
+++ b/web/funnelAC/answers/sc16.lis
@@ -0,0 +1,456 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 36 3A 20 54 65 73 74 20 3C 73 70 65 63 | SC16: Test <spec |
+| 69 61 6C 3E 5E 20 73 65 71 75 65 6E 63 65 2E 0A | ial>^ sequence.. |
+| 0A 31 2E 20 54 65 73 74 20 74 68 61 74 20 61 6C | .1. Test that al |
+| 6C 20 62 61 73 65 20 63 68 61 72 61 63 74 65 72 | l base character |
+| 73 20 77 6F 72 6B 20 28 69 6E 20 62 6F 74 68 20 | s work (in both |
+| 63 61 73 65 73 29 2E 0A 20 20 20 54 68 65 73 65 | cases).. These |
+| 20 73 68 6F 75 6C 64 20 70 72 6F 76 6F 6B 65 20 | should provoke |
+| 6E 6F 20 65 72 72 6F 72 73 2E 0A 0A 20 20 20 40 | no errors... @ |
+| 5E 42 28 30 30 30 30 30 30 30 30 29 20 20 20 40 | ^B(00000000) @ |
+| 5E 62 28 30 30 30 30 30 30 30 30 29 0A 20 20 20 | ^b(00000000). |
+| 40 5E 4F 28 30 30 30 29 20 20 20 40 5E 6F 28 30 | @^O(000) @^o(0 |
+| 30 30 29 0A 20 20 20 40 5E 51 28 30 30 30 29 20 | 00). @^Q(000) |
+| 20 20 40 5E 71 28 30 30 30 29 0A 20 20 20 40 5E | @^q(000). @^ |
+| 44 28 30 30 30 29 20 20 20 40 5E 64 28 30 30 30 | D(000) @^d(000 |
+| 29 0A 20 20 20 40 5E 48 28 30 30 29 20 20 20 20 | ). @^H(00) |
+| 40 5E 68 28 30 30 29 0A 20 20 20 40 5E 58 28 30 | @^h(00). @^X(0 |
+| 30 29 20 20 20 20 40 5E 78 28 30 30 29 0A 0A 32 | 0) @^x(00)..2 |
+| 2E 20 54 65 73 74 20 74 68 61 74 20 73 6F 6D 65 | . Test that some |
+| 20 6F 74 68 65 72 20 62 61 73 65 20 63 68 61 72 | other base char |
+| 61 63 74 65 72 73 20 67 65 6E 65 72 61 74 65 20 | acters generate |
+| 61 6E 20 65 72 72 6F 72 2E 0A 0A 20 20 20 40 5E | an error... @^ |
+| 75 28 30 29 0A 20 20 20 40 5E 79 0A 20 20 20 40 | u(0). @^y. @ |
+| 5E 23 0A 20 20 20 40 5E 28 0A 0A 33 2E 20 54 65 | ^#. @^(..3. Te |
+| 73 74 20 74 68 61 74 20 61 6E 20 65 72 72 6F 72 | st that an error |
+| 20 69 73 20 67 65 6E 65 72 61 74 65 64 20 69 66 | is generated if |
+| 20 70 61 72 65 6E 74 68 65 73 69 73 20 69 73 20 | parenthesis is |
+| 6D 69 73 73 69 6E 67 2E 0A 0A 20 20 20 40 5E 44 | missing... @^D |
+| 33 34 29 0A 0A 34 2E 20 54 65 73 74 20 6C 65 67 | 34)..4. Test leg |
+| 61 6C 20 64 69 67 69 74 73 20 69 6E 20 65 61 63 | al digits in eac |
+| 68 20 62 61 73 65 2E 0A 0A 20 20 20 40 5E 42 28 | h base... @^B( |
+| 30 30 30 30 31 31 31 31 29 0A 20 20 20 40 5E 4F | 00001111). @^O |
+| 28 30 31 32 29 20 20 40 5E 4F 28 30 33 34 29 20 | (012) @^O(034) |
+| 40 5E 4F 28 30 35 36 29 20 40 5E 4F 28 30 37 37 | @^O(056) @^O(077 |
+| 29 0A 20 20 20 40 5E 44 28 30 31 32 29 20 20 40 | ). @^D(012) @ |
+| 5E 44 28 30 33 34 29 20 40 5E 44 28 30 35 36 29 | ^D(034) @^D(056) |
+| 20 40 5E 44 28 30 37 38 29 20 40 5E 44 28 30 39 | @^D(078) @^D(09 |
+| 39 29 0A 20 20 20 40 5E 48 28 30 31 29 20 40 5E | 9). @^H(01) @^ |
+| 48 28 32 33 29 20 40 5E 48 28 34 35 29 20 40 5E | H(23) @^H(45) @^ |
+| 48 28 36 37 29 0A 20 20 20 40 5E 48 28 38 39 29 | H(67). @^H(89) |
+| 20 40 5E 48 28 41 42 29 20 40 5E 58 28 43 44 29 | @^H(AB) @^X(CD) |
+| 20 40 5E 58 28 45 46 29 20 20 40 5E 78 28 61 66 | @^X(EF) @^x(af |
+| 29 0A 0A 35 2E 20 54 65 73 74 20 69 6C 6C 65 67 | )..5. Test illeg |
+| 61 6C 20 64 69 67 69 74 73 20 69 6E 20 65 61 63 | al digits in eac |
+| 68 20 62 61 73 65 2E 0A 0A 20 20 20 40 5E 42 28 | h base... @^B( |
+| 30 30 30 30 30 30 30 32 29 0A 20 20 20 40 5E 4F | 00000002). @^O |
+| 28 30 30 38 29 0A 20 20 20 40 5E 44 28 30 30 41 | (008). @^D(00A |
+| 29 0A 20 20 20 40 5E 48 28 30 47 29 0A 0A 36 2E | ). @^H(0G)..6. |
+| 20 54 65 73 74 20 77 68 61 74 20 68 61 70 70 65 | Test what happe |
+| 6E 73 20 69 66 20 74 68 65 72 65 20 61 72 65 20 | ns if there are |
+| 74 68 65 20 77 72 6F 6E 67 20 6E 75 6D 62 65 72 | the wrong number |
+| 20 6F 66 20 64 69 67 69 74 73 0A 20 20 20 28 74 | of digits. (t |
+| 6F 6F 20 66 65 77 2C 20 74 6F 6F 20 6D 61 6E 79 | oo few, too many |
+| 29 2E 0A 0A 20 20 20 40 5E 42 28 31 29 0A 20 20 | )... @^B(1). |
+| 20 40 5E 4F 28 31 29 0A 20 20 20 40 5E 44 28 31 | @^O(1). @^D(1 |
+| 29 0A 20 20 20 40 5E 48 28 31 29 0A 0A 20 20 20 | ). @^H(1).. |
+| 40 5E 42 28 30 30 30 30 30 30 30 30 31 29 0A 20 | @^B(000000001). |
+| 20 20 40 5E 4F 28 30 30 30 34 29 0A 20 20 20 40 | @^O(0004). @ |
+| 5E 44 28 30 30 30 31 29 0A 20 20 20 40 5E 48 28 | ^D(0001). @^H( |
+| 30 30 35 29 0A 0A 37 2E 20 54 65 73 74 20 74 68 | 005)..7. Test th |
+| 61 74 20 61 6E 20 65 72 72 6F 72 20 69 73 20 67 | at an error is g |
+| 65 6E 65 72 61 74 65 64 20 66 6F 72 20 61 20 6D | enerated for a m |
+| 69 73 73 69 6E 67 20 63 6C 6F 73 69 6E 67 20 70 | issing closing p |
+| 61 72 65 6E 74 68 65 73 69 73 2E 0A 0A 20 20 40 | arenthesis... @ |
+| 5E 42 28 30 30 30 30 30 30 30 30 0A 20 20 40 5E | ^B(00000000. @^ |
+| 44 28 30 34 35 28 0A 0A 38 2E 20 54 65 73 74 20 | D(045(..8. Test |
+| 77 68 61 74 20 68 61 70 70 65 6E 73 20 69 6E 20 | what happens in |
+| 6E 75 6D 62 65 72 20 69 73 20 6F 75 74 20 6F 66 | number is out of |
+| 20 74 68 65 20 72 61 6E 67 65 20 5B 30 2C 32 35 | the range [0,25 |
+| 35 5D 2E 0A 0A 20 20 40 5E 44 28 32 35 35 29 0A | 5]... @^D(255). |
+| 20 20 40 5E 44 28 32 35 36 29 0A 20 20 40 5E 44 | @^D(256). @^D |
+| 28 39 39 39 29 0A 0A | (999).. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC16: Test <special>^ sequence.<010>
+00002 00002| <010>
+00003 00003| 1. Test that all base characters work (in both cases).<010>
+00004 00004| These should provoke no errors.<010>
+00005 00005| <010>
+00006 00006| @^B(00000000) @^b(00000000)<010>
+00007 00007| @^O(000) @^o(000)<010>
+00008 00008| @^Q(000) @^q(000)<010>
+00009 00009| @^D(000) @^d(000)<010>
+00010 00010| @^H(00) @^h(00)<010>
+00011 00011| @^X(00) @^x(00)<010>
+00012 00012| <010>
+00013 00013| 2. Test that some other base characters generate an error.<010>
+00014 00014| <010>
+00015 00015| @^u(0)<010>
+00016 00016| @^y<010>
+00017 00017| @^#<010>
+00018 00018| @^(<010>
+00019 00019| <010>
+00020 00020| 3. Test that an error is generated if parenthesis is missing.<010>
+00021 00021| <010>
+00022 00022| @^D34)<010>
+00023 00023| <010>
+00024 00024| 4. Test legal digits in each base.<010>
+00025 00025| <010>
+00026 00026| @^B(00001111)<010>
+00027 00027| @^O(012) @^O(034) @^O(056) @^O(077)<010>
+00028 00028| @^D(012) @^D(034) @^D(056) @^D(078) @^D(099)<010>
+00029 00029| @^H(01) @^H(23) @^H(45) @^H(67)<010>
+00030 00030| @^H(89) @^H(AB) @^X(CD) @^X(EF) @^x(af)<010>
+00031 00031| <010>
+00032 00032| 5. Test illegal digits in each base.<010>
+00033 00033| <010>
+00034 00034| @^B(00000002)<010>
+00035 00035| @^O(008)<010>
+00036 00036| @^D(00A)<010>
+00037 00037| @^H(0G)<010>
+00038 00038| <010>
+00039 00039| 6. Test what happens if there are the wrong number of digits<010>
+00040 00040| (too few, too many).<010>
+00041 00041| <010>
+00042 00042| @^B(1)<010>
+00043 00043| @^O(1)<010>
+00044 00044| @^D(1)<010>
+00045 00045| @^H(1)<010>
+00046 00046| <010>
+00047 00047| @^B(000000001)<010>
+00048 00048| @^O(0004)<010>
+00049 00049| @^D(0001)<010>
+00050 00050| @^H(005)<010>
+00051 00051| <010>
+00052 00052| 7. Test that an error is generated for a missing closing parenthesis.<010>
+00053 00053| <010>
+00054 00054| @^B(00000000<010>
+00055 00055| @^D(045(<010>
+00056 00056| <010>
+00057 00057| 8. Test what happens in number is out of the range [0,255].<010>
+00058 00058| <010>
+00059 00059| @^D(255)<010>
+00060 00060| @^D(256)<010>
+00061 00061| @^D(999)<010>
+00062 00062| <010>
+00063 00063| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 87 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC16: Test <special>^ sequence.<010>
+<010>
+1. Test that all base characters work (in both cases).<010>
+ These should provoke no errors.<010>
+<010>
+ "
+0006[04]: Text. Text scrap[Grey]="<000>"
+0006[17]: Text. Text scrap[White]=" "
+0006[20]: Text. Text scrap[Grey]="<000>"
+0006[33]: Text. Text scrap[White]="<010>
+ "
+0007[04]: Text. Text scrap[Grey]="<000>"
+0007[12]: Text. Text scrap[White]=" "
+0007[15]: Text. Text scrap[Grey]="<000>"
+0007[23]: Text. Text scrap[White]="<010>
+ "
+0008[04]: Text. Text scrap[Grey]="<000>"
+0008[12]: Text. Text scrap[White]=" "
+0008[15]: Text. Text scrap[Grey]="<000>"
+0008[23]: Text. Text scrap[White]="<010>
+ "
+0009[04]: Text. Text scrap[Grey]="<000>"
+0009[12]: Text. Text scrap[White]=" "
+0009[15]: Text. Text scrap[Grey]="<000>"
+0009[23]: Text. Text scrap[White]="<010>
+ "
+0010[04]: Text. Text scrap[Grey]="<000>"
+0010[11]: Text. Text scrap[White]=" "
+0010[15]: Text. Text scrap[Grey]="<000>"
+0010[22]: Text. Text scrap[White]="<010>
+ "
+0011[04]: Text. Text scrap[Grey]="<000>"
+0011[11]: Text. Text scrap[White]=" "
+0011[15]: Text. Text scrap[Grey]="<000>"
+0011[22]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test that some other base characters generate an error.<010>
+<010>
+ "
+0015[07]: Text. Text scrap[Grey]="(0)<010>
+ "
+0016[07]: Text. Text scrap[White]="<010>
+ "
+0017[07]: Text. Text scrap[White]="<010>
+ "
+0018[07]: Text. Text scrap[Grey]="<010>
+<010>
+3. Test that an error is generated if parenthesis is missing.<010>
+<010>
+ "
+0022[08]: Text. Text scrap[Grey]="4)<010>
+<010>
+4. Test legal digits in each base.<010>
+<010>
+ "
+0026[04]: Text. Text scrap[Grey]="<015>"
+0026[17]: Text. Text scrap[White]="<010>
+ "
+0027[04]: Text. Text scrap[Grey]="<010>
+"
+0027[12]: Text. Text scrap[White]=" "
+0027[14]: Text. Text scrap[Grey]="<028>"
+0027[22]: Text. Text scrap[White]=" "
+0027[23]: Text. Text scrap[Grey]="."
+0027[31]: Text. Text scrap[White]=" "
+0027[32]: Text. Text scrap[Grey]="?"
+0027[40]: Text. Text scrap[White]="<010>
+ "
+0028[04]: Text. Text scrap[Grey]="<012>"
+0028[12]: Text. Text scrap[White]=" "
+0028[14]: Text. Text scrap[Grey]="""
+0028[22]: Text. Text scrap[White]=" "
+0028[23]: Text. Text scrap[Grey]="8"
+0028[31]: Text. Text scrap[White]=" "
+0028[32]: Text. Text scrap[Grey]="N"
+0028[40]: Text. Text scrap[White]=" "
+0028[41]: Text. Text scrap[Grey]="c"
+0028[49]: Text. Text scrap[White]="<010>
+ "
+0029[04]: Text. Text scrap[Grey]="<001>"
+0029[11]: Text. Text scrap[White]=" "
+0029[12]: Text. Text scrap[Grey]="#"
+0029[19]: Text. Text scrap[White]=" "
+0029[20]: Text. Text scrap[Grey]="E"
+0029[27]: Text. Text scrap[White]=" "
+0029[28]: Text. Text scrap[Grey]="g"
+0029[35]: Text. Text scrap[White]="<010>
+ "
+0030[04]: Text. Text scrap[Grey]="<137>"
+0030[11]: Text. Text scrap[White]=" "
+0030[12]: Text. Text scrap[Grey]="<171>"
+0030[19]: Text. Text scrap[White]=" "
+0030[20]: Text. Text scrap[Grey]="<205>"
+0030[27]: Text. Text scrap[White]=" "
+0030[28]: Text. Text scrap[Grey]="<239>"
+0030[35]: Text. Text scrap[White]=" "
+0030[37]: Text. Text scrap[Grey]="<175>"
+0030[44]: Text. Text scrap[Grey]="<010>
+<010>
+5. Test illegal digits in each base.<010>
+<010>
+ "
+0034[16]: Text. Text scrap[Grey]=")<010>
+ "
+0035[11]: Text. Text scrap[Grey]=")<010>
+ "
+0036[11]: Text. Text scrap[Grey]=")<010>
+ "
+0037[10]: Text. Text scrap[Grey]=")<010>
+<010>
+6. Test what happens if there are the wrong number of digits<010>
+ (too few, too many).<010>
+<010>
+ "
+0042[10]: Text. Text scrap[White]="<010>
+ "
+0043[10]: Text. Text scrap[White]="<010>
+ "
+0044[10]: Text. Text scrap[White]="<010>
+ "
+0045[10]: Text. Text scrap[White]="<010>
+<010>
+ "
+0047[17]: Text. Text scrap[Grey]=")<010>
+ "
+0048[12]: Text. Text scrap[Grey]=")<010>
+ "
+0049[12]: Text. Text scrap[Grey]=")<010>
+ "
+0050[11]: Text. Text scrap[Grey]=")<010>
+<010>
+7. Test that an error is generated for a missing closing parenthesis.<010>
+<010>
+ "
+0055[01]: Text. Text scrap[White]=" "
+0055[11]: Text. Text scrap[Grey]="<010>
+<010>
+8. Test what happens in number is out of the range [0,255].<010>
+<010>
+ "
+0059[03]: Text. Text scrap[Grey]="<255>"
+0059[11]: Text. Text scrap[White]="<010>
+ "
+0060[11]: Text. Text scrap[White]="<010>
+ "
+0061[11]: Text. Text scrap[White]="<010>
+<010>
+"
+0063[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC16: Test <special>^ sequence.
+ 2 2|
+ 3 3| 1. Test that all base characters work (in both cases).
+ 4 4| These should provoke no errors.
+ 5 5|
+ 6 6| @^B(00000000) @^b(00000000)
+ 7 7| @^O(000) @^o(000)
+ 8 8| @^Q(000) @^q(000)
+ 9 9| @^D(000) @^d(000)
+ 10 10| @^H(00) @^h(00)
+ 11 11| @^X(00) @^x(00)
+ 12 12|
+ 13 13| 2. Test that some other base characters generate an error.
+ 14 14|
+ 15 15| @^u(0)
+ Error|......^Expecting one of 'B', 'Q', 'D', 'H'.
+ |......^(For Binary, Octal, Decimal, and Hexadecimal).
+ |......^A decimal character representation takes the form "@^D(ddd)".
+ |......^(exactly 3 digits) where each digit d is in the range 0..9.
+ 16 16| @^y
+ Error|......^Expecting one of 'B', 'Q', 'D', 'H'.
+ |......^(For Binary, Octal, Decimal, and Hexadecimal).
+ |......^A decimal character representation takes the form "@^D(ddd)".
+ |......^(exactly 3 digits) where each digit d is in the range 0..9.
+ 17 17| @^#
+ Error|......^Expecting one of 'B', 'Q', 'D', 'H'.
+ |......^(For Binary, Octal, Decimal, and Hexadecimal).
+ |......^A decimal character representation takes the form "@^D(ddd)".
+ |......^(exactly 3 digits) where each digit d is in the range 0..9.
+ 18 18| @^(
+ Error|......^Expecting one of 'B', 'Q', 'D', 'H'.
+ |......^(For Binary, Octal, Decimal, and Hexadecimal).
+ |......^A decimal character representation takes the form "@^D(ddd)".
+ |......^(exactly 3 digits) where each digit d is in the range 0..9.
+ 19 19|
+ 20 20| 3. Test that an error is generated if parenthesis is missing.
+ 21 21|
+ 22 22| @^D34)
+ Error|.......^Expecting '('.
+ |.......^A decimal character representation takes the form "@^D(ddd)".
+ |.......^(exactly 3 digits) where each digit d is in the range 0..9.
+ 23 23|
+ 24 24| 4. Test legal digits in each base.
+ 25 25|
+ 26 26| @^B(00001111)
+ 27 27| @^O(012) @^O(034) @^O(056) @^O(077)
+ 28 28| @^D(012) @^D(034) @^D(056) @^D(078) @^D(099)
+ 29 29| @^H(01) @^H(23) @^H(45) @^H(67)
+ 30 30| @^H(89) @^H(AB) @^X(CD) @^X(EF) @^x(af)
+ 31 31|
+ 32 32| 5. Test illegal digits in each base.
+ 33 33|
+ 34 34| @^B(00000002)
+ Error|...............^Illegal digit.
+ |...............^A binary character representation takes the form "@^B(dddddddd)".
+ |...............^(exactly 8 digits) where each digit d is either 0 or 1.
+ 35 35| @^O(008)
+ Error|..........^Illegal digit.
+ |..........^An octal character representation takes the form "@^Q(ddd)" (or "@^O(ddd)").
+ |..........^(exactly 3 digits) where each digit d is in the range 0..7.
+ 36 36| @^D(00A)
+ Error|..........^Illegal digit.
+ |..........^A decimal character representation takes the form "@^D(ddd)".
+ |..........^(exactly 3 digits) where each digit d is in the range 0..9.
+ 37 37| @^H(0G)
+ Error|.........^Illegal digit.
+ |.........^A hexadecimal character representation takes the form "@^X(dd)" (or "@^H(dd)").
+ |.........^(exactly 2 digits) where each digit d is in the range 0..9,A..F.
+ 38 38|
+ 39 39| 6. Test what happens if there are the wrong number of digits
+ 40 40| (too few, too many).
+ 41 41|
+ 42 42| @^B(1)
+ Error|.........^Illegal digit.
+ |.........^A binary character representation takes the form "@^B(dddddddd)".
+ |.........^(exactly 8 digits) where each digit d is either 0 or 1.
+ 43 43| @^O(1)
+ Error|.........^Illegal digit.
+ |.........^An octal character representation takes the form "@^Q(ddd)" (or "@^O(ddd)").
+ |.........^(exactly 3 digits) where each digit d is in the range 0..7.
+ 44 44| @^D(1)
+ Error|.........^Illegal digit.
+ |.........^A decimal character representation takes the form "@^D(ddd)".
+ |.........^(exactly 3 digits) where each digit d is in the range 0..9.
+ 45 45| @^H(1)
+ Error|.........^Illegal digit.
+ |.........^A hexadecimal character representation takes the form "@^X(dd)" (or "@^H(dd)").
+ |.........^(exactly 2 digits) where each digit d is in the range 0..9,A..F.
+ 46 46|
+ 47 47| @^B(000000001)
+ Error|................^Expecting ')'.
+ |................^A binary character representation takes the form "@^B(dddddddd)".
+ |................^(exactly 8 digits) where each digit d is either 0 or 1.
+ 48 48| @^O(0004)
+ Error|...........^Expecting ')'.
+ |...........^An octal character representation takes the form "@^Q(ddd)" (or "@^O(ddd)").
+ |...........^(exactly 3 digits) where each digit d is in the range 0..7.
+ 49 49| @^D(0001)
+ Error|...........^Expecting ')'.
+ |...........^A decimal character representation takes the form "@^D(ddd)".
+ |...........^(exactly 3 digits) where each digit d is in the range 0..9.
+ 50 50| @^H(005)
+ Error|..........^Expecting ')'.
+ |..........^A hexadecimal character representation takes the form "@^X(dd)" (or "@^H(dd)").
+ |..........^(exactly 2 digits) where each digit d is in the range 0..9,A..F.
+ 51 51|
+ 52 52| 7. Test that an error is generated for a missing closing parenthesis.
+ 53 53|
+ 54 54| @^B(00000000
+ Error|...............^Expecting ')'.
+ |...............^A binary character representation takes the form "@^B(dddddddd)".
+ |...............^(exactly 8 digits) where each digit d is either 0 or 1.
+ 55 55| @^D(045(
+ Error|..........^Expecting ')'.
+ |..........^A decimal character representation takes the form "@^D(ddd)".
+ |..........^(exactly 3 digits) where each digit d is in the range 0..9.
+ 56 56|
+ 57 57| 8. Test what happens in number is out of the range [0,255].
+ 58 58|
+ 59 59| @^D(255)
+ 60 60| @^D(256)
+ Error|..........^Character number is too large.
+ |..........^Character number must be in the range [0,255] (decimal).
+ |..........^A decimal character representation takes the form "@^D(ddd)".
+ |..........^(exactly 3 digits) where each digit d is in the range 0..9.
+ 61 61| @^D(999)
+ Error|..........^Character number is too large.
+ |..........^Character number must be in the range [0,255] (decimal).
+ |..........^A decimal character representation takes the form "@^D(ddd)".
+ |..........^(exactly 3 digits) where each digit d is in the range 0..9.
+ 62 62|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 21 Errors.
diff --git a/web/funnelAC/answers/sc17.lis b/web/funnelAC/answers/sc17.lis
new file mode 100644
index 0000000000..e23bf05b1d
--- /dev/null
+++ b/web/funnelAC/answers/sc17.lis
@@ -0,0 +1,352 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 37 3A 20 54 65 73 74 20 3C 73 70 65 63 | SC17: Test <spec |
+| 69 61 6C 3E 23 2E 0A 0A 46 69 72 73 74 20 77 65 | ial>#...First we |
+| 20 74 72 69 70 20 75 70 20 74 68 65 20 73 63 61 | trip up the sca |
+| 6E 6E 65 72 20 73 6F 20 6E 6F 20 66 75 72 74 68 | nner so no furth |
+| 65 72 20 70 61 73 73 65 73 20 74 61 6B 65 20 70 | er passes take p |
+| 6C 61 63 65 2E 0A 0A 40 0A 0A 31 2E 20 54 65 73 | lace...@..1. Tes |
+| 74 20 77 69 74 68 20 61 6C 6C 20 70 6F 73 73 69 | t with all possi |
+| 62 6C 65 20 70 72 69 6E 74 61 62 6C 65 20 63 68 | ble printable ch |
+| 61 72 61 63 74 65 72 73 2E 0A 0A 40 23 21 20 40 | aracters...@#! @ |
+| 23 22 20 40 23 23 20 40 23 24 20 40 23 25 20 40 | #" @## @#$ @#% @ |
+| 23 26 20 40 23 27 20 40 23 28 20 40 23 29 20 40 | #& @#' @#( @#) @ |
+| 23 2A 20 40 23 2B 20 40 23 2C 20 40 23 2D 20 40 | #* @#+ @#, @#- @ |
+| 23 2E 20 40 23 2F 0A 40 23 30 20 40 23 31 20 40 | #. @#/.@#0 @#1 @ |
+| 23 32 20 40 23 33 20 40 23 34 20 40 23 35 20 40 | #2 @#3 @#4 @#5 @ |
+| 23 36 20 40 23 37 20 40 23 38 20 40 23 39 20 40 | #6 @#7 @#8 @#9 @ |
+| 23 3A 20 40 23 3B 20 40 23 3C 20 40 23 3D 20 40 | #: @#; @#< @#= @ |
+| 23 3E 0A 40 23 3F 20 40 23 40 20 40 23 41 20 40 | #>.@#? @#@ @#A @ |
+| 23 42 20 40 23 43 20 40 23 44 20 40 23 45 20 40 | #B @#C @#D @#E @ |
+| 23 46 20 40 23 47 20 40 23 48 20 40 23 49 20 40 | #F @#G @#H @#I @ |
+| 23 4A 20 40 23 4B 20 40 23 4C 20 40 23 4D 0A 40 | #J @#K @#L @#M.@ |
+| 23 4E 20 40 23 4F 20 40 23 50 20 40 23 51 20 40 | #N @#O @#P @#Q @ |
+| 23 52 20 40 23 53 20 40 23 54 20 40 23 55 20 40 | #R @#S @#T @#U @ |
+| 23 56 20 40 23 57 20 40 23 58 20 40 23 59 20 40 | #V @#W @#X @#Y @ |
+| 23 5A 20 40 23 5B 20 40 23 5C 0A 40 23 5D 20 40 | #Z @#[ @#\.@#] @ |
+| 23 5E 20 40 23 5F 20 40 23 60 20 40 23 61 20 40 | #^ @#_ @#` @#a @ |
+| 23 62 20 40 23 63 20 40 23 64 20 40 23 65 20 40 | #b @#c @#d @#e @ |
+| 23 66 20 40 23 67 20 40 23 68 20 40 23 69 20 40 | #f @#g @#h @#i @ |
+| 23 6A 20 40 23 6B 0A 40 23 6C 20 40 23 6D 20 40 | #j @#k.@#l @#m @ |
+| 23 6E 20 40 23 6F 20 40 23 70 20 40 23 71 20 40 | #n @#o @#p @#q @ |
+| 23 72 20 40 23 73 20 40 23 74 20 40 23 75 20 40 | #r @#s @#t @#u @ |
+| 23 76 20 40 23 77 20 40 23 78 20 40 23 79 20 40 | #v @#w @#x @#y @ |
+| 23 7A 0A 40 23 7B 20 40 23 7C 20 40 23 7D 20 40 | #z.@#{ @#| @#} @ |
+| 23 7E 0A 0A 32 2E 20 54 65 73 74 20 74 68 61 74 | #~..2. Test that |
+| 20 3C 73 70 65 63 69 61 6C 3E 23 3C 73 70 61 63 | <special>#<spac |
+| 65 3E 20 69 73 20 66 6C 61 67 67 65 64 20 61 73 | e> is flagged as |
+| 20 61 6E 20 65 72 72 6F 72 2E 0A 0A 20 20 20 40 | an error... @ |
+| 23 20 20 20 20 20 40 21 20 53 68 6F 75 6C 64 20 | # @! Should |
+| 62 65 20 66 6C 61 67 67 65 64 20 61 73 20 61 6E | be flagged as an |
+| 20 65 72 72 6F 72 2E 0A 0A 33 2E 20 54 65 73 74 | error...3. Test |
+| 20 74 68 61 74 20 3C 73 70 65 63 69 61 6C 3E 23 | that <special># |
+| 45 4F 4C 20 69 73 20 66 6C 61 67 67 65 64 20 61 | EOL is flagged a |
+| 73 20 61 6E 20 65 72 72 6F 72 2E 0A 0A 20 20 20 | s an error... |
+| 40 23 0A 0A | @#.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC17: Test <special>#.<010>
+00002 00002| <010>
+00003 00003| First we trip up the scanner so no further passes take place.<010>
+00004 00004| <010>
+00005 00005| @<010>
+00006 00006| <010>
+00007 00007| 1. Test with all possible printable characters.<010>
+00008 00008| <010>
+00009 00009| @#! @#" @## @#$ @#% @#& @#' @#( @#) @#* @#+ @#, @#- @#. @#/<010>
+00010 00010| @#0 @#1 @#2 @#3 @#4 @#5 @#6 @#7 @#8 @#9 @#: @#; @#< @#= @#><010>
+00011 00011| @#? @#@ @#A @#B @#C @#D @#E @#F @#G @#H @#I @#J @#K @#L @#M<010>
+00012 00012| @#N @#O @#P @#Q @#R @#S @#T @#U @#V @#W @#X @#Y @#Z @#[ @#\<010>
+00013 00013| @#] @#^ @#_ @#` @#a @#b @#c @#d @#e @#f @#g @#h @#i @#j @#k<010>
+00014 00014| @#l @#m @#n @#o @#p @#q @#r @#s @#t @#u @#v @#w @#x @#y @#z<010>
+00015 00015| @#{ @#| @#} @#~<010>
+00016 00016| <010>
+00017 00017| 2. Test that <special>#<space> is flagged as an error.<010>
+00018 00018| <010>
+00019 00019| @# @! Should be flagged as an error.<010>
+00020 00020| <010>
+00021 00021| 3. Test that <special>#EOL is flagged as an error.<010>
+00022 00022| <010>
+00023 00023| @#<010>
+00024 00024| <010>
+00025 00025| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 194 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC17: Test <special>#.<010>
+<010>
+First we trip up the scanner so no further passes take place.<010>
+<010>
+"
+0006[01]: Text. Text scrap[Grey]="<010>
+1. Test with all possible printable characters.<010>
+<010>
+"
+0009[01]: @# Name. Character='!'.
+0009[04]: Text. Text scrap[White]=" "
+0009[05]: @# Name. Character='"'.
+0009[08]: Text. Text scrap[White]=" "
+0009[09]: @# Name. Character='#'.
+0009[12]: Text. Text scrap[White]=" "
+0009[13]: @# Name. Character='$'.
+0009[16]: Text. Text scrap[White]=" "
+0009[17]: @# Name. Character='%'.
+0009[20]: Text. Text scrap[White]=" "
+0009[21]: @# Name. Character='&'.
+0009[24]: Text. Text scrap[White]=" "
+0009[25]: @# Name. Character='''.
+0009[28]: Text. Text scrap[White]=" "
+0009[29]: @# Name. Character='('.
+0009[32]: Text. Text scrap[White]=" "
+0009[33]: @# Name. Character=')'.
+0009[36]: Text. Text scrap[White]=" "
+0009[37]: @# Name. Character='*'.
+0009[40]: Text. Text scrap[White]=" "
+0009[41]: @# Name. Character='+'.
+0009[44]: Text. Text scrap[White]=" "
+0009[45]: @# Name. Character=','.
+0009[48]: Text. Text scrap[White]=" "
+0009[49]: @# Name. Character='-'.
+0009[52]: Text. Text scrap[White]=" "
+0009[53]: @# Name. Character='.'.
+0009[56]: Text. Text scrap[White]=" "
+0009[57]: @# Name. Character='/'.
+0009[60]: Text. Text scrap[White]="<010>
+"
+0010[01]: @# Name. Character='0'.
+0010[04]: Text. Text scrap[White]=" "
+0010[05]: @# Name. Character='1'.
+0010[08]: Text. Text scrap[White]=" "
+0010[09]: @# Name. Character='2'.
+0010[12]: Text. Text scrap[White]=" "
+0010[13]: @# Name. Character='3'.
+0010[16]: Text. Text scrap[White]=" "
+0010[17]: @# Name. Character='4'.
+0010[20]: Text. Text scrap[White]=" "
+0010[21]: @# Name. Character='5'.
+0010[24]: Text. Text scrap[White]=" "
+0010[25]: @# Name. Character='6'.
+0010[28]: Text. Text scrap[White]=" "
+0010[29]: @# Name. Character='7'.
+0010[32]: Text. Text scrap[White]=" "
+0010[33]: @# Name. Character='8'.
+0010[36]: Text. Text scrap[White]=" "
+0010[37]: @# Name. Character='9'.
+0010[40]: Text. Text scrap[White]=" "
+0010[41]: @# Name. Character=':'.
+0010[44]: Text. Text scrap[White]=" "
+0010[45]: @# Name. Character=';'.
+0010[48]: Text. Text scrap[White]=" "
+0010[49]: @# Name. Character='<'.
+0010[52]: Text. Text scrap[White]=" "
+0010[53]: @# Name. Character='='.
+0010[56]: Text. Text scrap[White]=" "
+0010[57]: @# Name. Character='>'.
+0010[60]: Text. Text scrap[White]="<010>
+"
+0011[01]: @# Name. Character='?'.
+0011[04]: Text. Text scrap[White]=" "
+0011[05]: @# Name. Character='@'.
+0011[08]: Text. Text scrap[White]=" "
+0011[09]: @# Name. Character='A'.
+0011[12]: Text. Text scrap[White]=" "
+0011[13]: @# Name. Character='B'.
+0011[16]: Text. Text scrap[White]=" "
+0011[17]: @# Name. Character='C'.
+0011[20]: Text. Text scrap[White]=" "
+0011[21]: @# Name. Character='D'.
+0011[24]: Text. Text scrap[White]=" "
+0011[25]: @# Name. Character='E'.
+0011[28]: Text. Text scrap[White]=" "
+0011[29]: @# Name. Character='F'.
+0011[32]: Text. Text scrap[White]=" "
+0011[33]: @# Name. Character='G'.
+0011[36]: Text. Text scrap[White]=" "
+0011[37]: @# Name. Character='H'.
+0011[40]: Text. Text scrap[White]=" "
+0011[41]: @# Name. Character='I'.
+0011[44]: Text. Text scrap[White]=" "
+0011[45]: @# Name. Character='J'.
+0011[48]: Text. Text scrap[White]=" "
+0011[49]: @# Name. Character='K'.
+0011[52]: Text. Text scrap[White]=" "
+0011[53]: @# Name. Character='L'.
+0011[56]: Text. Text scrap[White]=" "
+0011[57]: @# Name. Character='M'.
+0011[60]: Text. Text scrap[White]="<010>
+"
+0012[01]: @# Name. Character='N'.
+0012[04]: Text. Text scrap[White]=" "
+0012[05]: @# Name. Character='O'.
+0012[08]: Text. Text scrap[White]=" "
+0012[09]: @# Name. Character='P'.
+0012[12]: Text. Text scrap[White]=" "
+0012[13]: @# Name. Character='Q'.
+0012[16]: Text. Text scrap[White]=" "
+0012[17]: @# Name. Character='R'.
+0012[20]: Text. Text scrap[White]=" "
+0012[21]: @# Name. Character='S'.
+0012[24]: Text. Text scrap[White]=" "
+0012[25]: @# Name. Character='T'.
+0012[28]: Text. Text scrap[White]=" "
+0012[29]: @# Name. Character='U'.
+0012[32]: Text. Text scrap[White]=" "
+0012[33]: @# Name. Character='V'.
+0012[36]: Text. Text scrap[White]=" "
+0012[37]: @# Name. Character='W'.
+0012[40]: Text. Text scrap[White]=" "
+0012[41]: @# Name. Character='X'.
+0012[44]: Text. Text scrap[White]=" "
+0012[45]: @# Name. Character='Y'.
+0012[48]: Text. Text scrap[White]=" "
+0012[49]: @# Name. Character='Z'.
+0012[52]: Text. Text scrap[White]=" "
+0012[53]: @# Name. Character='['.
+0012[56]: Text. Text scrap[White]=" "
+0012[57]: @# Name. Character='\'.
+0012[60]: Text. Text scrap[White]="<010>
+"
+0013[01]: @# Name. Character=']'.
+0013[04]: Text. Text scrap[White]=" "
+0013[05]: @# Name. Character='^'.
+0013[08]: Text. Text scrap[White]=" "
+0013[09]: @# Name. Character='_'.
+0013[12]: Text. Text scrap[White]=" "
+0013[13]: @# Name. Character='`'.
+0013[16]: Text. Text scrap[White]=" "
+0013[17]: @# Name. Character='a'.
+0013[20]: Text. Text scrap[White]=" "
+0013[21]: @# Name. Character='b'.
+0013[24]: Text. Text scrap[White]=" "
+0013[25]: @# Name. Character='c'.
+0013[28]: Text. Text scrap[White]=" "
+0013[29]: @# Name. Character='d'.
+0013[32]: Text. Text scrap[White]=" "
+0013[33]: @# Name. Character='e'.
+0013[36]: Text. Text scrap[White]=" "
+0013[37]: @# Name. Character='f'.
+0013[40]: Text. Text scrap[White]=" "
+0013[41]: @# Name. Character='g'.
+0013[44]: Text. Text scrap[White]=" "
+0013[45]: @# Name. Character='h'.
+0013[48]: Text. Text scrap[White]=" "
+0013[49]: @# Name. Character='i'.
+0013[52]: Text. Text scrap[White]=" "
+0013[53]: @# Name. Character='j'.
+0013[56]: Text. Text scrap[White]=" "
+0013[57]: @# Name. Character='k'.
+0013[60]: Text. Text scrap[White]="<010>
+"
+0014[01]: @# Name. Character='l'.
+0014[04]: Text. Text scrap[White]=" "
+0014[05]: @# Name. Character='m'.
+0014[08]: Text. Text scrap[White]=" "
+0014[09]: @# Name. Character='n'.
+0014[12]: Text. Text scrap[White]=" "
+0014[13]: @# Name. Character='o'.
+0014[16]: Text. Text scrap[White]=" "
+0014[17]: @# Name. Character='p'.
+0014[20]: Text. Text scrap[White]=" "
+0014[21]: @# Name. Character='q'.
+0014[24]: Text. Text scrap[White]=" "
+0014[25]: @# Name. Character='r'.
+0014[28]: Text. Text scrap[White]=" "
+0014[29]: @# Name. Character='s'.
+0014[32]: Text. Text scrap[White]=" "
+0014[33]: @# Name. Character='t'.
+0014[36]: Text. Text scrap[White]=" "
+0014[37]: @# Name. Character='u'.
+0014[40]: Text. Text scrap[White]=" "
+0014[41]: @# Name. Character='v'.
+0014[44]: Text. Text scrap[White]=" "
+0014[45]: @# Name. Character='w'.
+0014[48]: Text. Text scrap[White]=" "
+0014[49]: @# Name. Character='x'.
+0014[52]: Text. Text scrap[White]=" "
+0014[53]: @# Name. Character='y'.
+0014[56]: Text. Text scrap[White]=" "
+0014[57]: @# Name. Character='z'.
+0014[60]: Text. Text scrap[White]="<010>
+"
+0015[01]: @# Name. Character='{'.
+0015[04]: Text. Text scrap[White]=" "
+0015[05]: @# Name. Character='|'.
+0015[08]: Text. Text scrap[White]=" "
+0015[09]: @# Name. Character='}'.
+0015[12]: Text. Text scrap[White]=" "
+0015[13]: @# Name. Character='~'.
+0015[16]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test that <special>#<space> is flagged as an error.<010>
+<010>
+ "
+0019[07]: Text. Text scrap[White]=" "
+0020[01]: Text. Text scrap[Grey]="<010>
+3. Test that <special>#EOL is flagged as an error.<010>
+<010>
+ "
+0024[01]: Text. Text scrap[White]="<010>
+"
+0025[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC17: Test <special>#.
+ 2 2|
+ 3 3| First we trip up the scanner so no further passes take place.
+ 4 4|
+ 5 5| @
+ Error|.^<special><endofline> is not a legal special sequence.
+ 6 6|
+ 7 7| 1. Test with all possible printable characters.
+ 8 8|
+ 9 9| @#! @#" @## @#$ @#% @#& @#' @#( @#) @#* @#+ @#, @#- @#. @#/
+ 10 10| @#0 @#1 @#2 @#3 @#4 @#5 @#6 @#7 @#8 @#9 @#: @#; @#< @#= @#>
+ 11 11| @#? @#@ @#A @#B @#C @#D @#E @#F @#G @#H @#I @#J @#K @#L @#M
+ 12 12| @#N @#O @#P @#Q @#R @#S @#T @#U @#V @#W @#X @#Y @#Z @#[ @#\
+ 13 13| @#] @#^ @#_ @#` @#a @#b @#c @#d @#e @#f @#g @#h @#i @#j @#k
+ 14 14| @#l @#m @#n @#o @#p @#q @#r @#s @#t @#u @#v @#w @#x @#y @#z
+ 15 15| @#{ @#| @#} @#~
+ 16 16|
+ 17 17| 2. Test that <special>#<space> is flagged as an error.
+ 18 18|
+ 19 19| @# @! Should be flagged as an error.
+ Error|......^Expecting a printable character.
+ 20 20|
+ 21 21| 3. Test that <special>#EOL is flagged as an error.
+ 22 22|
+ 23 23| @#
+ Error|......^Expecting a printable character.
+ 24 24|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 3 Errors.
diff --git a/web/funnelAC/answers/sc18.lis b/web/funnelAC/answers/sc18.lis
new file mode 100644
index 0000000000..1442d3938d
--- /dev/null
+++ b/web/funnelAC/answers/sc18.lis
@@ -0,0 +1,261 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 38 3A 20 54 65 73 74 20 3C 73 70 65 63 | SC18: Test <spec |
+| 69 61 6C 3E 23 3D 0A 0A 46 69 72 73 74 20 77 65 | ial>#=..First we |
+| 20 74 72 69 70 20 75 70 20 74 68 65 20 73 63 61 | trip up the sca |
+| 6E 6E 65 72 20 73 6F 20 6E 6F 20 66 75 72 74 68 | nner so no furth |
+| 65 72 20 70 61 73 73 65 73 20 74 61 6B 65 20 70 | er passes take p |
+| 6C 61 63 65 2E 0A 0A 40 0A 0A 31 2E 20 54 65 73 | lace...@..1. Tes |
+| 74 20 77 69 74 68 20 61 6C 6C 20 70 6F 73 73 69 | t with all possi |
+| 62 6C 65 20 70 72 69 6E 74 61 62 6C 65 20 63 68 | ble printable ch |
+| 61 72 61 63 74 65 72 73 2E 0A 0A 40 3D 21 20 21 | aracters...@=! ! |
+| 3D 22 20 22 3D 23 20 23 3D 24 20 24 3D 25 20 25 | =" "=# #=$ $=% % |
+| 3D 26 20 26 3D 27 20 27 3D 28 20 28 3D 29 20 29 | =& &=' '=( (=) ) |
+| 3D 2A 20 2A 3D 2B 20 2B 3D 2C 20 2C 3D 2D 20 2D | =* *=+ +=, ,=- - |
+| 3D 2E 20 2E 3D 2F 0A 2F 3D 30 20 30 3D 31 20 31 | =. .=/./=0 0=1 1 |
+| 3D 32 20 32 3D 33 20 33 3D 34 20 34 3D 35 20 35 | =2 2=3 3=4 4=5 5 |
+| 3D 36 20 36 3D 37 20 37 3D 38 20 38 3D 39 20 39 | =6 6=7 7=8 8=9 9 |
+| 3D 3A 20 3A 3D 3B 20 3B 3D 3C 20 3C 3D 3D 20 3D | =: :=; ;=< <== = |
+| 3D 3E 0A 3E 3D 3F 20 3F 3D 40 20 40 3D 41 20 41 | =>.>=? ?=@ @=A A |
+| 3D 42 20 42 3D 43 20 43 3D 44 20 44 3D 45 20 45 | =B B=C C=D D=E E |
+| 3D 46 20 46 3D 47 20 47 3D 48 20 48 3D 49 20 49 | =F F=G G=H H=I I |
+| 3D 4A 20 4A 3D 4B 20 4B 3D 4C 20 4C 3D 4D 0A 4D | =J J=K K=L L=M.M |
+| 3D 4E 20 4E 3D 4F 20 4F 3D 50 20 50 3D 51 20 51 | =N N=O O=P P=Q Q |
+| 3D 52 20 52 3D 53 20 53 3D 54 20 54 3D 55 20 55 | =R R=S S=T T=U U |
+| 3D 56 20 56 3D 57 20 57 3D 58 20 58 3D 59 20 59 | =V V=W W=X X=Y Y |
+| 3D 5A 20 5A 3D 5B 20 5B 3D 5C 0A 5C 3D 5D 20 5D | =Z Z=[ [=\.\=] ] |
+| 3D 5E 20 5E 3D 5F 20 5F 3D 60 20 60 3D 61 20 61 | =^ ^=_ _=` `=a a |
+| 3D 62 20 62 3D 63 20 63 3D 64 20 64 3D 65 20 65 | =b b=c c=d d=e e |
+| 3D 66 20 66 3D 67 20 67 3D 68 20 68 3D 69 20 69 | =f f=g g=h h=i i |
+| 3D 6A 20 6A 3D 6B 0A 6B 3D 6C 20 6C 3D 6D 20 6D | =j j=k.k=l l=m m |
+| 3D 6E 20 6E 3D 6F 20 6F 3D 70 20 70 3D 71 20 71 | =n n=o o=p p=q q |
+| 3D 72 20 72 3D 73 20 73 3D 74 20 74 3D 75 20 75 | =r r=s s=t t=u u |
+| 3D 76 20 76 3D 77 20 77 3D 78 20 78 3D 79 20 79 | =v v=w w=x x=y y |
+| 3D 7A 0A 7A 3D 7B 20 7B 3D 7C 20 7C 3D 7D 20 7D | =z.z={ {=| |=} } |
+| 3D 7E 20 7E 3D 40 0A 0A 32 2E 20 54 65 73 74 20 | =~ ~=@..2. Test |
+| 74 68 61 74 20 3C 73 70 65 63 69 61 6C 3E 3D 3C | that <special>=< |
+| 73 70 61 63 65 3E 20 69 73 20 66 6C 61 67 67 65 | space> is flagge |
+| 64 20 61 73 20 61 6E 20 65 72 72 6F 72 2E 0A 0A | d as an error... |
+| 20 20 20 40 3D 20 20 20 20 20 40 21 20 53 68 6F | @= @! Sho |
+| 75 6C 64 20 62 65 20 66 6C 61 67 67 65 64 20 61 | uld be flagged a |
+| 73 20 61 6E 20 65 72 72 6F 72 2E 0A 0A 33 2E 20 | s an error...3. |
+| 54 65 73 74 20 74 68 61 74 20 3C 73 70 65 63 69 | Test that <speci |
+| 61 6C 3E 3D 45 4F 4C 20 69 73 20 66 6C 61 67 67 | al>=EOL is flagg |
+| 65 64 20 61 73 20 61 6E 20 65 72 72 6F 72 2E 0A | ed as an error.. |
+| 0A 20 20 20 40 3D 0A 0A | . @=.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC18: Test <special>#=<010>
+00002 00002| <010>
+00003 00003| First we trip up the scanner so no further passes take place.<010>
+00004 00004| <010>
+00005 00005| @<010>
+00006 00006| <010>
+00007 00007| 1. Test with all possible printable characters.<010>
+00008 00008| <010>
+00009 00009| @=! !=" "=# #=$ $=% %=& &=' '=( (=) )=* *=+ +=, ,=- -=. .=/<010>
+00010 00010| /=0 0=1 1=2 2=3 3=4 4=5 5=6 6=7 7=8 8=9 9=: :=; ;=< <== ==><010>
+00011 00011| >=? ?=@ @=A A=B B=C C=D D=E E=F F=G G=H H=I I=J J=K K=L L=M<010>
+00012 00012| M=N N=O O=P P=Q Q=R R=S S=T T=U U=V V=W W=X X=Y Y=Z Z=[ [=\<010>
+00013 00013| \=] ]=^ ^=_ _=` `=a a=b b=c c=d d=e e=f f=g g=h h=i i=j j=k<010>
+00014 00014| k=l l=m m=n n=o o=p p=q q=r r=s s=t t=u u=v v=w w=x x=y y=z<010>
+00015 00015| z={ {=| |=} }=~ ~=@<010>
+00016 00016| <010>
+00017 00017| 2. Test that <special>=<space> is flagged as an error.<010>
+00018 00018| <010>
+00019 00019| @= @! Should be flagged as an error.<010>
+00020 00020| <010>
+00021 00021| 3. Test that <special>=EOL is flagged as an error.<010>
+00022 00022| <010>
+00023 00023| @=<010>
+00024 00024| <010>
+00025 00025| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 101 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC18: Test <special>#=<010>
+<010>
+First we trip up the scanner so no further passes take place.<010>
+<010>
+"
+0006[01]: Text. Text scrap[Grey]="<010>
+1. Test with all possible printable characters.<010>
+<010>
+"
+0009[04]: Text. Text scrap[White]=" "
+0009[08]: Text. Text scrap[White]=" "
+0009[12]: Text. Text scrap[White]=" "
+0009[16]: Text. Text scrap[White]=" "
+0009[20]: Text. Text scrap[White]=" "
+0009[24]: Text. Text scrap[White]=" "
+0009[28]: Text. Text scrap[White]=" "
+0009[32]: Text. Text scrap[White]=" "
+0009[36]: Text. Text scrap[White]=" "
+0009[40]: Text. Text scrap[White]=" "
+0009[44]: Text. Text scrap[White]=" "
+0009[48]: Text. Text scrap[White]=" "
+0009[52]: Text. Text scrap[White]=" "
+0009[56]: Text. Text scrap[White]=" "
+0009[60]: Text. Text scrap[White]="<010>
+"
+0010[04]: Text. Text scrap[White]=" "
+0010[08]: Text. Text scrap[White]=" "
+0010[12]: Text. Text scrap[White]=" "
+0010[16]: Text. Text scrap[White]=" "
+0010[20]: Text. Text scrap[White]=" "
+0010[24]: Text. Text scrap[White]=" "
+0010[28]: Text. Text scrap[White]=" "
+0010[32]: Text. Text scrap[White]=" "
+0010[36]: Text. Text scrap[White]=" "
+0010[40]: Text. Text scrap[White]=" "
+0010[44]: Text. Text scrap[White]=" "
+0010[48]: Text. Text scrap[White]=" "
+0010[52]: Text. Text scrap[White]=" "
+0010[56]: Text. Text scrap[White]=" "
+0010[60]: Text. Text scrap[White]="<010>
+"
+0011[04]: Text. Text scrap[White]=" "
+0011[08]: Text. Text scrap[White]=" "
+0011[12]: Text. Text scrap[White]=" "
+0011[16]: Text. Text scrap[White]=" "
+0011[20]: Text. Text scrap[White]=" "
+0011[24]: Text. Text scrap[White]=" "
+0011[28]: Text. Text scrap[White]=" "
+0011[32]: Text. Text scrap[White]=" "
+0011[36]: Text. Text scrap[White]=" "
+0011[40]: Text. Text scrap[White]=" "
+0011[44]: Text. Text scrap[White]=" "
+0011[48]: Text. Text scrap[White]=" "
+0011[52]: Text. Text scrap[White]=" "
+0011[56]: Text. Text scrap[White]=" "
+0011[60]: Text. Text scrap[White]="<010>
+"
+0012[04]: Text. Text scrap[White]=" "
+0012[08]: Text. Text scrap[White]=" "
+0012[12]: Text. Text scrap[White]=" "
+0012[16]: Text. Text scrap[White]=" "
+0012[20]: Text. Text scrap[White]=" "
+0012[24]: Text. Text scrap[White]=" "
+0012[28]: Text. Text scrap[White]=" "
+0012[32]: Text. Text scrap[White]=" "
+0012[36]: Text. Text scrap[White]=" "
+0012[40]: Text. Text scrap[White]=" "
+0012[44]: Text. Text scrap[White]=" "
+0012[48]: Text. Text scrap[White]=" "
+0012[52]: Text. Text scrap[White]=" "
+0012[56]: Text. Text scrap[White]=" "
+0012[60]: Text. Text scrap[White]="<010>
+"
+0013[04]: Text. Text scrap[White]=" "
+0013[08]: Text. Text scrap[White]=" "
+0013[12]: Text. Text scrap[White]=" "
+0013[16]: Text. Text scrap[White]=" "
+0013[20]: Text. Text scrap[White]=" "
+0013[24]: Text. Text scrap[White]=" "
+0013[28]: Text. Text scrap[White]=" "
+0013[32]: Text. Text scrap[White]=" "
+0013[36]: Text. Text scrap[White]=" "
+0013[40]: Text. Text scrap[White]=" "
+0013[44]: Text. Text scrap[White]=" "
+0013[48]: Text. Text scrap[White]=" "
+0013[52]: Text. Text scrap[White]=" "
+0013[56]: Text. Text scrap[White]=" "
+0013[60]: Text. Text scrap[White]="<010>
+"
+0014[04]: Text. Text scrap[White]=" "
+0014[08]: Text. Text scrap[White]=" "
+0014[12]: Text. Text scrap[White]=" "
+0014[16]: Text. Text scrap[White]=" "
+0014[20]: Text. Text scrap[White]=" "
+0014[24]: Text. Text scrap[White]=" "
+0014[28]: Text. Text scrap[White]=" "
+0014[32]: Text. Text scrap[White]=" "
+0014[36]: Text. Text scrap[White]=" "
+0014[40]: Text. Text scrap[White]=" "
+0014[44]: Text. Text scrap[White]=" "
+0014[48]: Text. Text scrap[White]=" "
+0014[52]: Text. Text scrap[White]=" "
+0014[56]: Text. Text scrap[White]=" "
+0014[60]: Text. Text scrap[White]="<010>
+"
+0015[04]: Text. Text scrap[White]=" "
+0015[08]: Text. Text scrap[White]=" "
+0015[12]: Text. Text scrap[White]=" "
+0015[16]: Text. Text scrap[White]=" "
+0015[20]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test that <special>=<space> is flagged as an error.<010>
+<010>
+ "
+0019[07]: Text. Text scrap[White]=" "
+0020[01]: Text. Text scrap[Grey]="<010>
+3. Test that <special>=EOL is flagged as an error.<010>
+<010>
+ "
+0024[01]: Text. Text scrap[White]="<010>
+"
+0025[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC18: Test <special>#=
+ 2 2|
+ 3 3| First we trip up the scanner so no further passes take place.
+ 4 4|
+ 5 5| @
+ Error|.^<special><endofline> is not a legal special sequence.
+ 6 6|
+ 7 7| 1. Test with all possible printable characters.
+ 8 8|
+ 9 9| @=! !=" "=# #=$ $=% %=& &=' '=( (=) )=* *=+ +=, ,=- -=. .=/
+ 10 10| /=0 0=1 1=2 2=3 3=4 4=5 5=6 6=7 7=8 8=9 9=: :=; ;=< <== ==>
+ 11 11| >=? ?=@ @=A A=B B=C C=D D=E E=F F=G G=H H=I I=J J=K K=L L=M
+ 12 12| M=N N=O O=P P=Q Q=R R=S S=T T=U U=V V=W W=X X=Y Y=Z Z=[ [=\
+ 13 13| \=] ]=^ ^=_ _=` `=a a=b b=c c=d d=e e=f f=g g=h h=i i=j j=k
+ 14 14| k=l l=m m=n n=o o=p p=q q=r r=s s=t t=u u=v v=w w=x x=y y=z
+ 15 15| z={ {=| |=} }=~ ~=@
+ 16 16|
+ 17 17| 2. Test that <special>=<space> is flagged as an error.
+ 18 18|
+ 19 19| @= @! Should be flagged as an error.
+ Error|....^You cannot set the special character to <space>!
+ |....^Special sequence ignored.
+ 20 20|
+ 21 21| 3. Test that <special>=EOL is flagged as an error.
+ 22 22|
+ 23 23| @=
+ Error|....^You cannot set the special character to <endofline>!
+ |....^Special sequence ignored.
+ 24 24|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 3 Errors.
diff --git a/web/funnelAC/answers/sc19.lis b/web/funnelAC/answers/sc19.lis
new file mode 100644
index 0000000000..4cfda7a5a4
--- /dev/null
+++ b/web/funnelAC/answers/sc19.lis
@@ -0,0 +1,94 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 39 3A 20 54 65 73 74 20 3C 73 70 65 63 | SC19: Test <spec |
+| 69 61 6C 3E 2D 0A 0A 31 2E 20 54 65 73 74 20 74 | ial>-..1. Test t |
+| 68 61 74 20 65 72 72 6F 72 20 69 73 20 66 6C 61 | hat error is fla |
+| 67 67 65 64 20 69 66 20 73 65 71 75 65 6E 63 65 | gged if sequence |
+| 20 69 73 20 6E 6F 74 20 61 74 20 74 68 65 20 65 | is not at the e |
+| 6E 64 20 6F 66 20 61 20 6C 69 6E 65 2E 0A 0A 54 | nd of a line...T |
+| 68 69 73 20 69 73 20 61 20 6C 69 6E 65 20 63 6F | his is a line co |
+| 6E 74 61 69 6E 69 6E 67 20 40 2D 20 74 68 65 20 | ntaining @- the |
+| 65 6E 64 20 6F 66 20 6C 69 6E 65 20 73 75 70 70 | end of line supp |
+| 72 65 73 73 6F 72 2E 0A 0A 32 2E 20 54 65 73 74 | ressor...2. Test |
+| 20 74 68 65 20 73 65 71 75 65 6E 63 65 20 66 6F | the sequence fo |
+| 6C 6C 6F 77 65 64 20 62 79 20 74 72 61 69 6C 69 | llowed by traili |
+| 6E 67 20 62 6C 61 6E 6B 73 2E 0A 0A 20 20 20 20 | ng blanks... |
+| 20 40 2D 20 20 20 0A 0A | @- .. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC19: Test <special>-<010>
+00002 00002| <010>
+00003 00003| 1. Test that error is flagged if sequence is not at the end of a line.<010>
+00004 00004| <010>
+00005 00005| This is a line containing @- the end of line suppressor.<010>
+00006 00006| <010>
+00007 00007| 2. Test the sequence followed by trailing blanks.<010>
+00008 00008| <010>
+00009 00009| @- <010>
+00010 00010| <010>
+00011 00011| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 4 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC19: Test <special>-<010>
+<010>
+1. Test that error is flagged if sequence is not at the end of a line.<010>
+<010>
+This is a line containing "
+0005[29]: Text. Text scrap[Grey]=" the end of line suppressor.<010>
+<010>
+2. Test the sequence followed by trailing blanks.<010>
+<010>
+ "
+0009[08]: Text. Text scrap[White]=" <010>
+<010>
+"
+0011[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC19: Test <special>-
+ 2 2|
+ 3 3| 1. Test that error is flagged if sequence is not at the end of a line.
+ 4 4|
+ 5 5| This is a line containing @- the end of line suppressor.
+ Error|...........................^Suppress EOL sequence is legal only at the end of a line.
+ 6 6|
+ 7 7| 2. Test the sequence followed by trailing blanks.
+ 8 8|
+ 9 9| @-
+ Error|......^Suppress EOL sequence is legal only at the end of a line.
+ Warning|..........^Line has trailing spaces up to and including this space.
+ 10 10|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 2 Errors and 1 Warning.
diff --git a/web/funnelAC/answers/sc20.lis b/web/funnelAC/answers/sc20.lis
new file mode 100644
index 0000000000..84db05a3ec
--- /dev/null
+++ b/web/funnelAC/answers/sc20.lis
@@ -0,0 +1,112 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 30 3A 20 54 65 73 74 20 40 21 0A 0A 31 | SC20: Test @!..1 |
+| 2E 20 54 65 73 74 20 61 74 20 74 68 65 20 73 74 | . Test at the st |
+| 61 72 74 20 6F 66 20 61 20 6C 69 6E 65 2E 0A 0A | art of a line... |
+| 40 21 20 54 68 69 73 20 69 73 20 61 20 63 6F 6D | @! This is a com |
+| 6D 65 6E 74 20 61 6E 64 20 77 65 20 63 61 6E 20 | ment and we can |
+| 73 74 69 63 6B 20 61 6E 79 20 73 6F 72 74 20 6F | stick any sort o |
+| 66 20 72 75 62 62 69 73 68 20 69 6E 20 69 74 2E | f rubbish in it. |
+| 0A 40 21 20 40 23 20 40 69 20 40 5E 64 73 3B 61 | .@! @# @i @^ds;a |
+| 66 3B 6C 73 64 6D 66 3B 6C 61 6E 64 20 6F 74 68 | f;lsdmf;land oth |
+| 65 72 20 40 20 72 75 62 62 69 73 68 2E 0A 0A 32 | er @ rubbish...2 |
+| 2E 20 54 65 73 74 20 68 61 6C 66 77 61 79 20 74 | . Test halfway t |
+| 68 72 6F 75 67 68 20 61 20 6C 69 6E 65 2E 0A 0A | hrough a line... |
+| 54 68 69 73 20 69 73 20 61 20 6C 69 6E 65 20 40 | This is a line @ |
+| 21 20 77 68 6F 73 65 20 73 65 63 6F 6E 64 20 68 | ! whose second h |
+| 61 6C 66 20 6E 65 76 65 72 20 73 65 65 73 20 74 | alf never sees t |
+| 68 65 20 64 61 79 6C 69 67 68 74 2E 20 40 69 20 | he daylight. @i |
+| 40 3C 0A 0A | @<.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC20: Test @!<010>
+00002 00002| <010>
+00003 00003| 1. Test at the start of a line.<010>
+00004 00004| <010>
+00005 00005| @! This is a comment and we can stick any sort of rubbish in it.<010>
+00006 00006| @! @# @i @^ds;af;lsdmf;land other @ rubbish.<010>
+00007 00007| <010>
+00008 00008| 2. Test halfway through a line.<010>
+00009 00009| <010>
+00010 00010| This is a line @! whose second half never sees the daylight. @i @<<010>
+00011 00011| <010>
+00012 00012| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 5 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC20: Test "
+0002[01]: Text. Text scrap[Grey]="<010>
+1. Test at the start of a line.<010>
+<010>
+"
+0007[01]: Text. Text scrap[Grey]="<010>
+2. Test halfway through a line.<010>
+<010>
+This is a line "
+0011[01]: Text. Text scrap[White]="<010>
+"
+0012[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="SC20: Test "
+Text scrap[Grey]="<010>
+1. Test at the start of a line.<010>
+<010>
+"
+Text scrap[Grey]="<010>
+2. Test halfway through a line.<010>
+<010>
+This is a line "
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+E: No macros defined.
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+There were 2 Errors.
diff --git a/web/funnelAC/answers/sc21.lis b/web/funnelAC/answers/sc21.lis
new file mode 100644
index 0000000000..e64bcb3ac2
--- /dev/null
+++ b/web/funnelAC/answers/sc21.lis
@@ -0,0 +1,339 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 31 3A 20 54 65 73 74 20 67 65 6E 65 72 | SC21: Test gener |
+| 69 63 20 73 79 6E 74 61 78 20 63 68 65 63 6B 69 | ic syntax checki |
+| 6E 67 20 6F 66 20 70 72 61 67 6D 61 73 20 61 6E | ng of pragmas an |
+| 64 20 74 79 70 65 73 65 74 74 65 72 20 64 69 72 | d typesetter dir |
+| 65 63 74 69 76 65 73 2E 0A 0A 31 2E 20 54 65 73 | ectives...1. Tes |
+| 74 20 70 72 61 67 6D 61 20 6E 6F 74 20 61 74 20 | t pragma not at |
+| 74 68 65 20 73 74 61 72 74 20 6F 66 20 6C 69 6E | the start of lin |
+| 65 2E 0A 20 20 20 40 70 0A 20 20 20 40 74 0A 0A | e.. @p. @t.. |
+| 32 2E 20 54 65 73 74 20 63 68 61 72 61 63 74 65 | 2. Test characte |
+| 72 20 66 6F 6C 6C 6F 77 69 6E 67 20 3C 73 70 65 | r following <spe |
+| 63 69 61 6C 3E 70 20 69 73 20 6E 6F 74 20 61 20 | cial>p is not a |
+| 62 6C 61 6E 6B 2E 0A 40 70 78 0A 40 74 78 0A 40 | blank..@px.@tx.@ |
+| 70 0A 40 74 0A 0A 33 2E 20 54 65 73 74 20 70 72 | p.@t..3. Test pr |
+| 61 67 6D 61 20 6C 69 6E 65 20 69 73 20 74 6F 6F | agma line is too |
+| 20 6C 6F 6E 67 20 28 6C 69 6D 69 74 20 69 73 20 | long (limit is |
+| 31 30 30 29 0A 20 20 20 20 20 20 20 20 20 31 20 | 100). 1 |
+| 20 20 20 20 20 20 20 20 32 20 20 20 20 20 20 20 | 2 |
+| 20 20 33 20 20 20 20 20 20 20 20 20 34 20 20 20 | 3 4 |
+| 20 20 20 20 20 20 35 20 20 20 20 20 20 20 20 20 | 5 |
+| 36 20 20 20 20 20 20 20 20 20 37 20 20 20 20 20 | 6 7 |
+| 20 20 20 20 38 20 20 20 20 20 20 20 20 20 39 20 | 8 9 |
+| 20 20 20 20 20 20 20 20 31 0A 40 70 20 34 35 36 | 1.@p 456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 0A 40 | 78901234567890.@ |
+| 70 20 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | p 45678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 0A 40 74 20 34 35 36 37 38 39 30 31 | 8901.@t 45678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 0A 40 74 20 34 35 36 | 234567890.@t 456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 0A | 789012345678901. |
+| 0A 34 2E 20 54 65 73 74 20 76 61 72 69 6F 75 73 | .4. Test various |
+| 20 64 69 66 66 65 72 65 6E 74 20 70 72 61 67 6D | different pragm |
+| 61 20 6C 69 6E 65 73 2E 0A 40 70 20 24 23 25 40 | a lines..@p $#%@ |
+| 20 32 35 32 35 20 20 73 6C 6F 74 68 0A 40 74 20 | 2525 sloth.@t |
+| 24 23 25 40 20 32 35 32 35 20 20 73 6C 6F 74 68 | $#%@ 2525 sloth |
+| 0A 0A 35 2E 20 54 65 73 74 20 70 72 61 67 6D 61 | ..5. Test pragma |
+| 20 77 69 74 68 20 6E 6F 20 61 72 67 75 6D 65 6E | with no argumen |
+| 74 73 2E 20 28 57 69 6C 6C 20 67 65 74 20 61 20 | ts. (Will get a |
+| 74 72 61 69 6C 69 6E 67 20 62 6C 61 6E 6B 73 20 | trailing blanks |
+| 65 72 72 6F 72 2E 29 2E 0A 40 70 20 20 20 20 0A | error.)..@p . |
+| 40 74 20 20 20 20 0A 0A 36 2E 20 54 65 73 74 20 | @t ..6. Test |
+| 70 72 61 67 6D 61 20 77 69 74 68 20 74 6F 6F 20 | pragma with too |
+| 6D 61 6E 79 20 61 72 67 75 6D 65 6E 74 73 2E 0A | many arguments.. |
+| 40 70 20 61 20 62 20 63 20 64 20 65 20 66 20 67 | @p a b c d e f g |
+| 20 68 20 69 20 6A 20 6B 20 6C 20 6D 20 6E 20 6F | h i j k l m n o |
+| 20 70 20 71 20 72 20 73 20 74 20 75 20 76 20 77 | p q r s t u v w |
+| 20 78 20 79 20 7A 0A 40 74 20 61 20 62 20 63 20 | x y z.@t a b c |
+| 64 20 65 20 66 20 67 20 68 20 69 20 6A 20 6B 20 | d e f g h i j k |
+| 6C 20 6D 20 6E 20 6F 20 70 20 71 20 72 20 73 20 | l m n o p q r s |
+| 74 20 75 20 76 20 77 20 78 20 79 20 7A 0A 0A | t u v w x y z.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC21: Test generic syntax checking of pragmas and typesetter directives.<010>
+00002 00002| <010>
+00003 00003| 1. Test pragma not at the start of line.<010>
+00004 00004| @p<010>
+00005 00005| @t<010>
+00006 00006| <010>
+00007 00007| 2. Test character following <special>p is not a blank.<010>
+00008 00008| @px<010>
+00009 00009| @tx<010>
+00010 00010| @p<010>
+00011 00011| @t<010>
+00012 00012| <010>
+00013 00013| 3. Test pragma line is too long (limit is 100)<010>
+00014 00014| 1 2 3 4 5 6 7 8 9 1<010>
+00015 00015| @p 4567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890<010>
+00016 00016| @p 45678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901<010>
+00017 00017| @t 4567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890<010>
+00018 00018| @t 45678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901<010>
+00019 00019| <010>
+00020 00020| 4. Test various different pragma lines.<010>
+00021 00021| @p $#%@ 2525 sloth<010>
+00022 00022| @t $#%@ 2525 sloth<010>
+00023 00023| <010>
+00024 00024| 5. Test pragma with no arguments. (Will get a trailing blanks error.).<010>
+00025 00025| @p <010>
+00026 00026| @t <010>
+00027 00027| <010>
+00028 00028| 6. Test pragma with too many arguments.<010>
+00029 00029| @p a b c d e f g h i j k l m n o p q r s t u v w x y z<010>
+00030 00030| @t a b c d e f g h i j k l m n o p q r s t u v w x y z<010>
+00031 00031| <010>
+00032 00032| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 9 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC21: Test generic syntax checking of pragmas and typesetter directives.<010>
+<010>
+1. Test pragma not at the start of line.<010>
+ "
+0005[01]: Text. Text scrap[White]=" "
+0006[01]: Text. Text scrap[Grey]="<010>
+2. Test character following <special>p is not a blank.<010>
+"
+0012[01]: Text. Text scrap[Grey]="<010>
+3. Test pragma line is too long (limit is 100)<010>
+ 1 2 3 4 5 6 7 8 9 1<010>
+"
+0019[01]: Text. Text scrap[Grey]="<010>
+4. Test various different pragma lines.<010>
+"
+0023[01]: Text. Text scrap[Grey]="<010>
+5. Test pragma with no arguments. (Will get a trailing blanks error.).<010>
+"
+0027[01]: Text. Text scrap[Grey]="<010>
+6. Test pragma with too many arguments.<010>
+"
+0031[01]: Text. Text scrap[White]="<010>
+"
+0032[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC21: Test generic syntax checking of pragmas and typesetter directives.
+ 2 2|
+ 3 3| 1. Test pragma not at the start of line.
+ 4 4| @p
+ Error|....^Pragma sequence @p must be at the start of a line.
+ |....^The rest of this line will be ignored.
+ Error|....^Unrecognised pragma. Possible legal pragmas are:
+ |....^ @p indentation = none | blank
+ |....^ @p maximum_input_line_length = <num>|infinity
+ |....^ @p maximum_output_line_length = <num>|infinity
+ |....^ @p typesetter = none | tex
+ |....^The blanks between arguments are important.
+ |....^Pragma ignored.
+ 5 5| @t
+ Error|....^Typesetter directive @t must be at the start of a line.
+ |....^The rest of this line will be ignored.
+ Error|....^Unrecognised typesetter directive. Legal ones are:
+ |....^ @t new_page
+ |....^ @t table_of_contents
+ |....^ @t title <font> <align> <string>
+ |....^ @t vskip <num> mm
+ |....^The blanks between arguments are important.
+ |....^Typesetter directive ignored.
+ 6 6|
+ 7 7| 2. Test character following <special>p is not a blank.
+ 8 8| @px
+ Error|.^Pragma sequence @p must be followed by a blank.
+ Error|.^Unrecognised pragma. Possible legal pragmas are:
+ |.^ @p indentation = none | blank
+ |.^ @p maximum_input_line_length = <num>|infinity
+ |.^ @p maximum_output_line_length = <num>|infinity
+ |.^ @p typesetter = none | tex
+ |.^The blanks between arguments are important.
+ |.^Pragma ignored.
+ 9 9| @tx
+ Error|.^Typesetter directive @t must be followed by a blank.
+ Error|.^Unrecognised typesetter directive. Legal ones are:
+ |.^ @t new_page
+ |.^ @t table_of_contents
+ |.^ @t title <font> <align> <string>
+ |.^ @t vskip <num> mm
+ |.^The blanks between arguments are important.
+ |.^Typesetter directive ignored.
+ 10 10| @p
+ Error|.^Pragma sequence @p must be followed by a blank.
+ Error|.^Unrecognised pragma. Possible legal pragmas are:
+ |.^ @p indentation = none | blank
+ |.^ @p maximum_input_line_length = <num>|infinity
+ |.^ @p maximum_output_line_length = <num>|infinity
+ |.^ @p typesetter = none | tex
+ |.^The blanks between arguments are important.
+ |.^Pragma ignored.
+ 11 11| @t
+ Error|.^Typesetter directive @t must be followed by a blank.
+ Error|.^Unrecognised typesetter directive. Legal ones are:
+ |.^ @t new_page
+ |.^ @t table_of_contents
+ |.^ @t title <font> <align> <string>
+ |.^ @t vskip <num> mm
+ |.^The blanks between arguments are important.
+ |.^Typesetter directive ignored.
+ 12 12|
+ 13 13| 3. Test pragma line is too long (limit is 100)
+ 14 14| 1 2 3 4 5 6 7 8 9 1
+ Error|.................................................................................^Input line is too long (this character is the first offender).
+ |.................................................................................^Currently, the maximum allowable input line length is 80.
+ |.................................................................................^Note: You can change this using a pragma directive (@p).
+ 15 15| @p 4567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
+ Error|.^Unrecognised pragma. Possible legal pragmas are:
+ |.^ @p indentation = none | blank
+ |.^ @p maximum_input_line_length = <num>|infinity
+ |.^ @p maximum_output_line_length = <num>|infinity
+ |.^ @p typesetter = none | tex
+ |.^The blanks between arguments are important.
+ |.^Pragma ignored.
+ Error|.................................................................................^Input line is too long (this character is the first offender).
+ |.................................................................................^Currently, the maximum allowable input line length is 80.
+ |.................................................................................^Note: You can change this using a pragma directive (@p).
+ 16 16| @p 45678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901
+ Error|.^This pragma line is too long.
+ |.^The maximum pragma line length is 100 characters.
+ Error|.^Unrecognised pragma. Possible legal pragmas are:
+ |.^ @p indentation = none | blank
+ |.^ @p maximum_input_line_length = <num>|infinity
+ |.^ @p maximum_output_line_length = <num>|infinity
+ |.^ @p typesetter = none | tex
+ |.^The blanks between arguments are important.
+ |.^Pragma ignored.
+ Error|.................................................................................^Input line is too long (this character is the first offender).
+ |.................................................................................^Currently, the maximum allowable input line length is 80.
+ |.................................................................................^Note: You can change this using a pragma directive (@p).
+ 17 17| @t 4567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
+ Error|.^Unrecognised typesetter directive. Legal ones are:
+ |.^ @t new_page
+ |.^ @t table_of_contents
+ |.^ @t title <font> <align> <string>
+ |.^ @t vskip <num> mm
+ |.^The blanks between arguments are important.
+ |.^Typesetter directive ignored.
+ Error|.................................................................................^Input line is too long (this character is the first offender).
+ |.................................................................................^Currently, the maximum allowable input line length is 80.
+ |.................................................................................^Note: You can change this using a pragma directive (@p).
+ 18 18| @t 45678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901
+ Error|.^This typestter directive line is too long.
+ |.^The maximum typesetter directive line length is 100 characters.
+ Error|.^Unrecognised typesetter directive. Legal ones are:
+ |.^ @t new_page
+ |.^ @t table_of_contents
+ |.^ @t title <font> <align> <string>
+ |.^ @t vskip <num> mm
+ |.^The blanks between arguments are important.
+ |.^Typesetter directive ignored.
+ Error|.................................................................................^Input line is too long (this character is the first offender).
+ |.................................................................................^Currently, the maximum allowable input line length is 80.
+ |.................................................................................^Note: You can change this using a pragma directive (@p).
+ 19 19|
+ 20 20| 4. Test various different pragma lines.
+ 21 21| @p $#%@ 2525 sloth
+ Error|.^Unrecognised pragma. Possible legal pragmas are:
+ |.^ @p indentation = none | blank
+ |.^ @p maximum_input_line_length = <num>|infinity
+ |.^ @p maximum_output_line_length = <num>|infinity
+ |.^ @p typesetter = none | tex
+ |.^The blanks between arguments are important.
+ |.^Pragma ignored.
+ 22 22| @t $#%@ 2525 sloth
+ Error|.^Unrecognised typesetter directive. Legal ones are:
+ |.^ @t new_page
+ |.^ @t table_of_contents
+ |.^ @t title <font> <align> <string>
+ |.^ @t vskip <num> mm
+ |.^The blanks between arguments are important.
+ |.^Typesetter directive ignored.
+ 23 23|
+ 24 24| 5. Test pragma with no arguments. (Will get a trailing blanks error.).
+ 25 25| @p
+ Error|.^Pragma sequence @p must be followed by a keyword.
+ Error|.^Unrecognised pragma. Possible legal pragmas are:
+ |.^ @p indentation = none | blank
+ |.^ @p maximum_input_line_length = <num>|infinity
+ |.^ @p maximum_output_line_length = <num>|infinity
+ |.^ @p typesetter = none | tex
+ |.^The blanks between arguments are important.
+ |.^Pragma ignored.
+ Warning|......^Line has trailing spaces up to and including this space.
+ 26 26| @t
+ Error|.^Typesetter directive @t must be followed by a keyword.
+ Error|.^Unrecognised typesetter directive. Legal ones are:
+ |.^ @t new_page
+ |.^ @t table_of_contents
+ |.^ @t title <font> <align> <string>
+ |.^ @t vskip <num> mm
+ |.^The blanks between arguments are important.
+ |.^Typesetter directive ignored.
+ Warning|......^Line has trailing spaces up to and including this space.
+ 27 27|
+ 28 28| 6. Test pragma with too many arguments.
+ 29 29| @p a b c d e f g h i j k l m n o p q r s t u v w x y z
+ Error|.^Unrecognised pragma. Possible legal pragmas are:
+ |.^ @p indentation = none | blank
+ |.^ @p maximum_input_line_length = <num>|infinity
+ |.^ @p maximum_output_line_length = <num>|infinity
+ |.^ @p typesetter = none | tex
+ |.^The blanks between arguments are important.
+ |.^Pragma ignored.
+ 30 30| @t a b c d e f g h i j k l m n o p q r s t u v w x y z
+ Error|.^Unrecognised typesetter directive. Legal ones are:
+ |.^ @t new_page
+ |.^ @t table_of_contents
+ |.^ @t title <font> <align> <string>
+ |.^ @t vskip <num> mm
+ |.^The blanks between arguments are important.
+ |.^Typesetter directive ignored.
+ 31 31|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 31 Errors and 2 Warnings.
diff --git a/web/funnelAC/answers/sc22.lis b/web/funnelAC/answers/sc22.lis
new file mode 100644
index 0000000000..5fd10d7311
--- /dev/null
+++ b/web/funnelAC/answers/sc22.lis
@@ -0,0 +1,165 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 32 3A 20 54 65 73 74 20 73 79 6E 74 61 | SC22: Test synta |
+| 78 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 69 6E | x checking of in |
+| 70 75 74 20 6C 69 6E 65 20 6C 65 6E 67 74 68 20 | put line length |
+| 70 72 61 67 6D 61 2E 0A 0A 31 2E 20 54 65 73 74 | pragma...1. Test |
+| 20 6E 6F 74 20 74 68 72 65 65 20 61 72 67 75 6D | not three argum |
+| 65 6E 74 73 2E 0A 40 70 20 6D 61 78 69 6D 75 6D | ents..@p maximum |
+| 5F 69 6E 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 | _input_line_leng |
+| 74 68 0A 40 70 20 6D 61 78 69 6D 75 6D 5F 69 6E | th.@p maximum_in |
+| 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 74 68 20 | put_line_length |
+| 3D 0A 40 70 20 6D 61 78 69 6D 75 6D 5F 69 6E 70 | =.@p maximum_inp |
+| 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 74 68 20 3D | ut_line_length = |
+| 20 78 78 78 20 79 79 79 0A 0A 32 2E 20 54 65 73 | xxx yyy..2. Tes |
+| 74 20 73 65 63 6F 6E 64 20 61 72 67 75 6D 65 6E | t second argumen |
+| 74 20 6E 6F 74 20 22 3D 22 2E 0A 40 70 20 6D 61 | t not "="..@p ma |
+| 78 69 6D 75 6D 5F 69 6E 70 75 74 5F 6C 69 6E 65 | ximum_input_line |
+| 5F 6C 65 6E 67 74 68 20 78 20 73 6C 6F 74 68 0A | _length x sloth. |
+| 0A 33 2E 20 54 65 73 74 20 76 61 6C 75 65 20 6F | .3. Test value o |
+| 66 20 69 6E 66 69 6E 69 74 79 2E 0A 40 70 20 6D | f infinity..@p m |
+| 61 78 69 6D 75 6D 5F 69 6E 70 75 74 5F 6C 69 6E | aximum_input_lin |
+| 65 5F 6C 65 6E 67 74 68 20 3D 20 69 6E 66 69 6E | e_length = infin |
+| 69 74 79 0A 0A 34 2E 20 54 65 73 74 20 6E 6F 6E | ity..4. Test non |
+| 2D 64 65 63 69 6D 61 6C 20 64 69 67 69 74 20 69 | -decimal digit i |
+| 6E 20 6E 75 6D 62 65 72 2E 0A 40 70 20 6D 61 78 | n number..@p max |
+| 69 6D 75 6D 5F 69 6E 70 75 74 5F 6C 69 6E 65 5F | imum_input_line_ |
+| 6C 65 6E 67 74 68 20 3D 20 32 65 66 0A 0A 35 2E | length = 2ef..5. |
+| 20 54 65 73 74 20 6E 75 6D 62 65 72 20 69 73 20 | Test number is |
+| 6D 6F 72 65 20 74 68 61 6E 20 65 69 67 68 74 20 | more than eight |
+| 64 69 67 69 74 73 20 6C 6F 6E 67 2E 0A 40 70 20 | digits long..@p |
+| 6D 61 78 69 6D 75 6D 5F 69 6E 70 75 74 5F 6C 69 | maximum_input_li |
+| 6E 65 5F 6C 65 6E 67 74 68 20 3D 20 31 32 33 34 | ne_length = 1234 |
+| 35 36 37 38 39 0A 0A 36 2E 20 54 65 73 74 20 6E | 56789..6. Test n |
+| 75 6D 62 65 72 20 69 73 20 65 78 61 63 74 6C 79 | umber is exactly |
+| 20 65 69 67 68 74 20 64 69 67 69 74 73 20 6C 6F | eight digits lo |
+| 6E 67 2E 0A 40 70 20 6D 61 78 69 6D 75 6D 5F 69 | ng..@p maximum_i |
+| 6E 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 74 68 | nput_line_length |
+| 20 3D 20 31 32 33 34 35 36 37 38 0A 0A 0A | = 12345678... |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC22: Test syntax checking of input line length pragma.<010>
+00002 00002| <010>
+00003 00003| 1. Test not three arguments.<010>
+00004 00004| @p maximum_input_line_length<010>
+00005 00005| @p maximum_input_line_length =<010>
+00006 00006| @p maximum_input_line_length = xxx yyy<010>
+00007 00007| <010>
+00008 00008| 2. Test second argument not "=".<010>
+00009 00009| @p maximum_input_line_length x sloth<010>
+00010 00010| <010>
+00011 00011| 3. Test value of infinity.<010>
+00012 00012| @p maximum_input_line_length = infinity<010>
+00013 00013| <010>
+00014 00014| 4. Test non-decimal digit in number.<010>
+00015 00015| @p maximum_input_line_length = 2ef<010>
+00016 00016| <010>
+00017 00017| 5. Test number is more than eight digits long.<010>
+00018 00018| @p maximum_input_line_length = 123456789<010>
+00019 00019| <010>
+00020 00020| 6. Test number is exactly eight digits long.<010>
+00021 00021| @p maximum_input_line_length = 12345678<010>
+00022 00022| <010>
+00023 00023| <010>
+00024 00024| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 8 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC22: Test syntax checking of input line length pragma.<010>
+<010>
+1. Test not three arguments.<010>
+"
+0007[01]: Text. Text scrap[Grey]="<010>
+2. Test second argument not "=".<010>
+"
+0010[01]: Text. Text scrap[Grey]="<010>
+3. Test value of infinity.<010>
+"
+0013[01]: Text. Text scrap[Grey]="<010>
+4. Test non-decimal digit in number.<010>
+"
+0016[01]: Text. Text scrap[Grey]="<010>
+5. Test number is more than eight digits long.<010>
+"
+0019[01]: Text. Text scrap[Grey]="<010>
+6. Test number is exactly eight digits long.<010>
+"
+0022[01]: Text. Text scrap[White]="<010>
+<010>
+"
+0024[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC22: Test syntax checking of input line length pragma.
+ 2 2|
+ 3 3| 1. Test not three arguments.
+ 4 4| @p maximum_input_line_length
+ Error|.^This pragma has the wrong number of arguments.
+ |.^The correct format is: "@p maximum_input_line_length = <num>|infinity".
+ |.^Pragma ignored.
+ 5 5| @p maximum_input_line_length =
+ Error|.^This pragma has the wrong number of arguments.
+ |.^The correct format is: "@p maximum_input_line_length = <num>|infinity".
+ |.^Pragma ignored.
+ 6 6| @p maximum_input_line_length = xxx yyy
+ Error|.^This pragma has the wrong number of arguments.
+ |.^The correct format is: "@p maximum_input_line_length = <num>|infinity".
+ |.^Pragma ignored.
+ 7 7|
+ 8 8| 2. Test second argument not "=".
+ 9 9| @p maximum_input_line_length x sloth
+ |.^The correct format is: "@p maximum_input_line_length = <num>|infinity".
+ |.^Pragma ignored.
+ Error|..............................^Expecting "=".
+ 10 10|
+ 11 11| 3. Test value of infinity.
+ 12 12| @p maximum_input_line_length = infinity
+ 13 13|
+ 14 14| 4. Test non-decimal digit in number.
+ 15 15| @p maximum_input_line_length = 2ef
+ Error|.................................^Illegal digit. Value must consist entirely of decimal digits.
+ |.................................^You can also use the value "infinity".
+ |.................................^Pragma ignored.
+ 16 16|
+ 17 17| 5. Test number is more than eight digits long.
+ 18 18| @p maximum_input_line_length = 123456789
+ Error|................................^Too many digits. The maximum is eight.
+ |................................^Pragma ignored.
+ 19 19|
+ 20 20| 6. Test number is exactly eight digits long.
+ 21 21| @p maximum_input_line_length = 12345678
+ 22 22|
+ 23 23|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 6 Errors.
diff --git a/web/funnelAC/answers/sc23.lis b/web/funnelAC/answers/sc23.lis
new file mode 100644
index 0000000000..df72bd6601
--- /dev/null
+++ b/web/funnelAC/answers/sc23.lis
@@ -0,0 +1,188 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 33 3A 20 54 65 73 74 20 73 79 6E 74 61 | SC23: Test synta |
+| 78 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 6F 75 | x checking of ou |
+| 74 70 75 74 20 6C 69 6E 65 20 6C 65 6E 67 74 68 | tput line length |
+| 20 70 72 61 67 6D 61 2E 0A 0A 31 2E 20 54 65 73 | pragma...1. Tes |
+| 74 20 6E 6F 74 20 74 68 72 65 65 20 61 72 67 75 | t not three argu |
+| 6D 65 6E 74 73 2E 0A 40 70 20 6D 61 78 69 6D 75 | ments..@p maximu |
+| 6D 5F 6F 75 74 70 75 74 5F 6C 69 6E 65 5F 6C 65 | m_output_line_le |
+| 6E 67 74 68 0A 40 70 20 6D 61 78 69 6D 75 6D 5F | ngth.@p maximum_ |
+| 6F 75 74 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 | output_line_leng |
+| 74 68 20 3D 0A 40 70 20 6D 61 78 69 6D 75 6D 5F | th =.@p maximum_ |
+| 6F 75 74 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 | output_line_leng |
+| 74 68 20 3D 20 78 78 78 20 79 79 79 0A 0A 32 2E | th = xxx yyy..2. |
+| 20 54 65 73 74 20 73 65 63 6F 6E 64 20 61 72 67 | Test second arg |
+| 75 6D 65 6E 74 20 6E 6F 74 20 22 3D 22 2E 0A 40 | ument not "="..@ |
+| 70 20 6D 61 78 69 6D 75 6D 5F 6F 75 74 70 75 74 | p maximum_output |
+| 5F 6C 69 6E 65 5F 6C 65 6E 67 74 68 20 78 20 73 | _line_length x s |
+| 6C 6F 74 68 0A 0A 33 2E 20 54 65 73 74 20 76 61 | loth..3. Test va |
+| 6C 75 65 20 6F 66 20 69 6E 66 69 6E 69 74 79 2E | lue of infinity. |
+| 0A 40 70 20 6D 61 78 69 6D 75 6D 5F 6F 75 74 70 | .@p maximum_outp |
+| 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 74 68 20 3D | ut_line_length = |
+| 20 69 6E 66 69 6E 69 74 79 0A 0A 34 2E 20 54 65 | infinity..4. Te |
+| 73 74 20 6E 6F 6E 2D 64 65 63 69 6D 61 6C 20 64 | st non-decimal d |
+| 69 67 69 74 20 69 6E 20 6E 75 6D 62 65 72 2E 0A | igit in number.. |
+| 40 70 20 6D 61 78 69 6D 75 6D 5F 6F 75 74 70 75 | @p maximum_outpu |
+| 74 5F 6C 69 6E 65 5F 6C 65 6E 67 74 68 20 3D 20 | t_line_length = |
+| 32 65 66 0A 0A 35 2E 20 54 65 73 74 20 6E 75 6D | 2ef..5. Test num |
+| 62 65 72 20 69 73 20 6D 6F 72 65 20 74 68 61 6E | ber is more than |
+| 20 65 69 67 68 74 20 64 69 67 69 74 73 20 6C 6F | eight digits lo |
+| 6E 67 2E 0A 40 70 20 6D 61 78 69 6D 75 6D 5F 6F | ng..@p maximum_o |
+| 75 74 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 74 | utput_line_lengt |
+| 68 20 3D 20 31 32 33 34 35 36 37 38 39 0A 0A 36 | h = 123456789..6 |
+| 2E 20 54 65 73 74 20 6E 75 6D 62 65 72 20 69 73 | . Test number is |
+| 20 65 78 61 63 74 6C 79 20 65 69 67 68 74 20 64 | exactly eight d |
+| 69 67 69 74 73 20 6C 6F 6E 67 2E 0A 37 2E 20 54 | igits long..7. T |
+| 65 73 74 20 70 72 61 67 6D 61 20 6F 70 70 6F 73 | est pragma oppos |
+| 69 6E 67 20 65 61 72 6C 69 65 72 20 70 72 61 67 | ing earlier prag |
+| 6D 61 2E 0A 40 70 20 6D 61 78 69 6D 75 6D 5F 6F | ma..@p maximum_o |
+| 75 74 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 74 | utput_line_lengt |
+| 68 20 3D 20 31 32 33 34 35 36 37 38 0A 0A 38 2E | h = 12345678..8. |
+| 20 54 65 73 74 20 70 72 61 67 6D 61 20 6E 6F 74 | Test pragma not |
+| 20 6F 70 70 6F 73 69 6E 67 20 65 61 72 6C 69 65 | opposing earlie |
+| 72 20 70 72 61 67 6D 61 2E 0A 40 70 20 6D 61 78 | r pragma..@p max |
+| 69 6D 75 6D 5F 6F 75 74 70 75 74 5F 6C 69 6E 65 | imum_output_line |
+| 5F 6C 65 6E 67 74 68 20 3D 20 69 6E 66 69 6E 69 | _length = infini |
+| 74 79 0A 0A | ty.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC23: Test syntax checking of output line length pragma.<010>
+00002 00002| <010>
+00003 00003| 1. Test not three arguments.<010>
+00004 00004| @p maximum_output_line_length<010>
+00005 00005| @p maximum_output_line_length =<010>
+00006 00006| @p maximum_output_line_length = xxx yyy<010>
+00007 00007| <010>
+00008 00008| 2. Test second argument not "=".<010>
+00009 00009| @p maximum_output_line_length x sloth<010>
+00010 00010| <010>
+00011 00011| 3. Test value of infinity.<010>
+00012 00012| @p maximum_output_line_length = infinity<010>
+00013 00013| <010>
+00014 00014| 4. Test non-decimal digit in number.<010>
+00015 00015| @p maximum_output_line_length = 2ef<010>
+00016 00016| <010>
+00017 00017| 5. Test number is more than eight digits long.<010>
+00018 00018| @p maximum_output_line_length = 123456789<010>
+00019 00019| <010>
+00020 00020| 6. Test number is exactly eight digits long.<010>
+00021 00021| 7. Test pragma opposing earlier pragma.<010>
+00022 00022| @p maximum_output_line_length = 12345678<010>
+00023 00023| <010>
+00024 00024| 8. Test pragma not opposing earlier pragma.<010>
+00025 00025| @p maximum_output_line_length = infinity<010>
+00026 00026| <010>
+00027 00027| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 9 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC23: Test syntax checking of output line length pragma.<010>
+<010>
+1. Test not three arguments.<010>
+"
+0007[01]: Text. Text scrap[Grey]="<010>
+2. Test second argument not "=".<010>
+"
+0010[01]: Text. Text scrap[Grey]="<010>
+3. Test value of infinity.<010>
+"
+0013[01]: Text. Text scrap[Grey]="<010>
+4. Test non-decimal digit in number.<010>
+"
+0016[01]: Text. Text scrap[Grey]="<010>
+5. Test number is more than eight digits long.<010>
+"
+0019[01]: Text. Text scrap[Grey]="<010>
+6. Test number is exactly eight digits long.<010>
+7. Test pragma opposing earlier pragma.<010>
+"
+0023[01]: Text. Text scrap[Grey]="<010>
+8. Test pragma not opposing earlier pragma.<010>
+"
+0026[01]: Text. Text scrap[White]="<010>
+"
+0027[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC23: Test syntax checking of output line length pragma.
+ 2 2|
+ 3 3| 1. Test not three arguments.
+ 4 4| @p maximum_output_line_length
+ Error|.^This pragma has the wrong number of arguments.
+ |.^The correct format is: "@p maximum_output_line_length = <num>|infinity".
+ |.^Pragma ignored.
+ 5 5| @p maximum_output_line_length =
+ Error|.^This pragma has the wrong number of arguments.
+ |.^The correct format is: "@p maximum_output_line_length = <num>|infinity".
+ |.^Pragma ignored.
+ 6 6| @p maximum_output_line_length = xxx yyy
+ Error|.^This pragma has the wrong number of arguments.
+ |.^The correct format is: "@p maximum_output_line_length = <num>|infinity".
+ |.^Pragma ignored.
+ 7 7|
+ 8 8| 2. Test second argument not "=".
+ 9 9| @p maximum_output_line_length x sloth
+ |.^The correct format is: "@p maximum_output_line_length = <num>|infinity".
+ |.^Pragma ignored.
+ Error|...............................^Expecting "=".
+ 10 10|
+ 11 11| 3. Test value of infinity.
+ 12 12| @p maximum_output_line_length = infinity
+ |.^This pragma is opposed by the pragma at line 22.
+ 13 13|
+ 14 14| 4. Test non-decimal digit in number.
+ 15 15| @p maximum_output_line_length = 2ef
+ Error|..................................^Illegal digit. Value must consist entirely of decimal digits.
+ |..................................^You can also use the value "infinity".
+ |..................................^Pragma ignored.
+ 16 16|
+ 17 17| 5. Test number is more than eight digits long.
+ 18 18| @p maximum_output_line_length = 123456789
+ Error|.................................^Too many digits. The maximum is eight.
+ |.................................^Pragma ignored.
+ 19 19|
+ 20 20| 6. Test number is exactly eight digits long.
+ 21 21| 7. Test pragma opposing earlier pragma.
+ 22 22| @p maximum_output_line_length = 12345678
+ Error|.^This pragma opposes the pragma at line 12.
+ |.^You can have as many output line length pragmas
+ |.^as you like, but they all have to be the same!
+ |.^Pragma ignored.
+ 23 23|
+ 24 24| 8. Test pragma not opposing earlier pragma.
+ 25 25| @p maximum_output_line_length = infinity
+ 26 26|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 7 Errors.
diff --git a/web/funnelAC/answers/sc24.lis b/web/funnelAC/answers/sc24.lis
new file mode 100644
index 0000000000..804e5e5d64
--- /dev/null
+++ b/web/funnelAC/answers/sc24.lis
@@ -0,0 +1,162 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 33 3A 20 54 65 73 74 20 73 79 6E 74 61 | SC23: Test synta |
+| 78 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 69 6E | x checking of in |
+| 64 65 6E 74 61 74 69 6F 6E 20 70 72 61 67 6D 61 | dentation pragma |
+| 2E 0A 0A 31 2E 20 54 65 73 74 20 6E 6F 74 20 74 | ...1. Test not t |
+| 68 72 65 65 20 61 72 67 75 6D 65 6E 74 73 2E 0A | hree arguments.. |
+| 40 70 20 69 6E 64 65 6E 74 61 74 69 6F 6E 0A 40 | @p indentation.@ |
+| 70 20 69 6E 64 65 6E 74 61 74 69 6F 6E 20 3D 0A | p indentation =. |
+| 40 70 20 69 6E 64 65 6E 74 61 74 69 6F 6E 20 3D | @p indentation = |
+| 20 78 78 78 20 79 79 79 0A 0A 32 2E 20 54 65 73 | xxx yyy..2. Tes |
+| 74 20 73 65 63 6F 6E 64 20 61 72 67 75 6D 65 6E | t second argumen |
+| 74 20 6E 6F 74 20 22 3D 22 2E 0A 40 70 20 69 6E | t not "="..@p in |
+| 64 65 6E 74 61 74 69 6F 6E 20 78 20 73 6C 6F 74 | dentation x slot |
+| 68 0A 0A 33 2E 20 54 65 73 74 20 74 68 69 72 64 | h..3. Test third |
+| 20 61 72 67 75 6D 65 6E 74 20 69 73 20 6E 6F 74 | argument is not |
+| 20 6C 65 67 61 6C 2E 0A 40 70 20 69 6E 64 65 6E | legal..@p inden |
+| 74 61 74 69 6F 6E 20 3D 20 73 6C 6F 74 68 0A 0A | tation = sloth.. |
+| 34 2E 20 54 65 73 74 20 74 68 69 72 64 20 61 72 | 4. Test third ar |
+| 67 75 6D 65 6E 74 20 69 73 20 6E 6F 6E 65 2E 0A | gument is none.. |
+| 40 70 20 69 6E 64 65 6E 74 61 74 69 6F 6E 20 3D | @p indentation = |
+| 20 6E 6F 6E 65 0A 0A 35 2E 20 54 65 73 74 20 74 | none..5. Test t |
+| 68 69 72 64 20 61 72 67 75 6D 65 6E 74 20 69 73 | hird argument is |
+| 20 62 6C 61 6E 6B 2E 0A 36 2E 20 54 65 73 74 20 | blank..6. Test |
+| 70 72 61 67 6D 61 20 6F 70 70 6F 73 65 73 20 65 | pragma opposes e |
+| 61 72 6C 69 65 72 20 70 72 61 67 6D 61 2E 0A 40 | arlier pragma..@ |
+| 70 20 69 6E 64 65 6E 74 61 74 69 6F 6E 20 3D 20 | p indentation = |
+| 62 6C 61 6E 6B 0A 0A 37 2E 20 54 65 73 74 20 70 | blank..7. Test p |
+| 72 61 67 6D 61 20 64 6F 65 73 20 6E 6F 74 20 6F | ragma does not o |
+| 70 70 6F 73 65 20 65 61 72 6C 69 65 72 20 70 72 | ppose earlier pr |
+| 61 67 6D 61 2E 0A 40 70 20 69 6E 64 65 6E 74 61 | agma..@p indenta |
+| 74 69 6F 6E 20 3D 20 6E 6F 6E 65 0A 0A | tion = none.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC23: Test syntax checking of indentation pragma.<010>
+00002 00002| <010>
+00003 00003| 1. Test not three arguments.<010>
+00004 00004| @p indentation<010>
+00005 00005| @p indentation =<010>
+00006 00006| @p indentation = xxx yyy<010>
+00007 00007| <010>
+00008 00008| 2. Test second argument not "=".<010>
+00009 00009| @p indentation x sloth<010>
+00010 00010| <010>
+00011 00011| 3. Test third argument is not legal.<010>
+00012 00012| @p indentation = sloth<010>
+00013 00013| <010>
+00014 00014| 4. Test third argument is none.<010>
+00015 00015| @p indentation = none<010>
+00016 00016| <010>
+00017 00017| 5. Test third argument is blank.<010>
+00018 00018| 6. Test pragma opposes earlier pragma.<010>
+00019 00019| @p indentation = blank<010>
+00020 00020| <010>
+00021 00021| 7. Test pragma does not oppose earlier pragma.<010>
+00022 00022| @p indentation = none<010>
+00023 00023| <010>
+00024 00024| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 8 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC23: Test syntax checking of indentation pragma.<010>
+<010>
+1. Test not three arguments.<010>
+"
+0007[01]: Text. Text scrap[Grey]="<010>
+2. Test second argument not "=".<010>
+"
+0010[01]: Text. Text scrap[Grey]="<010>
+3. Test third argument is not legal.<010>
+"
+0013[01]: Text. Text scrap[Grey]="<010>
+4. Test third argument is none.<010>
+"
+0016[01]: Text. Text scrap[Grey]="<010>
+5. Test third argument is blank.<010>
+6. Test pragma opposes earlier pragma.<010>
+"
+0020[01]: Text. Text scrap[Grey]="<010>
+7. Test pragma does not oppose earlier pragma.<010>
+"
+0023[01]: Text. Text scrap[White]="<010>
+"
+0024[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC23: Test syntax checking of indentation pragma.
+ 2 2|
+ 3 3| 1. Test not three arguments.
+ 4 4| @p indentation
+ Error|.^This indentation pragma has the wrong number of arguments.
+ |.^The correct format is: "@p indentation = none|blank".
+ |.^Pragma ignored.
+ 5 5| @p indentation =
+ Error|.^This indentation pragma has the wrong number of arguments.
+ |.^The correct format is: "@p indentation = none|blank".
+ |.^Pragma ignored.
+ 6 6| @p indentation = xxx yyy
+ Error|.^This indentation pragma has the wrong number of arguments.
+ |.^The correct format is: "@p indentation = none|blank".
+ |.^Pragma ignored.
+ 7 7|
+ 8 8| 2. Test second argument not "=".
+ 9 9| @p indentation x sloth
+ |.^The correct format is: "@p indentation = none|blank".
+ |.^Pragma ignored.
+ Error|................^Expecting "=".
+ 10 10|
+ 11 11| 3. Test third argument is not legal.
+ 12 12| @p indentation = sloth
+ |.^The correct format is: "@p indentation = none|blank".
+ |.^Pragma ignored.
+ Error|..................^Expecting either "none" or "blank".
+ 13 13|
+ 14 14| 4. Test third argument is none.
+ 15 15| @p indentation = none
+ |.^This pragma is opposed by the pragma at line 19.
+ 16 16|
+ 17 17| 5. Test third argument is blank.
+ 18 18| 6. Test pragma opposes earlier pragma.
+ 19 19| @p indentation = blank
+ Error|.^This pragma opposes the pragma at line 15.
+ |.^You can have as many indentation pragmas as you like,
+ |.^but they all have to be the same!
+ |.^Pragma ignored.
+ 20 20|
+ 21 21| 7. Test pragma does not oppose earlier pragma.
+ 22 22| @p indentation = none
+ 23 23|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 6 Errors.
diff --git a/web/funnelAC/answers/sc25.lis b/web/funnelAC/answers/sc25.lis
new file mode 100644
index 0000000000..0182f4e147
--- /dev/null
+++ b/web/funnelAC/answers/sc25.lis
@@ -0,0 +1,85 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 35 3A 20 54 65 73 74 20 73 79 6E 74 61 | SC25: Test synta |
+| 78 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 6E 65 | x checking of ne |
+| 77 20 70 61 67 65 20 74 79 70 65 73 65 74 74 65 | w page typesette |
+| 72 20 64 69 72 65 63 74 69 76 65 2E 0A 0A 31 2E | r directive...1. |
+| 20 4D 61 6B 65 20 73 75 72 65 20 74 68 61 74 20 | Make sure that |
+| 61 20 6C 65 67 61 6C 20 6E 65 77 20 70 61 67 65 | a legal new page |
+| 20 64 69 72 65 63 74 69 76 65 20 69 73 20 4F 4B | directive is OK |
+| 2E 0A 40 74 20 6E 65 77 5F 70 61 67 65 0A 0A 32 | ..@t new_page..2 |
+| 2E 20 43 68 65 63 6B 20 74 68 61 74 20 69 74 20 | . Check that it |
+| 64 6F 65 73 6E 27 74 20 73 74 61 6E 64 20 66 6F | doesn't stand fo |
+| 72 20 61 6E 79 20 6E 6F 6E 73 65 6E 73 65 2E 0A | r any nonsense.. |
+| 40 74 20 6E 65 77 5F 70 61 67 65 20 6E 6F 6E 73 | @t new_page nons |
+| 65 6E 73 65 0A 0A | ense.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC25: Test syntax checking of new page typesetter directive.<010>
+00002 00002| <010>
+00003 00003| 1. Make sure that a legal new page directive is OK.<010>
+00004 00004| @t new_page<010>
+00005 00005| <010>
+00006 00006| 2. Check that it doesn't stand for any nonsense.<010>
+00007 00007| @t new_page nonsense<010>
+00008 00008| <010>
+00009 00009| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 5 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC25: Test syntax checking of new page typesetter directive.<010>
+<010>
+1. Make sure that a legal new page directive is OK.<010>
+"
+0004[01]: @t.. Newpage.
+0005[01]: Text. Text scrap[Grey]="<010>
+2. Check that it doesn't stand for any nonsense.<010>
+"
+0008[01]: Text. Text scrap[White]="<010>
+"
+0009[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC25: Test syntax checking of new page typesetter directive.
+ 2 2|
+ 3 3| 1. Make sure that a legal new page directive is OK.
+ 4 4| @t new_page
+ 5 5|
+ 6 6| 2. Check that it doesn't stand for any nonsense.
+ 7 7| @t new_page nonsense
+ Error|.............^The new_page directive does not take arguments.
+ |.............^Directive ignored.
+ 8 8|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There was 1 Error.
diff --git a/web/funnelAC/answers/sc26.lis b/web/funnelAC/answers/sc26.lis
new file mode 100644
index 0000000000..5cb968aa74
--- /dev/null
+++ b/web/funnelAC/answers/sc26.lis
@@ -0,0 +1,87 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 36 3A 20 54 65 73 74 20 73 79 6E 74 61 | SC26: Test synta |
+| 78 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 74 61 | x checking of ta |
+| 62 6C 65 20 6F 66 20 63 6F 6E 74 65 6E 74 73 20 | ble of contents |
+| 74 79 70 65 73 65 74 74 69 6E 67 20 70 72 61 67 | typesetting prag |
+| 6D 61 2E 0A 0A 31 2E 20 4D 61 6B 65 20 73 75 72 | ma...1. Make sur |
+| 65 20 74 68 61 74 20 61 20 6C 65 67 61 6C 20 74 | e that a legal t |
+| 61 62 6C 65 20 6F 66 20 63 6F 6E 74 65 6E 74 73 | able of contents |
+| 20 64 69 72 65 63 74 69 76 65 20 69 73 20 4F 4B | directive is OK |
+| 2E 0A 40 74 20 74 61 62 6C 65 5F 6F 66 5F 63 6F | ..@t table_of_co |
+| 6E 74 65 6E 74 73 0A 0A 32 2E 20 43 68 65 63 6B | ntents..2. Check |
+| 20 74 68 61 74 20 69 74 20 64 6F 65 73 6E 27 74 | that it doesn't |
+| 20 73 74 61 6E 64 20 66 6F 72 20 61 6E 79 20 6E | stand for any n |
+| 6F 6E 73 65 6E 73 65 2E 0A 40 74 20 74 61 62 6C | onsense..@t tabl |
+| 65 5F 6F 66 5F 63 6F 6E 74 65 6E 74 73 20 6E 6F | e_of_contents no |
+| 6E 73 65 6E 73 65 0A 0A | nsense.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC26: Test syntax checking of table of contents typesetting pragma.<010>
+00002 00002| <010>
+00003 00003| 1. Make sure that a legal table of contents directive is OK.<010>
+00004 00004| @t table_of_contents<010>
+00005 00005| <010>
+00006 00006| 2. Check that it doesn't stand for any nonsense.<010>
+00007 00007| @t table_of_contents nonsense<010>
+00008 00008| <010>
+00009 00009| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 5 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC26: Test syntax checking of table of contents typesetting pragma.<010>
+<010>
+1. Make sure that a legal table of contents directive is OK.<010>
+"
+0004[01]: @t.. TOC.
+0005[01]: Text. Text scrap[Grey]="<010>
+2. Check that it doesn't stand for any nonsense.<010>
+"
+0008[01]: Text. Text scrap[White]="<010>
+"
+0009[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC26: Test syntax checking of table of contents typesetting pragma.
+ 2 2|
+ 3 3| 1. Make sure that a legal table of contents directive is OK.
+ 4 4| @t table_of_contents
+ 5 5|
+ 6 6| 2. Check that it doesn't stand for any nonsense.
+ 7 7| @t table_of_contents nonsense
+ Error|......................^The table_of_contents directive does not take arguments.
+ |......................^Directive ignored.
+ 8 8|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There was 1 Error.
diff --git a/web/funnelAC/answers/sc27.lis b/web/funnelAC/answers/sc27.lis
new file mode 100644
index 0000000000..404a5b2827
--- /dev/null
+++ b/web/funnelAC/answers/sc27.lis
@@ -0,0 +1,145 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 37 3A 20 54 65 73 74 20 73 79 6E 74 61 | SC27: Test synta |
+| 78 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 76 73 | x checking of vs |
+| 6B 69 70 20 74 79 70 65 73 65 74 74 69 6E 67 20 | kip typesetting |
+| 64 69 72 65 63 74 69 76 65 2E 0A 0A 31 2E 20 54 | directive...1. T |
+| 65 73 74 20 6E 6F 74 20 65 78 61 63 74 6C 79 20 | est not exactly |
+| 74 68 72 65 65 20 61 72 67 75 6D 65 6E 74 73 20 | three arguments |
+| 28 69 6E 63 6C 75 64 65 73 20 76 73 6B 69 70 29 | (includes vskip) |
+| 2E 0A 40 74 20 76 73 6B 69 70 0A 40 74 20 76 73 | ..@t vskip.@t vs |
+| 6B 69 70 20 6F 6E 65 0A 40 74 20 76 73 6B 69 70 | kip one.@t vskip |
+| 20 6F 6E 65 20 74 77 6F 20 74 68 72 65 65 20 66 | one two three f |
+| 6F 75 72 0A 0A 32 2E 20 54 65 73 74 20 74 68 69 | our..2. Test thi |
+| 72 64 20 61 72 67 75 6D 65 6E 74 20 6E 6F 74 20 | rd argument not |
+| 22 6D 6D 22 2E 0A 40 74 20 76 73 6B 69 70 20 33 | "mm"..@t vskip 3 |
+| 32 20 78 78 0A 0A 33 2E 20 54 65 73 74 20 73 65 | 2 xx..3. Test se |
+| 63 6F 6E 64 20 61 72 67 75 6D 65 6E 74 20 68 61 | cond argument ha |
+| 73 20 62 61 64 20 64 69 67 69 74 2E 0A 40 74 20 | s bad digit..@t |
+| 76 73 6B 69 70 20 33 66 20 6D 6D 0A 0A 34 2E 20 | vskip 3f mm..4. |
+| 54 65 73 74 20 6E 75 6D 62 65 72 20 68 61 73 20 | Test number has |
+| 6D 6F 72 65 20 74 68 61 6E 20 74 68 72 65 65 20 | more than three |
+| 64 69 67 69 74 73 0A 0A 40 74 20 76 73 6B 69 70 | digits..@t vskip |
+| 20 34 33 35 35 20 6D 6D 0A 0A 35 2E 20 54 65 73 | 4355 mm..5. Tes |
+| 74 20 61 20 6C 65 67 61 6C 20 6F 6E 65 20 74 6F | t a legal one to |
+| 6F 2E 0A 40 74 20 76 73 6B 69 70 20 32 30 20 6D | o..@t vskip 20 m |
+| 6D 0A 0A | m.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC27: Test syntax checking of vskip typesetting directive.<010>
+00002 00002| <010>
+00003 00003| 1. Test not exactly three arguments (includes vskip).<010>
+00004 00004| @t vskip<010>
+00005 00005| @t vskip one<010>
+00006 00006| @t vskip one two three four<010>
+00007 00007| <010>
+00008 00008| 2. Test third argument not "mm".<010>
+00009 00009| @t vskip 32 xx<010>
+00010 00010| <010>
+00011 00011| 3. Test second argument has bad digit.<010>
+00012 00012| @t vskip 3f mm<010>
+00013 00013| <010>
+00014 00014| 4. Test number has more than three digits<010>
+00015 00015| <010>
+00016 00016| @t vskip 4355 mm<010>
+00017 00017| <010>
+00018 00018| 5. Test a legal one too.<010>
+00019 00019| @t vskip 20 mm<010>
+00020 00020| <010>
+00021 00021| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 8 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC27: Test syntax checking of vskip typesetting directive.<010>
+<010>
+1. Test not exactly three arguments (includes vskip).<010>
+"
+0007[01]: Text. Text scrap[Grey]="<010>
+2. Test third argument not "mm".<010>
+"
+0010[01]: Text. Text scrap[Grey]="<010>
+3. Test second argument has bad digit.<010>
+"
+0013[01]: Text. Text scrap[Grey]="<010>
+4. Test number has more than three digits<010>
+<010>
+"
+0017[01]: Text. Text scrap[Grey]="<010>
+5. Test a legal one too.<010>
+"
+0019[01]: @t.. Vertical skip. Vertical space skipped=20mm.
+0020[01]: Text. Text scrap[White]="<010>
+"
+0021[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC27: Test syntax checking of vskip typesetting directive.
+ 2 2|
+ 3 3| 1. Test not exactly three arguments (includes vskip).
+ 4 4| @t vskip
+ Error|.^This directive has the wrong number of arguments.
+ |.^The correct format is: "@t vskip <num> mm".
+ |.^Directive ignored.
+ 5 5| @t vskip one
+ Error|.^This directive has the wrong number of arguments.
+ |.^The correct format is: "@t vskip <num> mm".
+ |.^Directive ignored.
+ 6 6| @t vskip one two three four
+ Error|.^This directive has the wrong number of arguments.
+ |.^The correct format is: "@t vskip <num> mm".
+ |.^Directive ignored.
+ 7 7|
+ 8 8| 2. Test third argument not "mm".
+ 9 9| @t vskip 32 xx
+ |.^The correct format is: "@t vskip <num> mm".
+ |.^Directive ignored.
+ Error|.............^Expecting "mm".
+ 10 10|
+ 11 11| 3. Test second argument has bad digit.
+ 12 12| @t vskip 3f mm
+ Error|...........^Illegal digit.
+ |...........^Value must consist entirely of decimal digits.
+ |...........^Directive ignored.
+ 13 13|
+ 14 14| 4. Test number has more than three digits
+ 15 15|
+ 16 16| @t vskip 4355 mm
+ Error|..........^Too many digits. The maximum is three.
+ |..........^Directive ignored.
+ 17 17|
+ 18 18| 5. Test a legal one too.
+ 19 19| @t vskip 20 mm
+ 20 20|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 6 Errors.
diff --git a/web/funnelAC/answers/sc28.lis b/web/funnelAC/answers/sc28.lis
new file mode 100644
index 0000000000..8208193d4b
--- /dev/null
+++ b/web/funnelAC/answers/sc28.lis
@@ -0,0 +1,253 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 38 3A 20 54 65 73 74 20 73 79 6E 74 61 | SC28: Test synta |
+| 78 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 74 69 | x checking of ti |
+| 74 6C 65 20 74 79 70 65 73 65 74 74 69 6E 67 20 | tle typesetting |
+| 64 69 72 65 63 74 69 76 65 2E 0A 0A 31 2E 20 54 | directive...1. T |
+| 65 73 74 20 6C 65 73 73 20 74 68 61 6E 20 66 6F | est less than fo |
+| 75 72 20 61 72 67 75 6D 65 6E 74 73 20 28 69 6E | ur arguments (in |
+| 63 6C 75 64 65 73 20 74 69 74 6C 65 29 2E 0A 4E | cludes title)..N |
+| 6F 74 65 3A 20 54 68 65 20 74 69 74 6C 65 20 63 | ote: The title c |
+| 6F 6D 6D 61 6E 64 20 70 75 6C 6C 73 20 61 20 68 | ommand pulls a h |
+| 61 63 6B 20 74 72 65 61 74 69 6E 67 20 74 68 65 | ack treating the |
+| 20 72 65 73 74 20 6F 66 20 74 68 65 20 6C 69 6E | rest of the lin |
+| 65 20 61 66 74 65 72 0A 74 77 6F 20 61 72 67 75 | e after.two argu |
+| 6D 65 6E 74 73 20 61 73 20 74 68 65 20 73 74 72 | ments as the str |
+| 69 6E 67 2E 20 53 6F 20 69 74 20 63 61 6E 27 74 | ing. So it can't |
+| 20 64 65 74 65 63 74 20 61 6E 20 45 58 43 45 53 | detect an EXCES |
+| 53 20 6F 66 20 61 72 67 75 6D 65 6E 74 73 21 0A | S of arguments!. |
+| 40 74 20 74 69 74 6C 65 0A 40 74 20 74 69 74 6C | @t title.@t titl |
+| 65 20 74 77 6F 0A 40 74 20 74 69 74 6C 65 20 74 | e two.@t title t |
+| 77 6F 20 74 68 72 65 65 0A 0A 32 2E 20 54 65 73 | wo three..2. Tes |
+| 74 20 6F 75 74 20 62 61 64 20 66 6F 6E 74 2E 0A | t out bad font.. |
+| 40 74 20 74 69 74 6C 65 20 73 6C 6F 74 68 66 6F | @t title slothfo |
+| 6E 74 20 6C 65 66 74 20 22 53 6C 6F 74 68 22 0A | nt left "Sloth". |
+| 0A 33 2E 20 54 65 73 74 20 6F 75 74 20 62 61 64 | .3. Test out bad |
+| 20 61 6C 69 67 6E 6D 65 6E 74 2E 0A 40 74 20 74 | alignment..@t t |
+| 69 74 6C 65 20 74 69 74 6C 65 66 6F 6E 74 20 77 | itle titlefont w |
+| 65 73 74 77 61 72 64 20 22 53 6C 6F 74 68 22 0A | estward "Sloth". |
+| 0A 34 2E 20 54 65 73 74 20 6F 75 74 20 66 75 6E | .4. Test out fun |
+| 6E 79 20 73 74 72 69 6E 67 73 2E 0A 40 74 20 74 | ny strings..@t t |
+| 69 74 6C 65 20 74 69 74 6C 65 66 6F 6E 74 20 6C | itle titlefont l |
+| 65 66 74 20 22 0A 40 74 20 74 69 74 6C 65 20 74 | eft ".@t title t |
+| 69 74 6C 65 66 6F 6E 74 20 6C 65 66 74 20 22 22 | itlefont left "" |
+| 0A 40 21 20 4E 6F 74 65 3A 20 54 68 65 20 66 6F | .@! Note: The fo |
+| 6C 6C 6F 77 69 6E 67 2C 20 62 65 6C 69 65 76 65 | llowing, believe |
+| 20 69 74 20 6F 72 20 6E 6F 74 2C 20 69 73 20 61 | it or not, is a |
+| 63 74 75 61 6C 6C 79 20 4C 45 47 41 4C 21 0A 40 | ctually LEGAL!.@ |
+| 74 20 74 69 74 6C 65 20 74 69 74 6C 65 66 6F 6E | t title titlefon |
+| 74 20 6C 65 66 74 20 22 73 6C 6F 74 68 22 73 6C | t left "sloth"sl |
+| 6F 74 68 22 0A 0A 35 2E 20 54 65 73 74 20 6F 75 | oth"..5. Test ou |
+| 74 20 61 6C 6C 20 63 6F 6D 62 69 6E 61 74 69 6F | t all combinatio |
+| 6E 73 20 6F 66 20 66 6F 6E 74 20 61 6E 64 20 61 | ns of font and a |
+| 6C 69 67 6E 6D 65 6E 74 2E 0A 40 74 20 74 69 74 | lignment..@t tit |
+| 6C 65 20 74 69 74 6C 65 66 6F 6E 74 20 20 20 20 | le titlefont |
+| 20 20 6C 65 66 74 20 20 20 22 53 6C 6F 74 68 22 | left "Sloth" |
+| 0A 40 74 20 74 69 74 6C 65 20 74 69 74 6C 65 66 | .@t title titlef |
+| 6F 6E 74 20 20 20 20 20 20 63 65 6E 74 72 65 20 | ont centre |
+| 22 53 6C 6F 74 68 22 0A 40 74 20 74 69 74 6C 65 | "Sloth".@t title |
+| 20 74 69 74 6C 65 66 6F 6E 74 20 20 20 20 20 20 | titlefont |
+| 72 69 67 68 74 20 20 22 53 6C 6F 74 68 22 0A 40 | right "Sloth".@ |
+| 74 20 74 69 74 6C 65 20 73 6D 61 6C 6C 74 69 74 | t title smalltit |
+| 6C 65 66 6F 6E 74 20 6C 65 66 74 20 20 20 22 53 | lefont left "S |
+| 6C 6F 74 68 22 0A 40 74 20 74 69 74 6C 65 20 73 | loth".@t title s |
+| 6D 61 6C 6C 74 69 74 6C 65 66 6F 6E 74 20 63 65 | malltitlefont ce |
+| 6E 74 72 65 20 22 53 6C 6F 74 68 22 0A 40 74 20 | ntre "Sloth".@t |
+| 74 69 74 6C 65 20 73 6D 61 6C 6C 74 69 74 6C 65 | title smalltitle |
+| 66 6F 6E 74 20 72 69 67 68 74 20 20 22 53 6C 6F | font right "Slo |
+| 74 68 22 0A 40 74 20 74 69 74 6C 65 20 6E 6F 72 | th".@t title nor |
+| 6D 61 6C 66 6F 6E 74 20 20 20 20 20 6C 65 66 74 | malfont left |
+| 20 20 20 22 53 6C 6F 74 68 22 0A 40 74 20 74 69 | "Sloth".@t ti |
+| 74 6C 65 20 6E 6F 72 6D 61 6C 66 6F 6E 74 20 20 | tle normalfont |
+| 20 20 20 63 65 6E 74 72 65 20 22 53 6C 6F 74 68 | centre "Sloth |
+| 22 0A 40 74 20 74 69 74 6C 65 20 6E 6F 72 6D 61 | ".@t title norma |
+| 6C 66 6F 6E 74 20 20 20 20 20 72 69 67 68 74 20 | lfont right |
+| 20 22 53 6C 6F 74 68 22 0A 0A 36 2E 20 54 65 73 | "Sloth"..6. Tes |
+| 74 20 6D 69 73 73 70 65 6C 6C 69 6E 67 20 6F 66 | t misspelling of |
+| 20 63 65 6E 74 72 65 20 28 52 6F 73 73 27 73 20 | centre (Ross's |
+| 72 65 76 65 6E 67 65 29 2E 0A 40 74 20 74 69 74 | revenge)..@t tit |
+| 6C 65 20 6E 6F 72 6D 61 6C 66 6F 6E 74 20 20 20 | le normalfont |
+| 20 20 63 65 6E 74 65 72 20 22 53 6C 6F 74 68 22 | center "Sloth" |
+| 0A | . |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC28: Test syntax checking of title typesetting directive.<010>
+00002 00002| <010>
+00003 00003| 1. Test less than four arguments (includes title).<010>
+00004 00004| Note: The title command pulls a hack treating the rest of the line after<010>
+00005 00005| two arguments as the string. So it can't detect an EXCESS of arguments!<010>
+00006 00006| @t title<010>
+00007 00007| @t title two<010>
+00008 00008| @t title two three<010>
+00009 00009| <010>
+00010 00010| 2. Test out bad font.<010>
+00011 00011| @t title slothfont left "Sloth"<010>
+00012 00012| <010>
+00013 00013| 3. Test out bad alignment.<010>
+00014 00014| @t title titlefont westward "Sloth"<010>
+00015 00015| <010>
+00016 00016| 4. Test out funny strings.<010>
+00017 00017| @t title titlefont left "<010>
+00018 00018| @t title titlefont left ""<010>
+00019 00019| @! Note: The following, believe it or not, is actually LEGAL!<010>
+00020 00020| @t title titlefont left "sloth"sloth"<010>
+00021 00021| <010>
+00022 00022| 5. Test out all combinations of font and alignment.<010>
+00023 00023| @t title titlefont left "Sloth"<010>
+00024 00024| @t title titlefont centre "Sloth"<010>
+00025 00025| @t title titlefont right "Sloth"<010>
+00026 00026| @t title smalltitlefont left "Sloth"<010>
+00027 00027| @t title smalltitlefont centre "Sloth"<010>
+00028 00028| @t title smalltitlefont right "Sloth"<010>
+00029 00029| @t title normalfont left "Sloth"<010>
+00030 00030| @t title normalfont centre "Sloth"<010>
+00031 00031| @t title normalfont right "Sloth"<010>
+00032 00032| <010>
+00033 00033| 6. Test misspelling of centre (Ross's revenge).<010>
+00034 00034| @t title normalfont center "Sloth"<010>
+00035 00035| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 18 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC28: Test syntax checking of title typesetting directive.<010>
+<010>
+1. Test less than four arguments (includes title).<010>
+Note: The title command pulls a hack treating the rest of the line after<010>
+two arguments as the string. So it can't detect an EXCESS of arguments!<010>
+"
+0009[01]: Text. Text scrap[Grey]="<010>
+2. Test out bad font.<010>
+"
+0012[01]: Text. Text scrap[Grey]="<010>
+3. Test out bad alignment.<010>
+"
+0015[01]: Text. Text scrap[Grey]="<010>
+4. Test out funny strings.<010>
+"
+0018[01]: @t.. Title. Font=Title, Alignment=Left. Title text follows:
+Text scrap[Grey]=""
+0020[01]: @t.. Title. Font=Title, Alignment=Left. Title text follows:
+Text scrap[Grey]="sloth"sloth"
+0021[01]: Text. Text scrap[Grey]="<010>
+5. Test out all combinations of font and alignment.<010>
+"
+0023[01]: @t.. Title. Font=Title, Alignment=Left. Title text follows:
+Text scrap[Grey]="Sloth"
+0024[01]: @t.. Title. Font=Title, Alignment=Centre. Title text follows:
+Text scrap[Grey]="Sloth"
+0025[01]: @t.. Title. Font=Title, Alignment=Right. Title text follows:
+Text scrap[Grey]="Sloth"
+0026[01]: @t.. Title. Font=Small Title, Alignment=Left. Title text follows:
+Text scrap[Grey]="Sloth"
+0027[01]: @t.. Title. Font=Small Title, Alignment=Centre. Title text follows:
+Text scrap[Grey]="Sloth"
+0028[01]: @t.. Title. Font=Small Title, Alignment=Right. Title text follows:
+Text scrap[Grey]="Sloth"
+0029[01]: @t.. Title. Font=Normal, Alignment=Left. Title text follows:
+Text scrap[Grey]="Sloth"
+0030[01]: @t.. Title. Font=Normal, Alignment=Centre. Title text follows:
+Text scrap[Grey]="Sloth"
+0031[01]: @t.. Title. Font=Normal, Alignment=Right. Title text follows:
+Text scrap[Grey]="Sloth"
+0032[01]: Text. Text scrap[Grey]="<010>
+6. Test misspelling of centre (Ross's revenge).<010>
+"
+0035[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC28: Test syntax checking of title typesetting directive.
+ 2 2|
+ 3 3| 1. Test less than four arguments (includes title).
+ 4 4| Note: The title command pulls a hack treating the rest of the line after
+ 5 5| two arguments as the string. So it can't detect an EXCESS of arguments!
+ 6 6| @t title
+ Error|.^This directive has too few arguments.
+ |.^The correct format is: "@t title <font> <align> <text>".
+ |.^ where <font> = titlefont | smalltitlefont | normalfont.
+ |.^ and <align> = left | centre | right.
+ |.^ and <text> = text delimited by double quotes.
+ |.^Directive ignored.
+ 7 7| @t title two
+ Error|.^This directive has too few arguments.
+ |.^The correct format is: "@t title <font> <align> <text>".
+ |.^ where <font> = titlefont | smalltitlefont | normalfont.
+ |.^ and <align> = left | centre | right.
+ |.^ and <text> = text delimited by double quotes.
+ |.^Directive ignored.
+ 8 8| @t title two three
+ Error|.^This directive has too few arguments.
+ |.^The correct format is: "@t title <font> <align> <text>".
+ |.^ where <font> = titlefont | smalltitlefont | normalfont.
+ |.^ and <align> = left | centre | right.
+ |.^ and <text> = text delimited by double quotes.
+ |.^Directive ignored.
+ 9 9|
+ 10 10| 2. Test out bad font.
+ 11 11| @t title slothfont left "Sloth"
+ Error|..........^Expecting one of {titlefont,smalltitlefont,normalfont}.
+ |..........^Directive ignored.
+ 12 12|
+ 13 13| 3. Test out bad alignment.
+ 14 14| @t title titlefont westward "Sloth"
+ Error|....................^Expecting one of {left,right,centre}.
+ |....................^Directive ignored.
+ 15 15|
+ 16 16| 4. Test out funny strings.
+ 17 17| @t title titlefont left "
+ Error|.........................^Text argument must be delimited by double quotes.
+ |.........................^Directive ignored.
+ 18 18| @t title titlefont left ""
+ 19 19| @! Note: The following, believe it or not, is actually LEGAL!
+ 20 20| @t title titlefont left "sloth"sloth"
+ 21 21|
+ 22 22| 5. Test out all combinations of font and alignment.
+ 23 23| @t title titlefont left "Sloth"
+ 24 24| @t title titlefont centre "Sloth"
+ 25 25| @t title titlefont right "Sloth"
+ 26 26| @t title smalltitlefont left "Sloth"
+ 27 27| @t title smalltitlefont centre "Sloth"
+ 28 28| @t title smalltitlefont right "Sloth"
+ 29 29| @t title normalfont left "Sloth"
+ 30 30| @t title normalfont centre "Sloth"
+ 31 31| @t title normalfont right "Sloth"
+ 32 32|
+ 33 33| 6. Test misspelling of centre (Ross's revenge).
+ 34 34| @t title normalfont center "Sloth"
+ Error|.........................^Expecting one of {left,right,centre}.
+ |.........................^Note: Centre is spelt centRE, not centER.
+ |.........................^ This is my revenge for years of getting error messages
+ |.........................^ from TeX whenever I accidentally wrote \centreline - Ross Williams.
+ |.........................^Directive ignored.
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 7 Errors.
diff --git a/web/funnelAC/answers/sc29.lis b/web/funnelAC/answers/sc29.lis
new file mode 100644
index 0000000000..4253f03689
--- /dev/null
+++ b/web/funnelAC/answers/sc29.lis
@@ -0,0 +1,161 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 39 3A 20 54 65 73 74 20 73 79 6E 74 61 | SC29: Test synta |
+| 78 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 74 79 | x checking of ty |
+| 70 65 73 65 74 74 65 72 20 70 72 61 67 6D 61 2E | pesetter pragma. |
+| 0A 0A 31 2E 20 54 65 73 74 20 6E 6F 74 20 74 68 | ..1. Test not th |
+| 72 65 65 20 61 72 67 75 6D 65 6E 74 73 2E 0A 40 | ree arguments..@ |
+| 70 20 74 79 70 65 73 65 74 74 65 72 0A 40 70 20 | p typesetter.@p |
+| 74 79 70 65 73 65 74 74 65 72 20 3D 0A 40 70 20 | typesetter =.@p |
+| 74 79 70 65 73 65 74 74 65 72 20 3D 20 78 78 78 | typesetter = xxx |
+| 20 79 79 79 0A 0A 32 2E 20 54 65 73 74 20 73 65 | yyy..2. Test se |
+| 63 6F 6E 64 20 61 72 67 75 6D 65 6E 74 20 6E 6F | cond argument no |
+| 74 20 22 3D 22 2E 0A 40 70 20 74 79 70 65 73 65 | t "="..@p typese |
+| 74 74 65 72 20 78 20 73 6C 6F 74 68 0A 0A 33 2E | tter x sloth..3. |
+| 20 54 65 73 74 20 74 68 69 72 64 20 61 72 67 75 | Test third argu |
+| 6D 65 6E 74 20 69 73 20 6E 6F 74 20 6C 65 67 61 | ment is not lega |
+| 6C 2E 0A 40 70 20 74 79 70 65 73 65 74 74 65 72 | l..@p typesetter |
+| 20 3D 20 73 6C 6F 74 68 0A 0A 34 2E 20 54 65 73 | = sloth..4. Tes |
+| 74 20 74 68 69 72 64 20 61 72 67 75 6D 65 6E 74 | t third argument |
+| 20 69 73 20 6E 6F 6E 65 2E 0A 40 70 20 74 79 70 | is none..@p typ |
+| 65 73 65 74 74 65 72 20 3D 20 6E 6F 6E 65 0A 0A | esetter = none.. |
+| 35 2E 20 54 65 73 74 20 74 68 69 72 64 20 61 72 | 5. Test third ar |
+| 67 75 6D 65 6E 74 20 69 73 20 74 65 78 2E 0A 36 | gument is tex..6 |
+| 2E 20 54 65 73 74 20 70 72 61 67 6D 61 20 6F 70 | . Test pragma op |
+| 70 6F 73 65 73 20 65 61 72 6C 69 65 72 20 70 72 | poses earlier pr |
+| 61 67 6D 61 2E 0A 40 70 20 74 79 70 65 73 65 74 | agma..@p typeset |
+| 74 65 72 20 3D 20 74 65 78 0A 0A 37 2E 20 54 65 | ter = tex..7. Te |
+| 73 74 20 70 72 61 67 6D 61 20 64 6F 65 73 20 6E | st pragma does n |
+| 6F 74 20 6F 70 70 6F 73 65 20 65 61 72 6C 69 65 | ot oppose earlie |
+| 72 20 70 72 61 67 6D 61 2E 0A 40 70 20 74 79 70 | r pragma..@p typ |
+| 65 73 65 74 74 65 72 20 3D 20 6E 6F 6E 65 0A 0A | esetter = none.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC29: Test syntax checking of typesetter pragma.<010>
+00002 00002| <010>
+00003 00003| 1. Test not three arguments.<010>
+00004 00004| @p typesetter<010>
+00005 00005| @p typesetter =<010>
+00006 00006| @p typesetter = xxx yyy<010>
+00007 00007| <010>
+00008 00008| 2. Test second argument not "=".<010>
+00009 00009| @p typesetter x sloth<010>
+00010 00010| <010>
+00011 00011| 3. Test third argument is not legal.<010>
+00012 00012| @p typesetter = sloth<010>
+00013 00013| <010>
+00014 00014| 4. Test third argument is none.<010>
+00015 00015| @p typesetter = none<010>
+00016 00016| <010>
+00017 00017| 5. Test third argument is tex.<010>
+00018 00018| 6. Test pragma opposes earlier pragma.<010>
+00019 00019| @p typesetter = tex<010>
+00020 00020| <010>
+00021 00021| 7. Test pragma does not oppose earlier pragma.<010>
+00022 00022| @p typesetter = none<010>
+00023 00023| <010>
+00024 00024| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 8 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC29: Test syntax checking of typesetter pragma.<010>
+<010>
+1. Test not three arguments.<010>
+"
+0007[01]: Text. Text scrap[Grey]="<010>
+2. Test second argument not "=".<010>
+"
+0010[01]: Text. Text scrap[Grey]="<010>
+3. Test third argument is not legal.<010>
+"
+0013[01]: Text. Text scrap[Grey]="<010>
+4. Test third argument is none.<010>
+"
+0016[01]: Text. Text scrap[Grey]="<010>
+5. Test third argument is tex.<010>
+6. Test pragma opposes earlier pragma.<010>
+"
+0020[01]: Text. Text scrap[Grey]="<010>
+7. Test pragma does not oppose earlier pragma.<010>
+"
+0023[01]: Text. Text scrap[White]="<010>
+"
+0024[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC29: Test syntax checking of typesetter pragma.
+ 2 2|
+ 3 3| 1. Test not three arguments.
+ 4 4| @p typesetter
+ Error|.^This typesetter pragma has the wrong number of arguments.
+ |.^The correct format is: "@p typesetter = none|tex".
+ |.^Pragma ignored.
+ 5 5| @p typesetter =
+ Error|.^This typesetter pragma has the wrong number of arguments.
+ |.^The correct format is: "@p typesetter = none|tex".
+ |.^Pragma ignored.
+ 6 6| @p typesetter = xxx yyy
+ Error|.^This typesetter pragma has the wrong number of arguments.
+ |.^The correct format is: "@p typesetter = none|tex".
+ |.^Pragma ignored.
+ 7 7|
+ 8 8| 2. Test second argument not "=".
+ 9 9| @p typesetter x sloth
+ |.^The correct format is: "@p typesetter = none|tex".
+ |.^Pragma ignored.
+ Error|...............^Expecting "=".
+ 10 10|
+ 11 11| 3. Test third argument is not legal.
+ 12 12| @p typesetter = sloth
+ |.^The correct format is: "@p typesetter = none|tex".
+ |.^Pragma ignored.
+ Error|.................^Expecting either "none" or "tex".
+ 13 13|
+ 14 14| 4. Test third argument is none.
+ 15 15| @p typesetter = none
+ |.^This pragma is opposed by the pragma at line 19.
+ 16 16|
+ 17 17| 5. Test third argument is tex.
+ 18 18| 6. Test pragma opposes earlier pragma.
+ 19 19| @p typesetter = tex
+ Error|.^This pragma opposes the pragma at line 15.
+ |.^You can have as many typesetter pragmas as you like,
+ |.^but they all have to be the same!
+ |.^Pragma ignored.
+ 20 20|
+ 21 21| 7. Test pragma does not oppose earlier pragma.
+ 22 22| @p typesetter = none
+ 23 23|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 6 Errors.
diff --git a/web/funnelAC/answers/tg01.lis b/web/funnelAC/answers/tg01.lis
new file mode 100644
index 0000000000..47a43fdf7f
--- /dev/null
+++ b/web/funnelAC/answers/tg01.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed .out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/tg01.out b/web/funnelAC/answers/tg01.out
new file mode 100644
index 0000000000..148e1e38a0
--- /dev/null
+++ b/web/funnelAC/answers/tg01.out
@@ -0,0 +1,3 @@
+Patterson's prayer:
+ "There is nothing I would rather be, than chairman of the ABC."
+ - Les Patterson
diff --git a/web/funnelAC/answers/tg02.lis b/web/funnelAC/answers/tg02.lis
new file mode 100644
index 0000000000..a9dac774ec
--- /dev/null
+++ b/web/funnelAC/answers/tg02.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed tg02.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/tg02.out b/web/funnelAC/answers/tg02.out
new file mode 100644
index 0000000000..4f731e9543
--- /dev/null
+++ b/web/funnelAC/answers/tg02.out
@@ -0,0 +1,23 @@
+The other day upon the stair,
+I met a man who wasn't there.
+He wasn't there again today,
+I think he's from the CIA.
+
+In the output begin0 should be at the left margin, then begin1 to begin wayout
+should be indented by three spaces. Then the "It's scary" should be
+positioned over the "a" ofd margin. The rest should be at the left margin.
+
+begin0
+ begin1
+ begin2
+ begin3
+ begin4
+ begin wayout----------V
+ It's scary out here
+So far from the left margin.
+end wayout----------^
+end4
+end3
+end2
+end1
+end0
diff --git a/web/funnelAC/answers/tg03.lis b/web/funnelAC/answers/tg03.lis
new file mode 100644
index 0000000000..346577fb0d
--- /dev/null
+++ b/web/funnelAC/answers/tg03.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed tg03.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/tg03.out b/web/funnelAC/answers/tg03.out
new file mode 100644
index 0000000000..1d638b1c32
--- /dev/null
+++ b/web/funnelAC/answers/tg03.out
@@ -0,0 +1,21 @@
+The other day upon the stair,
+I met a man who wasn't there.
+He wasn't there again today,
+I think he's from the CIA.
+
+The following nest of begin and ends should be indented in a nest.
+
+begin0
+ begin1
+ begin2
+ begin3
+ begin4
+ begin wayout----------V
+ It's scary out here
+ So far from the left margin.
+ end wayout----------^
+ end4
+ end3
+ end2
+ end1
+end0
diff --git a/web/funnelAC/answers/tg04.lis b/web/funnelAC/answers/tg04.lis
new file mode 100644
index 0000000000..0ffe1aacf9
--- /dev/null
+++ b/web/funnelAC/answers/tg04.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed tg04.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/tg04.out b/web/funnelAC/answers/tg04.out
new file mode 100644
index 0000000000..e65d9bf4ab
--- /dev/null
+++ b/web/funnelAC/answers/tg04.out
@@ -0,0 +1,22 @@
+
+
+1. Test macro call with no parameters.
+"Teapot" =
+"Teapot"
+
+2. Test macro call with one parameter.
+"Left Testing Right" =
+"Left Testing Right"
+
+3. Test macro call with many parameters.
+"Left x Middle y Right" =
+"Left x Middle y Right"
+
+4. Test macro call as a parameter of another macro call.
+"Left Ostrich Middle Left Wombat Right Right" =
+"Left Ostrich Middle Left Wombat Right Right"
+
+5. Test expression recursive macro call.
+"[X[[Walrus]]Y]" =
+"[X[[Walrus]]Y]"
+
diff --git a/web/funnelAC/answers/tg05.lis b/web/funnelAC/answers/tg05.lis
new file mode 100644
index 0000000000..a9502089a9
--- /dev/null
+++ b/web/funnelAC/answers/tg05.lis
@@ -0,0 +1,17 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+E: Product file line is too long (line 4 of "<<Suppressed>>").
+ Product file line length limit is 80 characters.
+ Note: You can change the limit by specifying.
+ @p maximum_output_line_length = <desired length>
+ somewhere in the input file.
+Tangle: Completed tg05.out.
+
+There was 1 Error.
diff --git a/web/funnelAC/answers/tg05.out b/web/funnelAC/answers/tg05.out
new file mode 100644
index 0000000000..1cc2528cae
--- /dev/null
+++ b/web/funnelAC/answers/tg05.out
@@ -0,0 +1,4 @@
+We test the default limit of 80 characters.
+Only the second of the following two lines should provoke an error.
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+123456789012345678901234567890123456789012345678901234567890123456789012345678901
diff --git a/web/funnelAC/answers/tg06.lis b/web/funnelAC/answers/tg06.lis
new file mode 100644
index 0000000000..749c27a39f
--- /dev/null
+++ b/web/funnelAC/answers/tg06.lis
@@ -0,0 +1,17 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+E: Product file line is too long (line 6 of "<<Suppressed>>").
+ Product file line length limit is 60 characters.
+ Note: You can change the limit by specifying.
+ @p maximum_output_line_length = <desired length>
+ somewhere in the input file.
+Tangle: Completed tg06.out.
+
+There was 1 Error.
diff --git a/web/funnelAC/answers/tg06.out b/web/funnelAC/answers/tg06.out
new file mode 100644
index 0000000000..6d95ce3bf8
--- /dev/null
+++ b/web/funnelAC/answers/tg06.out
@@ -0,0 +1,6 @@
+We test the user-set limit of 60 characters.
+Only the third of the following three lines
+should provoke an error.
+ 1 2 3 4 5 6
+123456789012345678901234567890123456789012345678901234567890
+1234567890123456789012345678901234567890123456789012345678901
diff --git a/web/funnelAC/answers/tg07.lis b/web/funnelAC/answers/tg07.lis
new file mode 100644
index 0000000000..d6bcf21b41
--- /dev/null
+++ b/web/funnelAC/answers/tg07.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed tg07.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/tg07.out b/web/funnelAC/answers/tg07.out
new file mode 100644
index 0000000000..113b1fac7b
--- /dev/null
+++ b/web/funnelAC/answers/tg07.out
@@ -0,0 +1,2 @@
+The following long line should not blow the line length limit.
+12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
diff --git a/web/funnelAC/answers/tg08.lis b/web/funnelAC/answers/tg08.lis
new file mode 100644
index 0000000000..a3d0140430
--- /dev/null
+++ b/web/funnelAC/answers/tg08.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed tg08.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/tg08.out b/web/funnelAC/answers/tg08.out
new file mode 100644
index 0000000000..aab49f17ad
--- /dev/null
+++ b/web/funnelAC/answers/tg08.out
@@ -0,0 +1,7 @@
+Is this a mouse I see before me?
+Its contours moulded for my hand?
+Come, let me clutch thee!
+
+Now might I drink hot jolt cola
+And create hacks in C
+That would not bear witness of the Sun.
diff --git a/web/funnelAC/answers/tg09.lis b/web/funnelAC/answers/tg09.lis
new file mode 100644
index 0000000000..f8c0868d36
--- /dev/null
+++ b/web/funnelAC/answers/tg09.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed tg09.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/tg09.out b/web/funnelAC/answers/tg09.out
new file mode 100644
index 0000000000..64d7ff5028
--- /dev/null
+++ b/web/funnelAC/answers/tg09.out
@@ -0,0 +1,23 @@
+A Megastar's Mantras
+--------------------
+(Things that Mean a Lot to Me)
+
+A is for Australia
+The land I adore;
+It's so spotless and clean
+You can eat off the floor.
+
+B is for Boomerang,
+Which our quaint Abos launch
+In the hope it will bring back
+A roast quokka's haunch.
+
+C is for Culture
+Which blossoms unchecked,
+You can't move in my homeland
+for Beckett and Brecht.
+
+...more...
+
+- Dame Edna Everage,
+"Neglected Poems and Other Creatures" by Barry Humphries, 1991.
diff --git a/web/funnelAC/answers/wv01.lis b/web/funnelAC/answers/wv01.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/answers/wv01.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/wv01.tex b/web/funnelAC/answers/wv01.tex
new file mode 100644
index 0000000000..83e0d3a42a
--- /dev/null
+++ b/web/funnelAC/answers/wv01.tex
@@ -0,0 +1,367 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+WV01: Test basic typeset file output mechanism.
+
+\fwseca{1}{A section for no particular reason}
+
+\fwbeginmacro
+\fwfilename{wv01.out}{1}\fwequals \fwodef \fwbtx[Some text for no particular reason.
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/answers/wv02.lis b/web/funnelAC/answers/wv02.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/answers/wv02.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/wv02.tex b/web/funnelAC/answers/wv02.tex
new file mode 100644
index 0000000000..aab813ee0f
--- /dev/null
+++ b/web/funnelAC/answers/wv02.tex
@@ -0,0 +1,454 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+WV05: Test typesetting features.
+
+\fwbeginmacro
+\fwfilename{wv05.out}{1}\fwequals \fwodef \fwbtx[
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+
+1. Test all five levels of headings with explicit titles.
+
+\fwseca{1}{One}
+\fwsecb{1.1}{Two}
+\fwsecc{1.1.1}{Three}
+\fwsecd{1.1.1.1}{Four}
+\fwsece{1.1.1.1.1}{Five}
+
+2. Test all five levels of headings with implicit titles.
+
+\fwseca{2}{Macro at level one}
+\fwbeginmacro
+\fwmacroname{Macro at level one}{2}\fwzero{}\fwequals \fwodef \fwbtx[Sloth]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsecb{2.1}{Macro at level two}
+\fwbeginmacro
+\fwmacroname{Macro at level two}{3}\fwzero{}\fwequals \fwodef \fwbtx[Walrus]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsecc{2.1.1}{Macro at level three}
+\fwbeginmacro
+\fwmacroname{Macro at level three}{4}\fwzero{}\fwequals \fwodef \fwbtx[Aardvark]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsecd{2.1.1.1}{Macro at level four}
+\fwbeginmacro
+\fwmacroname{Macro at level four}{5}\fwzero{}\fwequals \fwodef \fwbtx[Teapot]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsece{2.1.1.1.1}{Macro at level five}
+\fwbeginmacro
+\fwmacroname{Macro at level five}{6}\fwzero{}\fwequals \fwodef \fwbtx[Emu]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+3. Test the table of contents directive.
+
+\fwtocstart{}
+\fwtoca{1}{One}
+\fwtocb{1.1}{Two}
+\fwtocc{1.1.1}{Three}
+\fwtocd{1.1.1.1}{Four}
+\fwtoce{1.1.1.1.1}{Five}
+\fwtoca{2}{Macro at level one}
+\fwtocb{2.1}{Macro at level two}
+\fwtocc{2.1.1}{Macro at level three}
+\fwtocd{2.1.1.1}{Macro at level four}
+\fwtoce{2.1.1.1.1}{Macro at level five}
+\fwtocfinish{}
+
+
+4. Test the newpage directive.
+
+\fwnewpage
+
+
+5. Test the vskip directive.
+\fwvskip{50}
+
+6. Test the title directive.
+\fwcenterline{\fwfonttitle{This is a test Title}}
+
+
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/answers/wv03.lis b/web/funnelAC/answers/wv03.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/answers/wv03.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/wv03.tex b/web/funnelAC/answers/wv03.tex
new file mode 100644
index 0000000000..f9d5bda6cd
--- /dev/null
+++ b/web/funnelAC/answers/wv03.tex
@@ -0,0 +1,568 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+WV03: Test the typesetting of various kinds of macros.
+
+First create an output file to keep the analyser happy.
+\fwbeginmacro
+\fwfilename{wv03.out}{1}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+
+1. Test macro never used.
+\fwbeginmacro
+\fwmacroname{Never Used}{2}\fwzero{}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+2. Test a macro used once.
+\fwbeginmacro
+\fwmacroname{Used Once}{3}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is invoked in definition 7.}
+\fwendmacronotes
+\fwendmacro
+
+
+3. Test a macro used twice.
+\fwbeginmacro
+\fwmacroname{Used Twice}{4}\fwmany{}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is invoked in definitions 7 and 8.}
+\fwendmacronotes
+\fwendmacro
+
+
+4. Test a macro used three times.
+\fwbeginmacro
+\fwmacroname{Used Thrice}{5}\fwmany{}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is invoked in definitions 7, 8, and 9.}
+\fwendmacronotes
+\fwendmacro
+
+
+5. Test a macro used five times.
+\fwbeginmacro
+\fwmacroname{Used Quice}{6}\fwmany{}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is invoked in definitions 7, 8, 9, 10, and 11.}
+\fwendmacronotes
+\fwendmacro
+
+
+Here is the macro that does all the calling for the above.
+\fwbeginmacro
+\fwmacroname{Dummy1}{7}\fwzero{}\fwequals \fwodef \fwmacroname{Used Once}{3}\fwbtx[
+]fwetx=%
+\fwmacroname{Used Twice}{4}\fwbtx[
+]fwetx=%
+\fwmacroname{Used Thrice}{5}\fwbtx[
+]fwetx=%
+\fwmacroname{Used Quice}{6}\fwbtx[
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwbeginmacro
+\fwmacroname{Dummy2}{8}\fwzero{}\fwequals \fwodef \fwmacroname{Used Twice}{4}\fwbtx[
+]fwetx=%
+\fwmacroname{Used Thrice}{5}\fwbtx[
+]fwetx=%
+\fwmacroname{Used Quice}{6}\fwbtx[
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwbeginmacro
+\fwmacroname{Dummy3}{9}\fwzero{}\fwequals \fwodef \fwmacroname{Used Thrice}{5}\fwbtx[
+]fwetx=%
+\fwmacroname{Used Quice}{6}\fwbtx[
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwbeginmacro
+\fwmacroname{Dummy4}{10}\fwzero{}\fwequals \fwodef \fwmacroname{Used Quice}{6}\fwbtx[
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwbeginmacro
+\fwmacroname{Dummy5}{11}\fwzero{}\fwequals \fwodef \fwmacroname{Used Quice}{6}\fwbtx[
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+6. Test a macro with two body parts.
+\fwbeginmacro
+\fwmacroname{Two body parts}{12}\fwzero{}\fwplusequals \fwodef \fwbtx[Sloth]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 12 and 13.}
+\fwusedin{This macro is invoked in definition 21.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Two body parts}{13}\fwzero{}\fwplusequals \fwodef \fwbtx[Walrus]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 12 and 13.}
+\fwusedin{This macro is invoked in definition 21.}
+\fwendmacronotes
+\fwendmacro
+
+
+7. Test a macro with three body parts.
+\fwbeginmacro
+\fwmacroname{Three body parts}{14}\fwzero{}\fwplusequals \fwodef \fwbtx[Sloth]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 14, 15, and 16.}
+\fwusedin{This macro is invoked in definition 19.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Three body parts}{15}\fwzero{}\fwplusequals \fwodef \fwbtx[Walrus]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 14, 15, and 16.}
+\fwusedin{This macro is invoked in definition 19.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Three body parts}{16}\fwzero{}\fwplusequals \fwodef \fwbtx[Aardvaark]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 14, 15, and 16.}
+\fwusedin{This macro is invoked in definition 19.}
+\fwendmacronotes
+\fwendmacro
+
+
+8. Test a macro with five body parts.
+\fwbeginmacro
+\fwmacroname{Five body parts}{17}\fwzero{}\fwplusequals \fwodef \fwbtx[Sloth]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 17, 18, 19, 20, and 21.}
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Five body parts}{18}\fwzero{}\fwplusequals \fwodef \fwbtx[Walrus]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 17, 18, 19, 20, and 21.}
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Five body parts}{19}\fwzero{}\fwplusequals \fwodef \fwmacroname{Three body parts}{14}\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 17, 18, 19, 20, and 21.}
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Five body parts}{20}\fwzero{}\fwplusequals \fwodef \fwbtx[Aardvaark]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 17, 18, 19, 20, and 21.}
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Five body parts}{21}\fwzero{}\fwplusequals \fwodef \fwmacroname{Two body parts}{12}\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 17, 18, 19, 20, and 21.}
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/answers/wv04.lis b/web/funnelAC/answers/wv04.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/answers/wv04.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/wv04.tex b/web/funnelAC/answers/wv04.tex
new file mode 100644
index 0000000000..f60d8158a3
--- /dev/null
+++ b/web/funnelAC/answers/wv04.tex
@@ -0,0 +1,397 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+WV04: Test ugly string processing.
+
+\fwbeginmacro
+\fwfilename{wv04.out}{1}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+
+1. Test ugly string in section name.
+\fwseca{1}{ !\char`\"\#\$\%'()*+,-./0123456789:;$<$=$>$?}
+\fwseca{2}{ABCDEFGHIJKLMNOPQRSTUVWXYZ[$\backslash$]\char`\^\_`}
+\fwseca{3}{abcdefghijklmnopqrstuvwxyz$\{$$|$$\}$\char`\~}
+
+2. Test ugly string in macro name.
+\fwbeginmacro
+\fwmacroname{ !\char`\"\#\$\%'()*+,-./0123456789:;$<$=$>$?}{2}\fwzero{}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{ABCDEFGHIJKLMNOPQRSTUVWXYZ[$\backslash$]\char`\^\_`}{3}\fwzero{}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{abcdefghijklmnopqrstuvwxyz$\{$$|$$\}$\char`\~}{4}\fwzero{}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+3. Test ugly string in literal section.
+\fwlit{ !\char`\"\#\$\%'()*+,-./0123456789:;\char`\<=\char`\>?}
+\fwlit{ABCDEFGHIJKLMNOPQRSTUVWXYZ[\char`\\]\char`\^\_`}
+\fwlit{abcdefghijklmnopqrstuvwxyz\char`\{\char`\|\char`\}\char`\~}
+
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/answers/wv05.lis b/web/funnelAC/answers/wv05.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/answers/wv05.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/wv05.tex b/web/funnelAC/answers/wv05.tex
new file mode 100644
index 0000000000..833907b66e
--- /dev/null
+++ b/web/funnelAC/answers/wv05.tex
@@ -0,0 +1,442 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+WV05: Test processing of ugly strings as ordinary and protected text
+with no typesetter set.
+
+\fwbeginmacro
+\fwfilename{wv05.out}{1}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+
+A paragraph in ordinary mode.
+
+33 con!text
+34 con\char`\"text
+35 con\#text
+36 con\$text
+37 con\%text
+38 con\&text
+39 con'text
+40 con(text
+41 con)text
+42 con*text
+43 con+text
+44 con,text
+45 con-text
+46 con.text
+47 con/text
+48-57 con0123456789text
+58 con:text
+59 con;text
+60 con$<$text
+61 con=text
+62 con$>$text
+63 con?text
+64 con@text
+65-90 conABCDEFGHIJKLMNOPQRSTUVWXYZtext
+91 con[text
+92 con$\backslash$text
+93 con]text
+94 con\char`\^text
+95 con\_text
+96 con`text
+97-122 conabcdefghijklmnopqrstuvwxyztext
+123 con$\{$text
+124 con$|$text
+125 con$\}$text
+126 con\char`\~text
+
+Now again, but this time inside protective braces.
+
+\fwlit{
+33 con!text
+34 con\char`\"text
+35 con\#text
+36 con\$text
+37 con\%text
+38 con\&text
+39 con'text
+40 con(text
+41 con)text
+42 con*text
+43 con+text
+44 con,text
+45 con-text
+46 con.text
+47 con/text
+48-57 con0123456789text
+58 con:text
+59 con;text
+60 con\char`\<text
+61 con=text
+62 con\char`\>text
+63 con?text
+64 con@text
+65-90 conABCDEFGHIJKLMNOPQRSTUVWXYZtext
+91 con[text
+92 con\char`\\text
+93 con]text
+94 con\char`\^text
+95 con\_text
+96 con`text
+97-122 conabcdefghijklmnopqrstuvwxyztext
+123 con\char`\{text
+124 con\char`\|text
+125 con\char`\}text
+126 con\char`\~text
+}
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/answers/wv06.lis b/web/funnelAC/answers/wv06.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/answers/wv06.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/answers/wv06.tex b/web/funnelAC/answers/wv06.tex
new file mode 100644
index 0000000000..e2626dbb69
--- /dev/null
+++ b/web/funnelAC/answers/wv06.tex
@@ -0,0 +1,443 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+WV06: Test processing of ugly strings as ordinary and protected text
+with typesetter = tex.
+
+
+\fwbeginmacro
+\fwfilename{wv06.out}{1}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+
+A paragraph in ordinary mode.
+
+33 con!text
+34 con"text
+35 con#text
+36 con$text
+37 con%text
+38 con&text
+39 con'text
+40 con(text
+41 con)text
+42 con*text
+43 con+text
+44 con,text
+45 con-text
+46 con.text
+47 con/text
+48-57 con0123456789text
+58 con:text
+59 con;text
+60 con<text
+61 con=text
+62 con>text
+63 con?text
+64 con@text
+65-90 conABCDEFGHIJKLMNOPQRSTUVWXYZtext
+91 con[text
+92 con\text
+93 con]text
+94 con^text
+95 con_text
+96 con`text
+97-122 conabcdefghijklmnopqrstuvwxyztext
+123 con{text
+124 con|text
+125 con}text
+126 con~text
+
+Now again, but this time inside protective braces.
+
+\fwlit{
+33 con!text
+34 con\char`\"text
+35 con\#text
+36 con\$text
+37 con\%text
+38 con\&text
+39 con'text
+40 con(text
+41 con)text
+42 con*text
+43 con+text
+44 con,text
+45 con-text
+46 con.text
+47 con/text
+48-57 con0123456789text
+58 con:text
+59 con;text
+60 con\char`\<text
+61 con=text
+62 con\char`\>text
+63 con?text
+64 con@text
+65-90 conABCDEFGHIJKLMNOPQRSTUVWXYZtext
+91 con[text
+92 con\char`\\text
+93 con]text
+94 con\char`\^text
+95 con\_text
+96 con`text
+97-122 conabcdefghijklmnopqrstuvwxyztext
+123 con\char`\{text
+124 con\char`\|text
+125 con\char`\}text
+126 con\char`\~text
+}
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/contrib/README b/web/funnelAC/contrib/README
new file mode 100644
index 0000000000..e34781ccdb
--- /dev/null
+++ b/web/funnelAC/contrib/README
@@ -0,0 +1,36 @@
+Hi ho! Here are some FunnelWeb bits and pieces.
+
+If you are reading this and decide to pick up
+the files in this directory, please send me an email.
+That way I know who is interested.
+
+dek.fw is the FunnelWeb source to a sample program originally
+written in (Pascal) WEB by Don Knuth, and published in CACM.
+
+dek2.fw is the same program, but designed to be processed
+with LaTeX instead of Plain TeX. You'll need fw-latex.sty
+in this directory.
+To do this, use
+ fw dek2 +t
+then remove the first 347 lines of dek2.tex (the Plain TeX
+header) with your editor. (Or maybe say
+ tail +348 dek2.tex > dek2.latex ; mv dek2.latex dek2.tex
+in a Makefile . . . .)
+Then run LaTeX on dek.tex.
+
+Oh, by the way - rand_int.p is the Pascal source for a
+suitable random number generator for use with the program.
+This is Sun-specific!
+To compile (on a Sun), do
+pc -o sample sample.p rand_int.p
+(you'll get a harmless warning).
+
+PLEASE PLEASE PLEASE send me bug reports for fw-latex.sty!
+
+Note that I have only tried to get the Plain TeX functionality
+to work properly - anything extra is up to you.
+
+Richard Walker richard@cs.anu.edu.au
+Department of Computer Science Aust: (06) 249 5687
+The Australian National University Intl: +61 6 249 5687
+GPO Box 4, Canberra, ACT 2601, Australia
diff --git a/web/funnelAC/contrib/dek.fw b/web/funnelAC/contrib/dek.fw
new file mode 100644
index 0000000000..a034f137ec
--- /dev/null
+++ b/web/funnelAC/contrib/dek.fw
@@ -0,0 +1,264 @@
+@p typesetter = tex
+
+% Set your own page size here . . . .
+
+\hsize 160mm
+\vsize 245mm
+
+\def\fwseca#1#2{\fwlibc{#1}{#2}}
+\def\fwsecb#1#2{\fwlibd{#1}{#2}}
+\def\fwsecc#1#2{\fwlibe{#1}{#2}}
+\def\fwsecd#1#2{\fwlibe{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+@t vskip 40 mm
+@t title titlefont centre "A Programming Pearl"
+@t title titlefont centre "Generating sorted random numbers"
+@t vskip 20 mm
+@t title smalltitlefont centre "Don Knuth"
+@t vskip 10 mm
+@t title normalfont centre "FunnelWeb by Richard Walker"
+@t new_page
+@t table_of_contents
+@t new_page
+
+@!------------------------------------------------------------
+@a@<Introduction@>
+
+Jon Bentley recently discussed the following interesting problem
+as one of his `Programming Pearls' [{\sl Communications of the
+ACM 27\/} (December, 1984), 1179--1182]:
+
+The input consists of two integers @{M@} and @{N@}, with @{M@}$<$@{N@}.
+The output is a sorted list of @{M@} random numbers in the range
+1..@{N@} in which no integer occurs more than once. For probability
+buffs, we desire a sorted selection without replacement in which each
+selection occurs equiprobably.
+
+The present program illustrates what I think is the best solution to
+the problem, when @{M@} is reasonably large yet small compared to @{N@}.
+It's the method described tersely in the answer to exercise 3.4.2--15 of
+my book {\sl Seminumerical Algorithms}, pp.~141 and 555.
+
+@!------------------------------------------------------------
+@a@<Some macros@>
+
+For simplicity, all input and output in this program is assumed to be
+handled at the terminal. The @{WEB@} macros @{read_terminal@},
+@{print@}, and @{print_ln@} defined here can easily be changed to
+accommodate other conventions.
+
+Input a value from the terminal.
+@$@<read_terminal@>@(@1@)@M==@{read(@1)@}
+
+Output to the terminal.
+@$@<print@>@(@1@)@M==@{write(@1)@}
+
+Output to the terminal and end the line.
+@$@<print_ln@>@(@1@)@M==@{writeln(@1)@}
+
+@!------------------------------------------------------------
+@a@<An outline of the program@>
+
+Here's an outline of the entire Pascal program:
+
+@o@<sample.p@>==@{@-
+program sample(input,output);
+ var @<Global variables@>
+ @<The random number generation procedure@>
+ begin @<The main program@>;
+ end.
+@}
+
+@!------------------------------------------------------------
+@a@<Global variables@>
+
+The global variables @{M@} and @{N@} have already been mentioned; we had
+better declare them. Other global variables will be declared later.
+
+@{M_max@} is the maximum value of @{M@} allowed in this program.
+@$@<M_max@>@M==@{5000@}
+
+@{2M-1_max@} is $2M-1$ for use later on.
+@$@<2M-1_max@>@M==@{9999@}
+
+@$@<Global variables@>+=@{@-
+M: integer; { size of the sample }
+N: integer; { size of the population }
+@}
+
+@!------------------------------------------------------------
+@a@<Random number generator@>
+
+We assume the existence of a system routine called @{rand_int(i,j)@}
+that returns a random integer chosen uniformly in the range $i..j$.
+
+@$@<The random number generation procedure@>==@{@-
+function rand_int(i,j: integer): integer; external;
+@}
+
+@!------------------------------------------------------------
+@a@<A plan of attack@>
+
+After the user has specified @{M@} and @{N@}, we compute the sample by
+following a general procedure recommended by Bentley:
+
+@$@<The main program@>==@{@-
+@<Establish the values of M and N@>;
+size := 0; @<Initialise set S to empty@>;
+while size < M do
+ begin
+ T := rand_int(1,N);
+ @<If T is not in S, insert it and increase size@>;
+ end;
+@<Print the elements of S in sorted order@>@}
+
+@!------------------------------------------------------------
+@a@<More globals@>
+
+The main program just sketched has introduced several more
+globals. There's a set @{S@} of integers, whose representation
+will be deferred until later; but we can declare two auxiliary
+integer variables now.
+
+@$@<Global variables@>+=@{@-
+size: integer; { the number of elements in set S }
+T: integer; { new candidate for membership in S }
+@}
+
+@!------------------------------------------------------------
+@a
+
+The first order of business is to have a short dialogue with the
+user.
+
+@$@<Establish the values of M and N@>==@{@-
+repeat @<print@>@('population size: N = '@);
+ @<read_terminal@>@(N@);
+ if N <= 0 then
+ @<print_ln@>@('N should be positive!'@);
+until N > 0;
+repeat @<print@>@('sample size: M = '@);
+ @<read_terminal@>@(M@);
+ if M < 0 then
+ @<print_ln@>@('M shouldn''t be negative!'@)
+ else if M > N then
+ @<print_ln@>@('M shouldn''t exceed N!'@)
+ else if M > @<M_max@> then
+ @<print_ln@>@('(Sorry, M must be at most ',@<M_max@>:1,'.)'@);
+until (M >= 0) and (M <= N) and (M <= @<M_max@>)@}
+
+@!------------------------------------------------------------
+@a@<An ordered hash table@>
+
+The key idea to an efficient solution of this sampling problem is
+to maintain a set whose entries are easily sorted. The method of
+`ordered hash tables' [Amble and Knuth, {\sl The Computer Journal
+17\/} (May 1974), 135--142] is ideally suited to this task, as we
+shall see.
+
+Ordered hashing is similar to ordinary linear probing, except that
+the relative order of keys is taken into account. The cited
+paper derives theoretical results that will not be rederived
+here, but we shall use the following fundamental property: {\sl
+The entries of an ordered hash table are independent of the order
+in which its keys were inserted}. Thus, an ordered hash table is
+a `canonical' representation of its set of entries.
+
+We shall represent @{S@} by an array of $2M$ integers. Since
+Pascal doesn't permit arrays of variable size, we must leave room
+for the largest possible table.
+
+@$@<Global variables@>+=@{@-
+hash: array[0..@<2M-1_max@>] of integer;
+ { the ordered hash table }
+H: 0..@<2M-1_max@>; { an index into hash }
+H_max: 0..@<2M-1_max@>; { the current hash size }
+alpha: real; { the ratio of table size to N }
+@}
+
+@!------------------------------------------------------------
+@a
+
+@$@<Initialise set S to empty@>==@{@-
+H_max := 2 * M - 1; alpha := 2 * M / N;
+for H := 0 to H_max do hash[H] := 0@}
+
+@!------------------------------------------------------------
+@a
+
+Now we come to the interesting part, where the algorithm tries to
+insert @{T@} into an ordered hash table. The hash address
+$H=\lfloor2M(T-1)/N\rfloor$ is used as a starting point, since
+this quantity is monotonic in @{T@} and almost uniformly
+distributed in the range $0\le H<2M$.
+
+@$@<If T is not in S, insert it and increase size@>==@{@-
+H := trunc(alpha * (T-1));
+while hash[H] > T do
+ if H = 0 then H := H_max else H := H-1;
+if hash[H] < T then { T is not present }
+ begin size := size + 1;
+ @<Insert T into the ordered hash table@>;
+ end@}
+
+@!------------------------------------------------------------
+
+The heart of ordered hashing is the insertion process. In general,
+the new key @{T@} will be inserted in place of a previous key $T_1<T$,
+which is then re-inserted in place of $T_2<T_1$, etc., until an empty
+slot is discovered.
+
+@$@<Insert T into the ordered hash table@>==@{@-
+while hash[H] > 0 do
+ begin TT := hash[H]; { we have 0 < TT < T }
+ hash[H] := T; T := TT;
+ repeat if H = 0 then H := H_max
+ else H := H - 1;
+ until hash[H] < T;
+end;
+hash[H] := T@}
+
+@!------------------------------------------------------------
+@a
+
+@$@<Global variables@>+=@{@-
+TT: integer; { a key that's being moved }
+@}
+
+@!------------------------------------------------------------
+@a@<Sorting in linear time@>
+
+The climax of this program is the fact that the entries in our ordered
+hash table can easily be read out in increasing order.
+
+Why is this true? Well, we know that the final state of the table is
+independent of the order in which the elements entered. Furthermore
+it's easy to understand what the table looks like when the entries are
+inserted in decreasing order, because we have used a monotonic hash
+function. Therefore we know that the table must have an especially
+simple form.
+
+Suppose the nonzero entries are $T_1<\cdots<T_M$. If $k$ of these
+have `wrapped around' in the insertion process (i.e., if @{H@} passed
+from 0 to @{H\_max@}, $k$ times), table position @{hash[0]@} will
+either be zero (in which case $k$ must also be zero) or it will
+contain $T_{k+1}$. In the latter case, the entries
+$T_{k+1}<\cdots<T_M$ and $T_1<\cdots<T_k$ will appear in order from
+left to right. Thus the output can be sorted with at most two passes
+over the table!
+
+@$@<print_it@>@M==@{@<print_ln@>@(hash[H] : 10@)@}
+
+@$@<Print the elements of S in sorted order@>==@{@-
+if hash[0] = 0 then { there was no wrap-around }
+ begin for H := 1 to H_max do
+ if hash[H] > 0 then @<print_it@>;
+ end
+else begin for H := 1 to H_max do
+ { print the wrapped-around entries }
+ if hash[H] > 0 then
+ if hash[H] < hash[0] then @<print_it@>;
+ for H := 0 to H_max do
+ if hash[H] >= hash[0] then @<print_it@>;
+ end@}
diff --git a/web/funnelAC/contrib/dek2.fw b/web/funnelAC/contrib/dek2.fw
new file mode 100644
index 0000000000..0e7385dbf0
--- /dev/null
+++ b/web/funnelAC/contrib/dek2.fw
@@ -0,0 +1,263 @@
+@p typesetter = tex
+
+% Use a4 if you have A4 paper. If you're in the US you probably want
+% to take it out . . . .
+
+\documentstyle[fw-latex,a4]{article}
+
+\begin{document}
+
+% Just to show that it all works in LaTeX . . . .
+@t vskip 40 mm
+@t title titlefont centre "A Programming Pearl"
+@t title titlefont centre "Generating sorted random numbers"
+@t vskip 20 mm
+@t title smalltitlefont centre "Don Knuth"
+@t vskip 10 mm
+@t title normalfont centre "FunnelWeb by Richard Walker"
+@t new_page
+\tableofcontents % . . . BUT use LaTeX's table of contents.
+@t new_page
+
+@!------------------------------------------------------------
+@a@<Introduction@>
+
+Jon Bentley recently discussed the following interesting problem
+as one of his `Programming Pearls' [{\sl Communications of the
+ACM 27\/} (December, 1984), 1179--1182]:
+
+The input consists of two integers @{M@} and @{N@}, with @{M@}$<$@{N@}.
+The output is a sorted list of @{M@} random numbers in the range
+1..@{N@} in which no integer occurs more than once. For probability
+buffs, we desire a sorted selection without replacement in which each
+selection occurs equiprobably.
+
+The present program illustrates what I think is the best solution to
+the problem, when @{M@} is reasonably large yet small compared to @{N@}.
+It's the method described tersely in the answer to exercise 3.4.2--15 of
+my book {\sl Seminumerical Algorithms}, pp.~141 and 555.
+
+@!------------------------------------------------------------
+@a@<Some macros@>
+
+For simplicity, all input and output in this program is assumed to be
+handled at the terminal. The @{WEB@} macros @{read_terminal@},
+@{print@}, and @{print_ln@} defined here can easily be changed to
+accommodate other conventions.
+
+Input a value from the terminal.
+@$@<read_terminal@>@(@1@)@M==@{read(@1)@}
+
+Output to the terminal.
+@$@<print@>@(@1@)@M==@{write(@1)@}
+
+Output to the terminal and end the line.
+@$@<print_ln@>@(@1@)@M==@{writeln(@1)@}
+
+@!------------------------------------------------------------
+@a@<An outline of the program@>
+
+Here's an outline of the entire Pascal program:
+
+@o@<sample.p@>==@{@-
+program sample(input,output);
+ var @<Global variables@>
+ @<The random number generation procedure@>
+ begin @<The main program@>;
+ end.
+@}
+
+@!------------------------------------------------------------
+@a@<Global variables@>
+
+The global variables @{M@} and @{N@} have already been mentioned; we had
+better declare them. Other global variables will be declared later.
+
+@{M_max@} is the maximum value of @{M@} allowed in this program.
+@$@<M_max@>@M==@{5000@}
+
+@{2M-1_max@} is $2M-1$ for use later on.
+@$@<2M-1_max@>@M==@{9999@}
+
+@$@<Global variables@>+=@{@-
+M: integer; { size of the sample }
+N: integer; { size of the population }
+@}
+
+@!------------------------------------------------------------
+@a@<Random number generator@>
+
+We assume the existence of a system routine called @{rand_int(i,j)@}
+that returns a random integer chosen uniformly in the range $i..j$.
+
+@$@<The random number generation procedure@>==@{@-
+function rand_int(i,j: integer): integer; external;
+@}
+
+@!------------------------------------------------------------
+@a@<A plan of attack@>
+
+After the user has specified @{M@} and @{N@}, we compute the sample by
+following a general procedure recommended by Bentley:
+
+@$@<The main program@>==@{@-
+@<Establish the values of M and N@>;
+size := 0; @<Initialise set S to empty@>;
+while size < M do
+ begin
+ T := rand_int(1,N);
+ @<If T is not in S, insert it and increase size@>;
+ end;
+@<Print the elements of S in sorted order@>@}
+
+@!------------------------------------------------------------
+@a@<More globals@>
+
+The main program just sketched has introduced several more
+globals. There's a set @{S@} of integers, whose representation
+will be deferred until later; but we can declare two auxiliary
+integer variables now.
+
+@$@<Global variables@>+=@{@-
+size: integer; { the number of elements in set S }
+T: integer; { new candidate for membership in S }
+@}
+
+@!------------------------------------------------------------
+@a
+
+The first order of business is to have a short dialogue with the
+user.
+
+@$@<Establish the values of M and N@>==@{@-
+repeat @<print@>@('population size: N = '@);
+ @<read_terminal@>@(N@);
+ if N <= 0 then
+ @<print_ln@>@('N should be positive!'@);
+until N > 0;
+repeat @<print@>@('sample size: M = '@);
+ @<read_terminal@>@(M@);
+ if M < 0 then
+ @<print_ln@>@('M shouldn''t be negative!'@)
+ else if M > N then
+ @<print_ln@>@('M shouldn''t exceed N!'@)
+ else if M > @<M_max@> then
+ @<print_ln@>@('(Sorry, M must be at most ',@<M_max@>:1,'.)'@);
+until (M >= 0) and (M <= N) and (M <= @<M_max@>)@}
+
+@!------------------------------------------------------------
+@a@<An ordered hash table@>
+
+The key idea to an efficient solution of this sampling problem is
+to maintain a set whose entries are easily sorted. The method of
+`ordered hash tables' [Amble and Knuth, {\sl The Computer Journal
+17\/} (May 1974), 135--142] is ideally suited to this task, as we
+shall see.
+
+Ordered hashing is similar to ordinary linear probing, except that
+the relative order of keys is taken into account. The cited
+paper derives theoretical results that will not be rederived
+here, but we shall use the following fundamental property: {\sl
+The entries of an ordered hash table are independent of the order
+in which its keys were inserted}. Thus, an ordered hash table is
+a `canonical' representation of its set of entries.
+
+We shall represent @{S@} by an array of $2M$ integers. Since
+Pascal doesn't permit arrays of variable size, we must leave room
+for the largest possible table.
+
+@$@<Global variables@>+=@{@-
+hash: array[0..@<2M-1_max@>] of integer;
+ { the ordered hash table }
+H: 0..@<2M-1_max@>; { an index into hash }
+H_max: 0..@<2M-1_max@>; { the current hash size }
+alpha: real; { the ratio of table size to N }
+@}
+
+@!------------------------------------------------------------
+@a
+
+@$@<Initialise set S to empty@>==@{@-
+H_max := 2 * M - 1; alpha := 2 * M / N;
+for H := 0 to H_max do hash[H] := 0@}
+
+@!------------------------------------------------------------
+@a
+
+Now we come to the interesting part, where the algorithm tries to
+insert @{T@} into an ordered hash table. The hash address
+$H=\lfloor2M(T-1)/N\rfloor$ is used as a starting point, since
+this quantity is monotonic in @{T@} and almost uniformly
+distributed in the range $0\le H<2M$.
+
+@$@<If T is not in S, insert it and increase size@>==@{@-
+H := trunc(alpha * (T-1));
+while hash[H] > T do
+ if H = 0 then H := H_max else H := H-1;
+if hash[H] < T then { T is not present }
+ begin size := size + 1;
+ @<Insert T into the ordered hash table@>;
+ end@}
+
+@!------------------------------------------------------------
+
+The heart of ordered hashing is the insertion process. In general,
+the new key @{T@} will be inserted in place of a previous key $T_1<T$,
+which is then re-inserted in place of $T_2<T_1$, etc., until an empty
+slot is discovered.
+
+@$@<Insert T into the ordered hash table@>==@{@-
+while hash[H] > 0 do
+ begin TT := hash[H]; { we have 0 < TT < T }
+ hash[H] := T; T := TT;
+ repeat if H = 0 then H := H_max
+ else H := H - 1;
+ until hash[H] < T;
+end;
+hash[H] := T@}
+
+@!------------------------------------------------------------
+@a
+
+@$@<Global variables@>+=@{@-
+TT: integer; { a key that's being moved }
+@}
+
+@!------------------------------------------------------------
+@a@<Sorting in linear time@>
+
+The climax of this program is the fact that the entries in our ordered
+hash table can easily be read out in increasing order.
+
+Why is this true? Well, we know that the final state of the table is
+independent of the order in which the elements entered. Furthermore
+it's easy to understand what the table looks like when the entries are
+inserted in decreasing order, because we have used a monotonic hash
+function. Therefore we know that the table must have an especially
+simple form.
+
+Suppose the nonzero entries are $T_1<\cdots<T_M$. If $k$ of these
+have `wrapped around' in the insertion process (i.e., if @{H@} passed
+from 0 to @{H\_max@}, $k$ times), table position @{hash[0]@} will
+either be zero (in which case $k$ must also be zero) or it will
+contain $T_{k+1}$. In the latter case, the entries
+$T_{k+1}<\cdots<T_M$ and $T_1<\cdots<T_k$ will appear in order from
+left to right. Thus the output can be sorted with at most two passes
+over the table!
+
+@$@<print_it@>@M==@{@<print_ln@>@(hash[H] : 10@)@}
+
+@$@<Print the elements of S in sorted order@>==@{@-
+if hash[0] = 0 then { there was no wrap-around }
+ begin for H := 1 to H_max do
+ if hash[H] > 0 then @<print_it@>;
+ end
+else begin for H := 1 to H_max do
+ { print the wrapped-around entries }
+ if hash[H] > 0 then
+ if hash[H] < hash[0] then @<print_it@>;
+ for H := 0 to H_max do
+ if hash[H] >= hash[0] then @<print_it@>;
+ end@}
+
+\end{document}
diff --git a/web/funnelAC/contrib/rand_int.p b/web/funnelAC/contrib/rand_int.p
new file mode 100644
index 0000000000..0d836e30b1
--- /dev/null
+++ b/web/funnelAC/contrib/rand_int.p
@@ -0,0 +1,4 @@
+function rand_int(i,j: integer): integer;
+begin
+ rand_int := trunc(random(1)*(j-i+2)+i-1);
+end;
diff --git a/web/funnelAC/fwACsrc/HTML.txt b/web/funnelAC/fwACsrc/HTML.txt
new file mode 100644
index 0000000000..f3e05ba499
--- /dev/null
+++ b/web/funnelAC/fwACsrc/HTML.txt
@@ -0,0 +1,2379 @@
+Hypertext Markup Language (HTML) Tim Berners-Lee, CERN
+Internet Draft Daniel Connolly, Atrium
+IIIR Working Group June 1993
+
+
+ Hypertext Markup Language (HTML)
+
+ A Representation of Textual Information and MetaInformation
+ for Retrieval and Interchange
+
+
+Status of this Document
+
+ This document is an Internet Draft. Internet Drafts are working
+ documents of the Internet Engineering Task Force (IETF), its Areas,
+ and its Working Groups. Note that other groups may also distribute
+ working documents as Internet Drafts.
+
+ Internet Drafts are working documents valid for a maximum of six
+ months. Internet Drafts may be updated, replaced, or obsoleted by
+ other documents at any time. It is not appropriate to use Internet
+ Drafts as reference material or to cite them other than as a
+ "working draft" or "work in progress".
+
+ Distribution of this document is unlimited. The document is a
+ draft form of a standard for interchange of information on the
+ network which is proposed to be registered as a MIME (RFC1341)
+ content type. Please send comments to timbl@info.cern.ch or the
+ discussion list www-talk@info.cern.ch.
+
+ This is version 1.2 of this draft. This document is available in
+ hypertext on the World-Wide Web as
+ http://info.cern.ch/hypertext/WWW/MarkUp/HTML.html
+
+Abstract
+
+ HyperText Markup Language (HTML) can be used to represent
+
+ Hypertext news, mail, online documentation, and collaborative
+ hypermedia;
+
+ Menus of options;
+
+ Database query results;
+
+ Simple structured documents with inlined graphics.
+
+ Hypertext views of existing bodies of information
+
+ The World Wide Web (W3) initiative links related information
+ throughout the globe. HTML provides one simple format for
+ providing linked information, and all W3 compatible programs are
+ required to be capable of handling HTML. W3 uses an Internet
+
+
+
+Berners-Lee and Connolly 1
+
+ protocol (Hypertext Transfer Protocol, HTTP), which allows transfer
+ representations to be negotiated between client and server, the
+ result being returned in an extended MIME message. HTML is
+ therefore just one, but an important one, of the representations
+ used with W3.
+
+ HTML is proposed as a MIME content type.
+
+ HTML refers to the URL specification of RFCxxxx.
+
+ Implementations of HTML parsers and generators can be found in the
+ various W3 servers and browsers, in the public domain W3 code, and
+ may also be built using various public domain SGML parsers such as
+ [SGMLS] . HTML is an SGML document type with fairly generic
+ semantics appropriate for representing information from a wide
+ range of applications. It is more generic than many specific SGML
+ applications, but is still completely device-independent.
+
+ IN THIS DOCUMENT
+
+ This document contains the following parts:
+
+ Vocabulary used in this document, degrees of imperative.
+
+ HTML and MIME with discussion of character sets.
+
+ HTML and SGML and the relationship between them, and
+ Structured text : an introduction for
+ beginners to SGML.
+
+ HTML Elements A list with description, example, and
+ typical rendering.
+
+ HTML Entities Entities used to describe characters.
+
+ The HTML DTD The text of the SGML DTD for HTML
+
+ Link relationship values .
+ A provisional list. Not part of the
+ standard.
+
+ Registration Authority
+ The authority for extending lists of valid
+ vales.
+
+ References to related documents
+
+ Authors addresses Contact information.
+
+ table of contents
+
+Vocabulary
+
+
+
+
+Berners-Lee and Connolly 2
+
+ This specification uses the words below with the precise meaning
+ given.
+
+ Representation The encoding of information for interchange.
+ For example, HTML is a representation of
+ hypertext.
+
+ Rendering The form of presentation to information to
+ the human reader.
+
+ IMPERATIVES
+
+ may The implementation is not obliged to follow
+ this in any way.
+
+ must If this is not followed, the implementation
+ does not conform to this specification.
+
+ shall as "must"
+
+ should If this is not followed, though the
+ implementation officially conforms to the
+ standard, undesirable results may occur in
+ practice.
+
+ typical Typical rendering is described for many
+ elements. This is not a mandatory part of the
+ standard but is given as guidance for
+ designers and to help explain the uses for
+ which the elements were intended.
+
+ NOTES
+
+ Sections marked "Note:" are not mandatory parts of the
+ specification but for guidance only.
+
+ STATUS OF FEATURES
+
+ Mainstream All parsers must recognize these features.
+ Features are mainstream unless otherwise
+ mentioned.
+
+ Extra Standard HTML features which may safely be
+ ignored by parsers. It is legal to ignore
+ these, treat the contents as though the tags
+ were not there. (e.g. EM, and any undefined
+ elements)
+
+ Obsolete Not standard HTML. Parsers should implement
+ these features as far as possible in order to
+ preserve back-compatibility with previous
+ versions of this specification.
+
+
+
+
+Berners-Lee and Connolly 3
+
+ HTML AND MIME
+
+ The definition of the HTML content subtype is
+
+ MIME Type name text
+
+ MIME subtype name: html
+
+ Required parameters: none
+
+ Optional parameters: charset
+
+Character sets
+
+ The base character set (the SGML BASESET) for HTML is ISO Latin-1.
+ This is the set referred to by any numeric character references .
+ The actual character set used in the representation of an HTML
+ document may be ISO Latin 1, or its 7-bit subset which is ASCII.
+ There is no obligation for an HTML document to contain any
+ characters above decimal 127. It is possible that a transport
+ medium such as electronic mail imposes constraints on the number of
+ bits in a representation of a document, though the HTTP access
+ protocol used by W3 always allows 8 bit transfer.
+
+ When an HTML document is encoded using 7-bit characters, then the
+ mechanisms of character references and entity references may be
+ used to encode characters in the upper half of the ISO Latin-1 set.
+ In this way, documents may be prepared which are suitable for
+ mailing through 7-bit limited systems.
+
+ INTRODUCTION
+
+ The HyperText Markup Language is defined in terms of the ISO
+ Standard Generalized Markup Language []. SGML is a system for
+ defining structured document types and markup languages to
+ represent instances of those document types.
+
+ Every SGML document has three parts:
+
+ An SGML declaration, which binds SGML processing quantities and
+ syntax token names to specific values. For example, the SGML
+ declaration in the HTML DTD specifies that the string that opens
+ a tag is </ and the maximum length of a name is 40 characters.
+
+ A prologue including one or more document type declarations,
+ which specifiy the element types, element relationships and
+ attributes, and references that can be represented by markup.
+ The HTML DTD specifies, for example, that the HEAD element
+ contains at most one TITLE element.
+
+ An instance, which contains the data and markup of the document.
+
+ We use the term HTML to mean both the document type and the markup
+
+
+
+Berners-Lee and Connolly 4
+
+ language for representing instances of that document type.
+
+ All HTML documents share the same SGML declaration an prologue.
+ Hence implementations of the WorldWide Web generally only transmit
+ and store the instance part of an HTML document. To construct an
+ SGML document entity for processing by an SGML parser, it is
+ necessary to prefix the text from ``HTML DTD'' on page 10 to the
+ HTML instance.
+
+ Conversely, to implement an HTML parser, one need only implement
+ those parts of an SGML parser that are needed to parse an instance
+ after parsing the HTML DTD.
+
+
+
+Structured Text
+
+ An HTML instance is like a text file, except that some of the
+ characters are interpreted as markup. The markup gives structure to
+ the document.
+
+ The instance represents a hierarchy of elements. Each element has a
+ name , some attributes , and some content. Most elements are
+ represented in the document as a start tag, which gives the name
+ and attributes, followed by the content, followed by the end tag.
+ For example:
+
+ <HTML>
+ <TITLE>
+ A sample HTML instance
+ </TITLE>
+ <H1>
+ An Example of Structure
+ </H1>
+ Here's a typical paragraph.
+ <P>
+ <UL>
+ <LI>
+ Item one has an
+ <A NAME="anchor">
+ anchor
+ </A>
+ <LI>
+ Here's item two.
+ </UL>
+ </HTML>
+
+ Some elements (e.g. P, LI) are empty. They have no content. They
+ show up as just a start tag.
+
+ For the rest of the elements, the content is a sequence of data
+ characters and nested elements. Note that the HTML DTD in fact
+ severely limits the amount of nesting which is allowed: most things
+
+
+
+Berners-Lee and Connolly 5
+
+ cannot be nested, in fact. No elements may be recursively nested.
+ Anchors and character highlighting may be put inside other
+ constructs.
+
+ TAGS
+
+ Every element starts with a tag, and every non-empty element ends
+ with a tag. Start tags are delimited by < and >, and end tags are
+ delimited by </ and >.
+
+ Names
+
+ The element name immediately follows the tag open delimiter. Names
+ consist of a letter followed by up to 33 letters, digits, periods,
+ or hyphens. Names are not case sensitive.
+
+ Attributes
+
+ In a start tag, whitespace and attributes are allowed between the
+ element name and the closing delimiter. An attribute consists of a
+ name, an equal sign, and a value. Whitespace is allowed around the
+ equal sign.
+
+ The value is specified in a string surrounded by single quotes or a
+ string surrounded by double quotes. (See: other tolerated forms @@)
+
+ The string is parsed like RCDATA (see below ) to determine the
+ attribute value. This allows, for example, quote characters in
+ attribute values to be represented by character references.
+
+ The length of an attribute value (after parsing) is limited to 1024
+ characters.
+
+ ELEMENT TYPES
+
+ The name of a tag refers to an element type declaration in the HTML
+ DTD. An element type declaration associates an element name with
+
+ A list of attributes and their types and statuses
+
+ A content type (one of EMPTY, CDATA, RCDATA, ELEMENT, or MIXED)
+ which determines the syntax of the element's content
+
+ A content model, which specifies the pattern of nested elements
+ and data
+
+ Empty Elements
+
+ Empty elements have the keyword EMPTY in their declaration. For
+ example:
+
+ <!ELEMENT NEXTID - O EMPTY>
+ <!ATTLIST NEXTID N NUMBER #REQUIRED>
+
+
+
+Berners-Lee and Connolly 6
+
+ This means that the following:
+
+ <nextid n=''27''>
+
+ is legal, but these others are not:
+
+ <nextid>
+ <nextid n=''abc''>
+
+ Character Data
+
+ The keyword CDATA indicates that the content of an element is
+ character data. Character data is all the text up to the next end
+ tag open delimiter-in-context. For example:
+
+<!ELEMENT XMP - - CDATA>
+
+ specifies that the following text is a legal XMP element:
+
+ <xmp>Here's an example. It looks like it has
+ <tags> and <!--comments-->
+ in it, but it does not. Even this
+ </ is data.</xmp>
+
+ The string </ is only recognized as the opening delimiter of an end
+ tag when it is ``in context,'' that is, when it is followed by a
+ letter. However, as soon as the end tag open delimiter is
+ recognized, it terminates the CDATA content. The following is an
+ error:
+
+ <xmp>There is no way to represent </end> tags
+ in CDATA </xmp>
+
+ Replaceable Character Data
+
+ Elements with RCDATA content behave much like those with CDATA,
+ except for character references and entity references. Elements
+ declared like:
+
+<!ELEMENT TITLE - - RCDATA>
+
+ can have any sequence of characters in their content.
+
+ Character References
+
+ To represent a character that would otherwise be recognized as
+ markup, use a character reference. The string &# signals a
+ character reference when it is followed by a letter or a digit. The
+ delimiter is followed by the decimal character number and a
+ semicolon. For example:
+
+<title>You can even represent &#60;/end> tags in RCDATA </title>
+
+
+
+
+Berners-Lee and Connolly 7
+
+ Entity References
+
+ The HTML DTD declares entities for the less than, greater than, and
+ ampersand characters and each of the ISO Latin 1 characters so that
+ you can reference them by name rather than by number.
+
+ The string & signals an entity reference when it is followed by a
+ letter or a digit. The delimiter is followed by the entity name and
+ a semicolon. For example:
+
+Kurt G&ouml;del was a famous logician and mathematician.
+
+ Note: To be sure that a string of characters has
+ no markup, HTML writers should represent all
+ occurrences of <, >, and & by character or
+ entity references.
+
+ Element Content
+
+ Some elements have, in stead of a keyword that states the type of
+ content, a content model, which tells what patterns of data and
+ nested elements are allowed. If the content model of an element
+ does not include the symbol #PCDATA , the content is element
+ content.
+
+ Whitespace in element content is considered markup and ignored. Any
+ characters that are not markup, that is, data characters, are
+ illegal.
+
+ For example:
+
+<!ELEMENT HEAD - - (TITLE? & ISINDEX? & NEXTID? & LINK*)>
+
+ declares an element that may be used as follows:
+
+<head>
+ <isindex>
+ <title>Head Example</title>
+</head>
+
+ But the following are illegal:
+
+<head> no data allowed! </head>
+<head><isindex><title>Two isindex tags</title><isindex></head>
+
+ Mixed Content
+
+ If the content model includes the symbol #PCDATA, the content of
+ the element is parsed as mixed content. For example:
+
+<!ELEMENT PRE - - (#PCDATA | A | B | I | U | P)+>
+<!ATTLIST PRE
+ WIDTH NUMBER #implied
+
+
+
+Berners-Lee and Connolly 8
+
+ >
+
+ This says that the PRE element contains one or more A, B, I, U, or
+ P elements or data characters. Here's an example of a PRE element:
+
+<pre>
+<b>NAME</b>
+ cat -- concatenate<a href=''terms.html#file''>files</a>
+<b>EXAMPLE</b>
+ cat <xyz
+</pre>
+
+ The content of the above PRE element is:
+
+ A B element
+
+ The string `` cat -- concatenate''
+
+ An A element
+
+ The string ``\n''
+
+ Another B element
+
+ The string ``\n cat <xyz''
+
+ COMMENTS AND OTHER MARKUP
+
+ To include comments in an HTML document that will be ignored by the
+ parser, surround them with <!-- and -->. After the comment
+ delimiter, all text up to the next occurrence of -- is ignored.
+ Hence comments cannot be nested. Whitespace is allowed between the
+ closing -- and >. (But not between the opening <! and --.)
+
+ For example:
+
+<HEAD>
+<TITLE>HTML Guide: Recommended Usage</TITLE>
+<!-- $Id: recommended.html,v 1.3 93/01/06 18:38:11 connolly Exp $ -->
+</HEAD>
+
+ There are a few other SGML markup constructs that are deprecated or
+ illegal.
+
+ Delimiter Signals...
+
+ <? Processing instruction. Terminated by >.
+
+ <![ Marked section. Marked sections are
+ deprecated. See the SGML standard for
+ complete information.
+
+ <! Markup declaration. HTML defines no short
+
+
+
+Berners-Lee and Connolly 9
+
+ reference maps, so these are errors.
+ Terminated by >.
+
+ LINE BREAKS
+
+ A line break character is considered markup (and ignored) if it is
+ the first or last piece of content in an element. This allows you
+ to write either
+
+<PRE>some example text</pre>
+
+ or
+
+<pre>
+some example text
+</pre>
+
+ and these will be processed identically.
+
+ Also, a line that's not empty but contains no content will be
+ ignored altogether. For example, the element
+
+<pre>
+<!-- this line is ignored, including the linebreak character -->
+first line
+
+third line<!-- the following linebreak is content: -->
+fourth line<!-- this one's ignored because it's the last piece of cont
+ent: -->
+</pre>
+
+ contains only the strings
+
+
+ first line
+
+ third line
+ fourth line.
+
+ SPACES AND TABS
+
+ Space characters must be rendered as horizontal white space. In
+ HTML, multiple spaces should be rendered as proportionally larger
+ spaces.
+
+ The rendering of a horizontal tab (HT) character is not defined,
+ and HT should therefore not be used, except within a PRE (or
+ obsolete XMP, LISTING or PLAINTEXT) element.
+
+ Neither spaces nor tabs should be used to make SGML source layout
+ more attractive or easier to read.
+
+ SUMMARY OF MARKUP SIGNALS
+
+
+
+Berners-Lee and Connolly 10
+
+ The following delimiters may signal markup, depending on context.
+
+ Delimiter Signals
+
+ <!-- Comment
+
+ &# Character reference
+
+ & Entity reference
+
+ </ End tag
+
+ <! Markup declaration
+
+ ]]> Marked section close (an error)
+
+ < Start tag
+
+ HTML ELEMENTS
+
+ This is a list of elements used in the HTML language. Documents
+ should (but need not absolutely) contain an initial HEAD element
+ followed by a BODY element.
+
+ Old style documents may contain a just the contents of the normal
+ HEAD and BODY elements, in any order. This is deprecated but must
+ be supported by parsers.
+
+ See also: Status of elements
+
+Properties of the whole document
+
+ Properties of the whole document are defined by the following
+ elements. They should appear within the HEAD element. Their order
+ is not significant.
+
+ TITLE The title of the document
+
+ ISINDEX Sent by a server in a searchable document
+
+ NEXTID A parameter used by editors to generate
+ unique identifiers
+
+ LINK Relationship between this document and
+ another. See also the Anchor element ,
+ Relationships . A document may have many
+ LINK elements.
+
+ BASE A record of the URL of the document when
+ saved
+
+Text formatting
+
+
+
+
+Berners-Lee and Connolly 11
+
+ These are elements which occur within the BODY element of a
+ document. Their order is the logical order in which the elements
+ should be rendered on the output device.
+
+ Headings Several levels of heading are supported.
+
+ Anchors Sections of text which form the beginning
+ and/or end of hypertext links are called
+ "anchors" and defined by the A tag.
+
+ Paragraph marks The P element marks the break between two
+ paragraphs.
+
+ Address style An ADDRESS element is displayed in a
+ particular style.
+
+ Blockquote style A block of text quoted from another source.
+
+ Lists Bulleted lists, glossaries, etc.
+
+ Preformatted text Sections in fixed-width font for
+ preformatted text.
+
+ Character highlighting
+ Formatting elements which do not cause
+ paragraph breaks.
+
+Graphics
+
+ IMG The IMG tag allows inline graphics.
+
+Obsolete elements
+
+ The other elements are obsolete but should be recognised by parsers
+ for back-compatibility.
+
+HEAD
+
+ The HEAD element contains all information about the document in
+ general. It does not contain any text which is part of the
+ document: this is in the BODY. Within the head element, only
+ certain elements are allowed.
+
+BODY
+
+ The BODY element contains all the information which is part of the
+ document, as opposed information about the document which is in the
+ HEAD .
+
+ The elements within the BODY element are in the order in which they
+ should be presented to the reader.
+
+ See the list of things which are allowed within a BODY element .
+
+
+
+Berners-Lee and Connolly 12
+
+Anchors
+
+ An anchor is a piece of text which marks the beginning and/or the
+ end of a hypertext link.
+
+ The text between the opening tag and the closing tag is either the
+ start or destination (or both) of a link. Attributes of the anchor
+ tag are as follows.
+
+ HREF OPTIONAL. If the HREF attribute is present,
+ the anchor is sensitive text: the start of a
+ link. If the reader selects this text, (s)he
+ should be presented with another document
+ whose network address is defined by the value
+ of the HREF attribute . The format of the
+ network address is specified elsewhere . This
+ allows for the form HREF="#identifier" to
+ refer to another anchor in the same document.
+ If the anchor is in another document, the
+ attribute is a relative name , relative to
+ the documents address (or specified base
+ address if any).
+
+ NAME OPTIONAL. If present, the attribute NAME
+ allows the anchor to be the destination of a
+ link. The value of the attribute is an
+ identifier for the anchor. Identifiers are
+ arbitrary strings but must be unique within
+ the HTML document. Another document can
+ then make a reference explicitly to this
+ anchor by putting the identifier after the
+ address, separated by a hash sign .
+
+ REL OPTIONAL. An attribute REL may give the
+ relationship (s) described by the hypertext
+ link. The value is a comma-separated list of
+ relationship values. Values and their
+ semantics will be registered by the HTML
+ registration authority . The default
+ relationship if none other is given is void.
+ REL should not be present unless HREF is
+ present. See Relationship values , REV .
+
+ REV OPTIONAL. The same as REL , but the
+ semantics of the link type are in the reverse
+ direction. A link from A to B with REL="X"
+ expresses the same relationship as a link
+ from B to A with REV="X". An anchor may
+ have both REL and REV attributes.
+
+ URN OPTIONAL. If present, this specifies a
+ uniform resource number for the document. See
+ note .
+
+
+
+Berners-Lee and Connolly 13
+
+ TITLE OPTIONAL. This is informational only. If
+ present the value of this field should equal
+ the value of the TITLE of the document whose
+ address is given by the HREF attribute. See
+ note .
+
+ METHODS OPTIONAL. The value of this field is a
+ string which if present must be a comma
+ separated list of HTTP METHODS supported by
+ the object for public use. See note .
+
+ All attributes are optional, although one of NAME and HREF is
+ necessary for the anchor to be useful. See also: LINK .
+
+ EXAMPLE OF USE:
+
+ See <A HREF="http://info.cern.ch/">CERN</A>'s information for
+ more details.
+
+ A <A NAME=serious>serious</A> crime is one which is associated
+ with imprisonment.
+ ...
+ The Organization may refuse employment to anyone convicted
+ of a <a href="#serious">serious</A> crime.
+
+
+ NOTE : UNIVERSAL RESOURCE NUMBERS
+
+ URNs are provided to allow a document to be recognized if duplicate
+ copies are found. This should save a client implementation from
+ picking up a copy of something it already has.
+
+ The format of URNs is under discussion (1993) by various working
+ groups of the Internet Engineering Task Force.
+
+ NOTE: TITLE ATTRIBUTE OF LINKS
+
+ The link may carry a TITLE attribute which should if present give
+ the title of the document whose address is given by the HREF
+ attribute.
+
+ This is useful for at least two reasons
+
+ The browser software may chose to display the title of the
+ document as a preliminary to retrieving it, for example as a
+ margin note or on a small box while the mouse is over the
+ anchor, or during document fetch.
+
+ Some documents -- mainly those which are not marked up text,
+ such as graphics, plain text and also Gopher menus, do not come
+ with a title themselves, and so putting a title in the link is
+ the only way to give them a title. This is how Gopher works.
+ Obviously it leads to duplication of data, and so it is
+
+
+
+Berners-Lee and Connolly 14
+
+ dangerous to assume that the title attribute of the link is a
+ valid and unique title for the destination document.
+
+ NOTE: METHODS ATTRIBUTE OF LINKS
+
+ The METHODS attributes of anchors and links are used to provide
+ information about the functions which the user may perform on an
+ object. These are more accurately given by the HTTP protocol when
+ it is used, but it may, for similar reasons as for the TITLE
+ attribute, be useful to include the information in advance in the
+ link.
+
+ For example, The browser may chose a different rendering as a
+ function of the methods allowed (for example something which is
+ searchable may get a different icon)
+
+Address
+
+ This element is for address information, signatures, authorship,
+ etc, often at the top or bottom of a document.
+
+ TYPICAL RENDERING
+
+ Typically, an address element is italic and/or right justified or
+ indented. The address element implies a paragraph break. Paragraph
+ marks within the address element do not cause extra white space to
+ be inserted.
+
+ EXAMPLES OF USE:
+
+ <ADDRESS><A HREF="Author.html">A.N.Other</A></ADDRESS>
+
+
+ <ADDRESS>
+ Newsletter editor<p>
+ J.R. Brown<p>
+ JimquickPost News, Jumquick, CT 01234<p>
+ Tel (123) 456 7890
+ </ADDRESS>
+
+
+BASE
+
+ This element allows the URL of the document itself to be recorded
+ in situations in which the document may be read out of context.
+ URLs within the document may be in a "partial" form relative to
+ this base address.
+
+ Where the base address is not specified, the reader will use the
+ URL it used to access the document to resolve any relative URLs.
+
+ The one attribute is:
+
+
+
+
+Berners-Lee and Connolly 15
+
+ HREF the URL
+
+BLOCKQUOTE
+
+ The BLOCKQUOTE element allows text quoted from another source to be
+ rendered specially.
+
+ TYPICAL RENDERING
+
+ A typical rendering might be a slight extra left and right indent,
+ and/or italic font. BLOCKQUOTE causes a paragraph break, and
+ typically a line or so of white space will be allowed between it
+ and any text before or after it.
+
+ Single-font rendition may for example put a vertical line of ">"
+ characters down the left margin to indicate quotation in the
+ Internet mail style.
+
+ EXAMPLE
+
+I think it ends
+<BLOCKQUOTE>Soft you now, the fair Ophelia. Nymph, in thy orisons,
+be all my sins remembered.
+</BLOCKQUOTE>
+but I am not sure.
+
+Headings
+
+ Six levels of heading are supported. (Note that a hypertext node
+ within a hypertext work tends to need less levels of heading than
+ a work whose only structure is given by the nesting of headings.)
+
+ A heading element implies all the font changes, paragraph breaks
+ before and after, and white space (for example) necessary to render
+ the heading. Further character emphasis or paragraph marks are not
+ required in HTML.
+
+ H1 is the highest level of heading, and is recommended for the
+ start of a hypertext node. It is suggested that the the text of
+ the first heading be suitable for a reader who is already browsing
+ in related information, in contrast to the title tag which should
+ identify the node in a wider context.
+
+ The heading elements are
+
+ <H1>, <H2>, <H3>, <H4>, <H5>, <H6>
+
+ It is not normal practice to jump from one header to a header level
+ more than one below, for example for follow an H1 with an H3.
+ Although this is legal, it is discouraged, as it may produce
+ strange results for example when generating other representations
+ from the HTML.
+
+
+
+
+Berners-Lee and Connolly 16
+
+ EXAMPLE:
+
+ <H1>This is a heading</H1>
+ Here is some text
+ <H2>Second level heading</H2>
+ Here is some more text.
+
+ PARSER NOTE:
+
+ Parsers should not require any specific order to heading elements,
+ even if the heading level increases by more than one between
+ successive headings.
+
+ TYPICAL RENDERING
+
+ H1 Bold very large font, centered. One or two
+ lines clear space between this and anything
+ following. If printed on paper, start new
+ page.
+
+ H2 Bold, large font,, flush left against left
+ margin, no indent. One or two clear lines
+ above and below.
+
+ H3 Italic, large font, slightly indented from
+ the left margin. One or two clear lines above
+ and below.
+
+ H4 Bold, normal font, indented more than H3.
+ One clear line above and below.
+
+ H5 Italic, normal font, indented as H4. One
+ clear line above.
+
+ H6 Bold, indented same as normal text, more
+ than H5. One clear line above.
+
+ These typical values are just an indication, and it is up to the
+ designer of the presentation software to define the styles. The
+ reader may have options to customize these. When writing
+ documents, you should assume that whatever is done it is designed
+ to have the same sort of effect as the styles above.
+
+ The rendering software is responsible for generating suitable
+ vertical white space between elements, so it is NOT normal or
+ required to follow a heading element with a paragraph mark.
+
+IMG: Embedded Images
+
+ Status: Extra
+
+ The IMG element allows another document to be inserted inline. The
+ document is normally an icon or small graphic, etc. This element is
+
+
+
+Berners-Lee and Connolly 17
+
+ NOT intended for embedding other HTML text.
+
+ Browsers which are not able to display inline images ignore IMG
+ elements. Authors should note that some browsers will be able to
+ display (or print) linked graphics but not inline graphics. If the
+ graphic is essential, it may be wiser to make a link to it rather
+ than to put it inline. If the graphic is essentially decorative,
+ then IMG is appropriate.
+
+ The IMG element is empty: it has no closing tag. It has two
+ attributes:
+
+ SRC The value of this attribute is the URL of
+ the document to be embedded. Its syntax is
+ the same as that of the HREF attribute of the
+ A tag. SRC is mandatory.
+
+ ALIGN Take values TOP or MIDDLE or BOTTOM,
+ defining whether the tops or middles of
+ bottoms of the graphics and text should be
+ aligned vertically.
+
+ ALT Optional alternative text as an alternative
+ to the graphics for display in text-only
+ environments.
+
+ Note that IMG elements are allowed within anchors.
+
+ EXAMPLE
+
+ Warning: < IMG SRC ="triangle.gif" ALT="Warning:"> This must b
+e done by a
+ qualified technician.
+
+ < A HREF="Go">< IMG SRC ="Button"> Press to start</A>
+
+
+
+
+
+ISINDEX
+
+ This element informs the reader that the document is an index
+ document. As well as reading it, the reader may use a keyword
+ search.
+
+ The node may be queried with a keyword search by suffixing the node
+ address with a question mark, followed by a list of keywords
+ separated by plus signs. See the network address format .
+
+ Note that this tag is normally generated automatically by a server.
+ If it is added by hand to an HTML document, then the client will
+ assume that the server can handle a search on the document.
+
+
+
+Berners-Lee and Connolly 18
+
+ Obviously the server must have this capability for it to work:
+ simply adding <ISINDEX> in the document is not enough to make
+ searches happen if the server does not have a search engine!
+
+ Status: standard.
+
+ EXAMPLE OF USE:
+
+ <ISINDEX>
+
+LINK
+
+ The LINK element occurs within the HEAD element of an HTML
+ document. It is used to indicate a relationship between the
+ document and some other object. A document may have any number of
+ LINK elements.
+
+ The LINK element is empty, but takes the same attributes as the
+ anchor element .
+
+ Typical uses are to indicate authorship, related indexes and
+ glossaries, older or more recent versions, etc. Links can indicate
+ a static tree structure in which the document was authored by
+ pointing to a "parent" and "next" and "previous" document, for
+ example.
+
+ Servers may also allow links to be added by those who do not have
+ the right to alter the body of a document.
+
+Forms of list in HTML
+
+ GLOSSARIES
+
+ A glossary (or definition list) is a list of paragraphs each of
+ which has a short title alongside it. Apart from glossaries, this
+ element is useful for presenting a set of named elements to the
+ reader. The elements within a glossary follow are
+
+ DT The "term", typically placed in a wide left
+ indent
+
+ DD The "definition", which may wrap onto many
+ lines
+
+ These elements must appear in pairs. Single occurrences of DT
+ without a following DD are illegal. The one attribute which DL can
+ take is
+
+ COMPACT suggests that a compact rendering be used,
+ because the enclosed elements are
+ individually small, or the whole glossary is
+ rather large, or both.
+
+
+
+
+Berners-Lee and Connolly 19
+
+ Typical rendering
+
+ The definition list DT, DD pairs are arranged vertically. For
+ each pair, the DT element is on the left, in a column of about a
+ third of the display area, and the DD element is in the right hand
+ two thirds of the display area. The DT term is normally small
+ enough to fit on one line within the left-hand column. If it is
+ longer, it will either extend across the page, in which case the DD
+ section is moved down to separate them, or it is wrapped onto
+ successive lines of the left hand column.
+
+ White space is typically left between successive DT,DD pairs unless
+ the COMPACT attribute is given. The COMPACT attribute is
+ appropriate for lists which are long and/or have DT,DD pairs which
+ each take only a line or two. It is of course possible for the
+ rendering software to discover these cases itself and make its own
+ decisions, and this is to be encouraged.
+
+ The COMPACT attribute may also reduce the width of the left-hand
+ (DT) column.
+
+ Examples of use
+
+ <DL>
+ <DT>Term the first<DD>definition paragraph is reasonably
+ long but is still displayed clearly
+ <DT>Term2 follows<DD>Definition of term2
+ </DL>
+
+ <DL COMPACT>
+ <DT>Term<DD>definition paragraph
+ <DT>Term2<DD>Definition of term2
+ </DL>
+
+
+
+
+ LISTS
+
+ A list is a sequence of paragraphs, each of which may be preceded
+ by a special mark or sequence number. The syntax is:
+
+
+ <UL>
+ <LI> list element
+ <LI> another list element ...
+ </UL>
+
+ The opening list tag may be any of UL, OL, MENU or DIR. It must
+ be immediately followed by the first list element.
+
+ Typical rendering
+
+
+
+
+Berners-Lee and Connolly 20
+
+ The representation of the list is not defined here, but a bulleted
+ list for unordered lists, and a sequence of numbered paragraphs
+ for an ordered list would be quite appropriate. Other possibilities
+ for interactive display include embedded scrollable browse panels.
+
+ List elements with typical rendering are:
+
+ UL A list of multi-line paragraphs, typically
+ separated by some white space and/or marked
+ by bullets, etc.
+
+ OL As UL, but the paragraphs are typically
+ numbered in some way to indicate the order as
+ significant.
+
+ MENU A list of smaller paragraphs. Typically one
+ line per item, with a style more compact than
+ UL.
+
+ DIR A list of short elements, typically less
+ than 20 characters. These may be arranged in
+ columns across the page, typically 24
+ character in width. If the rendering software
+ is able to optimize the column width as
+ function of the widths of individual
+ elements, so much the better.
+
+ Example of use
+
+ <OL>
+ <LI> When you get to the station, leave
+ by the southern exit, on platform one.
+ <LI>Turn left to face toward the mountain
+ <LI>Walk for a mile or so until you reach the
+ "Asquith Arms" then
+ <LI>Wait and see...
+ </OL>
+
+ < MENU >
+ <LI>The oranges should be pressed fresh
+ <LI>The nuts may come from a packet
+ <LI>The gin must be good quality
+ </MENU>
+
+ < DIR >
+ <LI>A-H<LI>I-M
+ <LI>M-R<LI>S-Z
+ </DIR>
+
+
+
+Next ID
+
+
+
+
+Berners-Lee and Connolly 21
+
+ This tag takes a single attribute which is the number of the next
+ document-wide numeric identifier to be allocated of the form z123.
+
+ When modifying a document, old anchor ids should not be reused, as
+ there may be references stored elsewhere which point to them. This
+ is read and generated by hypertext editors. Human writers of HTML
+ usually use mnemonic alphabetical identifiers. Browser software may
+ ignore this tag.
+
+ EXAMPLE OF USE:
+
+ <NEXTID N=27>
+
+
+P: Paragraph mark
+
+ The empty P element indicates a paragraph break. The exact
+ rendering of this (indentation, leading, etc) is not defined here,
+ and may be a function of other tags, style sheets etc.
+
+ <P> is used between two pieces of text which otherwise would be
+ flowed together.
+
+ You do NOT need to use <P> to put white space around heading,
+ list, address or blockquote elements which imply a paragraph break.
+ It is the responsibility of the rendering software to generate that
+ white space. A paragraph mark which is preceded or followed by
+ such elements which imply a paragraph break is has undefined effect
+ and should be avoided.
+
+ TYPICAL RENDERING
+
+ Typically, <P> will generate a small vertical space (of a line or
+ half a line) between the paragraphs. This is not the case
+ (typically) within ADDRESS or (ever) within PRE elements. With
+ some implementations, in normal text, <P> may generate a small
+ extra left indent on the first line.
+
+ EXAMPLES OF USE
+
+ <h1>What to do</h1>
+ This is a one paragraph.< p >This is a second.
+ < P >
+ This is a third.
+
+ BAD EXAMPLE
+
+ <h1><P>What not to do</h1>
+ <p>I found that on my XYZ browser it looked prettier to
+ me if I put some paragraph marks
+ <p>
+ <ul><p><li>Around lists, and
+ <li>After headings.
+
+
+
+Berners-Lee and Connolly 22
+
+ </ul>
+ <p>
+ None of the paragraph marks in this example should
+ be there.
+
+
+
+
+PRE: Preformatted text
+
+ Preformatted elements in HTML are displayed with text in a fixed
+ width font, and so are suitable for text which has been formatted
+ for a teletype by some existing formatting system.
+
+
+
+ The optional attribute is:
+
+ WIDTH This attribute gives the maximum number of
+ characters which will occur on a line. It
+ allows the presentation system to select a
+ suitable font and indentation. Where the
+ WIDTH attribute is not recognized, it is
+ recommended that a width of 80 be assumed.
+ Where WIDTH is supported, it is recommended
+ that at least widths of 40, 80 and 132
+ characters be presented optimally, with other
+ widths being rounded up.
+
+ Within a PRE element,
+
+ Line boundaries within the text are rendered as a move to the
+ beginning of the next line, except for one immediately following
+ or immediately preceding a tag.
+
+ The <p> tag should not be used. If found, it should be rendered
+ as a move to the beginning of the next line.
+
+ Anchor elements and character highlighting elements may be used.
+
+ Elements which define paragraph formatting (Headings, Address,
+ etc) must not be used.
+
+ The ASCII Horizontal Tab (HT) character must be interpreted as
+ the smallest positive nonzero number of spaces which will leave
+ the number of characters so far on the line as a multiple of 8.
+ Its use is not recommended however.
+
+ Example of use
+
+ <PRE WIDTH="80">
+ This is an example line
+ </PRE>
+
+
+
+Berners-Lee and Connolly 23
+
+ Note: Highlighting
+
+ Within a preformatted element, the constraint that the rendering
+ must be on a fixed horizontal character pitch may limit or prevent
+ the ability of the renderer to render highlighting elements
+ specially.
+
+ Note: Margins
+
+ The above references to the "beginning of a new line" must not be
+ taken as implying that the renderer is forbidden from using a
+ (constant) left indent for rendering preformatted text. The left
+ indent may of course be constrained by the width required.
+
+TITLE
+
+ The title of a document is specified by the TITLE element. The
+ TITLE element should occur in the HEAD of the document.
+
+ There may only be one title in any document. It should identify the
+ content of the document in a fairly wide context.
+
+ The title is not part of the text of the document, but is a
+ property of the whole document. It may not contain anchors,
+ paragraph marks, or highlighting. The title may be used to identify
+ the node in a history list, to label the window displaying the
+ node, etc. It is not normally displayed in the text of a document
+ itself. Contrast titles with headings . The title should ideally
+ be less than 64 characters in length. That is, many applications
+ will display document titles in window titles, menus, etc where
+ there is only limited room. Whilst there is no limit on the length
+ of a title (as it may be automatically generated from other data),
+ information providers are warned that it may be truncated if long.
+
+ Examples of use
+
+ Appropriate titles might be
+
+ <TITLE>Rivest and Neuman. 1989(b)</TITLE>
+
+ or
+
+ <TITLE>A Recipe for Maple Syrup Flap-Jack</TITLE>
+
+ or
+
+ <TITLE>Introduction -- AFS user's Guide</TITLE>
+
+ Examples of inappropriate titles are those which are only
+ meaningful within context,
+
+ <TITLE>Introduction</TITLE>
+
+
+
+
+Berners-Lee and Connolly 24
+
+ or too long,
+
+ <TITLE>Remarks on the Quantum-Gravity effects of "Bean
+ Pole" diversification in Mononucleosis patients in Developing
+ Countries under Economic Conditions Prevalent during
+ the Second half of the Twentieth Century, and Related Papers:
+ a Summary</TITLE>
+
+
+
+
+Character highlighting
+
+ Status: Extra
+
+ These elements allow sections of text to be formatted in a
+ particular way, to provide emphasis, etc. The tags do NOT cause a
+ paragraph break, and may be used on sections of text within
+ paragraphs.
+
+ Where not supported by implementations, like all tags, these tags
+ should be ignored but the content rendered.
+
+ All these tags have related closing tags, as in
+
+ This is <EM>emphasized</EM> text.
+
+ Some of these styles are more explicit than others about how they
+ should be physically represented. The logical styles should be
+ used wherever possible, unless for example it is necessary to refer
+ to the formatting in the text. (Eg, "The italic parts are
+ mandatory".)
+
+ Note:
+
+ Browsers unable to display a specified style may render it in some
+ alternative, or the default, style, with some loss of quality for
+ the reader. Some implementations may ignore these tags altogether,
+ so information providers should attempt not to rely on them as
+ essential to the information content.
+
+ These element names are derived from TeXInfo macro names.
+
+ PHYSICAL STYLES
+
+ TT Fixed-width typewriter font.
+
+ B Boldface, where available, otherwise
+ alternative mapping allowed.
+
+ I Italic font (or slanted if italic
+ unavailable).
+
+
+
+
+Berners-Lee and Connolly 25
+
+ U Underline.
+
+ LOGICAL STYLES
+
+ EM Emphasis, typically italic.
+
+ STRONG Stronger emphasis, typically bold.
+
+ CODE Example of code. typically monospaced font.
+ (Do not confuse with PRE )
+
+ SAMP A sequence of literal characters.
+
+ KBD in an instruction manual, Text typed by a
+ user.
+
+ VAR A variable name.
+
+ DFN The defining instance of a term. Typically
+ bold or bold italic.
+
+ CITE A citation. Typically italic.
+
+ EXAMPLES OF USE
+
+ This text contains an <em>emphasized</em> word.
+ <strong>Don't assume</strong> that it will be italic!
+ It was made using the <CODE>EM</CODE> element. A citation is
+ typically italic and has no formal necessary structure:
+ <cite>Moby Dick</cite> is a book title.
+
+
+
+
+Obsolete elements
+
+ The following elements of HTML are obsolete. It is recommended
+ that client implementors implement the obsolete forms for
+ compatibility with old servers.
+
+ Plaintext
+
+ Status: Obsolete .
+
+ The empty PLAINTEXT tag terminates the HTML entity. What follows is
+ not SGML. In stead, there's an old HTTP convention that what
+ follows is an ASCII (MIME "text/plain") body.
+
+ An example if its use is:
+
+ <PLAINTEXT>
+ 0001 This is line one of a ling listing
+ 0002 file from <any@host.inc.com> which is sen
+
+
+
+Berners-Lee and Connolly 26
+
+t
+
+ This tag allows the rest of a file to be read efficiently without
+ parsing. Its presence is an optimization. There is no closing tag.
+ The rest of the data is not in SGML.
+
+ XMP and LISTING: Example sections
+
+ Status: Obsolete . This are in use and should be recognized by
+ browsers. New servers should use <PRE> instead.
+
+ These styles allow text of fixed-width characters to be embedded
+ absolutely as is into the document. The syntax is:
+
+ <LISTING>
+ ...
+ </LISTING>
+
+ or
+
+ <XMP>
+ ...
+ </XMP>
+
+ The text between these tags is to be portrayed in a fixed width
+ font, so that any formatting done by character spacing on
+ successive lines will be maintained. Between the opening and
+ closing tags:
+
+ The text may contain any ISO Latin printable characters, but not
+ the end tag opener. (See Historical note )
+
+ Line boundaries are significant, except any occurring
+ immediately after the opening tag or before the closing tag. and
+ are to be rendered as a move to the start of a new line.
+
+ The ASCII Horizontal Tab (HT) character must be interpreted as
+ the smallest positive nonzero number of spaces which will leave
+ the number of characters so far on the line as a multiple of 8.
+ Its use is not recommended however.
+
+ The LISTING element is portrayed so that at least 132 characters
+ will fit on a line. The XMP elementis portrayed in a font so that
+ at least 80 characters will fit on a line but is otherwise
+ identical to LISTING.
+
+ Highlighted Phrase HP1 etc
+
+ Status: Obsolete . These tags like all others should be ignored if
+ not implemented. Replaced will more meaningful elements -- see
+ character highlighting .
+
+ Examples of use:
+
+
+
+Berners-Lee and Connolly 27
+
+ <HP1>...</HP1> <HP2>... </HP2> etc.
+
+ Comment element
+
+ Status: Obsolete
+
+ A comment element used for bracketing off unneed text and comment
+ has been introduced in some browsers but will be replaced by the
+ SGML command feature in new implementations.
+
+ HISTORICAL NOTE: XMP AND LISTING
+
+ The XMP and LISTING elements used historically to have non SGML
+ conforming specifications, in that the text could contain any ISO
+ Latin printable characters, including the tag opener, so long as it
+ does not contain the closing tag in full.
+
+ This form is not supported by SGML and so is not the specified HTML
+ interpretation. Providers should be warned that implementations
+ may vary on how they interpret end tags apparently within these
+ elements
+
+ ENTITIES
+
+ The following entity names are used in HTML , always prefixed by
+ ampersand (&) and followed by a semicolon as shown. They represent
+ particular graphic characters which have special meanings in places
+ in the markup, or may not be part of the character set available to
+ the writer.
+
+ &lt; The less than sign <
+
+ &gt; The "greater than" sign >
+
+ &amp; The ampersand sign & itself.
+
+ &quot; The double quote sign "
+
+ Also allowed are references to any of the ISO Latin-1 alphabet,
+ using the entity names in the following table.
+
+ISO Latin 1 character entities
+
+ This list is derived from "ISO 8879:1986//ENTITIES Added Latin
+ 1//EN".
+
+ &AElig; capital AE diphthong (ligature)
+
+ &Aacute; capital A, acute accent
+
+ &Acirc; capital A, circumflex accent
+
+ &Agrave; capital A, grave accent
+
+
+
+Berners-Lee and Connolly 28
+
+ &Aring; capital A, ring
+
+ &Atilde; capital A, tilde
+
+ &Auml; capital A, dieresis or umlaut mark
+
+ &Ccedil; capital C, cedilla
+
+ &ETH; capital Eth, Icelandic
+
+ &Eacute; capital E, acute accent
+
+ &Ecirc; capital E, circumflex accent
+
+ &Egrave; capital E, grave accent
+
+ &Euml; capital E, dieresis or umlaut mark
+
+ &Iacute; capital I, acute accent
+
+ &Icirc; capital I, circumflex accent
+
+ &Igrave; capital I, grave accent
+
+ &Iuml; capital I, dieresis or umlaut mark
+
+ &Ntilde; capital N, tilde
+
+ &Oacute; capital O, acute accent
+
+ &Ocirc; capital O, circumflex accent
+
+ &Ograve; capital O, grave accent
+
+ &Oslash; capital O, slash
+
+ &Otilde; capital O, tilde
+
+ &Ouml; capital O, dieresis or umlaut mark
+
+ &THORN; capital THORN, Icelandic
+
+ &Uacute; capital U, acute accent
+
+ &Ucirc; capital U, circumflex accent
+
+ &Ugrave; capital U, grave accent
+
+ &Uuml; capital U, dieresis or umlaut mark
+
+ &Yacute; capital Y, acute accent
+
+ &aacute; small a, acute accent
+
+
+
+Berners-Lee and Connolly 29
+
+ &acirc; small a, circumflex accent
+
+ &aelig; small ae diphthong (ligature)
+
+ &agrave; small a, grave accent
+
+ &aring; small a, ring
+
+ &atilde; small a, tilde
+
+ &auml; small a, dieresis or umlaut mark
+
+ &ccedil; small c, cedilla
+
+ &eacute; small e, acute accent
+
+ &ecirc; small e, circumflex accent
+
+ &egrave; small e, grave accent
+
+ &eth; small eth, Icelandic
+
+ &euml; small e, dieresis or umlaut mark
+
+ &iacute; small i, acute accent
+
+ &icirc; small i, circumflex accent
+
+ &igrave; small i, grave accent
+
+ &iuml; small i, dieresis or umlaut mark
+
+ &ntilde; small n, tilde
+
+ &oacute; small o, acute accent
+
+ &ocirc; small o, circumflex accent
+
+ &ograve; small o, grave accent
+
+ &oslash; small o, slash
+
+ &otilde; small o, tilde
+
+ &ouml; small o, dieresis or umlaut mark
+
+ &szlig; small sharp s, German (sz ligature)
+
+ &thorn; small thorn, Icelandic
+
+ &uacute; small u, acute accent
+
+ &ucirc; small u, circumflex accent
+
+
+
+Berners-Lee and Connolly 30
+
+ &ugrave; small u, grave accent
+
+ &uuml; small u, dieresis or umlaut mark
+
+ &yacute; small y, acute accent
+
+ &yuml; small y, dieresis or umlaut mark
+
+ THE HTML DTD
+
+ The HTML DTD follows . Its relationship to the content of an SGML
+ document is explained in the section "HTML and SGML" .
+
+
+<!SGML "ISO 8879:1986"
+--
+ Document Type Definition for the HyperText Markup Language
+ as used by the World Wide Web application (HTML DTD).
+
+ NOTE: This is a definition of HTML with respect to
+ SGML, and assumes an understanding of SGML terms.
+--
+
+CHARSET
+ BASESET "ISO 646:1983//CHARSET
+ International Reference Version (IRV)//ESC 2/5 4/0"
+ DESCSET 0 9 UNUSED
+ 9 2 9
+ 11 2 UNUSED
+ 13 1 13
+ 14 18 UNUSED
+ 32 95 32
+ 127 1 UNUSED
+ BASESET "ISO Registration Number 100//CHARSET
+ ECMA-94 Right Part of Latin Alphabet Nr. 1//ESC 2/13 4
+/1"
+ DESCSET 128 32 UNUSED
+ 160 95 32
+ 255 1 UNUSED
+
+
+CAPACITY SGMLREF
+ TOTALCAP 150000
+ GRPCAP 150000
+
+SCOPE DOCUMENT
+SYNTAX
+ SHUNCHAR CONTROLS 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
+ 18
+ 19 20 21 22 23 24 25 26 27 28 29 30 31 127
+255
+ BASESET "ISO 646:1983//CHARSET
+ International Reference Version (IRV)//ESC 2/5 4/0"
+
+
+
+Berners-Lee and Connolly 31
+
+ DESCSET 0 128 0
+ FUNCTION RE 13
+ RS 10
+ SPACE 32
+ TAB SEPCHAR 9
+ NAMING LCNMSTRT ""
+ UCNMSTRT ""
+ LCNMCHAR ".-"
+ UCNMCHAR ".-"
+ NAMECASE GENERAL YES
+ ENTITY NO
+ DELIM GENERAL SGMLREF
+ SHORTREF SGMLREF
+ NAMES SGMLREF
+ QUANTITY SGMLREF
+ NAMELEN 34
+ TAGLVL 100
+ LITLEN 1024
+ GRPGTCNT 150
+ GRPCNT 64
+
+FEATURES
+ MINIMIZE
+ DATATAG NO
+ OMITTAG NO
+ RANK NO
+ SHORTTAG NO
+ LINK
+ SIMPLE NO
+ IMPLICIT NO
+ EXPLICIT NO
+ OTHER
+ CONCUR NO
+ SUBDOC NO
+ FORMAL YES
+ APPINFO NONE
+>
+
+<!DOCTYPE HTML [
+<!-- Jul 1 93 -->
+<!-- Regarding clause 6.1, SGML Document:
+
+ [1] SGML document = SGML document entity,
+ (SGML subdocument entity |
+ SGML text entity | non-SGML data entity)*
+
+ The role of SGML document entity is filled by this DTD,
+ followed by the conventional HTML data stream.
+-->
+
+<!-- DTD definitions -->
+
+<!ENTITY % heading "H1|H2|H3|H4|H5|H6" >
+
+
+
+Berners-Lee and Connolly 32
+
+<!ENTITY % list "UL|OL|DIR|MENU">
+<!ENTITY % literal "XMP|LISTING">
+
+<!ENTITY % headelement
+ "TITLE|NEXTID|ISINDEX" >
+
+<!ENTITY % bodyelement
+ "P | %heading |
+ %list | DL | HEADERS | ADDRESS | PRE | BLOCKQUOTE
+ | %literal">
+
+<!ENTITY % oldstyle "%headelement | %bodyelement | #PCDATA">
+
+<!ENTITY % URL "CDATA"
+ -- The term URL means a CDATA attribute
+ whose value is a Uniform Resource Locator,
+ as defined. (A URN may also be usable here when defined.)
+ -->
+
+<!ENTITY % linkattributes
+ "NAME NMTOKEN #IMPLIED
+ HREF %URL; #IMPLIED
+ REL CDATA #IMPLIED -- forward relationship type --
+ REV CDATA #IMPLIED -- reversed relationship type
+ to referent data:
+
+ PARENT CHILD, SIBLING, NEXT, TOP,
+ DEFINITION, UPDATE, ORIGINAL etc. --
+
+ URN CDATA #IMPLIED -- universal resource number --
+
+ TITLE CDATA #IMPLIED -- advisory only --
+
+ METHODS NAMES #IMPLIED -- supported public methods of the obje
+ct:
+ TEXTSEARCH, GET, HEAD, ... --
+
+ ">
+
+
+<!-- Document Element -->
+
+<!ELEMENT HTML O O (( HEAD | BODY | %oldstyle)*, PLAINTEXT?)>
+
+<!ELEMENT HEAD - - (TITLE? & ISINDEX? & NEXTID? & LINK*
+ & BASE?)>
+
+<!ELEMENT TITLE - - RCDATA
+ -- The TITLE element is not considered part of the flow of t
+ext.
+ It should be displayed, for example as the page header or
+ window title.
+ -->
+
+
+
+Berners-Lee and Connolly 33
+
+<!ELEMENT ISINDEX - O EMPTY
+ -- WWW clients should offer the option to perform a search o
+n
+ documents containing ISINDEX.
+ -->
+
+<!ELEMENT NEXTID - O EMPTY>
+<!ATTLIST NEXTID N NAME #REQUIRED
+ -- The number should be a name suitable for use
+ for the ID of a new element. When used, the value
+ has its numeric part incremented. EG Z67 becomes Z68
+ -->
+<!ELEMENT LINK - O EMPTY>
+<!ATTLIST LINK
+ %linkattributes>
+
+<!ELEMENT BASE - O EMPTY -- Reference context for URLS -->
+<!ATTLIST BASE
+
+ HREF %URL; #IMPLIED
+
+ >
+<!ENTITY % inline "EM | TT | STRONG | B | I | U |
+ CODE | SAMP | KBD | KEY | VAR | DFN | CITE "
+ >
+
+<!ELEMENT (%inline;) - - (#PCDATA)>
+
+<!ENTITY % text "#PCDATA | IMG | %inline;">
+
+<!ENTITY % htext "A | %text">
+
+<!ELEMENT BODY - - (%bodyelement|%htext;)*>
+
+
+<!ELEMENT A - - (%text)>
+<!ATTLIST A
+ %linkattributes;
+ >
+
+<!ELEMENT IMG - O EMPTY -- Embedded image -->
+<!ATTLIST IMG
+ SRC %URL; #IMPLIED -- URL of document to embed --
+ >
+
+
+<!ELEMENT P - O EMPTY -- separates paragraphs -->
+
+<!ELEMENT ( %heading ) - - (%htext;)+>
+
+<!ELEMENT DL - - (DT | DD | P | %htext;)*>
+<!-- Content should match ((DT,(%htext;)+)+,(DD,(%htext;)+))
+ But mixed content is messy.
+
+
+
+Berners-Lee and Connolly 34
+
+ -->
+
+<!ELEMENT DT - O EMPTY>
+<!ELEMENT DD - O EMPTY>
+
+<!ELEMENT (UL|OL) - - (%htext;|LI|P)+>
+<!ELEMENT (DIR|MENU) - - (%htext;|LI)+>
+<!-- Content should match ((LI,(%htext;)+)+)
+ But mixed content is messy.
+ -->
+<!ATTLIST (%list)
+ COMPACT NAME #IMPLIED -- COMPACT, etc.--
+ >
+
+<!ELEMENT LI - O EMPTY>
+
+<!ELEMENT BLOCKQUOTE - - (%htext;|P)+
+ -- for quoting some other source -->
+
+<!ELEMENT ADDRESS - - (%htext;|P)+>
+
+<!ELEMENT PRE - - (#PCDATA|%inline|A|P)+>
+<!ATTLIST PRE
+ WIDTH NUMBER #implied
+ >
+
+<!-- Mnemonic character entities. -->
+<!ENTITY AElig "&#198;" -- capital AE diphthong (ligature) -->
+<!ENTITY Aacute "&#193;" -- capital A, acute accent -->
+<!ENTITY Acirc "&#194;" -- capital A, circumflex accent -->
+<!ENTITY Agrave "&#192;" -- capital A, grave accent -->
+<!ENTITY Aring "&#197;" -- capital A, ring -->
+<!ENTITY Atilde "&#195;" -- capital A, tilde -->
+<!ENTITY Auml "&#196;" -- capital A, dieresis or umlaut mark -->
+<!ENTITY Ccedil "&#199;" -- capital C, cedilla -->
+<!ENTITY ETH "&#208;" -- capital Eth, Icelandic -->
+<!ENTITY Eacute "&#201;" -- capital E, acute accent -->
+<!ENTITY Ecirc "&#202;" -- capital E, circumflex accent -->
+<!ENTITY Egrave "&#200;" -- capital E, grave accent -->
+<!ENTITY Euml "&#203;" -- capital E, dieresis or umlaut mark -->
+<!ENTITY Iacute "&#205;" -- capital I, acute accent -->
+<!ENTITY Icirc "&#206;" -- capital I, circumflex accent -->
+<!ENTITY Igrave "&#204;" -- capital I, grave accent -->
+<!ENTITY Iuml "&#207;" -- capital I, dieresis or umlaut mark -->
+<!ENTITY Ntilde "&#209;" -- capital N, tilde -->
+<!ENTITY Oacute "&#211;" -- capital O, acute accent -->
+<!ENTITY Ocirc "&#212;" -- capital O, circumflex accent -->
+<!ENTITY Ograve "&#210;" -- capital O, grave accent -->
+<!ENTITY Oslash "&#216;" -- capital O, slash -->
+<!ENTITY Otilde "&#213;" -- capital O, tilde -->
+<!ENTITY Ouml "&#214;" -- capital O, dieresis or umlaut mark -->
+<!ENTITY THORN "&#222;" -- capital THORN, Icelandic -->
+<!ENTITY Uacute "&#218;" -- capital U, acute accent -->
+
+
+
+Berners-Lee and Connolly 35
+
+<!ENTITY Ucirc "&#219;" -- capital U, circumflex accent -->
+<!ENTITY Ugrave "&#217;" -- capital U, grave accent -->
+<!ENTITY Uuml "&#220;" -- capital U, dieresis or umlaut mark -->
+<!ENTITY Yacute "&#221;" -- capital Y, acute accent -->
+<!ENTITY aacute "&#225;" -- small a, acute accent -->
+<!ENTITY acirc "&#226;" -- small a, circumflex accent -->
+<!ENTITY aelig "&#230;" -- small ae diphthong (ligature) -->
+<!ENTITY agrave "&#224;" -- small a, grave accent -->
+<!ENTITY amp "&amp;" -- ampersand -->
+<!ENTITY aring "&#229;" -- small a, ring -->
+<!ENTITY atilde "&#227;" -- small a, tilde -->
+<!ENTITY auml "&#228;" -- small a, dieresis or umlaut mark -->
+<!ENTITY ccedil "&#231;" -- small c, cedilla -->
+<!ENTITY eacute "&#233;" -- small e, acute accent -->
+<!ENTITY ecirc "&#234;" -- small e, circumflex accent -->
+<!ENTITY egrave "&#232;" -- small e, grave accent -->
+<!ENTITY eth "&#240;" -- small eth, Icelandic -->
+<!ENTITY euml "&#235;" -- small e, dieresis or umlaut mark -->
+<!ENTITY gt "&#62;" -- greater than -->
+<!ENTITY iacute "&#237;" -- small i, acute accent -->
+<!ENTITY icirc "&#238;" -- small i, circumflex accent -->
+<!ENTITY igrave "&#236;" -- small i, grave accent -->
+<!ENTITY iuml "&#239;" -- small i, dieresis or umlaut mark -->
+<!ENTITY lt "&lt;" -- less than -->
+<!ENTITY ntilde "&#241;" -- small n, tilde -->
+<!ENTITY oacute "&#243;" -- small o, acute accent -->
+<!ENTITY ocirc "&#244;" -- small o, circumflex accent -->
+<!ENTITY ograve "&#242;" -- small o, grave accent -->
+<!ENTITY oslash "&#248;" -- small o, slash -->
+<!ENTITY otilde "&#245;" -- small o, tilde -->
+<!ENTITY ouml "&#246;" -- small o, dieresis or umlaut mark -->
+<!ENTITY szlig "&#223;" -- small sharp s, German (sz ligature) -->
+<!ENTITY thorn "&#254;" -- small thorn, Icelandic -->
+<!ENTITY uacute "&#250;" -- small u, acute accent -->
+<!ENTITY ucirc "&#251;" -- small u, circumflex accent -->
+<!ENTITY ugrave "&#249;" -- small u, grave accent -->
+<!ENTITY uuml "&#252;" -- small u, dieresis or umlaut mark -->
+<!ENTITY yacute "&#253;" -- small y, acute accent -->
+<!ENTITY yuml "&#255;" -- small y, dieresis or umlaut mark -->
+
+<!-- deprecated elements -->
+
+<!ELEMENT (%literal) - - CDATA>
+
+<!ELEMENT PLAINTEXT - O EMPTY>
+
+<!-- Local Variables: -->
+<!-- mode: sgml -->
+<!-- compile-command: "sgmls -s -p " -->
+<!-- end: -->
+]>
+
+
+
+
+
+Berners-Lee and Connolly 36
+
+ LINK RELATIONSHIP VALUES
+
+ Status: This list is not part of the standard. It is intended to
+ illustrate the use of link relationships and to provide a framework
+ for further development.
+
+ Additions to this list will be controlled by the HTML registration
+ authority . Experimental values may be used on the condition that
+ they begin with "X-".
+
+ These values of the REL attribute of hypertext links have a
+ significance defined here, and may be treated in special ways by
+ HTML applications.
+
+ These relationships relate whole documents (objects), rather than
+ particular anchors within them. If the relationship value is used
+ with a link between anchors rather than whole documents, the
+ semantics are considered to apply to the documents.
+
+ In the explanations which follows, A is the source document of the
+ link and B is the destination document specified by the HREF
+ attribute.
+
+ A relationship marked "Acyclic" has the property that no sequence
+ of links with that relationship may be followed from any document
+ back to itself. These types of links may therefore be used to
+ define trees.
+
+Relationships between documents
+
+ These relationships are between the documents themselves rather
+ than the subjects of the documents.
+
+ USEINDEX
+
+ B is a related index for a search by a user reading this document
+ who asks for an index search function.
+
+ A document may have any number of index links, causing several
+ indexes top be searched in a client-defined manner.
+
+ B must support SEARCH operations under its access protocol.
+
+ USEGLOSSARY
+
+ B is an index which should be used to resolve glossary queries in
+ the document. (Typically, a double-click on a word which is not
+ within an anchor).
+
+ A document may have any number of glossary links.
+
+ ANNOTATION
+
+
+
+
+Berners-Lee and Connolly 37
+
+ The information in B is additional to and subsidiary to that in A.
+
+ Annotation is used by one person to write the equivalent of "margin
+ notes" or other criticism on another's document, for example.
+
+ Example: The relationship between a newsgroup and its articles.
+
+ Acyclic.
+
+ REPLY
+
+ Similar to Annotation, but there is no suggestion that B is
+ subsidiary to A: A and B are on equal footings.
+
+ Example: The relationship between a mail message and its reply, a
+ news article and its reply.
+
+ Acyclic.
+
+ EMBED
+
+ If this link is followed, the node at the end of it is embedded
+ into the display of the source document.
+
+ Acyclic.
+
+ PRECEDES
+
+ In an ordered structure defined by the author, A precedes B, B is
+ followed by A.
+
+ Acyclic.
+
+ Any document may only have one link of this relationship, and/or
+ one link of the reverse relationship.
+
+ Note: May be used to control navigational aids, generate printed
+ material, etc. In conjunction with " subdocument ", may be used to
+ define a tree such as a printed book made of hypertext document.
+ The document can only have one such tree.
+
+ SUBDOCUMENT
+
+ B is a lower part in the author's hierarchy to A. Acyclic. See
+ also Precedes .
+
+ PRESENT
+
+ Whenever A is presented, B must also be presented. This implies
+ that whenever A is retrieved, B must also be retrieved.
+
+ SEARCH
+
+
+
+
+Berners-Lee and Connolly 38
+
+ When the link is followed, the node B should be searched rather
+ than presented. That is, where the client software allows it, the
+ user should immediately be presented with a search panel and
+ prompted for text. The search is then performed without an
+ intermediate retrieval or presentation of the node B
+
+ SUPERSEDES
+
+ B is a previous version of A.
+
+ Acyclic.
+
+ HISTORY
+
+ B is a list of versions of A
+
+ A link reverse link must exist from B to A and to all other known
+ versions of A.
+
+Relationships about subjects of documents
+
+ These relationships convey semantics about objects described by
+ documents, rather than the documents themselves.
+
+ INCLUDES
+
+ A includes B, B is part of A. For example, a person described by
+ document A is a part of the group described by document B.
+
+ Acyclic.
+
+ MADE
+
+ Person (etc) described by node A is author of, or is responsible
+ for B
+
+ This information can be used for protection, and informing authors
+ of interest, for sending mail to authors, etc.
+
+ INTERESTED
+
+ Person (etc) described by A is interested in node B.
+
+ This information can be used for notification of changes.
+
+ Typically, this is a request that, when object B changes in some
+ way, a new link is made to object A.
+
+ The phrase "object B changes" may be interpreted narrowly (as "B
+ itself changes") or widely (as "B or anythink linked to it or
+ related to it closely changes"). The amount of change considered
+ worth notifying people about is also subject to interpretation,
+ varying from bit changes in the source to a "new edition" statement
+
+
+
+Berners-Lee and Connolly 39
+
+ by the publisher.
+
+ REGISTRATION AUTHORITY
+
+ The HTTP Registration Authority is responsible for maintaining
+ lists of:
+
+ Relationship names for link and anchor elements
+
+ It is proposed that the Internet Assigned Numbers Authority or
+ their successors take this role.
+
+ Unregistered values may be used for experimental purposes if they
+ are start with "X-".
+
+ REFERENCES
+
+ SGML ISO 8879:1986, Information Processing Text
+ and Office Systems Standard Generalized
+ Markup Language (SGML).
+
+ sgmls an SGML parser by James Clark
+ <jjc@jclark.com> derived from the ARCSGML
+ parser materials which were written by
+ Charles F. Goldfarb. The source is available
+ on the ifi.uio.no FTP server in the directory
+ /pub/SGML/SGMLS .
+
+ WWW The World-Wide Web , a global information
+ initiative. For bootstrap information, telnet
+ info.cern.ch or find documents by
+ ftp://info.cern.ch/pub/www/doc
+
+ URL Universal Resource Locators. RFCxxx.
+ Currently available by anonymous FTP from
+ info.cern.ch in /pub/ietf.
+
+ AUTHOR'S ADDRESSES
+
+ This document was prepared with the help and advice of many people
+ across the net. Dan Connolly prepared the DTD and the section on
+ HTML and SGML whilst with Convex Computer Corporation of 3000
+ Waterview Parkway Richardson, TX 75083. He is now with Atrium
+ Technology Inc., and is not a current editor of the document.
+
+ Tim Berners-Lee
+ Address CERN
+ 1211 Geneva 23
+ Switzerland
+ Telephone: +41(22)767 3755
+ Fax: +41(22)767 7155
+ email: timbl@info.cern.ch
+
+
+
+
+Berners-Lee and Connolly 40
+
+ Daniel Connolly
+ Address: Atrium Technologies, Inc.
+ 5000 Plaza on the Lake, Suite 275
+ Austin, TX 78746
+ USA
+ email: connolly@atrium.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Berners-Lee and Connolly 41
+
diff --git a/web/funnelAC/fwACsrc/Makefile b/web/funnelAC/fwACsrc/Makefile
new file mode 100644
index 0000000000..adaff3ccbb
--- /dev/null
+++ b/web/funnelAC/fwACsrc/Makefile
@@ -0,0 +1,65 @@
+# ABC Anthony B. Coates, makefile for FunnelWeb
+
+.SUFFIXES: .c .o .a
+
+# Set the C compiler to be CC or GCC as appropriate
+#CC=cc
+#CC=gcc -g -O -c -Wall
+CC=c89 -O2 -w1 -c
+
+# Linker/loader
+#LD=gcc -g -O
+LD=c89 -O2 -w1
+
+# Libraries, etc.
+#LIBS=
+LIBS=-call_shared
+
+# Make
+MAKE=make
+
+# Remove/delete
+RM=\rm
+
+# List directory
+LS=ls
+
+# Directory separator
+DSP=/
+
+# FunnelWeb executable file name
+FWX=fw
+
+# Command script for running tests
+TEST=cd ../scripts ; ../fwACsrc/fw +xmaster
+
+# The full list of FunnelWeb C source files
+SRC=\
+analyse.c as.c clock.c command.c data.c \
+dump.c help.c help_gnu.c list.c lister.c \
+machin.c main.c mapper.c fwmem.c misc.c \
+option.c parser.c scanner.c section.c table.c \
+tangle.c texhead.c weave.c writfile.c htmlhead.c
+
+# The full list of FunnelWeb object files
+OBJ=$(SRC:.c=.o)
+
+# The list of FunnelWeb object files/libraries
+OBJLIST=$(OBJ)
+
+all: $(FWX) test
+
+$(FWX): $(OBJLIST)
+ $(LD) -o $(FWX) $(OBJLIST) $(LIBS)
+ strip $(FWX)
+
+.c.o:
+ $(CC) $<
+
+test:
+ $(TEST)
+
+clean:
+ $(RM) *.o
+
+# end of Makefile
diff --git a/web/funnelAC/fwACsrc/Makefile.os2 b/web/funnelAC/fwACsrc/Makefile.os2
new file mode 100644
index 0000000000..12eacac0ec
--- /dev/null
+++ b/web/funnelAC/fwACsrc/Makefile.os2
@@ -0,0 +1,68 @@
+# ABC Anthony B. Coates, GNU `make' (OS/2) makefile for FunnelWeb
+
+ZTYPE=
+OBJEXT=o
+#ZTYPE=-Zomf
+#OBJEXT=obj
+
+.SUFFIXES: .c .$(OBJEXT) .exe
+
+SHELL=cmd.exe
+
+# Set the C compiler to be CC or GCC as appropriate
+#CC=cc
+CC=gcc -g -O -Wall $(ZTYPE) -c
+
+# Linker/loader
+LD=gcc -g -O $(ZTYPE)
+
+# Libraries, etc.
+LIBS=fw.def -Zmtd
+
+# Make
+MAKE=nmake
+
+# Remove/delete
+RM=del
+
+# List directory
+LS=dir/w
+
+# Directory separator
+DSP=\\
+
+# FunnelWeb executable file name
+FWX=fw.exe
+
+# Command script for running tests
+TEST=fwtest.cmd
+
+# The full list of FunnelWeb C source files
+SRC=\
+analyse.c as.c clock.c command.c data.c \
+dump.c help.c help_gnu.c list.c lister.c \
+machin.c main.c mapper.c fwmem.c misc.c \
+option.c parser.c scanner.c section.c table.c \
+tangle.c texhead.c weave.c writfile.c htmlhead.c
+
+# The full list of FunnelWeb object files
+OBJ=$(SRC:.c=.$(OBJEXT))
+
+# The list of FunnelWeb object files/libraries
+OBJLIST=$(OBJ)
+
+all: $(FWX) test
+
+$(FWX): $(OBJLIST)
+ $(LD) -o $(FWX) $(OBJLIST) $(LIBS)
+
+.c.$(OBJEXT):
+ $(CC) $<
+
+test:
+ $(TEST)
+
+clean:
+ $(RM) *.$(OBJEXT)
+
+# end of Makefile
diff --git a/web/funnelAC/fwACsrc/Makefile.unix b/web/funnelAC/fwACsrc/Makefile.unix
new file mode 100644
index 0000000000..adf04618e1
--- /dev/null
+++ b/web/funnelAC/fwACsrc/Makefile.unix
@@ -0,0 +1,61 @@
+# ABC Anthony B. Coates, makefile for FunnelWeb
+
+.SUFFIXES: .c .o .a
+
+# Set the C compiler to be CC or GCC as appropriate
+#CC=cc
+CC=gcc -g -O -c -Wall
+
+# Linker/loader
+LD=gcc -g -O
+
+# Libraries, etc.
+LIBS=
+
+# Make
+MAKE=make
+
+# Remove/delete
+RM=\rm
+
+# List directory
+LS=ls
+
+# Directory separator
+DSP=/
+
+# FunnelWeb executable file name
+FWX=fw
+
+# Command script for running tests
+TEST=cd ../scripts ; ../fwACsrc/fw +xmaster
+
+# The full list of FunnelWeb C source files
+SRC=\
+analyse.c as.c clock.c command.c data.c \
+dump.c help.c help_gnu.c list.c lister.c \
+machin.c main.c mapper.c fwmem.c misc.c \
+option.c parser.c scanner.c section.c table.c \
+tangle.c texhead.c weave.c writfile.c htmlhead.c
+
+# The full list of FunnelWeb object files
+OBJ=$(SRC:.c=.o)
+
+# The list of FunnelWeb object files/libraries
+OBJLIST=$(OBJ)
+
+all: $(FWX) test
+
+$(FWX): $(OBJLIST)
+ $(LD) -o $(FWX) $(OBJLIST) $(LIBS)
+
+.c.o:
+ $(CC) $<
+
+test:
+ $(TEST)
+
+clean:
+ $(RM) *.o
+
+# end of Makefile
diff --git a/web/funnelAC/fwACsrc/README.ABC b/web/funnelAC/fwACsrc/README.ABC
new file mode 100644
index 0000000000..a529539304
--- /dev/null
+++ b/web/funnelAC/fwACsrc/README.ABC
@@ -0,0 +1,347 @@
+In case you are using emacs, this is a -*- text -*- file.
+
+ Documentation for FunnelWeb 3.05AC
+ 10th October, 1995.
+ Anthony B. Coates
+ Department of Physics
+ The University of Queensland
+ QLD 4072
+ Australia
+ coates@physics.uq.edu.au
+
+This document lists the features which I [ABC] have added to Ross
+Williams' FunnelWeb v3.0 in developing FunnelWeb 3.05AC. Although
+Ross does not want bogus copies of FunnelWeb to be distributed, for
+the very good reason that existing FunnelWeb code should not break
+because someone unknowingly installs an improperly modified version of
+the program, he has allowed me to distribute FunnelWeb 3.05AC freely.
+However, note that while the features of FunnelWeb 3.05AC may appear
+in the next official release of FunnelWeb, there is no guarantee that
+they will, as this will be up to Ross Williams to decide.
+
+Note too that when my version of FunnelWeb is run, it automatically
+prints out a message pointing out that it is not FunnelWeb v3.0.
+Please do not remove or change this message without my express
+permission [ABC].
+
+****ATTENTION****
+FunnelWeb is currently written using K&R C. This means that it can be
+compiled by both old-style K&R C compilers and new-style ANSI/ISO C
+compilers, but not (as C++) by C++ compilers, as C++ uses the ANSI/ISO
+syntax. In future releases, FunnelWeb AC may change from K&R to
+ANSI/ISO syntax. This is because the number of people who wish to
+compile FunnelWeb using a C++ compiler will probably outnumber those
+who wish to use a K&R C compiler. However, if you have a strong
+opinion as to whether FunnelWeb should be written in K&R or ANSI/ISO
+C, send an email message to coates@physics.uq.edu.au, so that users'
+opinions can be gauged.
+****ATTENTION****
+
+To avoid problems with existing FunnelWeb code breaking when processed
+with FunnelWeb 3.05AC, new features are only enabled by the explicit
+setting of pragmas. As such, this version of FunnelWeb should process
+all existing sources without problems, and all product files,
+including the documentation, should be exactly the same as produced by
+FunnelWeb v3.0. The one exception to this is if the FunnelWeb
+document contains macro names that begin with the hash character '#'.
+This will be discussed later in this document.
+
+Differences from FunnelWeb 3.0AC:
+ 1. Fixed a serious bug in the HTML code generation
+ (the characters '<' and '>' should have been escaped in the
+ generated HTML documentation, but were not).
+ 2. Added the concept of source code types. Currently, this is used
+ only to allow line directives to be generated in some product
+ files but not others.
+ 3. Added the internal macro #timestamp to allow timestamping of
+ product files.
+ 4. Added PC32 machine type for 32-bit DOS code (no 64K boundary
+ restrictions).
+ 5. Added +Qb command line switch for true batch mode
+ (no interaction with the user is attempted if FunnelWeb
+ has to abort).
+ 6. Mapping of files into memory changed to try and avoid problems
+ of differing EOL conventions when taking FunnelWeb sources from
+ one type of system to another (e.g. DOS to Unix).
+
+Modifications:
+ 1. Addition of OSF64, OS2, and LINUX machine types to environ.h,
+ machin.h, and machin.c. The OSF64 machine type is for a 64-bit
+ processor running the OSF/1.3 version of UNIX, such as a DEC
+ AXP (Alpha). The OS2 machine type is for a PC386/486 running OS/2
+ 2.1. The code now checks for `PATH_MAX' before `FILENAME_MAX'
+ as the constant giving the maximum fully qualified filename
+ length for an operating system. This is to accomodate
+ Unix System V. The PC32 machine type has also been added for
+ 32-bit DOS code.
+
+ 2. Additions to `typesetter' pragma:
+ FunnelWeb v.3.0 supports the `@p typesetter = tex' pragma, which
+ allows (La)TeX expressions to be imbedded in the documentation
+ text without being escaped. Without this pragma, FunnelWeb
+ treats all documentation text as literal ASCII.
+ My version [ABC] of FunnelWeb also supports the additional
+ typesetter choices `@p typesetter = hypertext' and
+ `@p typesetter = html'. The `hypertext' option causes FunnelWeb
+ to output an HTML hypertext file rather than a TeX file. This
+ HTML file can be viewed using `Mosaic', and indeed `Mosaic' is
+ the only HTML viewer with which the HTML code produced by this
+ FunnelWeb 3.05AC has been tested. In `hypertext' mode, the
+ standard FunnelWeb typesetting commands are converted to
+ hypertext equivalents, so an existing FunnelWeb file which does
+ NOT contain a `@p typesetter = tex' pragma should be able to be
+ used for hypertext by simply adding `@p typesetter = hypertext'
+ as the first line. The resulting hypertext output is not be
+ formatted exactly the same as the TeX version (in particular,
+ vertical skips are currently ignored for hypertext), but the
+ formatting should nonetheless be reasonable for a hypertext
+ document, and includes appropriate hypertext links for macro
+ invocations and the table of contents. The
+ `@p typesetter = html' option allows HTML expressions to be
+ included in the documentation without being escaped, and so is
+ the HTML equivalent of the `@p typesetter = tex' option.
+
+ 3. no_doc_header pragma:
+ `@p no_doc_header' is used to suppress the TeX (or HTML)
+ header definitions that FunnelWeb normally includes in the output
+ file. It is mainly intended for users who use
+ `@p typesetter = tex' so that they can write their documentation
+ using LaTeX. The file `fw-latex.sty' contains all of the
+ standard FunnelWeb header definitions, and can be included as an
+ optional style file for the LaTeX `\documentstyle' command. Note
+ that it is not necessary to do this for LaTeX files, as the
+ FunnelWeb TeX definitions work perfectly well under LaTeX;
+ however, by separating the definitions into a single style file,
+ the same definitions are not repeated in every documentation
+ file, which can offer a useful saving in disk space. Leaving the
+ TeX header intact *and* using the FunnelWeb style file as well
+ will lead to a LaTeX error, so you must choose one or the other
+ if you are writing your documentation this way. Using
+ `@p no_doc_header' also suppresses the automatic inclusion of a
+ TeX `\bye' command at the end of the documentation file. For
+ LaTeX, the `\end{document}' command makes `\bye' unnecessary.
+
+ 4. raw_macro_and_section_names pragma:
+ Normally, FunnelWeb escapes all TeX (or HTML) expressions that
+ occur in section names (if you use the FunnelWeb sectioning
+ commands) or in macro names. The
+ `@p raw_macro_and_section_names' pragma inhibits this escaping of
+ expressions in section and macro names, unless the macro is
+ attached to a file (TeX or HTML in file names almost certainly
+ have no practical value, and would more likely be unintentional,
+ particularly with file systems that use `\' as the directory
+ separator).
+
+ 4. ignore_text_after_special_minus pragma:
+ Normally, it is an error to have any text on a line after a
+ FunnelWeb `@-' command, which suppresses the return at the end of
+ a line. However, in some cases it may be useful to allow the
+ text appearing after a `@-' command on a line to be treated as a
+ comment which does not appear in the final documentation (in
+ particular, this style of comment allows the automatic setting of
+ emacs buffer modes for editing code scraps when using certain
+ emacs WEB modes). The `@p ignore_text_after_special_minus'
+ allows the use of such trailing comments after `@-' (assuming
+ that `@' is the special character as per usual; the use of `@' as
+ the special is not at all necessary for this pragma to work).
+
+ 5. no_paragraph_markups pragma:
+ For the hypertext settings `@p typesetter = hypertext' and
+ `@p typesetter = html', HTML paragraph markups (`<P>') are
+ inserted in the documentation text wherever one or more blank
+ lines occur in a row. However, particularly for users writing
+ HTML documentation directly and using `@p typesetter = html', it
+ may be undesirable to have these `<P>' markups automatically
+ inserted, since they may already exist as desired in the
+ documentation text. The `@p no_paragraph_markups' pragma
+ suppresses the automatic insertion of `<P>' markups in HTML
+ documentation (but has no effect on TeX documentation).
+
+ 6. automatic_line_directive_macro pragma:
+ This pragma allows the *automatic* insertion of line directives
+ into the product files, similarly to the manner supported by
+ `noweb'. For example, `@p automatic_line_directive_macro = line'
+ would make FunnelWeb call the macro `@<line@>' whenever a line
+ directive was needed (an appropriate definition of @<line@> for
+ C/C++ is given in `autoccln.fwi'. The fact that this macro is
+ user defined means that the user can support any type of line
+ directive convention, or just add comments to show where a
+ section of a product file came from in the original FunnelWeb
+ source. New line directive types can be defined using
+ `@<#line@>' and `@<#file@>', which are described in the next
+ section.
+ There are some caveats that go with using automatic line
+ directive insertion. The same macro is used for all the line
+ directives, which means that a single FunnelWeb source cannot
+ support multiple language/file types unless the line directive
+ style happens to be the same for all of them. Also, when adding
+ line directives, there is the need to insert carriage returns
+ into the product files before and after macro invocations. So
+ your code may break unless macros are only used where adding
+ newlines before or after the macro invocations does not affect
+ the meaning of the product code. For many languages, such as
+ C/C++ or Pascal, this is generally the case; it isn't for
+ Fortran, though. Using a macro in the middle of a string
+ definition would probably also do the wrong thing, breaking
+ the string up across multiple lines.
+
+ 7. allow_source_code_typing and declare_source_code_type pragmas:
+ As originally implemented, the `automatic_line_directive_macro'
+ pragma added the same line directives to every product file
+ (except the documentation file). This is O.K. when all of the
+ files are, say, C files, but if you also generate the makefile
+ from the FunnelWeb file, you would then have to remove the #line
+ directives from the makefile, or use two separate FunnelWeb
+ files. The `allow_source_code_typing' macro tells FunnelWeb that
+ you wish apply the insertion of line directives selectively to
+ the product files. This pragma is required so that the new
+ features remain inactive unless explicitly asked for, to protect
+ existing FunnelWeb code.
+ Continuing the example of a FunnelWeb file from which is produced
+ a C file and a makefile, the product makefile should not have any
+ line directives. Since the FunnelWeb default is no line
+ directives, the makefile can be produced with the default source
+ code type. Then `@p declare_source_code_type "C"' can be used to
+ declare a source code type for the C file. You can declare as
+ many source code types as are required. Do not create a special
+ source code type for files without line directives, though, since
+ the default already provides this.
+ With source code types, the `automatic_line_directive_macro'
+ pragma can have two forms. The first form is
+ `@p automatic_line_directive_macro = <macro>', which sets the
+ automatic line directive macro for the default source type. If
+ you are using source code typing, you probably will have some
+ files to generate without line directives, and so you will not
+ want to set a line directive type for the default source code
+ type. Having defined a "C" source code type, you set the
+ automatic line directive macro for C files by
+ `@p automatic_line_directive_macro = <macro> "C"', i.e. you add
+ the source code type name to the end of the line.
+ There is only one more thing to do. Source code types apply only
+ to macros which are attached to files. So when you generate your
+ C file `main.c', you change its definition from
+ `@O@<main.c>==@{...@}' to `@O@<main.c@,C@>==@{...@}'. Note the
+ special use of `@,' here, and also that in the file macro
+ definition the source code type name is not surrounded by double
+ quotes as it is in the pragmas.
+ If you have followed all of this, you should be able to
+ understand the following sample FunnelWeb file which uses these
+ pragmas.
+
+ -----------sample FunnelWeb file----------------
+ @p allow_source_code_typing
+ @p declare_source_code_type "C"
+ @p automatic_line_directive_macro = "line" "C"
+ @i autoccln.fwi
+
+ @O@<main.c@,C@>==@{int main(void) { return 0; }@}
+
+ @$@<TAB@>==@{@^D(009)@} @! ASCII TAB character is decimal 9.
+ @O@<Makefile@>==@{@-
+ main.exe: main.c
+ @<TAB@>$(CC) -o $@@ main.c
+ @}
+ -----------end of sample FunnelWeb file----------
+
+ 8. A command switch `+Qb' has been added. The `b' stands for
+ `batch', and this switch stops FunnelWeb from asking the user
+ for confirmation if it has to abort. This means that FunnelWeb
+ will run as a completely batch-mode program, which apparently is
+ important for users who want to integrate it into the Borland
+ C/C++ IDE (development environment).
+
+ 9. The way FunnelWeb AC maps files into memory has been modified in
+ order to avoid problems with Unix systems choking on the CR/LF
+ pair used to terminate lines in DOS files. While the new system
+ has been checked under OS/2, OSF/1(Unix), and DOS, I would
+ appreciate knowing if this system works for Macintoshes as I
+ believe it should.
+ In principle this change could make FunnelWeb 3.05AC act
+ differently to FunnelWeb 3.0 for some files, but only files
+ so perverse as to be unreasonable in any case. If this is not
+ the case, report it to the author immediately.
+
+Special Internal Macros:
+ Some special `internal' macros have been added to FunnelWeb 3.05AC
+ to support imbedding of references to the original FunnelWeb
+ source(s) in the product files. In particular, the FunnelWeb
+ include file `ccline.fwi' defines a macro called @<line@> which can
+ be used to insert a C/C++ #line directive into a product file (for
+ manual line directive insertion, i.e. where the user types
+ `@<line@>' wherever needed. The version of `@<line@>' to be used
+ for automatic line directive insertion is to be found in
+ `autoccln.fwi'). These internal macros, of which only three
+ currently exist (@<#line@>, @<#file@>, and @<#timestamp@>), have
+ names which start with the hash character '#'.
+ This is the one place where existing FunnelWeb code might be
+ expected to break when processed by this experimental version of
+ FunnelWeb, if the name of an internal macro also used for a
+ user-defined macro. As such, it is strongly recommended that the
+ user avoid macro names which start with the '#' character.
+ The @<#line@> macro causes a FunnelWeb source line number to
+ be inserted into the product file, while the @<#file@> macro inserts
+ a FunnelWeb source file name. See `ccline.fwi' for an example.
+ There are two pragmas related to this pair of internal macros.
+ `@p #line_offset = <num>' is used to set a value which is added to
+ the actual FunnelWeb source file line on which @<#line@> is invoked
+ before the line number is printed in the product file. This is
+ necessary for C/C++ #line directives because the directive much
+ specify the source line number of the line *after* the directive,
+ not the source line number of the directive itself. Thus, the
+ offset value needs to be 1 for C/C++ (and is defined to be in
+ `ccline.fwi').
+ `@p #line_depth = <num>' controls *which* line number and file name
+ are actually printed by @<#line@> and @<#file@>. Taking
+ `ccline.fwi' as an example, this file defines a @<line@> macro in
+ which @<#line@> and @<#file@> are then called. My first naive
+ version of @<line@> [ABC] ended up printing the line number and file
+ name for `ccline.fwi' (which is then the same for every case)!!!
+ What I [ABC] wanted was the line number and file name for where
+ @<line@> was invoked, not where @<#line@> and @<#file@> were
+ actually invoked inside @<line@>. This means that it is necessary
+ to climb up the current stack of macro invocations until you arrive
+ at the one you want. `@p #line_depth = <num>' allows the user to
+ define how far up the macro invocation stack you must go in order to
+ get the desired line number and file name. The appropriate value
+ for C/C++ #line directives is set in `ccline.fwi'.
+ The @<#timestamp@> macro is converted in the product files
+ (but not in the documentation file)to a date/time string in the form
+ `yyyy/mm/dd/hh/mm/ss'. Although most file systems will date the
+ product files anyway, timestamping may be useful for having the
+ program itself print a message saying when FunnelWeb was last used
+ to generate the product files. The actually date and time used for
+ the timestamp are only checked once, the first time that
+ @<#timestamp@> is processed by FunnelWeb. Thus, all product files
+ produced by the same run of FunnelWeb will contain the same
+ timestamp. This seems more reasonable than having slightly
+ different times in each of the product files. If you have more
+ complicated timestamp or version control requirements, try using GNU
+ RCS (revision control system), which has been found to work well
+ with FunnelWeb. *WARNING*: if you use @<#timestamp@> in a product
+ file, the FunnelWeb `+D' command line flag will not affect that
+ file, since the timestamp in the file will be different every time
+ FunnelWeb is run. Hence, if you use makefiles, and do not want to
+ recompile/regenerate everything every time, be careful about using
+ @<#timestamp@>.
+
+Other changes:
+ Ross Williams once posted a message to the FunnelWeb mailing list
+ stating that FunnelWeb allocated a maximally-sized string to every
+ macro name, and that this was a waste of space. In my version,
+ this has been modified so that only the amount of string space
+ necessary is allocated. How much is saved will depend greatly on
+ the nature of the FunnelWeb source. I [ABC] did manage in one case
+ to save 100k on the memory that needed to be allocated, but this was
+ on a project where FunnelWeb allocated itself just over 11M while
+ running; thus the saving is not necessarily significant.
+
+Compiling the code:
+ I have included some example makefiles, but the standard FunnelWeb
+ creed of `just compile it all together at once' should work fine. I
+ [ABC] tend not to do this because my compiler is not lightning fast.
+ Because of the modifications, when you run the FunnelWeb tests, you
+ will not get the same errors as with FunnelWeb v.3.0. The number of
+ errors and differences that you should get is to be found in the
+ file `err.status'.
+
+This is the end of this documentation file.
diff --git a/web/funnelAC/fwACsrc/analyse.c b/web/funnelAC/fwACsrc/analyse.c
new file mode 100644
index 0000000000..3a2490c845
--- /dev/null
+++ b/web/funnelAC/fwACsrc/analyse.c
@@ -0,0 +1,326 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 03-Sep-1994 ABC Added support for the automatic insertion of
+ line directives when `aldmname' is a non-null
+ string referring to a macro without parameters.
+ It is necessary to ignore @M or @Z for the
+ given line directive insertion macro.
+ 25-Jul-1995 ABC Replaced `aldmname' with a list of structures
+ containing a source code type name (or NULL)
+ and a corresponding automatic line directive
+ insertion macro name.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* ANALYSE.C */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "analyse.h"
+#include "as.h"
+#include "data.h"
+#include "lister.h"
+#include "misc.h"
+#include "table.h"
+
+/******************************************************************************/
+
+LOCAL void chk_mac P_((p_ma_t));
+LOCAL void chk_mac (p_ma)
+p_ma_t p_ma;
+{
+ mc_t *call;
+ /* ABC { */
+ p_srcnmac_t p_srctype;
+ bool isaldmQ;
+ /* } ABC */
+
+ /* Deal with undefined macros by flagging the first invocation. */
+ if (!p_ma->ma_defn.md_isdef)
+ {
+ ls_loo(p_ma->ma_calls,(ulong) 1,PPV &call);
+ as_cold(call!=NULL,"check_macro: No instances of \"undefined\" macro!");
+ lr_err(&call->mc_ps,"Call to undefined macro.");
+ return;
+ }
+
+ /* Assert: The macro has a definition. */
+
+ /* Check that all the calls to the macro have the correct number of params. */
+ ls_fir(p_ma->ma_calls);
+ ls_nxt(p_ma->ma_calls,PPV &call);
+ while (call!=NULL)
+ {
+ if (call->mc_npar != p_ma->ma_defn.md_npar)
+ {
+ sprintf(linet1,"Call has %lu parameter%s, but the macro",
+ (ulong) call->mc_npar,
+ call->mc_npar==1 ? "" : "s");
+ lr_err(&(call->mc_ps),linet1);
+ sprintf(linet1,"definition at line %lu specifies %lu parameter%s.",
+ (ulong) p_ma->ma_defn.md_ps.ps_line,
+ (ulong) p_ma->ma_defn.md_npar,
+ p_ma->ma_defn.md_npar==1 ? "" : "s");
+ lr_mes(&(call->mc_ps),linet1);
+ if (p_ma->ma_defn.md_npar==0 && call->mc_npar==1)
+ {
+ lr_mes(&(call->mc_ps),"Note: If your call looks like this: @<Macro@>@(@) then you");
+ lr_mes(&(call->mc_ps),"should be aware that FunnelWeb treats this as a call with");
+ lr_mes(&(call->mc_ps),"a single parameter consisting of the empty string. This");
+ lr_mes(&(call->mc_ps),"is a consequence of parameter delimiters @\"@\" being optional.");
+ }
+ }
+ ls_nxt(p_ma->ma_calls,PPV &call);
+ }
+
+/* ABC { */
+ /* Check if the macro is an automatic line directive insertion macro */
+ isaldmQ = FALSE;
+ ls_fir(srctlist);
+ for (;;) { /* forever */
+ ls_nxt(srctlist, (pp_lsel_t)&p_srctype);
+ if (p_srctype == NULL) break;
+ if (p_srctype->lnmac == NULL) continue;
+ if (!strcmp(p_srctype->lnmac, p_ma->ma_name)) {
+ isaldmQ = TRUE;
+ break;
+ } /* end if */
+ } /* end forever */
+/* } ABC */
+
+ /* Check that the number of calls of the macro is legal. */
+ if (p_ma->ma_defn.md_isfil)
+ {
+ /* Flag all calls to a file macro as errors. */
+ if (ls_len(p_ma->ma_calls)>0)
+ {
+ lr_mes(&p_ma->ma_defn.md_ps,
+ "This file macro is called one or more times.");
+ lr_mes(&p_ma->ma_defn.md_ps,
+ "Each call has been flagged with an error message.");
+ }
+ ls_fir(p_ma->ma_calls);
+ ls_nxt(p_ma->ma_calls,PPV &call);
+ while (call!=NULL)
+ {
+ lr_err(&(call->mc_ps),"Calls to file macros are not allowed.");
+ lr_mes(&(call->mc_ps),"Reason: It should be possible to comment out a");
+ lr_mes(&(call->mc_ps),"file macro without a big fuss. Calling a file macro");
+ lr_mes(&(call->mc_ps),"just tangles it up in the macro structure,");
+ lr_mes(&(call->mc_ps),"making it more difficult to comment out later.");
+ ls_nxt(p_ma->ma_calls,PPV &call);
+ }
+ }
+ /* ABC { */
+ else if (!isaldmQ)
+ /* } ABC */
+ {
+ /* Non-file macros. */
+ if (ls_len(p_ma->ma_calls)==0 && !p_ma->ma_defn.md_iszer)
+ lr_err(&p_ma->ma_defn.md_ps,
+ "This macro is never used (and has no @Z).");
+
+ if (ls_len(p_ma->ma_calls)>1 && !p_ma->ma_defn.md_isman)
+ lr_err(&p_ma->ma_defn.md_ps,
+ "This macro is used more than once (and has no @M).");
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void chk_rec P_((void));
+LOCAL void chk_rec()
+/* This macro analyses the calls between the macros in the macro */
+/* table and flags all recursive macros with an error message. */
+/* */
+/* Def: A macro is a "level 0 macro" if it does not call any macros. */
+/* Def: A macro is a "level n macro" if it calls at least one macro of level */
+/* n-1, but does not call any macros of level n or higher. */
+/* Def: A macro is a "level infinity macro" if it directly or indirectly */
+/* calls itself. */
+/* */
+/* This function totally ignores undefined macros. This means that it can be */
+/* invoked even if problems are detected by the other checks. */
+/* */
+/* Although the actions of this may seem rather time expensive, they may not */
+/* be. The function repeatedly runs through the macro table and each macro's */
+/* bodypart list and expression lists. However, there are not likely to be */
+/* many macros and each definition expression list is likely to be quite */
+/* short, as each macro will be mainly text. */
+/* Even if this stuff does take a while, it is better to detect recursion now */
+/* than at tangle time! */
+{
+ p_ma_t p_ma; /* General purpose pointer to macro. */
+ name_t dummy_name; /* Dummy name variable acts as a placeholder in calls. */
+ uword level; /* Level of macro currently being tagged. */
+ bool gotone; /* TRUE iff current loop iteration tagged >0 macros. */
+
+/* We need a concrete number to stand for level infinity. */
+/* 30000 is a nice, large 15 bit number. */
+#define LEVINF 30000
+
+ /* Make sure that our idea of infinity is big enough. */
+ as_cold(tb_len(macro_table)<LEVINF,"ana_rec: too many macros.");
+
+ /* Tag all the macros as being at level infinity. */
+ /* This could be done in the parser, but it's neater to do it here. */
+ tb_fir(macro_table);
+ while (tb_rea(macro_table,PV dummy_name,PV &p_ma))
+ if (p_ma->ma_defn.md_isdef)
+ p_ma->ma_level=LEVINF;
+
+ gotone=TRUE;
+ /* Work from level 0 upwards identifying macros of successive levels. */
+ for (level=0; level<LEVINF && gotone; level++)
+ {
+ /* Identify all macros of level 'level'. */
+ /* Gotone tells us if we managed to tag a macro during this iteration. */
+ gotone=FALSE;
+
+ /* Run through table tagging all macros at level 'level'. */
+ tb_fir(macro_table);
+ while (tb_rea(macro_table,PV dummy_name,PV &p_ma))
+ {
+ if (p_ma->ma_defn.md_isdef && p_ma->ma_level == LEVINF)
+ {
+ p_bpls_t p_bpls = p_ma->ma_defn.md_body;
+ /* Run through each body part of the macro. */
+ ls_fir(p_bpls);
+ while (TRUE)
+ {
+ p_bp_t p_bp;
+ ls_nxt(p_bpls,PPV &p_bp);
+ if (p_bp==NULL) break;
+ /* Run through the list of expression elements. */
+ ls_fir(p_bp->bp_ex);
+ while (TRUE)
+ {
+ p_el_t p_el;
+ ls_nxt(p_bp->bp_ex,PPV &p_el);
+ if (p_el==NULL) break;
+ /* Don't tag anything that calls anything that isn't tagged. */
+ if ((p_el->el_kind==EL_INVC ) &&
+ (p_el->el_p_mac->ma_defn.md_isdef) &&
+
+ (p_el->el_p_mac->ma_level==LEVINF))
+ goto nextmacro;
+ }
+ }
+ /* If we got this far, then our macro must have called nothing but */
+ /* macros of levels [0,level-1]. Thus, we can tag it level 'level'. */
+ p_ma->ma_level=level;
+ gotone=TRUE;
+ } /* End if */
+ nextmacro:;
+ } /* End while */
+ } /* End for loop. */
+
+ /* At this point, we have tagged all macros with their level number. Note */
+ /* that level infinity macros are discovered simply because they do not get */
+ /* tagged. The following loop flags all such recursive macros with errors. */
+ tb_fir(macro_table);
+ while (tb_rea(macro_table,PV dummy_name,PV &p_ma))
+ if (p_ma->ma_defn.md_isdef && p_ma->ma_level==LEVINF)
+ lr_err(&p_ma->ma_defn.md_ps,"This macro has an infinite expansion.");
+
+ /* Note: The above message is not "This macro is defined recursively", */
+ /* because this function catches not only recursive macros, but also all the */
+ /* non-recursive macros that call the recursive macros!! To detect only */
+ /* the recursive macros, we really ought to use Tarjan's algorithm for the */
+ /* detection of strongly connected components. However, I don't have the */
+ /* reference handy right now and I want to finish this version of FunnelWeb */
+ /* soon, so I'll leave the installation of Tarjan's algorithm as a possible */
+ /* future enhancement. Then the error message can be changed. */
+}
+
+/******************************************************************************/
+
+EXPORT void analyse()
+{
+ name_t dummy_name;
+ p_ma_t p_ma;
+
+ /* Issue an error if there are no macros. */
+ if (tb_len(macro_table)==0)
+ {
+ char *m="E: No macros defined.";
+ wl_l(m);
+ if (option.op_s_b)
+ wl_sj(m);
+ num_err++;
+ }
+
+ /* Issue an error if there are no product (output) files. */
+ if (tb_len(file_table)==0)
+ {
+ char *m="E: No output files specified.";
+ wl_l(m);
+ if (option.op_s_b)
+ wl_sj(m);
+ num_err++;
+ }
+
+ /* Take a look at each macro and issue appropriate diagnostics. */
+ tb_fir(macro_table);
+ while (tb_rea(macro_table,PV dummy_name,PV &p_ma))
+ chk_mac(p_ma);
+
+ /* Check for recursive macros. */
+ chk_rec();
+
+ /* Run through the document list and flag any sections that still have not */
+ /* been given names. */
+ ls_fir(document_list);
+ while (TRUE)
+ {
+ p_dc_t p_dc;
+ ls_nxt(document_list,PPV &p_dc);
+ if (p_dc==NULL) break;
+ if (p_dc->dc_kind==DC_TYPE &&
+ p_dc->dc_ty.ty_kind==TY_NSEC &&
+ !p_dc->dc_ty.ty_isnam)
+ {
+ lr_err(&p_dc->dc_ps,"This section has no name.");
+ lr_mes(&p_dc->dc_ps,"You can give it one explicitly (As in @A@<Sloth@>) or implicitly by");
+ lr_mes(&p_dc->dc_ps,"defining a macro (whose name will be inherited) within the section.");
+ }
+ }
+}
+
+/******************************************************************************/
+/* End of ANALYSE.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/analyse.h b/web/funnelAC/fwACsrc/analyse.h
new file mode 100644
index 0000000000..3c2826b810
--- /dev/null
+++ b/web/funnelAC/fwACsrc/analyse.h
@@ -0,0 +1,61 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* ANALYSE.H */
+/******************************************************************************/
+/* */
+/* This package exports a single function called analyse() that should be */
+/* invoked just after the parser has finished. The scanner and parser */
+/* serve only to construct a structured representation of the input file in */
+/* memory; they do not critique it beyond syntax. In contrast, analyse() */
+/* analyses the representation, checking it for "semantic" errors. Any */
+/* problems that are found are sent to the lister package with appropriate */
+/* positioning information so that the messages appear at exactly the right */
+/* spot in the listing. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+EXPORT void analyse P_((void));
+
+/******************************************************************************/
+/* End of ANALYSE.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/as.c b/web/funnelAC/fwACsrc/as.c
new file mode 100644
index 0000000000..f47d25b35e
--- /dev/null
+++ b/web/funnelAC/fwACsrc/as.c
@@ -0,0 +1,72 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 16-Aug-1995 ABC Added support for batch mode (via `batchQ') in
+ which there is no interaction at all with the
+ user.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* AS.C */
+/******************************************************************************/
+
+#include "style.h"
+/* ABC { */
+#include "data.h"
+/* } ABC */
+
+#include "as.h"
+#include "machin.h"
+
+/******************************************************************************/
+
+EXPORT void as_bomb(message)
+char *message;
+{
+ fprintf(stderr,"%s\n",message);
+ fprintf(stderr,"An assertion has failed! See the line above.\n");
+ /* ABC { */
+ if (batchQ) {
+ fprintf(stderr,"FunnelWeb aborted immediately without finishing.\n");
+ } else {
+ fprintf(stderr,"Press return to abort FunnelWeb>\n"); (void) getchar();
+ } /* end if */
+ /* } ABC */
+ exit(EXIT_FAILURE);
+}
+
+/******************************************************************************/
+/* AS.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/as.h b/web/funnelAC/fwACsrc/as.h
new file mode 100644
index 0000000000..ab89d73e83
--- /dev/null
+++ b/web/funnelAC/fwACsrc/as.h
@@ -0,0 +1,119 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* AS.H */
+/******************************************************************************/
+/* */
+/* ASSERTION PACKAGE */
+/* ================= */
+/* This package contains macros and functions that support assertions. An */
+/* assertion is a boolean condition that is supposed always to be true at a */
+/* particular point during program execution. An assertion statement tests */
+/* such a condition and bombs the program if it is false; better to be */
+/* alerted to such a condition rather than suffer and erroneous execution. */
+/* */
+/* Standard C supports asertions with the <assert.h> header file providing */
+/* the "assert" macro. Unfortunately, this does not meet the needs of */
+/* FunnelWeb for two reasons: */
+/* */
+/* 1) Portability is emphasised in FunnelWeb and the assert macro is fairly */
+/* recent. Its only argument is the boolean condition, which means that */
+/* without the ANSI macros __FILE__ and __LINE__, the macro would be */
+/* unable to indicate where an assertion failure occurred, in a non-ANSI */
+/* environment. */
+/* */
+/* 2) There is only one assert macro and it can be either on or off, the */
+/* implication being that in production code, it should be turned off. In */
+/* contrast, the execution speed of the assert macro will usually matter */
+/* only in a small portion of the code as, in most programs, a small */
+/* portion of the code accounts for most of the execution time. By having */
+/* two categories of assertion, we can leave most of the assertions turned */
+/* on in the production program. */
+/* */
+/* This reasoning leads to the slightly different assertion facilty provided */
+/* by this package. Here, there are two assertion routines/macros, HOT */
+/* assertions for HOT code (code in a program hot spot) and COLD assertions */
+/* for COLD code (not in a hot spot). Only the HOT assertions can be turned */
+/* off. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_AS
+#define DONE_AS
+
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+/* The following #define determines whether hot assertions are to be turned */
+/* on or off. Set to 0 for OFF and 1 for ON. */
+/* Note: I have left hot assertions on in the production version as FunnelWeb */
+/* doesn't go slowly enough to make me want to turn it off. */
+#define AS_DOHOT 1
+
+/******************************************************************************/
+
+EXPORT void as_bomb P_((char *));
+/* This function writes out its argument string and then bombs the program. */
+/* It should be called at any point where it has been determined that an */
+/* illegal condition has been detected. The other assertion routines/macros */
+/* call this function. */
+
+/* The following two macros define hot and cold assertions. Be sure never to */
+/* call them with arguments with side effects! */
+#define as_cold(e,s) {if (!(e)) as_bomb(s);}
+
+#if AS_DOHOT
+#define as_hot(e,s) {if (!(e)) as_bomb(s);}
+#define AS_HCODE(CODE) {CODE}
+#else
+#define as_hot(e,s) ((void) 0)
+#define AS_HCODE(CODE) ((void) 0)
+#endif
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* AS.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/autoccln.fwi b/web/funnelAC/fwACsrc/autoccln.fwi
new file mode 100644
index 0000000000..6532d05289
--- /dev/null
+++ b/web/funnelAC/fwACsrc/autoccln.fwi
@@ -0,0 +1,45 @@
+@! FUNNNELWEB COPYRIGHT
+@! ====================
+@! FunnelWeb is a literate-programming macro preprocessor.
+@!
+@! Copyright (C) 1992 Ross N. Williams.
+@!
+@! Ross N. Williams
+@! ross@spam.adelaide.edu.au
+@! 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+@!
+@! This program is free software; you can redistribute it and/or modify
+@! it under the terms of Version 2 of the GNU General Public License as
+@! published by the Free Software Foundation.
+@!
+@! This program is distributed WITHOUT ANY WARRANTY; without even the implied
+@! warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+@! See Version 2 of the GNU General Public License for more details.
+@!
+@! You should have received a copy of Version 2 of the GNU General Public
+@! License along with this program. If not, you can FTP the license from
+@! prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+@! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+@!
+@! Section 2a of the license requires that all changes to this file be
+@! recorded prominently in this file. Please record all changes here.
+@!
+@! Programmers:
+@! ABC Anthony B. Coates coates@physics.uq.edu.au
+
+@! Defines a macro "@<line@>" for automatically inserting #line
+@! pragmas into C and C++ code when using the
+@! `@p auto_line_directive_macro = line' pragma.
+
+@! The #line_offset pragma needs to be set to 0 for C/C++.
+@p #line_offset = 0
+
+@! The #line_depth pragma needs to be set to 1 to
+@! work in the manner described above.
+@p #line_depth = 1
+
+@! After all that, here is the definition itself.
+
+@$@<line@>==@{#line @<#line@> "@<#file@>"@}
+
+@! End of autoccln.fwi
diff --git a/web/funnelAC/fwACsrc/ccline.fwi b/web/funnelAC/fwACsrc/ccline.fwi
new file mode 100644
index 0000000000..8b17c718ed
--- /dev/null
+++ b/web/funnelAC/fwACsrc/ccline.fwi
@@ -0,0 +1,74 @@
+@! FUNNNELWEB COPYRIGHT
+@! ====================
+@! FunnelWeb is a literate-programming macro preprocessor.
+@!
+@! Copyright (C) 1992 Ross N. Williams.
+@!
+@! Ross N. Williams
+@! ross@spam.adelaide.edu.au
+@! 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+@!
+@! This program is free software; you can redistribute it and/or modify
+@! it under the terms of Version 2 of the GNU General Public License as
+@! published by the Free Software Foundation.
+@!
+@! This program is distributed WITHOUT ANY WARRANTY; without even the implied
+@! warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+@! See Version 2 of the GNU General Public License for more details.
+@!
+@! You should have received a copy of Version 2 of the GNU General Public
+@! License along with this program. If not, you can FTP the license from
+@! prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+@! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+@!
+@! Section 2a of the license requires that all changes to this file be
+@! recorded prominently in this file. Please record all changes here.
+@!
+@! Programmers:
+@! ABC Anthony B. Coates coates@physics.uq.edu.au
+
+@! Defines a macro "@<line@>" for inserting #line pragmas into C and
+@! C++ code.
+
+@! Here is an example of a (trivial) FunnelWeb file for a C program
+@! with the @<line@> macros added.
+
+@!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+@! @i ccline.fwi @! include the @<line@> definition
+@!
+@! @$@<dummy@>==@{@- @! OK, here is a definition with some C code
+@! @<line@> @! At the start of it, add a @<line@> definition
+@! void dummy(void) {};
+@! @}
+
+@! @O@<tester.cc@>==@{@- @! The main code
+@! @<line@> @! Start with @<line@>
+@! @<dummy@> @! Code for dummy routine
+@! @<line@> @! Call @<line@> again to reset file/line
+@! int main(void) {
+@! } // end main
+@! @}
+@!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+@! i.e. the rules are
+@! (i) call @<line@> at the start of any definition containing
+@! code.
+@! (ii) call @<line@> after any macro call which may itself
+@! contain a @<line@> call.
+
+@! **** These pragmas need to be set at the top of the .fw file.
+@! **** Include this file at the top or set the pragmas there
+@! **** manually.
+
+@! The #line_offset pragma needs to be set to 1 for C/C++.
+@p #line_offset = 1
+
+@! The #line_depth pragma needs to be set to 1 to
+@! work in the manner described above.
+@p #line_depth = 1
+
+@! After all that, here is the definition itself.
+
+@$@<line@>@M==@{#line @<#line@> "@<#file@>"@}
+
+@! End of ccline.fwi
diff --git a/web/funnelAC/fwACsrc/clock.c b/web/funnelAC/fwACsrc/clock.c
new file mode 100644
index 0000000000..886b1bff55
--- /dev/null
+++ b/web/funnelAC/fwACsrc/clock.c
@@ -0,0 +1,125 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* CLOCK.C */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "as.h"
+#include "clock.h"
+#include "machin.h"
+
+/******************************************************************************/
+
+#define MAGIC_HEAD (565854L)
+#define MAGIC_TAIL (256194L)
+
+/******************************************************************************/
+
+LOCAL void ck_check P_((p_ck_t));
+LOCAL void ck_check(p_ck)
+p_ck_t p_ck;
+{
+ as_cold(p_ck!=NULL,"ck_check: Clock pointer is NULL.");
+ as_cold(p_ck->ck_mhead==MAGIC_HEAD,
+ "ck_check: Magic number at head of record is incorrect.");
+ as_cold(p_ck->ck_mtail==MAGIC_TAIL,
+ "ck_check: Magic number at tail of record is incorrect.");
+}
+
+/******************************************************************************/
+
+EXPORT void ck_ini(p_ck)
+p_ck_t p_ck;
+{
+ p_ck->ck_mhead = MAGIC_HEAD;
+ p_ck->ck_run = FALSE;
+ p_ck->ck_csum = 0.0;
+ p_ck->ck_rsum = 0.0;
+ /* ck_csta and ck_rsta are undefined in a stopped clock. */
+ p_ck->ck_mtail = MAGIC_TAIL;
+}
+
+/******************************************************************************/
+
+EXPORT void ck_start(p_ck)
+p_ck_t p_ck;
+{
+ ck_check(p_ck);
+ as_cold(!p_ck->ck_run,"ck_start: Clock is already running!");
+ p_ck->ck_run = TRUE;
+ p_ck->ck_csta = tim_cpu();
+ p_ck->ck_rsta = tim_real();
+}
+
+/******************************************************************************/
+
+EXPORT void ck_stop(p_ck)
+p_ck_t p_ck;
+{
+ ck_check(p_ck);
+ as_cold(p_ck->ck_run,"ck_stop: Clock is already stopped!");
+ p_ck->ck_run = FALSE;
+ p_ck->ck_csum += tim_cpu () - p_ck->ck_csta;
+ p_ck->ck_rsum += tim_real() - p_ck->ck_rsta;
+}
+
+/******************************************************************************/
+
+EXPORT float ck_cpu(p_ck)
+p_ck_t p_ck;
+{
+ ck_check(p_ck);
+ as_cold(!p_ck->ck_run,"ck_cpu: Clock is running.");
+ return p_ck->ck_csum;
+}
+
+/******************************************************************************/
+
+EXPORT float ck_real(p_ck)
+p_ck_t p_ck;
+{
+ ck_check(p_ck);
+ as_cold(!p_ck->ck_run,"ck_real: Clock is running.");
+ return p_ck->ck_rsum;
+}
+
+/******************************************************************************/
+/* End of CLOCK.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/clock.h b/web/funnelAC/fwACsrc/clock.h
new file mode 100644
index 0000000000..906879db1b
--- /dev/null
+++ b/web/funnelAC/fwACsrc/clock.h
@@ -0,0 +1,107 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* CLOCK.H */
+/******************************************************************************/
+/* */
+/* This package implements a clock abstraction that is used to generate */
+/* timing statistics which are useful for performance tuning. The package */
+/* allows the measurement of both real and CPU time. This package gets its */
+/* raw information from the tim_cpu() and tim_real() functions of the machine */
+/* dependent module "machin". */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_CLOCK
+#define DONE_CLOCK
+
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+/* The following clock type is supposed to be an ADT so don't frob any of its */
+/* fields manually! */
+typedef struct
+ {
+ ulong ck_mhead; /* Magic number helps detect corruptions. */
+ bool ck_run; /* TRUE iff the clock is running. */
+ float ck_csum; /* Accumulated CPU time. */
+ float ck_rsum; /* Accumulated real time. */
+ float ck_csta; /* ck_run => CPU time when clock was started. */
+ float ck_rsta; /* ck_run => Real time when clock was started. */
+ ulong ck_mtail; /* Magic number helps detect corruptions. */
+ } ck_t;
+
+typedef ck_t *p_ck_t;
+
+/******************************************************************************/
+
+EXPORT void ck_ini P_((p_ck_t));
+/* Initializes the clock. After this call, the argument clock will be in the */
+/* STOPPED state and all its registers will be zero. A clock must be */
+/* initialized before any other operations are performed on it. */
+
+EXPORT void ck_start P_((p_ck_t));
+/* Changes the clock from the STOPPED state to the RUNNING state. Starts */
+/* accumulating real time and CPU time on its registers. */
+/* Raises an error if the clock is not in the STOPPED state. */
+
+EXPORT void ck_stop P_((p_ck_t));
+/* Changes the clock from the RUNNING state to the STOPPED state. Stops */
+/* accumulating real time and CPU time on its registers. */
+/* Raises an error if the clock is not in the RUNNING state. */
+
+EXPORT float ck_cpu P_((p_ck_t));
+/* Returns the number of seconds of CPU time accumulated on the clock. */
+/* Raises an error if the clock is not in the STOPPED state. */
+
+EXPORT float ck_real P_((p_ck_t));
+/* Returns the number of seconds of real time accumulated on the clock. */
+/* Raises an error if the clock is not in the STOPPED state. */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of CLOCK.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/command.c b/web/funnelAC/fwACsrc/command.c
new file mode 100644
index 0000000000..e3cdf22b33
--- /dev/null
+++ b/web/funnelAC/fwACsrc/command.c
@@ -0,0 +1,2147 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 16-Sep-1993 ABC Changed all constants *_MAX to *_FWMAX to avoid
+ conflict with some standard UNIX constants.
+ 18-Sep-1994 ABC Changed startup message to reflect my changes.
+ 01-Jan-1995 ABC Modified initial message to reflect first
+ release of FunnelWeb 3.0AC.
+ 20-Jul-1995 ABC Modified initial message to reflect
+ release of FunnelWeb 3.01AC.
+ 08-Aug-1995 ABC Changed include file name from "memory.h"
+ to "fwmem.h" to avoid a clash with the C++
+ standard header file "memory.h".
+ 08-Aug-1995 ABC Modified initial message to reflect
+ release of FunnelWeb 3.02AC.
+ 10-Aug-1995 ABC Modified initial message to reflect
+ release of FunnelWeb 3.03AC.
+ 16-Aug-1995 ABC Added support for `+Qb' batch mode option and
+ matching boolean `batchQ'.
+ 16-Aug-1995 ABC Modified initial message to reflect
+ release of FunnelWeb 3.04AC.
+ 19-Sep-1995 ABC Modified initial message to reflect
+ release of FunnelWeb 3.05AC.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* COMMAND.C */
+/******************************************************************************/
+
+#include <ctype.h>
+#include "style.h"
+
+#include "analyse.h"
+#include "as.h"
+#include "command.h"
+#include "data.h"
+#include "dump.h"
+#include "lister.h"
+#include "fwmem.h"
+#include "mapper.h"
+#include "misc.h"
+#include "option.h"
+#include "parser.h"
+#include "scanner.h"
+#include "tangle.h"
+#include "weave.h"
+
+/******************************************************************************/
+
+/* Because FunnelWeb has so many options ,it is convenient to allow the user */
+/* to construct a startup file. This is its name. */
+#define INITFILE "fwinit.fws"
+
+/******************************************************************************/
+
+/* Three variables hold options information in FunnelWeb. */
+/* 'p_comopt' holds the options conveyed by the original raw command line. */
+/* 'p_defopt' holds the options that are default in the FunnelWeb shell. */
+/* 'option' is global and holds the options that have been specified for the */
+/* current invocation of FunnelWeb proper. */
+/* 'option' is global so here we see only 'p_comopt' and 'p_defopt'. */
+LOCVAR op_t *p_comopt; /* Initial command line options. */
+LOCVAR op_t *p_defopt; /* Default shell options. */
+
+/* The FunnelWeb shell interpreter has many different commands and it is */
+/* worth them sharing the same basic command line scanner. These two */
+/* variables hold the numer of arguments and a pointer to strings holding */
+/* copies of each argument. */
+/* Note: The first argument is placed in arr_arg[0]. */
+#define ARG_FWMAX 5
+LOCVAR uword arg_num;
+LOCVAR char *arg_arr[ARG_FWMAX+1]; /* Is this +1 necessary? */
+
+/* The FunnelWeb command interpreter allows 10 substitution strings. */
+/* These strings are stored in the following array. */
+#define NUM_SUBS (10+26) /* 0..9 and A..Z */
+LOCVAR char *subval[NUM_SUBS];
+
+LOCVAR ulong old_war;
+LOCVAR ulong old_err;
+LOCVAR ulong old_sev;
+
+/* The FunnelWeb script interpreter can echo (trace) each command before it */
+/* executes it. Whether it does is determined by this variable. */
+LOCVAR bool tracing;
+
+/* If this variable is set to true then the interpreter will not abort if the */
+/* very next command (and that one only) generates an error or severe error. */
+LOCVAR bool noabort;
+
+/* If the following boolean is true, the interpreter skips lines until it */
+/* hits the HERE command. */
+LOCVAR bool skipping;
+
+/* The following variables count how many times DIFF is invoked and how many */
+/* times it succeeded. This allows us to output a summary at the end of the */
+/* processing of the test suite. */
+LOCVAR ulong difftotl = 0;
+LOCVAR ulong diffsucc = 0;
+
+/******************************************************************************/
+
+/* Here are the prototypes for recursive or out-of-order functions. */
+LOCAL void interstr P_((char *));
+LOCAL void do_set P_((char *));
+
+/******************************************************************************/
+
+LOCAL char *sing P_((ulong,char *,char *));
+LOCAL char *sing(num,sinstr,plustr)
+/* Return one or other string depending on whether first argument is singular.*/
+ulong num;
+char *sinstr;
+char *plustr;
+{
+ if (num==1)
+ return sinstr;
+ else
+ return plustr;
+}
+
+/******************************************************************************/
+
+LOCAL uword numpos P_((ulong,ulong,ulong));
+LOCAL uword numpos(a,b,c)
+/* Returns the number of its arguments that are positive. */
+ulong a,b,c;
+{
+ uword result=0;
+ if (a>0) result++;
+ if (b>0) result++;
+ if (c>0) result++;
+ return result;
+}
+
+/******************************************************************************/
+
+LOCAL void errsum P_((ulong,ulong,ulong,ulong));
+LOCAL void errsum(fat,sev,err,war)
+/* Supply as arguments, the number of various kinds of diagnostics. */
+/* Places in linet1 a string describing the diagnostics. */
+ulong fat,sev,err,war;
+{
+ char linet2[100];
+
+ if (fat+sev+err+war==0)
+ {strcpy(linet1,"SUCCESS: No diagnostics."); return;}
+
+ strcpy(linet1,"There ");
+
+ /* "Was" or "were" depending on the plurality of highest level diagnostic. */
+ if (fat>0) strcat(linet1,sing(fat,"was","were"));
+ else if (sev>0) strcat(linet1,sing(sev,"was","were"));
+ else if (err>0) strcat(linet1,sing(err,"was","were"));
+ else if (war>0) strcat(linet1,sing(war,"was","were"));
+ else as_bomb("errsum: Error hierarchy failed!");
+
+ strcat(linet1," ");
+
+ /* Fatal errors. */
+ if (fat>0)
+ {
+ sprintf(linet2,"%1lu Fatal error",fat); strcat(linet1,linet2);
+ strcat(linet1,sing(fat,"","s"));
+ }
+
+ /* Joiner stuff. */
+ if (fat>0 && numpos(sev,err,war)>=2) strcat(linet1,", ");
+ if (fat>0 && sev>0 && err==0 && war==0) strcat(linet1," and ");
+
+ /* Severe errors. */
+ if (sev>0)
+ {
+ sprintf(linet2,"%1lu Severe error",sev); strcat(linet1,linet2);
+ strcat(linet1,sing(sev,"","s"));
+ }
+
+ /* Joiner stuff. */
+ if (fat+sev>0 && err>0 && war >0) strcat(linet1,", ");
+ if (fat+sev>0 && err>0 && war==0) strcat(linet1," and ");
+
+ /* Errors. */
+ if (err>0)
+ {
+ sprintf(linet2,"%1lu Error",err); strcat(linet1,linet2);
+ strcat(linet1,sing(err,"","s"));
+ }
+
+ /* Joiner stuff. */
+ if (fat+sev+err>0 && war>0) strcat(linet1," and ");
+
+ /* Warnings. */
+ if (war > 0)
+ {
+ sprintf(linet2,"%1lu Warning",war); strcat(linet1,linet2);
+ strcat(linet1,sing(war,"","s"));
+ }
+
+ /* The final full stop! */
+ strcat(linet1,".");
+}
+
+/******************************************************************************/
+
+LOCAL void allocarg P_((void));
+LOCAL void allocarg()
+/* Some compilers don't allow much room for statics and so it is necessary to */
+/* declare some variables as pointers and allocate them explicitly. This */
+/* function allocates the command line argument array to point to strings. */
+{
+ uword i;
+ for (i=0;i<=ARG_FWMAX;i++)
+ arg_arr[i]=(char *) mm_perm(sizeof(cl_t));
+
+ /* Also initialize the substitution strings. */
+ for (i=0;i<NUM_SUBS;i++)
+ {
+ subval[i]=(char *) mm_perm(sizeof(cl_t));
+ subval[i][0]=EOS;
+ }
+ p_comopt=(p_op_t) mm_perm(sizeof(op_t));
+ p_defopt=(p_op_t) mm_perm(sizeof(op_t));
+}
+
+/******************************************************************************/
+
+LOCAL void zerdia P_((void));
+LOCAL void zerdia()
+{
+ old_war=num_war;
+ old_err=num_err;
+ old_sev=num_sev;
+ num_sev=num_err=num_war=0;
+}
+
+LOCAL void sumdia P_((void));
+LOCAL void sumdia()
+{
+ sum_sev+=num_sev;
+ sum_err+=num_err;
+ sum_war+=num_war;
+}
+
+LOCAL void restdia P_((void));
+LOCAL void restdia()
+{
+ num_sev+=old_sev;
+ num_err+=old_err;
+ num_war+=old_war;
+}
+
+/******************************************************************************/
+
+LOCAL void explode P_((char *));
+LOCAL void explode(p)
+/* Parses the string p into a set of non-blank sequences. Copies each */
+/* distinct run of non-blanks into successive values of arg_arr. Places the */
+/* number of runs of non-blanks into arg_num. DOESN'T generate an error if */
+/* there are too many arguments. */
+char *p;
+{
+ arg_num=0;
+ while (TRUE)
+ {
+ char *x;
+
+ /* Skip to the next argument. */
+ while (*p==' ') p++;
+
+ /* Exit if we have hit the end of the string. */
+ if (*p==EOS) break;
+
+ /* Exit if we are already full up with arguments. */
+ if (arg_num==ARG_FWMAX) break;
+
+ /* Copy the next argument. */
+ x=arg_arr[arg_num];
+ while (*p!=' ' && *p!=EOS) *x++ = *p++;
+ *x=EOS;
+ arg_num++;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void dollsub P_((char *));
+LOCAL void dollsub(p_comlin)
+/* Assumes that it's string argument is in a command line object. */
+/* Performs dollar substitutions. */
+char *p_comlin;
+{
+ char *p=p_comlin;
+ cl_t cl;
+ char *t;
+
+ t = &cl[0];
+
+ /* Copy the unexpanded command line to the temporary from which we expand it */
+ /* back from whence it came. */
+ strcpy(t,p);
+
+ /* Work through the unexpanded command line expanding. */
+ while (*t != EOS)
+ {
+ /* Complain if there is not room for one more character. */
+ if ((p-p_comlin) == COMLINE_FWMAX) goto toobig;
+
+ /* If no dollar sign, no tricks. Just copy the character over. */
+ if (*t!='$') {*p++ = *t++; continue;}
+
+ /* We have seen a dollar sign. Move onto the next character. */
+ t++;
+
+ /* The only legal escapes are decimal digits, slash, and the dollar sign. */
+ if (!isdigit(*t) && !isupper(*t) && *t!='$' && *t!='/')
+ {
+ wl_sj("S: Illegal dollar subtitution sequence in command line.");
+ wl_sj("Legal sequences are $0..$9, $A..$Z, $/, and $$.");
+ num_sev++;
+ strcpy(p,t);
+ return;
+ }
+
+ /* A dollar escape is easy to process. */
+ if (*t=='$') {*p++ = *t++; continue;}
+
+ /* A slash escape is easy to process. */
+ if (*t=='/') {*p++ = FN_DELIM; t++; continue;}
+
+ /* Substitutions have to be expanded. */
+ if (isdigit(*t) || isupper(*t))
+ {
+ ubyte num;
+ char *q;
+ if (isdigit(*t))
+ num = *t-'0';
+ else
+ num = 10+(*t-'A');
+ as_cold(num<NUM_SUBS,"dollsub: num is too bug!");
+ q=subval[num];
+ if ((p-p_comlin)+strlen(subval[num]) > COMLINE_FWMAX) goto toobig;
+ while (*q!=EOS) *p++ = *q++;
+ t++;
+ }
+ }
+ *p=EOS;
+ return;
+
+ toobig:
+ wl_sj("S: Expanded (i.e. after $1 etc) command line is too long.");
+ num_sev++;
+ strcpy(p,t);
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void fwonerun P_((void));
+LOCAL void fwonerun()
+/* Performs a single run of FunnelWeb proper, using the global variable */
+/* 'options' as the input command line. */
+{
+ fn_t lisnam;
+
+ /* The following clocks record the time taken by various parts of FunnelWeb. */
+ ck_t mappck;
+ ck_t scanck;
+ ck_t parsck;
+ ck_t analck;
+ ck_t dumpck;
+ ck_t lstrck;
+ ck_t tangck;
+ ck_t weavck;
+ ck_t totlck;
+
+ /* Intialize/zero all the clocks. */
+ ck_ini(&mappck);
+ ck_ini(&scanck);
+ ck_ini(&parsck);
+ ck_ini(&analck);
+ ck_ini(&dumpck);
+ ck_ini(&lstrck);
+ ck_ini(&tangck);
+ ck_ini(&weavck);
+ ck_ini(&totlck);
+
+ /* Start the total time clock ticking. A total time clock is used to gather */
+ /* up the gaps between the invocations of the other clocks. */
+ ck_start(&totlck);
+
+ ck_start(&lstrck);
+
+ /* Establish the listing file output stream. */
+ strcpy(lisnam,""); /* Start with an empty string. */
+ fn_ins(lisnam,option.op_f_s); /* Insert input file name. */
+ fn_ins(lisnam,".lis"); /* Insert constant extension. */
+ fn_ins(lisnam,option.op_l_s); /* Insert command line spec. */
+ wf_ini(&f_l,option.op_l_b); /* Initialize the stream. */
+ wf_ope(&f_l,lisnam); /* Create the file. */
+ if (option.op_l_b && wf_err(&f_l))
+ {
+ sprintf(linet1,"S: Error creating listing file \"%s\".",lisnam);
+ wl_sj(linet1);
+ wl_sj("Aborting...");
+ num_sev++;
+ return;
+ }
+
+ wl_l("FUNNELWEB LISTING FILE");
+ wl_l("======================");
+ wl_l("");
+
+ /* Initialize the lister for this run. */
+ lr_ini();
+
+ ck_stop(&lstrck);
+
+ /* Scanner comes first. */
+ ck_start(&scanck);
+ scanner(&mappck,&scanck);
+ ck_stop(&scanck);
+
+ /* Dump the line and token lists if requested. The scanner supplies sensible */
+ /* lists even if it encounters errors, so there is no danger here. */
+ ck_start(&dumpck);
+ if (option.op_b2_b) dm_lnls(&f_l);
+ if (option.op_b3_b) dm_tkls(&f_l);
+ ck_stop(&dumpck);
+
+ /* Invoke the parser if there were no serious scanner errors. */
+ if (num_sev+num_err==0)
+ {
+ ck_start(&parsck);
+ parser();
+ ck_stop(&parsck);
+ /* Only perform post parser dumps if the parser was run. */
+ ck_start(&dumpck);
+ if (option.op_b4_b) dm_matb(&f_l);
+ if (option.op_b5_b) dm_dcls(&f_l);
+ ck_stop(&dumpck);
+ }
+ else
+ {
+ if (option.op_b4_b)
+ wl_l("Macro table dump skipped (Parser was not invoked).");
+ if (option.op_b5_b)
+ wl_l("Document list dump skipped (Parser was not invoked).");
+ }
+
+ /* Invoke the macro structure analyser if still no errors. */
+ if (num_sev+num_err==0)
+ {
+ ck_start(&analck);
+ analyse();
+ ck_stop(&analck);
+ }
+
+ /* The scanner, parser, and analyser send errors to the lister package. */
+ /* Send sorted listing to the listing file (and screen if desired). */
+ ck_start(&lstrck);
+ if (option.op_l_b) lr_gen(&f_l,option.op_c_i);
+ if (option.op_s_b) lr_gen(&f_s,option.op_s_i);
+ if (option.op_s_b) lr_gen(&f_j,option.op_s_i);
+ ck_stop(&lstrck);
+
+ /* If the first stages went OK, invoke tangle and weave. */
+ if (num_sev+num_err==0)
+ {
+ if (option.op_o_b)
+ {
+ ck_start(&tangck);
+ tangle();
+ ck_stop(&tangck);
+ }
+ if (option.op_t_b)
+ {
+ ck_start(&weavck);
+ weave();
+ ck_stop(&weavck);
+ }
+ /* Leave output lines from Tangle and Weave joined, but separate them */
+ /* from any further output. */
+ if (option.op_t_b || option.op_o_b)
+ wl_sjl("");
+ }
+ else
+ {
+ /* Otherwise tell the user that back-end phases will be skipped. */
+ if ( option.op_o_b || option.op_t_b)
+ {
+ if (num_sev+num_err==1)
+ wr_sjl("Error caused ");
+ else
+ wr_sjl("Errors caused ");
+ }
+ if ( option.op_o_b && option.op_t_b) wr_sjl("tangle and weave phases");
+ if ( option.op_o_b && !option.op_t_b) wr_sjl("tangle phase");
+ if (!option.op_o_b && option.op_t_b) wr_sjl("weave phase");
+ if ( option.op_o_b || option.op_t_b)
+ {wl_sjl(" to be skipped."); wl_sjl("");}
+ }
+
+ ck_stop(&totlck);
+
+ /* If requested write out a summary of the time taken. */
+ if (option.op_b6_b)
+ dm_times(&f_l,
+ &mappck,&scanck,&parsck,&analck,
+ &dumpck,&lstrck,&tangck,&weavck,&totlck);
+
+ /* Write out a line summarizing the diagnostics for this run. */
+ errsum(0L,num_sev,num_err,num_war); wl_sjl(linet1);
+
+ /* Close the listing file. */
+ if (!option.op_l_b) goto finishoff;
+ if (wf_err(&f_l))
+ {
+ wl_sj("S: Error writing to listing file. Aborting...");
+ num_sev++;
+ goto finishoff;
+ }
+ wf_clo(&f_l);
+ if (wf_err(&f_l))
+ {
+ wl_sj("S: Error flushing and closing listing file. Aborting...");
+ num_sev++;
+ }
+
+ finishoff:
+ /* VERY IMPORTANT: Ask the memory management package to free up all the */
+ /* temporary memory (allocated using mm_temp) that has been allocated. This */
+ /* ensures that the memory allocated for this FunnelWeb run will be recycled.*/
+ mm_zapt();
+
+} /* End of fwonerun */
+
+/******************************************************************************/
+
+LOCAL void do_absen P_((void));
+LOCAL void do_absen ()
+{
+ if (arg_num != 2)
+ {
+ wl_sj("S: The ABSENT command requires exactly one argument.");
+ num_sev++;
+ return;
+ }
+ if (fexists(arg_arr[1]))
+ {
+ sprintf(linet1,"S: ABSENT found \"%s\".",arg_arr[1]);
+ wl_sj(linet1);
+ num_sev++;
+ return;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void do_cody P_((void));
+LOCAL void do_cody ()
+/* The CODIFY command takes an input text file and generates an output text */
+/* file containing C code to write out the input text file. The need for this */
+/* command springs from the weaver. Experience with FunnelWeb showed that use */
+/* of a separate header file, to be included, while apparently sensible, */
+/* caused no end of problems. In particular, problems with portably */
+/* specifying where the header file should be found. In the end, it was */
+/* decided that it would be better to write the header file out with the */
+/* weave output. As the header file is quite long, it is best to automate the */
+/* process of converting the file from text to C code to write out the text. */
+/* That is what the CODIFY command does. */
+{
+ FILE *file1;
+ FILE *file2;
+
+#define MAXHACK 1000
+ char hackline[MAXHACK+1];
+ uword lineno;
+
+ if (arg_num != 3)
+ {
+ wl_sj("S: The CODIFY command requires exactly two arguments.");
+ num_sev++;
+ return;
+ }
+
+ /* Open the input file for text reading. */
+ file1=fopen(arg_arr[1],"r");
+ if (file1 == FOPEN_F)
+ {
+ wl_sj("S: Error opening the input file.");
+ num_sev++;
+ return;
+ }
+ file2=fopen(arg_arr[2],"w");
+ if (file2 == FOPEN_F)
+ {
+ fclose(file1);
+ wl_sj("S: Error creating the output file.");
+ num_sev++;
+ return;
+ }
+
+ lineno=0;
+
+ /* PROCESS A SINGLE LINE PER ITERATION. */
+ while (TRUE)
+ {
+ uword linelength;
+ uword i;
+
+ /* Read in a line of input and terminate loop if there are no more lines. */
+ fgets(hackline,MAXHACK,file1);
+ if (ferror(file1))
+ {wl_sj("S: Error reading the input file.");num_sev++;return;}
+ if (feof(file1)) break;
+ lineno++;
+
+ /* Complain if the input line is too long. */
+ if (strlen(hackline)>81)
+ {
+ sprintf(linet1,"Line %lu of input file is too long.",
+ (ulong) strlen(hackline));
+ wl_sj(linet1);
+ wl_sj("The maximum allowable length is 80 characters.");
+ num_sev++;
+ return;
+ }
+
+ /* Write the start-of-line string. */
+ if (fputs(" WX(\"",file2) == FPUTS_F) goto write_failure;
+
+ /* Write out the line in sanitized form. */
+ linelength=strlen(hackline);
+ for (i=0;i<linelength;i++)
+ {
+ char ch = hackline[i];
+ if (ch==EOL)
+ ; /* Ignore this. */
+ else
+ if (ch=='\"')
+ {if (fputs("\\\"",file2) == FPUTS_F) goto write_failure;}
+ else
+ if (ch=='\\')
+ {if (fputs("\\\\",file2) == FPUTS_F) goto write_failure;}
+ else
+ {if (fputc(ch,file2) == FPUTC_F) goto write_failure;}
+ }
+
+ /* Write the end of line string. */
+ if (fputs("\");\n",file2) == FPUTS_F) goto write_failure;
+ }
+
+ if (fflush(file2) != FFLUSH_S)
+ {wl_sj("S: Error flushing the output file.");num_sev++;return;}
+ if (fclose(file1) == FCLOSE_F)
+ {wl_sj("S: Error closing the input file.");num_sev++;return;}
+ if (fclose(file2) == FCLOSE_F)
+ {wl_sj("S: Error closing the output file.");num_sev++;return;}
+ return;
+
+ write_failure:
+ wl_sj("S: Error writing the output file.");num_sev++;return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_comp P_((void));
+LOCAL void do_comp ()
+/* The compare command should have two arguments being file names. It */
+/* compares the two files and raises a fatal error if they differ. */
+{
+ char *errstr;
+ bool result;
+ if (arg_num != 3)
+ {
+ wl_sj("S: COMPARE command must be given exactly two arguments.");
+ num_sev++;
+ return;
+ }
+ errstr=eq_files(arg_arr[1],arg_arr[2],&result);
+ if (errstr!=NULL)
+ {
+ wl_sj("S: COMPARE command ran into a problem:");
+ wl_sj(errstr);
+ num_sev++;
+ return;
+ }
+ if (!result)
+ {
+ wl_sj("S: A comparison FAILED. Two files compared were not identical!");
+ sprintf(linet1," File1: \"%s\".",arg_arr[1]); wl_sj(linet1);
+ sprintf(linet1," File2: \"%s\".",arg_arr[2]); wl_sj(linet1);
+ wl_sj(" FunnelWeb has just FAILED a regression test.");
+ wl_sj(" You should now inspect the two files to see how the result of");
+ wl_sj(" this run of FunnelWeb differed from the \"correct answer\" in");
+ wl_sj(" the answer directory.");
+ num_sev++;
+ return;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void do_defin P_((char *));
+LOCAL void do_defin (p_comlin)
+/* The define command associates a string with a $n. */
+char *p_comlin;
+{
+ char *p;
+ ubyte defnum;
+
+ /* p is our scanning pointer and starts at the start of the command line. */
+ p=p_comlin;
+
+ /* Skip past the DEFINE command onto the second argument. */
+ while ((*p!=' ') && (*p!=EOS)) p++;
+ while (*p==' ') p++;
+
+ /* There should be a single digit or upper case letter there. */
+ if (!isdigit(*p) && !isupper(*p))
+ {wl_sj("S: The first argument to DEFINE must be a decimal digit or");
+ wl_sj(" upper case letter.");
+ wl_sj(" Example: define 3 \"A Walrus in Spain is a Walrus in Vain.\"");
+ num_sev++;return;}
+ if (isdigit(*p))
+ defnum = *p-'0';
+ else
+ defnum = 10+(*p-'A');
+ as_cold(defnum<NUM_SUBS,"do_defin: num is too bug!");
+
+ /* Move past the digit. */
+ p++;
+
+ /* Skip blanks to get to the next argument. */
+ while (*p==' ') p++;
+
+ /* Complain if there is no second argument. */
+ if (*p==EOS)
+ {wl_sj("S: The DEFINE command expected a second argument.");
+ num_sev++; return;}
+
+ /* Otherwise make sure that we have a double quoted string. */
+ if (*p!='"' || *(p+1)==EOS || p[strlen(p)-1]!='"')
+ {wl_sj("S: Second argument to DEFINE must be in double quotes.");
+ num_sev++;return;}
+
+ /* All is checked. Now it is safe to copy over the string. */
+ p++;
+ strcpy(subval[defnum],p);
+ subval[defnum][strlen(subval[defnum])-1]=EOS;
+
+ /* TRACE: All the definitions.
+ {
+ ubyte i;
+ for (i=0;i<NUM_SUB;i++)
+ printf("$%u=\"%s\"\n",(unsigned) i,subval[i]);
+ }
+ */
+}
+
+/******************************************************************************/
+
+LOCAL void do_diff P_((void));
+/* COMMAND FORMAT: diff file1 file2 logfile [abort] */
+/* This function/command performs a proper text differences on two files. */
+/* This function is long and messy because of C's lack of nested functions. */
+/* I don't want to create global variables here, and defining subfunctions */
+/* that do not have access to the variables of this function would provoke */
+/* too wide an interface to be worth the trouble. So it's code city. */
+/* How I wish that I had FunnelWeb to help me write this function! */
+LOCAL void do_diff()
+{
+ bool diffabort; /* TRUE iff we should abort if files are different. */
+ bool is_same = FALSE; /* True iff files are proven to be the same. */
+ FILE *logfile; /* File to write result of comparison. */
+ bool badwrite = FALSE; /* TRUE if we couldn't write to the logfile. */
+ char *p_file1; /* Pointer to mapping of first file to compare. */
+ char *p_file2; /* Pointer to mapping of second file to compare. */
+ ulong len_file1; /* Number of bytes in mapping of first file. */
+ ulong len_file2; /* Number of bytes in mapping of second file. */
+ char *mess1; /* Error message from mapper for first file. */
+ char *mess2; /* Error message from mapper for second file. */
+ bool is_image; /* TRUE iff mapped images are identical. */
+ bool anydiff = FALSE; /* TRUE iff any differences detected during loop. */
+
+ /* Check that the number of arguments is correct. */
+ if (arg_num < 4 || arg_num > 5)
+ {
+ wl_sj("S: The DIFF command must be given either 3 or 4 arguments.");
+ wl_sj(" Usage: diff f1 f2 logfile [abort]");
+ num_sev++;
+ return;
+ }
+
+ /* Check that the fourth argument, if present, is legal. */
+ diffabort=FALSE;
+ if (arg_num == 5)
+ if (strcmp(arg_arr[4],"ABORT")==0 || strcmp(arg_arr[4],"abort")==0)
+ diffabort=TRUE;
+ else
+ {
+ wl_sj(
+ "S: The DIFF command's fourth argument, if present, must be ABORT.");
+ wl_sj(" Usage: diff f1 f2 logfile [abort]");
+ num_sev++;
+ return;
+ }
+
+ /* Now open the log file to append result of compare. */
+ logfile=fopen(arg_arr[3],"a");
+ if (logfile == FOPEN_F)
+ {
+ wl_sj("S: DIFF: Error opening the log file (to append result of compare).");
+ num_sev++;
+ return;
+ }
+
+ /* The following define simplifies writing to the log file. */
+#define LOGLINE {if (fputs(linet1,logfile) == FPUTS_F) badwrite=TRUE;}
+#define LOGSTR(STR) {if (fputs((STR),logfile) == FPUTS_F) badwrite=TRUE;}
+#define LOGCHAR(CH) {if (fputc((CH),logfile) == FPUTC_F) badwrite=TRUE;}
+
+ /* Write the header for this comparison to the log file. */
+ sprintf(linet1,"\n\n" ); LOGLINE;
+ sprintf(linet1,"Comparing \"%s\"\n" ,arg_arr[1]); LOGLINE;
+ sprintf(linet1," with \"%s\".\n",arg_arr[2]); LOGLINE;
+
+ /* Now map in the two files to be compared. */
+ /* Once this is done, we MUST do a mm_zapt later or memory will leak. */
+ /* We attempt to map the second file, even if the first mapping has failed */
+ /* as, if the first file is absent, there is a good chance that the second */
+ /* is absent too, and it is useful to the user to know this. */
+ mess1=map_file(arg_arr[1],&p_file1,&len_file1);
+ mess2=map_file(arg_arr[2],&p_file2,&len_file2);
+ if (mess1 != NULL)
+ {
+ sprintf(linet1,"Error mapping \"%s\".\n",arg_arr[1]); LOGLINE;
+ wr_sj("E: DIFF: "); wr_sj(linet1);
+ sprintf(linet1," %s\n",mess1); LOGLINE; wr_sj(linet1);
+ num_err++;
+ }
+ if (mess2 != NULL)
+ {
+ sprintf(linet1,"Error mapping \"%s\".\n",arg_arr[2]); LOGLINE;
+ wr_sj("E: DIFF: "); wr_sj(linet1);
+ sprintf(linet1," %s\n",mess2); LOGLINE; wr_sj(linet1);
+ num_err++;
+ }
+ if ((mess1 != NULL) || (mess2 != NULL))
+ goto frombadmap;
+
+ /* At this point the two files to be compared are sitting in memory and we */
+ /* have a ready-for-writing log file. We are now ready to compare. */
+
+ /* First perform a binary image comparison as a check for later. */
+ /* We could do this later, but it is better to do this now, in case the */
+ /* complicated comparison code somehow corrupts one of the images. */
+ is_image= ((len_file1 == len_file2) &&
+ (memcmp(p_file1,p_file2,(size_t) len_file1) == 0));
+
+ /* This anonymous block performs the actual comparison. */
+ {
+ /* The comparison is performed by scrolling the two input files through two */
+ /* fixed-length line buffers (buf1 and buf2 - see below). To avoid copying, */
+ /* the buffers are made circular. Processing takes place by comparing the */
+ /* first line of each buffer. If the line is the same, the buffers are */
+ /* scrolled by one line. If they are different, then we have encountered a */
+ /* DIFFERENCES SECTION and we have to compare lines near the top of the */
+ /* buffers to find a match. When a match is found, each buffer is scrolled */
+ /* down to its match point and processing continues. */
+
+/* LBUFSIZ is the number of number of lines that each buffer can hold. */
+/* Lines are indexed from [0,LBUFSIZ-1]. */
+/* WARNING: LBUFSIZ must be a power of two corresponding to WRAP(X). */
+/* WARNING: Totally different input files will provoke O(LBUFSIZ^2) */
+/* checksum comparisons per LBUFSIZ input lines. */
+/* WRAP(X) is a macro that performs wraparound of buffer indices. */
+/* GAP is the number of lines that have to match to end a diff section. */
+/* MAXDIST is the maximum "distance" that is tested when matching. */
+#define LBUFSIZ 64
+#define WRAP(X) ((X) & 0x3F)
+#define GAP 3
+#define MAXDIST (LBUFSIZ-GAP)
+
+/* The following macro compares two lines in the buffers. */
+/* The arguments are absolute buffer indices, not relative ones. */
+/* We assume that checksums will mismatch more often than line lengths. */
+#define COMPLINE(INDA,INDB) \
+ ((buf1[INDA].c_line == buf2[INDB].c_line) && \
+ (buf1[INDA].l_line == buf2[INDB].l_line) && \
+ (memcmp(buf1[INDA].p_line,buf2[INDB].p_line, \
+ (size_t) buf1[INDA].l_line)==0))
+
+ /* The two line buffers buf1 and buf2 (see below) don't actually store */
+ /* lines. Instead they store line structures which store pointers to the */
+ /* lines in the mapped images of the files. They also store the length of */
+ /* each line, and a checksum of the line. The checksum is useful for */
+ /* speeding up the comparisons between lines when processing a differences */
+ /* section. */
+ typedef
+ struct
+ {
+ char *p_line; /* Pointer to first byte in the line. */
+ ulong l_line; /* Number of bytes in the line. */
+ uword c_line; /* Checksum of the line. */
+ } line_t;
+
+ char *p_next1 = p_file1; /* Points to next line in file1. */
+ char *p_next2 = p_file2; /* Points to next line in file2. */
+ char *p_post1 = p_file1+len_file1; /* Byte following image of file1. */
+ char *p_post2 = p_file2+len_file2; /* Byte following image of file2. */
+ line_t buf1[LBUFSIZ]; /* Comparison buffer for first file. */
+ line_t buf2[LBUFSIZ]; /* Comparison buffer for second file. */
+ ulong buf1top = 0; /* Index of first line in first buffer. */
+ ulong buf2top = 0; /* Index of first line in second buffer. */
+ ulong buf1fil = 0; /* Number of lines in first buffer. */
+ ulong buf2fil = 0; /* Number of lines in second buffer. */
+ ulong topnum1 = 1; /* Line number of first line of first buffer. */
+ ulong topnum2 = 1; /* Line number of first line of second buffer. */
+
+ /* The following loop compares the line(s) at the top of the two buffers */
+ /* and processes (lines1,lines2) lines of each. */
+ while (TRUE)
+ {
+ ulong lines1; /* Lines of file1 processed during this loop iteration. */
+ ulong lines2; /* Lines of file2 processed during this loop iteration. */
+ ulong d,g; /* Used in comparison loops. */
+
+ /* The first thing we do is to fill each buffer as full as possible. At */
+ /* the end of the next two lumps of code, the only reason that a file's */
+ /* is not full is that we have reached the end of the file. */
+
+ /* Fill the first buffer as full as possible. */
+ while ((buf1fil < LBUFSIZ) && (p_next1 != p_post1))
+ {
+ ulong ind = WRAP(buf1top + buf1fil);
+ ulong len = 0;
+ uword csum = 0;
+ char *p_lin = p_next1;
+ while (TRUE)
+ {
+ if (p_next1 == p_post1) break;
+ len++;
+ csum=(csum+*p_next1++) & 0xFFFF;
+ if (*(p_next1-1) == EOL) break;
+ }
+ buf1[ind].p_line = p_lin;
+ buf1[ind].l_line = len;
+ buf1[ind].c_line = csum;
+ buf1fil++;
+ }
+
+ /* Fill the second buffer as full as possible. */
+ while ((buf2fil < LBUFSIZ) && (p_next2 != p_post2))
+ {
+ ulong ind = WRAP(buf2top + buf2fil);
+ ulong len = 0;
+ uword csum = 0;
+ char *p_lin = p_next2;
+ while (TRUE)
+ {
+ if (p_next2 == p_post2) break;
+ len++;
+ csum=(csum+*p_next2++) & 0xFFFF;
+ if (*(p_next2-1) == EOL) break;
+ }
+ buf2[ind].p_line = p_lin;
+ buf2[ind].l_line = len;
+ buf2[ind].c_line = csum;
+ buf2fil++;
+ }
+
+ /* If the buffers are empty then we must be at the end of each file. */
+ if (buf1fil==0 && buf2fil==0)
+ break;
+
+ /* Try to peel a pair of matching lines off the top of the buffer. */
+ /* If we succeed, zip down to the end of the loop and flush them. */
+ /* We can't integrate this code into the next part because the next part */
+ /* requires GAP matches, whereas here we require just one. */
+ if ((buf1fil>0) && (buf2fil>0) && COMPLINE(buf1top,buf2top))
+ {lines1=lines2=1; goto flushlines;}
+
+ /* At this point, we know we have a differences section. */
+ anydiff=TRUE;
+
+ /* We now compare the top lines of the two buffers for a match. A match */
+ /* is only considered to have been found if we match GAP consecutive */
+ /* lines. The best match minimizes the DISTANCE which is the sum of the */
+ /* offsets (lines1,lines2) (in lines) from the top of each buffer where */
+ /* the match starts. Even better matches minimize abs(lines1-lines2) as */
+ /* well. All these nested loops are to ensure that we search best first. */
+ for (d=1;d<=MAXDIST;d++)
+ {
+ /* Calculate half distance on the high side. */
+ long half = (d/2)+1;
+ long off;
+ long sign_v;
+ /* Explore up and down simultaneously from the halfway mark. */
+ for (off=0;off<=half;off++)
+ for (sign_v= -1;sign_v<2;sign_v+=2)
+ {
+ long x = half + sign_v*off;
+ /* The following test allows the above loops to be sloppy. */
+ if (0<=x && x<=d)
+ {
+ lines1=x;
+ lines2=d-lines1;
+ /* We now know that we want to test at (lines1,lines2). */
+ /* So compare the GAP lines starting at those positions. */
+ /* Note: lines1 and lines2, as well as being the number */
+ /* of lines processed, are also the offset to the first */
+ /* match line in our match gap. */
+ for (g=0;g<GAP;g++)
+ { /* Note: R for relative, A for absolute. */
+ ulong t1r = lines1 + g;
+ ulong t2r = lines2 + g;
+ ulong t1a,t2a;
+
+ /* If both files have run out at this point, it's a match!*/
+ if ((t1r>=buf1fil) && (t2r>=buf2fil)) continue;
+
+ /* If just one of the files has run out it's a mismatch. */
+ if ((t1r>=buf1fil) || (t2r>=buf2fil)) goto gapfail;
+
+ /* We now know that we have two real lines. Compare them. */
+ /* Variables are to avoid big nested macro expansions. */
+ t1a = WRAP(buf1top+t1r);
+ t2a = WRAP(buf2top+t2r);
+ if (!COMPLINE(t1a,t2a)) goto gapfail;
+ }
+ /* If we dropped out of the gap loop, we must have found */
+ /* GAP consecutive matches. So we can run off and write out */
+ /* the difference section. */
+ goto writediff;
+
+ /* Here's where we jump if we found a mismatch during gap */
+ /* looping. All we do is try next pair of offsets. */
+ gapfail:;
+ } /* End sloppy if. */
+ } /* End for sign_v. */
+ } /* End for distance loop. */
+
+ /* If we got to here then we must have dropped out of the search loop */
+ /* which means that there must have been no match at all between the */
+ /* buffers. The only thing to do is to write out what we have as */
+ /* a differences section. */
+ lines1=buf1fil;
+ lines2=buf2fil;
+
+ /* Write out the differences section (lines1,lines2) to the log file. */
+ writediff:
+ { /* Begin writediff */
+ ulong i,j;
+ LOGSTR("\n");
+ LOGSTR(" +-----\n");
+ for (i=0;i<lines1;i++)
+ {
+ ulong nline = WRAP(buf1top+i);
+ sprintf(linet1,"%05lu|",(ulong) topnum1+i); LOGLINE;
+ for (j=0;j<buf1[nline].l_line;j++)
+ LOGCHAR(*(buf1[nline].p_line+j));
+ }
+ LOGSTR(" +-----\n");
+ for (i=0;i<lines2;i++)
+ {
+ ulong nline = WRAP(buf2top+i);
+ sprintf(linet1,"%05lu|",(ulong) topnum2+i); LOGLINE;
+ for (j=0;j<buf2[nline].l_line;j++)
+ LOGCHAR(*(buf2[nline].p_line+j));
+ }
+ LOGSTR(" +-----\n");
+ } /* End writediff. */
+
+ /* Flush from buffer however many lines we ended up processing. */
+ flushlines:
+ buf1top=WRAP(buf1top+lines1); topnum1+=lines1; buf1fil-=lines1;
+ buf2top=WRAP(buf2top+lines2); topnum2+=lines2; buf2fil-=lines2;
+
+ } /* End the while loop that runs through the two files. */
+ } /* End of anonymous block for doing actual comparison. */
+
+ /* The anydiff flag tells us if the loop found any difference sections. */
+ is_same=!anydiff;
+
+ /* Target position if we couldn't map in the input files earlier. */
+ frombadmap:
+
+ /* Release the memory allocated by the mapper for the input files. */
+ /* Failure to do this will result in a memory leak! */
+ mm_zapt();
+
+ /* If the two files are identical, tell the log file. */
+ if (is_same)
+ LOGSTR("The two files are IDENTICAL.\n");
+
+ /* Invalidate this test in the log file, if inconsistent (see later). */
+ if (is_same != is_image)
+ LOGSTR("<<CONSISTENCY FAILURE: ABOVE COMPARISON INVALID>>\n");
+
+ /* If we had problems with the log file at any stage, kick up a fuss now. */
+ if (badwrite)
+ {wl_sj("S: DIFF: Error writing to log file."); num_sev++;}
+
+ /* Close the log file. */
+ if (fclose(logfile) == FCLOSE_F)
+ {wl_sj("S: DIFF: Error closing the log file."); num_sev++;}
+
+ /* The above code is quite tricky and there is a chance that it contains */
+ /* bugs. So, as a safety check we compare the results from the binary memory */
+ /* image comparison performed earlier and the more complicated text */
+ /* comparison above. If they differ, then it's time to go kaboom. */
+ if (is_image && !is_same)
+ as_bomb("do_diff: Image comparison succeeded, but text comparison failed.");
+ if (!is_image && is_same)
+ as_bomb("do_diff: Image comparison failed, but text comparison succeeded.");
+
+ /* If files are non-same and ABORT option is turned on, set severe status. */
+ if (!is_same && diffabort)
+ {
+ wl_sj(
+ "S: DIFF: Files have not been proven identical, and ABORT option is on.");
+ num_sev++;
+ }
+
+ /* Tell the console whether comparison succeeded. */
+ if (is_same)
+ wl_sj("The two files are IDENTICAL.");
+ else
+ wl_sj("The two files are DIFFERENT (see the differences file for the details).");
+
+ /* Increment the difference summary counters. */
+ difftotl++;
+ if (is_same)
+ diffsucc++;
+}
+
+/******************************************************************************/
+
+LOCAL void do_dsum P_((void));
+LOCAL void do_dsum ()
+{
+ sprintf(linet1,"Summary of Differences"); wl_sj(linet1);
+ sprintf(linet1,"----------------------"); wl_sj(linet1);
+ sprintf(linet1,"Identical = %lu.",(ulong) diffsucc); wl_sj(linet1);
+ sprintf(linet1,"Different = %lu.",(ulong) (difftotl-diffsucc)); wl_sj(linet1);
+ sprintf(linet1,"Total = %lu.",(ulong) difftotl); wl_sj(linet1);
+}
+
+/******************************************************************************/
+
+LOCAL void do_dzer P_((void));
+LOCAL void do_dzer ()
+/* Zaps difference counters. */
+{
+ difftotl = 0;
+ diffsucc = 0;
+}
+
+/******************************************************************************/
+
+LOCAL void do_eneo P_((void));
+LOCAL void do_eneo ()
+{
+ if (arg_num != 2)
+ {
+ wl_sj("S: The ENEO command must be given exactly one argument.");
+ num_sev++;
+ return;
+ }
+ if (fexists(arg_arr[1]))
+ if (remove(arg_arr[1]) != REMOVE_S)
+ {
+ sprintf(linet1,"S: ENEO failed to delete \"%s\".",arg_arr[1]);
+ wl_sj(linet1);
+ num_sev++;
+ return;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void do_exec P_((void));
+LOCAL void do_exec ()
+{
+ uword i;
+
+ if (arg_num < 2)
+ {
+ wl_sj("S: The EXECUTE command requires at least one argument.");
+ num_sev++;
+ return;
+ }
+ if (arg_num > 10)
+ {
+ wl_sj("S: The EXECUTE command can have at most nine arguments.");
+ num_sev++;
+ return;
+ }
+
+ /* Zap all the numeric arguments. */
+ for (i=0; i<10; i++)
+ subval[i][0]=EOS;
+
+ /* Copy the arguments over to the $1 $2 etc substitution variables. */
+ for (i=1;i<arg_num; i++)
+ strcpy(subval[i-1],arg_arr[i]);
+
+ /* Run up a new FunnelWeb shell and interpret the file. */
+ interstr(arg_arr[1]);
+}
+
+/******************************************************************************/
+
+LOCAL void do_exist P_((void));
+LOCAL void do_exist ()
+{
+ if (arg_num != 2)
+ {
+ wl_sj("S: The EXISTS command requires exactly one argument.");
+ num_sev++;
+ return;
+ }
+ if (!fexists(arg_arr[1]))
+ {
+ sprintf(linet1,"S: EXISTS failed to find \"%s\".",arg_arr[1]);
+ wl_sj(linet1);
+ num_sev++;
+ return;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void do_fix P_((void));
+LOCAL void do_fix ()
+/* When the test suite is moved from one machine to another, it is possible */
+/* that at some stage it will be moved using a BINARY transfer rather than a */
+/* text file transfer. The result is that the test files will contain lines */
+/* terminated with a sequence of control characters that the local buffered */
+/* IO library will not convert to '\n' upon reading in. The are a few */
+/* solutions to this problem, but one of the most direct is to have a command */
+/* such as this one that can convert the file over. */
+/* */
+/* Once we have identified an end of line, it is easy to write it out as we */
+/* can just send a '\n' and the local buffered IO library will write the */
+/* right codes for us. The tricky part is deciding what an EOL is in the */
+/* input stream. Well, I could have made the control characters for the */
+/* remote EOL a parameter of this command, but instead I decided to use a */
+/* simple algorithm that should cover nearly all cases... */
+/* ALGORITHM: Parse the input into alternating blocks of control characters */
+/* and non-control characters. Parse each block of control characters into */
+/* subblocks by parsing it from left to right and starting a new subblock the */
+/* moment a character of the subblock currently being parsed appears again. */
+/* This covers at least the following cases, and probably many more: */
+/* UNIX LF */
+/* MSDOS CR LF */
+/* Macintosh CR */
+{
+ /* Erk! But I found out the hard way, it doesn't work on a VAX! */
+ /* I'm making this do nothing on a VAX rather than generate an error as I */
+ /* want the scripts to work silently on the VAX without modification. */
+#if !VMS
+ FILE *infile; /* File variable for input file. */
+ FILE *tmpfile; /* File variable for temporary output file. */
+ char *p_target; /* Name of final (target) output file. */
+ STAVAR char *p_temp=NULL; /* Name of temporary output file. */
+
+ bool seen[256]; /* TRUE if char is in current control sequence. */
+ char undo[256]; /* undo[0..length-1] contains current control sequence. */
+ uword length; /* Number of control bytes in our buffer. */
+ uword i;
+ int status;
+
+ /* Allocate the temporary file name if not already allocated. */
+ if (p_temp==NULL) p_temp=(p_fn_t) mm_perm(sizeof(fn_t));
+
+ /* We can take one or two arguments. One argument means that we should */
+ /* fix up the input file, leaving the result in the input file. */
+ if (arg_num != 2 && arg_num != 3)
+ {
+ wl_sj("S: The FIXEOLS command requires one or two filename arguments.");
+ num_sev++;
+ return;
+ }
+
+ /* Change to two arguments if the input name is the same as output name. */
+ if (arg_num==3 && strcmp(arg_arr[1],arg_arr[2])==0) arg_num=2;
+
+ /* Work out what the target name is going to be. */
+ p_target=(arg_num==2) ? arg_arr[1] : arg_arr[2];
+
+ /* Generate a temporary filename for the output file. This is tricky because */
+ /* on many machines, one cannot rename across devices or directories. This */
+ /* means that the temporary file has to be created in the same directory as */
+ /* the file that we are going to rename it to later (the target file). */
+ strcpy(p_temp,p_target);
+ fn_ins(p_temp,fn_temp());
+
+ /* Open the input file for BINARY reading. */
+ infile=fopen(arg_arr[1],"rb");
+ if (infile == FOPEN_F)
+ {
+ sprintf(linet1,"S: FIXEOLS: Error opening \"%s\".",arg_arr[1]);
+ wl_sj(linet1);
+ num_sev++;
+ return;
+ }
+
+ /* Create the output file for TEXT writing. */
+ tmpfile=fopen(p_temp,"w");
+ if (tmpfile == FOPEN_F)
+ {
+ fclose(infile);
+ wl_sj("S: FIXEOLS: Error creating the temporary output file.");
+ num_sev++;
+ return;
+ }
+
+ /* Initialialize the control character buffer to empty. */
+ for (i=0;i<256;i++) seen[i]=FALSE;
+ length=0;
+
+ while (TRUE)
+ {
+ /* Read in the next character from the input file. */
+ char ch=getc(infile);
+ if (ferror(infile))
+ {wl_sj("S: FIXEOLS: Error reading the input file.");num_sev++;return;}
+ if (feof(infile)) break;
+
+ /* Does character terminate a non-empty buffer? If so, flush it. */
+ if (length>0 && (isascprn(ch) || seen[ch]))
+ {
+ if (fputc(EOL,tmpfile) == FPUTC_F) goto write_failure;
+ for (i=0;i<length;i++) seen[undo[i]]=FALSE;
+ length=0;
+ }
+
+ /* Now we can approach the character cleanly and freshly. */
+ if (isascprn(ch))
+ {if (fputc(ch,tmpfile) == FPUTC_F) goto write_failure;}
+ else
+ {undo[length++]=ch; seen[ch]=TRUE;}
+ }
+ if (length>0)
+ {if (fputc(EOL,tmpfile) == FPUTC_F) goto write_failure;}
+
+ if (fflush(tmpfile) != FFLUSH_S)
+ {wl_sj("S: FIXEOLS: Error flushing the temporary output file.");num_sev++;return;}
+ if (fclose(infile) == FCLOSE_F)
+ {wl_sj("S: FIXEOLS: Error closing the input file.");num_sev++;return;}
+ if (fclose(tmpfile) == FCLOSE_F)
+ {wl_sj("S: FIXEOLS: Error closing the temporary output file.");num_sev++;return;}
+
+ /* If renaming to the input file, we have to delete the input file first. */
+ if (arg_num==2)
+ {
+ status=remove(arg_arr[1]);
+ if (status != REMOVE_S)
+ {
+ wl_sj("S: FIXEOLS: Error deleting existing input file to replace it");
+ wl_sj(" with the temporary output file. Deleting temporary and aborting...");
+ remove(p_temp);
+ num_sev++;
+ return;
+ }
+ }
+
+ /* Rename the temporary file to the target output file. */
+ status=rename(p_temp,p_target);
+
+ /* Do the error checking. */
+ if (status != RENAME_S)
+ {
+ wl_sjl("S: FIXEOLS: Error renaming temporary output file to output file.");
+ sprintf(linet1,"Temporary file name was \"%s\".",p_temp);
+ wl_sjl(linet1);
+ sprintf(linet1,"Output file name was \"%s\".",p_target);
+ wl_sjl(linet1);
+ wl_sjl("FunnelWeb will leave both files intact so you can look at them.");
+ num_sev++;
+ return;
+ }
+
+ return;
+
+ write_failure:
+ wl_sj("S: FIXEOLS: Error writing the output file.");num_sev++;return;
+#endif
+}
+
+/******************************************************************************/
+
+LOCAL void do_fweb P_((char *));
+LOCAL void do_fweb(p_cl)
+/* This function performs a single run of FunnelWeb proper. */
+char *p_cl;
+{
+ op_t saveop;
+
+ /* Do set can do all the work for us. However, it operates on p_defopt so we */
+ /* have to do some juggling. */
+ ASSIGN(saveop,*p_defopt);
+ do_set(p_cl);
+ ASSIGN(option,*p_defopt);
+ ASSIGN(*p_defopt,saveop);
+ if (num_sev>0) return;
+
+ /* do_set ensures that the user hasn't specified any action parameters such */
+ /* as +X and +K, but it necessarily doesn't check to make sure that the user */
+ /* has actually specified an input file! */
+ if (!option.op_f_b)
+ {
+ wl_sj("S: No input file specified in FW command.");
+ num_sev++;
+ return;
+ }
+ fwonerun();
+}
+
+/******************************************************************************/
+
+LOCAL void do_help P_((void));
+LOCAL void do_help()
+{
+ uword messno;
+
+ if (arg_num == 1)
+ {
+ hel_wri(wr_sj,HL_MEN);
+ return;
+ }
+ if (arg_num > 2)
+ {
+ wl_sj("S: The HELP command takes at most one argument.");
+ num_sev++;
+ return;
+ }
+
+ /* Translate message name to number. */
+
+ messno=hel_num(arg_arr[1]);
+ if (messno == HL_ERR)
+ {
+ wl_sj(
+ "S: Unrecognised help message name. Try just \"help\" for a list of names.");
+ num_sev++;
+ return;
+ }
+
+ hel_wri(wr_sj,messno);
+}
+
+/******************************************************************************/
+
+LOCAL void do_set(p_comlin)
+/* The SET command allows the user to specify default FunnelWeb options. */
+char *p_comlin;
+{
+ op_t tmpopt;
+
+ /* Experiment with temporary options, not the real thing. */
+ ASSIGN(tmpopt,*p_defopt);
+
+ /* Now execute the effect of the command line on 'p_defopt'. */
+ if (!op_add(&tmpopt,p_comlin,wr_sj))
+ {
+ wl_s("This is a severe error (S). Aborting to FunnelWeb shell...");
+ num_sev++;
+ return;
+ }
+
+ /* Now make sure that the user didn't specify an option to do with the */
+ /* entire FunnelWeb run and not just this invocation of FunnelWeb proper. */
+ if (tmpopt.op_j_b)
+ {
+ wl_s("S: You cannot invoke FunnelWeb with +J from the FunnelWeb shell.");
+ wl_s(" To create a journal file, exit FunnelWeb and reinvoke with \"fw +j\".");
+ wl_s("This is a severe error. Aborting to FunnelWeb shell...");
+ num_sev++;
+ return;
+ }
+ if (tmpopt.op_x_b)
+ {
+ wl_s("S: You cannot invoke FunnelWeb with +X from the FunnelWeb shell.");
+ wl_s("Use the interactive command EXECUTE instead.");
+ wl_s("This is a severe error. Aborting to FunnelWeb shell...");
+ num_sev++;
+ return;
+ }
+ if (tmpopt.op_k_b)
+ {
+ wl_s("S: You cannot invoke FunnelWeb with +K from the FunnelWeb shell.");
+ wl_s("This is a severe error. Aborting to FunnelWeb shell...");
+ num_sev++;
+ return;
+ }
+ if (tmpopt.op_h_b)
+ {
+ wl_s("S: You cannot invoke FunnelWeb with +H from the FunnelWeb shell.");
+ wl_s("Use the interactive command HELP instead.");
+ wl_s("This is a severe error. Aborting to FunnelWeb shell...");
+ num_sev++;
+ return;
+ }
+
+ /* If we get to here, the options must be OK so we can set them as default. */
+ ASSIGN(*p_defopt,tmpopt);
+}
+
+/******************************************************************************/
+
+LOCAL void do_show P_((void));
+LOCAL void do_show()
+/* The SHOW command writes out the current options. */
+{
+ if (arg_num != 1)
+ {
+ wl_sj("S: The SHOW command does not take arguments.");
+ num_sev++;
+ return;
+ }
+ wl_sj("Here are the FunnelWeb command line options that are");
+ wl_sj("current in this FunnelWeb session:");
+ op_wri(p_defopt,wr_sj);
+}
+
+/******************************************************************************/
+
+LOCAL void do_stat P_((void));
+LOCAL void do_stat ()
+/* The status command checks the number of diagnostics generated by the run. */
+{
+ uword i;
+ char *thing;
+ ulong cnum;
+
+ if (arg_num<1 || arg_num>4)
+ {
+ wl_sj("S: The STATUS command requires zero to three arguments.");
+ num_sev++;
+ return;
+ }
+
+ /* Zero arguments just means write out status. */
+ if (arg_num == 1)
+ {
+ sprintf(linet1,"Last command: Severes=%lu, Errors=%lu, Warnings=%lu.",
+ (ulong) old_sev, (ulong) old_err, (ulong) old_war);
+ wl_sj(linet1);
+ sprintf(linet1,"Totals : Severes=%lu, Errors=%lu, Warnings=%lu.",
+ (ulong) sum_sev, (ulong) sum_err, (ulong) sum_war);
+ wl_sj(linet1);
+ return;
+ }
+
+ /* More than one argument means CHECK status. */
+ for (i=1;i<arg_num;i++)
+ {
+ char ch=toupper(arg_arr[i][0]);
+ unsigned num;
+ if (ch!='W' && ch!='E' && ch!='S')
+ {
+ sprintf(linet1,
+ "S: Argument %u of STATUS command has bad letter.",
+ (unsigned) i);
+ wl_sj(linet1);
+ wl_sj("Arguments must be of the form ('W'|'E'|'S')<decimalnumber>.");
+ num_sev++;
+ return;
+ }
+ if (sscanf(&arg_arr[i][1],"%u",&num) != 1)
+ {
+ sprintf(linet1,
+ "S: Argument %u of STATUS command has bad number.",
+ (unsigned) i);
+ wl_sj(linet1);
+ wl_sj(" Arguments must be of the form ('W'|'E'|'S')<decimalnumber>.");
+ num_sev++;
+ return;
+ }
+ switch(ch)
+ {
+ case 'W': cnum=old_war; thing="warnings"; break;
+ case 'E': cnum=old_err; thing="errors" ; break;
+ case 'S': cnum=old_sev; thing="severes" ; break;
+ default : as_bomb("do_stat: case defaulted.");
+ }
+ if (cnum != num)
+ {
+ sprintf(linet1,
+ "S: STATUS command detected wrong number of %s.",thing);
+ wl_sj(linet1);
+ sprintf(linet1, "Specifed %s=%u, Actual %s=%u.",
+ thing,(unsigned) num,thing,(unsigned) cnum);
+ wl_sj(linet1);
+ num_sev++;
+ }
+ }
+}
+
+/******************************************************************************/
+
+
+LOCAL void do_trace P_((void));
+LOCAL void do_trace()
+{
+ if (arg_num != 2) goto help;
+ strupper(arg_arr[1]);
+ if (strcmp(arg_arr[1],"OFF") == 0) {tracing=FALSE; return;}
+ if (strcmp(arg_arr[1], "ON") == 0) {tracing=TRUE ; return;}
+
+ help:
+ wl_sj("S: The TRACE command has two forms:");
+ wl_sj(" TRACE OFF");
+ wl_sj(" TRACE ON");
+ num_sev++;
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_write P_((char *));
+LOCAL void do_write(p)
+char *p;
+{
+ uword len;
+
+ /* Skip over the main command and the following blanks. */
+ while (*p!=' ' && *p!=EOS) p++;
+ while (*p==' ') p++;
+
+ /* Now make sure that the remaining string is delimited by double quotes. */
+ len=strlen(p);
+ if ((*p != '\"') || (p[len-1] != '\"') || len<2)
+ {
+ wl_sj("W: The argument to WRITE should be delimited by double quotes.");
+ wl_sj(p);
+ num_war++;
+ return;
+ }
+
+ /* Now temporarily hack out the quotes and write out the string. */
+ p[len-1]=EOS;
+ wl_sj(p+1);
+ p[len-1]='\"';
+}
+
+/******************************************************************************/
+
+LOCAL void do_writu P_((char *));
+LOCAL void do_writu(p)
+char *p;
+{
+ uword len;
+
+ /* Skip over the main command and the following blanks. */
+ while (*p!=' ' && *p!=EOS) p++;
+ while (*p==' ') p++;
+
+ /* Now make sure that the remaining string is delimited by double quotes. */
+ len=strlen(p);
+ if ((*p != '\"') || (p[len-1] != '\"') || len<2)
+ {
+ wl_sj("W: The argument to WRITEU should be delimited by double quotes.");
+ wl_sj(p);
+ num_war++;
+ return;
+ }
+
+ /* Now temporarily hack out the quotes and write out the string. */
+ p[len-1]=EOS;
+ wl_sj(p+1);
+ p[len-1]='\"';
+
+ /* Now write out another line underlining the above. */
+ {uword i; for (i=0;i<len-2;i++) wr_sj("-"); wl_sj("");}
+}
+
+/******************************************************************************/
+
+LOCAL bool do_command P_((char *));
+LOCAL bool do_command(p_command)
+/* Execute a single FunnelWeb shell command. */
+char *p_command;
+{
+ char *v;
+ bool result=FALSE;
+
+ zerdia();
+
+ /* Check the command for non-printables. */
+ {
+ char *s=p_command;
+ while (*s!=EOS)
+ {
+ if (!isascprn(*s))
+ {
+ sprintf(linet1,
+ "S: Command line has non-printable at column %u.",
+ (unsigned) (s-p_command)+1);
+ wl_sj(linet1);
+ num_sev++;
+ goto finished;
+ }
+ s++;
+ }
+ }
+
+ /* Perform substitutions. */
+ dollsub(p_command); if (num_sev>0) goto finished;
+
+ /* Ignore commands consisting entirely of blanks (or empty commands). */
+ {
+ char *s=p_command;
+ while (*s==' ') s++;
+ if (*s==EOS) goto finished;
+ }
+
+ /* Reject command lines beginning with a blank. */
+ if (p_command[0]==' ')
+ {
+ wl_sj("S: Leading blanks are not allowed in command lines.");
+ num_sev++;
+ goto finished;
+ }
+
+ /* Ignore command lines commencing with the comment character. */
+ if (p_command[0]=='!')
+ {restdia(); goto finished;}
+
+ /* Parse the command line into arguments. */
+ explode(p_command);
+
+ /* Complain if there is no command verb. */
+ as_cold(arg_num>0,"do_command: zero arguments!");
+
+ /* It's convenient to have v pointing to verb. */
+ v=arg_arr[0];
+
+ /* Convert the verb to upper case. */
+ strupper(v);
+
+
+ /* Execute the verb. */
+
+ if (strcmp(v,"HERE")==0) skipping=FALSE;
+ else if (!skipping)
+ if (strcmp(v,"ABSENT" )==0) do_absen();
+ else if (strcmp(v,"CODIFY" )==0) do_cody ();
+ else if (strcmp(v,"COMPARE" )==0) do_comp ();
+ else if (strcmp(v,"DEFINE" )==0) do_defin(&p_command[0]);
+ else if (strcmp(v,"DIFF" )==0) do_diff();
+ else if (strcmp(v,"DIFFSUMMARY")==0) do_dsum();
+ else if (strcmp(v,"DIFFZERO" )==0) do_dzer();
+ else if (strcmp(v,"ENEO" )==0) do_eneo ();
+ else if (strcmp(v,"EXECUTE" )==0) do_exec ();
+ else if (strcmp(v,"EXISTS" )==0) do_exist();
+ else if (strcmp(v,"FIXEOLS" )==0) do_fix ();
+ else if (strcmp(v,"FW" )==0) do_fweb (&p_command[0]);
+ else if (strcmp(v,"HELP" )==0) do_help ();
+ else if (strcmp(v,"QUIT" )==0) result=TRUE;
+ else if (strcmp(v,"SET" )==0) do_set (&p_command[0]);
+ else if (strcmp(v,"SHOW" )==0) do_show ();
+ else if (strcmp(v,"SKIPTO" )==0) skipping=TRUE;
+ else if (strcmp(v,"STATUS" )==0) do_stat ();
+ else if (strcmp(v,"TOLERATE" )==0) noabort=TRUE;
+ else if (strcmp(v,"TRACE" )==0) do_trace();
+ else if (strcmp(v,"WRITE" )==0) do_write(&p_command[0]);
+ else if (strcmp(v,"WRITEU" )==0) do_writu(&p_command[0]);
+ else
+ {
+ /* The following trace is likely to confuse beginners. */
+ /* sprintf(linet1,"Expanded command line=\"%s\".",p_command); */
+ /* wl_sj(linet1); */
+ wl_sj("S: Unknown command. Type HELP for a list of commands.");
+ num_sev++;
+ goto finished;
+ }
+
+ finished:
+ sumdia();
+ return result;
+}
+
+/******************************************************************************/
+
+LOCAL void interpret P_((FILE *,char *));
+LOCAL void interpret(p_file,filnam)
+/* p_file must be a file opened for reading. The file's name must be supplied */
+/* in filnam for error reporting reasons. The function reads each line from */
+/* the file and feeds it to the FunnelWeb interpreter command executer. */
+FILE *p_file;
+char *filnam;
+{
+ ulong lineno=0;
+ char *result;
+ bool b;
+ cl_t comline;
+ char *p_comline;
+
+ p_comline = &comline[0];
+
+ while (TRUE)
+ {
+ bool oldnoabort = noabort;
+ noabort=FALSE;
+
+ if (p_file == stdin || tracing)
+ wr_sj("FunnelWeb>");
+
+ result=fgets(p_comline,(int) COMLINE_FWMAX,p_file);
+ if (feof(p_file))
+ {
+ sprintf(linet1,"<End of Script File \"%s\">",filnam);
+ if (p_file == stdin || tracing)
+ wl_sj(linet1);
+ break;
+ }
+ if (ferror(p_file) || (result == FGETS_FE))
+ {
+ sprintf(linet1,"F: Error reading command file \"%s\".",filnam);
+ wl_sj(linet1);
+ wl_sj("Aborting...");
+ sum_fat++;
+ return;
+ }
+ if (p_file == stdin || tracing) wr_j(p_comline);
+ if (p_file != stdin && tracing) wr_s(p_comline);
+
+ lineno++;
+ if (strlen(p_comline)==COMLINE_FWMAX)
+ {
+ sprintf(linet1,"F: Line %lu of command file \"%s\" is too long.",
+ (unsigned long) lineno,filnam);
+ wl_sj(linet1);
+ wl_sj("Aborting...");
+ sum_fat++;
+ return;
+ }
+ as_cold(p_comline[strlen(p_comline)-1]==EOL,"interpret: NO NEWLINE!");
+ p_comline[strlen(p_comline)-1]=EOS;
+ as_cold(strlen(p_comline)<COMLINE_FWMAX,"interpret: Filename too long.");
+
+ b=do_command(p_comline);
+ if (b) break;
+
+ if (sum_fat>0) break;
+ if ((p_file != stdin) && (num_sev+num_err>0) && !oldnoabort)
+ {
+ wl_sj("Error caused termination of FunnelWeb shellscript.");
+ break;
+ }
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void interstr(filnam)
+/* The 'interpret' function (above) interprets each line of a file already */
+/* opened for reading. This function does a little more, opening and closing */
+/* the file before and after calling 'interpret'. */
+char *filnam;
+{
+ FILE *p_file;
+ fn_t fn;
+
+ /* Set up a default of ".fws" as a file extension. */
+ strcpy(&fn[0],".fws");
+
+ /* Inherit the actual filename. */
+ as_cold(strlen(filnam)<=FILENAME_FWMAX,"interstr: Filename blasted.");
+ fn_ins(&fn[0],filnam);
+
+ p_file=fopen(fn,"r");
+ if (p_file == FOPEN_F)
+ {
+ sprintf(linet1,"S: Error opening command file \"%s\".",fn);
+ wl_sj(linet1);
+ sum_sev++;
+ return;
+ }
+
+ interpret(p_file,&fn[0]); if (sum_fat>0) return;
+
+ if (fclose(p_file) == FCLOSE_F)
+ {
+ sprintf(linet1,"F: Error closing command file \"%s\".",fn);
+ wl_sj(linet1);
+ wl_sj("Aborting...");
+ sum_fat++;
+ return;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void chk_cline P_((void));
+LOCAL void chk_cline()
+/* Checks to make sure that the command line specifies exactly one action. */
+{
+ uword countopt=0;
+
+ /* Count the number of active action options are turned on. */
+ if (p_comopt->op_f_b) countopt++;
+ if (p_comopt->op_x_b) countopt++;
+ if (p_comopt->op_k_b) countopt++;
+ if (p_comopt->op_h_b) countopt++;
+
+ if (countopt == 0)
+ {
+ wl_sj("Your command line does not specify an action.");
+ wl_sj("Here some common ways of invoking FunnelWeb.");
+ wl_sj("");
+ wl_sj(" fw filename Tangle filename.web.");
+ wl_sj(" fw filename +t Tangle and weave filename.web.");
+ wl_sj(" fw +k Enter interactive mode.");
+ wl_sj(" fw +xfilename Execute FunnelWeb shellscript filename.fws.");
+ wl_sj(" fw +h Display help information about FunnelWeb.");
+ wl_sj("");
+ if (countopt == 0)
+ wl_sj("F: Aborting because command line does not specify an action.");
+ sum_fat++;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void open_j P_((void));
+LOCAL void open_j()
+/* Creates and opens the journal file. Note that the journal output stream is */
+/* established regardless of whether the user requested a journal file. The */
+/* only difference is that if the user did not specify a journal file, the */
+/* stream is created in error mode which means that it never actually writes. */
+{
+ fn_t jname;
+
+ /* Establish the journal file output stream. */
+ strcpy(jname,""); /* Start with an empty string. */
+ fn_ins(jname,p_comopt->op_f_s); /* Insert input file name. */
+ fn_ins(jname,".jrn"); /* Insert file extension. */
+ fn_ins(jname,p_comopt->op_j_s); /* Insert command line spec. */
+ wf_ini(&f_j,p_comopt->op_j_b); /* Initialize the stream. */
+ wf_ope(&f_j,jname); /* Create the file. */
+ if (p_comopt->op_j_b && wf_err(&f_j))
+ {
+ sprintf(linet1,"F: Error creating journal file \"%s\".",jname);
+ wl_s(linet1);
+ wl_s("Aborting...");
+ sum_fat++;
+ return;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void close_j P_((void));
+LOCAL void close_j()
+/* Closes the journal file. */
+{
+ if (!p_comopt->op_j_b) return;
+ if (wf_err(&f_j))
+ {
+ wl_s("F: Error writing to journal file. Aborting...");
+ sum_fat++;
+ return;
+ }
+ wf_clo(&f_j);
+ if (wf_err(&f_j))
+ {
+ wl_s("F: Error flushing and closing journal file. Aborting...");
+ sum_fat++;
+ return;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void cl_help P_((void));
+LOCAL void cl_help ()
+{
+ uword messno;
+
+ /* Translate message name to number. This ought to work, as the options */
+ /* package is already have supposed to have cleared this argument as OK. */
+ messno=hel_num(p_comopt->op_h_s);
+ as_cold(messno!=HL_ERR,"cl_help: Unknown help argument.");
+
+ /* Write out the message. */
+ hel_wri(wr_sj,messno);
+}
+
+/******************************************************************************/
+
+EXPORT void command(p_comline)
+/* Execute the top level command line. This is the place where we do all the */
+/* "once per shell" things as opposed to the "once per run" things. */
+/* If a fatal error occurs, the correct course of action here is to increment */
+/* sum_fat and return immediately. The main() function deals with delivering */
+/* the correct return status to the operating system. */
+char *p_comline;
+{
+ old_war=old_err=old_sev=0;
+
+ tracing=FALSE;
+ noabort=FALSE;
+ skipping=FALSE;
+
+ /* Allocate space for command line arguments. */
+ allocarg();
+
+ /* Set up the standard output (stdout) screen (console) output stream. */
+ wf_ini(&f_s,TRUE);
+ wf_att(&f_s,stdout);
+
+ /* Parse the command line and place the information in p_comopt-> */
+ op_ini(p_comopt);
+ if (!op_add(p_comopt,p_comline,wr_s))
+ {wr_s("F: Command line error. Aborting..."); sum_fat++; goto windup;}
+
+ /* If the user asked for some peace and quiet by setting +Q, disable the */
+ /* console stream. Note: FunnelWeb main() always issues a message using a */
+ /* printf if any diagnostics have been generated. */
+ if (p_comopt->op_q_b) wf_ini(&f_s,FALSE);
+
+ /* Create and open the journal file. */
+ open_j(); if (sum_fat>0) goto windup;
+
+ wl_sj("FunnelWeb Version 3.05AC (Oct 1995)");
+ wl_sj("----------------------**-----------");
+ wl_sj("* Differences from FunnelWeb 3.0 are in `sources/README.ABC'.");
+ wl_sj("* No guarantee can be given that all of the features");
+ wl_sj("* of FunnelWeb 3.05AC will appear in Ross Williams'");
+ wl_sj("* next official release of `FunnelWeb'.");
+ wl_sj("-----------------------------------");
+ wl_sj("Copyright (C) Ross Williams 1992.");
+ wl_sj("Copyright (C) Anthony B. Coates 1995. There is ABSOLUTELY NO WARRANTY.");
+ wl_sj("-----------------------------------");
+ wl_sj("Bug reports to `coates@physics.uq.edu.au'.");
+ wl_sj("You are welcome to distribute this software under certain conditions.");
+ /*
+ wl_sj("THIS IS NOT AN APPROVED VERSION OF FUNNELWEB.");
+ wl_sj("USE ONLY AT OWN RISK. [A.B.Coates]");
+ */
+ if (p_comopt->op_k_b)
+ wl_sj("For more information, type HELP.");
+ else
+ wl_sj("For more information, use the +h (help) option (e.g. \"fw +h\").");
+ wl_sj("");
+
+ /* Ensure that the user has specified at least one action. */
+ chk_cline(); if (sum_fat>0) goto windup;
+
+ /* Establish the default options for the shell run (if any). */
+ /* Get rid of any options not to do with a single run of FunnelWeb proper. */
+ ASSIGN(*p_defopt,*p_comopt);
+ p_defopt->op_j_b=FALSE;
+ p_defopt->op_x_b=FALSE;
+ p_defopt->op_k_b=FALSE;
+
+ /* In the absence of everything else, command line options are run options. */
+ ASSIGN(option,*p_comopt);
+
+ /* Execute initialization file if any. */
+ if (fexists(INITFILE))
+ interstr(INITFILE);
+
+ /* Execute the specified actions. */
+ /* ABC { */
+ batchQ = p_comopt->op_q_b && !strcmp(p_comopt->op_q_s, "b");
+ /* } ABC */
+ if (p_comopt->op_x_b) interstr(p_comopt->op_x_s);
+ if (p_comopt->op_f_b) {zerdia(); fwonerun(); sumdia();}
+ if (p_comopt->op_h_b) cl_help();
+ if (p_comopt->op_k_b) interpret(stdin,"standard_input");
+
+ /* If we weren't in onerun mode, give a grand summary of errors. */
+ if (p_comopt->op_k_b || p_comopt->op_x_b)
+ {
+ wr_sj("Final diagnostics totals: ");
+ errsum(sum_fat,sum_sev,sum_err,sum_war);
+ wl_sj(linet1);
+ }
+
+ /* Close the journal file. */
+ close_j(); if (sum_fat>0) goto windup;
+
+ /* Check for errors on the screen stream (standard output). */
+ if (p_comopt->op_s_b && wf_err(&f_s))
+ {
+ /* No point in trying to write a message to the screen! */
+ /* But we can at least register a fatal error. */
+ sum_fat++;
+ }
+
+ windup:
+
+ /* If the user has set +Q to turn off screen output and one or more */
+ /* diagnostics have been generated, we need to break through to warn the */
+ /* user. */
+ {
+ ulong sum_all=sum_fat+sum_sev+sum_err+sum_war;
+ if (p_comopt->op_q_b && sum_all>0)
+ {
+ errsum(sum_fat,sum_sev,sum_err,sum_war);
+ fprintf(stderr,"%s\n",linet1);
+ }
+ }
+}
+
+/******************************************************************************/
+/* End of COMMAND.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/command.h b/web/funnelAC/fwACsrc/command.h
new file mode 100644
index 0000000000..1419a7c8f8
--- /dev/null
+++ b/web/funnelAC/fwACsrc/command.h
@@ -0,0 +1,61 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* COMMAND.H */
+/******************************************************************************/
+/* */
+/* The command package is the mover and shaker of FunnelWeb. It exports a */
+/* single function, whose argument is the command line given to FunnelWeb */
+/* when it is invoked at the operating system level. The command package */
+/* routine examines the command line and executes it, possibly invoking a */
+/* mini-interpreter or calling the different component of FunnelWeb in turn */
+/* (e.g. the parser). */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+#include "machin.h"
+
+/******************************************************************************/
+
+void command P_((p_cl_t));
+/* Executes the command line which is passed as the argument. */
+
+/******************************************************************************/
+/* End of COMMAND.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/data.c b/web/funnelAC/fwACsrc/data.c
new file mode 100644
index 0000000000..7c96c7d566
--- /dev/null
+++ b/web/funnelAC/fwACsrc/data.c
@@ -0,0 +1,50 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* DATA.C */
+/******************************************************************************/
+
+/* The following definition causes the definitions in data.h to be treated */
+/* as real meaty declarations and not wimpy "external" ones. */
+#define EXTERN
+
+#include "data.h"
+
+/******************************************************************************/
+/* End of DATA.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/data.h b/web/funnelAC/fwACsrc/data.h
new file mode 100644
index 0000000000..248102af96
--- /dev/null
+++ b/web/funnelAC/fwACsrc/data.h
@@ -0,0 +1,684 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 24-Aug-1993 ABC Adjusted ps_t and ln_t structures to carry
+ pointers to a file name.
+ Added new token TK_SPEC for special functions
+ (to be recognised by the parser, not by the
+ scanner).
+ Added SF_... tokens for specifying which special
+ function represented by a TK_SPEC token.
+ Added fnam_t and p_fnam_t types for creating a
+ linked list of input file names.
+ 16-Sep-1993 ABC Changed all constants *_MAX to *_FWMAX to avoid
+ conflict with some standard UNIX constants.
+ 30-Dec-1993 ABC Added global variables `lin_off' and `lin_dep'
+ to support internal `#line' macro.
+ 15-Apr-1994 ABC Added hypertext typesetter types
+ TR_HTXT and TR_HTML, which are to HTML hypertext
+ what TR_NONE and TR_TEX are to TeX respectively.
+ 15-Apr-1994 ABC Added doc_incQ flag for inclusion or not of
+ FunnelWeb TeX/HTML header.
+ 10-May-1994 ABC Added DYN_NAMES option to allow macro and
+ section names to be allocated dynamically
+ instead of statically.
+ 20-May-1994 ABC Added raw_namQ flag for allowing or not of
+ raw TeX/HTML in macro/section names.
+ 28-May-1994 ABC Added no_pmrkQ flag for suppressing the inclusion
+ of `<P>' paragraph markups in hypertext or HTML
+ modes.
+ 16-Jul-1994 ABC Added `aldmname' character pointer for the
+ (optional) name of a macro which is called
+ whenever any other macro is invoked in order to
+ generate line directives.
+ 25-Jul-1995 ABC Changed `aldmname' to a pointer to an array of
+ strings, to allow for multiple source types and
+ hence multiple line directive macro types.
+ 25-Jul-1995 ABC Added `xsrctypes' unsigned integer value to hold
+ the number of extra source code types (if any).
+ 25-Jul-1995 ABC Added `xsrcname' char** value to hold
+ the names of extra source code types (if any).
+ 01-Aug-1995 ABC Added automatic line directive macro pointer to
+ macro definition structure.
+ 01-Aug-1995 ABC Changed `xsrctypes' to a boolean `xsrctypesQ'
+ controlling if extra source code types are
+ allowed or not.
+ 03-Aug-1995 ABC Modified the macro definition structure (md_t) by
+ adding a member which records which automatic
+ line insertion macro to use (if required). This
+ member is only valid for macros which are
+ attached to output files.
+ 10-Aug-1995 ABC Added SF_TMS token for @<#timestamp@> internal
+ macro.
+ 16-Aug-1995 ABC Added `batchQ' boolean to denote batch mode -
+ no interaction at all with user.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* DATA.H */
+/******************************************************************************/
+/* */
+/* This package (data.h, data.c) contains ALL of the global variables in */
+/* FunnelWeb. Some of the FunnelWeb packages (e.g. the lister) harbour hidden */
+/* static state variables which could be considered to be a global variable, */
+/* but, these aside, this package contains all the variables that are used */
+/* directly by more than one package. In many programs, it would likely be */
+/* appropriate to have a separate package for each distinct group of shared */
+/* data so that only those packages needing a particular group of data need */
+/* see it. However, in FunnelWeb's case, the variables are so few, and their */
+/* use so widespread that they are clustered here in one package for all to */
+/* see. */
+/* */
+/* This package also contains type definitions for the central FunnelWeb data */
+/* structures. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_DATA
+#define DONE_DATA
+
+/******************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include "style.h"
+#include "clock.h"
+#include "list.h"
+#include "table.h"
+#include "option.h"
+#include "section.h"
+#include "writfile.h"
+
+/******************************************************************************/
+
+/* ABC { */
+/* Set DYN_NAMES to TRUE to make macro and section names
+ * dynamically allocated. Else, set it to false.
+ */
+#define DYN_NAMES TRUE
+/* } ABC */
+
+/******************************************************************************/
+/* */
+/* DATA TYPES */
+/* ========== */
+/* The following section contains all the data types of the global variables. */
+/* */
+/******************************************************************************/
+
+/* ABC { */
+/* The following structure defines a filename, used to */
+/* identify the file to which each token is connected. */
+typedef
+ struct fnam_t_body /* NEVER declare a `fnam_t_body'!! */
+ {
+ char* fnam_name;
+ struct fnam_t_body *fnam_next;
+ } fnam_t;
+
+typedef fnam_t *p_fnam_t;
+/* } ABC */
+
+/******************************************************************************/
+
+/* The following structure defines a position in the global listing of the */
+/* input data by storing a line number and a column number. The line number */
+/* is a global line number meaning that it increases continuously through */
+/* the lines of included files. The first line is line number 1. The first */
+/* (leftmost) column is column number 1. */
+/* A local line-number for the actual source file and the filename for the */
+/* actual source file are also included for use by internal macros. */
+/* The flag ps_declQ defines whether the position actually exists in the */
+/* global source (this should only be false for internally defined macros. */
+typedef
+ struct
+ {
+ ulong ps_line;
+ ulong ps_column;
+ /* ABC { */
+ ulong ps_localno;
+ p_fnam_t ps_fnam;
+ bool ps_declQ;
+ /* } ABC */
+ } ps_t ;
+
+typedef ps_t *p_ps_t; /* A pointer to a position is handy too! */
+
+/******************************************************************************/
+
+/* A macro name is represented simply as a character array. */
+#define NAME_FWMAX 80
+typedef char name_t[NAME_FWMAX+1];
+/* ABC { */
+#if DYN_NAMES
+typedef char *p_name_t;
+#else /* !DYN_NAMES */
+typedef name_t *p_name_t;
+#endif /* DYN_NAMES */
+/* } ABC */
+
+/******************************************************************************/
+
+/* SC stands for SCrap of text. A scrap of text is a contiguous group of */
+/* printable bytes in memory. The following structure defines such a group by */
+/* storing a pointer to the first and last character of the scrap. */
+/* The scrap must contain at least one character (i.e. sc_last>=sc_first). */
+typedef
+ struct
+ {
+ char *sc_first; /* Pointer to the first byte of the scrap. */
+ char *sc_last; /* Pointer to the last byte of the scrap. */
+ bool sc_white; /* TRUE iff the scrap consists entirely of whitespace. */
+ } sc_t;
+
+typedef sc_t *p_sc_t;
+
+/******************************************************************************/
+
+/* LN stands for LiNe. This record holds global and local line numbers as */
+/* well as a scrap that points to the line in question. The scanner (which */
+/* generates this list) guarantees that the last character of the line scrap */
+/* is an EOL. */
+typedef
+ struct
+ {
+ sc_t ln_body; /* Scrap pointing to the line. Line ends in EOL. */
+ ulong ln_global; /* Global line number of this line. */
+ ulong ln_local; /* Local line number of this line. */
+ /* ABC { */
+ p_fnam_t ln_fnam; /* Local file name for this line. */
+ /* } ABC */
+ } ln_t;
+
+/* The global line list is simply a list of lines of the following type. */
+typedef p_ls_t p_lnls_t;
+
+/******************************************************************************/
+
+/* The following enumerated type identifies a font. */
+#define FT_NORM 1
+#define FT_TITL 2
+#define FT_STIT 3
+
+/* The following enumerated type identifies a horizontal alignment. */
+#define LR_LEFT 1
+#define LR_RIGH 2
+#define LR_CENT 3
+
+/* We want to pack a font and an alignment into the tk_gen byte of the token */
+/* record (we could create a new field, but as none of the other token kinds */
+/* require an extra field, we choose to pack instead. The formula is this: */
+/* Packed byte=LRFT_PACK*FONT+ALIGNMENT. */
+#define LRFT_PACK 10
+
+/******************************************************************************/
+
+/* The following enumerated type identifies the kind of a token. */
+#define TK_TEXT 1 /* Text segment. */
+#define TK_NSEC 2 /* @A..New section. */
+#define TK_MDEF 3 /* @$ Macro definition. */
+#define TK_FDEF 4 /* @F File definition. */
+#define TK_ONAM 5 /* @< Open name. */
+#define TK_CNAM 6 /* @> Close name. */
+#define TK_ODEF 7 /* @{ Open definition. */
+#define TK_CDEF 8 /* @} Close definition. */
+#define TK_OPAR 9 /* @( Open parameter list. */
+#define TK_CPAR 10 /* @) Close parameter list. */
+#define TK_COMA 11 /* @, Comma. */
+#define TK_QUOT 12 /* @" Quote. */
+#define TK_PARM 13 /* @1 Parameter. */
+#define TK_ZERO 14 /* @Z Zero calls allowed. */
+#define TK_MANY 15 /* @M Many calls allowed. */
+#define TK_NAME 16 /* @# Self contained name. */
+#define TK_EMPH 17 /* @/ Emphasize text. */
+#define TK_NPAG 18 /* @t..Newpage. */
+#define TK_TOCS 19 /* @t..Table of contents. */
+#define TK_SKIP 20 /* @t..Vertical skip. */
+#define TK_TITL 21 /* @t..Title text. */
+#define TK_EOF 22 /* End of file. */
+typedef ubyte tk_k_t;
+
+/* The following structure conveys all the information about a single token. */
+/* As well as the kind of token, the parser needs to know where the token is */
+/* in the input file and what the text of the token is if it is a text token. */
+/* Some other tokens have a numeric attribute associated with them and the */
+/* tk_gen field provides a place for this. The attributes are: */
+/* TK_PARM - The number of the parameter [1,9]. */
+/* TK_NAME - The number of the character forming the name [0,255]. */
+/* TK_NSEC - The level of the section [0,5]. 0=@*, 1=@A, 2=@B,..,5=@E. */
+/* TK_SKIP - Number of millimetres to skip vertically [0,255]. */
+/* TK_TITL - Font and alignment packed into byte as specified earlier. */
+/* tk_sc is the text to be set as a title. */
+typedef
+ struct
+ {
+ tk_k_t tk_kind; /* Kind of this token. */
+ ps_t tk_ps; /* Position of the first character of this token. */
+ sc_t tk_sc; /* Scrap constituting token. */
+ ubyte tk_gen; /* General token attribute. */
+ } tk_t;
+
+typedef p_ls_t p_tkls_t; /* A list of tokens. */
+
+/******************************************************************************/
+
+typedef p_ls_t p_scls_t; /* List of scraps. */
+typedef p_ls_t p_scll_t; /* List of list of scraps =TEXT. */
+
+typedef p_ls_t p_ells_t; /* List of pointers to elements = EXPRESSION. */
+typedef p_ls_t p_elll_t; /* List of list of pointers to elements. */
+typedef p_ls_t p_ell3_t; /* List of list of list of pointers to elements. */
+
+/******************************************************************************/
+
+/* This structure's signature is BP for Body Part. FunnelWeb macros can */
+/* be defined in a series of "+=" definitions scattered through the input */
+/* file. The definition of the macro is the concatenation of all the parts. */
+/* The contributory part of a part consists of a single expression. */
+/* Throughout the document, body parts (definition parts) are numbered */
+/* sequentially by a sequence number. */
+typedef
+ struct
+ {
+ p_ells_t bp_ex; /* Expression that is logically appended to definition. */
+ ulong bp_seq; /* Sequence number of body part. */
+ ps_t bp_ps; /* Position at which the definition appears. */
+ } bp_t;
+
+typedef bp_t *p_bp_t;
+
+/* A list of body parts constitutes the full body of a macro. */
+typedef p_ls_t p_bpls_t;
+
+/******************************************************************************/
+
+/* The following structure summarizes a macro CALL. Each macro table entry */
+/* contains a field ma_calls which contains a list of these structures. The */
+/* list is used to generate diagnostics (e.g. if a call has the wrong number */
+/* of parameters) and also to give cross reference information in the typeset */
+/* documentation. */
+typedef
+ struct
+ {
+ ulong mc_seq; /* Sequence number of body part containing call. */
+ ps_t mc_ps; /* Position at which the call occurred. */
+ ulong mc_npar; /* Number of parameters in call. */
+ } mc_t;
+
+typedef mc_t *p_mc_t;
+
+/* A list of calls summarizes the entire usage of a macro in a document. */
+typedef p_ls_t p_mcls_t;
+
+/******************************************************************************/
+
+/* ABC { */
+/* The following define a source code type structure and a list *
+ * of the aforesaid. */
+
+typedef struct {
+ /* sourcetype and auto line directive insertion macro name */
+ char *typnam, *lnmac;
+} srcnmac_t, *p_srcnmac_t, **pp_srcnmac_t;
+
+typedef p_ls_t p_srct_t;
+/* } ABC */
+
+/******************************************************************************/
+
+/* This structure stores the definition of a single macro. The first field */
+/* md_isdef indicates whether a definition for this macro has so far been */
+/* seen. If it has, md_isdef=TRUE and the remaining fields are well defined. */
+typedef
+ struct
+ {
+ bool md_isdef; /* TRUE iff the macro is defined. */
+ ps_t md_ps; /* isdef=> Position of first definition part. */
+ ubyte md_npar; /* isdef=> Number of params specified in defn. */
+ bool md_isadd; /* isdef=> TRUE iff additively defined. */
+ bool md_iszer; /* isdef=> TRUE iff zero calls allowed. */
+ bool md_isman; /* isdef=> TRUE iff many calls allowed. */
+ bool md_isfil; /* isdef=> TRUE iff macro is bound to an outp file. */
+ p_bpls_t md_body; /* isdef=> Body of the macro (list of parts). */
+/* ABC { */
+ p_srcnmac_t md_aldm; /* Automatic line insertion macro. */
+/* } ABC */
+ } md_t;
+
+/******************************************************************************/
+
+/* The following structure contains the full information about a macro. */
+typedef
+ struct
+ {
+/* ABC { */
+#if DYN_NAMES
+ p_name_t ma_name; /* Name of the macro. */
+#else /* !DYN_NAMES */
+ name_t ma_name; /* Name of the macro. */
+#endif /* DYN_NAMES */
+/* } ABC */
+ p_mcls_t ma_calls; /* List of calls of this macro in the document. */
+ md_t ma_defn; /* Definition of this macro. */
+ p_ell3_t ma_actn; /* Used by tangle. List of actual parameter lists. */
+ uword ma_level; /* Used by analyser. Depth of deepest call. */
+ } ma_t;
+
+/* A pointer to the comprehensive macro structure defined above is the way */
+/* that FunnelWeb refers to macros internally. */
+typedef ma_t *p_ma_t;
+
+/******************************************************************************/
+
+/* An expression consists of a sequence of ELEMENTS each of which can */
+/* be one of three kinds: */
+/* */
+/* 1. A block of text. */
+/* 2. An invocation of another macro. */
+/* 3. A parameter of the current macro. */
+/* 4. An invocation of an internal function. */
+/* */
+/* The following enumerated type identifies one of these three alternatives. */
+#define EL_TEXT 1
+#define EL_INVC 2
+#define EL_PARM 3
+/* ABC { */
+#define EL_SPEC 4
+/* } ABC */
+
+typedef ubyte el_k_t;
+
+/* ABC { */
+/* The following enumerated type identifies a particular special function. */
+/* This relates to the element type EL_SPEC. */
+#define SF_ERR 0 /* Error value */
+#define SF_LIN 1 /* Insert current local source line value. */
+ /* an offset to this is settable using the */
+ /* pragma `#line_offset'. */
+#define SF_FIL 2 /* Insert current local source file name. */
+#define SF_TMS 3 /* Insert timestamp. */
+
+typedef ubyte sf_k_t;
+/* } ABC */
+
+/* The following rather messy structure contains information about a single */
+/* element. As mentioned above, an element can be one of three kinds and the */
+/* following structure should, strictly speaking, be defined as a C union so */
+/* as to emphasize the mutually exclusive nature of most of its fields. */
+/* At one stage this structure did contain a union, however, it introduced */
+/* more mess than it brought clarity (because of the extra two subnames) and */
+/* was eventually dropped. */
+/* A few fields deserve some explanation: */
+/* el_pretx and el_postx hold the exact whitespace appearing between */
+/* actual parameters in a macro call. This enables the call to be */
+/* formatted properly in the typeset output. */
+/* el_which is part of the macro parameter element (e.g. @1) and points to */
+/* the macro within which the @1 appears. Strictly speaking this should */
+/* not be necessary, but it is convenient for the tangler to have this */
+/* information when it is half way through expanding an expression. */
+typedef
+ struct /* ABC { */ el_t_body /* NEVER use this name!! */ /* } ABC */
+ {
+ el_k_t el_kind; /* Indicates what kind of element structure holds. */
+
+ p_scls_t el_text; /* EL_TEXT => List of scraps forming a text chunk. */
+
+ p_ma_t el_p_mac; /* EL_INVC => Pointer to macro being invoked. */
+ p_elll_t el_parls; /* EL_INVC => List of actual parameters. */
+ p_scll_t el_pretx; /* EL_INVC => Text before each parameter. */
+ p_scll_t el_postx; /* EL_INVC => Text after each parameter. */
+ struct el_t_body
+ *el_p_par; /* EL_INVC/EL_SPEC => Parent invocation. */
+ p_ma_t el_which; /* EL_PARM => Macro in which this element appears. */
+ ubyte el_parno; /* EL_PARM => Parameter number of this actual param. */
+ sf_k_t el_selec; /* EL_SPEC => Identifies which special function. */
+ ps_t el_ps; /* EL_SPEC => Position where function applies. */
+ } el_t;
+
+typedef el_t *p_el_t;
+
+/******************************************************************************/
+
+/* A document component (represented by the DC_ data structures (see below) */
+/* can be one of three things: a lump of text, a typesetter-generic */
+/* typesetting directive, or a macro definition. The second of these consists */
+/* of a whole collection of typesetting commands and so rather than */
+/* cluttering up the dc_ record, they have been separated out here. */
+#define TY_NSEC 1 /* New section. */
+#define TY_OLIT 2 /* Open literal. */
+#define TY_CLIT 3 /* Close literal. */
+#define TY_OEMP 4 /* Open emphasise. */
+#define TY_CEMP 5 /* Close emphasise. */
+#define TY_NPAG 6 /* New page. */
+#define TY_TOCS 7 /* Table of contents. */
+#define TY_SKIP 8 /* Skip vertical. */
+#define TY_TITL 9 /* Title. */
+typedef ubyte ty_k_t;
+
+typedef
+ struct
+ {
+ ty_k_t ty_kind; /* Kind of this typesetting directive. */
+ sn_t ty_sn; /* TY_NSEC=> Hierarchical section number. */
+ bool ty_isnam; /* TY_NSEC=> TRUE iff the section is named. */
+/* ABC { */
+#ifdef DYN_NAMES
+ p_name_t ty_name; /* TY_NSEC=> ty_isnam=> Name of section. */
+#else /* !DYN_NAMES */
+ name_t ty_name; /* TY_NSEC=> ty_isnam=> Name of section. */
+#endif /* DYN_NAMES */
+/* } ABC */
+
+ uword ty_mm; /* TY_SKIP=> Millimetres to skip. */
+
+ ubyte ty_font; /* TY_TITL=> Font in which to write title. */
+ ubyte ty_align; /* TY_TITL=> Alignment with which to write title. */
+ sc_t ty_sc; /* TY_TITL=> Scrap that is title text. */
+ } ty_t;
+
+typedef ty_t *p_ty_t;
+
+/******************************************************************************/
+
+/* The document list contains a representation of the input document in the */
+/* form in which it was fed to FunnelWeb. This structured representation of */
+/* the input is used by the weaver to generate the typeset output. */
+/* Here, a document is represented by a list of DOCUMENT COMPONENTs (DC) each */
+/* of which contains information about a major chunk of the document. The */
+/* following enumerated type dc_k_t (document component kind type) is used to */
+/* indicate which kind of component each list element contains. */
+#define DC_TEXT 1 /* Text component consists of a block of text. */
+#define DC_TYPE 2 /* Typesettting component affecting document typesetting. */
+#define DC_MACR 3 /* A MACRo definition. */
+typedef ubyte dc_k_t;
+
+/* The following structure stores a single document component. Like the el_t */
+/* type, the dc_t type should really be a union type, but a union construct */
+/* has been avoided to make the naming simpler. */
+typedef
+ struct
+ {
+ ps_t dc_ps; /* Position of this component. */
+ dc_k_t dc_kind; /* Kind of this component. */
+
+ p_scls_t dc_text; /* DC_TEXT=> Text segment constituting this compnt. */
+
+ ty_t dc_ty; /* DC_TYPE=> Typesetting object record. */
+
+ p_ma_t dc_p_ma; /* DC_MACR=> Pointer to the macro defined. */
+ ulong dc_part; /* DC_MACR=> Part number of this part of macro defn. */
+ } dc_t;
+
+typedef dc_t *p_dc_t;
+
+/* A list of document components constitutes the global document list */
+/* declared later. */
+typedef p_ls_t p_dcls_t;
+
+/******************************************************************************/
+
+/* This enumerated type identifies a typesetter. */
+/* TR_NONE - No specific typesetter specified. */
+/* TR_TEX - The TeX typesetter. */
+/* ABC { */
+/* TR_HTXT - No specific typesetter, but hypertext. */
+/* TR_HTML - HTML output, for typesetters such as Mosaic. */
+/* } ABC */
+#define TR_NONE 1
+#define TR_TEX 2
+/* ABC { */
+/* TR_HTXT means convert FunnelWeb typesetting to HTML form. */
+#define TR_HTXT 3
+/* TR_HTML means not to use FunnelWeb typesetting, but assume
+ * that the documentation part of the file is in HTML form
+ * already (in the way the TR_TEX assumes that the documentation
+ * part is in (La)TeX form).
+ */
+#define TR_HTML 4
+/* } ABC */
+/* Add more typesetters here later. */
+typedef ubyte tr_k_t;
+
+
+/******************************************************************************/
+/* */
+/* VARIABLES */
+/* ========= */
+/* This section contains external declarations of the global variables. */
+/* The global variables themselves appear in DATA.C. */
+/* */
+/******************************************************************************/
+
+/* This #ifndef is part of a mechanism that makes the following definitions */
+/* visible to other modules declared as "extern", and visible to data.c */
+/* declared as ordinary declarations. This prevents inconsistencies. */
+#ifndef EXTERN
+#define EXTERN extern
+#endif
+
+/* This global options variable holds the options that were transmitted to */
+/* FunnelWeb proper through the command line. */
+EXTERN GLOVAR op_t option;
+
+/* The following option variable is set by the scanner and is used by the */
+/* tangler. It determines whether the tangler will use natural indenting. */
+/* TRUE => Tangler should use space indenting. FALSE=>No indenting. */
+EXTERN GLOVAR bool tgindent;
+
+/* The following option variable is set by the scanner and is used by the */
+/* tangler. It sets a limit on the length of the lines of the product files */
+/* generated by tangle. A value of TGMAXINF indicates that no checking need */
+/* be performed. */
+#define TGMAXINF (ULONG_MAX)
+EXTERN GLOVAR ulong tglinmax;
+
+/* The following variable is written by the scanner and read by weave. It */
+/* stores the typesetter format possibly specified by the user in the input. */
+EXTERN GLOVAR tr_k_t tr_codes;
+
+/* The following five lists and tables constitute the major data structures */
+/* that are communicated between the major components of FunnelWeb. */
+/* The TOKEN_LIST contains a tokenized representation of the input file. */
+/* The LINE_LIST contains a list of the lines of the input file. */
+/* The DOCUMENT_LIST contains a structured representation of the input file. */
+/* The MACRO_TABLE describes the macros defined in the input file. */
+/* The FILE_TABLE identifies macros that are connected to product files. */
+/* Created By Used By */
+/* ---------- ------- */
+EXTERN GLOVAR p_tkls_t token_list; /* Scanner Parser */
+EXTERN GLOVAR p_lnls_t line_list; /* Scanner Lister */
+EXTERN GLOVAR p_dcls_t document_list; /* Parser Weaver */
+EXTERN GLOVAR p_tb_t macro_table; /* Parser Tangler, Weaver */
+EXTERN GLOVAR p_tb_t file_table; /* Parser Tangler, Weaver */
+
+/* Three output streams are accessible globally. */
+/* The SCREEN FILE is connected to standard output (the user screen). */
+/* The JOURNAL FILE logs FunnelWeb command language transactions. */
+/* The LISTING FILE is created by an single invocation of FunnelWeb proper. */
+EXTERN GLOVAR wf_t f_s; /* Screen file. */
+EXTERN GLOVAR wf_t f_j; /* Journal file. */
+EXTERN GLOVAR wf_t f_l; /* Listing file. */
+
+/* Many of the FunnelWeb IO functions accept a single string as a parameter. */
+/* This means that sprintf and a temporary string must be used in order to */
+/* produce parameterized formatted output. Rather than declare temporary */
+/* strings in each local function, we declare them globally. */
+EXTERN GLOVAR char linet1[2000];
+
+/* Definitions of Diagnostic Levels */
+/* -------------------------------- */
+/* A WARNING has no effect except to cause a message to be issued. */
+/* An ERROR causes FunnelWeb to abort to the shell at the end of the phase. */
+/* Example: An error during scanning means that the FunnelWeb run will */
+/* terminate to the shell at the end of the scanning phase. */
+/* A SEVERE ERROR causes FunnelWeb to abort to the shell immediately. */
+/* A FATAL ERROR causes FunnelWeb to abort to the OS immediately. */
+
+/* The following variables count diagnostics over a single FunnelWeb run. */
+EXTERN GLOVAR ulong num_war; /* Number of warnings. */
+EXTERN GLOVAR ulong num_err; /* Number of errors. */
+EXTERN GLOVAR ulong num_sev; /* Number of severe errors. */
+
+/* The following variables count diagnostics over multiple FunnelWeb runs. */
+EXTERN GLOVAR ulong sum_war; /* Number of warnings. */
+EXTERN GLOVAR ulong sum_err; /* Number of errors. */
+EXTERN GLOVAR ulong sum_sev; /* Number of severe errors. */
+EXTERN GLOVAR ulong sum_fat; /* Number of fatal errors. */
+
+/* ABC { */
+/* Whether the TeX or HTML header should be included or not. */
+EXTERN GLOVAR bool doc_incQ; /* Include TeX/HTML header at weave time */
+EXTERN GLOVAR bool raw_namQ; /* Allow raw TeX/HTML in macro/section names */
+EXTERN GLOVAR bool no_pmrkQ; /* Suppress automatic <P> markups (HTML) */
+EXTERN GLOVAR bool xsrctypesQ; /* Are extra source code types to be allowed? */
+EXTERN GLOVAR p_srct_t srctlist; /* Names of the source code types and the */
+ /* corresponding macros to use for automatic */
+ /* line directive insertion. */
+EXTERN GLOVAR word lin_off; /* line offset for @<#line@> internal macro. */
+EXTERN GLOVAR uword lin_dep; /* unwind depth for @<#line@> internal macro. */
+EXTERN GLOVAR bool batchQ; /* Batch mode - no interaction at all? */
+/* } ABC */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of DATA.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/dump.c b/web/funnelAC/fwACsrc/dump.c
new file mode 100644
index 0000000000..9a1687cb80
--- /dev/null
+++ b/web/funnelAC/fwACsrc/dump.c
@@ -0,0 +1,900 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 31-Aug-1993 ABC Added support for EL_SPEC
+ 10-May-1994 ABC Added DYN_NAMES option to allow macro and
+ section names to be allocated dynamically
+ instead of statically.
+ 06-Aug-1995 ABC Modified the macro definition dump to dump
+ information on the automatic line directive
+ macro, if appropriate.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* DUMP.C */
+/******************************************************************************/
+
+#include <ctype.h>
+#include "style.h"
+
+#include "as.h"
+#include "clock.h"
+#include "data.h"
+#include "dump.h"
+#include "misc.h"
+
+/******************************************************************************/
+
+#define DUMP_WIDTH (80)
+
+/******************************************************************************/
+
+/* The following advance declarations are required because of recursion. */
+LOCAL void dm_ex P_((p_wf_t,p_ells_t));
+
+/******************************************************************************/
+
+LOCAL void centerln P_((p_wf_t,uword,int,char *));
+LOCAL void centerln(p_wf,width,ch,s)
+/* Writes string s in a line surrounded by character ch to specified width. */
+/* Example: centerln(*,20,'-',"sloth") would write: "------ sloth -------" */
+p_wf_t p_wf;
+uword width;
+int ch;
+char *s;
+{
+ uword sidebar,i;
+ char linet2[100];
+ /* Warning: linet2 can't be too big, or it will blow the Mac's limited */
+ /* stack space. Perhaps it should be put in the heap with a static pointer. */
+
+ as_cold(width>=5,"centerln: Width is too small.");
+ as_cold(width<=80,"centerln: Width is too large.");
+ as_cold(strlen(s) <= width-4,"centerln: Width is too narrow for string.");
+
+ /* Construct a sidebar string. */
+ sidebar=(width-strlen(s)-2)/2;
+ for (i=0;i<sidebar;i++) linet2[i]=ch;
+ linet2[sidebar]=EOS;
+
+ /* Now construct the result string. */
+ strcpy(linet1,linet2);
+ strcat(linet1," ");
+ strcat(linet1,s);
+ strcat(linet1," ");
+ strcat(linet1,linet2);
+
+ /* If the sidebar division removed a character, and the line is long enough */
+ /* for the user not to notice the imbalance, tack a character on the end. */
+ if (width>40 && strlen(linet1)==width-1)
+ {
+ uword len=strlen(linet1);
+ linet1[len]=ch;
+ linet1[len+1]=EOS;
+ }
+
+ /* Write the result string to the specified stream. */
+ wf_wl(p_wf,linet1);
+}
+
+/******************************************************************************/
+
+LOCAL char * fontname P_((ubyte));
+LOCAL char * fontname(font)
+/* Given a font number, returns a pointer to a static string containing the */
+/* name of the font. */
+ubyte font;
+{
+ switch (font)
+ {
+ case FT_NORM: return "Normal";
+ case FT_TITL: return "Title";
+ case FT_STIT: return "Small Title";
+ default : as_bomb("fontname: Font switch defaulted.");
+ }
+ /* Keep GCC warnings happy. */
+ as_bomb("fontname: Dropped out of switch.");
+ return "Failure";
+}
+
+/******************************************************************************/
+
+LOCAL char * alignname P_((ubyte));
+LOCAL char * alignname(align)
+/* Given an alignment number, returns a pointer to a static string containing */
+/* the name of the alignment. */
+ubyte align;
+{
+ switch (align)
+ {
+ case LR_LEFT: return "Left";
+ case LR_RIGH: return "Right";
+ case LR_CENT: return "Centre";
+ default : as_bomb("alignname: Alignment switch defaulted.");
+ }
+ /* Keep GCC warnings happy. */
+ as_bomb("alignnamename: Dropped out of switch.");
+ return "Failure";
+}
+
+/******************************************************************************/
+
+EXPORT void dm_mem(p_wf,p_mem,length)
+p_wf_t p_wf;
+char *p_mem;
+ulong length;
+{
+ ubyte_ *p_base = (ubyte_ *) p_mem;
+ long len = length;
+
+ wf_wl(p_wf,"");
+ wf_wl(p_wf,"MEMORY DUMP OF MAPPED FILE");
+ wf_wl(p_wf,"==========================");
+ wf_wl(p_wf,"");
+ wf_wr(p_wf,"+-------------------------------------------------+------------------+\n");
+ wf_wr(p_wf,"| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |\n");
+ wf_wr(p_wf,"+-------------------------------------------------+------------------+\n");
+
+ while (len>0)
+ {/* Write a single line of 16 bytes per iteration. */
+ uword j;
+ wf_wr(p_wf,"| ");
+ for (j=0;j<16;j++)
+ if (j>=len)
+ wf_wr(p_wf," ");
+ else
+ {
+ char s[10];
+ sprintf(s,"%02X ",(unsigned int) p_base[j]);
+ wf_wr(p_wf,s);
+ }
+ wf_wr(p_wf,"| ");
+ for (j=0;j<16;j++)
+ if (j>=len)
+ wf_chr(p_wf,' ');
+ else
+ {
+ char ch=p_base[j];
+ /* DON'T use library function "isprint" - it is too loose. */
+ /* e.g. The vax "isprint" accepts top bit characters. */
+ if (!isascprn(ch)) ch='.';
+ wf_chr(p_wf,ch);
+ }
+ wf_wr(p_wf," |\n");
+ p_base+=16;
+ len-=16;
+ } /* End while */
+
+ wf_wr(p_wf,"+-------------------------------------------------+------------------+\n");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+LOCAL void dm_byte P_((p_wf_t,ubyte));
+LOCAL void dm_byte(p_wf,b)
+/* Dumps a text representation of the given byte to the specified stream. */
+p_wf_t p_wf;
+ubyte b;
+{
+ char t[10];
+ /* DON'T use library function "isprint" - it is too loose. */
+ /* e.g. The vax "isprint" accepts top bit characters. */
+ if (isascprn(b))
+ sprintf(t,"%c",(char) b);
+ else
+ sprintf(t,"<%03u>",(unsigned) b);
+ wf_wr(p_wf,t);
+}
+
+/******************************************************************************/
+
+EXPORT void dm_lnls(p_wf)
+p_wf_t p_wf;
+{
+ wf_wl(p_wf,"");
+ centerln(p_wf,DUMP_WIDTH,'=',"Start of LINE LIST DUMP");
+ wf_wl(p_wf,"");
+ /*12345678901234567890123456789012345678901234567890123456789012345678901234567890*/
+ wf_wl(p_wf,"Globl Local| Text");
+ wf_wl(p_wf,"-----------+--------------------------------------------------------------------");
+ ls_fir(line_list);
+ while (TRUE)
+ {
+ ln_t *p_line;
+ char *p;
+ ls_nxt(line_list,PPV &p_line);
+ if (p_line==NULL) break;
+ sprintf(linet1,"%05lu %05lu| ",
+ (ulong) p_line->ln_global,
+ (ulong) p_line->ln_local);
+ wf_wr(p_wf,linet1);
+ for (p=p_line->ln_body.sc_first; p<=p_line->ln_body.sc_last; p++)
+ dm_byte(p_wf,*((ubyte_ *)p));
+ wf_wl(p_wf,"");
+ }
+ wf_wl(p_wf,"-----------+--------------------------------------------------------------------");
+ wf_wl(p_wf,"Globl Local| Text");
+ wf_wl(p_wf,"");
+ centerln(p_wf,DUMP_WIDTH,'=',"End of LINE LIST DUMP");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+LOCAL void dm_sc P_((p_wf_t,p_sc_t));
+LOCAL void dm_sc(p_wf,p_sc)
+/* Dumps the specified scrap to the specified stream. */
+p_wf_t p_wf;
+p_sc_t p_sc;
+{
+ char *p;
+
+ as_cold(p_sc->sc_first !=NULL,"dm_sc: NULL ptr1.");
+ as_cold(p_sc->sc_last !=NULL,"dm_sc: NULL ptr2.");
+
+ if (p_sc->sc_white)
+ wf_wr(p_wf,"Text scrap[White]=");
+ else
+ wf_wr(p_wf,"Text scrap[Grey]=");
+ wf_wr(p_wf,"\"");
+ for (p=p_sc->sc_first; p<=p_sc->sc_last; p++)
+ {
+ dm_byte(p_wf,*((ubyte_ *) p));
+ if (*p=='\n')
+ wf_wl(p_wf,"");
+ }
+ wf_wl(p_wf,"\"");
+}
+
+/******************************************************************************/
+
+LOCAL void dm_scls P_((p_wf_t,p_scls_t));
+LOCAL void dm_scls(p_wf,p_scls)
+/* Dumps the specified scrap list to the specified stream. */
+p_wf_t p_wf;
+p_scls_t p_scls;
+{
+ wf_wl(p_wf,"");
+ centerln(p_wf,30,'-',"Start of Text Scrap List");
+ ls_fir(p_scls);
+ while (TRUE)
+ {
+ p_sc_t p_sc;
+ ls_nxt(p_scls,PPV &p_sc);
+ if (p_sc==NULL) break;
+ dm_sc(p_wf,p_sc);
+ }
+ centerln(p_wf,30,'-',"End of Text Scrap List");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+EXPORT void dm_tkls(p_wf)
+p_wf_t p_wf;
+{
+ tk_t *token;
+ char *m;
+ ubyte font;
+ ubyte align;
+
+ wf_wl(p_wf,"");
+ centerln(p_wf,DUMP_WIDTH,'=',"Start of TOKEN LIST DUMP");
+ wf_wl(p_wf,"");
+ sprintf(linet1,"Summary: There are %lu tokens in the token list.",
+ (ulong) ls_len(token_list));
+ wf_wl(p_wf,linet1);
+ wf_wl(p_wf,"");
+ wf_wl(p_wf,"Line[Column]: Token Description");
+ wf_wl(p_wf,"-------------------------------");
+ wf_wl(p_wf,"");
+
+ ls_fir(token_list);
+ ls_nxt(token_list,PPV &token);
+ while (token != NULL)
+ {
+ sprintf(linet1,"%04lu[%02lu]: ",
+ (ulong) token->tk_ps.ps_line,
+ (ulong) token->tk_ps.ps_column);
+ wf_wr(p_wf,linet1);
+ switch (token->tk_kind)
+ {
+ case TK_TEXT: m="Text." ; break;
+ case TK_MDEF: m="@$ Macro defn." ; break;
+ case TK_FDEF: m="@F File defn." ; break;
+ case TK_ONAM: m="@< Open name." ; break;
+ case TK_CNAM: m="@> Close name." ; break;
+ case TK_ODEF: m="@{ Open defn." ; break;
+ case TK_CDEF: m="@} Close defn." ; break;
+ case TK_OPAR: m="@( Open param." ; break;
+ case TK_CPAR: m="@} Close param." ; break;
+ case TK_COMA: m="@, Comma." ; break;
+ case TK_QUOT: m="@\" Quote." ; break;
+ case TK_PARM: m="@n Parameter." ; break;
+ case TK_ZERO: m="@Z Zero calls." ; break;
+ case TK_MANY: m="@M Many calls." ; break;
+ case TK_NAME: m="@# Name." ; break;
+ case TK_EMPH: m="@/ Emphasise." ; break;
+ case TK_NPAG: m="@t.. Newpage." ; break;
+ case TK_TOCS: m="@t.. TOC." ; break;
+ case TK_SKIP: m="@t.. Vertical skip."; break;
+ case TK_TITL: m="@t.. Title." ; break;
+ case TK_EOF : m="End Of File." ; break;
+ case TK_NSEC:
+ switch (token->tk_gen)
+ {
+ case 0: m="@* New section (Level 0)."; break;
+ case 1: m="@A New section (Level 1)."; break;
+ case 2: m="@B New section (Level 2)."; break;
+ case 3: m="@C New section (Level 3)."; break;
+ case 4: m="@D New section (Level 4)."; break;
+ case 5: m="@E New section (Level 5)."; break;
+ default: as_bomb("dmtkls: Level case defaulted.");
+ }
+ break;
+ default: as_bomb("dmtkls: Token case defaulted.");
+ }
+ wf_wr(p_wf,m);
+ wf_wr(p_wf," ");
+ switch (token->tk_kind)
+ {
+ case TK_PARM:
+ sprintf(linet1,"Parameterno=%u.",(unsigned) token->tk_gen);
+ wf_wl(p_wf,linet1);
+ break;
+ case TK_NAME:
+ wf_wr(p_wf,"Character='");
+ dm_byte(p_wf,token->tk_gen);
+ wf_wl(p_wf,"'.");
+ break;
+ case TK_TEXT:
+ dm_sc(p_wf,&token->tk_sc);
+ break;
+ case TK_SKIP:
+ sprintf(linet1,"Vertical space skipped=%lumm.",
+ (ulong) token->tk_gen);
+ wf_wl(p_wf,linet1);
+ break;
+ case TK_TITL:
+ font = token->tk_gen / LRFT_PACK;
+ align = token->tk_gen % LRFT_PACK;
+ wf_wr(p_wf,"Font="); wf_wr(p_wf,fontname(font));
+ wf_wr(p_wf,", Alignment="); wf_wr(p_wf,alignname(align));
+ wf_wl(p_wf,". Title text follows:");
+ dm_sc(p_wf,&token->tk_sc);
+ break;
+ default: wf_wl(p_wf,""); break;
+ }
+ ls_nxt(token_list,PPV &token);
+ } /* End of while loop. */
+
+ centerln(p_wf,DUMP_WIDTH,'=',"End of TOKEN LIST DUMP");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+LOCAL void dm_eltx P_((p_wf_t,p_el_t));
+LOCAL void dm_eltx (p_wf,p_el)
+/* Dumps the specified text element to the specified stream. */
+p_wf_t p_wf;
+p_el_t p_el;
+{
+ p_sc_t p_sc;
+
+ wf_wl(p_wf,"");
+ centerln(p_wf,30,'-',"Start Text Element");
+
+ ls_fir(p_el->el_text);
+ ls_nxt(p_el->el_text,PPV &p_sc);
+ while (p_sc != NULL)
+ {
+ dm_sc(p_wf,p_sc);
+ ls_nxt(p_el->el_text,PPV &p_sc);
+ }
+ centerln(p_wf,30,'-',"End Text Element");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+LOCAL void dm_elin P_((p_wf_t,p_el_t));
+LOCAL void dm_elin(p_wf,p_el)
+/* Dumps the specified invocation element to the specified stream. */
+p_wf_t p_wf;
+p_el_t p_el;
+{
+ ulong parno;
+ p_ells_t *pp_ex;
+ p_ells_t p_ex;
+ p_elll_t p_elll = p_el->el_parls;
+
+ wf_wl(p_wf,"");
+ centerln(p_wf,30,'-',"Begin Invocation Element");
+
+/* ABC { */
+ sprintf(
+ linet1,
+ "Invocation of macro @<%s@>",
+ /* ABC { */
+#if DYN_NAMES
+ p_el->el_p_mac->ma_name
+#else /* !DYN_NAMES */
+ &p_el->el_p_mac->ma_name[0]
+#endif /* DYN_NAMES */
+ /* } ABC */
+ );
+/* } ABC */
+ wf_wl(p_wf,linet1);
+
+ if (ls_len(p_elll)==0)
+ wf_wl(p_wf,"No actual parameters.");
+ else
+ {
+ sprintf(linet1,"This invocation has %lu actual parameters.",
+ (ulong) ls_len(p_elll));
+ wf_wl(p_wf,linet1);
+ wf_wl(p_wf,
+ "Actual parameter list follows as a sequence of expressions:");
+ wf_wl(p_wf,"(Text crud before and after parameter has been omitted).");
+ parno=1;
+ ls_fir(p_elll);
+ while (TRUE)
+ {
+ ls_nxt(p_elll,PPV &pp_ex);
+ if (pp_ex==NULL) break;
+ p_ex = *pp_ex;
+ sprintf(linet1,"Expression for parameter number %lu:",(ulong) parno);
+ wf_wl(p_wf,linet1);
+ dm_ex(p_wf,p_ex);
+ parno++;
+ }
+ }
+
+ centerln(p_wf,30,'-',"End Invocation Element");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+LOCAL void dm_elpr P_((p_wf_t,p_el_t));
+LOCAL void dm_elpr(p_wf,p_el)
+/* Dumps the specified parameter element to the specified stream. */
+p_wf_t p_wf;
+p_el_t p_el;
+{
+ wf_wl(p_wf,"");
+ centerln(p_wf,30,'-',"Start Parameter Element");
+ sprintf(linet1,"Parameter number=%lu.",(ulong) p_el->el_parno);
+ wf_wl(p_wf,linet1);
+ /* ABC { */
+ sprintf(
+ linet1,
+ "Parameter is of macro \"%s\".",
+ /* ABC { */
+#if DYN_NAMES
+ p_el->el_which->ma_name
+#else /* !DYN_NAMES */
+ &p_el->el_which->ma_name[0]
+#endif /* DYN_NAMES */
+ /* } ABC */
+ );
+ /* } ABC */
+ wf_wl(p_wf,linet1);
+ centerln(p_wf,30,'-',"End Parameter Element");
+ wf_wl(p_wf,"");
+}
+
+/* ABC { */
+/******************************************************************************/
+
+LOCAL void dm_elsp P_((p_wf_t,p_el_t));
+LOCAL void dm_elsp (p_wf,p_el)
+/* Dumps the specified special function result to the specified stream. */
+p_wf_t p_wf;
+p_el_t p_el;
+{
+ wf_wl(p_wf,"");
+ centerln(p_wf,30,'-',"Start Special Function");
+
+ centerln(p_wf,30,'-',"End Special Function");
+ wf_wl(p_wf,"");
+}
+
+/* } ABC */
+
+/******************************************************************************/
+
+LOCAL void dm_ex(p_wf,p_ex)
+/* Dumps the specified expression to the specified stream. */
+p_wf_t p_wf;
+p_ells_t p_ex;
+{
+ p_el_t p_el;
+
+ wf_wl(p_wf,"");
+ centerln(p_wf,30,'-',"Start of Expression");
+ ls_fir(p_ex);
+ ls_nxt(p_ex,PPV &p_el);
+ while (p_el != NULL)
+ {
+ switch (p_el->el_kind)
+ {
+ case EL_TEXT: dm_eltx(p_wf,p_el); break;
+ case EL_INVC: dm_elin(p_wf,p_el); break;
+ case EL_PARM: dm_elpr(p_wf,p_el); break;
+ /* ABC { */
+ case EL_SPEC: dm_elsp(p_wf,p_el); break;
+ /* } ABC */
+ default : as_bomb("dm_ex: Case defaulted.");
+ }
+ ls_nxt(p_ex,PPV &p_el);
+ }
+ centerln(p_wf,30,'-',"End of Expression");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+LOCAL void dm_macro P_((p_wf_t,p_ma_t));
+LOCAL void dm_macro(p_wf,p_ma)
+/* Dump all the information on the specified macro. */
+p_wf_t p_wf;
+p_ma_t p_ma;
+{
+ wf_wl(p_wf,"");
+ centerln(p_wf,DUMP_WIDTH-20,'-',"Start of Macro Dump");
+
+ /* A macro can't exist in the macro table without a name. */
+ sprintf(linet1,"Macro Name : \"%s\"",p_ma->ma_name); wf_wl(p_wf,linet1);
+
+ /* Is the macro defined? */
+ if (!p_ma->ma_defn.md_isdef) wf_wl(p_wf,"Defined? : No.");
+ else wf_wl(p_wf,"Defined? : Yes.");
+
+ /* Defined macros carry lots more information. */
+ if (p_ma->ma_defn.md_isdef)
+ {
+ /* Number of parameters the macro has. */
+ sprintf(linet1,"Parameters : %lu",(ulong) p_ma->ma_defn.md_npar);
+ wf_wl(p_wf,linet1);
+
+ /* Is the macro additive? */
+ if (p_ma->ma_defn.md_isadd) wf_wl(p_wf,"Additive? : Yes.");
+ else wf_wl(p_wf,"Additive? : No.");
+
+ /* Is the macro allowed to be called zero times? */
+ if (p_ma->ma_defn.md_iszer) wf_wl(p_wf,"Zero Calls? : Yes.");
+ else wf_wl(p_wf,"Zero Calls? : No.");
+
+ /* Is the macro allowed to be called many times? */
+ if (p_ma->ma_defn.md_isman) wf_wl(p_wf,"Many Calls? : Yes.");
+ else wf_wl(p_wf,"Many Calls? : No.");
+
+ /* Is the macro connected to an product file? */
+ if (p_ma->ma_defn.md_isfil) wf_wl(p_wf,"Output File?: Yes.");
+ else wf_wl(p_wf,"Output File?: No.");
+
+/* ABC { */
+ /* Is there an automatic line directive macro? */
+ if (p_ma->ma_defn.md_aldm != NULL) {
+ wf_wl(p_wf,"Automatic Line Directive Macro?: Yes.");
+ wf_wr(p_wf," macro name: ");
+ if (p_ma->ma_defn.md_aldm->lnmac == NULL)
+ wf_wr(p_wf, "NULL");
+ else
+ wf_wr(p_wf, p_ma->ma_defn.md_aldm->lnmac);
+ wf_wr(p_wf,", source type: ");
+ if (p_ma->ma_defn.md_aldm->typnam == NULL)
+ wf_wl(p_wf, "NULL");
+ else
+ wf_wl(p_wf, p_ma->ma_defn.md_aldm->typnam);
+ } else {
+ wf_wl(p_wf,"Automatic Line Directive Macro?: No.");
+ } /* end if */
+/* } ABC */
+
+ /* Dump a list of all the calls to the macro. */
+ {
+ p_mc_t p_mc;
+ ulong mcnum;
+ wf_wl(p_wf,"Call list :");
+ ls_fir(p_ma->ma_calls);
+ ls_nxt(p_ma->ma_calls,PPV &p_mc);
+ mcnum=1;
+ while (p_mc != NULL)
+ {
+ sprintf(linet1,
+ " Call %lu: Parameters=%lu, Sequence num=%lu, Position(L,C)=(%lu,%lu).",
+ (ulong) mcnum,
+ (ulong) p_mc->mc_npar,
+ (ulong) p_mc->mc_seq,
+ (ulong) p_mc->mc_ps.ps_line,
+ (ulong) p_mc->mc_ps.ps_column);
+ wf_wl(p_wf,linet1);
+ ls_nxt(p_ma->ma_calls,PPV &p_mc);
+ mcnum++;
+ }
+ }
+
+ /* Dump a list of the body parts of the macro. */
+ {
+ p_bp_t p_bp;
+ ulong bpnum;
+ ulong bptot = ls_len(p_ma->ma_defn.md_body);
+ wf_wl(p_wf,"Macro body :");
+ wf_wl(p_wf,"");
+ wf_wl(p_wf,"--Start of List of Body Parts--");
+ sprintf(linet1,"This macro has %lu body part",(ulong) bptot);
+ if (bptot!=1) strcat(linet1,"s");
+ strcat(linet1,".");
+ wf_wl(p_wf,linet1);
+ bpnum=1;
+ ls_fir(p_ma->ma_defn.md_body);
+ ls_nxt(p_ma->ma_defn.md_body,PPV &p_bp);
+ while (p_bp != NULL)
+ {
+ sprintf(linet1,
+ "Body part %lu: Seqnum=%lu, Pos(L,C)=(%lu,%lu), Expression follows:",
+ (ulong) bpnum,
+ (ulong) p_bp->bp_seq,
+ (ulong) p_bp->bp_ps.ps_line,
+ (ulong) p_bp->bp_ps.ps_column);
+ wf_wl(p_wf,linet1);
+ dm_ex(p_wf,p_bp->bp_ex);
+ ls_nxt(p_ma->ma_defn.md_body,PPV &p_bp);
+ bpnum++;
+ }
+ wf_wl(p_wf,"---End of List of Body Parts---");
+ wf_wl(p_wf,"");
+ }
+
+ } /* End of IF defined. */
+
+ centerln(p_wf,DUMP_WIDTH-20,'-',"End of Macro Dump");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+EXPORT void dm_matb P_((p_wf_t));
+EXPORT void dm_matb(p_wf)
+p_wf_t p_wf;
+{
+ wf_wl(p_wf,"");
+ centerln(p_wf,DUMP_WIDTH,'=',"Start of MACRO TABLE DUMP");
+ wf_wl(p_wf,"");
+ tb_fir(macro_table);
+ while (TRUE)
+ {
+ name_t name;
+ p_ma_t p_ma;
+ if (!tb_rea(macro_table,PV &name[0],PV &p_ma)) break;
+ dm_macro(p_wf,p_ma);
+ wf_wl(p_wf,"");
+ }
+ wf_wl(p_wf,"");
+ centerln(p_wf,DUMP_WIDTH,'=',"End of MACRO TABLE DUMP");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+LOCAL void dm_ty P_((p_wf_t,p_ty_t));
+LOCAL void dm_ty(p_wf,p_ty)
+p_wf_t p_wf;
+p_ty_t p_ty;
+{
+ char linet2[200];
+ char linet3[200];
+
+ switch (p_ty->ty_kind)
+ {
+ case TY_NSEC:
+ sn_str(&p_ty->ty_sn,linet2);
+ strcpy(linet3,"<No name>");
+ /* ABC { */
+#if DYN_NAMES
+ if (p_ty->ty_isnam) strcpy(linet3,p_ty->ty_name);
+#else /* !DYN_NAMES */
+ if (p_ty->ty_isnam) strcpy(linet3,&p_ty->ty_name[0]);
+#endif /* DYN_NAMES */
+ /* } ABC */
+ sprintf(linet1," Section \"%s\", Section name=\"%s\".",linet2,linet3);
+ wf_wl(p_wf,"");
+ wf_wl(p_wf,linet1);
+ break;
+ case TY_OLIT: wf_wl(p_wf," Open literal." ); break;
+ case TY_CLIT: wf_wl(p_wf," Close literal." ); break;
+ case TY_OEMP: wf_wl(p_wf," Open emphasise." ); break;
+ case TY_CEMP: wf_wl(p_wf," Close emphasise." ); break;
+ case TY_NPAG: wf_wl(p_wf," New page." ); break;
+ case TY_TOCS: wf_wl(p_wf," Table of contents."); break;
+ case TY_SKIP:
+ sprintf(linet1," Vertical skip by %lu mm.",(ulong) p_ty->ty_mm);
+ wf_wl(p_wf,linet1);
+ break;
+ case TY_TITL:
+ wf_wr(p_wf,"Font="); wf_wr(p_wf,fontname(p_ty->ty_font));
+ wf_wr(p_wf,", Alignment="); wf_wr(p_wf,alignname(p_ty->ty_align));
+ wf_wl(p_wf,". Title text follows:");
+ dm_sc(p_wf,&p_ty->ty_sc);
+ break;
+ default: as_bomb("dm_ty: Typesetter directive switch defaulted.");
+ }
+}
+
+/******************************************************************************/
+
+EXPORT void dm_dcls(p_wf)
+/* Dumps a text representation of the document list to the given stream. */
+p_wf_t p_wf;
+{
+ wf_wl(p_wf,"");
+ centerln(p_wf,DUMP_WIDTH,'=',"Start of DOCUMENT LIST DUMP");
+ wf_wl(p_wf,"");
+
+ ls_fir(document_list);
+ while (TRUE)
+ {
+ p_dc_t p_dc;
+ ls_nxt(document_list,PPV &p_dc);
+ if (p_dc == NULL) break;
+ wf_wl(p_wf,"");
+ sprintf(linet1,"Pos(L,C)=(%lu,%lu). ",
+ p_dc->dc_ps.ps_line,
+ p_dc->dc_ps.ps_column);
+ switch (p_dc->dc_kind)
+ {
+ case DC_TEXT:
+ wf_wr(p_wf,"TEXT COMPONENT: "); wf_wl(p_wf,linet1);
+ dm_scls(p_wf,p_dc->dc_text);
+ break;
+
+ case DC_TYPE:
+ wf_wr(p_wf,"TYPESETTER DIRECTIVE COMPONENT: ");
+ dm_ty(p_wf,&p_dc->dc_ty);
+ break;
+
+ case DC_MACR:
+ wf_wr(p_wf,"MACRO DEFINITION COMPONENT: "); wf_wl(p_wf,linet1);
+ /* ABC { */
+ sprintf(linet1,"Part %lu of macro @<%s@>.",
+ p_dc->dc_part,
+#if DYN_NAMES
+ p_dc->dc_p_ma->ma_name
+#else /* !DYN_NAMES */
+ &p_dc->dc_p_ma->ma_name[0]
+#endif /* DYN_NAMES */
+ );
+ /* } ABC */
+ wf_wl(p_wf,linet1);
+ break;
+
+ default: as_bomb("dm_scls: Case defaulted.");
+ }
+ }
+
+ wf_wl(p_wf,"");
+ centerln(p_wf,DUMP_WIDTH,'=',"End of DOCUMENT LIST DUMP");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+LOCAL void tm_for P_((p_wf_t,char *,p_ck_t,p_ck_t));
+LOCAL void tm_for(p_wf,s,p_val,p_tot)
+/* This rather ragged function simplifies the formatting in dm_times. */
+p_wf_t p_wf;
+char *s;
+p_ck_t p_val;
+p_ck_t p_tot;
+{
+ sprintf(linet1,"|%s| %3d%% | %8.2f | %8.2f | %3d%% |",
+ s,
+ (int) ((100.0*ck_cpu(p_val))/ck_cpu(p_tot)),
+ (float) ck_cpu(p_val),
+ (float) ck_real(p_val),
+ (int) ((100.0*ck_real(p_val))/ck_real(p_tot))
+ );
+ wf_wl(p_wf,linet1);
+}
+
+/******************************************************************************/
+
+EXPORT void dm_times(p_wf,
+ p_mapp,p_scan,p_pars,p_anal,
+ p_dump,p_lstr,p_tang,p_weav,p_totl)
+p_wf_t p_wf;
+p_ck_t p_mapp;
+p_ck_t p_scan;
+p_ck_t p_pars;
+p_ck_t p_anal;
+p_ck_t p_dump;
+p_ck_t p_lstr;
+p_ck_t p_tang;
+p_ck_t p_weav;
+p_ck_t p_totl;
+{
+ float cputot;
+ float realtot;
+ float cpuerr;
+ float realerr;
+
+ cputot = ck_cpu(p_mapp) + ck_cpu(p_scan) + ck_cpu(p_pars) +
+ ck_cpu(p_anal) + ck_cpu(p_dump) + ck_cpu(p_lstr) +
+ ck_cpu(p_tang) + ck_cpu(p_weav);
+
+ realtot = ck_real(p_mapp) + ck_real(p_scan) + ck_real(p_pars) +
+ ck_real(p_anal) + ck_real(p_dump) + ck_real(p_lstr) +
+ ck_real(p_tang) + ck_real(p_weav);
+
+ cpuerr = ck_cpu (p_totl)-cputot;
+ realerr = ck_real(p_totl)-realtot;
+
+ wf_wl(p_wf,"");
+ wf_wl(p_wf,"Summary of time used by each subsystem of Funnelweb (seconds).");
+ wf_wl(p_wf,"");
+ wf_wl(p_wf, "+------------+------+----------+----------+------+");
+ wf_wl(p_wf, "| Subsystem | CPU% | CPU Time | RealTime | RT% |");
+ wf_wl(p_wf, "+------------+------+----------+----------+------+");
+ tm_for(p_wf," Mapper ",p_mapp,p_totl);
+ tm_for(p_wf," Scanner ",p_scan,p_totl);
+ tm_for(p_wf," Parser ",p_pars,p_totl);
+ tm_for(p_wf," Analyser ",p_anal,p_totl);
+ tm_for(p_wf," Dumper ",p_dump,p_totl);
+ tm_for(p_wf," Lister ",p_lstr,p_totl);
+ tm_for(p_wf," Tangler ",p_tang,p_totl);
+ tm_for(p_wf," Weaver ",p_weav,p_totl);
+ sprintf(linet1,"|%s| %3d%% | %8.2f | %8.2f | %3d%% |",
+ " Clock Err ",
+ (int) ((100.0*cpuerr )/ck_cpu (p_totl)),
+ (float) cpuerr,
+ (float) realerr,
+ (int) ((100.0*realerr)/ck_real(p_totl))
+ );
+ wf_wl(p_wf,linet1);
+
+ wf_wl(p_wf, "+------------+------+----------+----------+------+");
+ tm_for(p_wf," Total ",p_totl,p_totl);
+ wf_wl(p_wf, "+------------+------+----------+----------+------+");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+/* End of DUMP.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/dump.h b/web/funnelAC/fwACsrc/dump.h
new file mode 100644
index 0000000000..a02222428f
--- /dev/null
+++ b/web/funnelAC/fwACsrc/dump.h
@@ -0,0 +1,78 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* DUMP.H */
+/******************************************************************************/
+/* */
+/* This package contains functions that dump text representations of */
+/* FunnelWeb data structures. Each function accepts a wf stream on which it */
+/* writes its text representation. These functions are used in testing and */
+/* debugging only and are not used ordinarily in the program. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "clock.h"
+#include "writfile.h"
+
+/******************************************************************************/
+
+EXPORT void dm_mem P_((p_wf_t,char *,ulong));
+/* Writes a hex and ascii dump of the specified block of memory to the */
+/* specified stream. */
+
+EXPORT void dm_lnls P_((p_wf_t));
+/* Dumps a text representation of the global line list to the given stream. */
+
+EXPORT void dm_tkls P_((p_wf_t));
+/* Dumps a text representation of the global token list to the given stream. */
+
+EXPORT void dm_matb P_((p_wf_t));
+/* Dumps a text representation of the macro table to the given stream. */
+
+EXPORT void dm_dcls P_((p_wf_t));
+/* Dumps a text representation of the document list to the given stream. */
+
+EXPORT void dm_times P_((p_wf_t,p_ck_t,p_ck_t,p_ck_t,p_ck_t,
+ p_ck_t,p_ck_t,p_ck_t,p_ck_t,p_ck_t));
+/* Dumps a text representation of the execution times to the given stream. */
+
+/******************************************************************************/
+/* End of DUMP.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/environ.h b/web/funnelAC/fwACsrc/environ.h
new file mode 100644
index 0000000000..daad4f871c
--- /dev/null
+++ b/web/funnelAC/fwACsrc/environ.h
@@ -0,0 +1,316 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+ JMS John Max Skaller maxtal@suphys.physics.su.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 16-Sep-1993 ABC Added machine type OSF64 for a 64-bit processor
+ running OSF/1 (particularly the DEC AXP).
+ 14-Dec-1993 ABC Added machine type OS2 for PCs running OS/2 2.1.
+ 15-Jun-1994 ABC Added machine type LINUX for PCs running
+ LINUX 1.1.8
+ 18-Sep-1994 ABC Added NO_FCASE definition for file systems
+ (like DOS and OS/2) which are case insensitive.
+ 13-Aug-1995 JMS Added PC32 type for 32-bit DOS-extended code.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* ENVIRON.H */
+/******************************************************************************/
+/* */
+/* WARNING: DO NOT ADD ANY PROGRAM-DEPENDENT DEFINITIONS. */
+/* */
+/* This header file environ.h contains definitions and objects whose values */
+/* depends directly on the compilation and execution environment, but are */
+/* otherwise independent of any particular computer program. */
+/* */
+/* This is one of two machine-dependent, program-independent modules. The */
+/* other module is machin (machin.h,machin.c). This "environ" module contains */
+/* definitions and objects that are considered essential. The "machin" module */
+/* contains less essential definitions. Motivation for the division came from */
+/* the fact that style.h (used by almost every module) includes environ.h */
+/* (this file), and from the need for the stuff in style.h by some */
+/* environment-dependent definitions. */
+/* */
+/* There seems to be two ways to organize a module such as this one. The */
+/* first is to have a different version of this module for each target */
+/* environment. The second is to have a single file that uses #defines and */
+/* #ifs to select between code for each target environment. I have chosen the */
+/* latter method as this allows many different environments to share the same */
+/* definitions. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_ENVIRON
+#define DONE_ENVIRON
+
+/******************************************************************************/
+
+/* Select An Environment */
+/* --------------------- */
+/* Choose the environment in which the program will be compiled and executed. */
+/* This may be the only change you need to make to get FunnelWeb to compile. */
+/* */
+/* If your exact environment is not listed, try one that is close. */
+/* If problems arise, an attempt should be made to solve them */
+/* without creating a new environment definition. However, if this is not */
+/* possible, define a new environment below and "implement" it by going */
+/* through environ.h and machin.h and machin.c and adding appropriate */
+/* definitions. */
+/* */
+/* The following table lists real/defined environment pairs under which */
+/* FunnelWeb is known to compile cleanly. */
+/* */
+/* Symbol = Processor Machine OS Compiler */
+/* ------ --------- ------- -- -------- */
+/* MAC = 68000 Macintosh-SE Mac THINK-C V4.0.5 */
+/* SUN = SPARC SUN ELC Unix(SunOS) GNUC */
+/* VMS = VAX VAXStation VMS VAXC */
+/* PC = 386 IBM PC Clone MSDOS5.0 Borland C++ */
+/* ABC { */
+/* OSF64 = 64bit e.g. DEC AXP Unix(OSF/1) c89 */
+/* OS2 = 32bit IBM PC Clone OS/2 2.1 GNUC (emx 0.8h) */
+/* LINUX = 32bit IBM PC Clone Linux 1.1.8 GNUC */
+/* } ABC */
+/* JMS { */
+/* PC32 = 32bit IBM PC Clone DOS EXTENDER Borland C++ */
+/* } JMS */
+/* */
+/* Set exactly one of the following environments to 1, the others to 0. */
+
+#define MAC 0
+#define SUN 0
+#define VMS 0
+#define PC 0
+/* ABC { */
+#define OSF64 1
+#define OS2 0
+#define LINUX 0
+/* } ABC */
+/* JMS { */
+#define PC32 0
+/* } JMS */
+/* Ensure that exactly one environment has been selected. */
+/* ABC/JMS { */
+#if MAC+SUN+VMS+PC+OSF64+OS2+LINUX+PC32 != 1
+/* } ABC/JMS */
+ #error Error: You must choose exactly one machine in ENVIRON.H.
+#endif
+
+/******************************************************************************/
+
+/* Establish Presence or Absence of __STDC__ */
+/* ----------------------------------------- */
+/* The __STDC__ symbol is very useful for determining if the compiler is */
+/* ANSI. However, some "nearly ANSI" compilers don't set this symbol, and */
+/* experience shows that things turn out better if it is set. */
+/* This section decides if __STDC__ should be defined. */
+
+/* The Macintosh THINK C compiler seems to be ANSI standard but, strangely */
+/* does not define the standard preprocessor symbol __STDC__ that indicates */
+/* this. Instead it defines THINK_C. Here, we execute the link manually. */
+/* For more information see the THINK C User's Manual, Chapter 57: "Language */
+/* Reference", Section 12.10, p.442. */
+#ifdef THINK_C
+#define __STDC__ 1
+#endif
+
+/* The problem seems to exist with VAX C too. */
+#if VMS
+#define __STDC__ 1
+#endif
+
+/******************************************************************************/
+
+/* Switch From Definedness to Boolean Symbols */
+/* ------------------------------------------ */
+/* Use of the definedness of a preprocessor symbol to detect a condition is */
+/* convenient if it is desired that only one condition be tested at a time. */
+/* However, if we want to OR conditions, it is more convenient to use defined */
+/* symbols that are either 0 or 1. This section contains ifdefs that do this. */
+
+#ifdef __STDC__
+#define STDC 1
+#else
+#define STDC 0
+#endif
+
+/* Note: If THINK_C is predefined, it is predefined to be 1. */
+#ifndef THINK_C
+#define THINK_C 0
+#endif
+
+/******************************************************************************/
+
+/* Void */
+/* ---- */
+/* Define void if necessary and define pointer to void. */
+/* This idea from the book "Portable C", p.41. */
+/* If necessary, add a boolean condition to cover your environment. */
+/* Note: The "| SUN" is a last minute desperate hack. */
+#if STDC | SUN
+typedef void *p_void;
+#else
+typedef int void;
+typedef char *p_void;
+#endif
+
+/* The following function is here solely to act as a first tripping point for */
+/* environments with no "void" so that the users trying to port this code */
+/* will look here first instead of starting to delete voids in the program. */
+extern void test_void();
+
+/******************************************************************************/
+
+/* Const */
+/* ----- */
+/* It's useful to be able to specify that certain objects are constants. */
+/* Unfortunately, the "const" construct is only available in ANSI C and so we */
+/* have to have a macro so as to cope with non-ANSI compilers. */
+/* Note: THINK-C is nearly ANSI, but does not support "const". */
+#if STDC & !THINK_C
+#define CONST const
+#else
+#define CONST
+#endif
+
+/******************************************************************************/
+
+/* Prototypes */
+/* ---------- */
+/* Define a macro to wrap around prototype parameter lists so as to support */
+/* compilers with and without prototypes. */
+/* This idea came from the book "Portable C", S3.1, p.32. */
+#if STDC
+#define P_(A) A
+#else
+#define P_(A) ()
+#endif
+
+/******************************************************************************/
+
+/* Structure Assignments */
+/* --------------------- */
+/* Structure assignments are not supported on some of the older compilers and */
+/* so we use a macro to perform such operations. */
+/* This idea came from the book "Portable C", S8.2.2, p.184. */
+#if STDC
+#define ASSIGN(a,b) ((a)=(b))
+#else
+#define ASSIGN(a,b) (memcpy((char *)&(a),(char *)&(b),sizeof(a)))
+#endif
+
+/******************************************************************************/
+
+/* VMS EXIT STATUS */
+/* --------------- */
+/* The VAX C compiler I used doesn't seem to be ANSI. This means that the */
+/* exit symbols aren't set up properly. Furthermore, the sensible defaults */
+/* in the style.h file don't work for VMS. The upshot is that we have to do */
+/* a special case. Note: The top bit set in a VMS exit status means suppress */
+/* diagnostic message. Even status means failure. Odd means success. */
+#if VMS
+#undef EXIT_SUCCESS
+#undef EXIT_FAILURE
+#define EXIT_SUCCESS 1
+#define EXIT_FAILURE (0x10000002)
+#endif
+
+/******************************************************************************/
+/* ABC { */
+/* MACHINE DEPENDENT TYPEDEFS */
+/* -------------------------- */
+/* These are used in `style.h'. */
+typedef int int_t;
+typedef short short_t;
+#if !OSF64
+/* General types, taken from OSF/1 definitions */
+typedef char char_t;
+typedef long long_t;
+typedef unsigned char uchar_t, uchar;
+#if LINUX
+#include <linux/types.h>
+typedef ushort ushort_t;
+typedef unsigned int uint_t;
+typedef ulong ulong_t;
+#else /* !LINUX */
+typedef unsigned short ushort_t, ushort;
+typedef unsigned int uint_t, uint;
+typedef unsigned long ulong_t, ulong;
+#endif /* LINUX */
+
+#if defined(_LONGLONG)
+typedef long long longlong_t, longlong;
+typedef unsigned long long ulonglong_t, ulonglong;
+#else
+typedef long longlong_t, longlong;
+typedef unsigned long ulonglong_t, ulonglong;
+#endif
+
+typedef void *pointer;
+typedef double double_t;
+typedef float float_t;
+#endif /* !OSF64 */
+/* } ABC */
+
+/******************************************************************************/
+/* ABC { */
+/* Case insensitive filesystems */
+/* ============================ */
+/* Some filesystems, like those of DOS and OS/2, are case *
+ * insensitive (although OS/2 HPFS file systems preserve *
+ * the case of filenames, they consider two file names *
+ * which only differ in case to refer to the same file. *
+ * The NO_FCASE definition tells FunnelWeb to compare *
+ * file macro names in a case-insensitive manner to match *
+ * the way the file system works. */
+
+/* NOTE: case-insensitive filename checking is not yet *
+ * implemented. */
+
+#if PC || PC32 || OS2
+#define NO_FCASE=1
+#endif /* PC || PC32 || OS2 */
+
+/* } ABC */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of ENVIRON.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/err.status b/web/funnelAC/fwACsrc/err.status
new file mode 100644
index 0000000000..aac6d3cb99
--- /dev/null
+++ b/web/funnelAC/fwACsrc/err.status
@@ -0,0 +1 @@
+1 Severe error, 271 Errors and 10 Warnings : Different = 23
diff --git a/web/funnelAC/fwACsrc/fw-latex.sty b/web/funnelAC/fwACsrc/fw-latex.sty
new file mode 100644
index 0000000000..2d35861581
--- /dev/null
+++ b/web/funnelAC/fwACsrc/fw-latex.sty
@@ -0,0 +1,327 @@
+%* Last edited: Apr 8 15:20 1993 (richard)
+%=================== Start of FunnelWeb LaTeX Definitions ====================
+
+
+% Version
+% -------
+% This is FunnelWeb LaTeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb LaTeX definitions was written by Richard Walker
+% and Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. It isn't now.
+
+
+% Modification
+% ------------
+% Please record all modifications to these LaTeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+% RJW Richard Walker richard@cs.anu.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+% 6 April 1993 RJW Started work on LaTeX definitions
+%
+
+% Please send bug reports to Richard at the above email address.
+
+
+% General Comments
+% ----------------
+% This set of LaTeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb LaTeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\renewcommand"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells LaTeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the LaTeX file through
+% LaTeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+%% I don't like indentation as it makes the page look more busy. Instead,
+%% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% I *do* like indentation. RJW
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\newcommand{\fwparskipon}{\parskip=\medskipamount}
+\newcommand{\fwparskipoff}{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows LaTeX to leave a bit of space at the
+% bottom of the page in order to better vertically align the rest of
+% the page (e.g. skips won't stretch as much). It also means that
+% headings are less likely to be isolated at the bottom of the page
+% without any following text.
+
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\newcommand{\fwfontnote}{\scriptsize}
+
+\newcommand{\fwfontnorm}{\normalsize}
+\newcommand{\fwfontnorma}{\large}
+\newcommand{\fwfontnormb}{\Large}
+
+\newcommand{\fwfontbold}{\normalsize\bf}
+\newcommand{\fwfontbolda}{\large\bf}
+\newcommand{\fwfontboldb}{\Large\bf}
+\newcommand{\fwfontboldc}{\LARGE\bf}
+\newcommand{\fwfontboldd}{\huge\bf}
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\newcommand{\fwbeginmacro}{\fwparskipoff\bigbreak}
+\newcommand{\fwendmacro}{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\newcommand{\fwmacroname}[2]{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\newcommand{\fwfilename}[2]{{\bf #1}$\lbrack$#2$\rbrack$}
+\newcommand{\fwzero}[1]{{\bf Z}}
+\newcommand{\fwmany}[1]{{\bf M}}
+\newcommand{\fwequals}{ $\equiv$}
+\newcommand{\fwplusequals}{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\newcommand{\fwodef}{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\newcommand{\fwcdef}{$\rbrace$\vskip0pt\parindent=0pt}
+\newcommand{\fwoquote}{`}
+\newcommand{\fwcquote}{'}
+\newcommand{\fwoparen}{$($}
+\newcommand{\fwcomma}{$,$}
+\newcommand{\fwcparen}{$)$}
+\newcommand{\fwparam}[1]{$\diamond #1$}
+\newcommand{\fwparams}[1]{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\newcommand{\fwbeginmacronotes}{\begingroup\baselineskip=9pt\smallbreak}
+\newcommand{\fwnote}[1]{{\fwfontnote #1}\par}
+\newcommand{\fwisafile}[1]{\fwnote{#1}}
+\newcommand{\fwusedin}[1]{\fwnote{#1}}
+\newcommand{\fwseealso}[1]{\fwnote{#1}}
+\newcommand{\fwendmacronotes}{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main LaTeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% LaTeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because LaTeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that LaTeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make LaTeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\newcommand{\fwrule}{\medskip\hrule\medskip}
+\newcommand{\fwqh}{\hskip1.5em\relax}
+\newcommand{\fwbeforesec}{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\newcommand{\fwtocstart}[1]{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\newcommand{\fwtoca}[2]{\leftline{{\bf #1 #2}}}
+\newcommand{\fwtocb}[2]{\leftline{\fwqh #1 #2}}
+\newcommand{\fwtocc}[2]{\leftline{\fwqh\fwqh #1 #2}}
+\newcommand{\fwtocd}[2]{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\newcommand{\fwtoce}[2]{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\newcommand{\fwtocfinish}[1]{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\newcommand{\fwliba}[2]{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\newcommand{\fwlibb}[2]{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\newcommand{\fwlibc}[2]{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\newcommand{\fwlibd}[2]{\fwbeforesec{\bf #1 #2}\penalty200}
+\newcommand{\fwlibe}[2]{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\newcommand{\fwseca}[2]{\section{#2}}
+\newcommand{\fwsecb}[2]{\fwlibb{#1}{#2}}
+\newcommand{\fwsecc}[2]{\fwlibc{#1}{#2}}
+\newcommand{\fwsecd}[2]{\fwlibd{#1}{#2}}
+\newcommand{\fwsece}[2]{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\newcommand{\fwlit}[1]{{\tt #1}}
+\newcommand{\fwemp}[1]{{\it #1}}
+
+% The "@p new_page" pragma.
+\newcommand{\fwnewpage}{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\newcommand{\fwvskip}[1]{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\newcommand{\fwfontnormal}[1]{{\fwfontnorm {#1}}}
+\newcommand{\fwfonttitle}[1]{{\fwfontboldd {#1}}}
+\newcommand{\fwfontsmalltitle}[1]{{\fwfontboldb {#1}}}
+\newcommand{\fwleftline}[1]{\leftline{#1}}
+\newcommand{\fwcenterline}[1]{\centerline{#1}}
+\newcommand{\fwrightline}[1]{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\newcommand{\p}[1]{{\tt #1}} % P for Program text.
+\newcommand{\flagpage}[2]{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb LaTeX Definitions ===================
diff --git a/web/funnelAC/fwACsrc/fw.def b/web/funnelAC/fwACsrc/fw.def
new file mode 100644
index 0000000000..3984db6c35
--- /dev/null
+++ b/web/funnelAC/fwACsrc/fw.def
@@ -0,0 +1,3 @@
+NAME FW WINDOWCOMPAT
+DESCRIPTION 'FunnelWeb Literate Programming Tool'
+STACKSIZE 0x80000
diff --git a/web/funnelAC/fwACsrc/fwmem.c b/web/funnelAC/fwACsrc/fwmem.c
new file mode 100644
index 0000000000..26a8434998
--- /dev/null
+++ b/web/funnelAC/fwACsrc/fwmem.c
@@ -0,0 +1,371 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 10-May-1994 ABC Added MEMTOTALS debugging option.
+ 08-Aug-1995 ABC Changed include file name from "memory.h"
+ to "fwmem.h" to avoid a clash with the C++
+ standard header file "memory.h".
+ Similarly, changed the name of this file to
+ "fwmem.c".
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* FWMEM.C */
+/******************************************************************************/
+/* */
+/* Implementation Overview */
+/* ----------------------- */
+/* One of the tasks of this Memory Management (MM) package is to keep track */
+/* of the memory that it has allocated so that it can all be deallocated */
+/* later, in one go. To do this, the package keeps a linked list whose */
+/* elements describe the blocks allocated. Two linked lists are kept, one for */
+/* temporary blocks and one for permanent blocks. Only the list for the */
+/* temporary blocks is used for deallocation. Permanent blocks are arranged */
+/* in a list so that the code for temporary blocks is also applicable. */
+/* */
+/* In order to avoid many calls to malloc() for small blocks of memory */
+/* (legend has it that some implementations of malloc() are very slow in this */
+/* case), the MM package keeps a spare temporary and permanent block of */
+/* length MM_BLOCK from which it allocates small blocks. Small is defined as */
+/* <=MM_BLOCK/16. A separate malloc call is made for "Large" blocks greater */
+/* than MM_BLOCK bytes. "Large" blocks less than MM_BLOCK bytes may or may */
+/* not be allocated from a buffer block, depending on how much space is */
+/* available. See the code for the full details. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "as.h"
+#include "machin.h"
+#include "fwmem.h"
+
+/******************************************************************************/
+
+/* The environ.h file contains a definition for ALIGN_POWER which is the */
+/* exponent of the power of two corresponding to the machine's alignment */
+/* requirements. The following two constants convert that constant to more */
+/* useful forms. These definitions should never need to be changed. */
+#define ALIGN_SIZE (1L<<ALIGN_POWER)
+#define ALIGN_MASK (ALIGN_SIZE-1)
+
+/* Because standard malloc() can be slow on some systems for large numbers of */
+/* calls requesting small blocks of memory, FunnelWeb's memory management */
+/* package MM_* allocates memory in sizeable blocks and then allocates */
+/* smaller blocks from these big blocks without reference to malloc(). The */
+/* following #define tells the MM package how big the sizeable allocated */
+/* blocks should be. The rule is then: if the requested block is greater than */
+/* MM_BLOCK/16, allocate it directly using malloc(), otherwise peel off some */
+/* memory from the latest sizeable block allocated. */
+/* In practice, MM_BLOCK should be chosen to be about 1/10 to 1/20 of the */
+/* memory available to FunnelWeb. The disadvantage of making it big is that */
+/* when memory is tight, MM will be unable to allocate a full block and about */
+/* half a block of memory will be unusable. The disadvantage of making it too */
+/* small is that the linked lists tracking memory allocations will grow long */
+/* and it will take a long time to free up memory between invocations of */
+/* FunnelWeb proper. The value is not critical. A value of 31K should work */
+/* well on most systems. 31K is chosen instead of 32K just to be on the safe */
+/* side of 16 bits (so who's paranoid?). */
+#define MM_BLOCK (31L*1024L)
+
+/* This definition provides the definition of the size of a "big" block; that */
+/* is, one that should possibly be treated differently from the others. */
+/* The rule we use is that a big block is 1/16 of the standard block size. */
+/* This results in a maximum memory wastage of 1/16 or about 7%. */
+#define MM_BIG (MM_BLOCK >> 4)
+
+/* Magic numbers help us to detect corruptions. */
+#define MAGIC_HEAD (83716343L)
+#define MAGIC_TAIL (11172363L)
+
+/* Set MEMTRACE to TRUE to trace all memory operations. */
+#define MEMTRACE FALSE
+
+/* ABC { */
+#if MEMTRACE
+#define MEMTOTALS TRUE
+#else /* !MEMTRACE */
+/* Set MEMTOTALS to TRUE to see block memory allocations and total */
+#define MEMTOTALS FALSE
+#endif /* MEMTRACE */
+/* } ABC */
+
+/******************************************************************************/
+
+/* The following structures define a type for the linked lists that keep */
+/* track of the allocated blocks. */
+typedef struct mm_t_
+ {
+ ulong mm_mhead; /* Magic number protecting beginning of record. */
+ ubyte_ *mm_pblok; /* Pointer to the allocated block. */
+ ubyte_ *mm_pfree; /* Pointer to next free byte in block (ALIGNED). */
+ ulong mm_nfree; /* Number of unused bytes available in the block. */
+ struct mm_t_ *mm_pnext; /* Pointer to the header for the next block. */
+ ulong mm_mtail; /* Magic number protecting end of record. */
+ } mm_t;
+
+typedef mm_t *p_mm_t; /* Handy to have a pointer type too. */
+
+/* The following two local variables point to the head of the temporary and */
+/* permanent block lists. The first block in each list is that list's buffer. */
+LOCVAR p_mm_t p_perm = NULL;
+LOCVAR p_mm_t p_temp = NULL;
+
+/******************************************************************************/
+
+LOCAL void mm_check P_((p_mm_t));
+LOCAL void mm_check(p_mm)
+/* Checks the magic numbers in the specified block header object. */
+p_mm_t p_mm;
+{
+ as_cold(p_mm!=NULL,"mm_check: Null pointer.");
+ as_cold(p_mm->mm_mhead==MAGIC_HEAD,"mm_check: Corrupted header.");
+ as_cold(p_mm->mm_mtail==MAGIC_TAIL,"mm_check: Corrupted trailer.");
+}
+
+/******************************************************************************/
+
+LOCAL void mm_align P_((p_mm_t));
+LOCAL void mm_align(p_mm)
+/* Some machines are very fussy about the memory alignment of allocated */
+/* objects. To solve this problem, the mm_pfree pointer is always kept at an */
+/* "aligned" address. This function accepts a pointer to the header of a */
+/* block whose mm_pfree pointer is possibly unaligned and consumes bytes */
+/* until mm_pfree is aligned. */
+p_mm_t p_mm;
+{
+ ubyte bump;
+ ubyte consume;
+
+ mm_check(p_mm);
+
+ /* Work out how many bytes are sticking out over the alignment boundary. */
+ bump = ((ulong) p_mm->mm_pfree) & ALIGN_MASK;
+
+ /* Return if the block is already aligned. */
+ if (bump==0) return;
+
+ /* Otherwise work out how many bytes we have to consume to become realigned. */
+ consume=ALIGN_SIZE-bump;
+
+ /* If there are not enough bytes left in the block to allow the free pointer */
+ /* to be aligned, then simply set the available bytes to zero and return. It */
+ /* doesn't matter if we don't achieve alignment in this case as if */
+ /* mm_nfree==0, nothing can ever be allocated at the misaligned address. */
+ if (consume>p_mm->mm_nfree) {p_mm->mm_nfree=0; return;}
+
+ /* Consume the bytes required to align the free pointer. */
+ p_mm->mm_pfree += consume;
+ p_mm->mm_nfree -= consume;
+
+ /* Check that we have properly aligned the free pointer. */
+ as_cold((((ulong) p_mm->mm_pfree) & ALIGN_MASK)==0,
+ "mm_align: Failed to align.");
+}
+
+/******************************************************************************/
+
+LOCAL p_mm_t mm_newblk P_((size_t));
+LOCAL p_mm_t mm_newblk(blk_len)
+/* Creates a new block containing (after alignment) at least blk_len bytes. */
+/* Returns a pointer to the header for the block. */
+size_t blk_len;
+{
+ p_mm_t p_mm;
+ ubyte_ *p_bl;
+#if MEMTOTALS
+ STAVAR ulong total_mem = 0;
+ ulong alloc_size;
+#endif /* MEMTOTALS */
+
+ /* Allocate the header and the block itself. Because we are guaranteeing */
+ /* that the resultant block will have at least blk_len bytes free, we have */
+ /* to take into account alignment and add in ALIGN_SIZE when requesting mem. */
+ p_mm=(p_mm_t ) malloc((size_t) sizeof(mm_t));
+ p_bl=(ubyte_ *) malloc((size_t) (blk_len+ALIGN_SIZE));
+ if (p_mm==NULL || p_bl==NULL)
+ {
+ fprintf(stderr,"mm_newblk: Out of memory!\n");
+ fprintf(stderr,"FunnelWeb doesn't cope well when it runs out of memory.\n");
+ fprintf(stderr,"It falls in a heap just as it is about to now.\n");
+ as_bomb("Stand by for an ungraceful termination!");
+ }
+
+ /* Fill in the fields of the block header. */
+ p_mm->mm_mhead = MAGIC_HEAD;
+ p_mm->mm_pblok = p_bl;
+ p_mm->mm_pfree = p_bl;
+ p_mm->mm_nfree = blk_len+ALIGN_SIZE;
+ p_mm->mm_pnext = NULL;
+ p_mm->mm_mtail = MAGIC_TAIL;
+
+ /* Align the free pointer in the header block. */
+ mm_align(p_mm);
+
+#if MEMTOTALS
+ alloc_size = sizeof(mm_t)+blk_len+ALIGN_SIZE;
+ printf(
+ "TRACE: mm_newblk: Allocated %lu bytes of memory.\n",
+ alloc_size
+ );
+ total_mem += alloc_size;
+ printf(
+ "TRACE: mm_newblk: Total allocated: %lu bytes.\n",
+ total_mem
+ );
+#endif /* MEMTOTALS */
+
+ /* Return a pointer to the header block we created. */
+ return p_mm;
+}
+
+/******************************************************************************/
+
+LOCAL p_void mm_alloc P_((p_mm_t *,size_t));
+LOCAL p_void mm_alloc(pp_mm,bytes)
+/* 'pp_mm' must be a pointer to either p_perm or p_temp. */
+/* 'bytes' is the number of bytes required. */
+/* Allocates the required memory and returns an aligned pointer to it. */
+/* Bombs the program if the memory is not available. */
+p_mm_t *pp_mm;
+size_t bytes;
+{
+ p_mm_t p_from; /* Pointer to header for block from which we finally alloc.*/
+ ubyte_ *p_result; /* The result pointer returned to the caller. */
+
+ /* If the list is empty, create a "buffer block" and put it in the list. */
+ if (*pp_mm==NULL) *pp_mm=mm_newblk((size_t) MM_BLOCK);
+
+ /* If there is room in the current buffer block, we can allocate directly. */
+ /* Note that we may be allocating a "big" block here, but as long as it fits */
+ /* into the free space of the current buffer block, we don't care. */
+ if ((*pp_mm)->mm_nfree >= bytes) {p_from = *pp_mm; goto dole_out;}
+
+ /* At this point we know that there is not enough space in the current */
+ /* buffer block. This could mean that we have an extra big allocation on our */
+ /* hands in which case, we should malloc up a block specially for this */
+ /* request. It could also mean that we are running out of space in our */
+ /* buffer block in which case a new one must be allocated. */
+ if (bytes >= MM_BIG)
+ {
+ /* If the request is BIG, allocate a special block for it and insert the */
+ /* block in the block list just after the buffer block, leaving the */
+ /* buffer block the first in the block list. */
+ p_mm_t p_tmp=mm_newblk(bytes);
+ p_tmp->mm_pnext=(*pp_mm)->mm_pnext;
+ (*pp_mm)->mm_pnext=p_tmp;
+ p_from=p_tmp;
+ }
+ else
+ {
+ /* If the request is not big, our buffer block is probably too empty and */
+ /* so it is time to create a new one. Allocate a new buffer block and */
+ /* make it the new head of this block list. Note that by giving up on the */
+ /* previous buffer, we waste at most 1/16 of the block we are giving up */
+ /* on. This cost is reasonable in exchange for all the speed this gives. */
+ p_mm_t p_tmp=mm_newblk((size_t) MM_BLOCK);
+ p_tmp->mm_pnext=(*pp_mm);
+ (*pp_mm)=p_tmp;
+ p_from=p_tmp;
+ }
+
+ dole_out:
+ /* Jump here to dole out 'bytes' bytes from block 'p_from'. */
+ p_result=p_from->mm_pfree;
+ p_from->mm_pfree += bytes;
+ p_from->mm_nfree -= bytes;
+ mm_align(p_from);
+
+ /* Ensure that the pointer being returned is properly aligned. */
+ as_cold((((ulong) p_result) & ALIGN_MASK)==0,
+ "mm_alloc: Result is misaligned.");
+
+ /* Return the result. */
+ return (p_void) p_result;
+}
+
+/******************************************************************************/
+
+EXPORT p_void mm_perm(bytes)
+size_t bytes;
+{
+#if MEMTRACE
+ printf("TRACE: mm_perm: Allocating %lu bytes of permanent memory.\n",
+(ulong) bytes);
+#endif
+ return mm_alloc(&p_perm,bytes);
+}
+
+/******************************************************************************/
+
+EXPORT p_void mm_temp(bytes)
+size_t bytes;
+{
+#if MEMTRACE
+ printf("TRACE: mm_temp: Allocating %lu bytes of temporary memory.\n",
+(ulong) bytes);
+#endif
+ return mm_alloc(&p_temp,bytes);
+}
+
+/******************************************************************************/
+
+EXPORT void mm_zapt()
+/* This function frees all the memory blocks recorded in the temporary */
+/* memory list. We choose to free them rather than merely re-using them */
+/* directly because they may not all be the same size, and we want to give */
+/* the built-in memory manager a chance to smooth out the heap. */
+{
+#if MEMTRACE
+ printf("TRACE: mm_zapt: Attempting to release all temporary memory.\n");
+#endif
+
+ while (p_temp != NULL)
+ {
+ p_mm_t p_mm=p_temp;
+ mm_check(p_temp);
+#if MEMTRACE
+ printf("TRACE: mm_zapt: Deallocating a big chunk of temporary memory.\n");
+#endif
+ free(p_temp->mm_pblok);
+ p_temp=p_temp->mm_pnext;
+ free(p_mm);
+ }
+}
+
+/******************************************************************************/
+/* End of FWMEM.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/fwmem.h b/web/funnelAC/fwACsrc/fwmem.h
new file mode 100644
index 0000000000..44dd8615c7
--- /dev/null
+++ b/web/funnelAC/fwACsrc/fwmem.h
@@ -0,0 +1,116 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 08-Aug-1995 ABC Changed the file name from "memory.h"
+ to "fwmem.h" to avoid a clash with the C++
+ standard header file "memory.h".
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* FWMEM.H */
+/******************************************************************************/
+/* */
+/* Introduction */
+/* ------------ */
+/* This package provides a memory management facility for FunnelWeb. */
+/* The conventional MALLOC does not suit the needs of FunnelWeb. The */
+/* following notes give an idea of why: */
+/* */
+/* 1. At the times where FunnelWeb requires memory, it is nearly always */
+/* the case that failure to provide the memory should result in a bomb. */
+/* It therefore makes sense to wrap MALLOC up inside another function */
+/* that, at the very least, checks the status from malloc and bombs */
+/* the program if the requested memory is not available. */
+/* */
+/* 2. Because FunnelWeb proper can be invoked an indefinite number of */
+/* times from the FunnelWeb command interpreter, it is very important */
+/* to reclaim all the memory used by each invocation. This could be */
+/* done by explicitly tearing apart the data structures constructed */
+/* for each run. However, this is very messy, requiring detailed */
+/* knowledge of the data structures. A far simpler, safer scheme is to */
+/* arrange for a memory manager to keep track of all the memory that it */
+/* allocates and to provide a single call to free it all. This facility */
+/* is provided by this package. */
+/* */
+/* 3. In addition to the TEMPORARY memory allocations described in (2) above, */
+/* it should also be possible to make permanent allocations. */
+/* */
+/* 4. FunnelWeb uses linked lists a lot and hence will make many requests */
+/* for small chunks of memory (e.g 10 bytes). Legend has it that some */
+/* malloc libraries are very inefficient in this case, and that it is */
+/* better to use malloc to allocate a large chunk of memory and dole it */
+/* out yourself. This package does this too. */
+/* */
+/* For all these reasons, FunnelWeb memory management has been handed over to */
+/* this package which provides services that satisfy the conditions outlined */
+/* above. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_MEMORY
+#define DONE_MEMORY
+
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+EXPORT p_void mm_perm P_((size_t));
+/* Allocates a block of memory of the specified size (specified in bytes) and */
+/* returns a pointer to the new block of memory. Bombs the program if the */
+/* memory is not available. Memory allocated using mm_perm is permanently */
+/* allocated and cannot be freed. */
+
+EXPORT p_void mm_temp P_((size_t));
+/* Allocates a block of memory of the specified size (specified in bytes) and */
+/* returns a pointer to the new block of memory. Bombs the program if the */
+/* memory is not available. Memory allocated using this function can later be */
+/* freed in its entirely by making a call to mm_zapt. */
+
+EXPORT void mm_zapt P_((void));
+/* This function can be called at any time. Its effect is to free up all the */
+/* memory allocated using mm_temp since the last call to mm_zapt or the start */
+/* of the program, whichever is the more recent. */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of FWMEM.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/fwtest.cmd b/web/funnelAC/fwACsrc/fwtest.cmd
new file mode 100644
index 0000000000..007a1231d5
--- /dev/null
+++ b/web/funnelAC/fwACsrc/fwtest.cmd
@@ -0,0 +1,5 @@
+@echo off
+rem FunnelWeb test sequence
+cd ..\scripts
+..\fwACsrc\fw +xmaster
+cd ..\fwACsrc
diff --git a/web/funnelAC/fwACsrc/help.c b/web/funnelAC/fwACsrc/help.c
new file mode 100644
index 0000000000..f4e554790d
--- /dev/null
+++ b/web/funnelAC/fwACsrc/help.c
@@ -0,0 +1,631 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 16-Sep-1993 ABC Changed all constants *_MAX to *_FWMAX to avoid
+ conflict with some standard UNIX constants.
+ 20-Jul-1995 ABC Modified program name to reflect
+ release of FunnelWeb 3.01AC.
+ 08-Aug-1995 ABC Modified program name to reflect
+ release of FunnelWeb 3.02AC.
+ 10-Aug-1995 ABC Modified program name to reflect
+ release of FunnelWeb 3.03AC.
+ 16-Aug-1995 ABC Added support for batch mode (no interaction
+ with user) via `+Qb' command switch.
+ 16-Aug-1995 ABC Modified program name to reflect
+ release of FunnelWeb 3.04AC.
+ 19-Sep-1995 ABC Modified program name to reflect
+ release of FunnelWeb 3.05AC.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* HELP.C */
+/******************************************************************************/
+/* */
+/* REPRESENTING MESSAGES AS C CODE */
+/* =============================== */
+/* Experience has shown that it is much more reliable to code text messages */
+/* into a program than to expect the program to track down text files */
+/* containing the messages at run time. Worthwhile for smallish files (such */
+/* as these help messages) at least. For this reason, most the messages in */
+/* this module are represented by code (e.g. as in printf statements). */
+/* */
+/* The only exception is the 18K Gnu license message which is a bit too big */
+/* to be done by hand. It has been moved to the help_gnu module. */
+/* */
+/******************************************************************************/
+
+#include <ctype.h>
+#include "style.h"
+
+#include "as.h"
+#include "help.h"
+#include "help_gnu.h"
+#include "misc.h"
+#include "option.h"
+
+/******************************************************************************/
+
+/* This module contains many many output statements that call an output */
+/* function. To neaten up all these calls, we define a global variable to */
+/* hold a pointer to the function and simple macro to write output using */
+/* the function. */
+LOCVAR void (*pf) P_((char *));
+
+#define WX(STR) (*pf)(STR)
+
+/******************************************************************************/
+
+LOCAL void hel_men P_((void));
+LOCAL void hel_men ()
+{
+ WX("\n");
+ WX("FunnelWeb Help Messages\n");
+ WX("-----------------------\n");
+ WX("Introduction - Introduction to FunnelWeb.\n");
+ WX("DOcumentation - How to obtain FunnelWeb documentation.\n");
+ WX("Options - Command line options.\n");
+ WX("DEfoptions - Default command line options.\n");
+ WX("COMmands - Interactive commands.\n");
+ WX("Registration - How to register as an \"official\" FunnelWeb user.\n");
+ WX("Support - How you can help support FunnelWeb development.\n");
+ WX("COPyright - Copyright notice.\n");
+ WX("License - The license under which this software is distributed (long).\n");
+ WX("Nowarranty - Extract from the GNU license concerning lack of warranty.\n");
+ WX("DIstribution - Extract from the GNU license concerning distribution.\n");
+ WX("MOdification - Read this message if you intend to modify FunnelWeb.\n");
+ WX("Versions - A list of existing versions of FunnelWeb.\n");
+ WX("Acknowledge - Thanks to people who helped with FunnelWeb development.\n");
+ WX("MEnu - The message you are reading (the default help message).\n");
+ WX("\n");
+ WX("To display a message, give its (optionally abbreviated) name in a help command.\n");
+ WX("To capture a message to a file, add +J<filename> to the fw command. Examples:\n");
+ WX("\n");
+ WX(" fw +Hintroduction +Jintro.txt -- From the operating system level.\n");
+ WX(" help introduction -- From FunnelWeb interactive mode.\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_int P_((void));
+LOCAL void hel_int ()
+{
+ WX("\n");
+ WX("FunnelWeb Introduction\n");
+ WX("----------------------\n");
+ WX("Welcome to FunnelWeb, a literate-programming macro preprocessor.\n");
+ WX("\n");
+ WX("Traditional computer programs are primarily written for computers and consist\n");
+ WX("of code laced with comments. In contrast, literate programs are primarily\n");
+ WX("written for humans and consist of comments laced with code. While simple, the\n");
+ WX("effect of this inversion can be so profound as to change one's whole approach\n");
+ WX("to programming. The literate programmer focuses on conveying meaning to other\n");
+ WX("intelligent beings rather than merely convincing the computer to behave in a\n");
+ WX("particular way. It is the difference between performing and exposing a magic\n");
+ WX("trick.\n");
+ WX("\n");
+ WX("FunnelWeb is a production-quality literate-programming tool that emphasises\n");
+ WX("simplicity and reliability. It provides a macro facility, and assists in the\n");
+ WX("production of typeset documentation. FunnelWeb runs on most popular machines\n");
+ WX("(Sun, VAX, Mac, PC) and its highly portable source code in C is freely\n");
+ WX("available under a GNU license.\n");
+ WX("\n");
+ WX("To get started with FunnelWeb, obtain a printed copy of the \"FunnelWeb User's\n");
+ WX("Manual\" (see the \"DOCUMENTATION\" help message). Read the introduction and work\n");
+ WX("through the tutorial. The manual contains an overview of FunnelWeb, an\n");
+ WX("introductory tutorial, and a comprehensive reference manual. Try it!\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_opt P_((void));
+LOCAL void hel_opt ()
+{
+ WX("\n");
+ WX("FunnelWeb Command Line Options\n");
+ WX("------------------------------\n");
+ WX("Options are of the form (\"+\" | \"=\" | \"-\") <letter> [<string>].\n");
+ WX("+ turns on an option. - turns it off. = doesn't affect it's onoffedness.\n");
+ WX("The case (e.g. upper or lower) of <letter> does not matter.\n");
+ WX("<string> is usually a filename or directory, but sometimes a number.\n");
+ WX("Convention: f=filename, n=decimal number, h=help message name.\n");
+ WX("\n");
+ WX("Example: fw sloth +L +Jaardvark.xxx +W80 -Q =Twalrus.tex\n");
+ WX("\n");
+ WX("Action options: (choose at least one when you invoke FunnelWeb from the OS).\n");
+ WX("If you choose more than one, they will be executed in the order given here.\n");
+ WX(" +Xf Execute specified Funnelweb script.\n");
+ WX(" +Ff Process specified input file.\n");
+ WX(" +Hh Display specified help message.\n");
+ WX(" +K Invoke FunnelWeb's interative mode.\n");
+ WX("\n");
+ WX("Other options:\n");
+ WX(" +B1 Diagnostic: Dump image of input file to listing file.\n");
+ WX(" +B2 Diagnostic: Dump scanner's line list to listing file.\n");
+ WX(" +B3 Diagnostic: Dump scanner's token list to listing file.\n");
+ WX(" +B4 Diagnostic: Dump parser's macro table to listing file.\n");
+ WX(" +B5 Diagnostic: Dump parser's document list to listing file.\n");
+ WX(" +B6 Diagnostic: Dump time breakdown report to listing file.\n");
+ WX(" +B7 Diagnostic: Suppress non-deterministic output.\n");
+ WX(" +Cn Number of lines of context around diagnostics in listing file.\n");
+ WX(" +D Delete each output file identical to its previous version.\n");
+ WX(" +If Default file specification for include files.\n");
+ WX(" +Jf Generate journal file. Default file specification.\n");
+ WX(" +Lf Generate listing file. Default file specification.\n");
+ WX(" +Of Generate product files. Default file specification.\n");
+ WX(" +Q Quiet mode. Only really important messages displayed on console.\n");
+ /* ABC { */
+ WX(" +Qb Batch mode. No interaction with user via console.\n");
+ /* } ABC */
+ WX(" +Tf Generate typesetter file. Default file specification.\n");
+ WX(" +Sn Send errors to console with specified number of lines of context.\n");
+ WX(" +Wn Set maximum length of lines in product files.\n");
+ WX("\n");
+ WX("If an option appears more than once, the rightmost one dominates.\n");
+ WX("For more detailed information, refer to the FunnelWeb User's Manual.\n");
+ WX("For default values refer to the \"DEFOPTIONS\" help message.\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_dop P_((void));
+LOCAL void hel_dop ()
+{
+ op_t defop;
+
+ WX("\n");
+ WX("FunnelWeb Default Option Settings\n");
+ WX("---------------------------------\n");
+ WX("These are the settings FunnelWeb STARTS UP with.\n");
+ op_ini(&defop);
+ WX("\n");
+ op_wri(&defop,pf);
+ WX("\n");
+ WX("See the OPTIONS help message for a brief description of these options.\n");
+ WX("For more detailed information, refer to the FunnelWeb User's Manual.\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_com P_((void));
+LOCAL void hel_com ()
+{
+ WX("\n");
+ WX("FunnelWeb Interactive Commands\n");
+ WX("------------------------------\n");
+ WX(" ! - Comment. Ignores the whole line. \n");
+ WX(" ABSENT fn - Aborts if specified file exists. \n");
+ WX(" CODIFY ftext fC - Convert text file into C code to write text. \n");
+ WX(" COMPARE f1 f2 - Aborts if two files are different. \n");
+ WX(" DEFINE n \"text\" - Defines $n to translate to text. \n");
+ WX(" DIFF f1 f2 logf [ABORT] - Writes differences between f1 and f2 to logf.\n");
+ WX(" - Severe if different and ABORT is present. \n");
+ WX(" DIFFSUMMARY - Summary of differences done since DIFFZERO. \n");
+ WX(" DIFFZERO - Zeros differences counters. \n");
+ WX(" ENEO fn - Establish Non Existence Of file. \n");
+ WX(" EXECUTE fn - Execute commands in specified file. \n");
+ WX(" EXISTS fn - Aborts if file does not exist. \n");
+ WX(" FIXEOLS fn [outf] - Fixes up EOL markers in specified file. \n");
+ WX(" FW options - Invoke FunnelWeb-proper once. \n");
+ WX(" HELP [name] - Displays specified help message. \n");
+ WX(" HERE - Terminates effect of SKIPTO command. \n");
+ WX(" QUIT - Quits FunnelWeb. \n");
+ WX(" SET options - Sets options. \n");
+ WX(" SHOW - Displays currently active options. \n");
+ WX(" SKIPTO - Ignore commands until HERE command. \n");
+ WX(" STATUS - Write out status and diagnostic counts. \n");
+ WX(" STATUS [Sn] [En] [Wn] - Aborts if status is not as specified. \n");
+ WX(" TOLERATE - Don't abort script if next commmand gens err.\n");
+ WX(" TRACE ON | OFF - Turns command tracing ON or OFF. \n");
+ WX(" WRITE \"text\" - Writes specified text to screen and journal. \n");
+ WX(" WRITEU \"text\" - Same as WRITE but underlines text. \n");
+ WX("\n");
+ WX("More detailed information can be found in the FunnelWeb User's Manual.\n");
+ WX("\n");
+ WX("Most of these commands were created to support regression testing and\n");
+ WX("can be ignored by most users. In fact most users will never need to invoke\n");
+ WX("FunnelWeb's interactive mode at all. If you are just getting started\n");
+ WX("with FunnelWeb, it's probably best to run FunnelWeb directly from your\n");
+ WX("command interface and ignore the +K command line option for now.\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_doc P_((void));
+LOCAL void hel_doc ()
+{
+ WX("\n");
+ WX("FunnelWeb Documentation\n");
+ WX("-----------------------\n");
+ WX("The following FunnelWeb documentation is available:\n");
+ WX("\n");
+ WX(" \"FunnelWeb User's Manual\": Tutorial, Hints, Reference Manual.\n");
+ WX(" \"FunnelWeb Hacker's Manual\": Notes on Design and Implementation.\n");
+ WX("\n");
+ WX("Everyone involved with FunnelWeb should read the User's Manual.\n");
+ WX("It contains everything you need to learn how to use FunnelWeb.\n");
+ WX("\n");
+ WX("The Hacker's Manual is for those who want to install, modify, fix,\n");
+ WX("fiddle with, and generally hack the FunnelWeb C source code.\n");
+ WX("\n");
+ WX("Both of these manuals are shipped with the FunnelWeb distribution\n");
+ WX("kit, and should be available on your machine in the form of LaTeX text\n");
+ WX("files. If you cannot find them, you can obtain them by FTP from:\n");
+ WX("\n");
+ WX(" Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3].\n");
+ WX(" Directory: ~pub/funnelweb/ (or a directory of similar name).\n");
+ WX("\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_reg P_((void));
+LOCAL void hel_reg ()
+{
+ WX("FunnelWeb Registration\n");
+ WX("----------------------\n");
+ WX("If you install or use FunnelWeb, please fill in and return this form:\n");
+ WX("\n");
+ WX(" +----------------------FunnelWeb Registration Form----------------------+\n");
+ WX(" | 1. Date: |\n");
+ WX(" | 2. Title and name: |\n");
+ WX(" | 3. Internet email address: |\n");
+ WX(" | 4. Snail mail address: |\n");
+ WX(" | 5. Work phone number (country,area,number): |\n");
+ WX(" | 6. Which category of FunnelWeb user best describes you? |\n");
+ WX(" | Latent - Installed FunnelWeb, but don't intend to use it. |\n");
+ WX(" | Beginner - Haven't used FunnelWeb much yet; have an open mind. |\n");
+ WX(" | Casual - Use FunnelWeb occasionally. |\n");
+ WX(" | Convert - Use FunnelWeb to do most programming. |\n");
+ WX(" | Fanatic - FunnelWeb has become a way of life. |\n");
+ WX(" | 7. What changes or new features would you like to see in FunnelWeb? |\n");
+ WX(" | 8. Do you want to be kept informed of new FunnelWeb developments? |\n");
+ WX(" | 9. Email this form to \"ross@spam.adelaide.edu.au\", OR snail mail to |\n");
+ WX(" | Ross Williams, 16 Lerwick Avenue, Hazelwood Park 5066, Australia. |\n");
+ WX(" +-----------------------------------------------------------------------+\n");
+ WX("To write this form to a file, use \"fw +hreg +jregform.txt\".\n");
+ WX("You may wish to make a contribution when you register. See SUPPORT.\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_cop P_((void));
+LOCAL void hel_cop ()
+{
+ WX("\n");
+ WX("FunnelWeb Copyright\n");
+ WX("-------------------\n");
+ WX("Copyright (C) 1992 Ross Williams.\n");
+ WX("\n");
+ WX("However, FunnelWeb has been released by the author and copyright owner Ross\n");
+ WX("Williams (ross@spam.adelaide.edu.au) under Version 2 of the GNU General Public\n");
+ WX("License published by the Free Software Foundation. This means that you can\n");
+ WX("redistribute FunnelWeb and/or modify it under the terms of the license.\n");
+ WX("\n");
+ WX("Note: This program is distributed WITHOUT ANY WARRANTY; without even the\n");
+ WX("implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
+ WX("\n");
+ WX("The following help messages provide further information:\n");
+ WX("\n");
+ WX(" License - The license under which this software is distributed (long).\n");
+ WX(" DIstribution - Extract from the GNU license concerning distribution.\n");
+ WX(" Nowarranty - Extract from the GNU license concerning lack of warranty.\n");
+ WX(" MOdification - Read this message if you intend to modify FunnelWeb.\n");
+ WX(" Registration - How to register as an \"official\" FunnelWeb user.\n");
+ WX("\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_now P_((void));
+LOCAL void hel_now ()
+{
+ WX("\n");
+ WX("FunnelWeb Comes With No Warranty\n");
+ WX("--------------------------------\n");
+ WX("Here is an extract from the GNU General Public License Version 2, under which\n");
+ WX("FunnelWeb is distributed. See help message \"LICENSE\" for the full license.\n");
+ WX("\n");
+ WX(" 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n");
+ WX(" FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n");
+ WX(" OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n");
+ WX(" PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n");
+ WX(" OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n");
+ WX(" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n");
+ WX(" TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n");
+ WX(" PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n");
+ WX(" REPAIR OR CORRECTION.\n");
+ WX("\n");
+ WX(" 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n");
+ WX(" WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n");
+ WX(" REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n");
+ WX(" INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n");
+ WX(" OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n");
+ WX(" TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n");
+ WX(" YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n");
+ WX(" PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n");
+ WX(" POSSIBILITY OF SUCH DAMAGES.\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_dis P_((void));
+LOCAL void hel_dis ()
+{
+ WX("\n");
+ WX("FunnelWeb Distribution\n");
+ WX("----------------------\n");
+ WX("The following is an extract from the GNU General Public License Version 2,\n");
+ WX("under which FunnelWeb is distributed.\n");
+ WX("\n");
+ WX(" 1. You may copy and distribute verbatim copies of the Program's\n");
+ WX(" source code as you receive it, in any medium, provided that you\n");
+ WX(" conspicuously and appropriately publish on each copy an appropriate\n");
+ WX(" copyright notice and disclaimer of warranty; keep intact all the\n");
+ WX(" notices that refer to this License and to the absence of any warranty;\n");
+ WX(" and give any other recipients of the Program a copy of this License\n");
+ WX(" along with the Program.\n");
+ WX("\n");
+ WX(" You may charge a fee for the physical act of transferring a copy, and\n");
+ WX(" you may at your option offer warranty protection in exchange for a fee.\n");
+ WX("\n");
+ WX("The license also allows you other freedoms. For more information refer\n");
+ WX("to the full text of the license in the help message \"LICENSE\".\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_ack P_((void));
+LOCAL void hel_ack ()
+{
+ WX("\n");
+ WX("FunnelWeb Acknowledgements\n");
+ WX("--------------------------\n");
+ WX("The following people assisted with the preparation of FunnelWeb V3.0.\n");
+ WX("\n");
+ WX("Many thanks go to DAVID HULSE (dave@cs.adelaide.edu.au) who translated the 1986\n");
+ WX("version of FunnelWeb (V1) written in Ada into a public domain C version (V2).\n");
+ WX("The C code written by David formed the basis of V3 of FunnelWeb, but was\n");
+ WX("entirely rewritten during the intensive refinement and feature-injection\n");
+ WX("period leading up to this release (V3 is about 3 times the size of V2).\n");
+ WX("\n");
+ WX("Thanks go to SIMON HACKETT (simon@internode.com.au) of Internode Systems\n");
+ WX("Pty Ltd for the use of his Sun, Mac, and PC, for assistance in porting\n");
+ WX("FunnelWeb to the Sun and PC, and for helpful discussions.\n");
+ WX("\n");
+ WX("Thanks go to JEREMY BEGG (jeremy@vsm.com.au) of VSM Software Services\n");
+ WX("for the use of his VAX, and for assistance with the VMS-specific code.\n");
+ WX("\n");
+ WX("Ross Williams (ross@spam.adelaide.edu.au), 12 May 1992.\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_ver P_((void));
+LOCAL void hel_ver ()
+{
+ WX("\n");
+ WX("FunnelWeb Versions\n");
+ WX("------------------\n");
+ WX("FunnelWeb was created in 1986 and was used extensively by Ross Williams\n");
+ WX("(ross@spam.adelaide.edu.au) for three years. However, Version 1.0 was written\n");
+ WX("in Ada and was not very portable (it was fairly VAX/VMS specific). David Hulse\n");
+ WX("(dave@cs.adelaide.edu.au) took the first step towards a release by translating\n");
+ WX("the Ada code into C. Ross Williams then extensively reworked the C code, making\n");
+ WX("it robust and portable, adding new features, and polishing it to its current\n");
+ WX("form.\n");
+ WX("\n");
+ WX("Vers Lang Created Released Author Copyright Licensing \n");
+ WX("---- ---- ------- -------- -------------- ------------- --------- \n");
+ WX("V1.0 Ada 1986 Never Ross Williams Ross Williams \n");
+ WX("V2.0 C 1989 Never David Hulse Public domain No restriction.\n");
+ WX("V3.0 C 1992 May-1992 Ross Williams Ross Williams GNU release. \n");
+ WX("V3.0AC C 1994 Sep-1994 A.B.Coates RW and ABC GNU release. \n");
+ WX("V3.01AC C 1995 Never A.B.Coates RW and ABC GNU release. \n");
+ WX("V3.02AC C 1995 Never A.B.Coates RW and ABC GNU release. \n");
+ WX("V3.03AC C 1995 Never A.B.Coates RW and ABC GNU release. \n");
+ WX("V3.04AC C 1995 Never A.B.Coates RW and ABC GNU release. \n");
+ WX("V3.05AC C 1995 Oct-1995 A.B.Coates RW and ABC GNU release. \n");
+ WX("\n");
+ WX("This is FunnelWeb Version 3.05AC. Unless otherwise specified, all references\n");
+ WX("in this release to \"FunnelWeb\" refer either to the abstract identity\n");
+ WX("of FunnelWeb, or to this version, FunnelWeb Version 3.05AC.\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_sup P_((void));
+LOCAL void hel_sup ()
+{
+ WX("\n");
+ WX("FunnelWeb Support\n");
+ WX("-----------------\n");
+ WX("FunnelWeb is released \"as is\" under a GNU license, and no formal support\n");
+ WX("is available. You have the right to make changes to FunnelWeb and to use\n");
+ WX("the modified versions created by random programmers. However, this is\n");
+ WX("discouraged (see the MODIFICATION help message).\n");
+ WX("\n");
+ WX("In fact the support that is most needed is your financial support for the\n");
+ WX("FunnelWeb developers! It has taken MONTHS of full-time UNPAID work to bring\n");
+ WX("FunnelWeb to you in its current form. I don't want to inconvenience users\n");
+ WX("who install FunnelWeb, play with it, and then hardly ever use it. If you are\n");
+ WX("in this category, please register, but don't bother contributing. However,\n");
+ WX("if you find that FunnelWeb has become a useful programming tool, a contribution\n");
+ WX("of some positive multiple of US$50 would be appreciated.\n");
+ WX("\n");
+ WX("To make a contribution, send payment with a completed registration form\n");
+ WX("(see the REGISTRATION help message) to:\n");
+ WX("\n");
+ WX(" Renaissance Software Pty Ltd\n");
+ WX(" Email: ross@spam.adelaide.edu.au\n");
+ WX(" Snail: 16 Lerwick Avenue, Hazelwood Park 5066, Australia.\n");
+ WX("\n");
+ WX("Payment can be by personal or bank cheque to any bank in the world or by\n");
+ WX("Visa or Mastercard. Please give the card name, number, expiry date, and\n");
+ WX("the amount to be paid in US dollars. All contributions will be appreciated\n");
+ WX("and will encourage further FunnelWeb development. However, no undertaking\n");
+ WX("is made whatsoever about how the money will be used.\n");
+ WX("\n");
+ WX("Ross Williams (ross@spam.adelaide.edu.au), 12 May 1992.\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_mod P_((void));
+LOCAL void hel_mod ()
+{
+ WX("\n");
+ WX("FunnelWeb Modifications\n");
+ WX("-----------------------\n");
+ WX("FunnelWeb is distributed under a GNU license, and you are free to modify the\n");
+ WX("source code and distribute modified copies (see the help message LICENSE).\n");
+ WX("However, there are good reasons why you should avoid doing this.\n");
+ WX("\n");
+ WX(" 1) If you distribute modified versions of FunnelWeb, you run the risk of\n");
+ WX(" creating a version that will diverge from the \"official\" version of\n");
+ WX(" FunnelWeb which I intend to maintain.\n");
+ WX("\n");
+ WX(" 2) If you release a version of FunnelWeb with a changed input language,\n");
+ WX(" users of your modified version will create source files that will no\n");
+ WX(" longer work on other versions of FunnelWeb. The result will be chaos.\n");
+ WX("\n");
+ WX("For these reasons I request that you do not distribute modified versions of\n");
+ WX("FunnelWeb, particularly versions with a modified language. However, if you must\n");
+ WX("distribute a version with a modified language, PLEASE CHANGE ITS NAME (i.e.\n");
+ WX("from \"FunnelWeb\" to something else). Please also allocate a new file extension\n");
+ WX("to replace \".fw\" as the extension for source files written in the modified\n");
+ WX("language. For more information, refer to the FunnelWeb Hacker's Manual.\n");
+ WX("\n");
+ WX("Ross Williams (ross@spam.adelaide.edu.au), 12 May 1992.\n");
+}
+
+/******************************************************************************/
+
+LOCAL bool prefeq P_((char *,char *));
+LOCAL bool prefeq (p_pref,p_target)
+/* Returns TRUE iff string p_pref is a case insensitive prefix of p_target. */
+char *p_pref;
+char *p_target;
+{
+ char *p,*q;
+
+ if (strlen(p_pref) > strlen(p_target))
+ return FALSE;
+
+ p=p_pref;
+ q=p_target;
+ while (*p != EOS)
+ {
+ if (toupper(*p) != toupper(*q)) return FALSE;
+ p++;
+ q++;
+ }
+ return TRUE;
+}
+
+/******************************************************************************/
+
+EXPORT uword hel_num (p_name)
+char *p_name;
+{
+ uword matches = 0;
+ uword messnum;
+
+ /* We want to be fairly lenient on the user here as the user is trying to */
+ /* obtain help and will probably get annoyed and give up if it doesn't work, */
+ /* so we perform case insensitive prefix matching. However, we don't want */
+ /* to match if the user inputs a prefix that matches two message names. This */
+ /* means we can't just return when we find a match; we have to see if there */
+ /* are any others as well. */
+
+ if (prefeq(p_name,"MENU" )) {messnum=HL_MEN; matches++;}
+ if (prefeq(p_name,"INTRODUCTION" )) {messnum=HL_INT; matches++;}
+ if (prefeq(p_name,"OPTIONS" )) {messnum=HL_OPT; matches++;}
+ if (prefeq(p_name,"DEFOPTIONS" )) {messnum=HL_DOP; matches++;}
+ if (prefeq(p_name,"COMMANDS" )) {messnum=HL_COM; matches++;}
+ if (prefeq(p_name,"DOCUMENTATION")) {messnum=HL_DOC; matches++;}
+ if (prefeq(p_name,"REGISTRATION" )) {messnum=HL_REG; matches++;}
+ if (prefeq(p_name,"LICENSE" )) {messnum=HL_GNU; matches++;}
+ if (prefeq(p_name,"COPYRIGHT" )) {messnum=HL_COP; matches++;}
+ if (prefeq(p_name,"NOWARRANTY" )) {messnum=HL_NOW; matches++;}
+ if (prefeq(p_name,"DISTRIBUTION" )) {messnum=HL_DIS; matches++;}
+ if (prefeq(p_name,"ACKNOWLEDGE" )) {messnum=HL_ACK; matches++;}
+ if (prefeq(p_name,"VERSIONS" )) {messnum=HL_VER; matches++;}
+ if (prefeq(p_name,"SUPPORT" )) {messnum=HL_SUP; matches++;}
+ if (prefeq(p_name,"MODIFICATION" )) {messnum=HL_MOD; matches++;}
+
+ if (matches != 1) return HL_ERR;
+
+ return messnum;
+}
+
+/******************************************************************************/
+
+EXPORT void hel_wri (p_outf,messno)
+void (*p_outf) P_((char *));
+uword messno;
+{
+ as_cold(1 <= messno,
+ "hel_wri: Message number is zero.");
+ as_cold(messno <= HL_FWMAX,
+ "hel_wri: Message number is greater than HL_FWMAX.");
+
+ /* Set the global output function pointer. */
+ pf=p_outf;
+
+ switch(messno)
+ {
+ case HL_MEN: hel_men(); break;
+ case HL_INT: hel_int(); break;
+ case HL_OPT: hel_opt(); break;
+ case HL_DOP: hel_dop(); break;
+ case HL_COM: hel_com(); break;
+ case HL_DOC: hel_doc(); break;
+ case HL_REG: hel_reg(); break;
+ case HL_GNU: hel_gnu(p_outf); break; /* Calling another module. */
+ case HL_COP: hel_cop(); break;
+ case HL_NOW: hel_now(); break;
+ case HL_DIS: hel_dis(); break;
+ case HL_ACK: hel_ack(); break;
+ case HL_VER: hel_ver(); break;
+ case HL_SUP: hel_sup(); break;
+ case HL_MOD: hel_mod(); break;
+ default : as_bomb("hel_wri: switch defaulted.");
+ }
+}
+
+/******************************************************************************/
+/* End of HELP.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/help.h b/web/funnelAC/fwACsrc/help.h
new file mode 100644
index 0000000000..d51690f8e3
--- /dev/null
+++ b/web/funnelAC/fwACsrc/help.h
@@ -0,0 +1,164 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 16-Sep-1993 ABC Changed all constants *_MAX to *_FWMAX to avoid
+ conflict with some standard UNIX constants.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* HELP.H */
+/******************************************************************************/
+/* */
+/* HELP PACKAGE */
+/* ============ */
+/* As I came closer and closer to completing the release version of */
+/* FunnelWeb, I noticed that the online help was a bit of a mess. I had */
+/* random commands and command line options here and there to provide bits of */
+/* information. After a close look and some thought, I decided to centralize */
+/* all of FunnelWeb's help messages into one module, and provide a clean and */
+/* consistent interface to the help messages, both in the command line, and */
+/* in interactive mode. */
+/* */
+/* The result is that all of the help messages have been moved to */
+/* this module. Each help message has a name consisting of a string. One */
+/* particular message has the name "MENU" and is the root help message (the */
+/* "menu message"). It contains a list of all the help messages available and */
+/* their names. */
+/* */
+/* The command line connects to help by providing a single command line */
+/* option called +Hx which has the effect of displaying the help message */
+/* called x. The default is -Hmenu. The "-" means that help is not invoked by */
+/* default, but that if the user specifies +H, the menu message will be */
+/* printed. If the user specifies (say) +Hsloth, message SLOTH will be */
+/* displayed. The menu message is printed if the user invokes FunnelWeb with */
+/* no actions. The +H option is classified as an action option. */
+/* */
+/* Interactive mode connects to help through the HELP command. In the spirit */
+/* of the command line interface, if no argument is given, the menu message */
+/* is displayed. If an argument is given, the specified message is written */
+/* out. */
+/* */
+/* This module contributes two things to this process: */
+/* 1) Provides a mapping from message names to messages. */
+/* 2) Acts as a repository for the messages themselves. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_HELP
+#define DONE_HELP
+
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+/* Place a bound on help name length, and define an array type to hold them. */
+#define HL_NMLEN 20
+typedef char hn_t[HL_NMLEN+1];
+
+/******************************************************************************/
+
+/* Each of the messages has a unique symbol and number. The reason for */
+/* defining these symbols instead of just using the message names in the code */
+/* is that doing it this way allows us to change the exact message names */
+/* without having to track down all their occurences in the code, or getting */
+/* nasty surprises later down the track at run time (the compiler will tell */
+/* you in a call containing HL_SLT that the symbol doesn't exist, but it */
+/* won't complain about a string argument that just happens not to be the */
+/* name of a message anymore). */
+
+/* HL_ERR is the non-existent message. */
+#define HL_ERR 0
+
+/* HL_MEN - Help messages. */
+/* HL_INT - Introduction to FunnelWeb. */
+/* HL_OPT - Command line options. */
+/* HL_DOP - Option defaults. */
+/* HL_COM - Interactive commands. */
+/* HL_DOC - Documentation. */
+/* HL_REG - Registration. */
+/* HL_LIC - The GNU License. */
+/* HL_COP - Copyright notice. */
+/* HL_NOW - No Warranty notice. */
+/* HL_DIS - Distribution notice. */
+/* HL_ACK - Acknowledgements. */
+/* HL_VER - Versions. */
+/* HL_SUP - Support. */
+/* HL_MOD - Modifications. */
+#define HL_MEN 1
+#define HL_INT 2
+#define HL_OPT 3
+#define HL_DOP 4
+#define HL_COM 5
+#define HL_DOC 6
+#define HL_REG 7
+#define HL_GNU 8
+#define HL_COP 9
+#define HL_NOW 10
+#define HL_DIS 11
+#define HL_ACK 12
+#define HL_VER 13
+#define HL_SUP 14
+#define HL_MOD 15
+
+/* The following symbol does not represent a message. It is the number of */
+/* messages. This is useful for range checking and possibly in for loops. */
+#define HL_FWMAX 15
+
+/******************************************************************************/
+
+EXPORT uword hel_num P_((char *));
+/* Accepts a character string that is supposed to be the name of a message */
+/* and returns the number of the message, or HL_ERR if the string does not */
+/* correspond to any defined message. A match will occur if the argument */
+/* string is the same (with case independent matching) as the prefix (of */
+/* corresponding length) of exactly one message name. */
+
+EXPORT void hel_wri P_((void (*)(char *),uword));
+/* Accepts a message number and writes the message using the function */
+/* provided in the first argument. Bombs the program if the message number in */
+/* the second argument is not in the range [1,HL_FWMAX]. */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of HELP.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/help_gnu.c b/web/funnelAC/fwACsrc/help_gnu.c
new file mode 100644
index 0000000000..20555d3b14
--- /dev/null
+++ b/web/funnelAC/fwACsrc/help_gnu.c
@@ -0,0 +1,105 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* HELP_GNU.C */
+/******************************************************************************/
+/* */
+/* REPRESENTING MESSAGES AS C CODE */
+/* =============================== */
+/* Experience has shown that it is much more reliable to code text messages */
+/* into a program than to expect the program to track down text files */
+/* containing the messages at run time. Worthwhile for smallish files (such */
+/* as these help messages) at least. For this reason, all the messages in */
+/* this module are represented by code (e.g. as in printf statements). */
+/* */
+/* There is no difficulty turning a short message into code; simply place it */
+/* in output statements. However, large messages (e.g. the GNU license) are */
+/* more tedious, and also present more of a problem if it is necessary to */
+/* change them substantially at a later date. This problem has been solved in */
+/* FunnelWeb by writing a small program that reads a text file and writes out */
+/* C code that writes the text file. The files involved are: */
+/* */
+/* help_gnu.mes - The original message. */
+/* help_gnu.c - C code to write out the original message. */
+/* */
+/* To turn help_gnu.mes into help_gnu.c, give the following command in */
+/* FunnelWeb interactive mode: codify help_gnu.txt help_gnu.c */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "help_gnu.h"
+
+/******************************************************************************/
+
+/* This module contains many many output statements that call an output */
+/* function. To neaten up all these calls, we define a global variable to */
+/* hold a pointer to the function and simple macro to write output using */
+/* the function. */
+LOCVAR void (*pf) P_((char *));
+
+#define WX(STR) (*pf)(STR);(*pf)("\n")
+#define WY(STR) (*pf)(STR)
+
+/******************************************************************************/
+
+EXPORT void hel_gnu (p_outf)
+void (*p_outf) P_((char *));
+{
+ pf=p_outf;
+ WY("\n");
+ WY("FunnelWeb License\n");
+ WY("-----------------\n");
+ WY("FunnelWeb is distributed under the following license.\n");
+ WY("\n");
+ WY("--<Start of GNU License>--\n");
+#include "help_gnu.ctx"
+ WY("--<End of GNU License>--\n");
+ WY("\n");
+ WY("If all that scrolled off your screen too quickly, don't worry. You can\n");
+ WY("capture this message (or any other FunnelWeb output) in a file by\n");
+ WY("specifying the +J option when you invoke FunnelWeb. For example:\n");
+ WY("\n");
+ WY(" fw +hlicense +jresult.txt\n");
+ WY("\n");
+}
+
+/******************************************************************************/
+/* End of HELP_GNU.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/help_gnu.ctx b/web/funnelAC/fwACsrc/help_gnu.ctx
new file mode 100644
index 0000000000..34af6039b0
--- /dev/null
+++ b/web/funnelAC/fwACsrc/help_gnu.ctx
@@ -0,0 +1,339 @@
+ WX(" GNU GENERAL PUBLIC LICENSE");
+ WX(" Version 2, June 1991");
+ WX("");
+ WX(" Copyright (C) 1989, 1991 Free Software Foundation, Inc.");
+ WX(" 675 Mass Ave, Cambridge, MA 02139, USA");
+ WX(" Everyone is permitted to copy and distribute verbatim copies");
+ WX(" of this license document, but changing it is not allowed.");
+ WX("");
+ WX(" Preamble");
+ WX("");
+ WX(" The licenses for most software are designed to take away your");
+ WX("freedom to share and change it. By contrast, the GNU General Public");
+ WX("License is intended to guarantee your freedom to share and change free");
+ WX("software--to make sure the software is free for all its users. This");
+ WX("General Public License applies to most of the Free Software");
+ WX("Foundation's software and to any other program whose authors commit to");
+ WX("using it. (Some other Free Software Foundation software is covered by");
+ WX("the GNU Library General Public License instead.) You can apply it to");
+ WX("your programs, too.");
+ WX("");
+ WX(" When we speak of free software, we are referring to freedom, not");
+ WX("price. Our General Public Licenses are designed to make sure that you");
+ WX("have the freedom to distribute copies of free software (and charge for");
+ WX("this service if you wish), that you receive source code or can get it");
+ WX("if you want it, that you can change the software or use pieces of it");
+ WX("in new free programs; and that you know you can do these things.");
+ WX("");
+ WX(" To protect your rights, we need to make restrictions that forbid");
+ WX("anyone to deny you these rights or to ask you to surrender the rights.");
+ WX("These restrictions translate to certain responsibilities for you if you");
+ WX("distribute copies of the software, or if you modify it.");
+ WX("");
+ WX(" For example, if you distribute copies of such a program, whether");
+ WX("gratis or for a fee, you must give the recipients all the rights that");
+ WX("you have. You must make sure that they, too, receive or can get the");
+ WX("source code. And you must show them these terms so they know their");
+ WX("rights.");
+ WX("");
+ WX(" We protect your rights with two steps: (1) copyright the software, and");
+ WX("(2) offer you this license which gives you legal permission to copy,");
+ WX("distribute and/or modify the software.");
+ WX("");
+ WX(" Also, for each author's protection and ours, we want to make certain");
+ WX("that everyone understands that there is no warranty for this free");
+ WX("software. If the software is modified by someone else and passed on, we");
+ WX("want its recipients to know that what they have is not the original, so");
+ WX("that any problems introduced by others will not reflect on the original");
+ WX("authors' reputations.");
+ WX("");
+ WX(" Finally, any free program is threatened constantly by software");
+ WX("patents. We wish to avoid the danger that redistributors of a free");
+ WX("program will individually obtain patent licenses, in effect making the");
+ WX("program proprietary. To prevent this, we have made it clear that any");
+ WX("patent must be licensed for everyone's free use or not licensed at all.");
+ WX("");
+ WX(" The precise terms and conditions for copying, distribution and");
+ WX("modification follow.");
+ WX("");
+ WX(" GNU GENERAL PUBLIC LICENSE");
+ WX(" TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION");
+ WX("");
+ WX(" 0. This License applies to any program or other work which contains");
+ WX("a notice placed by the copyright holder saying it may be distributed");
+ WX("under the terms of this General Public License. The \"Program\", below,");
+ WX("refers to any such program or work, and a \"work based on the Program\"");
+ WX("means either the Program or any derivative work under copyright law:");
+ WX("that is to say, a work containing the Program or a portion of it,");
+ WX("either verbatim or with modifications and/or translated into another");
+ WX("language. (Hereinafter, translation is included without limitation in");
+ WX("the term \"modification\".) Each licensee is addressed as \"you\".");
+ WX("");
+ WX("Activities other than copying, distribution and modification are not");
+ WX("covered by this License; they are outside its scope. The act of");
+ WX("running the Program is not restricted, and the output from the Program");
+ WX("is covered only if its contents constitute a work based on the");
+ WX("Program (independent of having been made by running the Program).");
+ WX("Whether that is true depends on what the Program does.");
+ WX("");
+ WX(" 1. You may copy and distribute verbatim copies of the Program's");
+ WX("source code as you receive it, in any medium, provided that you");
+ WX("conspicuously and appropriately publish on each copy an appropriate");
+ WX("copyright notice and disclaimer of warranty; keep intact all the");
+ WX("notices that refer to this License and to the absence of any warranty;");
+ WX("and give any other recipients of the Program a copy of this License");
+ WX("along with the Program.");
+ WX("");
+ WX("You may charge a fee for the physical act of transferring a copy, and");
+ WX("you may at your option offer warranty protection in exchange for a fee.");
+ WX("");
+ WX(" 2. You may modify your copy or copies of the Program or any portion");
+ WX("of it, thus forming a work based on the Program, and copy and");
+ WX("distribute such modifications or work under the terms of Section 1");
+ WX("above, provided that you also meet all of these conditions:");
+ WX("");
+ WX(" a) You must cause the modified files to carry prominent notices");
+ WX(" stating that you changed the files and the date of any change.");
+ WX("");
+ WX(" b) You must cause any work that you distribute or publish, that in");
+ WX(" whole or in part contains or is derived from the Program or any");
+ WX(" part thereof, to be licensed as a whole at no charge to all third");
+ WX(" parties under the terms of this License.");
+ WX("");
+ WX(" c) If the modified program normally reads commands interactively");
+ WX(" when run, you must cause it, when started running for such");
+ WX(" interactive use in the most ordinary way, to print or display an");
+ WX(" announcement including an appropriate copyright notice and a");
+ WX(" notice that there is no warranty (or else, saying that you provide");
+ WX(" a warranty) and that users may redistribute the program under");
+ WX(" these conditions, and telling the user how to view a copy of this");
+ WX(" License. (Exception: if the Program itself is interactive but");
+ WX(" does not normally print such an announcement, your work based on");
+ WX(" the Program is not required to print an announcement.)");
+ WX("");
+ WX("These requirements apply to the modified work as a whole. If");
+ WX("identifiable sections of that work are not derived from the Program,");
+ WX("and can be reasonably considered independent and separate works in");
+ WX("themselves, then this License, and its terms, do not apply to those");
+ WX("sections when you distribute them as separate works. But when you");
+ WX("distribute the same sections as part of a whole which is a work based");
+ WX("on the Program, the distribution of the whole must be on the terms of");
+ WX("this License, whose permissions for other licensees extend to the");
+ WX("entire whole, and thus to each and every part regardless of who wrote it.");
+ WX("");
+ WX("Thus, it is not the intent of this section to claim rights or contest");
+ WX("your rights to work written entirely by you; rather, the intent is to");
+ WX("exercise the right to control the distribution of derivative or");
+ WX("collective works based on the Program.");
+ WX("");
+ WX("In addition, mere aggregation of another work not based on the Program");
+ WX("with the Program (or with a work based on the Program) on a volume of");
+ WX("a storage or distribution medium does not bring the other work under");
+ WX("the scope of this License.");
+ WX("");
+ WX(" 3. You may copy and distribute the Program (or a work based on it,");
+ WX("under Section 2) in object code or executable form under the terms of");
+ WX("Sections 1 and 2 above provided that you also do one of the following:");
+ WX("");
+ WX(" a) Accompany it with the complete corresponding machine-readable");
+ WX(" source code, which must be distributed under the terms of Sections");
+ WX(" 1 and 2 above on a medium customarily used for software interchange; or,");
+ WX("");
+ WX(" b) Accompany it with a written offer, valid for at least three");
+ WX(" years, to give any third party, for a charge no more than your");
+ WX(" cost of physically performing source distribution, a complete");
+ WX(" machine-readable copy of the corresponding source code, to be");
+ WX(" distributed under the terms of Sections 1 and 2 above on a medium");
+ WX(" customarily used for software interchange; or,");
+ WX("");
+ WX(" c) Accompany it with the information you received as to the offer");
+ WX(" to distribute corresponding source code. (This alternative is");
+ WX(" allowed only for noncommercial distribution and only if you");
+ WX(" received the program in object code or executable form with such");
+ WX(" an offer, in accord with Subsection b above.)");
+ WX("");
+ WX("The source code for a work means the preferred form of the work for");
+ WX("making modifications to it. For an executable work, complete source");
+ WX("code means all the source code for all modules it contains, plus any");
+ WX("associated interface definition files, plus the scripts used to");
+ WX("control compilation and installation of the executable. However, as a");
+ WX("special exception, the source code distributed need not include");
+ WX("anything that is normally distributed (in either source or binary");
+ WX("form) with the major components (compiler, kernel, and so on) of the");
+ WX("operating system on which the executable runs, unless that component");
+ WX("itself accompanies the executable.");
+ WX("");
+ WX("If distribution of executable or object code is made by offering");
+ WX("access to copy from a designated place, then offering equivalent");
+ WX("access to copy the source code from the same place counts as");
+ WX("distribution of the source code, even though third parties are not");
+ WX("compelled to copy the source along with the object code.");
+ WX("");
+ WX(" 4. You may not copy, modify, sublicense, or distribute the Program");
+ WX("except as expressly provided under this License. Any attempt");
+ WX("otherwise to copy, modify, sublicense or distribute the Program is");
+ WX("void, and will automatically terminate your rights under this License.");
+ WX("However, parties who have received copies, or rights, from you under");
+ WX("this License will not have their licenses terminated so long as such");
+ WX("parties remain in full compliance.");
+ WX("");
+ WX(" 5. You are not required to accept this License, since you have not");
+ WX("signed it. However, nothing else grants you permission to modify or");
+ WX("distribute the Program or its derivative works. These actions are");
+ WX("prohibited by law if you do not accept this License. Therefore, by");
+ WX("modifying or distributing the Program (or any work based on the");
+ WX("Program), you indicate your acceptance of this License to do so, and");
+ WX("all its terms and conditions for copying, distributing or modifying");
+ WX("the Program or works based on it.");
+ WX("");
+ WX(" 6. Each time you redistribute the Program (or any work based on the");
+ WX("Program), the recipient automatically receives a license from the");
+ WX("original licensor to copy, distribute or modify the Program subject to");
+ WX("these terms and conditions. You may not impose any further");
+ WX("restrictions on the recipients' exercise of the rights granted herein.");
+ WX("You are not responsible for enforcing compliance by third parties to");
+ WX("this License.");
+ WX("");
+ WX(" 7. If, as a consequence of a court judgment or allegation of patent");
+ WX("infringement or for any other reason (not limited to patent issues),");
+ WX("conditions are imposed on you (whether by court order, agreement or");
+ WX("otherwise) that contradict the conditions of this License, they do not");
+ WX("excuse you from the conditions of this License. If you cannot");
+ WX("distribute so as to satisfy simultaneously your obligations under this");
+ WX("License and any other pertinent obligations, then as a consequence you");
+ WX("may not distribute the Program at all. For example, if a patent");
+ WX("license would not permit royalty-free redistribution of the Program by");
+ WX("all those who receive copies directly or indirectly through you, then");
+ WX("the only way you could satisfy both it and this License would be to");
+ WX("refrain entirely from distribution of the Program.");
+ WX("");
+ WX("If any portion of this section is held invalid or unenforceable under");
+ WX("any particular circumstance, the balance of the section is intended to");
+ WX("apply and the section as a whole is intended to apply in other");
+ WX("circumstances.");
+ WX("");
+ WX("It is not the purpose of this section to induce you to infringe any");
+ WX("patents or other property right claims or to contest validity of any");
+ WX("such claims; this section has the sole purpose of protecting the");
+ WX("integrity of the free software distribution system, which is");
+ WX("implemented by public license practices. Many people have made");
+ WX("generous contributions to the wide range of software distributed");
+ WX("through that system in reliance on consistent application of that");
+ WX("system; it is up to the author/donor to decide if he or she is willing");
+ WX("to distribute software through any other system and a licensee cannot");
+ WX("impose that choice.");
+ WX("");
+ WX("This section is intended to make thoroughly clear what is believed to");
+ WX("be a consequence of the rest of this License.");
+ WX("");
+ WX(" 8. If the distribution and/or use of the Program is restricted in");
+ WX("certain countries either by patents or by copyrighted interfaces, the");
+ WX("original copyright holder who places the Program under this License");
+ WX("may add an explicit geographical distribution limitation excluding");
+ WX("those countries, so that distribution is permitted only in or among");
+ WX("countries not thus excluded. In such case, this License incorporates");
+ WX("the limitation as if written in the body of this License.");
+ WX("");
+ WX(" 9. The Free Software Foundation may publish revised and/or new versions");
+ WX("of the General Public License from time to time. Such new versions will");
+ WX("be similar in spirit to the present version, but may differ in detail to");
+ WX("address new problems or concerns.");
+ WX("");
+ WX("Each version is given a distinguishing version number. If the Program");
+ WX("specifies a version number of this License which applies to it and \"any");
+ WX("later version\", you have the option of following the terms and conditions");
+ WX("either of that version or of any later version published by the Free");
+ WX("Software Foundation. If the Program does not specify a version number of");
+ WX("this License, you may choose any version ever published by the Free Software");
+ WX("Foundation.");
+ WX("");
+ WX(" 10. If you wish to incorporate parts of the Program into other free");
+ WX("programs whose distribution conditions are different, write to the author");
+ WX("to ask for permission. For software which is copyrighted by the Free");
+ WX("Software Foundation, write to the Free Software Foundation; we sometimes");
+ WX("make exceptions for this. Our decision will be guided by the two goals");
+ WX("of preserving the free status of all derivatives of our free software and");
+ WX("of promoting the sharing and reuse of software generally.");
+ WX("");
+ WX(" NO WARRANTY");
+ WX("");
+ WX(" 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY");
+ WX("FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN");
+ WX("OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES");
+ WX("PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED");
+ WX("OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF");
+ WX("MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS");
+ WX("TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE");
+ WX("PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,");
+ WX("REPAIR OR CORRECTION.");
+ WX("");
+ WX(" 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING");
+ WX("WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR");
+ WX("REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,");
+ WX("INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING");
+ WX("OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED");
+ WX("TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY");
+ WX("YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER");
+ WX("PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE");
+ WX("POSSIBILITY OF SUCH DAMAGES.");
+ WX("");
+ WX(" END OF TERMS AND CONDITIONS");
+ WX("");
+ WX(" Appendix: How to Apply These Terms to Your New Programs");
+ WX("");
+ WX(" If you develop a new program, and you want it to be of the greatest");
+ WX("possible use to the public, the best way to achieve this is to make it");
+ WX("free software which everyone can redistribute and change under these terms.");
+ WX("");
+ WX(" To do so, attach the following notices to the program. It is safest");
+ WX("to attach them to the start of each source file to most effectively");
+ WX("convey the exclusion of warranty; and each file should have at least");
+ WX("the \"copyright\" line and a pointer to where the full notice is found.");
+ WX("");
+ WX(" <one line to give the program's name and a brief idea of what it does.>");
+ WX(" Copyright (C) 19yy <name of author>");
+ WX("");
+ WX(" This program is free software; you can redistribute it and/or modify");
+ WX(" it under the terms of the GNU General Public License as published by");
+ WX(" the Free Software Foundation; either version 2 of the License, or");
+ WX(" (at your option) any later version.");
+ WX("");
+ WX(" This program is distributed in the hope that it will be useful,");
+ WX(" but WITHOUT ANY WARRANTY; without even the implied warranty of");
+ WX(" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the");
+ WX(" GNU General Public License for more details.");
+ WX("");
+ WX(" You should have received a copy of the GNU General Public License");
+ WX(" along with this program; if not, write to the Free Software");
+ WX(" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.");
+ WX("");
+ WX("Also add information on how to contact you by electronic and paper mail.");
+ WX("");
+ WX("If the program is interactive, make it output a short notice like this");
+ WX("when it starts in an interactive mode:");
+ WX("");
+ WX(" Gnomovision version 69, Copyright (C) 19yy name of author");
+ WX(" Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.");
+ WX(" This is free software, and you are welcome to redistribute it");
+ WX(" under certain conditions; type `show c' for details.");
+ WX("");
+ WX("The hypothetical commands `show w' and `show c' should show the appropriate");
+ WX("parts of the General Public License. Of course, the commands you use may");
+ WX("be called something other than `show w' and `show c'; they could even be");
+ WX("mouse-clicks or menu items--whatever suits your program.");
+ WX("");
+ WX("You should also get your employer (if you work as a programmer) or your");
+ WX("school, if any, to sign a \"copyright disclaimer\" for the program, if");
+ WX("necessary. Here is a sample; alter the names:");
+ WX("");
+ WX(" Yoyodyne, Inc., hereby disclaims all copyright interest in the program");
+ WX(" `Gnomovision' (which makes passes at compilers) written by James Hacker.");
+ WX("");
+ WX(" <signature of Ty Coon>, 1 April 1989");
+ WX(" Ty Coon, President of Vice");
+ WX("");
+ WX("This General Public License does not permit incorporating your program into");
+ WX("proprietary programs. If your program is a subroutine library, you may");
+ WX("consider it more useful to permit linking proprietary applications with the");
+ WX("library. If this is what you want to do, use the GNU Library General");
+ WX("Public License instead of this License.");
diff --git a/web/funnelAC/fwACsrc/help_gnu.h b/web/funnelAC/fwACsrc/help_gnu.h
new file mode 100644
index 0000000000..8844e1463a
--- /dev/null
+++ b/web/funnelAC/fwACsrc/help_gnu.h
@@ -0,0 +1,58 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* HELP_GNU.H */
+/******************************************************************************/
+/* */
+/* This module is used solely by the help module, and is really part of the */
+/* help module, but has been separated out because THINK C on the Macintosh */
+/* couldn't cope with more than 32K of code in one module. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+EXPORT void hel_gnu P_((void (*)(char *)));
+/* Writes out the GNU General Public License Version 2 using the specified */
+/* output function. */
+
+/******************************************************************************/
+/* End of HELP_GNU.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/help_gnu.txt b/web/funnelAC/fwACsrc/help_gnu.txt
new file mode 100644
index 0000000000..b8cf3a1ab2
--- /dev/null
+++ b/web/funnelAC/fwACsrc/help_gnu.txt
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/web/funnelAC/fwACsrc/htmlhead.c b/web/funnelAC/fwACsrc/htmlhead.c
new file mode 100644
index 0000000000..1af2e9524f
--- /dev/null
+++ b/web/funnelAC/fwACsrc/htmlhead.c
@@ -0,0 +1,112 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 15-Apr-1994 ABC Created this file by modifying `texhead.c'
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* HTMLHEAD.C */
+/******************************************************************************/
+/* */
+/* HTML HEADER PACKAGE */
+/* ================== */
+/* This package contains a single function that writes the HTML header */
+/* (containing all the Weave macros) to the specified stream. The package */
+/* consists of: */
+/* */
+/* htmlhead.htm - The header file ("source code" for htmlhead.cht). */
+/* htmlhead.cht - Automatically generated C code based on htmlhead.htm. */
+/* htmlhead.h - Exported header file containing function definition. */
+/* htmlhead.c - Contains the function body and the codified header file. */
+/* */
+/* WARNING: THE ONLY FILE THAT SHOULD EVER BE MODIFIED BY HAND IS */
+/* HTMLHEAD.HTM. */
+/* From this can be generated a new version of htmlhead.cht. Here's how: */
+/* 1. Edit htmlhead.htm as desired. */
+/* 2. Fire up the FunnelWeb shell and give the command: */
+/* codify htmlhead.htm htmlhead.cht */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "htmlhead.h"
+#include "writfile.h"
+
+/******************************************************************************/
+
+EXPORT void html_head(p_wf)
+p_wf_t p_wf;
+/* Writes the FunnelWeb HTML header block to the argument stream. */
+{
+
+ /*#############################################################################
+ IMPORTANT COPYRIGHT NOTICE
+ --------------------------
+ The set of FunnelWeb HTML definitions, embodied in C code in the file
+ included by the #include directive below, is a public domain work.
+
+ Notwithstanding the fact that the public domain set of FunnelWeb HTML
+ definitions is represented in the form of strings in C code #included by the
+ FunnelWeb literate-programming preprocessor program released under GNU General
+ Public License Version 2, the set of HTML definitions themselves do not fall
+ under GNU license. Instead, the set of FunnelWeb HTML definitions is classified
+ as a public domain work that is distributed with FunnelWeb as a "separate
+ work". The set of definitions is included as strings in the FunnelWeb code for
+ the sole reason that this organization avoids FunnelWeb having to locate the
+ file at run time. Thus, when FunnelWeb writes the set of HTML definitions to a
+ .htm output file, it is not generating a work based on itself, but is merely
+ copying a public domain file (which it happened to represent in the form of
+ code rather than data) into the output file.
+
+ The motivation for rigorously clarifying the status of the set of
+ FunnelWeb HTML definitions is that it will appear in HTML output files
+ generated by FunnelWeb, and I do not want any output files generated by
+ FunnelWeb to be under any copyright restrictions.
+
+ -- Ross N. Williams, 5:42pm 07-May-1992, Adelaide, Australia.
+ -- A.B.Coates, 5:55pm 15-Apr-1994, Brisbane, Australia.
+
+ #############################################################################*/
+
+#define WX(STR) wf_wl(p_wf,STR)
+
+#include "htmlhead.cht"
+}
+
+/******************************************************************************/
+/* End of HTMLHEAD.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/htmlhead.cht b/web/funnelAC/fwACsrc/htmlhead.cht
new file mode 100644
index 0000000000..25e78253b1
--- /dev/null
+++ b/web/funnelAC/fwACsrc/htmlhead.cht
@@ -0,0 +1,42 @@
+ WX("<!--============ Start of FunnelWeb HTML Definitions ============-->");
+ WX("");
+ WX("<!-- Version -->");
+ WX("<!-- ------- -->");
+ WX("<!-- This is FunnelWeb HTML Macro Library Version 1.0. -->");
+ WX("");
+ WX("<!-- Copyright -->");
+ WX("<!-- --------- -->");
+ WX("<!-- This set of FunnelWeb HTML definitions was written by -->");
+ WX("<!-- Anthony Coates and is Copyright (C) 1994 Anthony B. Coates. -->");
+ WX("<!-- However, I, Anthony Coates, hereby forego any claim to -->");
+ WX("<!-- Copyright in this set of FunnelWeb HTML definitions and -->");
+ WX("<!-- hereby authorize that the set of HTML definitions pass -->");
+ WX("<!-- into the public domain. -->");
+ WX("<!-- Anthony B. Coates, 6:25pm 15-Apr-1994, Brisbane, Australia. -->");
+ WX("");
+ WX("<!-- Modification -->");
+ WX("<!-- ------------ -->");
+ WX("<!-- Please record all modifications to these HTML definitions -->");
+ WX("<!-- here. Unless otherwise specified, all modified definitions -->");
+ WX("<!-- fall in the public domain too. -->");
+ WX("");
+ WX("<!-- Programmers: -->");
+ WX("<!-- ABC Anthony B. Coates coates@physics.uq.edu.au -->");
+ WX("");
+ WX("<!-- Changes: -->");
+ WX("<!-- 23-Apr-1994 ABC Prepared this work for -->");
+ WX("<!-- public domain release. -->");
+ WX("");
+ WX("<!-- General Comments -->");
+ WX("<!-- ---------------- -->");
+ WX("<!-- Where possible, definitions here will be used to reflect -->");
+ WX("<!-- existing FunnelWeb TeX definitions. -->");
+ WX("");
+ WX("<!-- The ISO-Latin-1 character set does not have the bullet -->");
+ WX("<!-- character that FunnelWeb uses for unprintable characters in -->");
+ WX("<!-- TeX output, so an inverted question mark (a Spanish -->");
+ WX("<!-- character used at the start of questions) is used instead. -->");
+ WX("");
+ WX("<!-- THERE ARE CURRENTLY NO DEFINITIONS IN THIS HEADER FILE. -->");
+ WX("");
+ WX("<!--============= End of FunnelWeb HTML Definitions =============-->");
diff --git a/web/funnelAC/fwACsrc/htmlhead.h b/web/funnelAC/fwACsrc/htmlhead.h
new file mode 100644
index 0000000000..09ea08e6a6
--- /dev/null
+++ b/web/funnelAC/fwACsrc/htmlhead.h
@@ -0,0 +1,125 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 15-Apr-1994 ABC Created this file by modifying `texhead.h'
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* HTMLHEAD.H */
+/******************************************************************************/
+/* */
+/* HTML HEADER PACKAGE */
+/* ================== */
+/* This package contains a single function that writes the HTML header */
+/* (containing all the Weave macros) to the specified stream. The package */
+/* consists of: */
+/* */
+/* htmlhead.htm - The header file ("source code" for htmlhead.cht). */
+/* htmlhead.cht - C code automatically generated by htmlhead.htm. */
+/* htmlhead.h - This file, containing a function definition. */
+/* htmlhead.c - Contains a function body. */
+/* */
+/* The first version of FunnelWeb (1986) generated TeX output files that used */
+/* a collection of macros to neaten and simplify the bulk of the TeX output */
+/* file. For example, the macro \fwbtx provided a simple way to specify */
+/* verbatim text. This system worked extremely well, the only inconvenience */
+/* being that each FunnelWeb TeX output file had to "\input" the TeX header */
+/* file containing all the macros. At the time, this seemed a sensible */
+/* factorization of the macros, and, within the limited environment in which */
+/* FunnelWeb was operating, worked well. */
+/* */
+/* In NEW, IMPROVED FunnelWeb, "\input"ing the header file has the potential */
+/* to cause lots of problems, the major ones being: */
+/* */
+/* - The header file would have to be installed as part of the FunnelWeb */
+/* system. Currently this means that it would be the ONLY other file */
+/* necessary apart from the FunnelWeb executable. It would be far more */
+/* desirable to avoid having to install the header file. */
+/* */
+/* - The header file would have to be referred to somehow by the TeX file. */
+/* As it makes sense to have only one copy of the header file on a machine, */
+/* TeX files would have to refer to that copy. This would require one of a */
+/* number of messy machine-specific mechanisms such as (VMS) logical name */
+/* translation or environment variable translation. */
+/* */
+/* - TeX files could not be easily moved to other machines (particularly */
+/* those not running FunnelWeb themselves) without also sending the header */
+/* file. */
+/* */
+/* - If FunnelWeb and the header file were ever jointly modified, the dynamic */
+/* binding of old TeX files would mean that they may no longer be printable.*/
+/* */
+/* For all these reasons, the decision was made to write the library of TeX */
+/* macros at the start of each TeX output file, thus making each TeX output */
+/* file entirely self-contained. To do this, the header file had to be */
+/* converted into a sequence of C output statments. To this end, a new */
+/* FunnelWeb shell command CODIFY was added that performs this transformation.*/
+/* CODIFY could have been a separate utility program, but if it was, it might */
+/* somehow be separated from the rest of FunnelWeb during distribution. By */
+/* building CODIFY into FunnelWeb itself, this possibility is eliminated. */
+/* */
+/* This package encapsulates the automatically generated C code. This header */
+/* file defines a function that writes it to a specified stream. The package */
+/* body htmlhead.c contains the body of the function which consists mainly of */
+/* a #include of the automatically generated C code in htmlhead.cht. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_HTMLH
+#define DONE_HTMLH
+
+/******************************************************************************/
+
+/* Define NO_HEADER to suppress inclusion of the FunnelWeb HTML header */
+
+#include "style.h"
+
+#include "writfile.h"
+
+/******************************************************************************/
+
+EXPORT void html_head P_((p_wf_t));
+/* Writes the FunnelWeb HTML header block to the argument stream. */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of HTMLHEAD.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/htmlhead.htm b/web/funnelAC/fwACsrc/htmlhead.htm
new file mode 100644
index 0000000000..95bd531d66
--- /dev/null
+++ b/web/funnelAC/fwACsrc/htmlhead.htm
@@ -0,0 +1,42 @@
+<!--============ Start of FunnelWeb HTML Definitions ============-->
+
+<!-- Version -->
+<!-- ------- -->
+<!-- This is FunnelWeb HTML Macro Library Version 1.0. -->
+
+<!-- Copyright -->
+<!-- --------- -->
+<!-- This set of FunnelWeb HTML definitions was written by -->
+<!-- Anthony Coates and is Copyright (C) 1994 Anthony B. Coates. -->
+<!-- However, I, Anthony Coates, hereby forego any claim to -->
+<!-- Copyright in this set of FunnelWeb HTML definitions and -->
+<!-- hereby authorize that the set of HTML definitions pass -->
+<!-- into the public domain. -->
+<!-- Anthony B. Coates, 6:25pm 15-Apr-1994, Brisbane, Australia. -->
+
+<!-- Modification -->
+<!-- ------------ -->
+<!-- Please record all modifications to these HTML definitions -->
+<!-- here. Unless otherwise specified, all modified definitions -->
+<!-- fall in the public domain too. -->
+
+<!-- Programmers: -->
+<!-- ABC Anthony B. Coates coates@physics.uq.edu.au -->
+
+<!-- Changes: -->
+<!-- 23-Apr-1994 ABC Prepared this work for -->
+<!-- public domain release. -->
+
+<!-- General Comments -->
+<!-- ---------------- -->
+<!-- Where possible, definitions here will be used to reflect -->
+<!-- existing FunnelWeb TeX definitions. -->
+
+<!-- The ISO-Latin-1 character set does not have the bullet -->
+<!-- character that FunnelWeb uses for unprintable characters in -->
+<!-- TeX output, so an inverted question mark (a Spanish -->
+<!-- character used at the start of questions) is used instead. -->
+
+<!-- THERE ARE CURRENTLY NO DEFINITIONS IN THIS HEADER FILE. -->
+
+<!--============= End of FunnelWeb HTML Definitions =============-->
diff --git a/web/funnelAC/fwACsrc/list.c b/web/funnelAC/fwACsrc/list.c
new file mode 100644
index 0000000000..6585904214
--- /dev/null
+++ b/web/funnelAC/fwACsrc/list.c
@@ -0,0 +1,328 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 08-Aug-1995 ABC Changed include file name from "memory.h"
+ to "fwmem.h" to avoid a clash with the C++
+ standard header file "memory.h".
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* LIST.C */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "as.h"
+#include "machin.h"
+#include "fwmem.h"
+
+/******************************************************************************/
+
+/* In order to catch uninitialized and corrupted lists, the first and last */
+/* fields of legitimate list objects contain magic numbers. The following */
+/* #defines give the values of these numbers. The first thing that each */
+/* function of this package does is to check the two magic number fields of */
+/* the list it has just been passed, and bomb the package if the fields have */
+/* the wrong values. This technique is likely to pick uninitialized lists, */
+/* as well as lists that have been partially overwritten. */
+#define MAGIC_HEAD_VALUE (97673812L)
+#define MAGIC_TAIL_VALUE (49357294L)
+
+/******************************************************************************/
+
+typedef struct node_t_ /* Structure used to compose the list proper. */
+ {
+ struct node_t_ *p_prev; /* Points to adjacent node closer to head. */
+ struct node_t_ *p_next; /* Points to adjacent node closer to tail. */
+ p_void p_data; /* Points to data in heap for this element. */
+ }
+ node_t;
+
+typedef node_t *p_node_t; /* Pointer to node type. */
+
+typedef struct /* Main list object containing all the goodies. */
+ {
+ ulong magic_head; /* Helpful in catching list object corruptions. */
+ p_node_t p_head; /* Points to the head of the list (or NULL). */
+ p_node_t p_tail; /* Points to the tail of the list (or NULL). */
+ p_node_t p_mark; /* Points to the marked element (or NULL). */
+ size_t data_bytes; /* Number of bytes in this list's data elements. */
+ ulong length; /* Number of elements in this list. */
+ ulong magic_tail; /* Helpful in catching list object corruptions. */
+ }
+ ls_t;
+
+typedef ls_t *p_ls_t; /* Main list view type. */
+
+typedef p_void p_lsel_t; /* Escalating pointers to data elements! */
+typedef p_lsel_t *pp_lsel_t;
+
+/* We need the function prototypes from list.h. The #define ensures that the */
+/* abstract exported definition of a list is not visible to us here. */
+#define INLISTC
+#include "list.h"
+
+/******************************************************************************/
+
+LOCAL void ls_check P_((p_ls_t));
+LOCAL void ls_check(p_ls)
+/* Accepts a pointer to a list and performs a series of checks to make sure */
+/* that the list has not been corrupted in some way. */
+/* This function is the sort of function that is normally turned off in */
+/* production versions. However, we are too scared to in FunnelWeb because */
+/* lists are not typesafe and are used throughout the program. */
+p_ls_t p_ls;
+{
+ as_cold(p_ls!=NULL,"ls_check: List pointer is NULL.");
+ as_cold(p_ls->magic_head==MAGIC_HEAD_VALUE,
+ "ls_check: Magic number at head of record is incorrect.");
+ as_cold(p_ls->magic_tail==MAGIC_TAIL_VALUE,
+ "ls_check: Magic number at tail of record is incorrect.");
+}
+
+/******************************************************************************/
+
+EXPORT p_ls_t ls_cre (data_bytes)
+size_t data_bytes;
+{
+ p_ls_t p_ls;
+
+ p_ls=(p_ls_t) mm_temp(sizeof(ls_t));
+ p_ls->magic_head = MAGIC_HEAD_VALUE;
+ p_ls->p_head = NULL;
+ p_ls->p_tail = NULL;
+ p_ls->p_mark = NULL;
+ p_ls->data_bytes = data_bytes;
+ p_ls->length = 0;
+ p_ls->magic_tail = MAGIC_TAIL_VALUE;
+ return p_ls;
+}
+
+/******************************************************************************/
+
+EXPORT void ls_add(p_ls,p_lsel)
+p_ls_t p_ls;
+p_void p_lsel;
+{
+ p_node_t p_node;
+
+ AS_HCODE(ls_check(p_ls);)
+
+ /* Create the list node and the data node hanging off it. Copy the data in. */
+ p_node =(p_node_t) mm_temp(sizeof(node_t));
+ p_node->p_data=(p_void) mm_temp(p_ls->data_bytes);
+ memcpy(p_node->p_data,p_lsel,p_ls->data_bytes);
+
+ /* Attach the new node to the tail of the list. */
+
+ p_node->p_prev=p_ls->p_tail; /* Pointers in the new node itself. */
+ p_node->p_next=NULL;
+
+ if (p_ls->p_head == NULL) /* Headside pointer pointing to new node. */
+ p_ls->p_head=p_node;
+ else
+ p_ls->p_tail->p_next=p_node;
+
+ p_ls->p_tail=p_node; /* Tailside pointer pointing to new node. */
+
+ /* Inc the length. */
+ p_ls->length++;
+}
+
+/******************************************************************************/
+
+EXPORT void ls_lop(p_ls)
+p_ls_t p_ls;
+{
+ /* p_node_t p_targ; ONLY NEEDED IF DEALLOCATING */
+
+ AS_HCODE(ls_check(p_ls);)
+
+ as_cold(p_ls->length>0,"ls_lop: List is empty.");
+
+ /* Make a note of the node being deleted. */
+ /* p_targ=p_ls->p_tail; ONLY NEEDED IF DEALLOCATED. */
+
+ /* If the target node was the only node, stitch up the ends of the list. */
+ if (--p_ls->length==0)
+ {
+ p_ls->p_head=NULL;
+ p_ls->p_tail=NULL;
+ }
+ else
+ { /* Unhook node from tail of list. */
+ p_ls->p_tail = p_ls->p_tail->p_prev;
+ p_ls->p_tail->p_next = NULL;
+ }
+
+ /* The following two commented calls show what we WOULD have to do to */
+ /* deallocate the list node. However, in FunnelWeb, all list items are */
+ /* allocated under the mm package watermark system using mm_temp calls so */
+ /* there is no need to free up the memory here. */
+ /* DEALLOCATE(PV p_targ->p_data); */
+ /* DEALLOCATE(PV p_targ); */
+}
+
+/******************************************************************************/
+
+EXPORT ulong ls_len(p_ls)
+p_ls_t p_ls;
+{
+ AS_HCODE(ls_check(p_ls);)
+ return p_ls->length;
+}
+
+/******************************************************************************/
+
+EXPORT void ls_fir(p_ls)
+p_ls_t p_ls;
+{
+ ls_check(p_ls);
+ p_ls->p_mark=p_ls->p_head;
+}
+
+/******************************************************************************/
+
+EXPORT void ls_nxt(p_ls,pp_lsel)
+p_ls_t p_ls;
+pp_lsel_t pp_lsel;
+{
+ AS_HCODE(ls_check(p_ls);)
+
+ if (p_ls->p_mark==NULL)
+ {*pp_lsel=NULL; return;}
+ *pp_lsel=p_ls->p_mark->p_data;
+ p_ls->p_mark=p_ls->p_mark->p_next;
+}
+
+/******************************************************************************/
+
+EXPORT void ls_loo(p_ls,index,pp_lsel)
+p_ls_t p_ls;
+ulong index;
+pp_lsel_t pp_lsel;
+{
+ p_node_t p;
+ ulong i;
+
+ AS_HCODE(ls_check(p_ls);)
+
+ p=p_ls->p_head;
+ as_cold(p!=NULL,"is_loo: List is empty.");
+ for(i=1;i<index;i++)
+ {
+ p=p->p_next;
+ as_cold(p!=NULL,"is_loo: Index is too high for this list.");
+ }
+ *pp_lsel=p->p_data;
+}
+
+/******************************************************************************/
+
+EXPORT void ls_tai(p_ls,pp_lsel)
+p_ls_t p_ls;
+pp_lsel_t pp_lsel;
+{
+ AS_HCODE(ls_check(p_ls);)
+
+ as_cold(p_ls->p_tail!=NULL,"ls_tai: List is empty.");
+ *pp_lsel=p_ls->p_tail->p_data;
+}
+
+/******************************************************************************/
+
+EXPORT void ls_emp(p_ls)
+p_ls_t p_ls;
+{
+ AS_HCODE(ls_check(p_ls);)
+
+ /* The following loop WOULD be required if we had to deallocate the list */
+ /* elements explicitly. However, as all list elements are allocated using */
+ /* mm_temp, it is possible to claim them later as a block. So here, we just */
+ /* let the list items drift off into the sunset. */
+ /* p_node_t p_curr; */
+ /* p_curr=p_ls->p_head; */
+ /* while (p_curr != NULL) */
+ /* { */
+ /* p_node_t p_targ=p_curr; */
+ /* p_curr=p_curr->p_next; */
+ /* my_free(PV p_targ->p_data); */
+ /* my_free(PV p_targ); */
+ /* } */
+
+ p_ls->p_head=NULL;
+ p_ls->p_tail=NULL;
+ p_ls->p_mark=NULL;
+ p_ls->length=0;
+}
+
+/******************************************************************************/
+
+EXPORT void ls_des(p_ls)
+p_ls_t p_ls;
+{
+ ls_check(p_ls);
+
+ ls_emp(p_ls);
+ p_ls->magic_head=0; /* Zap the magic numbers in case memory is reused. */
+ p_ls->magic_tail=0;
+
+ /* The following call WOULD be required if it wasn't for the MM watermark */
+ /* system of memory allocation. */
+ /* my_free(PV p_ls); */
+}
+
+/******************************************************************************/
+
+EXPORT p_void ls_mar (p_ls)
+p_ls_t p_ls;
+{
+ AS_HCODE(ls_check(p_ls);)
+ return PV p_ls->p_mark;
+}
+
+/******************************************************************************/
+
+EXPORT void ls_set(p_ls,p_m)
+p_ls_t p_ls;
+p_void p_m;
+{
+ AS_HCODE(ls_check(p_ls);)
+ p_ls->p_mark=(p_node_t) p_m;
+}
+
+/******************************************************************************/
+/* End of LIST.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/list.h b/web/funnelAC/fwACsrc/list.h
new file mode 100644
index 0000000000..f7cadf90a7
--- /dev/null
+++ b/web/funnelAC/fwACsrc/list.h
@@ -0,0 +1,207 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* LIST.H */
+/******************************************************************************/
+/* */
+/* Introduction */
+/* ------------ */
+/* This list package (list.h and list.c) implements a list abstraction. */
+/* */
+/* Facts about Lists */
+/* ----------------- */
+/* - A LIST stores zero or more LIST ELEMENTS. */
+/* - The user decides the type of element to be stored in each list. */
+/* - Each list stores only one type of list element; lists are homogeneous. */
+/* - Lists store copies of elements rather than pointers to elements. */
+/* - Each list can hold from zero to about 2^31 elements. */
+/* - Each list has a HEAD end and a TAIL end. */
+/* - Elements can be appended and deleted only at the tail of the list. */
+/* - The elements of a list can be read sequentially from head to tail. */
+/* - A MARKER stores the current position in the list for sequential reading. */
+/* - Upon list creation, the marker is positioned at the tail of the list. */
+/* - In a list of n elements, elements are numbered from 1 to n. */
+/* - Element 1 is at the head of the list. Element n is at the tail. */
+/* - The identifier "ls" is used as an abbreviation for "list". */
+/* - The identifier "el" is used as an abbreviation for "element". */
+/* - Longer names are desirable, but shorter ones have been used so as to */
+/* enhance the portability of the package. */
+/* - IMPORTANT: Lists get all their memory using mm_temp calls. */
+/* */
+/* How To Use This List Package */
+/* ---------------------------- */
+/* 1. Include this .H file in your program file. */
+/* 2. Identify the type of elements to be placed in the list. */
+/* 3. Define a variable of type p_ls as a view to a list. */
+/* 4. Use the ls_* functions to perform the desired operations. */
+/* Start with a call to ls_cre and (optionally) end with a call to ls_des. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_LIST
+#define DONE_LIST
+
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+/* Users manipulate lists through pointers to lists (p_ls_t). The following */
+/* declaration serves the list user of the package while hiding the */
+/* implementation details (which appear in a similar declaration in list.c). */
+/* The #ifndef stops list.c from seeing these public declarations. */
+#ifndef INLISTC
+typedef struct {word NEVER_USE_THIS_FIELD_UQJTKC;} ls_yqwx; /* Don't use! */
+typedef ls_yqwx *p_ls_t;
+typedef p_void p_lsel_t;
+typedef p_lsel_t *pp_lsel_t;
+#endif
+
+/******************************************************************************/
+/* */
+/* General Notes About These Functions */
+/* ----------------------------------- */
+/* - All lists and elements are passed by pointer. Whether a parameter is */
+/* read or written is determined by it's function's description. */
+/* - Each function (except ls_cre) accepts a single pointer to a list and */
+/* each function's description is assumed to be referring to the list. */
+/* - "Raising an error" means calling the external function "error" to */
+/* write out a message and bomb the program. */
+/* - You must create a list using ls_cre before performing any operations */
+/* upon it. A list function will usually raise an error if it is */
+/* handed a pointer that does not point to a properly CREated list. */
+/* */
+/* WARNING: This package copies values into its internal data structures */
+/* (through ls_add), but returns only POINTERS to elements when asked to */
+/* retrieve them. These pointers are valid only so long as the element */
+/* that they point to remains in the list. If the element is deleted somehow, */
+/* the pointer points to garbage and becomes dangerous. */
+/* So, if you have been handed a pointer to an element in a list (ls_nxt, */
+/* ls_loo), do not subsequently delete the element (ls_lop, ls_emp, ls_des) */
+/* and then attempt to access the element through the pointer. */
+/* One sure way to avoid the problem is always to use the pointer handed back */
+/* by ls_nxt or ls_loo to copy the element immediately. */
+
+/* The Functions */
+/* ------------- */
+EXPORT p_ls_t ls_cre P_((size_t));
+/* CREate. Creates a new list and returns a pointer to the new list. The user */
+/* must specify in the parameter the size of elements that are to be stored */
+/* in the list. Specify the size of elements in bytes (usually using sizeof). */
+/* The sequential reading marker is set to position n+1=1=tail of the list. */
+
+EXPORT void ls_add P_((p_ls_t,p_lsel_t));
+/* ADD. Adds a new element onto the tail of the list (at position n+1). */
+/* The user must supply in the second parameter a pointer to the element to */
+/* be added. ls_add takes a copy of the element (it knows from the earlier */
+/* call to ls_cre how many bytes to copy) and stores the copy in its own */
+/* internal data structures. */
+
+EXPORT void ls_lop P_((p_ls_t));
+/* LOP. Removes (lops) element n from the tail of the list. */
+/* Raises an error if the list is empty. */
+
+EXPORT ulong ls_len P_((p_ls_t));
+/* LENgth. Returns the number of elements in the list (n). */
+
+EXPORT void ls_fir P_((p_ls_t));
+/* FIRst. Sets the sequential reading marker to element 1. */
+/* If the list is empty (n=0) the marker is placed at the tail of the list */
+/* and subsequent calls to ls_add will leave it there until the next call to */
+/* ls_fir. */
+
+EXPORT void ls_nxt P_((p_ls_t,pp_lsel_t));
+/* NeXT. Returns the list element under the marker and advances the marker */
+/* one position towards the tail of the list. */
+/* The method of returning the list element is a little messy. The user */
+/* supplies a pointer to a pointer in the second parameter, and the function */
+/* writes the address of the element in the list into the pointer. */
+/* If the marker is at position n+1 upon entry to ls_nxt, the marker position */
+/* doesn't change and NULL is written to the argument pointer. */
+
+EXPORT void ls_loo P_((p_ls_t,ulong,pp_lsel_t));
+/* LOOkup. Returns (using the same mechanism as ls_nxt) the k'th element of */
+/* the specified list where k is the second (ulong) parameter and the first */
+/* element (at the head of the list) is numbered number one (1). */
+/* Raises an error if the index k is out of the range [1,n]. */
+
+EXPORT void ls_tai P_((p_ls_t,pp_lsel_t));
+/* Lookup TAIl. Returns (using the same mechanism as ls_nxt) the tail element */
+/* of the specified list. */
+/* Raises an error if the list is empty. */
+
+EXPORT void ls_emp P_((p_ls_t));
+/* EMPty. Empties the specified list, deallocating all the space used by the */
+/* list elements. Upon completion, the list will be empty and the list marker */
+/* will be positioned at the tail of the list. */
+
+EXPORT void ls_des P_((p_ls_t));
+/* DEStroy. Destroys a list, destroying all its elements and deallocating all */
+/* the memory used by the list. */
+
+/* Marker Functions */
+/* ---------------- */
+/* The following two functions ls_mar and ls_set were hacked in to this list */
+/* package when it was discovered that the tangler sometimes needs to run */
+/* more than one context down a list at the same time. The two new functions */
+/* allow the list package user to save and restore the current mark. */
+/* These functions are not tightly controlled and so care must be taken in */
+/* their use. */
+
+EXPORT p_void ls_mar P_((p_ls_t));
+/* Returns a representation of the current list marker. */
+
+EXPORT void ls_set P_((p_ls_t,p_void));
+/* Sets the position of the marker to an earlier saved position. */
+/* Calls to this function should satisfy the following conditions: */
+/* 1. The marker argument (p_void) must be the result of an earlier call */
+/* to ls_mar with the same list as an argument. */
+/* 2. No part of the list should have been modified in the interim. In */
+/* particular, this means that no calls to ls_add, ls_lop, ls_emp or */
+/* ls_des can be made between linked calls to ls_mar and ls_set. */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of LIST.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/lister.c b/web/funnelAC/fwACsrc/lister.c
new file mode 100644
index 0000000000..659f199045
--- /dev/null
+++ b/web/funnelAC/fwACsrc/lister.c
@@ -0,0 +1,370 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 11-Jan-1994 ABC Increased MAXLINES to 100000.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* LISTER.C */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "as.h"
+#include "data.h"
+#include "list.h"
+#include "lister.h"
+#include "machin.h"
+#include "misc.h"
+#include "table.h"
+#include "writfile.h"
+
+/******************************************************************************/
+
+#define LISTWIDTH 80 /* Nominal width of listing file. Can be wider. */
+#define INDENTQ 3 /* Indentation quantum for include files. */
+#define MESSMAXCH 200 /* Maximum number of characters in a message. */
+#define CTXINF 100 /* Special value that signals infinite context. */
+#define MAXLINES 100000 /* Maximum number of lines in input file. */
+
+/******************************************************************************/
+
+/* The following #defines and typedef define an enumerated type for message */
+/* kinds. There are four kinds of message, and we need a type for storing */
+/* this information. mess_k_t stands for message_kind_type. */
+/* We use #defines instead of enums as enums are not portable enough. */
+#define MESS_MES 1
+#define MESS_WAR 2
+#define MESS_ERR 3
+#define MESS_SEV 4
+typedef ubyte mess_k_t;
+
+/* We wish to store messages in a table with message positions as keys. */
+/* However, the table package will not tolerate duplicate keys. To solve this */
+/* problem, we create a new type 'unqpos_t' (unique position type) which has */
+/* not only a position but a serial number as well. */
+typedef struct
+ {
+ ps_t up_pos;
+ ulong up_serial;
+ } unqpos_t;
+
+/* The following structure stores a single message. As we are storing COPIES */
+/* of the messages, we impose a maximum limit (MESSMAXCH) to their length. */
+typedef struct
+ {
+ mess_k_t ms_kind;
+ char ms_text[MESSMAXCH+1];
+ } mess_t;
+
+/******************************************************************************/
+
+LOCVAR p_tb_t p_msgtab; /* The message table storing diagnostics. */
+LOCVAR ulong serial_next; /* Serial number for numbering messages. */
+
+/******************************************************************************/
+
+LOCAL int cmpuqpos P_((unqpos_t *,unqpos_t *));
+LOCAL int cmpuqpos(p1,p2)
+/* Compare two unique positions for the table package and returns [-1,0,1]. */
+unqpos_t *p1;
+unqpos_t *p2;
+{
+ long diff;
+ ubyte i;
+
+ for (i=1; i<=3; i++)
+ {
+ switch (i)
+ {
+ case 1: diff= p1->up_pos.ps_line - p2->up_pos.ps_line; break;
+ case 2: diff= p1->up_pos.ps_column - p2->up_pos.ps_column; break;
+ case 3: diff= p1->up_serial - p2->up_serial; break;
+ default: as_bomb("cmpuqpos: Case defaulted.");
+ }
+ if (diff<0)
+ return -1;
+ else
+ if (diff>0)
+ return 1;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+
+/* Converts a value of message kind type into a representative string. */
+/* This routine unused at present.
+LOCAL char *mess_let P_((mess_k_t));
+LOCAL char *mess_let (mess_k)
+mess_k_t mess_k;
+{
+ switch (mess_k)
+ {
+ case MESS_MES : return "M";
+ case MESS_WAR : return "W";
+ case MESS_ERR : return "E";
+ case MESS_SEV : return "S";
+ default: as_bomb("mess_let: Case defaulted.");
+ }
+ as_bomb("mess_let: Switch dropped out.");
+ return "Failure";
+}
+*/
+
+/******************************************************************************/
+
+#define DUPMAX 200
+
+LOCAL char *dup P_((int,uword));
+LOCAL char *dup(ch,count)
+/* Returns a pointer to a STAVAR string containing 'count' copies of 'ch'. */
+/* Count must be in the range [0,DUPMAX]. The pointer returned always points */
+/* to the same address which is a 'STAVAR' inside this function. */
+int ch;
+uword count;
+{
+ STAVAR char buffer[DUPMAX+1];
+
+ as_cold(count<DUPMAX,"lister.dup: count>=DUPMAX");
+ /* The IF in the following is just in case 'memset' is brain damaged. */
+ if (count>0) memset(&buffer[0],ch,(size_t) count);
+ buffer[count]=EOS;
+ return &buffer[0];
+}
+
+/******************************************************************************/
+
+LOCAL void mess_wri P_((p_wf_t,mess_t *,uword,uword));
+LOCAL void mess_wri(p_wf,p_mess,indent,column)
+/* Writes message p_mess to file p_wf indented by INDENTQ*indent+column. */
+p_wf_t p_wf;
+mess_t *p_mess;
+uword indent;
+uword column;
+{
+ switch (p_mess->ms_kind)
+ {
+ case MESS_MES : wf_wr(p_wf," "); break;
+ case MESS_WAR : wf_wr(p_wf," Warning"); break;
+ case MESS_ERR : wf_wr(p_wf," Error"); break;
+ case MESS_SEV : wf_wr(p_wf," Severe"); break;
+ default: as_bomb("mess_let: Case defaulted.");
+ }
+ wf_wr(p_wf,"|.");
+ wf_wr(p_wf,dup('.',indent*INDENTQ));
+ wf_wr(p_wf,dup('.',column-1));
+ wf_wr(p_wf,"^");
+ wf_wr(p_wf,&p_mess->ms_text[0]);
+ wf_wr(p_wf,"\n");
+}
+
+/******************************************************************************/
+
+LOCAL void line_wri P_((p_wf_t,ln_t *));
+LOCAL void line_wri(p_wf,p_line)
+/* Writes the given line to the given output stream. */
+p_wf_t p_wf;
+ln_t *p_line;
+{
+ char buffer[100];
+
+ /* The last line of the line list is the EOF marker line and to indicate */
+ /* that it is not really part of the input file, we omit it's line number. */
+ if (p_line->ln_global==ls_len(line_list))
+ /*" 12345 12345| "*/
+ sprintf(buffer," | ");
+ else
+ sprintf(buffer," %5lu %5lu| ",
+ (unsigned long) p_line->ln_global,
+ (unsigned long) p_line->ln_local);
+ wf_wr(p_wf,buffer);
+ wf_blk(p_wf,p_line->ln_body.sc_first,(size_t)
+ (p_line->ln_body.sc_last-p_line->ln_body.sc_first+1));
+}
+
+/******************************************************************************/
+
+LOCAL void add_mess P_((ps_t *,mess_k_t,char *));
+LOCAL void add_mess(p_pos,messkind,p_string)
+/* Creates a message record and places the message information in the */
+/* argument into the record. Inserts the record into the message table. */
+ps_t *p_pos;
+mess_k_t messkind;
+char *p_string;
+{
+ mess_t tempmess;
+ unqpos_t unqpos;
+
+ tempmess.ms_kind=messkind;
+ as_cold(strlen(p_string)<=MESSMAXCH,
+ "lister.add_mess: Parameter message is too long.");
+ strcpy(tempmess.ms_text,p_string);
+ ASSIGN(unqpos.up_pos,*p_pos);
+ unqpos.up_serial=serial_next++;
+ tb_ins(p_msgtab,PV &unqpos,PV &tempmess);
+}
+
+/******************************************************************************/
+
+EXPORT void lr_ini P_((void))
+{
+ /* Create a brand new empty message table. */
+ p_msgtab=tb_cre(sizeof(unqpos_t),sizeof(mess_t),(p_kycm_t) cmpuqpos);
+
+ /* Start the serial numbers at zero again. */
+ serial_next=0;
+}
+
+/******************************************************************************/
+
+EXPORT void lr_mes(p_pos,s)
+ps_t *p_pos;
+char *s;
+{
+ add_mess(p_pos,MESS_MES,s);
+}
+
+/******************************************************************************/
+
+EXPORT void lr_war(p_pos,s)
+ps_t *p_pos;
+char *s;
+{
+ add_mess(p_pos,MESS_WAR,s);
+ num_war++;
+}
+
+/******************************************************************************/
+
+EXPORT void lr_err(p_pos,s)
+ps_t *p_pos;
+char *s;
+{
+ add_mess(p_pos,MESS_ERR,s);
+ num_err++;
+}
+
+/******************************************************************************/
+
+EXPORT void lr_sev(p_pos,s)
+ps_t *p_pos;
+char *s;
+{
+ add_mess(p_pos,MESS_SEV,s);
+ num_sev++;
+}
+
+/******************************************************************************/
+
+EXPORT void lr_gen(p_wf,ctx)
+p_wf_t p_wf;
+uword ctx;
+{
+ unqpos_t next_pos; /* Position of next message. */
+ mess_t next_mes; /* Content of next message. */
+ long prev_no; /* Global line number of previous message. */
+ long next_no; /* Global line number of next message. */
+ bool ingap; /* Controls issuance of gap markers in the listing. */
+ long context=ctx; /* Signed version of the parameter. */
+
+ /* A context of CTXINF signals an infinite context. */
+ if (context==CTXINF) context=MAXLINES;
+
+ /* Write listing header. */
+ wf_wr(p_wf,"\nGlobal Local| Input File\n");
+ wf_wr(p_wf,dup('-',12));wf_wr(p_wf,"+");
+ wf_wr(p_wf,dup('-',LISTWIDTH-13));wf_wr(p_wf,"\n");
+
+ /* Reset the line list and message table for reading. */
+ ls_fir(line_list);
+ tb_fir(p_msgtab);
+
+ /* Prime the variables ingap, prev_no, next_no, next_pos, and next_mes. */
+ ingap=FALSE; prev_no = -(context+1);
+ if (tb_rea(p_msgtab,PV &next_pos,PV &next_mes))
+ next_no=next_pos.up_pos.ps_line;
+ else
+ next_no=MAXLINES+context+1;
+
+ while (TRUE)
+ {/* Process a single line per iteration. */
+ ln_t *p_line;
+
+ /* Grab the next line from the line list. */
+ ls_nxt(line_list,PPV &p_line);
+ if (p_line==NULL) break;
+
+ /* List the line if it is within context range of prev or next message. */
+ if ((((long) p_line->ln_global) <= prev_no+context) ||
+ (((long) p_line->ln_global) >= next_no-context))
+ {line_wri(p_wf,p_line);ingap=FALSE;}
+ else
+ if (!ingap)
+ {wf_wr(p_wf,".................\n");ingap=TRUE;}
+
+ /* Issue any messages that are about this line. */
+ while (next_no == p_line->ln_global)
+ {
+ /* Write the current message. */
+ mess_wri(p_wf,&next_mes,(uword) 0,
+ (uword) next_pos.up_pos.ps_column);
+
+ /* Read the next message from the table. */
+ prev_no=next_no;
+ if (tb_rea(p_msgtab,PV &next_pos,PV &next_mes))
+ next_no=next_pos.up_pos.ps_line;
+ else
+ next_no=MAXLINES+context+1;
+ }
+ } /* End while */
+
+ /* Make sure that we have read to the end of the message table. */
+ {bool result;
+ result=tb_rea(p_msgtab,PV &next_pos,PV &next_mes);
+ as_cold(!result,
+ "lr_gen: Messages remaining in message table after listing.");
+ }
+
+ /* Write listing trailer. */
+ wf_wr(p_wf,dup('-',12));wf_wr(p_wf,"+");
+ wf_wr(p_wf,dup('-',LISTWIDTH-13));wf_wr(p_wf,"\n");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+/* End of LISTER.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/lister.h b/web/funnelAC/fwACsrc/lister.h
new file mode 100644
index 0000000000..829acce655
--- /dev/null
+++ b/web/funnelAC/fwACsrc/lister.h
@@ -0,0 +1,75 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* LISTER.H */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "data.h"
+
+/******************************************************************************/
+
+EXPORT void lr_ini P_((void));
+/* Initialize the lister. Calling this function destroys all the lister */
+/* package's old internal data structures and sets them to a well-defined */
+/* initial state (empty) and prepares the lister for the incoming messages. */
+/* This function may be called at any time and many times. */
+
+EXPORT void lr_mes P_((ps_t *,char *));
+EXPORT void lr_war P_((ps_t *,char *));
+EXPORT void lr_err P_((ps_t *,char *));
+EXPORT void lr_sev P_((ps_t *,char *));
+/* The functions above allow the user to record four different kinds of */
+/* messages and to specify exactly where in the listing each message is to */
+/* appear. */
+
+EXPORT void lr_gen P_((p_wf_t,uword));
+/* Merges the global structure line_list with the message table stored by the */
+/* lister package and writes the resultant listing to the p_wf_t stream. */
+/* The second parameter is the number of lines of context around each */
+/* diagnostic. The lister does not write the entire input file out. It only */
+/* writes input lines near a diagnostic. The context argument specifies the */
+/* number of lines that should be written around each diagnostic. */
+/* Note: A context of 100 is special and means that no lines should be */
+/* omitted in between diagnostics. */
+
+/******************************************************************************/
+/* End of LISTER.H */
+/******************************************************************************/
+
diff --git a/web/funnelAC/fwACsrc/machin.c b/web/funnelAC/fwACsrc/machin.c
new file mode 100644
index 0000000000..1692ca6bf3
--- /dev/null
+++ b/web/funnelAC/fwACsrc/machin.c
@@ -0,0 +1,355 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+ JMS John Max Skaller maxtal@suphys.physics.su.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 16-Sep-1993 ABC Added machine type OSF64 for a 64-bit processor
+ running OSF/1 (particularly the DEC AXP).
+ 16-Sep-1993 ABC Changed all constants *_MAX to *_FWMAX to avoid
+ conflict with some standard UNIX constants.
+ 14-Dec-1993 ABC Added machine type OS2 for PCs running OS/2 2.1.
+ 15-Jun-1994 ABC Added machine type LINUX for PCs running
+ LINUX 1.1.8
+ 13-Aug-1995 JMS Added PC32 type for 32-bit DOS-extended code.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* MACHIN.C */
+/******************************************************************************/
+/* */
+/* WARNING: DO NOT ADD ANY PROGRAM DEPENDENT DEFINITIONS. */
+/* */
+/* This file contains machine-dependent, program-independent stuff that */
+/* implements the functionality promised in MACHIN.H. */
+/* */
+/* Note: As usual, the full definitions of functions in the .H file are not */
+/* repeated here. */
+/* */
+/******************************************************************************/
+
+#include <time.h>
+#include "style.h"
+
+#include "as.h"
+#include "machin.h"
+
+/* The Macintosh's doesn't have a command language, and so we have to prompt */
+/* for a command line. This requires a special package. */
+#if MAC
+#include <console.h>
+#endif
+
+/* Under VMS, we need RMS to get at stuff to do with filenames. */
+#if VMS
+#include RMS
+#endif
+
+/******************************************************************************/
+/* LOCAL FUNCTIONS */
+/******************************************************************************/
+
+LOCAL void mconcat P_((int,char **,char *));
+LOCAL void mconcat(argc,argv,result)
+/* Given argc and argv, as passed to main(), this function appends all the */
+/* arguments together (separated by spaces) into the string "result". */
+/* This function assists in reconstructing the command line. */
+/* This function is actually portable, so you shouldn't have to change it. */
+/* Note: "mconcat" stands for Multiple CONCATenation. */
+int argc;
+char **argv;
+char *result;
+{
+ uword i;
+ strcpy(&result[0],argv[0]);
+ for (i=1;i<argc;i++)
+ {
+ strcat(&result[0]," " );
+ strcat(&result[0],argv[i]);
+ }
+}
+
+/******************************************************************************/
+
+#if MAC | SUN | PC | PC32 | OSF64 | OS2 | LINUX
+LOCAL void fn_split P_((p_fn_t,p_fn_t,p_fn_t,p_fn_t));
+LOCAL void fn_split(p_fn,p_path,p_name,p_ext)
+/* Accepts a filename in p_fn and writes the path, name, and extension */
+/* components of the filename to the strings p_path, p_name, and p_ext. */
+p_fn_t p_fn;
+p_fn_t p_path;
+p_fn_t p_name;
+p_fn_t p_ext;
+{
+ char *p,*q;
+
+ /* Make sure that the input filename is a sensible length. */
+ as_cold(strlen(p_fn)<=FILENAME_FWMAX,"fn_split: Filename is too long.");
+
+ /* Extract the path from the input string by searching for the last */
+ /* occurrance of the special character used for directories. */
+
+ /* Find the last directory/filename separator. */
+ p=strrchr(p_fn,FN_DELIM);
+ if (p==NULL)
+ {strcpy(p_path,""); p=p_fn;}
+ else
+ {
+ memcpy(p_path,p_fn,(size_t) (p-p_fn+1));
+ p_path[(size_t) (p-p_fn+1)]=EOS;
+ p++;
+ }
+
+ /* Assert: p now points to the first character of the name field. */
+
+ /* Now locate the file extension. */
+ q=strrchr(p_fn,'.');
+ if (q==NULL)
+ {strcpy(p_ext,""); q = &p_fn[strlen(p_fn)];}
+ else
+ {strcpy(p_ext,q);}
+
+ /* Assert: q now points to the '.' preceding the extension field. */
+
+ /* Now anything between p and q must be the filename proper. */
+ for (;p<q;p++)
+ *p_name++ = *p;
+ *p_name=EOS;
+}
+#endif
+
+/******************************************************************************/
+
+#if MAC | SUN | PC | PC32 | OSF64 | OS2 | LINUX
+LOCAL void fn_join P_((p_fn_t,p_fn_t,p_fn_t,p_fn_t));
+LOCAL void fn_join(p_fn,p_path,p_name,p_ext)
+/* This function sets p_fn to the empty string and then successively appends */
+/* p_path, p_name, and p_ext. Before doing this, it checks to make sure that */
+/* there will be enough room and bombs the program if there isn't. */
+p_fn_t p_fn;
+p_fn_t p_path;
+p_fn_t p_name;
+p_fn_t p_ext;
+{
+ as_cold(strlen(p_path)+strlen(p_name)+strlen(p_ext) <= FILENAME_FWMAX,
+ "fn_join: Constructed filename is too long.");
+ strcpy(p_fn,p_path);
+ strcat(p_fn,p_name);
+ strcat(p_fn,p_ext);
+}
+#endif
+
+/******************************************************************************/
+/* EXPORTED FUNCTIONS */
+/******************************************************************************/
+
+#if MAC | SUN | PC | PC32 | OSF64 | OS2 | LINUX
+EXPORT void fn_ins(p_cur,p_add)
+p_fn_t p_cur;
+p_fn_t p_add;
+{
+ fn_t cur_path, add_path;
+ fn_t cur_name, add_name;
+ fn_t cur_extn, add_extn;
+
+ /* Split the argument file names into their component parts. */
+ fn_split(p_cur,cur_path,cur_name,cur_extn);
+ fn_split(p_add,add_path,add_name,add_extn);
+
+ /* Perform the inheriting on a field by field basis. */
+ if (strlen(add_path) > 0) strcpy(cur_path,add_path);
+ if (strlen(add_name) > 0) strcpy(cur_name,add_name);
+ if (strlen(add_extn) > 0) strcpy(cur_extn,add_extn);
+
+ /* Put the fields back together again to yield the final result. */
+ fn_join(p_cur,cur_path,cur_name,cur_extn);
+}
+#endif
+
+#if VMS
+EXPORT void fn_ins(p_cur,p_add)
+/* This VMS version of fn_ins was written with the assistance of: */
+/* Jeremy Begg (jeremy@vsm.com.au) of VSM Software Services. Thanks! */
+/* The VMS version is messy because VMS has highly structured filenames and */
+/* highly ingrained rituals for manipulating them. */
+p_fn_t p_cur;
+p_fn_t p_add;
+{
+ struct FAB cur_fab; /* FAB for SYS$PARSE */
+ struct NAM cur_nam; /* NAM for SYS$PARSE */
+ fn_t expanded; /* Result of SYS$PARSE */
+ long rms_status; /* Status of SYS$PARSE */
+
+ /*
+ printf("\nTRACE: Call of fn_ins(...).\n");
+ printf(" Current spec = \"%s\".\n",p_cur);
+ printf(" Add spec = \"%s\".\n",p_add);
+ */
+
+ /* Initialize the FAB and NAM block to something sensible. */
+ cur_fab = cc$rms_fab;
+ cur_nam = cc$rms_nam;
+
+ /* (fna,fns) is address and size of input file spec in FAB block. */
+ cur_fab.fab$l_fna = p_add;
+ cur_fab.fab$b_fns = strlen(p_add);
+
+ /* (dna,dns) is address and size of default file spec in FAB block. */
+ cur_fab.fab$l_dna = p_cur;
+ cur_fab.fab$b_dns = strlen(p_cur);
+
+ /* Connect the NAM block to the FAB block. */
+ cur_fab.fab$l_nam = &cur_nam;
+
+ /* Point the NAM block's target name fields to the target namechar array. */
+ cur_nam.nam$l_esa = &expanded;
+ cur_nam.nam$b_ess = FILENAME_FWMAX; /* Reserve last char for NULL terminator */
+
+ /* PWD => put the password from a DECnet Access Control String in the filespec
+ * SYNCHK => check syntax only, don't search for the file on disk
+ */
+ cur_nam.nam$b_nop = NAM$M_PWD + NAM$M_SYNCHK;
+
+ /* Perform the parse. */
+ rms_status = sys$parse(&cur_fab);
+ if (rms_status & 1)
+ {
+ expanded[cur_nam.nam$b_esl]=EOS; /* Terminate VMS string. */
+ strcpy(p_cur,expanded);
+ }
+ else
+ {
+ printf("Note: RMS parse failed. Could be a syntax error, could be a bug!\n");
+ }
+
+ /* TRACE printf(" Result spec = \"%s\".",p_cur); */
+}
+#endif
+
+/******************************************************************************/
+
+EXPORT void getcline(argc,argv,p_comline)
+/* Given, argc and argv, writes a command line string in p_comline. */
+/* See machin.h for a thorough definition of this function. */
+int argc;
+char **argv;
+char *p_comline;
+{
+ int argc2;
+ char **argv2;
+
+#if MAC
+ /* On the Macintosh there is no command language and therefore no command */
+ /* line. Therefore we cannot trust the argc and argv handed to us by main() */
+ /* and have to obtain a command line from other sources. */
+ /* The "ccommand" function comes from <console.h> of the THINK C libraries. */
+ argc2=ccommand(&argv2);
+#endif
+
+/* The other systems work like Unix. */
+#if SUN | VMS | PC | PC32 | OSF64 | OS2 | LINUX
+argc2=argc;
+argv2=argv;
+#endif
+
+ /* The command line is currently in pieces. Reassemble it. That's all! */
+ mconcat(argc2,argv2,p_comline);
+}
+
+/******************************************************************************/
+
+EXPORT float tim_real()
+{
+ STAVAR bool init=FALSE;
+ STAVAR time_t base;
+
+ /* The first time this routine is called, we establish a base real time */
+ /* from which real time differences are calculated. There are two reasons */
+ /* for doing this. The first is that difftime seems to be the only way to */
+ /* get ANSI C to hand over a calibrated arithmetic type holding the real */
+ /* time. The second is that we don't want to have to deal with large */
+ /* absolute times anyway. */
+ if (!init)
+ {
+ /* Returns -1 if the time is not available (ANSI 7.12.2.4). */
+ base=time(NULL);
+ init=TRUE;
+ }
+
+ /* Return the elapsed time since the base time. */
+
+/* Macintosh, VMS, and PC have difftime. */
+#if MAC | VMS | PC | PC32 | OSF64 | OS2
+ if (base == -1)
+ return 0.0;
+ else
+ return (float) difftime(time(NULL),base);
+#endif
+
+/* Sun does not have difftime; neither does LINUX */
+#if SUN | LINUX
+ return 0.0;
+#endif
+
+/* The timing functions are only used to generate performance statistics and */
+/* are not critical to FunnelWeb. There is not much harm in returning 0.0. */
+}
+
+/******************************************************************************/
+
+EXPORT float tim_cpu()
+{
+ clock_t t=clock();
+
+/* Make sure that we have a definition for CLOCKS_PER_SEC. */
+#ifndef CLOCKS_PER_SEC
+#ifdef CLK_TCK
+#define CLOCKS_PER_SEC CLK_TCK
+#else
+/* Assume one million ticks per second. */
+#define CLOCKS_PER_SEC (1000000L)
+#endif
+#endif
+
+ /* The clock() function returns -1 if the CPU time is not available. */
+ /* Otherwise it returns the number of "clocks" since power-up. */
+ if (t == -1)
+ return 0.0;
+ else
+ return ((float) t) / ((float) CLOCKS_PER_SEC);
+}
+
+/******************************************************************************/
+/* End of MACHIN.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/machin.h b/web/funnelAC/fwACsrc/machin.h
new file mode 100644
index 0000000000..d9e48aca62
--- /dev/null
+++ b/web/funnelAC/fwACsrc/machin.h
@@ -0,0 +1,342 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+ JMS John Max Skaller maxtal@suphys.physics.su.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 16-Sep-1993 ABC Added machine type OSF64 for a 64-bit processor
+ running OSF/1 (particularly the DEC AXP).
+ 16-Sep-1993 ABC Changed all constants *_MAX to *_FWMAX to avoid
+ conflict with some standard UNIX constants.
+ 14-Dec-1993 ABC Added machine type OS2 for PCs running OS/2 2.1.
+ 15-Jun-1994 ABC Added machine type LINUX for PCs running LINUX 1.1.8
+ 13-Aug-1995 JMS Added PC32 type for 32-bit DOS-extended code.
+ 19-Sep-1995 ABC Set UNIX_EOL to 1 for Unix systems (having
+ removed dependency on this from `mapper.c'.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* MACHIN.H */
+/******************************************************************************/
+/* */
+/* WARNING: DO NOT ADD ANY PROGRAM DEPENDENT DEFINITIONS. */
+/* */
+/* This module (machin.h and machin.c) contains definitions and objects */
+/* whose values depends directly on the compilation and execution */
+/* environment, but are otherwise independent from any particular computer */
+/* program. */
+/* */
+/* The only difference between the purpose of this module and the "environ" */
+/* module is that the "environ" module contains the "essentials" whereas this */
+/* module contains extra machine specific definitions and objects that will */
+/* not be required by most user modules. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_MACHIN
+#define DONE_MACHIN
+
+/******************************************************************************/
+
+#include <time.h>
+#include "style.h"
+
+/******************************************************************************/
+
+/* Machine Alignment Constraints */
+/* ----------------------------- */
+/* Some machines require that objects of particular lengths be aligned in */
+/* memory. For example, the 68000 will trap any attempt to access a word */
+/* (16 bits or an int in THINK C) at an odd address. It is important that C */
+/* programs that deal with memory at a low level be aware of such */
+/* constraints. As the constraints are always at a power of two, we defined */
+/* ALIGN_POWER to be the minimum power of two at which it is both safe and */
+/* efficient to operate. */
+
+/* The Macintosh requires words and longs to be aligned on word boundaries. */
+/* The PC is not fussy about alignment, but operates more efficiently at word */
+/* boundaries. */
+#if MAC | PC
+#define ALIGN_POWER (1L)
+#endif
+
+/* The Sun requires objects to be aligned on longword boundaries (=2^2). */
+/* The VMS VAX doesn't care about alignment, but operates more efficiently on */
+/* longword boundaries. */
+/* OS2, LINUX, and 32-bit DOS code should work better with 32 bit boundaries */
+/* as well [ABC]. */
+#if SUN | VMS | PC32 | OS2 | LINUX
+#define ALIGN_POWER (2L)
+#endif
+
+/* ABC { */
+/* 64 bit processors, such as the DEC AXP, require objects to be aligned on */
+/* 64bit boundaries (=2^4). */
+#if OSF64
+#define ALIGN_POWER (4L)
+#endif
+/* } ABC */
+
+/******************************************************************************/
+
+/* Filenames */
+/* --------- */
+/* The length and structure of filenames varies from machine to machine. The */
+/* differences addressed here are: */
+/* 1) The character used to separate directory specs from filenames. */
+/* 2) The maximum length of a filename. */
+
+/* FN_DELIM must contain the character that separates directory specs from */
+/* filenames. Notice that in the VMS case, it is "]", not "." */
+
+#if MAC
+#define FN_DELIM ':'
+#endif
+
+#if SUN | OSF64 | LINUX
+#define FN_DELIM '/'
+#endif
+
+#if VAX
+#define FN_DELIM ']'
+#endif
+
+#if PC | PC32 | OS2
+#define FN_DELIM '\\'
+#endif
+
+/* The rest of this section shouldn't have to be changed, unless you */
+/* encounter a funny with your system's definition of FILENAME_FWMAX. */
+
+/* FILENAME_FWMAX tells the maximum number of characters allowed in a filename */
+/* on the target machine. The symbol FILENAME_MAX is supposed to be defined */
+/* in stdio.h (ANSI S7.9.1) so we don't want to override that. However, if it */
+/* isn't, we need to define a safe default length. */
+/* ABC { */
+/* Note that with SysV Unix, `FILENAME_MAX' is the maximum length of the */
+/* filename alone (same as VAX definition mentioned below), without the */
+/* directory path prepended. The full filename including the directory, has */
+/* a maximum length `PATH_MAX'. */
+#ifdef PATH_MAX
+#define FILENAME_FWMAX PATH_MAX
+#else /* !PATH_MAX */
+#ifdef FILENAME_MAX
+#define FILENAME_FWMAX FILENAME_MAX
+#else /* !FILENAME_MAX */
+#define FILENAME_FWMAX 300
+#endif /* FILENAME_MAX */
+#endif /* PATH_MAX */
+/* } ABC */
+
+/* Some VAX compilers define FILENAME_MAX to be 39, which is the maximum */
+/* length of the NAME part of a VMS filename. This is not appropriate, so we */
+/* override it. */
+#if VMS
+#undef FILENAME_FWMAX
+#define FILENAME_FWMAX 255 /* Should really be NAM$C_MAXRSS */
+#endif
+
+/* ABC { */
+/* OS/2 has a 256 character file-name limit (I think). */
+#if OS2
+#undef FILENAME_FWMAX
+#define FILENAME_FWMAX 255
+#endif /* OS2 */
+/* } ABC */
+
+/* Now we can use the constant to define a filename type. */
+/* Note: For a while I defined "typedef fn_t *p_fn_t". However, this is a */
+/* pointer to an array rather than (char *) and it caused no end of problems. */
+typedef char fn_t[FILENAME_FWMAX+1];
+typedef char *p_fn_t;
+
+/******************************************************************************/
+
+/* Command Lines */
+/* ------------- */
+/* The maximum length of command line varies from machine to machine and we */
+/* define symbols to reflect this. The reason why we don't just set this to a */
+/* high value and forget about it is that FunnelWeb sometimes places */
+/* command line variables on the stack, and some machines (e.g. MAC under */
+/* THINK-C don't provide much stack space. So we have to minimize this */
+/* variable on those machines. */
+
+/* We choose a small maximum command line on the Macintosh so as to avoid */
+/* chewing up stack space when command lines have to be pushed. */
+#if MAC
+#define COMLINE_FWMAX 300
+#endif
+
+/* On the Sun, OSF/1, or LINUX machine, 1024 is a normal command line and */
+/* 2048 is safe. */
+#if SUN | OSF64 | LINUX
+#define COMLINE_FWMAX 2048
+#endif
+
+/* On the VMS, 1024 is usually adequate. */
+#if VMS
+#define COMLINE_FWMAX 1024
+#endif
+
+/* On a PC and for OS/2, we assume this is enough. */
+#if PC | PC32 | OS2
+#define COMLINE_FWMAX 300
+#endif
+
+/* Make sure that the value is not too low. */
+/* The value 300 is guaranteed by the command interpreter. */
+#if COMLINE_FWMAX < 300
+ #error COMLINE_FWMAX must be at least 300.
+#endif
+
+/* Now define a type for command lines. */
+/* Note: For a while I defined "typedef cl_t *p_cl_t". However, this is a */
+/* pointer to an array rather than (char *) and it caused no end of problems. */
+typedef char cl_t[COMLINE_FWMAX+1];
+typedef char *p_cl_t;
+
+/******************************************************************************/
+
+/* Line Termination */
+/* ---------------- */
+
+/* FunnelWeb has special-case code to make reading input files faster on */
+/* machines where the format of text files corresponds to the internal C */
+/* text stream model. The UNIX_EOL #define should be activated if and only */
+/* the host environment has text files consisting of a stream of bytes with */
+/* a single LF (ASCII,decimal-10,hex-0A) character being used to terminate */
+/* each line, and no special character to indicate end of file. */
+/* This is the same format as is used in the Unix operating system. */
+/* If you are in doubt about this, play it safe and define your environment */
+/* to be non-Unix, as non-Unix will work on ALL systems (including Unix). */
+
+#if MAC | VMS | PC | PC32 | OS2
+/* These systems do NOT use Unix EOLs. */
+#define UNIX_EOL 0
+#endif
+
+#if SUN | OSF64 | LINUX
+/* ABC { */
+#define UNIX_EOL 1
+/* } ABC */
+#endif
+
+/******************************************************************************/
+
+/* Missing Prototypes */
+/* ---------------- */
+/* Compilers that are fussy about prototypes sometimes complain about calls */
+/* to the standard libraries. These declarations solve this problem. */
+
+#if SUN
+int fclose P_((FILE *stream));
+int fputs P_((const char *s, FILE *stream));
+int fputc P_((int c, FILE *stream));
+int fflush P_((FILE *stream));
+int remove P_((const char *filename));
+int rename P_((const char *oldname, const char *newname));
+int toupper P_((int));
+int sscanf P_(());
+int fprintf P_(());
+int _filbuf P_(());
+void *memcpy P_((void *s1, void *s2, size_t n));
+void *memset P_((void *s, int c, size_t n));
+int memcmp P_((void *s1, void *s2, size_t n));
+size_t fread P_((void *ptr, size_t size, size_t nobj, FILE *stream));
+size_t fwrite P_((const void *ptr, size_t size, size_t nobj, FILE *stream));
+clock_t clock P_((void));
+time_t time P_((time_t *tp));
+int printf P_(());
+#endif /* SUN */
+
+/******************************************************************************/
+
+EXPORT void fn_ins P_((p_fn_t,char *));
+/* - The name stands for FileName INSert. */
+/* - The first argument must be a pointer to an object of type fn_t */
+/* (containing an ordinary C character string). */
+/* - The second argument must be a pointer to an ordinary C character string. */
+/* - Both arguments must contain a full, partial, or empty filename spec. */
+/* - We will refer to the arguments as f1 and f2. */
+/* - If there is a syntax error in either spec, fn_ins does nothing. */
+/* - Otherwise, it: */
+/* 1. Analyses the two filename specifications into filename field . */
+/* 2. Replaces each field in f1 by the corresponding field in f2, but */
+/* only if the corresponding field in f2 is non-empty. */
+/* 3. Optionally [concession to VMS] it may then replace blank fields */
+/* in the resulting file spec in f1 by fields from the current */
+/* global "default" directory spec. */
+/* The structure and fields of filenames will vary from machine to machine */
+/* and so this is not important. However, every implementation must structure */
+/* the filename so that it will at least RECOGNISE a file extension */
+/* (e.g. ".lis") field. */
+
+/******************************************************************************/
+
+EXPORT void getcline P_((int,char **,char *));
+/* Operating system environments vary a lot in the way in which their command */
+/* language interfaces are set up. The approach taken in FunnelWeb is to */
+/* define a "standard" Unix-like command line syntax and then insist that */
+/* other environments deliver such a command line as a single string. */
+/* This function getcline must extract such a standard command line from its */
+/* environment and copy it as a single string of not more than COMLINE_FWMAX */
+/* characters into its third argument. A description of the "standard" */
+/* command line can be found in the options package. */
+/* The first argument is given to getcline and is argc from main(). */
+/* The second argument is given to getcline and is argv from main(). */
+/* These two arguments are given in case getcline needs them to assemble the */
+/* command line (as opposed to calling e.g. VMS CLI routines). */
+/* The third argument is the string into which the result should be placed. */
+
+/******************************************************************************/
+
+EXPORT float tim_real P_((void));
+/* Returns the number of seconds between the present and an unspecified, but */
+/* statically fixed time in the past. */
+/* Returns 0.0 if this information is unavailable */
+
+EXPORT float tim_cpu P_((void));
+/* Returns the number of CPU seconds consumed between the present and an */
+/* unspecified, but statically fixed time in the past. */
+/* Returns 0.0 if this information is unavailable */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of MACHIN.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/main.c b/web/funnelAC/fwACsrc/main.c
new file mode 100644
index 0000000000..1707220994
--- /dev/null
+++ b/web/funnelAC/fwACsrc/main.c
@@ -0,0 +1,115 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 16-Sep-1993 ABC Changed all constants *_MAX to *_FWMAX to avoid
+ conflict with some standard UNIX constants.
+ 08-Aug-1995 ABC Changed include file name from "memory.h"
+ to "fwmem.h" to avoid a clash with the C++
+ standard header file "memory.h".
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* MAIN.C */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "as.h"
+#include "command.h"
+#include "data.h"
+#include "machin.h"
+#include "fwmem.h"
+
+/******************************************************************************/
+
+/* The following variables should really be local to main. However, some */
+/* compilers have a problem with this and so it has been declared here. */
+LOCVAR char *p_comline;
+LOCVAR ulong sum_all;
+
+/******************************************************************************/
+
+LOCAL void minimain P_((int,char **));
+LOCAL void minimain(argc,argv)
+/* Some compilers generate buggy code for main() and so this minimain */
+/* function has been created to take the heat off main(). */
+int argc;
+char **argv;
+{
+ /* The principal concern of this main() function is to execute FunnelWeb and */
+ /* to ensure that the correct return status is returned to the OS. So it */
+ /* seems appropriate to zero all the global diagnostic counters here. */
+ sum_fat=sum_sev=sum_err=sum_war=0;
+
+ /* Some compilers place a low limit on the total amount of statics. So we */
+ /* have to allocate space for a command line. */
+ p_comline=(char *) mm_perm((size_t) COMLINE_FWMAX+1);
+
+ /* Obtaining the command line is highly machine specific and so it has been */
+ /* delegated to a function in the non-portable "machin". Just in case argc */
+ /* and argv are to be used, we hand them in too. The result of all this is a */
+ /* standard FunnelWeb command line string in the variable 'comline'. */
+ getcline(argc,argv,p_comline);
+
+ /* Execute the command line. */
+ command(p_comline);
+
+ /* Exit to the operating system with an appropriate status code. */
+ sum_all=sum_war+sum_err+sum_sev+sum_fat;
+ if (sum_all>0)
+ exit(EXIT_FAILURE);
+ else
+ exit(EXIT_SUCCESS);
+}
+
+/******************************************************************************/
+
+int main(argc,argv)
+int argc;
+char *argv[];
+{
+ /* We don't put anything into the function main() because some compilers */
+ /* generate incorrect code for main, especially with local variables. */
+ minimain(argc,argv);
+
+ /* Keep GCC warnings happy. */
+ as_bomb("Main program dropped through.");
+ return 0;
+}
+
+/******************************************************************************/
+/* End of MAIN.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/mapper.c b/web/funnelAC/fwACsrc/mapper.c
new file mode 100644
index 0000000000..fa4c7c67a8
--- /dev/null
+++ b/web/funnelAC/fwACsrc/mapper.c
@@ -0,0 +1,343 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 08-Aug-1995 ABC Changed include file name from "memory.h"
+ to "fwmem.h" to avoid a clash with the C++
+ standard header file "memory.h".
+ 16-Aug-1995 ABC Noted existence of new `PC32' type without
+ 64K block restriction.
+ 19-Sep-1995 ABC Removed UNIX_EOL #ifdef support and instead
+ modified `stan_map' to remove non-printable
+ whitespace (not space or tab) from the end of
+ lines. This should hopefully allow FunnelWeb
+ sources files to be moved between Unix and DOS
+ without complaints about the CR characters used
+ by DOS.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* MAPPER.C */
+/******************************************************************************/
+
+#include <limits.h>
+#include "style.h"
+
+#include "as.h"
+#include "machin.h"
+#include "mapper.h"
+#include "fwmem.h"
+
+/******************************************************************************/
+
+/* When we allocate a block of memory for a mapped file, we have to allocate */
+/* a little more than the official length of the file. Here are some reasons: */
+/* */
+/* - We may wish to append an EOF character later on in the program. */
+/* - fgets, when requested to fetch n characters, fetches n characters and */
+/* then puts an EOS on the end of them. */
+/* - It is conceivable that fgets will insert a "\n" at the end of the */
+/* block if it doesn't see a "\n" just before the end of file. */
+/* */
+/* For all these reasons, we allocate a little more memory than we need. How */
+/* much more is determined by BLK_FUDGE which is set to be on the safe side. */
+#define BLK_FUDGE (20)
+
+/* The following fudge is useful for avoiding the limits of types. */
+#define LIM_FUDGE (10)
+
+/* On PCs, size_t is 16 bits and malloc cannot allocate contiguous chunks of */
+/* memory of more than about 64K. This really stuffs up FunnelWeb's capacity */
+/* map in files of length greater than 64K. I didn't think of this problem */
+/* when I designed FunnelWeb because I was thinking of the VOLUME of memory */
+/* available nowadays, rather than its organization on small computers. */
+/* Anyway, this problem should really be fixed by allowing files to be read */
+/* in in segments. Perhaps the mapper should hand over a linked list of */
+/* chunks rather than a single chunk. Unfortunately, I don't have the time to */
+/* do this now, so users of the PC version of FunnelWeb will have to be */
+/* content with an (approx) 64K limit to input files. This isn't as bad as it */
+/* sounds, as large input files can be split using the include facility. */
+/* 63K is chosen instead of 64K so as to be paranoid. */
+/* ABC { */
+/* Note that this is unnecessary for the 32-bit `PC32' type. */
+/* } ABC */
+#define PCFILEMX (63L*1024L)
+
+/******************************************************************************/
+/* */
+/* Error Strings */
+/* ------------- */
+/* Routines in this package return pointers to error strings. These pointers */
+/* are subsequently bandied about by other packages. Therefore, they must be */
+/* pointers to constant strings. The trick of returning a pointer to a static */
+/* character array containing a specific sprintf message will backfire here */
+/* if there is an error opening more than one input file. Using mm_* to */
+/* create space for each error string would work though. */
+/* STOP PRESS: Now that the lister copies error messages, there may no longer */
+/* be a problem here. */
+/* */
+/******************************************************************************/
+
+/* Finding The Length of a File */
+/* ---------------------------- */
+/* We have to be able to find out the length of a file before reading it in */
+/* because, in this version of FunnelWeb, the entire file must be read into */
+/* one contiguous block of memory. */
+/* */
+/* As it turns out, finding the length of a file in portable C turns out to */
+/* be a very hard problem. Here are some possible solutions: */
+/* */
+/* 1. Read the entire file in and see how long it is. */
+/* 2. Use fseek to move to the end of the file and then use ftell. */
+/* 3. Use the Unix 'stat' call. */
+/* */
+/* Of these, only the first is portable. The second alternative is */
+/* non-portable because some environments do not support the SEEK_END symbol */
+/* required to perform a seek to the end of file. */
+/* Alternatives to needing the length are as follows: */
+/* */
+/* 4. Read the file/allocate memory in 64K blocks. */
+/* 5. Read the file in 64K blocks and then copy them to a contiguous one. */
+/* */
+/* Perhaps options 4 or 5 could be implemented later. However, right now I */
+/* haven't got the time to do anything except strive for portability, so */
+/* option 1 it is. */
+
+LOCAL char *file_len P_((char *,ulong *));
+LOCAL char *file_len (p_name,p_length)
+/* Given a filename (in 'p_name'), returns the length of the binary image of */
+/* the file in *p_length. Returns NULL upon success or a pointer to a string */
+/* describing an error upon failure. The length is measured in bytes. */
+char *p_name;
+ulong *p_length;
+{
+ FILE *infile;
+ STAVAR char *p_buf = NULL;
+
+/* The length of the buffer handed to fgets is non-critical. However, it */
+/* mustn't be bigger than 15 bits, as we are passing it as an int to fgets. */
+#define LENBUFLEN (1024L)
+#if LENBUFLEN > 30000L
+ #error "mapper.c: LENBUFLEN must be less than 15 bits."
+#endif
+
+ /* Allocate the buffer if it has not already been allocated. */
+ if (p_buf == NULL)
+ p_buf=mm_perm((size_t) LENBUFLEN);
+
+ /* Open for TEXT reading. Earlier, I tried this using a binary read, but */
+ /* I had problems with this on the VAX (I forget what the problems were) and */
+ /* so I have switched back to a text read which is slower, but more reliable.*/
+ infile=fopen(p_name,"r");
+ if (infile == FOPEN_F)
+ return "Error fopen()ing input file (to determine its length).";
+
+ /* Start with a zero length. */
+ *p_length=0;
+
+ /* Read the file as text and count the number of bytes it contains. */
+ while (!feof(infile))
+ {
+ /* Set the buffer to the empty string so it is valid even if fgets fails. */
+ p_buf[0]=EOS;
+
+ /* Read in a whole lot of bytes. */
+ fgets(p_buf,LENBUFLEN,infile);
+
+ /* If there is an error, abort. */
+ if (ferror(infile))
+ {
+ fclose(infile);
+ return "Error fgets()ing input file (as part of determining its length).";
+ }
+
+ /* Count the bytes that we have got. If EOF occurred above AND no bytes */
+ /* were read, the EOS we planted earlier saves us. */
+ (*p_length)+=strlen(p_buf);
+ }
+
+ if (fclose(infile) == FCLOSE_F)
+ return "Error fclose()ing input file (as part of determining its length).";
+
+ return NULL;
+}
+
+/******************************************************************************/
+
+LOCAL char *stan_map P_((char *,char **,ulong *));
+LOCAL char *stan_map(p_name,pp_mem,p_length)
+/* Maps in a file using refined text stream IO calls. */
+char *p_name;
+char **pp_mem;
+ulong *p_length;
+{
+ ulong file_length; /* Number of bytes in the target input file. */
+ char *p_err; /* Temporary to store pointer to error message. */
+ FILE *infile; /* The file variable for the input file we are reading. */
+ ulong num_bytes; /* Number of bytes actually read in (may be different). */
+ char *p_bytes; /* Pointer to the memory block where all the action is. */
+ char *p_curr; /* Pointer to current position in memory block. */
+ long bytes_left; /* Number of bytes still left to read. */
+
+ /* Obtain the length of the file we are about to map in. */
+ p_err=file_len(p_name,&file_length);
+ if (p_err != NULL)
+ return p_err;
+
+ /* Complain on the PC if the file is too big to fit in one 64K segment. */
+#if PC
+ if (file_length+BLK_FUDGE > PCFILEMX)
+ return
+ "Error: Input file too big for PC FunnelWeb. Split using include files.";
+#endif
+
+ /* TRACE printf("MAPPER: LENGTH OF INPUT FILE=%lu\n",file_length); */
+
+ /* Allocate memory to hold the mapped file. */
+ /* Note: The memory allocation package bombs if there is no more memory. */
+ /* Note: As Unix stream format (the format to which we are converting) uses */
+ /* just one byte to mark the end of file, it seems highly unlikely */
+ /* that the file read in will be longer than the binary image. */
+ p_bytes=(char *) mm_temp((size_t) file_length+BLK_FUDGE);
+
+ /* If the file is of zero length, we already know its contents! */
+ /* This is probably not strictly necessary, but why pressure the code below? */
+ if (file_length==0)
+ {
+ *pp_mem = p_bytes;
+ *p_length = 0;
+ return NULL;
+ }
+
+ /* Open the file afresh in TEXT mode for portable reading. */
+ infile=fopen(p_name,"r");
+ if (infile==FOPEN_F)
+ return "Error fopen()ing input file (for reading).";
+
+ /* Read in as much of the file as we can without actually overflowing the */
+ /* buffer. If the file finished before the buffer, things have probably gone */
+ /* OK. If the buffer finishes before the file, we have a problem. */
+ /* Note: bytes_left = file_length+1 because in the following loop, we might */
+ /* read exactly up to the EOF and then be unable to actually trigger the EOF */
+ /* condition without another read. So we add one on to allow this extra read */
+ /* to take place. I don't know if this is necessary, but I certainly can't */
+ /* find anything in all my C books that will tell me. Anyway, it doesn't */
+ /* matter because we fudged in a few extra bytes earlier. */
+
+ p_curr = p_bytes; /* p_curr runs through the memory. */
+ bytes_left = file_length+1; /* Bytes left in memory allocated to hold file. */
+
+ /* ABC { */
+ num_bytes = 0;
+ /* } ABC */
+ while (!feof(infile))
+ {
+ int bytes_try;
+ int bytes_read;
+
+ /* Try to read as much as we possibly can, but not more than the integer */
+ /* limit (which can be as low as 15 bits). */
+ bytes_try = bytes_left >= ((ulong) (INT_MAX-LIM_FUDGE)) ?
+ (int) INT_MAX-LIM_FUDGE : (int) bytes_left;
+
+ /* Plan an EOS to cover the EOF case. */
+ *p_curr=EOS;
+
+ /* Attempt to read bytes_try bytes. +1 is because fgets reads n-1 bytes. */
+ fgets(p_curr,bytes_try+1,infile);
+ if (ferror(infile))
+ {
+ fclose(infile);
+ return "Error fgets()ing the input file.";
+ }
+
+ /* fgets doesn't return a length so we have to hobble behind with strlen. */
+ /* It's still probably better than using lots of fgetc calls. */
+ /* If we hit EOF and no bytes were read, the EOS we planted saves us. */
+ bytes_read = strlen(p_curr);
+ p_curr += bytes_read;
+ bytes_left -= bytes_read;
+
+ /* ABC { */
+ /* Remove non-printing whitespace from the end of the bytes which have */
+ /* been read. */
+ if ((bytes_read > 0) && !isascprn(p_curr[-1])) {
+ while ((bytes_read > 0) && !isascprn(p_curr[-1])) {
+ *(--p_curr) = EOS;
+ bytes_read--;
+ } /* end while */
+ /* } ABC */
+ *(p_curr++) = EOL;
+ num_bytes += bytes_read+1; /* +1 for EOL */
+ *p_curr = EOS;
+ } /* end if */
+ /* } ABC */
+
+ /* If we have run out of bytes in our allocated memory zone, then the */
+ /* file is longer than the length reported earlier. This is a bad thing. */
+ as_cold(bytes_left >=0,
+ "stan_map: Text representation was longer than binary rep.");
+ }
+
+ /* ABC {
+ num_bytes=(file_length+1)-bytes_left;
+ } ABC */ /* See earlier to undserstand +1. */
+
+ /* Note: We can't get fussy here and check the read in length with the */
+ /* official length, as the read-in length is the text representation which */
+ /* is allowed to be shorter than the physical (binary) length of the file. */
+
+ if (fclose(infile) == FCLOSE_F)
+ return "Error fclose()ing input file.";
+
+ /* Success. We got through the IO calls. Now fill in the blanks and go home. */
+ *pp_mem = p_bytes;
+ *p_length = num_bytes;
+ return NULL;
+}
+
+/******************************************************************************/
+
+EXPORT char *map_file(p_name,pp_mem,p_length)
+char *p_name;
+char **pp_mem;
+ulong *p_length;
+{
+ return stan_map(p_name,pp_mem,p_length);
+}
+
+/******************************************************************************/
+/* End of MAPPER.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/mapper.h b/web/funnelAC/fwACsrc/mapper.h
new file mode 100644
index 0000000000..6210206df6
--- /dev/null
+++ b/web/funnelAC/fwACsrc/mapper.h
@@ -0,0 +1,69 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* MAPPER.H */
+/******************************************************************************/
+/* */
+/* The mapper is the first of FunnelWeb's four front end processors: (mapper, */
+/* scanner, parser, analyser). The sole task of the mapper is, given the */
+/* name of a file, to create an image of that file in memory. This approach */
+/* is not wasteful of memory at all because FunnelWeb requires random access */
+/* to each input file at all times anyway so it can scramble the text around. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+EXPORT char *map_file P_((char *,char **,ulong *));
+/* Allocates a block of memory and places a Unix text stream representation */
+/* (with EOL marking end of line and no character marking end of file) of the */
+/* file 'p_name' in the block of memory. Returns a pointer to the address and */
+/* len of the file in the mem block in the parameters (pp_mem and p_length). */
+/* Returns NULL upon success or a pointer to an error message string upon */
+/* failure. Note: Parameters are: p_name, pp_mem, p_length. */
+/* Note: Allocates enough memory so that there is guaranteed to be at least */
+/* two extra bytes of spare memory at the end of the mapped file. The */
+/* scanner uses this space to put EOL and EOF characters. */
+/* Note: The mapper grabs its memory using mm_temp, so it can be recycled */
+/* as part of a call to mm_zapt. */
+
+/******************************************************************************/
+/* End of MAPPER.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/misc.c b/web/funnelAC/fwACsrc/misc.c
new file mode 100644
index 0000000000..ab1a2db9d0
--- /dev/null
+++ b/web/funnelAC/fwACsrc/misc.c
@@ -0,0 +1,235 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 08-Aug-1995 ABC Changed include file name from "memory.h"
+ to "fwmem.h" to avoid a clash with the C++
+ standard header file "memory.h".
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* MISC.C */
+/******************************************************************************/
+
+#include <ctype.h>
+#include "style.h"
+
+#include "as.h"
+#include "data.h"
+#include "fwmem.h"
+#include "misc.h"
+#include "writfile.h"
+
+/******************************************************************************/
+
+EXPORT void wr_s (s) char *s; {wf_wr(&f_s,s);}
+EXPORT void wr_j (s) char *s; {wf_wr(&f_j,s);}
+EXPORT void wr_l (s) char *s; {wf_wr(&f_l,s);}
+
+EXPORT void wl_s (s) char *s; {wf_wr(&f_s,s); wf_wr(&f_s,"\n");}
+EXPORT void wl_j (s) char *s; {wf_wr(&f_j,s); wf_wr(&f_j,"\n");}
+EXPORT void wl_l (s) char *s; {wf_wr(&f_l,s); wf_wr(&f_l,"\n");}
+
+EXPORT void wr_sj (s) char *s; {wr_s(s); wr_j(s);}
+EXPORT void wl_sj (s) char *s; {wl_s(s); wl_j(s);}
+
+EXPORT void wr_sjl(s) char *s; {wr_s(s); wr_j(s); wr_l(s);}
+EXPORT void wl_sjl(s) char *s; {wl_s(s); wl_j(s); wl_l(s);}
+
+/******************************************************************************/
+
+EXPORT char *chabbrev(ch)
+int ch;
+{
+ switch (ch)
+ {
+ case 0: return "NUL";
+ case 1: return "SOH";
+ case 2: return "STX";
+ case 3: return "ETX";
+ case 4: return "EOT";
+ case 5: return "ENQ";
+ case 6: return "ACK";
+ case 7: return "BEL";
+ case 8: return "BS";
+ case 9: return "HT";
+ case 10: return "LF";
+ case 11: return "VT";
+ case 12: return "FF";
+ case 13: return "CR";
+ case 14: return "SO";
+ case 15: return "SI";
+ case 16: return "DLE";
+ case 17: return "DC1";
+ case 18: return "DC2";
+ case 19: return "DC3";
+ case 20: return "DC4";
+ case 21: return "NAK";
+ case 22: return "SYN";
+ case 23: return "ETB";
+ case 24: return "CAN";
+ case 25: return "EM";
+ case 26: return "SUB";
+ case 27: return "ESC";
+ case 28: return "FS";
+ case 29: return "GS";
+ case 30: return "RS";
+ case 31: return "US";
+ case 127:return "DEL";
+ default: return "";
+ }
+}
+
+/******************************************************************************/
+
+EXPORT sign signof(n)
+long n;
+{
+ if (n<0) return -1;
+ if (n>0) return 1;
+ return 0;
+}
+
+/******************************************************************************/
+
+EXPORT char * eq_files(name1,name2,p_result)
+char *name1;
+char *name2;
+bool *p_result;
+{
+ FILE *file1;
+ FILE *file2;
+
+ /* The following three lines define two comparison buffers. The next part of */
+ /* the two files being compared are read into these buffers and compared. */
+ /* Using the buffers allows bulk reads, which speeds things up considerably. */
+#define CMPBUFSIZ 16384
+ STAVAR ubyte_ *buf1 = NULL;
+ STAVAR ubyte_ *buf2 = NULL;
+
+ /* Set the default result to be FALSE (no match). */
+ *p_result=FALSE;
+
+ /* Allocate the comparison buffers if they are not already allocated. */
+ if (buf1 == NULL)
+ {
+ buf1=(ubyte_ *) mm_perm((size_t) CMPBUFSIZ);
+ buf2=(ubyte_ *) mm_perm((size_t) CMPBUFSIZ);
+ }
+
+ /* Open, for binary reading, the two files to be compared. */
+ file1=fopen(name1,"rb");
+ if (file1 == FOPEN_F)
+ return "Error opening the first file.";
+ file2=fopen(name2,"rb");
+ if (file2 == FOPEN_F)
+ {fclose(file1);return "Error opening the second file.";}
+
+ while (TRUE)
+ { /* Compare a chunk. */
+ size_t len1;
+ size_t len2;
+
+ /* Read a chunk from each file. */
+ len1=fread(buf1,(size_t) 1,(size_t) CMPBUFSIZ,file1);
+ len2=fread(buf2,(size_t) 1,(size_t) CMPBUFSIZ,file2);
+ if (ferror(file1))
+ return "Compare: Error reading the first file.";
+ if (ferror(file2))
+ return "Compare: Error reading the second file.";
+
+ /* Compare the two chunks. */
+ if (len1 != len2) break;
+ if (len1 == 0) {*p_result=TRUE; break;}
+ if (memcmp(buf1,buf2,(size_t) len1) != 0) break;
+ }
+
+ if (fclose(file1) == FCLOSE_F)
+ {*p_result=FALSE; return "Error closing the first file.";}
+ if (fclose(file2) == FCLOSE_F)
+ {*p_result=FALSE; return "Error closing the second file.";}
+
+ /* If we have reached this point, we can be sure that no errors occurred. */
+ return NULL;
+}
+
+/******************************************************************************/
+
+EXPORT bool fexists(fn)
+char *fn;
+{
+ FILE *file;
+ bool success;
+
+ file=fopen(fn,"rb");
+ if (file==NULL)
+ return FALSE;
+
+ success= (fclose(file) != FCLOSE_F);
+ as_cold(success,
+ "fexists: Error closing file whose existence is being tested!");
+
+ return TRUE;
+}
+
+/******************************************************************************/
+
+EXPORT char *fn_temp()
+{
+ STAVAR uword filnum=1;
+ STAVAR fn_t fn;
+ do
+ {
+ sprintf(fn,"fwtf%04lu.tmp",(ulong) filnum);
+ filnum++;
+ }
+ while (fexists(fn));
+ return fn;
+}
+
+/******************************************************************************/
+
+EXPORT void strupper(s)
+char *s;
+{
+ while (*s != EOS)
+ {
+ *s=toupper(*s);
+ s++;
+ }
+}
+
+/******************************************************************************/
+/* End of MISC.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/misc.h b/web/funnelAC/fwACsrc/misc.h
new file mode 100644
index 0000000000..aa98dbb2f0
--- /dev/null
+++ b/web/funnelAC/fwACsrc/misc.h
@@ -0,0 +1,126 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* MISC.H */
+/******************************************************************************/
+/* */
+/* This package contains a ragbag of FunnelWeb-specific functions that didn't */
+/* seem to have a home anywhere else. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "data.h"
+
+/******************************************************************************/
+
+/* The following functions each write a string to one or more output streams. */
+/* The code is as follows: */
+/* wr - means write the string only. */
+/* wl - means write the string followed by a '\n'. */
+/* s - The f_s output stream (the console/screen). */
+/* j - The f_j output stream (the journal file). */
+/* l - The f_l output stream (the listing file). */
+/* These functions are hard wired to the f_s, f_j, and f_l global variables. */
+
+EXPORT void wr_s P_((char *));
+EXPORT void wr_j P_((char *));
+EXPORT void wr_l P_((char *));
+
+EXPORT void wl_s P_((char *));
+EXPORT void wl_j P_((char *));
+EXPORT void wl_l P_((char *));
+
+EXPORT void wr_sj P_((char *));
+EXPORT void wl_sj P_((char *));
+
+EXPORT void wr_sjl P_((char *));
+EXPORT void wl_sjl P_((char *));
+
+/******************************************************************************/
+
+EXPORT char *chabbrev P_((int));
+/* If the argument is non-printable in the range [0,127], returns a pointer */
+/* to a constant string containing the mnemonic abbreviation for the */
+/* character (e.g. 10="LF"). Otherwise returns the empty string. */
+
+/******************************************************************************/
+
+EXPORT sign signof P_((long));
+/* Returns -1 if its argument is negative. */
+/* Returns 0 if its argument is zero. */
+/* Returns 1 if its argument is positive. */
+
+/******************************************************************************/
+
+EXPORT char * eq_files P_((char *,char *,bool *));
+/* Performs an exact binary comparison of the files named name1 and name2. */
+/* If there is no error during the comparison, returns NULL and the boolean */
+/* parameter carries the result of the comparison with TRUE=>Files identical. */
+/* If there is an error during the comparison, the boolean parameter is set */
+/* to FALSE and the function returns a pointer to a string describing the */
+/* error in terms of "the first file" and "the second file". */
+
+/******************************************************************************/
+
+EXPORT bool fexists P_((char *));
+/* Returns TRUE iff a file of the name given in the parameter exists. */
+/* (Does this by attempting to open the file. If it succeeds, it closes it */
+/* again). */
+
+/******************************************************************************/
+
+EXPORT char *fn_temp P_((void));
+/* Creates a filename (not containing a directory component) for which there */
+/* is no corresponding file in the current directory. */
+/* Returns a pointer to a static array containing the filename. */
+/* Each time this function is called, the new filename overwrites the old. */
+/* This function was created after it was discovered that, on some systems, */
+/* the standard library function "tmpnam" returns the name of a file in the */
+/* /tmp partition. This would not be a problem were it not for the fact that */
+/* generally, files cannot be renamed across partitions! */
+
+/******************************************************************************/
+
+EXPORT void strupper P_((char *));
+/* Converts all lower case letters in the argument string to upper case. */
+
+/******************************************************************************/
+/* End of MISC.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/option.c b/web/funnelAC/fwACsrc/option.c
new file mode 100644
index 0000000000..3211ae18a7
--- /dev/null
+++ b/web/funnelAC/fwACsrc/option.c
@@ -0,0 +1,454 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 16-Sep-1993 ABC Changed all constants *_MAX to *_FWMAX to avoid
+ conflict with some standard UNIX constants.
+ 16-Aug-1995 ABC Added `+Qb' command line option to suppress all
+ requests for user input in case of errors, so
+ that FunnelWeb can run in a genuine batch mode.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* OPTION.C */
+/******************************************************************************/
+
+#include <ctype.h>
+#include "style.h"
+
+#include "as.h"
+#include "data.h"
+#include "machin.h"
+#include "misc.h"
+#include "option.h"
+
+/******************************************************************************/
+
+LOCAL void wl_caret P_((ulong,void (*)(char *)));
+LOCAL void wl_caret(n,p_outf)
+/* Writes a caret at position n of an otherwise blank line. */
+ulong n;
+void (*p_outf) P_((char *));
+{
+ as_cold(n<1000,"wl_caret: Argument is out of range.");
+ while (--n > 0)
+ (*p_outf)(" ");
+ (*p_outf)("^\n");
+}
+
+/******************************************************************************/
+
+EXPORT void op_ini(p_op)
+p_op_t p_op;
+{
+ p_op->op_f_b=FALSE;
+ strcpy(&p_op->op_f_s[0],"");
+
+ p_op->op_j_b=FALSE;
+ strcpy(&p_op->op_j_s[0],"");
+
+ strcpy(&p_op->op_i_s[0],"");
+
+ p_op->op_o_b=TRUE;
+ strcpy(&p_op->op_o_s[0],"");
+
+ p_op->op_t_b=FALSE;
+ strcpy(&p_op->op_t_s[0],"");
+
+ p_op->op_l_b=TRUE;
+ strcpy(&p_op->op_l_s[0],"");
+
+ p_op->op_d_b=FALSE;
+
+ p_op->op_c_i=2;
+
+ p_op->op_q_b=FALSE;
+ strcpy(&p_op->op_q_s[0],"");
+
+ p_op->op_s_b=FALSE;
+ p_op->op_s_i=1;
+
+ p_op->op_w_b=FALSE;
+ p_op->op_w_i=80;
+
+ p_op->op_x_b=FALSE;
+ strcpy(&p_op->op_x_s[0],"");
+
+ p_op->op_k_b=FALSE;
+
+ p_op->op_b1_b=FALSE;
+ p_op->op_b2_b=FALSE;
+ p_op->op_b3_b=FALSE;
+ p_op->op_b4_b=FALSE;
+ p_op->op_b5_b=FALSE;
+ p_op->op_b6_b=FALSE;
+ p_op->op_b7_b=FALSE;
+
+ p_op->op_h_b=FALSE;
+ strcpy(&p_op->op_h_s[0],"menu");
+}
+
+/******************************************************************************/
+
+EXPORT bool op_add(p_op,p_cl,p_outf)
+p_op_t p_op;
+p_cl_t p_cl;
+void (*p_outf) P_((char *));
+{
+ op_t op_save; /* Saves *p_op so it can be restored later. */
+ char *comline = (char *) p_cl; /* Pointer to the command line to be parsed. */
+ char *p; /* Handy parsing pointer. */
+ bool seen_error = FALSE; /* TRUE iff one or more errors seen. */
+
+#define ECHO_CL {if (!seen_error)\
+ {(*p_outf)(comline);(*p_outf)("\n"); seen_error=TRUE;}}
+
+ /* Save the parameter option structure so that we can restore it */
+ /* if an error occurs later on. */
+ ASSIGN(op_save,*p_op);
+
+ /* Check to make sure that the command line is not too long. */
+ /* This error should really never occur. */
+ p=comline;
+ while (*p++ != EOS)
+ if ((p-comline) > COMLINE_FWMAX)
+ {
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("The entire command line is too long.\n");
+ sprintf(linet1,"The maximum command line length is %u characters.\n",
+ (unsigned) COMLINE_FWMAX);
+ (*p_outf)(linet1);
+ goto failure;
+ }
+
+ /* Check that the command line contains only printables. */
+ p=comline;
+ while (*p != EOS)
+ {
+ if (!isascprn(*p))
+ {
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Command line contains one or more non-printables.\n");
+ sprintf(linet1,"The first is at column %u.\n",(unsigned) (1+p-comline));
+ (*p_outf)(linet1);
+ goto failure;
+ }
+ p++;
+ }
+
+ /* Now parse each option. */
+ p=comline;
+ while (TRUE)
+ {/* This loop processes one command line parameter (option) per iteration. */
+ char *p_startopt; /* Points to the start of the parameter. */
+ bool opsign; /* The sign of the current option (+=TRUE). */
+ bool opsign_active; /* TRUE => (+ or -). FALSE => (=). */
+ char letter; /* Letter of current option. */
+ cl_t cl_temp; /* Parameter string of the current option. */
+ fn_t fn_temp; /* Parameter string of the current option. */
+ int i; /* Handy int used to feed sscanf. */
+
+ /* Skip first parameter or rest of previous parameter after syntax error. */
+ while ((*p!=' ') && (*p!=EOS)) p++;
+
+ /* Skip blanks between parameters. */
+ while (*p==' ') p++;
+
+ /* At this point we are either at the start of a parameter or at EOS. */
+ /* Finish if we are at the EOS. */
+ if (*p==EOS) break;
+
+ /* p now points to the next parameter (option). Make a note of its start. */
+ p_startopt=p;
+
+ /* This switch statement parses the sign and letter characters. */
+ switch (*p)
+ {
+ case '-': opsign=FALSE; opsign_active=TRUE; p++; goto parse_letter;
+ case '+': opsign=TRUE; opsign_active=TRUE; p++; goto parse_letter;
+ case '=': opsign_active=FALSE; p++; goto parse_letter;
+ parse_letter:
+ /* We have seen a sign. There should be a following letter. */
+ letter = *p;
+ if (!isalpha(letter))
+ {
+ ECHO_CL; wl_caret(p-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Option letter expected here.\n");
+ continue; /* Skip to the next parameter. */
+ }
+ p++;
+ break;
+ default: /* If no sign the option is a NAME option and defaults to +F. */
+ opsign=TRUE; opsign_active=TRUE; letter='F'; break;
+ } /* End switch */
+
+ /* Assert: p points to the parameter string of the option. */
+ /* Copy the parameter string into the holding variable cl_temp. */
+ {char *q;
+ q = &cl_temp[0];
+ while ((*p!=EOS) && (*p!=' '))
+ *q++ = *p++;
+ *q=EOS;
+ }
+
+ /* As COMLINE_FWMAX can be greater than FILENAME_FWMAX, we have to be careful */
+ /* that the user is not about to blow our filename buffer. */
+ if (strlen(cl_temp) > FILENAME_FWMAX)
+ {
+ ECHO_CL; wl_caret(p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Option parameter string is too long.\n");
+ sprintf(linet1,"The maximum option parameter length is %u characters.\n",
+ (unsigned) FILENAME_FWMAX);
+ (*p_outf)(linet1);
+ continue; /* Skip to next parameter. */
+ }
+
+ /* Now that we know that the parameter is not too big, we can copy it */
+ /* into a temporary variable of filename type. */
+ strcpy(&fn_temp[0],&cl_temp[0]);
+
+ /* At this point p points to the character following the option that */
+ /* we have just scanned. This is either a blank or an EOS. */
+ /* The current option is held in (opsign,opsign_active,letter,fn_temp). */
+ /* Now we apply the option to the option record. */
+ switch (toupper(letter))
+ {
+ case 'F':
+ if (opsign_active) p_op->op_f_b=opsign;
+ strcpy(&p_op->op_f_s[0],&fn_temp[0]);
+ break;
+ case 'J':
+ if (opsign_active) p_op->op_j_b=opsign;
+ strcpy(&p_op->op_j_s[0],&fn_temp[0]);
+ break;
+ case 'I':
+ strcpy(&p_op->op_i_s[0],&fn_temp[0]);
+ break;
+ case 'O':
+ if (opsign_active) p_op->op_o_b=opsign;
+ strcpy(&p_op->op_o_s[0],&fn_temp[0]);
+ break;
+ case 'T':
+ if (opsign_active) p_op->op_t_b=opsign;
+ strcpy(&p_op->op_t_s[0],&fn_temp[0]);
+ break;
+ case 'L':
+ if (opsign_active) p_op->op_l_b=opsign;
+ strcpy(&p_op->op_l_s[0],&fn_temp[0]);
+ break;
+ case 'D':
+ if (opsign_active) p_op->op_d_b=opsign;
+ if (strlen(fn_temp)>0)
+ {
+ ECHO_CL; wl_caret(3+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("The D option does not take an argument.\n");
+ }
+ break;
+ case 'C':
+ if ((sscanf(&fn_temp[0],"%d",&i) != 1) || (i<0) || (100<i))
+ {
+ ECHO_CL; wl_caret(3+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Numeric argument to C option invalid. It must\n");
+ (*p_outf)("be an unsigned decimal integer in the range [0,100].\n");
+ }
+ else
+ p_op->op_c_i=i;
+ break;
+ case 'Q':
+ if (opsign_active) p_op->op_q_b=opsign;
+ if (strlen(fn_temp)>0) {
+ /* ABC { */
+ if (!strcmp(fn_temp, "b")) {
+ strcpy(&p_op->op_q_s[0],&fn_temp[0]);
+ } else {
+ ECHO_CL; wl_caret(2+p_startopt-comline+(1+i),p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Error: Character in Q argument must be 'b'.\n");
+ } /* end if */
+ /* } ABC */
+ } /* end if */
+ break;
+ case 'S':
+ if (opsign_active) p_op->op_s_b=opsign;
+ if (strlen(fn_temp)==0) break;
+ if ((sscanf(&fn_temp[0],"%d",&i) != 1) || (i<0) || (100<i))
+ {
+ ECHO_CL; wl_caret(2+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Numeric argument to S option invalid. It must\n");
+ (*p_outf)("be an unsigned decimal integer in the range [0,100].\n");
+ }
+ else
+ p_op->op_s_i=i;
+ break;
+ case 'W':
+ if (opsign_active) p_op->op_w_b=opsign;
+ if (strlen(fn_temp)==0) break;
+ if ((sscanf(&fn_temp[0],"%d",&i) != 1) || (i<0) || (1000<i))
+ {
+ ECHO_CL; wl_caret(2+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Error: Numeric argument to W option invalid. It must\n");
+ (*p_outf)("be an unsigned decimal integer in the range [0,1000].\n");
+ }
+ else
+ p_op->op_w_i=i;
+ break;
+ case 'X':
+ if (opsign_active) p_op->op_x_b=opsign;
+ strcpy(&p_op->op_x_s[0],&fn_temp[0]);
+ break;
+ case 'K':
+ if (opsign_active) p_op->op_k_b=opsign;
+ if (strlen(fn_temp)>0)
+ {
+ ECHO_CL; wl_caret(3+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("The K option does not take an argument.\n");
+ }
+ break;
+ case 'H':
+ if (opsign_active) p_op->op_h_b=opsign;
+ if (strlen(&fn_temp[0])>0)
+ if (strlen(&fn_temp[0]) > HL_NMLEN)
+ {
+ ECHO_CL; wl_caret(3+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("The H option string argument is too long.\n");
+ (*p_outf)("Try +Hmenu for a list of help message names.\n");
+ }
+ else
+ if (hel_num(&fn_temp[0]) == HL_ERR)
+ {
+ ECHO_CL; wl_caret(3+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Unrecognised message name in argument to H option.\n");
+ (*p_outf)("Try +Hmenu for a list of help message names.\n");
+ }
+ else
+ strcpy(&p_op->op_h_s[0],&fn_temp[0]);
+ break;
+ case 'B':
+ {
+ uword i;
+ if (strlen(fn_temp)==0)
+ {
+ ECHO_CL; wl_caret(3+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("The B option must be followed by one or more digits.\n");
+ (*p_outf)("The digits must be in the range 1..7.\n");
+ break;
+ }
+ for (i=0;i<strlen(fn_temp);i++)
+ if (fn_temp[i]<'1' || fn_temp[i]>'7')
+ {
+
+ECHO_CL; wl_caret(2+p_startopt-comline+(1+i),p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Error: Characters in B argument must be '1'..'7'.\n");
+ goto endbop;
+ }
+ if (opsign_active)
+ for (i=0;i<strlen(fn_temp);i++)
+ switch (fn_temp[i])
+ {
+ case '1': p_op->op_b1_b=opsign; break;
+ case '2': p_op->op_b2_b=opsign; break;
+ case '3': p_op->op_b3_b=opsign; break;
+ case '4': p_op->op_b4_b=opsign; break;
+ case '5': p_op->op_b5_b=opsign; break;
+ case '6': p_op->op_b6_b=opsign; break;
+ case '7': p_op->op_b7_b=opsign; break;
+ default: as_bomb("op_add: b option case defaulted.");
+ }
+ endbop:
+ break;
+ }
+ default:
+ ECHO_CL; wl_caret(2+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Error: Unknown option letter.\n");
+ (*p_outf)("Legal option letters are FIOTLCSWPXZ.\n");
+ (*p_outf)("(Note: But P is not yet implemented!)\n");
+ break;
+ }
+ } /* End while. */
+ if (seen_error) goto failure;
+ return TRUE;
+
+ failure: ASSIGN(*p_op,op_save); return FALSE;
+ }
+
+/******************************************************************************/
+
+EXPORT void op_wri(p_op,p_outf)
+p_op_t p_op;
+void (*p_outf) P_((char *));
+{
+#define STC(BOOLV) ((BOOLV)?'+':'-')
+ sprintf(linet1," %cB1 %cB2 %cB3 %cB4 %cB5 %cB6 %cB7\n",
+ STC(p_op->op_b1_b),
+ STC(p_op->op_b2_b),
+ STC(p_op->op_b3_b),
+ STC(p_op->op_b4_b),
+ STC(p_op->op_b5_b),
+ STC(p_op->op_b6_b),
+ STC(p_op->op_b7_b));(*p_outf)(linet1);
+ sprintf(linet1," +C%u\n" , (unsigned) p_op->op_c_i );(*p_outf)(linet1);
+ sprintf(linet1," %cD\n" , STC(p_op->op_d_b) );(*p_outf)(linet1);
+ sprintf(linet1," %cF%s\n", STC(p_op->op_f_b), p_op->op_f_s );(*p_outf)(linet1);
+ sprintf(linet1," %cH%s\n", STC(p_op->op_h_b), p_op->op_h_s );(*p_outf)(linet1);
+ sprintf(linet1," +I%s\n" , p_op->op_i_s );(*p_outf)(linet1);
+ sprintf(linet1," %cJ%s\n", STC(p_op->op_j_b), p_op->op_j_s );(*p_outf)(linet1);
+ sprintf(linet1," %cK\n" , STC(p_op->op_k_b) );(*p_outf)(linet1);
+ sprintf(linet1," %cL%s\n", STC(p_op->op_l_b), p_op->op_l_s );(*p_outf)(linet1);
+ sprintf(linet1," %cO%s\n", STC(p_op->op_o_b), p_op->op_o_s );(*p_outf)(linet1);
+ /* ABC { */
+ sprintf(linet1," %cQ%s\n", STC(p_op->op_q_b), p_op->op_q_s );(*p_outf)(linet1);
+ /* } ABC */
+ sprintf(linet1," %cS%u\n", STC(p_op->op_s_b), (unsigned) p_op->op_s_i );(*p_outf)(linet1);
+ sprintf(linet1," %cT%s\n", STC(p_op->op_t_b), p_op->op_t_s );(*p_outf)(linet1);
+ sprintf(linet1," %cW%u\n", STC(p_op->op_w_b), (unsigned) p_op->op_w_i );(*p_outf)(linet1);
+ sprintf(linet1," %cX%s\n", STC(p_op->op_x_b), p_op->op_x_s );(*p_outf)(linet1);
+}
+
+/******************************************************************************/
+/* End of OPTION.C */
+/******************************************************************************/
+
diff --git a/web/funnelAC/fwACsrc/option.h b/web/funnelAC/fwACsrc/option.h
new file mode 100644
index 0000000000..b0b57e90b0
--- /dev/null
+++ b/web/funnelAC/fwACsrc/option.h
@@ -0,0 +1,180 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 16-Aug-1995 ABC Added `op_q_s' string to `op_t' structure to
+ accomodate the addition of a `+Qb' batch mode
+ command line switch.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* OPTION.H */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_OPTION
+#define DONE_OPTION
+
+/******************************************************************************/
+
+#include "style.h"
+
+#include "machin.h"
+#include "help.h"
+
+/******************************************************************************/
+
+/* THE B7 OPTION */
+/* ------------- */
+/* When FunnelWeb was first ported to different machines and the regression */
+/* testing was activated, a most irritating occurance was the failure of the */
+/* results of tests on different machines to compare, because of minor */
+/* differences in implementation. For example, error messages that contained */
+/* file names would differ because the directory name on different machines */
+/* was different. Another example was error messages that quoted */
+/* implementation limits. This problem was solved by creating the B7 option */
+/* which instructs FunnelWeb to suppress all output that is */
+/* non-deterministic, machine specific, or which in any other way would cause */
+/* an unncessary failure of the test suite. */
+
+/* The following symbol provides a simple replacement for filenames in error */
+/* messages. */
+#define SUPPNAME "<<Suppressed>>"
+#define SUPPVAL "<<Suppressed>>"
+
+/******************************************************************************/
+
+/* The following structure stores all the information that can be */
+/* communicated in one or more command lines. An important aspect of the */
+/* structure is that it is totally self contained; it does not contain any */
+/* pointers to outside structures such as command lines. */
+/* The rather strange field names are explained as follows: */
+/* 1) Local names must be distinct to 8 characters (for portability). */
+/* 2) All structure field names should be unique (for portability). */
+/* Some of the older compilers use a single field structure name space. */
+/* 3) The op_ is used as a prefix for entities in this whole package. */
+/* 4) The next letter is the option letter itself. It is not intended that */
+/* the command line option names be tightly bound to the internal */
+/* identifier names -- the command line names are just convenient. */
+/* 5) The next letter gives the type: [B]oolean, [S]tring, [I]nteger. */
+
+typedef struct
+ {
+ bool op_f_b; /* The input file. */
+ fn_t op_f_s;
+
+ bool op_j_b; /* The journal file. */
+ fn_t op_j_s;
+
+ fn_t op_i_s; /* Include file (default). */
+
+ bool op_o_b; /* Product files (default). */
+ fn_t op_o_s;
+
+ bool op_t_b; /* Typeset file (default). */
+ fn_t op_t_s;
+
+ bool op_l_b; /* Listing file (default). */
+ fn_t op_l_s;
+
+ bool op_d_b; /* Delete output files that have not changed? */
+
+ uword op_c_i; /* Lines of error context in listing file. */
+
+ bool op_q_b; /* Quiet mode. Console chatter suppressed if turned on. */
+ /* ABC { */
+ fn_t op_q_s;
+ /* } ABC */
+
+ bool op_s_b; /* Send errors to the screen with specified context. */
+ uword op_s_i;
+
+ bool op_w_b; /* Set maximum line length of product files. */
+ uword op_w_i;
+
+ bool op_x_b; /* Execute specified file in FunnelWeb shell. */
+ fn_t op_x_s;
+
+ bool op_k_b; /* Interactive (keyboard) mode. */
+
+ /* Dump flags: */
+ bool op_b1_b; /* Dump input file image. */
+ bool op_b2_b; /* Dump line list. */
+ bool op_b3_b; /* Dump token list. */
+ bool op_b4_b; /* Dump macro table. */
+ bool op_b5_b; /* Dump document list. */
+ bool op_b6_b; /* Dump time summary. */
+ bool op_b7_b; /* Don't write anything non-deterministic or machine */
+ /* specific. This option is designed to assist in */
+ /* regression testing. */
+
+ bool op_h_b; /* Help messages. */
+ hn_t op_h_s;
+ } op_t;
+
+typedef op_t *p_op_t;
+
+/******************************************************************************/
+
+EXPORT void op_ini P_((p_op_t));
+/* Initializes the specified options structure with default values. */
+/* This includes ALL the fields of the structure. If, for example, the */
+/* default value of op_l_b is FALSE, op_l_s will be set to the empty string. */
+
+EXPORT bool op_add P_((p_op_t,p_cl_t,void (*)(char *)));
+/* Parses the specified command line and places the information given in the */
+/* command line into specific fields of the options structure. The options */
+/* structure should be entirely defined upon entry, as this parsing function */
+/* only ADDS information present in the command line. Call op_ini if you */
+/* don't want to initialize all the fields manually. */
+/* The comline string should start with the leading command (e.g. "fw"). */
+/* However, he leading command is ignored. */
+/* Returns FALSE: One or more syntax errors have been detected. One or error */
+/* messages have been written using the funtion argument. */
+/* *p_op unchanged. */
+/* Returns TRUE : No syntax errors. Comline information placed in *p_op. */
+
+EXPORT void op_wri P_((p_op_t,void (*)(char *)));
+/* Writes a text representation of the specified options record using the */
+/* function argument. */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of OPTION.H */
+/******************************************************************************/
+
diff --git a/web/funnelAC/fwACsrc/parser.c b/web/funnelAC/fwACsrc/parser.c
new file mode 100644
index 0000000000..d34d7c122b
--- /dev/null
+++ b/web/funnelAC/fwACsrc/parser.c
@@ -0,0 +1,1476 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 31-Aug-1993 ABC Added support for EL_SPEC
+ 31-Aug-1993 ABC Added internal macros @<#line@>, @<#file@>.
+ 16-Sep-1993 ABC Changed all constants *_MAX to *_FWMAX to avoid
+ conflict with some standard UNIX constants.
+ 10-May-1994 ABC Added DYN_NAMES option to allow macro and
+ section names to be allocated dynamically
+ instead of statically.
+ 16-Jul-1994 ABC Added support for automatic insertion of #line
+ directives by supporting automatic calling of
+ of a macro (such as @<line@>).
+ 06-Aug-1995 ABC Added support for extra language types when
+ the `allow_source_code_typing' pragma is used.
+ 06-Aug-1995 ABC Modified `pr_name' to check for a source code
+ type as will for macros attached to files.
+ 08-Aug-1995 ABC Changed include file name from "memory.h"
+ to "fwmem.h" to avoid a clash with the C++
+ standard header file "memory.h".
+ 10-Aug-1995 ABC Added internal macro @<#timestamp@>
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* PARSER.C */
+/******************************************************************************/
+
+#include <setjmp.h>
+#include "style.h"
+
+#include "as.h"
+#include "data.h"
+#include "lister.h"
+#include "machin.h"
+#include "mapper.h"
+#include "fwmem.h"
+#include "misc.h"
+#include "parser.h"
+#include "section.h"
+#include "table.h"
+
+/******************************************************************************/
+
+#define DUMMYINT 0 /* It doesn't matter what this value is!!! */
+#define TKPS &(p_tk->tk_ps) /* A commonly used construct. */
+
+/******************************************************************************/
+
+/* The following variables look after sections. */
+LOCVAR sn_t last_sn; /* Hierarchical section number of last section. */
+LOCVAR ps_t pssection; /* Position of last section. */
+LOCVAR p_dc_t p_secdc; /* Pointer to current section document component. */
+LOCVAR tk_t *p_tk; /* Pointer to the current token (a structure). */
+LOCVAR ulong sequence; /* Current sequence number. */
+LOCVAR jmp_buf jmp_pos; /* Setjmp() position of main parsing loop. */
+
+
+/******************************************************************************/
+/* Comparison Functions */
+/******************************************************************************/
+
+LOCAL sign cm_name P_((name_t *,name_t *));
+LOCAL sign cm_name(name1,name2)
+/* Compares two names and returns: */
+/* -1 if name1 < name2 */
+/* 0 if name1 = name2 */
+/* 1 if name1 > name2 */
+/* Provides a full ordering on the set of names. */
+name_t *name1;
+name_t *name2;
+{
+ return signof(strcmp(&(*name1)[0],&(*name2)[0]));
+}
+
+/******************************************************************************/
+
+LOCAL sign eq_txst P_((p_scls_t,char *));
+LOCAL sign eq_txst(p_scls,p_str)
+/* The first argument is a list of text scraps. */
+/* The second argument is an ordinary string. */
+/* Returns TRUE iff the two are identical. Otherwise FALSE. */
+p_scls_t p_scls;
+char *p_str;
+{
+ /* To compare the scrap list with the string, we run through the scrap list */
+ /* comparing the bytes its scraps yield progressively with the string. */
+ /* The two scanning groups are (p_scls,p_sc,p_ch) and p_str. */
+ sc_t *p_sc;
+
+ ls_fir(p_scls);
+ ls_nxt(p_scls,PPV &p_sc);
+ while (p_sc!=NULL)
+ {
+ /* The loop body compares a single scrap pointed to by p_sc. */
+ char *p_ch;
+ for (p_ch=p_sc->sc_first; p_ch<=p_sc->sc_last; p_ch++)
+ {
+ if (*p_str==EOS || *p_str != *p_ch) return FALSE;
+ p_str++;
+ }
+ ls_nxt(p_scls,PPV &p_sc);
+ }
+ return *p_str==EOS;
+}
+
+/******************************************************************************/
+/* Parsing Primitives */
+/******************************************************************************/
+/* The following functions provide the basic parsing primitives used by the */
+/* main parsing routines. */
+/******************************************************************************/
+
+LOCAL void next_tk P_((bool));
+LOCAL void next_tk(iseoferr)
+/* This function reads the next token from the token list and places a */
+/* pointer to the token (structure) in the global variable "token". */
+/* The "iseoferr" determines whether a fuss should be made if the next token */
+/* fetched is TK_EOF. If iseoferr==TRUE and the next token is TK_EOF, next_tk */
+/* jumps to the main parsing loop. */
+bool iseoferr;
+{
+ ls_nxt(token_list,PPV &p_tk);
+ as_cold(p_tk!=NULL,"next_tk: Attempted to read next token at EOF.");
+ if (iseoferr && p_tk->tk_kind==TK_EOF)
+ {
+ lr_err(TKPS,"Ouch! High velocity encounter with end of file.");
+ lr_mes(TKPS,"FunnelWeb expected something else when it hit the EOF.");
+ longjmp(jmp_pos,DUMMYINT); /* Jump up to the main parsing loop. */
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void recover P_((void));
+LOCAL void recover()
+/* Parsing functions call this function at points where a syntax error has */
+/* has occurred that it is unlikely that the particular parsing function will */
+/* be able to recover from on its own. In these situations, the parser */
+/* resorts to a course grained syntactic error-recovery implemented by this */
+/* function. The goal of the error recovery system is to skip tokens until */
+/* the next major outer-level-syntax structure is encountered. These are: */
+/* - A new section (@A etc.). */
+/* - A macro definition (@$ or @O). */
+/* - End of file. */
+/* Once one of these three is found, "recover" raises the syntax exception */
+/* which sends control to the main parsing loop which is the correct place */
+/* to deal with a new, major syntactic construct. */
+{
+ lr_mes(TKPS,"Skipping after error to the next major construct...");
+
+ /* Skip to one of TK_NSEC,... */
+ while (TRUE)
+ {
+ tk_k_t k = p_tk->tk_kind;
+ if (k==TK_NSEC || k==TK_MDEF || k==TK_FDEF || k==TK_EOF) break;
+ next_tk(FALSE);
+ }
+
+ /* Keep the user informed. */
+ lr_mes(TKPS,"...skipped to here after the error.");
+
+ /* Jump up to the main parsing loop. */
+ longjmp(jmp_pos,DUMMYINT);
+}
+
+/******************************************************************************/
+
+LOCAL void genexerr P_((tk_k_t));
+LOCAL void genexerr(tk_kind)
+/* Genexerr stands for GENerate EXpecting ERRor. */
+/* Given a token kind, genexerr issues an error saying that the specified */
+/* kind of token was expected. It then invokes recover() for error recovery. */
+tk_k_t tk_kind;
+{
+ switch (tk_kind)
+ {
+ /* Note: Not all token kinds are listed here. Only those token kinds that */
+ /* are passed to pr_token and check_tk by the main parsing routines are */
+ /* included here. There are some tokens that one never expects! */
+ case TK_NSEC: lr_err(TKPS,"Expecting '@*'."); break;
+ case TK_ONAM: lr_err(TKPS,"Expecting '@<'."); break;
+ case TK_ODEF: lr_err(TKPS,"Expecting '@{'."); break;
+ case TK_CDEF: lr_err(TKPS,"Expecting '@}'."); break;
+ case TK_EMPH: lr_err(TKPS,"Expecting '@/'."); break;
+ case TK_CPAR: lr_err(TKPS,"Expecting '@)'."); break;
+ case TK_QUOT: lr_err(TKPS,"Expecting '@\"'."); break;
+ case TK_PARM: lr_err(TKPS,"Expecting one of [@1..@9]." ); break;
+ case TK_TEXT: lr_err(TKPS,"Expecting a text character."); break;
+ default: as_bomb("genexerr: Case defaulted.");
+ }
+ recover();
+}
+
+/******************************************************************************/
+
+LOCAL void pr_token P_((tk_k_t));
+LOCAL void pr_token(tk_kind)
+/* Parses a single token of the specified kind. */
+/* If the token is of the specified kind, gets the next token. */
+/* If the token is not of the specified kind, generates an "expecting" error. */
+tk_k_t tk_kind;
+{
+ if (p_tk->tk_kind != tk_kind)
+ genexerr(tk_kind);
+ next_tk(TRUE);
+}
+
+/******************************************************************************/
+
+LOCAL void check_tk P_((tk_k_t));
+LOCAL void check_tk(tk_kind)
+/* Same as pr_token, but only checks that the token is OK. Does not move on. */
+tk_k_t tk_kind;
+{
+ if (p_tk->tk_kind != tk_kind)
+ genexerr(tk_kind);
+}
+
+/******************************************************************************/
+
+LOCAL void ass_tk P_((tk_k_t));
+LOCAL void ass_tk(tk_kind)
+/* Aborts the program if the current token is not of the specified kind. */
+/* This function is intended to perform internal consistency checks, and */
+/* should not be considered to be part of the parsing operation. */
+tk_k_t tk_kind;
+{
+ as_cold(p_tk->tk_kind==tk_kind,"Parser.ass_tk: Incorrect token.");
+}
+
+/******************************************************************************/
+
+LOCAL void ass_tks P_((tk_k_t,tk_k_t));
+LOCAL void ass_tks(tk_kind1,tk_kind2)
+/* Same as ass_tk except it allows a choice of two token kinds. */
+tk_k_t tk_kind1;
+tk_k_t tk_kind2;
+{
+ as_cold((p_tk->tk_kind == tk_kind1) || (p_tk->tk_kind == tk_kind2),
+ "Parser.ass_tks: Token is neither of two allowables.");
+}
+
+/******************************************************************************/
+/* Main Parsing Functions */
+/******************************************************************************/
+
+/* The parse expression procedures are the only procedures for which forward */
+/* declarations are required. This is a product of the recursive definition */
+/* of a FunnelWeb expression. */
+LOCAL void pr_exp P_((p_ells_t *,p_ma_t));
+
+/******************************************************************************/
+
+LOCAL void pr_text P_((p_scls_t *,bool *));
+LOCAL void pr_text(pp_scls,p_white)
+/* This function parses a sequence of zero or more text tokens (until it runs */
+/* into a non-text token) and constructs a list of scraps containing the text */
+/* pointed to by the tokens. In addition the function writes TRUE to its */
+/* second argument iff all of the text scraps are whitespace. */
+p_scls_t *pp_scls;
+bool *p_white;
+{
+ *pp_scls=ls_cre(sizeof(sc_t));
+ *p_white=TRUE;
+
+ while (p_tk->tk_kind==TK_TEXT)
+ {
+ *p_white = *p_white && p_tk->tk_sc.sc_white;
+ ls_add(*pp_scls,PV &p_tk->tk_sc);
+ next_tk(FALSE);
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void pr_white P_((p_scls_t *));
+LOCAL void pr_white(pp_scls)
+/* Same as pr_text, but generates an error if the text is non-white. */
+p_scls_t *pp_scls;
+{
+ bool iswhite;
+ ps_t ps;
+ ASSIGN(ps,p_tk->tk_ps);
+ pr_text(pp_scls,&iswhite);
+ if (!iswhite)
+ lr_err(&ps,"Expecting whitespace text.");
+}
+
+/******************************************************************************/
+
+LOCAL void pr_name P_((char *,char *));
+LOCAL void pr_name(p_name,p_srctnam)
+/* Parses a single FunnelWeb name (e.g. "@<Sloth@>" and "@#K"). */
+char *p_name; /* Really should be of type p_name_t but this caused trouble. */
+/* ABC { */
+char *p_srctnam;
+/* } ABC */
+{
+ uword namelen = 0;
+/* ABC { */
+char *p_curr_str; /* current string being parsed */
+/* } ABC */
+
+ /* Deal with the special case of a token name. */
+ if (p_tk->tk_kind==TK_NAME)
+ {
+ p_name[0]=p_tk->tk_gen;
+ p_name[1]=EOS;
+ p_srctnam[0]=EOS;
+ next_tk(TRUE);
+ return;
+ }
+
+ ass_tk(TK_ONAM);
+ next_tk(TRUE);
+ p_curr_str = p_name;
+ p_srctnam[0] = EOS;
+
+ while (TRUE)
+ switch (p_tk->tk_kind)
+ {
+ case TK_TEXT:
+ {
+ /* Copy the text token to the name array, checking all the time. */
+ char *p;
+ for (p=p_tk->tk_sc.sc_first; p<=p_tk->tk_sc.sc_last; p++)
+ {
+ if (*p==EOL)
+ {
+ lr_err(TKPS,"Names cannot cross lines.");
+ recover();
+ }
+ namelen++;
+ if (namelen>NAME_FWMAX)
+ {
+ lr_err(TKPS,"Name is too long.");
+ sprintf(linet1,
+ "The maximum length of a legal name is %lu characters.",
+ (unsigned long) NAME_FWMAX);
+ lr_mes(TKPS,linet1);
+ recover();
+ }
+ p_curr_str[namelen-1] = *p;
+ }
+ next_tk(TRUE);
+ break;
+ }
+/* ABC { */
+ case TK_COMA:
+ /* A source type name has been supplied. */
+ p_curr_str[namelen]=EOS;
+ next_tk(TRUE);
+ namelen = 0;
+ p_curr_str = p_srctnam;
+ break;
+/* } ABC */
+ case TK_CNAM:
+ /* We finish successfully if we hit a close name token "@>". */
+ p_curr_str[namelen]=EOS;
+ next_tk(TRUE);
+ return;
+ default:
+ lr_err(TKPS,"Illegal character or symbol in name.");
+ recover();
+ } /* End switch */
+}
+
+/******************************************************************************/
+
+LOCAL void pr_dctxt P_((void));
+LOCAL void pr_dctxt()
+/* Parse a major text chunk. */
+{
+ dc_t dc;
+ bool dummybool;
+ ps_t pstext;
+
+ ass_tk(TK_TEXT);
+
+ ASSIGN(pstext,p_tk->tk_ps);
+ pr_text(&dc.dc_text,&dummybool);
+ ASSIGN(dc.dc_ps,pstext);
+ dc.dc_kind=DC_TEXT;
+ ls_add(document_list,PV &dc);
+}
+
+/******************************************************************************/
+
+LOCAL void sendtype P_((ty_k_t));
+LOCAL void sendtype(ty_kind)
+/* Send a document component of kind typesetter directive with no attributes. */
+ty_k_t ty_kind;
+{
+ dc_t dc;
+ ASSIGN(dc.dc_ps,p_tk->tk_ps);
+ dc.dc_kind = DC_TYPE;
+ dc.dc_ty.ty_kind=ty_kind;
+ ls_add(document_list,PV &dc);
+}
+
+/******************************************************************************/
+
+LOCAL void pr_lit P_((void));
+LOCAL void pr_lit()
+/* Parse a string delimited by literal typeset directives e.g. @{sloth@}. */
+{
+ /* Check and get past opening directive. */
+ ass_tk(TK_ODEF);
+ sendtype(TY_OLIT);
+
+ /* Move past the opening directive and parse the sandwich text. */
+ next_tk(TRUE);
+ if (p_tk->tk_kind!=TK_TEXT)
+ {
+ lr_err(TKPS,"Text expected after open literal token \"@{\".");
+ if (p_tk->tk_kind==TK_CDEF)
+ lr_mes(TKPS,"Sorry, empty literal strings are not allowed.");
+ recover();
+ }
+ pr_dctxt();
+
+ /* Check and parse the closing directive. */
+ pr_token(TK_CDEF);
+ sendtype(TY_CLIT);
+}
+
+/******************************************************************************/
+
+LOCAL void pr_emp P_((void));
+LOCAL void pr_emp()
+/* Parse a string delimited by emphasis typeset directives e.g. @/sloth@/. */
+{
+ /* Check and get past opening directive. */
+ ass_tk(TK_EMPH);
+ sendtype(TY_OEMP);
+
+ /* Move past the opening directive and parse the sandwich text. */
+ next_tk(TRUE);
+ if (p_tk->tk_kind!=TK_TEXT)
+ {
+ lr_err(TKPS,"Text expected after open emphasise token \"@/\".");
+ if (p_tk->tk_kind==TK_EMPH)
+ lr_mes(TKPS,"Sorry, empty emphasised strings are not allowed.");
+ recover();
+ }
+ pr_dctxt();
+
+ /* Check and parse the closing directive. */
+ pr_token(TK_EMPH);
+ sendtype(TY_CEMP);
+}
+
+/******************************************************************************/
+
+LOCAL void pr_npag P_((void));
+LOCAL void pr_npag()
+/* Parse a newpage token. */
+{
+ ass_tk(TK_NPAG);
+ sendtype(TY_NPAG);
+ pr_token(TK_NPAG);
+}
+
+/******************************************************************************/
+
+LOCAL void pr_tocs P_((void));
+LOCAL void pr_tocs()
+/* Parse a table of contents token. */
+{
+ ass_tk(TK_TOCS);
+ sendtype(TY_TOCS);
+ pr_token(TK_TOCS);
+}
+
+/******************************************************************************/
+
+LOCAL void pr_skip P_((void));
+LOCAL void pr_skip()
+/* Parse a skip token. */
+{
+ dc_t dc;
+ ass_tk(TK_SKIP);
+ ASSIGN(dc.dc_ps,p_tk->tk_ps);
+ dc.dc_kind = DC_TYPE;
+ dc.dc_ty.ty_kind=TY_SKIP;
+ dc.dc_ty.ty_mm=p_tk->tk_gen;
+ ls_add(document_list,PV &dc);
+ pr_token(TK_SKIP);
+}
+
+/******************************************************************************/
+
+LOCAL void pr_titl P_((void));
+LOCAL void pr_titl()
+/* Parse a title token. Bascially moving bones from one grave to another. */
+{
+ dc_t dc;
+ ass_tk(TK_TITL);
+ ASSIGN(dc.dc_ps,p_tk->tk_ps);
+ dc.dc_kind = DC_TYPE;
+ dc.dc_ty.ty_kind = TY_TITL;
+ dc.dc_ty.ty_font = p_tk->tk_gen / LRFT_PACK;
+ dc.dc_ty.ty_align = p_tk->tk_gen % LRFT_PACK;
+ ASSIGN(dc.dc_ty.ty_sc,p_tk->tk_sc);
+ ls_add(document_list,PV &dc);
+ pr_token(TK_TITL);
+}
+
+/******************************************************************************/
+
+LOCAL void pr_sec P_((void));
+LOCAL void pr_sec()
+/* Parse a new section marker ("@A.. and @*") and its optional name. */
+{
+ ps_t secps; /* Position of this new section. */
+ ubyte level; /* Level number of new section. */
+ bool has_name; /* Set to TRUE iff the section has a name. */
+ name_t name; /* Name of the section (if it has a name). */
+ /* ABC { */
+ name_t srctnam; /* Name of the source code type (if any). */
+ /* } ABC */
+
+ /* If called, a new section marker must have been seen. */
+ ass_tk(TK_NSEC);
+
+ /* Grab a copy of the position of the start of the section. */
+ ASSIGN(secps,p_tk->tk_ps);
+
+ /* Grab the level number of the section marker. Move to the next token. */
+ level=p_tk->tk_gen;
+ next_tk(TRUE);
+
+ /* Check for a discontinuity in level. */
+ if (level>sn_lev(&last_sn)+1)
+ {
+ if (sn_lev(&last_sn)==0)
+ lr_err(&secps,"The first section in a document must be an @A section.");
+ else
+ {
+ sprintf(linet1,"The next section (at line %lu) is too deep.",
+ (unsigned long) secps.ps_line);
+ lr_mes(&pssection,linet1);
+ lr_err(&secps,"This section is more than one level deeper than the last");
+ sprintf(linet1,"section (at line %lu). Example: @B followed by @D is not allowed.",
+ (unsigned long) pssection.ps_line);
+ lr_mes(&secps,linet1);
+ }
+ /* At this point we know that the section structure of the document is */
+ /* faulty and that the weaver will never be invoked. As such the */
+ /* principal concern becomes that of error recovery. The best we can do */
+ /* there is to set to the specified level regardless of how silly it is. */
+ /* This ensures that we generate section errors only relative to the */
+ /* previous section. Thus, we avoid cascades of errors, if, for example */
+ /* the user mistypes an @A at the beginning of a FunnelWeb document. */
+ /* Once an error has occurred we don't care about the actual numbers. */
+ sn_set(&last_sn,level);
+ }
+
+ /* Actually increment the section number at the specified level. */
+ sn_inc(&last_sn,level);
+
+ /* Record the position. */
+ ASSIGN(pssection,secps);
+
+ /* Parse optional name (e.g. "@<Sloth@>"). */
+ if (p_tk->tk_kind==TK_ONAM || p_tk->tk_kind==TK_NAME)
+ {
+ pr_name(name,srctnam);
+ if (strlen(srctnam) > 0)
+ as_bomb("pr_sec: Sections cannot have source code types.");
+ has_name=TRUE;
+ }
+ else
+ {
+ strcpy(name,"No name given");
+ has_name=FALSE;
+ }
+
+ /* Place all the information we have into a document component structure */
+ /* and add it to the document list. */
+ {
+ dc_t dc;
+ ASSIGN(dc.dc_ps,secps);
+ dc.dc_kind = DC_TYPE;
+ dc.dc_ty.ty_kind=TY_NSEC;
+ ASSIGN(dc.dc_ty.ty_sn,last_sn);
+ dc.dc_ty.ty_isnam = has_name;
+/* ABC { */
+#if DYN_NAMES
+ dc.dc_ty.ty_name = (char*)mm_temp((strlen(name)+1)*sizeof(char));
+ strcpy(dc.dc_ty.ty_name,&name[0]);
+#else /* !DYN_NAMES */
+ strcpy(&dc.dc_ty.ty_name[0],&name[0]);
+#endif /* DYN_NAMES */
+/* } ABC */
+ ls_add(document_list,PV &dc);
+ ls_tai(document_list,PPV &p_secdc);
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void rem_name P_((char *));
+LOCAL void rem_name(p_name)
+/* rem_name stands for REMember NAME. rem_name accepts a pointer to a name. */
+/* It looks up the name in the global macro table, and if the name is in the */
+/* table performs no action. If the name isn't in the table, it creates a new */
+/* entry for the name, filling the entry's fields with "blank" values. */
+/* The rem_name function should not be seen as recording the definition of a */
+/* macro. This is handled by the md_isdef field. Instead the rem_name macro */
+/* should be viewed as just creating the space in the table for the info. */
+char * p_name; /* Really should be of type p_name_t but this caused trouble. */
+{
+ if (!tb_itb(macro_table,PV p_name))
+ {
+ p_ma_t p_macro=(p_ma_t) mm_temp(sizeof(ma_t));
+ /* ABC { */
+#if DYN_NAMES
+ p_macro->ma_name =
+ (char*)mm_temp((strlen(p_name)+1)*sizeof(char));
+ strcpy(p_macro->ma_name,&p_name[0]);
+#else /* !DYN_NAMES */
+ strcpy(&p_macro->ma_name[0],&p_name[0]);
+#endif /* DYN_NAMES */
+ /* } ABC */
+ p_macro->ma_calls = ls_cre(sizeof(mc_t));
+ p_macro->ma_defn.md_isdef = FALSE;
+ /* ABC { */
+ p_macro->ma_defn.md_aldm = NULL;
+ /* } ABC */
+ p_macro->ma_actn = ls_cre(sizeof(p_elll_t));
+ tb_ins(macro_table,PV p_name,PV &p_macro);
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void chk_whex P_((p_ps_t,p_ells_t,p_scls_t *));
+LOCAL void chk_whex(p_ps,p_ex,pp_white)
+/* This function should really be a subfunction of pr_plist. However, C */
+/* doesn't allow nested functions so we have to put it here. This function is */
+/* called after pr_plist has just parsed an opening expression followed by */
+/* @". This means that the expression should consist of whitespace crud. Our */
+/* mission here is to check that it really does contain only whitespace crud */
+/* and return a text list containing the crud. If, on the other hand, it */
+/* contains meatier items, we have to call recover(). */
+p_ps_t p_ps; /* Position of the start of the expression. */
+p_ells_t p_ex; /* The expression that we have to check out. */
+p_scls_t *pp_white; /* The place to put the resultant whitespace list. */
+{
+ p_el_t p_el;
+
+ /* If the expression is empty, we can return an empty list. */
+ if (ls_len(p_ex)==0)
+ {
+ *pp_white=ls_cre(sizeof(sc_t));
+ return;
+ }
+
+ /* If there is more than one element, there is ...trouble. */
+ if (ls_len(p_ex) > 1) goto trouble;
+
+ /* Extract the first element of the list. */
+ ls_fir(p_ex); ls_nxt(p_ex,PPV &p_el);
+
+ /* If it's not text, there is ...trouble. */
+ if (p_el->el_kind != EL_TEXT) goto trouble;
+
+ /* If the text isn't lilly white, there is ...trouble. */
+ {
+ p_scls_t p_scls = p_el->el_text;
+ p_sc_t p_sc;
+ ls_fir(p_scls);
+ while (TRUE)
+ {
+ ls_nxt(p_scls,PPV &p_sc);
+ if (p_sc==NULL) break;
+ if (!p_sc->sc_white) goto trouble;
+ }
+ /* If we got this far, we know that the expression contains a single */
+ /* element and that that element is a text list and that that text */
+ /* list consists entirely of whitespace. We can now return it. */
+ *pp_white=p_scls;
+ return;
+ }
+
+ /* We COULD start dissecting the expression and issuing detailed specific */
+ /* error messages. However, the general approach is cleaner and so a general */
+ /* error message is used. */
+ trouble:
+ lr_err( p_ps,"Everything from here...");
+ lr_mes(TKPS,"...to here should be whitespace.");
+ lr_mes(TKPS,"Use of @\" to delimit macro parameters is optional, but");
+ lr_mes(TKPS,"if they are used, any surrounding text must be white.");
+ recover();
+}
+
+/******************************************************************************/
+
+LOCAL void pr_plist P_((p_elll_t *, p_scll_t *, p_scll_t *,p_ma_t));
+LOCAL void pr_plist(pp_plist,p_before,p_after,p_curmac)
+/* This function parses an optional parameter list. If the current token is */
+/* not TK_OPAR, then it is assumed that no list is present and no tokens are */
+/* consumed and empty lists are returned. */
+/* The three lists returned are: */
+/* A list of parameters each being a pointer to a list of elements. */
+/* A list of whitespace blocks being the space before each parameter. */
+/* A list of whitespace blocks being the space after each parameter. */
+/* The last parameter p_curmac should be supplied by the caller and should */
+/* contain a pointer to the macro currently being parsed. */
+p_elll_t *pp_plist;
+p_scll_t *p_before;
+p_scll_t *p_after;
+p_ma_t p_curmac;
+{
+ /* Initialize all the result lists to empty. */
+ *pp_plist = ls_cre(sizeof(p_ells_t));
+ *p_before = ls_cre(sizeof(p_scls_t));
+ *p_after = ls_cre(sizeof(p_scls_t));
+
+ /* The parameter list is optional. If it isn't there we assume a null one. */
+ if (p_tk->tk_kind!=TK_OPAR)
+ return;
+ next_tk(TRUE);
+
+ /* Now parse the parameter list, one parameter during each iteration. */
+ while (TRUE)
+ {
+ ps_t exp_ps;
+ p_ells_t p_ex;
+ p_scls_t p_white;
+
+ /* Things get a little tricky here because the double quotes around */
+ /* parameters are optional (per parameter). Thus the following calls are */
+ /* all legal (and functionally identical): */
+ /* @<Sloth@>@( @"walrus@" @, @"aardvark@" @) */
+ /* @<Sloth@>@(walrus@, @"aardvark@" @) */
+ /* @<Sloth@>@(walrus@,aardvark@) */
+
+ /* Note the position of the start of this parameter slot. */
+ ASSIGN(exp_ps,p_tk->tk_ps);
+
+ /* Because we face either crud text or an expression, we parse an exp. */
+ pr_exp(&p_ex,p_curmac);
+
+ /* Now take a look at the next token. If it is @" we know that we have */
+ /* been parsing whitespace crud. If it is @, or @) we know that we have */
+ /* been parsing the parameter expression itself. */
+ if (p_tk->tk_kind==TK_COMA || p_tk->tk_kind==TK_CPAR)
+ {
+ p_scls_t p_scls = ls_cre(sizeof(sc_t));
+ ls_add(*p_before,PV &p_scls); /* Add empty whitespace to crud list. */
+ ls_add(*pp_plist,PV &p_ex); /* Add expression to parameter list. */
+ ls_add(*p_after ,PV &p_scls); /* Add empty whitespace to crud list. */
+ }
+ else
+ if (p_tk->tk_kind==TK_QUOT)
+ {
+ /* After parsing the expression we hit a @". This means that the */
+ /* expression just parsed SHOULD turn out to contain a single */
+ /* element consisting of a white space text list. */
+ chk_whex(&exp_ps,p_ex,&p_white);
+ ls_add(*p_before,PV &p_white);
+
+ /* Get past the quote. */
+ next_tk(TRUE);
+
+ /* Parse the expression and add it to the parameter list. */
+ pr_exp(&p_ex,p_curmac); ls_add(*pp_plist,PV &p_ex);
+
+ /* Parse the quote to move onto the whitespace. */
+ pr_token(TK_QUOT);
+
+ /* Parse the whitespace after the parameter. */
+ {p_scls_t p_white; pr_white(&p_white); ls_add(*p_after,PV &p_white);}
+ }
+ else
+ {lr_err(TKPS,"Expecting @\" or @, or @)."); recover();}
+
+ /* The parameter list can now end (TK_CPAR) or continue (TK_COMA). */
+ if (p_tk->tk_kind==TK_COMA)
+ next_tk(TRUE);
+ else
+ if (p_tk->tk_kind==TK_CPAR)
+ {next_tk(TRUE);return;}
+ else
+ {lr_err(TKPS,"Expecting @, or @)."); recover();}
+ } /* End while */
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void pr_invelt P_((p_ells_t,p_el_t,p_ma_t));
+LOCAL void pr_invelt(ex,p_el,p_curmac)
+/* } ABC */
+/* Parses an "invocation element" which is just FunnelWebSpeak for "macro */
+/* call". Upon entry the current token must be TK_ONAM or TK_NAME which */
+/* presumably is the start of a macro call. Returns a pointer to an element */
+/* object describing the call. Does some other macro table stuff too. */
+/* p_curmac should be supplied by the caller and should be a pointer to the */
+/* macro currently being parsed. */
+p_ells_t ex;
+p_el_t p_el;
+p_ma_t p_curmac;
+{
+ name_t name; /* Name of the macro being invoked. */
+/* ABC { */
+ name_t srctnam; /* Name of the source code type. */
+/* } ABC */
+ ps_t mc_ps; /* Position of the start of the macro invocation. */
+ mc_t mc; /* Macro call object that describes the invocation. */
+ p_ma_t p_callee; /* Pointer to the macro object of the target macro. */
+ p_elll_t parlist; /* The parameter list of the invocation. */
+ p_scll_t before; /* Whitespace before each parameter in the param list. */
+ p_scll_t after; /* Whitespace after each parameter in the param list. */
+
+ /* We shouldn't have been called unless we have seen the start of a name. */
+ ass_tks(TK_ONAM,TK_NAME);
+
+ /* Note the position of the start of the invocation. */
+ mc_ps=p_tk->tk_ps;
+
+ /* Parse the invocation (name and optional parameter list). */
+ pr_name(name,srctnam);
+ if (strlen(srctnam) > 0)
+ as_bomb("pr_invelt: Macro invocations cannot have source code types.");
+ pr_plist(&parlist,&before,&after,p_curmac);
+
+ /* Ensure that there is an entry for this macro name in the macro table. */
+ rem_name(name);
+
+ /* Construct a macro call object describing the call and add it to the */
+ /* callee macro's call list. */
+ /* Note: The +1 in sequence+1 is because the sequence number is incremented */
+ /* at the end of each macro definition and we are only halfway here. */
+ mc.mc_seq = sequence + 1;
+ mc.mc_ps = mc_ps;
+ mc.mc_npar = ls_len(parlist);
+ tb_loo(macro_table,PV name,PV &p_callee);
+ ls_add(p_callee->ma_calls,PV &mc);
+
+ /* Write an invocation element describing the call to the parameter. */
+ p_el->el_kind = EL_INVC;
+ p_el->el_p_mac = p_callee;
+ p_el->el_parls = parlist;
+ p_el->el_pretx = before;
+ p_el->el_postx = after;
+ /* ABC { */
+ p_el->el_ps = mc_ps;
+ /* } ABC */
+}
+
+/******************************************************************************/
+
+LOCAL void pr_txtelt P_((p_el_t));
+LOCAL void pr_txtelt(p_el)
+/* Parses a text element. Upon entry, the current token must be of type */
+/* TK_TEXT. Writes a text element into its parameter. */
+p_el_t p_el;
+{
+ p_scls_t p_scls;
+ bool dummy;
+ ass_tk(TK_TEXT);
+ /* ABC { */
+ p_el->el_ps = p_tk->tk_ps;
+ /* } ABC */
+ pr_text(&p_scls,&dummy);
+ p_el->el_kind = EL_TEXT;
+ p_el->el_text = p_scls;
+}
+
+/******************************************************************************/
+
+LOCAL void pr_parelt P_((p_el_t,p_ma_t));
+LOCAL void pr_parelt(p_el,p_curmac)
+/* Parses a parameter element (e.g. @5). Writes the resultant parameter */
+/* element object to the first parameter. The second parameter should be */
+/* supplied by the caller and should be a pointer to the macro being parsed. */
+p_el_t p_el;
+p_ma_t p_curmac;
+{
+ /* We have to be sitting on a parameter token. */
+ ass_tk(TK_PARM);
+
+ /* Complain if the parameter does not exist. */
+ if (p_tk->tk_gen > p_curmac->ma_defn.md_npar)
+ {
+ sprintf(linet1,"Macro being defined has only %lu parameter%s.",
+ (unsigned long) p_curmac->ma_defn.md_npar,
+ p_curmac->ma_defn.md_npar==1 ? "" : "s");
+ lr_err(TKPS,linet1);
+ }
+
+ /* Write a parameter element to the function parameter. */
+ p_el->el_kind = EL_PARM;
+ p_el->el_parno = p_tk->tk_gen;
+ p_el->el_which = p_curmac;
+
+ /* Move on to the token following the parameter token. */
+ next_tk(TRUE);
+}
+
+/******************************************************************************/
+
+LOCAL void pr_exp(p_ex,p_curmac)
+/* Parses an expression and writes an expression list to the first parameter. */
+/* The second parameter should be supplied by the user and should be a */
+/* pointer to the macro currently being parsed. */
+p_ells_t *p_ex;
+p_ma_t p_curmac;
+{
+ p_ells_t ex = ls_cre(sizeof(el_t));
+
+ while (TRUE)
+ {
+ el_t el;
+ switch (p_tk->tk_kind)
+ {
+ case TK_TEXT: pr_txtelt(&el); break;
+ case TK_NAME:
+ case TK_ONAM: pr_invelt(ex,&el,p_curmac); break;
+ case TK_PARM: pr_parelt(&el,p_curmac); break;
+ default : *p_ex=ex; return;
+ }
+ ls_add(ex,PV &el);
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void pr_formal P_((uword *,p_ps_t));
+LOCAL void pr_formal(p_numpar,p_ps)
+/* A FunnelWeb formal parameter list looks something like this: "@(@5@)". */
+/* This function parses a parameter list if present and returns the number of */
+/* parameters in the formal parameter list. The function also returns the */
+/* position the parameter list. */
+uword *p_numpar;
+p_ps_t p_ps;
+{
+ /* If the parameter list is absent, we default to having zero parameters and */
+ /* making the position of the parameter list the position of the next token. */
+ *p_numpar = 0;
+ *p_ps = p_tk->tk_ps;
+
+ /* Parse the parameter list only if one is present. */
+ if (p_tk->tk_kind==TK_OPAR)
+ {
+ /* Move to the parameter token and get its number and position. */
+ next_tk(TRUE);
+ check_tk(TK_PARM);
+ *p_numpar=p_tk->tk_gen;
+ *p_ps=p_tk->tk_ps;
+
+ /* Parse the end of the formal parameter list. */
+ next_tk(TRUE);
+ pr_token(TK_CPAR);
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void pr_number P_((bool *,bool *));
+LOCAL void pr_number(p_iszer,p_isman)
+/* Parses optional @Z@M after parameter list. */
+bool *p_iszer;
+bool *p_isman;
+{
+ *p_iszer=FALSE;
+ *p_isman=FALSE;
+
+ /* The following parse allows zero, one or both of @Z@M, but in order. */
+
+ /* Grab an @Z if it is there. */
+ if (p_tk->tk_kind==TK_ZERO)
+ {
+ next_tk(TRUE);
+ *p_iszer=TRUE;
+ }
+
+ /* Grab an @M too if it is there. */
+ if (p_tk->tk_kind==TK_MANY)
+ {
+ next_tk(TRUE);
+ *p_isman=TRUE;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void pr_equals P_((bool *,p_ps_t));
+LOCAL void pr_equals(isadd,p_ps)
+/* Parses optional "==" or "+=". Sets *isadd==TRUE iff "+=" parsed else FALSE.*/
+/* Sets *p_ps to the position of the equals. */
+bool *isadd;
+p_ps_t p_ps;
+{
+ p_scls_t p_scls;
+ bool dummy;
+
+ /* Grab a copy of the position of the equals (even if it is not there) . */
+ ASSIGN(*p_ps,p_tk->tk_ps);
+
+ /* If the equals isn't there, we default to FALSE. */
+ *isadd=FALSE;
+ if (p_tk->tk_kind!=TK_TEXT) return;
+
+ /* Parse text tokens producing a text list. */
+ pr_text(&p_scls,&dummy);
+
+ /* Compare the text list with the assignment constant strings. */
+ if (eq_txst(p_scls,"==")) {*isadd=FALSE; ls_des(p_scls); return;}
+ if (eq_txst(p_scls,"+=")) {*isadd=TRUE; ls_des(p_scls); return;}
+
+ lr_err(p_ps,"Expecting \"==@{\" or \"+=@{\" or just \"@{\".");
+ lr_mes(p_ps,"(or @Z or @M if they have not already appeared).");
+ lr_mes(p_ps,"Note: FunnelWeb is intolerant of spaces at this point.");
+ ls_des(p_scls);
+ recover();
+}
+
+/******************************************************************************/
+
+LOCAL bool checkdef P_((p_ma_t,bool,ulong,bool,bool,bool,
+ p_ps_t,p_ps_t,p_ps_t,p_ps_t));
+LOCAL bool checkdef (p_ma,is_file,numpar,iszer,isman,isadd,
+ p_psnam,p_psfor,p_pseql,p_psnum)
+/* This function performs all sorts of checks on a macro definition. */
+/* If there is anything wrong, it generates and error and calls recover(). */
+/* This would be best as a local function but because C doesn't have local */
+/* functions we have to use millions of parameters instead. */
+p_ma_t p_ma;
+bool is_file;
+ulong numpar;
+bool iszer;
+bool isman;
+bool isadd;
+p_ps_t p_psnam;
+p_ps_t p_psfor;
+p_ps_t p_pseql;
+p_ps_t p_psnum;
+{
+ bool semerr = FALSE;
+
+ /* CHECK INTERNAL INCONSISTENCIES */
+ /* ------------------------------ */
+ /* Complain if a file macro has a parameter list. */
+ if (is_file && numpar>0)
+ {
+ lr_err(p_psfor,"Macros attached to output files cannot be parameterized.");
+ lr_mes(p_psfor,"Reason: No actual parameters would be available during");
+ lr_mes(p_psfor," output file generation.");
+ semerr=TRUE;
+ }
+
+ /* Complain if a file macro is declared additive. */
+ if (is_file && isadd)
+ {
+ lr_err(p_pseql,"Macros attached to output files cannot be additive.");
+ lr_mes(p_pseql,"Reason: Preventing this makes it easy to find output");
+ lr_mes(p_pseql,"file macros later, because there will be exactly one");
+ lr_mes(p_pseql,"@O declaration in the input file for each output file.");
+ lr_mes(p_pseql,"To do what you are trying to do, just create an additive");
+ lr_mes(p_pseql,"bridging macro, like this:");
+ lr_mes(p_pseql," @O@<prog.c@>@{@<Bridge@>@}");
+ lr_mes(p_pseql," @$@<Bridge@>+=@{void stringhack()...@}");
+ lr_mes(p_pseql," @$@<Bridge@>+=@{main()...@}");
+ semerr=TRUE;
+ }
+
+ /* Complain if a file macro has a name that is too long. */
+ /* ABC { */
+#if DYN_NAMES
+ if (is_file && strlen(p_ma->ma_name)>FILENAME_FWMAX)
+#else /* !DYN_NAMES */
+ if (is_file && strlen(&p_ma->ma_name[0])>FILENAME_FWMAX)
+#endif /* DYN_NAMES */
+ /* } ABC */
+ {
+ lr_err(p_psnam,
+ "File macro's name is longer than the maximum permissible filename length.");
+ sprintf(linet1,"Maximum filename length is %lu characters.",
+ (unsigned long) FILENAME_FWMAX);
+ lr_mes(p_psnam,linet1);
+ semerr=TRUE;
+ }
+
+ /* Complain if a file macro has "zero" or "many" attributes. */
+ if (is_file && (iszer || isman))
+ {
+ lr_err(p_psnum,"Macros attached to output files cannot have @Z or @M.");
+ lr_mes(p_psnum,"Reason: They are always called once to generate their");
+ lr_mes(p_psnum,"output file and they cannot be called from other macros.");
+ lr_mes(p_psnum,"Hence they are always called exactly once and so there");
+ lr_mes(p_psnum,"can be no need for @Z or @M in their declarations.");
+ semerr=TRUE;
+ }
+
+ /* COMPARE WITH EARLIER DEFINITIONS */
+ /* -------------------------------- */
+ /* Don't do this section if no previous definition exists. */
+ if (!p_ma->ma_defn.md_isdef) goto finish;
+
+ /* Assert: An earlier definition of this macro exists. */
+
+ /* Old definition is a full definition, not admitting partial ones now. */
+ if (!p_ma->ma_defn.md_isadd)
+ {
+ if (isadd)
+ {
+ sprintf(linet1,"A full definition of this macro appears at line %lu.",
+ (ulong) p_ma->ma_defn.md_ps.ps_line);
+ lr_err(p_psnam,linet1);
+ lr_mes(p_psnam,"Full and additive definitions of the same macro cannot coexist.");
+ }
+ else
+ {
+ sprintf(linet1,"This macro is already fully defined (at line %lu).",
+ (ulong) p_ma->ma_defn.md_ps.ps_line);
+ lr_err(p_psnam,linet1);
+ }
+ semerr=TRUE;
+ }
+
+ /* Old definition is partial but new definition is full. */
+ if (p_ma->ma_defn.md_isadd && !isadd)
+ {
+ sprintf(linet1,"An additive definition of this macro appears at line %lu.",
+ (ulong) p_ma->ma_defn.md_ps.ps_line);
+ lr_err(p_psnam,linet1);
+ lr_mes(p_psnam,"Full and additive definitions of the same macro cannot coexist.");
+ semerr=TRUE;
+ }
+
+ /* Make sure that non-first body parts of additive macros do not have params.*/
+ if (isadd && (numpar>0))
+ {
+ lr_err(p_psfor,"The formal parameter list of an additive macro");
+ lr_mes(p_psfor,"must be placed only in the first definition part.");
+ sprintf(linet1,"The first part of this macro appears at line %lu.",
+ (ulong) p_ma->ma_defn.md_ps.ps_line);
+ lr_mes(p_psfor,linet1);
+ semerr=TRUE;
+ }
+
+ /* Complain if number attributes are being attached to an additive. */
+ if (isadd && (iszer || isman))
+ {
+ lr_err(p_psnum,"@Z and @M modifiers for additive macros must");
+ lr_mes(p_psnum,"be placed only in the first definition part.");
+ sprintf(linet1,"The first part of this macro appears at line %lu.",
+ (ulong) p_ma->ma_defn.md_ps.ps_line);
+ lr_mes(p_psnum,linet1);
+ semerr=TRUE;
+ }
+
+ finish:
+ if (semerr)
+ {
+ lr_mes(p_psnam,"Macro definition ignored.");
+ recover();
+ }
+ return TRUE;
+}
+
+/******************************************************************************/
+
+LOCAL void pr_macro P_((void));
+LOCAL void pr_macro()
+/* This function parses a single macro definition. Upon entry, the current */
+/* token must be either TK_MDEF or TK_FDEF. */
+{
+ ps_t ps_mac; /* Position of start of the macro definition. */
+ bool is_file; /* TRUE iff definition starts with @O instead of @$. */
+ name_t name; /* The macro name appearing in this definition. */
+/* ABC { */
+ name_t srctname; /* The name of the source code type, if applicable. */
+/* } ABC */
+ p_ma_t p_ma; /* Pointer to the macro record corresponding to 'name'. */
+ ps_t ps_name; /* Position of the macro name. */
+ ps_t ps_form; /* Position of the formal parameter list. */
+ ps_t ps_equal; /* Position of the equals. */
+ ps_t ps_num; /* Position of number attributes. */
+ uword numpar; /* Number of parameters in formal parameter list. */
+ bool iszer; /* TRUE iff macro is allowed to be called zero times. */
+ bool isman; /* TRUE iff macro is allowed to be called more than once. */
+ bool isadd; /* TRUE iff equals parsed here is "+=" not "==". */
+ p_ells_t ex; /* Expression constituting this macro body part. */
+ bool hasname; /* TRUE iff current section already has a name. */
+/* ABC { */
+ p_srcnmac_t p_srctype; /* Pointer to a source code type structure. */
+/* } ABC */
+
+ /* We should not have got in here without seeing a definition token. */
+ ass_tks(TK_MDEF,TK_FDEF);
+
+ /* Grab a copy of the position of the start of the macro. */
+ ASSIGN(ps_mac,p_tk->tk_ps);
+
+ /* If we have seen a macro definition token then it means that the user is */
+ /* TRYING to define a macro. The macro may or may not provoke errors. In */
+ /* either case though we do not want to hassle the user with errors about */
+ /* nameless sections not containing macros if it is obvious that an attempt */
+ /* to define a macro has been made. So here we set the name flag after */
+ /* having a look at it so we can use its value later. */
+ if (sn_lev(&last_sn)>0)
+ {
+ as_cold(p_secdc->dc_kind==DC_TYPE,"pr_macro: section processing error (1).");
+ as_cold(p_secdc->dc_ty.ty_kind==TY_NSEC,"pr_macro: section processing error (2).");
+ hasname=p_secdc->dc_ty.ty_isnam;
+ p_secdc->dc_ty.ty_isnam=TRUE;
+ }
+
+ /* Record whether the macro is attached to an product file. */
+ is_file= (p_tk->tk_kind==TK_FDEF);
+
+ /* Parse the macro name. Record its position. Ensure that there is an entry */
+ /* in the macro table for this macro name (i.e. create one if not there). */
+ next_tk(TRUE);
+ if (p_tk->tk_kind!=TK_ONAM && p_tk->tk_kind!=TK_NAME)
+ {
+ lr_err(TKPS,"Macro name expected (@<...@> or @#c).");
+ recover();
+ }
+ ps_name=p_tk->tk_ps;
+ pr_name(name, srctname);
+ if (!xsrctypesQ && (strlen(srctname) > 0))
+ as_bomb("pr_macro: A pragma is needed to allow source code typing.");
+ rem_name(name);
+ tb_loo(macro_table,PV name,PV &p_ma);
+
+ /* Parse the optional formal parameter list and the equals. */
+ /* Extract positioning and other information. */
+ pr_formal(&numpar,&ps_form );
+ ASSIGN(ps_num,p_tk->tk_ps);
+ pr_number(&iszer, &isman);
+ pr_equals(&isadd ,&ps_equal);
+
+ /* Perform semantic checks on whether this definition is valid. */
+ checkdef(p_ma,is_file,numpar,iszer,isman,isadd,
+ &ps_name,&ps_form,&ps_equal,&ps_num);
+
+ /* If we have got this far, we know that we have parsed a valid macro */
+ /* definition except possibly for the actual expression body. */
+ /* If this is the first definition of this macro, establish its definition. */
+ if (!p_ma->ma_defn.md_isdef)
+ {
+ p_ma->ma_defn.md_isdef = TRUE;
+ ASSIGN(p_ma->ma_defn.md_ps,ps_mac);
+ p_ma->ma_defn.md_npar = numpar;
+ p_ma->ma_defn.md_isadd = isadd;
+ p_ma->ma_defn.md_iszer = iszer;
+ p_ma->ma_defn.md_isman = isman;
+ p_ma->ma_defn.md_isfil = is_file;
+/* ABC { */
+ if (p_ma->ma_defn.md_isfil) {
+ ls_fir(srctlist);
+ for (;;) { /* forever */
+ ls_nxt(srctlist, (pp_lsel_t)&p_srctype);
+ if (p_srctype == NULL) break;
+ if (p_srctype->typnam == NULL) {
+ if (strlen(srctname) == 0) break;
+ } else {
+ if (!strcmp(srctname, p_srctype->typnam)) break;
+ } /* end if */
+ } /* end forever */
+ p_ma->ma_defn.md_aldm = p_srctype;
+ } else {
+ p_ma->ma_defn.md_aldm = NULL;
+ } /* end if */
+/* } ABC */
+ p_ma->ma_defn.md_body = ls_cre(sizeof(bp_t));
+ if (is_file) tb_ins(file_table,PV name,PV &p_ma);
+ }
+
+ /* Parse the body of this macro definition. */
+ pr_token(TK_ODEF); pr_exp(&ex,p_ma); pr_token(TK_CDEF);
+
+ /* We are now clear to execute the effects of the macro on our tables. */
+ /* First we bump up the sequence number. */
+ sequence++;
+
+ {
+ /* Construct a body part object containing the information in this */
+ /* definition and append it to the list of body parts in the macro record. */
+ bp_t bp;
+ bp.bp_ex = ex;
+ bp.bp_seq = sequence;
+ bp.bp_ps = ps_name;
+ ls_add(p_ma->ma_defn.md_body,PV &bp);
+ }
+
+ {
+ /* Construct a document component object for this definition and append it */
+ /* to the global document component list. */
+ dc_t dc;
+ ASSIGN(dc.dc_ps,ps_mac);
+ dc.dc_kind = DC_MACR;
+ dc.dc_p_ma = p_ma;
+ dc.dc_part = ls_len(p_ma->ma_defn.md_body);
+ ls_add(document_list,PV &dc);
+ }
+
+ /* Sections without names inherit the name of their first macro. */
+ if (sn_lev(&last_sn)>0 && !hasname) {
+ /* ABC { */
+#if DYN_NAMES
+ p_secdc->dc_ty.ty_name =
+ (char*)mm_temp((strlen(name)+1)*sizeof(char));
+ strcpy(p_secdc->dc_ty.ty_name,name);
+#else /* !DYN_NAMES */
+ strcpy(&p_secdc->dc_ty.ty_name[0],name);
+#endif /* DYN_NAMES */
+ /* } ABC */
+ } /* end if */
+}
+
+/* ABC { */
+/******************************************************************************/
+
+LOCAL void pr_spinit P_((char*, sf_k_t));
+LOCAL void pr_spinit(p_name, selection)
+/* Initialises a single internal macro, associating the given name with *
+ * a value describing the actual function selected. */
+char *p_name;
+sf_k_t selection;
+{
+ p_ma_t p_macro;
+ bp_t bp;
+ el_t el;
+
+ p_macro = (p_ma_t)mm_temp(sizeof(ma_t));
+#if DYN_NAMES
+ p_macro->ma_name = (char*)mm_temp((strlen(p_name)+1)*sizeof(char));
+#endif /* DYN_NAMES */
+ strcpy(p_macro->ma_name, p_name);
+ p_macro->ma_calls = ls_cre(sizeof(mc_t));
+ p_macro->ma_actn = ls_cre(sizeof(p_elll_t));
+
+ p_macro->ma_defn.md_isdef = TRUE; /* Yes, being pre-defined */
+ p_macro->ma_defn.md_ps.ps_declQ = FALSE;
+ /* Not explicitly declared */
+ p_macro->ma_defn.md_npar = 0; /* No parameters */
+ p_macro->ma_defn.md_isadd = FALSE; /* Can't add to definition */
+ p_macro->ma_defn.md_iszer = TRUE; /* Doesn't have to be called */
+ p_macro->ma_defn.md_isman = TRUE; /* Can be called many times */
+ p_macro->ma_defn.md_isfil = FALSE; /* Not attached to a file */
+ p_macro->ma_defn.md_aldm = NULL; /* Not a file macro */
+
+ p_macro->ma_defn.md_body = ls_cre(sizeof(bp_t));
+ bp.bp_seq = 0; /* Not really valid here, just a definite value */
+ bp.bp_ps.ps_declQ = FALSE; /* Not explicitly declared */
+ bp.bp_ex = ls_cre(sizeof(el_t));
+
+ el.el_kind = EL_SPEC; /* Special function */
+ el.el_selec = selection; /* Particular function */
+
+ ls_add(bp.bp_ex, PV &el);
+ ls_add(p_macro->ma_defn.md_body, PV &bp);
+
+ tb_ins(macro_table,PV p_name,PV &p_macro);
+}
+
+/******************************************************************************/
+
+LOCAL void pr_intern P_((void));
+LOCAL void pr_intern()
+/* This routine initialises the document with a set of standard internal */
+/* macros which give access to such things as the line number and file name */
+/* for a given position in the FunnelWeb source. */
+{
+ STAVAR char lineMacroName[] = "#line";
+ STAVAR char fileMacroName[] = "#file";
+ STAVAR char tstampMacroName[] = "#timestamp";
+ /* EL_SPEC && SF_LIN : source line macro @<#line@> */
+ pr_spinit(lineMacroName, SF_LIN);
+ /* EL_SPEC && SF_FIL : source line macro @<#file@> */
+ pr_spinit(fileMacroName, SF_FIL);
+ /* EL_SPEC && SF_TMS : source line macro @<#timestamp@> */
+ pr_spinit(tstampMacroName, SF_TMS);
+}
+/* } ABC */
+
+/******************************************************************************/
+
+EXPORT void parser()
+/* This is the main parser function. This function contains parser */
+/* initialization as well as the main parsing loop to which control is */
+/* returned (by recover()) when an error occurs. */
+{
+ /* Create the lists and tables generated by the parser. */
+ macro_table = tb_cre (sizeof(name_t),sizeof(p_ma_t),(p_kycm_t) cm_name);
+ file_table = tb_cre (sizeof(name_t),sizeof(p_ma_t),(p_kycm_t) cm_name);
+ document_list= ls_cre (sizeof(dc_t));
+
+ /* Initialize the section number counter. */
+ sequence = 0;
+ sn_ini(&last_sn);
+ p_secdc = NULL;
+
+ /* Prime the scanning of the token list. */
+ ls_fir(token_list);
+ next_tk(FALSE);
+
+ /* ABC { */
+ /* Initialise the internal macros. */
+ pr_intern();
+ /* } ABC */
+
+ /* This is where we longjmp back to after hitting a nasty syntax error. */
+ /* We don't actually have to test dummyint, as our control state is no */
+ /* different after a syntax error has occurred. Example: We try to parse */
+ /* a macro but there is a syntax error. So we skip to the start of the */
+ /* next macro and then longjmp back to here ready to parse the next */
+ /* macro. Thus, there is no need to a fork test. */
+ (void) setjmp(jmp_pos);
+
+ /* This is the main parser loop which parses major syntactic chunks. */
+ while (p_tk->tk_kind != TK_EOF)
+ switch (p_tk->tk_kind)
+ {
+ case TK_NSEC: pr_sec (); break;
+ case TK_TEXT: pr_dctxt(); break;
+ case TK_MDEF: pr_macro(); break;
+ case TK_FDEF: pr_macro(); break;
+ case TK_ODEF: pr_lit (); break;
+ case TK_EMPH: pr_emp (); break;
+ case TK_NPAG: pr_npag (); break;
+ case TK_TOCS: pr_tocs (); break;
+ case TK_SKIP: pr_skip (); break;
+ case TK_TITL: pr_titl (); break;
+ default:
+ lr_err(TKPS,"The parser was at the top level and was expecting");
+ lr_mes(TKPS,"one of: {Directive, Text, Macro definition, EOF}.");
+ next_tk(FALSE);
+ break;
+ }
+
+}
+
+/******************************************************************************/
+/* End of PARSER.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/parser.h b/web/funnelAC/fwACsrc/parser.h
new file mode 100644
index 0000000000..687a5bbf23
--- /dev/null
+++ b/web/funnelAC/fwACsrc/parser.h
@@ -0,0 +1,65 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* PARSER.H */
+/******************************************************************************/
+/* */
+/* The FunnelWeb parser parses the tokens in the global token list and */
+/* constructs a macro table and a document list. These two data structures */
+/* give structured views of the input document which are used later by tangle */
+/* and weave. If the parser detects any errors it sends them to the lister */
+/* package. If any errors have occurred, the output of the parser should not */
+/* be used. */
+/* */
+/* IN : token_list - List of tokens to be parsed. */
+/* OUT: macro_table - Table of macros parsed. */
+/* file_table - Table indicating which macros are attached to files. */
+/* document_list - List giving a structured view of the document. */
+/* Also sends diagnostic messages to the lister. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+EXPORT void parser P_((void));
+
+/******************************************************************************/
+/* End of PARSER.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/scanner.c b/web/funnelAC/fwACsrc/scanner.c
new file mode 100644
index 0000000000..c80f2258c0
--- /dev/null
+++ b/web/funnelAC/fwACsrc/scanner.c
@@ -0,0 +1,2559 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 24-Aug-1993 ABC Added support for file name inclusion in tokens.
+ 16-Sep-1993 ABC Changed all constants *_MAX to *_FWMAX to avoid
+ conflict with some standard UNIX constants.
+ 30-Dec-1993 ABC Added the `#line_offset' and `#line_depth'
+ pragmas to support the internal `#line' macro.
+ 15-Apr-1994 ABC Added hypertext typesetter types
+ TR_HTXT and TR_HTML, which are to HTML hypertext
+ what TR_NONE and TR_TEX are to TeX respectively.
+ 15-Apr-1994 ABC Added no_doc_header pragma to suppress inclusion
+ of the TeX header (not needed for LaTeX) or HTML
+ header at weave time. Also suppresses addition
+ of "\bye" at end of TeX files, and suppresses
+ <HTML>...</HTML> markup around HTML files.
+ 15-Apr-1994 ABC Added doc_incQ flag for inclusion or not of
+ FunnelWeb TeX/HTML header.
+ 20-May-1994 ABC Added raw_macro_and_section_names pragma for
+ allowing or not of raw TeX/HTML in macro/section
+ names.
+ 20-May-1994 ABC Added raw_namQ flag for allowing or not of
+ raw TeX/HTML in macro/section names.
+ 27-May-1994 ABC Added ignore_text_after_special_minus flag to
+ cause text on a line after `@-' (assuming `@' is
+ the special character) to be ignored as a
+ comment. This is to aid in embedding text to
+ set the proper mode in an emacs buffer.
+ 28-May-1994 ABC Added no_paragraph_markups pragma which inhibits
+ the automatic insertion of `<P>' paragraph
+ markups for hypertext and HTML modes.
+ 16-Jul-1994 ABC Added automatic_line_directive_macro pragma to
+ allow the nomination of a macro which should
+ be called at each macro invocation in order
+ to generate line directives.
+ 25-Jul-1995 ABC Replaced `aldmname' with a list of structures
+ containing a source code type name (or NULL)
+ and a corresponding automatic line directive
+ insertion macro name.
+ 30-Jul-1995 ABC Added declare_source_code_type pragma to support
+ multiple source code types.
+ 30-Jul-1995 ABC Modified the automatic_line_directive_macro
+ pragma to accept an optional source code type.
+ 08-Aug-1995 ABC Changed include file name from "memory.h"
+ to "fwmem.h" to avoid a clash with the C++
+ standard header file "memory.h".
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* SCANNER.C */
+/******************************************************************************/
+/* */
+/* Introduction */
+/* ------------ */
+/* The FunnelWeb scanner is a little messy because it deals with two */
+/* structures at the same time while attempting to be efficient. On the one */
+/* hand it is busy constructing the line list. This means that it has to keep */
+/* an eye out for end of line characters ('\n'=EOL) so that it can add a line */
+/* record whenever it sees one. On the other hand, it has to scan the input */
+/* file into a token stream consisting of text tokens and special tokens */
+/* which usually have no regard for end of lines. It is tempting to divide */
+/* these two functions up (into perhaps a LINER and a TOKENIZER). However, */
+/* the presence of the include file facility would make this messy. Also, the */
+/* tokenizer has to count end of line markers so that it can generate */
+/* correctly positioned diagnostics. */
+/* */
+/* The long and short of it all is that the best way to do the scanning seems */
+/* to be to run a liner and a tokenizer as parallel layers. The liner */
+/* extracts characters from the input file and hands them to the tokenizer. */
+/* It also keeps an eye out for newline characters, sending a line record off */
+/* whenever it sees one, and counting lines. The tokenizer receives the */
+/* characters from the liner and performs the tokenize operation. */
+/* */
+/* Notes */
+/* ----- */
+/* - Currently FunnelWeb recognises only two characters as whitespace. */
+/* These are ' ' and EOL. */
+/* */
+/******************************************************************************/
+
+#include <ctype.h>
+#include <limits.h>
+#include "style.h"
+
+#include "as.h"
+#include "clock.h"
+#include "data.h"
+#include "dump.h"
+#include "list.h"
+#include "lister.h"
+#include "machin.h"
+#include "mapper.h"
+#include "fwmem.h"
+#include "misc.h"
+#include "option.h"
+#include "scanner.h"
+
+/******************************************************************************/
+
+/* The "special" character is the character that is used to introduce a */
+/* "special sequence". FunnelWeb allows the user to change this character so */
+/* as to cater for documents where the "default" character is common. This */
+/* definition defines what the default character is. */
+#define CH_DSPE ('@')
+
+/* FunnelWeb allows include files which are handled by the scanner by placing */
+/* recursive calls to scan_file. A maximum is placed on the level of nested */
+/* includes. This acts as a good sanity check as well as catching recursive */
+/* include files which are never a sensible construct in FunnelWeb as */
+/* FunnelWeb does not provide any conditional construct. */
+#define MAX_INCL (10)
+
+/* FunnelWeb is very conservative about what characters it will allow in its */
+/* input and output files. Currently the only characters allowed are */
+/* printables and end of lines. When FunnelWeb does spot an illegal character */
+/* it needs to be able to draw the user's attention to the character. The */
+/* best way to do this is to point to it in the listing file. However, if the */
+/* character is banned, it cannot appear in the listing file! The problem is */
+/* solved by having the scanner replace all illegal characters in each mapped */
+/* file by the following character. This eliminates further problems. */
+#define CENSORCH ('?')
+
+/* Following the Unix convention, mapped in files are not terminated with an */
+/* end-of-file character. However, the presence of such a character at the */
+/* end of the mapped file simplifies scanning and so we add one. This */
+/* definition defines what the character is to be. It doesn't matter what the */
+/* character is, so long as it cannot legally appear in the file. A control */
+/* character is a good choice as these are filtered out by the liner (see */
+/* above). */
+/* We undef EOF (from <stdio.h>) because it is too dangerously close to EOFCH.*/
+/* (EOF wasn't redefined as that might confuse readers used to <stdio.h>. */
+/* However, we still use EOF as an acronym for End Of File. */
+#define EOFCH (26)
+#undef EOF
+
+/* Tokens have a field for a general attribute which has meaning for some */
+/* token kinds. For other kinds, it has no meaning. This constant is used to */
+/* indicate a "don't care" value. */
+#define DONTCARE 0
+
+/* A nominal maximum value for the maximum length of an input line. */
+#define INMAXINF (ULONG_MAX)
+
+/******************************************************************************/
+
+/* The following type is used in the suite of pragma routines for parsing. */
+typedef
+ struct
+ {
+ ps_t pt_ps; /* Position of the start of this argument. */
+ char *pt_pstr; /* Pointer to a string containing the argument. */
+ char *pt_pinl; /* Pointer to first byte of the argument in commndline. */
+ } pt_t;
+typedef pt_t *p_pt_t;
+
+/******************************************************************************/
+
+ /* Variables Instantiated Over The Entire Scan */
+ /* ------------------------------------------- */
+LOCVAR p_ck_t p_mapp; /* Pointer to mapper's clock. */
+LOCVAR p_ck_t p_scan; /* Pointer to scanner's clock. */
+LOCVAR ulong globalno; /* Global line number of line being scanned. */
+LOCVAR ulong inclevel; /* Include level of current file. Top file is zero. */
+LOCVAR bool seenind; /* TRUE iff we have seen an indentation pragma. */
+LOCVAR ps_t ps_ind; /* seenind==TRUE => ps_ind is position of pragma. */
+LOCVAR bool seentyp; /* TRUE iff we have seen a typesetter pragma. */
+LOCVAR ps_t ps_typ; /* seentyp==TRUE => ps_typ is position of pragma. */
+LOCVAR bool seenlimo; /* TRUE iff we have seen an out lin len limit pragma. */
+LOCVAR ps_t ps_limo; /* seenlimo==TRUE => ps_limo is position of pragma. */
+
+ /* Variables Instantiated Over The Current File */
+ /* -------------------------------------------- */
+LOCVAR ulong inln_max; /* Maximum permitted length of an input line. */
+LOCVAR char specialch; /* Current special (escape) character. */
+LOCVAR char *p_eof; /* Pointer to EOFCH byte at the end of current file. */
+LOCVAR ulong localno; /* Local line number of line being scanned. */
+
+ /* Variables Instantiated Over The Current Line */
+ /* -------------------------------------------- */
+LOCVAR char *p_sol; /* Pointer to Start (first char) Of current Line. */
+LOCVAR char *p_ch; /* Pointer to current character in current line. */
+LOCVAR char ch; /* *p_ch. */
+/* ABC { */
+LOCVAR p_fnam_t src_1st; /* Start of list of all source filenames. */
+LOCVAR p_fnam_t src_cur; /* current filename. */
+LOCVAR bool igntxtQ; /* whether to ignore text on a line after `@-'. */
+/* } ABC */
+
+/******************************************************************************/
+/* Line Processing Layer */
+/******************************************************************************/
+/* */
+/* This mini-section contains the two routines (prepline and NEXTCH) that */
+/* take care of the line based-scanning and feed characters to the */
+/* token-based scanner routines which have the top level of control. */
+/* After mapping in a file to be read, place a call to prepline passing the */
+/* address of the first byte of the mapped file as an argument. At that */
+/* point the current position will be the first byte on the first line and */
+/* the "variables instantiated over the current line" will be well defined. */
+/* Calls to NEXTCH then move the position through the mapped file one byte at */
+/* a time, stopping at the end of file at which point calls will not move the */
+/* marker which will point to the EOF character. */
+/* */
+/******************************************************************************/
+
+LOCAL void prepline P_((char *));
+LOCAL void prepline(p_line)
+/* This function should be called at the end of each line to prepare the next */
+/* line for scanning. The user of the liner mini-package should place a */
+/* single call to this function at the start of scanning a mapped file. */
+/* The user should then place calls to NEXTCH (which calls prepline when */
+/* necessary). */
+/* This function serves two purposes: */
+/* 1. It looks at the next line and converts all non-printables into */
+/* CENSORCH and issues errors for each non-printable. */
+/* 2. It initializes the line scanning variables for the next line. */
+/* The argument is a pointer to the first byte of the next line. */
+char *p_line;
+{
+ char *p; /* Scans through the line and winds up sitting on the EOL. */
+
+ /* Test to see if the "line" we have been given is the end of file marker. */
+ /* We have to be careful here because the byte we are using to mark the end */
+ /* of file could appear as an illegal unprintable. This is the reason for */
+ /* the test p_line==p_eof. */
+ if (*p_line==EOFCH && p_line==p_eof)
+ {
+ /* The line we have to process is in fact the end of file marker. */
+ p_sol = p_line;
+ p_ch = p_line;
+ ch = EOFCH;
+ return;
+ }
+
+ /* At this point we know that we are faced with a run of bytes terminated by */
+ /* an EOL character (we know this cos we put an EOL before EOF earlier on). */
+ /* We know that we have a line, so we can now bump up the line counters. */
+ globalno++;
+ localno++;
+
+ /* Run through the line checking for non-printables and issuing errors. */
+ p = p_line;
+ while (*p != EOL)
+ {
+ /* The following test tests to see if the character is a printable in */
+ /* seven bit ascii. FunnelWeb is not currently designed to work with */
+ /* any character set other than seven-bit ascii and so we flag and */
+ /* convert all out-of-range characters here before they are exposed to */
+ /* the rest of the scanner code which assumes that each line that it is */
+ /* handed consists entirely of printables except for the EOL char on the */
+ /* end and possibly an EOF char at the "Start" of a line. */
+ /* In particular, the NEXTCH macro will fail on machines with siged */
+ /* chars if non-printables are not removed. It goes into an infinite */
+ /* loop. */
+ /* Note: I don't use library function "isprint" here because on the vax */
+ /* it's definition is too loose (seems to accept characters with the top */
+ /* bit set as printable). */
+ if (!isascprn(*p)) /* If not a printable character. */
+ {
+ ps_t ps;
+ char c = *p;
+ ubyte_ uc = *((ubyte_ *) p);
+ ps.ps_line = globalno;
+ ps.ps_column = p-p_line+1;
+ /* ABC { */
+ ps.ps_localno = localno;
+ ps.ps_fnam = src_cur;
+ ps.ps_declQ = TRUE;
+ /* } ABC */
+ if (strlen(chabbrev(c))==0)
+ sprintf(linet1,
+ "Non printable character (Sym=<none>, Dec=%03u, Hex=%02X, Oct=%03o).",
+ (unsigned) uc,(unsigned) uc,(unsigned) uc);
+ else
+ sprintf(linet1,
+ "Non printable character (Sym=%s, Dec=%03u, Hex=%02X, Oct=%03o).",
+ chabbrev(c),(unsigned) uc,(unsigned) uc,(unsigned) uc);
+ lr_err(&ps,linet1);
+ *p=CENSORCH;
+ }
+ p++;
+ }
+ /* Assert: p_line points to the start of the current line. */
+ /* Assert: p points to the EOL at the end of the current line. */
+
+ /* Check that the line is not too long. */
+ if ((p-p_line)>inln_max)
+ {
+ ps_t ps;
+ ps.ps_line = globalno;
+ ps.ps_column = inln_max+1;
+ /* ABC { */
+ ps.ps_localno = localno;
+ ps.ps_fnam = src_cur;
+ ps.ps_declQ = TRUE;
+ /* } ABC */
+ lr_err(&ps,"Input line is too long (this character is the first offender).");
+ sprintf(linet1,"Currently, the maximum allowable input line length is %lu.",
+ (unsigned long) inln_max);
+ lr_mes(&ps,linet1);
+ lr_mes(&ps,"Note: You can change this using a pragma directive (@p).");
+ }
+
+ /* Now check for trailing spaces. */
+ if ((p != p_line) && (*(p-1) == ' '))
+ {
+ ps_t ps;
+ ps.ps_line = globalno;
+ ps.ps_column = p-p_line;
+ /* ABC { */
+ ps.ps_localno = localno;
+ ps.ps_fnam = src_cur;
+ ps.ps_declQ = TRUE;
+ /* } ABC */
+ lr_war(&ps,"Line has trailing spaces up to and including this space.");
+ }
+
+ /* Construct a line record and append the record to the line list. */
+ /* Note that the line scrap encompasses the trailing EOL. */
+ {
+ ln_t line;
+ line.ln_global = globalno;
+ line.ln_local = localno;
+ line.ln_body.sc_first = p_line;
+ line.ln_body.sc_last = p;
+ /* ABC { */
+ line.ln_fnam = src_cur;
+ /* } ABC */
+ /* Note: We do not set sc_white as it is not used in lines. */
+ ls_add(line_list,PV &line);
+ }
+
+ /* Finally, set the line scanning variables to the start of the line. */
+ /* We can't do this earlier in case the start of the line was a */
+ /* non-printable and got substituted (ch might pick it up). */
+ p_sol = p_line;
+ p_ch = p_line;
+ ch = *p_line;
+
+} /* End of prepline. */
+
+/* NEXTCH can be called continuously after an initializing call to prepline. */
+/* After a call to NEXTCH, p_sol, p_ch, ch are all well-defined. p_sol points */
+/* to the start of the current line, p_ch points to the current character, */
+/* and ch contains *p_ch. NEXTCH can be called repeatedly forever. When it */
+/* hits the EOF character, it sticks on it and returns it forever. */
+/* Note: The "ch<' '" is an optimized form of "(ch==EOL)||(ch=EOFCH)". Speed */
+/* is very important here as this macro is called in scanning tightloops. */
+/* This line of code is a little tricky so read it carefully. */
+/* WARNING: The ch<' ' will cause an infinite loop if a character appears */
+/* that satisfies this condition without being EOF or EOL (e.g. a control */
+/* char (meant to be filtered out earlier) or a top-bit-set character on */
+/* machines with signed character type. */
+#define NEXTCH {if (ch<' ') {if (ch==EOL) prepline(p_ch+1);} else ch= *++p_ch;}
+
+/******************************************************************************/
+/* Scanner Support Routines */
+/******************************************************************************/
+
+LOCAL ps_t *psofch P_((void));
+LOCAL ps_t *psofch()
+/* Returns a pointer to an internal static ps structure holding the line and */
+/* column number of the current character ch. */
+{
+ STAVAR ps_t chps;
+ chps.ps_line = globalno;
+ chps.ps_column = p_ch-p_sol+1;
+ /* ABC { */
+ chps.ps_localno = localno;
+ chps.ps_fnam = src_cur;
+ chps.ps_declQ = TRUE;
+ /* } ABC */
+ return &chps;
+}
+
+/******************************************************************************/
+
+LOCAL void grabchps P_((p_ps_t));
+LOCAL void grabchps(p_ps)
+/* Writes the position of the current ch into the argument position struct. */
+p_ps_t p_ps;
+{
+ p_ps->ps_line = globalno;
+ p_ps->ps_column = p_ch-p_sol+1;
+ /* ABC { */
+ p_ps->ps_localno = localno;
+ p_ps->ps_fnam = src_cur;
+ p_ps->ps_declQ = TRUE;
+ /* } ABC */
+}
+
+/******************************************************************************/
+
+LOCAL void sendspec P_((p_ps_t,tk_k_t,ubyte));
+LOCAL void sendspec(p_tkps,tk_kind,tk_gen)
+/* Appends a non-text token of kind tk_kind to the end of the token list. */
+/* p_ps is a pointer to a position structure giving the position of the */
+/* first character of the token. tk_gen is the general token attribute. */
+p_ps_t p_tkps;
+tk_k_t tk_kind;
+ubyte tk_gen;
+{
+ tk_t token;
+ token.tk_kind = tk_kind;
+ ASSIGN(token.tk_ps,*p_tkps);
+ token.tk_sc.sc_first = NULL;
+ token.tk_sc.sc_last = NULL;
+ token.tk_sc.sc_white = TRUE;
+ token.tk_gen = tk_gen;
+ ls_add(token_list,PV &token);
+}
+
+/******************************************************************************/
+
+LOCAL void sendtext P_((p_ps_t,char *,char *,bool));
+LOCAL void sendtext(p_tkps,p_first,p_last,is_white)
+/* Appends a text token to the end of the token list. */
+/* IN: p_ps is a pointer to a position structure giving the position of the */
+/* first character of the token. */
+/* IN: p_first and p_last point to the first and last byte of the text scrap. */
+/* IN: is_white should be set to TRUE iff scrap is entirely whitespace. */
+p_ps_t p_tkps;
+char *p_first;
+char *p_last;
+bool is_white;
+{
+ tk_t token;
+
+ /* Empty text scraps should never be generated. */
+ as_cold(p_first<=p_last,"sendtext: Text scrap bounds are bad.");
+
+ /* If ch=EOL then we should be scanning more text, not shipping it! */
+ as_cold(ch!=EOL,"senttext: Shipping text while still more to scan.");
+
+ /* Send the text token. */
+ token.tk_kind = TK_TEXT;
+ ASSIGN(token.tk_ps,*p_tkps);
+ token.tk_sc.sc_first = p_first;
+ token.tk_sc.sc_last = p_last;
+ token.tk_sc.sc_white = is_white;
+ token.tk_gen = DONTCARE;
+ ls_add(token_list,PV &token);
+}
+
+/******************************************************************************/
+
+LOCAL void add_eof P_((void));
+LOCAL void add_eof()
+/* This function adds terminators to the line and token list. */
+/* 1. It adds a TK_EOF token to the end of the token list. */
+/* 2. It adds a visible <eof> line to the end of the line list. */
+/* This assists the parser by allowing it to point diagnostic messages to a */
+/* visible EOF marker rather than pointing vaguely to the end of the last */
+/* line of the input file which (by the way) may not even exist! */
+{
+ STAVAR char *eofstr = "<End-Of-File>\n";
+ ln_t line;
+ ps_t ps;
+
+ /* When the liner mini package encounters an end of file marker, it stops */
+ /* dead on the marker and returns EOFCH forever. scan_file() eventually gets */
+ /* the message and drops out. However, in all of this, the line numbers are */
+ /* not incremented to indicate that we have moved to an EOF line. This is */
+ /* intended, as we do not want EOFs to appear in the listing for include */
+ /* files; only at the end of the main input file. Thus, here we effectively */
+ /* perform the liner function of moving from the last line of the input file */
+ /* to the imaginary line containing the EOF marker. This is done by */
+ /* incrementing the line numbers. Note that the fact that these line number */
+ /* variables are incorrect from the point of detection of the final EOF to */
+ /* here doesn't matter as no tokens or diagnostics are ever added after an */
+ /* EOF is detected. */
+ globalno++;
+ localno++;
+
+ /* Add a line to represent the EOF marker. */
+ line.ln_global = globalno;
+ line.ln_local = localno;
+ line.ln_body.sc_first = eofstr;
+ line.ln_body.sc_last = eofstr+strlen(eofstr)-1;
+ /* ABC { */
+ line.ln_fnam = src_cur;
+ /* } ABC */
+ /* Note: We do not set sc_white as it is not used in lines. */
+ ls_add(line_list,PV &line);
+
+ /* Add a TK_EOF token to the end of the token list. */
+ ps.ps_line = globalno;
+ ps.ps_column = 1;
+ /* ABC { */
+ ps.ps_localno = localno;
+ ps.ps_fnam = src_cur;
+ ps.ps_declQ = TRUE;
+ /* } ABC */
+ sendspec(&ps,TK_EOF,DONTCARE);
+}
+
+
+/* ABC { */
+/******************************************************************************/
+/* Filename List Manipulation */
+/******************************************************************************/
+
+/******************************************************************************/
+
+LOCAL void fl_set P_((char*));
+LOCAL void fl_set(p_fname)
+/* This function checks to see if the given name currently exists in the */
+/* filename list. If so, it sets the value of src_cur accordingly. If not, */
+/* it adds the filename to the filename list, and then sets src_cur */
+/* accordingly. */
+char *p_fname;
+{
+ /* Check if *any* filenames have been added to the list. */
+ if (!src_1st) {
+ src_1st = (p_fnam_t)mm_temp(sizeof(fnam_t));
+ src_1st->fnam_next = (p_fnam_t)0;
+ src_1st->fnam_name = (char *)mm_temp((strlen(p_fname)+1)*sizeof(char));
+ strcpy(src_1st->fnam_name, p_fname);
+ src_cur = src_1st;
+ return;
+ } /* end if */
+
+ /* Start search from beginning of filename list. */
+
+ src_cur = src_1st;
+
+ /* Search for a match */
+ while (strcmp(src_cur->fnam_name, p_fname) && (src_cur->fnam_next)) {
+ src_cur = src_cur->fnam_next;
+ } /* end while */
+
+ /* If not match, add new filename. */
+ if (strcmp(src_cur->fnam_name, p_fname)) {
+ src_cur->fnam_next = (p_fnam_t)mm_temp(sizeof(fnam_t));
+ src_cur = src_cur->fnam_next;
+ src_cur->fnam_next = (p_fnam_t)0;
+ src_cur->fnam_name = (char *)mm_temp((strlen(p_fname)+1)*sizeof(char));
+ strcpy(src_cur->fnam_name, p_fname);
+ } /* end if */
+}
+/* } ABC */
+
+/******************************************************************************/
+/* The Scanner Proper */
+/******************************************************************************/
+
+LOCAL void skiptoeol P_((void));
+LOCAL void skiptoeol()
+{
+ while (ch != EOL)
+ NEXTCH;
+}
+
+/******************************************************************************/
+
+/* The incl_fil function calls this, so we have to declare it in advance. */
+LOCAL void scan_file P_((char *));
+
+LOCAL void incl_fil P_((p_ps_t));
+LOCAL void incl_fil(p_ps)
+/* Upon entry, the current character is the "i" of an "@i" sequence. Our task */
+/* is first to see if the sequence occurred at the start of a line (the only */
+/* point at which it is legal) and issue an error if it isn't. If it is legal,*/
+/* we have to read in the specified file and scan that. The included file */
+/* replaces exactly the line starting with the "@i" command and we return */
+/* to the "calling" file with the current position being the EOL character of */
+/* the include line. */
+p_ps_t p_ps;
+{
+ /* Complain if the include directive was not at the start of a line. */
+ if (p_ch-1 != p_sol)
+ {
+ lr_err(p_ps,"Include sequence must be at the beginning of a line.");
+ lr_mes(p_ps,"Include ignored.");
+ skiptoeol();
+ return;
+ }
+
+ /* The include command should be followed by a blank. Get the next char. */
+ NEXTCH;
+
+ /* Complain if the next character is not a blank. */
+ if (ch != ' ')
+ {
+ ps_t ps;
+ ASSIGN(ps,*p_ps);
+ ps.ps_column+=2;
+ lr_err(&ps,"Include sequence (@i) must be followed by a blank.");
+ lr_mes(&ps,"Example include: @i macros.fwi");
+ lr_mes(&ps,"Include ignored.");
+ skiptoeol();
+ return;
+ }
+
+ /* Complain if the include level is too high. */
+ if (inclevel == MAX_INCL)
+ {
+ lr_err(p_ps,"This include file is nested too deeply. It's probably recursive.");
+ sprintf(linet1,"The maximum level of nested includes is %u.",
+ (unsigned) MAX_INCL);
+ lr_mes(p_ps,linet1);
+ lr_mes(p_ps,"Include ignored.");
+ skiptoeol();
+ return;
+ }
+
+ {/* This construct does the work of the include. */
+ /* Warning: The following variables MUST be declared automatic. */
+ char *p_filename;
+ char *p_tempname;
+ /* ABC { */
+ char *p_oldname;
+ /* } ABC */
+ ulong length;
+ char *p;
+ ulong xinln_max;
+ char xspecial;
+ char *xp_eof;
+ ulong xlocalno;
+ char *xp_sol;
+ char *xp_ch;
+ char xch;
+
+ /* We save stack space by sticking this filename in the heap. */
+ p_filename=mm_temp((size_t) FILENAME_FWMAX+1+10); /* 10 is for paranoia. */
+ p_tempname=mm_temp((size_t) FILENAME_FWMAX+1+10); /* 10 is for paranoia. */
+ /* ABC { */
+ p_oldname=mm_temp((size_t) FILENAME_FWMAX+1+10); /* 10 is for paranoia. */
+ /* } ABC */
+
+ /* The rest of the line is supposed to hold a filename. Copy it. */
+ NEXTCH;
+ p=p_tempname;
+ length=0;
+ while (ch!=EOL)
+ {
+ if (++length > FILENAME_FWMAX)
+ {
+ lr_err(p_ps,
+ "This include command's file specification is too long.");
+ if (option.op_b7_b)
+ sprintf(linet1,"The maximum file name length is %s characters.",
+ SUPPVAL);
+ else
+ sprintf(linet1,"The maximum file name length is %u characters.",
+ (unsigned) FILENAME_FWMAX);
+ lr_mes(p_ps,linet1);
+ lr_mes(p_ps,"Include ignored.");
+ skiptoeol();
+ return;
+ }
+ *p++=ch;
+ NEXTCH;
+ }
+ *p=EOS;
+ /* Note: Current position is now on the EOL at the end of the @i line. */
+
+ /* Complain if the user has not specified a filename. */
+ if (strlen(p_tempname) ==0)
+ {
+ lr_err(psofch(),"Expecting the name of a file to include.");
+ return;
+ }
+
+ /* Perform the necessary filename inheritance. */
+ strcpy(p_filename,"");
+ fn_ins(p_filename,option.op_f_s);
+ fn_ins(p_filename,".fwi");
+ fn_ins(p_filename,option.op_i_s);
+ fn_ins(p_filename,p_tempname);
+
+ /* Include the included file by calling scan_file recursively. */
+ /* Save and restore all variables in instantiation scope. */
+ xinln_max = inln_max;
+ xspecial = specialch;
+ xp_eof = p_eof;
+ xlocalno = localno;
+ xp_sol = p_sol;
+ xp_ch = p_ch;
+ xch = ch;
+ inclevel++;
+
+ /* ABC { */
+ /* Store current filename */
+ strcpy(p_oldname, src_cur->fnam_name);
+ /* } ABC */
+
+ /* Scan include file */
+ scan_file(p_filename);
+
+ /* ABC { */
+ /* Restore previous filename */
+ fl_set(p_oldname);
+ /* } ABC */
+
+ inclevel--;
+ ch = xch;
+ p_ch = xp_ch;
+ p_sol = xp_sol;
+ localno = xlocalno;
+ p_eof = xp_eof;
+ specialch = xspecial;
+ inln_max = xinln_max;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void do_ascii P_((p_ps_t));
+LOCAL void do_ascii(p_psspec)
+/* Upon entry, the current character is the '^' of a @^ sequence. The task is */
+/* to parse the following ascii code and generate a text token. */
+p_ps_t p_psspec;
+{
+ ubyte base; /* Base of the number we are scanning. */
+ ubyte digits; /* Number of digits expected. */
+ uword val; /* Value of target character. */
+ ubyte i; /* Looping variable. */
+ STAVAR char alphab[256]; /* Static alphabet array to which to point scraps. */
+ STAVAR bool init=FALSE; /* Tells if alphab has been initialized. */
+
+ /* Establish an array containing the ascii character set. Later on we can */
+ /* point the sc_first and sc_last pointers to particular characters. */
+ if (!init) {uword i; for (i=0;i<256;i++) alphab[i]=(char) i; init=TRUE;}
+
+ /* Make sure that the base character is legal. */
+ NEXTCH;
+ switch(toupper(ch))
+ {
+ case 'B': base= 2; digits=8; break;
+ case 'O':
+ case 'Q': base= 8; digits=3; break;
+ case 'D': base=10; digits=3; break;
+ case 'H':
+ case 'X': base=16; digits=2; break;
+ default : lr_err(psofch(),"Expecting one of 'B', 'Q', 'D', 'H'.");
+ lr_mes(psofch(),"(For Binary, Octal, Decimal, and Hexadecimal).");
+ base=10;
+ goto trouble;
+ }
+
+ /* Parse opening parenthesis. */
+ NEXTCH;
+ if (ch!='(')
+ {lr_err(psofch(),"Expecting '('.");goto trouble;}
+
+ val=0;
+ for (i=0;i<digits;i++)
+ {
+ char uch;
+ ubyte d;
+
+ NEXTCH;
+ uch=toupper(ch);
+ if (('0'<=uch) && (uch<='9'))
+ d=uch-'0';
+ else
+ if ('A'<=uch && uch<='F')
+ d=10+uch-'A';
+ else
+ d=100;
+ if (d>=base)
+ {lr_err(psofch(),"Illegal digit."); goto trouble;}
+ val = base*val + d;
+ }
+
+ /* Parse closing parenthesis. */
+ NEXTCH;
+ if (ch!=')')
+ {lr_err(psofch(),"Expecting ')'.");goto trouble;}
+
+ /* Make sure that the number is not too big (this is possible in decimal). */
+ if (val>255)
+ {
+ lr_err(psofch(),"Character number is too large.");
+ lr_mes(psofch(),"Character number must be in the range [0,255] (decimal).");
+ goto trouble;
+ }
+
+ /* Success! Now we can parcel it up into a scrap! */
+ sendtext(p_psspec,&alphab[val],&alphab[val],ch==' ' || ch==EOL);
+ return;
+
+ trouble:
+ /* Jump here after a specific diagnostic to give the user a reminder of */
+ /* how to specify an ascii character constant. */
+ switch (base)
+ {
+ case 2:
+ lr_mes(psofch(),
+ "A binary character representation takes the form \"@^B(dddddddd)\".");
+ lr_mes(psofch(),
+ "(exactly 8 digits) where each digit d is either 0 or 1.");
+ break;
+ case 8:
+ lr_mes(psofch(),
+ "An octal character representation takes the form \"@^Q(ddd)\" (or \"@^O(ddd)\").");
+ lr_mes(psofch(),
+ "(exactly 3 digits) where each digit d is in the range 0..7.");
+ break;
+ case 10:
+ lr_mes(psofch(),
+ "A decimal character representation takes the form \"@^D(ddd)\".");
+ lr_mes(psofch(),
+ "(exactly 3 digits) where each digit d is in the range 0..9.");
+ break;
+ case 16:
+ lr_mes(psofch(),
+ "A hexadecimal character representation takes the form \"@^X(dd)\" (or \"@^H(dd)\").");
+ lr_mes(psofch(),
+ "(exactly 2 digits) where each digit d is in the range 0..9,A..F.");
+ break;
+ default: as_bomb("do_ascii: trouble base switch defaulted.");
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void do_name P_((p_ps_t));
+LOCAL void do_name (p_psspec)
+/* Upon entry, the current character is the # of a @#. The task is to parse */
+/* it and transmit a name token. */
+p_ps_t p_psspec;
+{
+ as_cold(ch=='#',"do_name: character is wrong.");
+ NEXTCH;
+ if ((ch==EOL) || (ch==' '))
+ {lr_err(psofch(),"Expecting a printable character."); return;}
+
+ /* Transmit a name token. */
+ sendspec(p_psspec,TK_NAME,(ubyte) ch);
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgind P_((uword,p_pt_t));
+LOCAL void do_pgind(numarg,arg)
+/* Parse an indentation pragma. */
+uword numarg;
+p_pt_t arg;
+{
+ bool pragind;
+ ps_t psprag;
+
+ /* Make sure that there are exactly three arguments. */
+ if (numarg != 3) /* "indentation" "none|blank". */
+ {
+ lr_err(&arg[0].pt_ps,
+ "This indentation pragma has the wrong number of arguments.");
+ goto help;
+ }
+
+ /* Make sure that the second argument is an "=". */
+ if (0 != strcmp(arg[2].pt_pstr,"="))
+ {
+ lr_err(&arg[2].pt_ps,"Expecting \"=\".");
+ goto help;
+ }
+
+ /* Check the third argument. */
+ if (strcmp(arg[3].pt_pstr,"none" )==0) pragind=FALSE;
+ else if (strcmp(arg[3].pt_pstr,"blank")==0) pragind=TRUE;
+ else
+ {
+ lr_err(&arg[3].pt_ps,"Expecting either \"none\" or \"blank\".");
+ goto help;
+ }
+
+ /* Construct a shorthand for the start of the pragma. */
+ ASSIGN(psprag,arg[0].pt_ps);
+
+ /* Make sure that the pragma does not contradict an earlier pragma. */
+ if (seenind && (tgindent!=pragind))
+ {
+ sprintf(linet1,"This pragma is opposed by the pragma at line %lu.",
+ (unsigned long) psprag.ps_line);
+ lr_mes(&ps_ind,linet1);
+ sprintf(linet1,"This pragma opposes the pragma at line %lu.",
+ (unsigned long) ps_ind.ps_line);
+ lr_err(&psprag,linet1);
+ lr_mes(&psprag,"You can have as many indentation pragmas as you like,");
+ lr_mes(&psprag,"but they all have to be the same!");
+ lr_mes(&psprag,"Pragma ignored.");
+ return;
+ }
+
+ /* Success: Record the pragma information. */
+ seenind = TRUE; /* Record that we have seen a pragma. */
+ tgindent = pragind; /* Record what the pragma said. */
+ ASSIGN(ps_ind,psprag); /* Record where the pragma was. */
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: \"@p indentation = none|blank\".");
+ lr_mes(&arg[0].pt_ps,"Pragma ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pginl P_((uword,p_pt_t));
+LOCAL void do_pginl(numarg,arg)
+/* Parse a maximum input line length pragma. */
+uword numarg;
+p_pt_t arg;
+{
+ char *numstr;
+ uword spn;
+
+ /* Make sure that there are exactly three arguments. */
+ if (numarg != 3) /* "max..length = <num>". */
+ {
+ lr_err(&arg[0].pt_ps,"This pragma has the wrong number of arguments.");
+ goto help;
+ }
+
+ /* Make sure that the second argument is "=". */
+ if (0 != strcmp(arg[2].pt_pstr,"="))
+ {lr_err(&arg[2].pt_ps,"Expecting \"=\"."); goto help;}
+
+ /* Set up an abbreviation. */
+ numstr=arg[3].pt_pstr;
+
+ /* See if the value is "infinity". */
+ if (strcmp(numstr,"infinity")==0)
+ {inln_max=INMAXINF; return;}
+
+ /* Calculate length of longest prefix containing all decimal digits. */
+ /* Check that there are no illegal digits. */
+ spn=strspn(numstr,"0123456789");
+ if (spn != strlen(numstr))
+ {
+ ps_t ps;
+ ASSIGN(ps,arg[3].pt_ps);
+ ps.ps_column+=spn;
+ lr_err(&ps,"Illegal digit. Value must consist entirely of decimal digits.");
+ lr_mes(&ps,"You can also use the value \"infinity\".");
+ lr_mes(&ps,"Pragma ignored.");
+ return;
+ }
+
+ /* Check that the number is not too long. */
+ if (strlen(numstr)>8)
+ {
+ lr_err(&arg[3].pt_ps,"Too many digits. The maximum is eight.");
+ lr_mes(&arg[3].pt_ps,"Pragma ignored.");
+ return;
+ }
+
+ /* Convert the argument into an integer. */
+ {
+ ulong val;
+ int result;
+ /* Note: Should really be %lu, but the Vax doesn't know about the %u */
+ /* in sscanf and so we make do with %ld. */
+ result=sscanf(numstr,"%ld",&val);
+ as_cold(result==1,"do_pginl:sscanf failed.");
+ inln_max=val;
+ }
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: \"@p maximum_input_line_length = <num>|infinity\".");
+ lr_mes(&arg[0].pt_ps,"Pragma ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgotl P_((uword,p_pt_t));
+LOCAL void do_pgotl(numarg,arg)
+/* Parse a maximum product file line length pragma. */
+uword numarg;
+p_pt_t arg;
+{
+ char *numstr;
+ uword spn;
+ ulong val;
+ ps_t psprag;
+
+ /* Set up an abbreviation. */
+ ASSIGN(psprag,arg[0].pt_ps);
+
+ /* Make sure that there are exactly three arguments. */
+ if (numarg != 3) /* "max..length" "=" "value". */
+ {
+ lr_err(&arg[0].pt_ps,"This pragma has the wrong number of arguments.");
+ goto help;
+ }
+
+ /* Make sure that the second argument is an "=". */
+ if (0 != strcmp(arg[2].pt_pstr,"="))
+ {lr_err(&arg[2].pt_ps,"Expecting \"=\"."); goto help;}
+
+ /* Set up an abbreviation. */
+ numstr=arg[3].pt_pstr;
+
+ /* See if the value is "infinity". */
+ if (strcmp(numstr,"infinity")==0)
+ {val=TGMAXINF; goto gotvalue;}
+
+ /* Calculate length of longest prefix containing all decimal digits. */
+ /* Check that there are no illegal digits. */
+ spn=strspn(numstr,"0123456789");
+ if (spn != strlen(numstr))
+ {
+ ps_t ps;
+ ASSIGN(ps,arg[3].pt_ps);
+ ps.ps_column+=spn;
+ lr_err(&ps,"Illegal digit. Value must consist entirely of decimal digits.");
+ lr_mes(&ps,"You can also use the value \"infinity\".");
+ lr_mes(&ps,"Pragma ignored.");
+ return;
+ }
+
+ /* Check that the number is not too long. */
+ if (strlen(numstr)>8)
+ {
+ lr_err(&arg[3].pt_ps,"Too many digits. The maximum is eight.");
+ lr_mes(&arg[3].pt_ps,"Pragma ignored.");
+ return;
+ }
+
+ /* Convert the argument into an integer. */
+ {
+ int result=sscanf(numstr,"%ld",&val);
+ as_cold(result==1,"do_pgotl:sscanf failed.");
+ }
+
+ gotvalue:
+ /* Make sure that the pragma does not contradict an earlier pragma. */
+ if (seenlimo && (tglinmax!=val))
+ {
+ sprintf(linet1,"This pragma is opposed by the pragma at line %lu.",
+ (unsigned long) psprag.ps_line);
+ lr_mes(&ps_limo,linet1);
+ sprintf(linet1,"This pragma opposes the pragma at line %lu.",
+ (unsigned long) ps_limo.ps_line);
+ lr_err(&psprag,linet1);
+ lr_mes(&psprag,"You can have as many output line length pragmas");
+ lr_mes(&psprag,"as you like, but they all have to be the same!");
+ lr_mes(&psprag,"Pragma ignored.");
+ return;
+ }
+
+ /* If we got this far then the pragma is just the same as an earlier one. */
+ /* We don't want to set the pragma position to the later pragma so we */
+ /* return now. */
+ if (seenlimo) return;
+
+ /* Success. Set the variables. */
+ tglinmax=val;
+ seenlimo=TRUE;
+ ASSIGN(ps_limo,psprag);
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: \"@p maximum_output_line_length = <num>|infinity\".");
+ lr_mes(&arg[0].pt_ps,"Pragma ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgnpg P_((uword,p_pt_t));
+LOCAL void do_pgnpg(numarg,arg)
+/* Parse a newpage typesetter directive. */
+uword numarg;
+p_pt_t arg;
+{
+ /* Make sure that there is exactly one argument. */
+ if (numarg > 1) /* "new_page" */
+ {
+ lr_err(&arg[2].pt_ps,"The new_page directive does not take arguments.");
+ lr_mes(&arg[2].pt_ps,"Directive ignored.");
+ return;
+ }
+ sendspec(&arg[0].pt_ps,TK_NPAG,DONTCARE);
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgtoc P_((uword,p_pt_t));
+LOCAL void do_pgtoc(numarg,arg)
+/* Parse a table of contents typesetter directive. */
+uword numarg; /* Number of arguments to table of contents directive. */
+p_pt_t arg; /* Array describing arguments. */
+{
+ /* Make sure that there is exactly one argument. */
+ if (numarg > 1) /* "table_of_contents" */
+ {
+ lr_err(&arg[2].pt_ps,
+ "The table_of_contents directive does not take arguments.");
+ lr_mes(&arg[2].pt_ps,"Directive ignored.");
+ return;
+ }
+ sendspec(&arg[0].pt_ps,TK_TOCS,DONTCARE);
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgvsk P_((uword,p_pt_t));
+LOCAL void do_pgvsk(numarg,arg)
+/* Parse a vskip typesetter directive. */
+uword numarg; /* Number of arguments to indentation directive. */
+p_pt_t arg; /* Array describing arguments. */
+{
+ char *numstr;
+ uword spn;
+
+ /* Make sure that there are exactly three arguments. */
+ if (numarg != 3) /* "vskip" n "mm". */
+ {
+ lr_err(&arg[0].pt_ps,"This directive has the wrong number of arguments.");
+ goto help;
+ }
+
+ /* Make sure that the third argument is "mm". */
+ if (0 != strcmp(arg[3].pt_pstr,"mm"))
+ {lr_err(&arg[3].pt_ps,"Expecting \"mm\"."); goto help;}
+
+ /* Set up an abbreviation. */
+ numstr=arg[2].pt_pstr;
+
+ /* Calculate length of longest prefix containing all decimal digits. */
+ /* Check that there are no illegal digits. */
+ spn=strspn(numstr,"0123456789");
+ if (spn != strlen(numstr))
+ {
+ ps_t ps;
+ ASSIGN(ps,arg[2].pt_ps);
+ ps.ps_column+=spn;
+ lr_err(&ps,"Illegal digit.");
+ lr_mes(&ps,"Value must consist entirely of decimal digits.");
+ lr_mes(&ps,"Directive ignored.");
+ return;
+ }
+
+ /* Check that the number is not too long. */
+ if (strlen(numstr)>3)
+ {
+ lr_err(&arg[2].pt_ps,"Too many digits. The maximum is three.");
+ lr_mes(&arg[2].pt_ps,"Directive ignored.");
+ return;
+ }
+
+ /* Convert the argument into an integer. */
+ {
+ ulong val;
+ int result;
+ result=sscanf(numstr,"%ld",&val);
+ as_cold(result==1,"do_pginl:sscanf failed.");
+ if (val>255)
+ {
+ lr_err(&arg[2].pt_ps,"Value too large. Maximum is 255.");
+ lr_mes(&arg[2].pt_ps,"Directive ignored.");
+ return;
+ }
+ sendspec(&arg[0].pt_ps,TK_SKIP,(ubyte) val);
+ }
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,"The correct format is: \"@t vskip <num> mm\".");
+ lr_mes(&arg[0].pt_ps,"Directive ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgtit P_((uword,p_pt_t));
+LOCAL void do_pgtit(numarg,arg)
+/* Parse a title typesetter directive. */
+uword numarg; /* Number of arguments to title directive. */
+p_pt_t arg; /* Array describing arguments. */
+{
+ uword align;
+ uword font;
+ char *p_sot,*p_eot;
+
+ /* Make sure that there are at least three arguments. */
+ if (numarg < 4) /* "title <font> <align> <text>". */
+ {lr_err(&arg[0].pt_ps,"This directive has too few arguments."); goto help;}
+
+ /* Check the font argument. */
+ if (strcmp(arg[2].pt_pstr,"normalfont" )==0) font=FT_NORM;
+ else if (strcmp(arg[2].pt_pstr,"titlefont" )==0) font=FT_TITL;
+ else if (strcmp(arg[2].pt_pstr,"smalltitlefont")==0) font=FT_STIT;
+ else
+ {
+ lr_err(&arg[2].pt_ps,
+ "Expecting one of {titlefont,smalltitlefont,normalfont}.");
+ lr_mes(&arg[2].pt_ps,"Directive ignored.");
+ return;
+ }
+
+ /* Check the alignment argument. */
+ if (strcmp(arg[3].pt_pstr,"left" )==0) align=LR_LEFT;
+ else if (strcmp(arg[3].pt_pstr,"right" )==0) align=LR_RIGH;
+ else if (strcmp(arg[3].pt_pstr,"centre")==0) align=LR_CENT;
+ else
+ {
+ lr_err(&arg[3].pt_ps,"Expecting one of {left,right,centre}.");
+ if (strcmp(arg[3].pt_pstr,"center")==0)
+ {
+ lr_mes(&arg[3].pt_ps,"Note: Centre is spelt centRE, not centER.");
+ lr_mes(&arg[3].pt_ps," This is my revenge for years of getting error messages");
+ lr_mes(&arg[3].pt_ps," from TeX whenever I accidentally wrote \\centreline - Ross Williams.");
+ }
+ lr_mes(&arg[3].pt_ps,"Directive ignored.");
+ return;
+ }
+
+ /* Now make sure that the remainder of the line is delimited by quotes. */
+ p_sot=arg[4].pt_pinl;
+ p_eot=p_sot+strlen(p_sot)-1;
+ if (*p_sot!='"' || *p_eot!='"' || p_sot==p_eot)
+ {
+ lr_err(&arg[4].pt_ps,"Text argument must be delimited by double quotes.");
+ lr_mes(&arg[4].pt_ps,"Directive ignored.");
+ return;
+ }
+ p_sot++; p_eot--;
+
+ /* Ship out a token whose fields are all fully laden. */
+ {
+ tk_t token;
+ token.tk_kind = TK_TITL;
+ ASSIGN(token.tk_ps,arg[0].pt_ps);
+ token.tk_sc.sc_first = p_sol+ (3+(p_sot-arg[1].pt_pinl));
+ token.tk_sc.sc_last = p_sol+ (3+(p_eot-arg[1].pt_pinl));
+ token.tk_sc.sc_white = FALSE;
+ token.tk_gen = LRFT_PACK*font+align;
+ ls_add(token_list,PV &token);
+ }
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: \"@t title <font> <align> <text>\".");
+ lr_mes(&arg[0].pt_ps,
+ " where <font> = titlefont | smalltitlefont | normalfont.");
+ lr_mes(&arg[0].pt_ps,
+ " and <align> = left | centre | right.");
+ lr_mes(&arg[0].pt_ps,
+ " and <text> = text delimited by double quotes.");
+ lr_mes(&arg[0].pt_ps,"Directive ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgtyp P_((uword,p_pt_t));
+LOCAL void do_pgtyp(numarg,arg)
+/* Parse a typesetter pragma. */
+uword numarg;
+p_pt_t arg;
+{
+ tr_k_t pragtyp;
+ ps_t psprag;
+
+ /* Make sure that there are exactly three arguments. */
+ if (numarg != 3) /* "typesetter" "=" "name". */
+ {
+ lr_err(&arg[0].pt_ps,
+ "This typesetter pragma has the wrong number of arguments.");
+ goto help;
+ }
+
+ /* Make sure that the second argument is "=". */
+ if (0 != strcmp(arg[2].pt_pstr,"="))
+ {
+ lr_err(&arg[2].pt_ps,"Expecting \"=\".");
+ goto help;
+ }
+
+ /* Check the third argument. */
+ if (strcmp(arg[3].pt_pstr,"none")==0) pragtyp=TR_NONE;
+ else if (strcmp(arg[3].pt_pstr,"tex" )==0) pragtyp=TR_TEX;
+ /* ABC { */
+ else if (strcmp(arg[3].pt_pstr,"hypertext" )==0) pragtyp=TR_HTXT;
+ else if (strcmp(arg[3].pt_pstr,"html" )==0) pragtyp=TR_HTML;
+ /* } ABC */
+ else
+ {
+ /* ABC { */
+ lr_err(&arg[3].pt_ps,"Expecting one of:");
+ lr_err(&arg[3].pt_ps," (i) \"none\"");
+ lr_err(&arg[3].pt_ps," (ii) \"tex\"");
+ lr_err(&arg[3].pt_ps," (iii) \"hypertext\"");
+ lr_err(&arg[3].pt_ps," (iv) \"html\".");
+ /* } ABC */
+ goto help;
+ }
+
+ /* Construct a shorthand for the start of the pragma. */
+ ASSIGN(psprag,arg[0].pt_ps);
+
+ /* Make sure that the pragma does not contradict an earlier pragma. */
+ if (seentyp && (tr_codes != pragtyp))
+ {
+ sprintf(linet1,"This pragma is opposed by the pragma at line %lu.",
+ (unsigned long) psprag.ps_line);
+ lr_mes(&ps_typ,linet1);
+ sprintf(linet1,"This pragma opposes the pragma at line %lu.",
+ (unsigned long) ps_typ.ps_line);
+ lr_err(&psprag,linet1);
+ lr_mes(&psprag,"You can have as many typesetter pragmas as you like,");
+ lr_mes(&psprag,"but they all have to be the same!");
+ lr_mes(&psprag,"Pragma ignored.");
+ return;
+ }
+
+ /* Success: Record the pragma information. */
+ seentyp = TRUE; /* Record that we have seen a pragma. */
+ tr_codes = pragtyp; /* Record what the pragma said. */
+ ASSIGN(ps_typ,psprag); /* Record where the pragma was. */
+ return;
+
+ help:
+ /* ABC { */
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: \"@p typesetter = none|tex\"");
+ lr_mes(&arg[0].pt_ps,
+ " or for hypertext \"@p typesetter = hypertext|html\".");
+ /* } ABC */
+ lr_mes(&arg[0].pt_ps,"Pragma ignored.");
+ return;
+}
+
+/* ABC { */
+/******************************************************************************/
+
+LOCAL void do_pgnoh P_((uword,p_pt_t));
+LOCAL void do_pgnoh(numarg,arg)
+/* Parse a no_doc_header pragma. */
+uword numarg;
+p_pt_t arg;
+{
+ /* Make sure that there is exactly one arguments. */
+ if (numarg != 1) /* "no_doc_header". */
+ {
+ lr_err(&arg[0].pt_ps,
+ "This no_doc_header pragma has the wrong number of arguments.");
+ goto help;
+ }
+
+ /* Success: set the value of doc_incQ. */
+ doc_incQ = FALSE;
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: \"@p no_doc_header\".");
+ lr_mes(&arg[0].pt_ps,"Pragma ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgraw P_((uword,p_pt_t));
+LOCAL void do_pgraw(numarg,arg)
+/* Parse a raw_macro_and_section_names pragma. */
+uword numarg;
+p_pt_t arg;
+{
+ /* Make sure that there is exactly one argument. */
+ if (numarg != 1) /* "raw_macro_and_section_names". */
+ {
+ lr_err(&arg[0].pt_ps,
+ "This raw_macro_and_section_names pragma has the wrong number of arguments.");
+ goto help;
+ }
+
+ /* Success: set the value of raw_namQ. */
+ raw_namQ = TRUE;
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: \"@p raw_macro_and_section_names\".");
+ lr_mes(&arg[0].pt_ps,"Pragma ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgign P_((uword,p_pt_t));
+LOCAL void do_pgign(numarg,arg)
+/* Parse an ignore_text_after_special_minus pragma. */
+uword numarg;
+p_pt_t arg;
+{
+ /* Make sure that there is exactly one argument. */
+ if (numarg != 1) /* "ignore_text_after_special_minus". */
+ {
+ lr_err(&arg[0].pt_ps,
+ "This ignore_text_after_special_minus pragma has the wrong number of arguments.");
+ goto help;
+ }
+
+ /* Success: set the value of raw_namQ. */
+ igntxtQ = TRUE;
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: \"@p ignore_text_after_special_minus\".");
+ lr_mes(&arg[0].pt_ps,"Pragma ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgnpm P_((uword,p_pt_t));
+LOCAL void do_pgnpm(numarg,arg)
+/* Parse a no_paragraph_markups pragma. */
+uword numarg;
+p_pt_t arg;
+{
+ /* Make sure that there is exactly one argument. */
+ if (numarg != 1) /* "no_paragraph_markups". */
+ {
+ lr_err(&arg[0].pt_ps,
+ "This no_paragraph_markups pragma has the wrong number of arguments.");
+ goto help;
+ }
+
+ /* Success: set the value of no_pmrkQ. */
+ no_pmrkQ = TRUE;
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: \"@p no_paragraph_markups\".");
+ lr_mes(&arg[0].pt_ps,"Pragma ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgasct P_((uword,p_pt_t));
+LOCAL void do_pgasct(numarg,arg)
+/* Allow source code typing. */
+uword numarg;
+p_pt_t arg;
+{
+
+ /* Make sure that there is exactly one arguments. */
+ if (numarg != 1) /* "allow_source_code_typing".
+ */
+ {
+ lr_err(&arg[0].pt_ps,"This pragma has the wrong number of arguments.");
+ goto help;
+ }
+ xsrctypesQ = TRUE;
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: '@p declare_source_code_type \"<name>\"'.");
+ lr_mes(&arg[0].pt_ps,"Pragma ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgdsrc P_((uword,p_pt_t));
+LOCAL void do_pgdsrc(numarg,arg)
+/* Define a user defined source code type. */
+uword numarg;
+p_pt_t arg;
+{
+ char *srcname, *tmp, *clpos;
+ p_srcnmac_t nexttype;
+ srcnmac_t newtype;
+ bool undefinedQ = TRUE;
+
+ /* Make sure that there are exactly two arguments. */
+ if (numarg != 2) /* "declare_source_code_type" "\"name\"".
+ */
+ {
+ lr_err(&arg[0].pt_ps,"This pragma has the wrong number of arguments.");
+ goto help;
+ }
+ /* Are extra source code types allowed? */
+ if (!xsrctypesQ) {
+ lr_err(&arg[0].pt_ps,"A pragma is required to allow source code types.");
+ goto help;
+ } /* end if */
+
+ /* Parse the name of the source type name. */
+ srcname = arg[2].pt_pstr;
+ /* Check for opening quotes surrounding macro name. */
+ if (*srcname != '"') {
+ lr_err(&arg[2].pt_ps,"Expecting opening \".");
+ goto help;
+ } /* end if */
+ /* Check for closing quotes at end of macro name. *
+ * Double quotes can be used in the macro name by *
+ * escaping them with a backslash. */
+ tmp = srcname + 1;
+ for (;;) { /* forever */
+ clpos = strchr(tmp, '"');
+ if (clpos == NULL) {
+ lr_err(&arg[2].pt_ps,"Can't find closing \".");
+ goto help;
+ } /* end if */
+ if (*(clpos+1) == (char)0) break; /* Quotes are at end. OK. */
+ if (*(clpos-1) == '\\') {
+ /* Quotes are quoted into string using backslash. */
+ tmp = clpos + 1;
+ continue; /* Keep searching. */
+ } /* end if */
+ /* Quotes must have text after them. This is bad. */
+ lr_err(&arg[2].pt_ps,"Extraneous text after closing \".");
+ goto help;
+ } /* end forever */
+ /* Check that source type name is unique. */
+ if (strlen(srcname) <= 2) {
+ lr_err(&arg[2].pt_ps,"Length of source type name must be >=1.");
+ goto help;
+ } /* end if */
+ ls_fir(srctlist);
+ for (;;) { /* forever */
+ ls_nxt(srctlist, (pp_lsel_t)&nexttype);
+ if (nexttype == NULL) break;
+ if (nexttype->typnam == NULL) continue;
+ if (!strncmp(nexttype->typnam, srcname+1, strlen(srcname)-2)) {
+ undefinedQ = FALSE;
+ } /* end if */
+ } /* end forever */
+ if (undefinedQ) {
+ newtype.typnam =
+ mm_temp((size_t) (strlen(srcname)-1)*sizeof(char));
+ strncpy(newtype.typnam, srcname+1, strlen(srcname)-2);
+ newtype.lnmac = NULL;
+ ls_add(srctlist, (p_lsel_t)&newtype);
+ } /* end if */
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: '@p declare_source_code_type \"<name>\"'.");
+ lr_mes(&arg[0].pt_ps,"Pragma ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgaldm P_((uword,p_pt_t));
+LOCAL void do_pgaldm(numarg,arg)
+/* Parse an automatic line directive macro pragma. */
+uword numarg;
+p_pt_t arg;
+{
+ char *autoname, *srcname, *tmp, *clpos;
+ p_srcnmac_t nexttype;
+
+ /* Make sure that there are three or four arguments. */
+ if ((numarg != 3) && (numarg != 4))
+ /* "automatic_line_directive_macro" "=" "\"name\"" or. *
+ * "automatic_line_directive_macro" "=" "\"name\"" "\"srctype\"" */
+ {
+ lr_err(&arg[0].pt_ps,"This pragma has the wrong number of arguments.");
+ goto help;
+ }
+
+ /* Make sure that the second argument is an "=". */
+ if (0 != strcmp(arg[2].pt_pstr,"="))
+ {lr_err(&arg[2].pt_ps,"Expecting \"=\"."); goto help;}
+
+ /* Parse the name of the automatic line call macro. */
+ autoname = arg[3].pt_pstr;
+ /* Check for opening quotes surrounding macro name. */
+ if (*autoname != '"') {
+ lr_err(&arg[3].pt_ps,"Expecting opening \".");
+ goto help;
+ } /* end if */
+ /* Check for closing quotes at end of macro name. *
+ * Double quotes can be used in the macro name by *
+ * escaping them with a backslash. */
+ tmp = autoname + 1;
+ for (;;) { /* forever */
+ clpos = strchr(tmp, '"');
+ if (clpos == NULL) {
+ lr_err(&arg[3].pt_ps,"Can't find closing \".");
+ goto help;
+ } /* end if */
+ if (*(clpos+1) == (char)0) break; /* Quotes are at end. OK. */
+ if (*(clpos-1) == '\\') {
+ /* Quotes are quoted into string using backslash. */
+ tmp = clpos + 1;
+ continue; /* Keep searching. */
+ } /* end if */
+ /* Quotes must have text after them. This is bad. */
+ lr_err(&arg[3].pt_ps,"Extraneous text after closing \".");
+ goto help;
+ } /* end forever */
+ if (numarg == 4) {
+ /* Parse the name of the source code type. */
+ srcname = arg[4].pt_pstr;
+ /* Check for opening quotes surrounding source type name. */
+ if (*srcname != '"') {
+ lr_err(&arg[4].pt_ps,"Expecting opening \".");
+ goto help;
+ } /* end if */
+ /* Check for closing quotes at end of source type name. *
+ * Double quotes can be used in the macro name by *
+ * escaping them with a backslash. */
+ tmp = srcname + 1;
+ for (;;) { /* forever */
+ clpos = strchr(tmp, '"');
+ if (clpos == NULL) {
+ lr_err(&arg[4].pt_ps,"Can't find closing \".");
+ goto help;
+ } /* end if */
+ if (*(clpos+1) == (char)0) break; /* Quotes are at end. OK. */
+ if (*(clpos-1) == '\\') {
+ /* Quotes are quoted into string using backslash. */
+ tmp = clpos + 1;
+ continue; /* Keep searching. */
+ } /* end if */
+ /* Quotes must have text after them. This is bad. */
+ lr_err(&arg[4].pt_ps,"Extraneous text after closing \".");
+ goto help;
+ } /* end forever */
+ if (strlen(srcname) <= 2) {
+ lr_err(&arg[4].pt_ps,"Length of source code type name must be >= 1.");
+ goto help;
+ } /* end if */
+ } else {
+ srcname = NULL;
+ } /* end if */
+
+ ls_fir(srctlist);
+ ls_nxt(srctlist, (pp_lsel_t)&nexttype);
+ if (srcname != NULL) {
+ for (
+ ;
+ nexttype != NULL;
+ ls_nxt(srctlist, (pp_lsel_t)&nexttype)
+ ) {
+ if (nexttype->typnam == NULL) continue;
+ if (!strncmp(nexttype->typnam, srcname+1, strlen(srcname)-2))
+ break;
+ } /* end for */
+ if (nexttype == NULL) {
+ lr_err(&arg[4].pt_ps,"Source code type not declared.");
+ goto help;
+ } /* end if */
+ } /* end if */
+ if (nexttype->lnmac != NULL) {
+ lr_err(&arg[4].pt_ps,"Automatic line insertion macro already defined for source code type.");
+ goto help;
+ } /* end if */
+ nexttype->lnmac =
+ mm_temp((size_t) (strlen(autoname)-1)*sizeof(char));
+ strncpy(nexttype->lnmac, autoname+1, strlen(autoname)-2);
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: '@p automatic_line_directive_macro = \"<name>\"'.");
+ lr_mes(&arg[0].pt_ps,
+ " or: '@p automatic_line_directive_macro = \"<name>\" \"<srctype>\"'.");
+ lr_mes(&arg[0].pt_ps,"Pragma ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pglof P_((uword,p_pt_t));
+LOCAL void do_pglof(numarg,arg)
+/* Parse a #line offset pragma. */
+uword numarg;
+p_pt_t arg;
+{
+ char *numstr;
+ uword spn;
+ ulong val;
+
+ /* Make sure that there are exactly three arguments. */
+ if (numarg != 3) /* "#line_offset" "=" "value". */
+ {
+ lr_err(&arg[0].pt_ps,"This pragma has the wrong number of arguments.");
+ goto help;
+ }
+
+ /* Make sure that the second argument is an "=". */
+ if (0 != strcmp(arg[2].pt_pstr,"="))
+ {lr_err(&arg[2].pt_ps,"Expecting \"=\"."); goto help;}
+
+ /* Set up an abbreviation. */
+ numstr=arg[3].pt_pstr;
+
+ /* Calculate length of longest prefix containing all decimal digits. */
+ /* A leading minus sign is also permissible. */
+ /* Check that there are no illegal digits, etc. */
+ spn=strspn(numstr,"0123456789");
+ if ((spn != strlen(numstr)) && (strchr("-",numstr[0]) != NULL))
+ {
+ spn=strspn(numstr+1,"0123456789")+1;
+ }
+ if (spn != strlen(numstr))
+ {
+ ps_t ps;
+ ASSIGN(ps,arg[3].pt_ps);
+ ps.ps_column+=spn;
+ lr_err(&ps,"Illegal digit. Value must consist entirely of decimal digits.");
+ lr_mes(&ps,"A leading \"-\" is also permitted.");
+ lr_mes(&ps,"You can also use the value \"infinity\".");
+ lr_mes(&ps,"Pragma ignored.");
+ return;
+ }
+
+ /* Check that the number is not too long. */
+ if (strlen(numstr)>4)
+ {
+ lr_err(&arg[3].pt_ps,"Too many digits. The maximum is four.");
+ lr_mes(&arg[3].pt_ps,"Pragma ignored.");
+ return;
+ }
+
+ /* Convert the argument into an integer. */
+ {
+ int result=sscanf(numstr,"%ld",&val);
+ as_cold(result==1,"do_pglof:sscanf failed.");
+ }
+
+ /* Success. Set the global variable. */
+ lin_off=(word)val;
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: \"@p #line_offset = <num>\".");
+ lr_mes(&arg[0].pt_ps,"Pragma ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgldp P_((uword,p_pt_t));
+LOCAL void do_pgldp(numarg,arg)
+/* Parse a #line depth pragma. */
+uword numarg;
+p_pt_t arg;
+{
+ char *numstr;
+ uword spn;
+ ulong val;
+
+ /* Make sure that there are exactly three arguments. */
+ if (numarg != 3) /* "#line_depth" "=" "value". */
+ {
+ lr_err(&arg[0].pt_ps,"This pragma has the wrong number of arguments.");
+ goto help;
+ }
+
+ /* Make sure that the second argument is an "=". */
+ if (0 != strcmp(arg[2].pt_pstr,"="))
+ {lr_err(&arg[2].pt_ps,"Expecting \"=\"."); goto help;}
+
+ /* Set up an abbreviation. */
+ numstr=arg[3].pt_pstr;
+
+ /* Calculate length of longest prefix containing all decimal digits. */
+ /* Check that there are no illegal digits, etc. */
+ spn=strspn(numstr,"0123456789");
+ if (spn != strlen(numstr))
+ {
+ ps_t ps;
+ ASSIGN(ps,arg[3].pt_ps);
+ ps.ps_column+=spn;
+ lr_err(&ps,"Illegal digit. Value must consist entirely of decimal digits.");
+ lr_mes(&ps,"You can also use the value \"infinity\".");
+ lr_mes(&ps,"Pragma ignored.");
+ return;
+ }
+
+ /* Check that the number is not too long. */
+ if (strlen(numstr)>4)
+ {
+ lr_err(&arg[3].pt_ps,"Too many digits. The maximum is four.");
+ lr_mes(&arg[3].pt_ps,"Pragma ignored.");
+ return;
+ }
+
+ /* Convert the argument into an integer. */
+ {
+ int result=sscanf(numstr,"%ld",&val);
+ as_cold(result==1,"do_pgldp:sscanf failed.");
+ }
+
+ /* Success. Set the global variable. */
+ lin_dep=(word)val;
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: \"@p #line_depth = <num>\".");
+ lr_mes(&arg[0].pt_ps,"Pragma ignored.");
+ return;
+}
+/* } ABC */
+
+/******************************************************************************/
+
+LOCAL void do_pragma P_((p_ps_t,bool));
+LOCAL void do_pragma(p_ps,is_typ)
+/* Upon entry, the current character is: */
+/* is_typ=FALSE => The P of a @p. */
+/* is_typ=TRUE => The T of a @t. */
+/* This function processes these contructs. */
+p_ps_t p_ps;
+bool is_typ;
+{
+#define MAXPARG 10 /* Maximum recorded arguments to a pragma. */
+#define PRAGMA_FWMAX 100 /* Maximum length of a pragma. */
+ char praglin[PRAGMA_FWMAX+1]; /* Array to hold pragma as a complete line. */
+ char pragstr[PRAGMA_FWMAX+1]; /* Array to hold pragma as strings. */
+ pt_t pragarg[MAXPARG+1]; /* Array of pragma arguments. */
+ uword length; /* Helps prevent scanning overrun. */
+ char *p,*q; /* Temporary. */
+ uword numarg,na; /* Number of arguments seen so far. */
+
+ /* Complain if the pragma directive is not at the start of a line. */
+ if (p_ch-1 != p_sol)
+ {
+ if (is_typ)
+ {
+ lr_err(p_ps,"Typesetter directive @t must be at the start of a line.");
+ lr_mes(p_ps,"The rest of this line will be ignored.");
+ }
+ else
+ {
+ lr_err(p_ps,"Pragma sequence @p must be at the start of a line.");
+ lr_mes(p_ps,"The rest of this line will be ignored.");
+ }
+ skiptoeol();
+ goto help;
+ }
+
+ /* The include command should be followed by a blank. Get the next char. */
+ NEXTCH;
+
+ /* Complain if the next character is not a blank. */
+ if (ch != ' ')
+ {
+ /* Note: If we position this error correctly, it gets put after the */
+ /* help message! */
+ if (is_typ)
+ lr_err(p_ps,"Typesetter directive @t must be followed by a blank.");
+ else
+ lr_err(p_ps,"Pragma sequence @p must be followed by a blank.");
+ skiptoeol();
+ goto help;
+ }
+
+ /* Copy the rest of the line to the pragma arrays. */
+ NEXTCH;
+ p = &praglin[0];
+ q = &pragstr[0];
+ length=0;
+ while (ch!=EOL)
+ {
+ if (++length > PRAGMA_FWMAX-3) /* 3 is for "@p " or "@t " */
+ {
+ if (is_typ)
+ {
+ lr_err(p_ps,"This typestter directive line is too long.");
+ sprintf(linet1,"The maximum typesetter directive line length is %u characters.",
+ (unsigned) PRAGMA_FWMAX);
+ lr_mes(p_ps,linet1);
+ }
+ else
+ {
+ lr_err(p_ps,"This pragma line is too long.");
+ sprintf(linet1,"The maximum pragma line length is %u characters.",
+ (unsigned) PRAGMA_FWMAX);
+ lr_mes(p_ps,linet1);
+ }
+ skiptoeol();
+ goto help;
+ }
+ *p++=ch;
+ *q++=ch;
+ NEXTCH;
+ }
+ *p=EOS;
+ *q=EOS;
+ /* Note: Current position is now on the EOL at the end of the @p line. */
+ /* That is the way we want to leave it for the scanspec() routine. */
+
+ /* So far we have copied the body of the pragma line into two arrays. The */
+ /* next lump of code parses that line into a sequence of non-blank arguments.*/
+ /* The result is an array of pt_t objects each of which contains the */
+ /* position of each argument, a pointer to the first character of each */
+ /* argument in praglin, and also a pointer to a string containing the arg. */
+ /* The string resides in the array pragstr which is the same as praglin */
+ /* except that some blanks have been replaced by EOSs so as to allow us to */
+ /* point into it to form strings. All this probably seems rather overdone */
+ /* for the analysis of a "simple" pragma, but I have found that pulling the */
+ /* different kinds of pragma lines apart separately is very messy. Far */
+ /* better to suffer here in what is at least reasonably neat code than */
+ /* later in the specific pragma routines. */
+ numarg=0;
+ p= &praglin[0];
+ q= &pragstr[0];
+ while (TRUE)
+ {
+ /* Skip whitespace between arguments. */
+ while (*p==' ') {p++;q++;}
+
+ /* Exit if we have hit the end of the line. */
+ if ((numarg==MAXPARG) || (*p==EOS)) break;
+
+ /* We have found another argument! */
+ numarg++;
+
+ /* Record the argument. */
+ ASSIGN(pragarg[numarg].pt_ps,*p_ps);
+ pragarg[numarg].pt_ps.ps_column=4+(p-praglin);
+ pragarg[numarg].pt_pinl=p;
+ pragarg[numarg].pt_pstr=q;
+
+ /* Skip to the end of the argument. */
+ while (*p!=' ' && *p!=EOS) {p++;q++;}
+
+ /* Drop a null in the string array to complete string rep of argument. */
+ *q=EOS;
+ }
+
+ /* At this point numarg is MIN(arguments,MAXPARG), and pragargs contains an */
+ /* entry for each of the numarg arguments. */
+
+ /* It is handy to have the position of the pragma itself handy. */
+ ASSIGN(pragarg[0].pt_ps,*p_ps);
+
+ /* CHECK: Make sure that the line and string arrays square up. */
+ {
+ uword i;
+ for (i=1;i<=numarg;i++)
+ {
+ uword j;
+ uword t=strlen(pragarg[i].pt_pstr);
+ for (j=0;j<t;j++)
+ {
+ as_cold(pragarg[i].pt_pstr[j]==pragarg[i].pt_pinl[j],
+ "do_pragma: String and line arrays are not equal.");
+ as_cold((pragarg[i].pt_pstr-pragstr)==(pragarg[i].pt_pinl-praglin),
+ "do_pragma: String and line arrays are out of synch.");
+ }
+ }
+ }
+
+ /* Complain if there are no arguments at all. */
+ if (numarg==0)
+ {
+ if (is_typ)
+ lr_err(p_ps,"Typesetter directive @t must be followed by a keyword.");
+ else
+ lr_err(p_ps,"Pragma sequence @p must be followed by a keyword.");
+ skiptoeol();
+ goto help;
+ }
+
+ /* Branch off to specific routines based on the first argument. */
+ p=pragarg[1].pt_pstr; na=numarg;
+ if (is_typ)
+ {
+ if (0==strcmp(p,"new_page" )) {do_pgnpg(na,pragarg);return;}
+ if (0==strcmp(p,"table_of_contents" )) {do_pgtoc(na,pragarg);return;}
+ if (0==strcmp(p,"title" )) {do_pgtit(na,pragarg);return;}
+ if (0==strcmp(p,"vskip" )) {do_pgvsk(na,pragarg);return;}
+ }
+ else
+ {
+ if (0==strcmp(p,"indentation" )) {do_pgind(na,pragarg);return;}
+ if (0==strcmp(p,"maximum_input_line_length" )) {do_pginl(na,pragarg);return;}
+ if (0==strcmp(p,"maximum_output_line_length")) {do_pgotl(na,pragarg);return;}
+ if (0==strcmp(p,"typesetter" )) {do_pgtyp(na,pragarg);return;}
+/* ABC { */
+ if (0==strcmp(p,"no_doc_header" )) {do_pgnoh(na,pragarg);return;}
+ if (0==strcmp(p,"raw_macro_and_section_names")) {do_pgraw(na,pragarg);return;}
+ if (0==strcmp(p,"ignore_text_after_special_minus")) {do_pgign(na,pragarg);return;}
+ if (0==strcmp(p,"no_paragraph_markups" )) {do_pgnpm(na,pragarg);return;}
+ if (0==strcmp(p,"allow_source_code_typing" )) {do_pgasct(na,pragarg);return;}
+ if (0==strcmp(p,"declare_source_code_type" )) {do_pgdsrc(na,pragarg);return;}
+ if (0==strcmp(p,"automatic_line_directive_macro")) {do_pgaldm(na,pragarg);return;}
+ if (0==strcmp(p,"#line_offset" )) {do_pglof(na,pragarg);return;}
+ if (0==strcmp(p,"#line_depth" )) {do_pgldp(na,pragarg);return;}
+/* } ABC */
+ }
+
+ help:
+ if (is_typ)
+ {
+ lr_err(p_ps,"Unrecognised typesetter directive. Legal ones are:");
+ lr_mes(p_ps," @t new_page");
+ lr_mes(p_ps," @t table_of_contents");
+ lr_mes(p_ps," @t title <font> <align> <string>");
+ lr_mes(p_ps," @t vskip <num> mm");
+ lr_mes(p_ps,"The blanks between arguments are important.");
+ lr_mes(p_ps,"Typesetter directive ignored.");
+ }
+ else
+ {
+ lr_err(p_ps,"Unrecognised pragma. Possible legal pragmas are:");
+ lr_mes(p_ps," @p indentation = none | blank");
+ lr_mes(p_ps," @p maximum_input_line_length = <num>|infinity");
+ lr_mes(p_ps," @p maximum_output_line_length = <num>|infinity");
+ /* ABC { */
+ lr_mes(p_ps," @p typesetter = none | tex | hypertext | html");
+ lr_mes(p_ps," @p no_doc_header");
+ lr_mes(p_ps," @p raw_macro_and_section_names");
+ lr_mes(p_ps," @p ignore_text_after_special_minus");
+ lr_mes(p_ps," @p no_paragraph_markups");
+ lr_mes(p_ps," @p declare_source_code_type \"<name>\"");
+ lr_mes(p_ps," @p automatic_line_directive_macro = \"<name>\"");
+ lr_mes(p_ps," @p automatic_line_directive_macro = \"<name>\" \"<srctype>\"");
+ lr_mes(p_ps," @p #line_offset = <num>");
+ lr_mes(p_ps," @p #line_depth = <num>");
+ /* } ABC */
+ lr_mes(p_ps,"The blanks between arguments are important.");
+ lr_mes(p_ps,"Pragma ignored.");
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void chksol P_((void));
+LOCAL void chksol()
+/* This function is called when the current character is the character after */
+/* an @. The function checks to see if the @ was at the start of a line and */
+/* issues a error message if it isn't. */
+{
+ ps_t ps;
+ grabchps(&ps);
+ if (ps.ps_column != 2)
+ {
+ ps.ps_column--;
+ sprintf(linet1,"@%c is legal only at the start of a line.",ch);
+ lr_err(&ps,linet1);
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void scanspec P_((void));
+LOCAL void scanspec()
+/* Upon entry the current character is the special character (usually '@'). */
+/* The task is to scan the special sequence. Upon exit, the current character */
+/* is the character following the special sequence. */
+{
+ ps_t ps_spec; /* Position of start of special sequence. */
+
+ /* Make a note of where the special sequence starts. */
+ grabchps(&ps_spec);
+
+ /* Move onto the character following the special (escape) character. */
+ NEXTCH;
+
+ /* Now react to the character. In most cases, the special sequence is simply */
+ /* a marker in the input and we can simply transmit it. The nasty special */
+ /* case sequences are left until the end of the switch statement. */
+ /* Purists will complain about how all the case options are hardwired and */
+ /* say that symbols should have been used. They once were, but were taken */
+ /* out when it was discovered that the symbols had cryptic names (because of */
+ /* the portability eight-character rule) and were only used here anyway. */
+ switch (toupper(ch))
+ {
+ case '<': sendspec(&ps_spec,TK_ONAM,DONTCARE); break;
+ case '>': sendspec(&ps_spec,TK_CNAM,DONTCARE); break;
+ case '{': sendspec(&ps_spec,TK_ODEF,DONTCARE); break;
+ case '}': sendspec(&ps_spec,TK_CDEF,DONTCARE); break;
+ case '(': sendspec(&ps_spec,TK_OPAR,DONTCARE); break;
+ case ')': sendspec(&ps_spec,TK_CPAR,DONTCARE); break;
+ case ',': sendspec(&ps_spec,TK_COMA,DONTCARE); break;
+ case '"': sendspec(&ps_spec,TK_QUOT,DONTCARE); break;
+ case '/': sendspec(&ps_spec,TK_EMPH,DONTCARE); break;
+ case 'A': sendspec(&ps_spec,TK_NSEC,1); chksol(); break;
+ case 'B': sendspec(&ps_spec,TK_NSEC,2); chksol(); break;
+ case 'C': sendspec(&ps_spec,TK_NSEC,3); chksol(); break;
+ case 'D': sendspec(&ps_spec,TK_NSEC,4); chksol(); break;
+ case 'E': sendspec(&ps_spec,TK_NSEC,5); chksol(); break;
+ case '1': sendspec(&ps_spec,TK_PARM,1); break;
+ case '2': sendspec(&ps_spec,TK_PARM,2); break;
+ case '3': sendspec(&ps_spec,TK_PARM,3); break;
+ case '4': sendspec(&ps_spec,TK_PARM,4); break;
+ case '5': sendspec(&ps_spec,TK_PARM,5); break;
+ case '6': sendspec(&ps_spec,TK_PARM,6); break;
+ case '7': sendspec(&ps_spec,TK_PARM,7); break;
+ case '8': sendspec(&ps_spec,TK_PARM,8); break;
+ case '9': sendspec(&ps_spec,TK_PARM,9); break;
+ case 'M': sendspec(&ps_spec,TK_MANY,DONTCARE); break;
+ case 'Z': sendspec(&ps_spec,TK_ZERO,DONTCARE); break;
+ case 'O': sendspec(&ps_spec,TK_FDEF,DONTCARE); chksol(); break;
+ case '$': sendspec(&ps_spec,TK_MDEF,DONTCARE); chksol(); break;
+ case EOL:
+ lr_err(&ps_spec,"<special><endofline> is not a legal special sequence.");
+ break;
+ case ' ':
+ lr_err(&ps_spec,"<special><space> is not a legal special sequence.");
+ break;
+ case '@':
+ /* @ instructs FunnelWeb to replace the special construct with the */
+ /* special character. Luckily one appears just before the @ !! */
+ /* Note: FALSE is OK because space is not a legal specialch. */
+ sendtext(&ps_spec,p_ch-1,p_ch-1,FALSE);
+ break;
+ case '-':
+ /* - instructs FunnelWeb to suppress the following end of line. */
+ if (*(p_ch+1) == EOL) {
+ NEXTCH
+ /* ABC { */
+ } else if (igntxtQ) {
+ while (*(p_ch+1) != EOL) NEXTCH;
+ } else {
+ lr_err(&ps_spec,
+ "Suppress EOL sequence is legal only at the end of a line");
+ lr_mes(&ps_spec,
+ "unless `@p ignore_text_after_special_minus' is used.");
+ } /* end if */
+ /* } ABC */
+ break;
+ case '+':
+ /* + instructs FunnelWeb to insert an EOL. We can't look to the end of */
+ /* the previous line to find an EOL as this might be the first line. */
+ /* Running ahead to the end of the line is expensive, and having the */
+ /* liner mini-package maintain a variable for it would be extra */
+ /* housekeeping. Instead of all this, we just point to a static. */
+ {STAVAR char stateol = EOL;
+ sendtext(&ps_spec,&stateol,&stateol,TRUE);}
+ break;
+ case '=':
+ /* = instructs FunnelWeb to change the special character to the */
+ /* character following the <special>= sequence. */
+ NEXTCH;
+ if (ch == ' ')
+ {
+ lr_err(&ps_spec,"You cannot set the special character to <space>!");
+ lr_mes(&ps_spec,"Special sequence ignored.");
+ }
+ else if (ch == EOL)
+ {
+ lr_err(&ps_spec,
+ "You cannot set the special character to <endofline>!");
+ lr_mes(&ps_spec,"Special sequence ignored.");
+ }
+ else
+ specialch=ch;
+ break;
+ case '!':
+ /* ! instructs FunnelWeb to ignore the rest of the line (a comment). */
+ skiptoeol();
+ break;
+ case 'I':
+ /* i instructs FunnelWeb to include a file. */
+ incl_fil(&ps_spec);
+ break;
+ case '^':
+ /* ^ instructs FunnelWeb to insert a specific ascii character. */
+ do_ascii(&ps_spec);
+ break;
+ case '#':
+ /* # instructs FunnelWeb to transmit a two character name "#c". */
+ do_name(&ps_spec);
+ break;
+ case 'P':
+ /* P is used as a miscellaneous PRAGMA. */
+ do_pragma(&ps_spec,FALSE);
+ break;
+ case 'T':
+ /* T introduces a one-line typesetting directive. */
+ do_pragma(&ps_spec,TRUE);
+ break;
+ default:
+ lr_err(&ps_spec,"Unknown special sequence.");
+ break;
+ }
+
+ /* The switch statment absorbs the special sequence and its effects. */
+ /* This NEXTCH places us on the character following the special sequence. */
+ NEXTCH;
+}
+
+/******************************************************************************/
+
+LOCAL void scantext P_((void));
+LOCAL void scantext()
+/* Upon entry, we know that the current character is not EOF and that it is */
+/* not the special character. Our task is to parse as much text as we can and */
+/* ship it off as a text token. The scanner will probably spend most of its */
+/* time in the loops in this function so it is important that they be */
+/* efficient. That is why two loops are used to deal with detecting */
+/* whitespace rather than a flag. */
+/* Upon return, the current character is the character following the text */
+/* sequence. This is guaranteed to be the special character or an EOF. */
+{
+ ps_t ps_start; /* Position of first character of text sequence. */
+ char *p_first = p_ch; /* Pointer to first character of text sequence. */
+
+ /* Grab a copy of the position of this token. */
+ grabchps(&ps_start);
+
+ /* Scan whitespace. */
+ while (ch==' ' || ch==EOL)
+ NEXTCH;
+
+ /* If we hit something that ends a text token */
+ /* then we can transmit a white text token. */
+ if (ch==specialch || ch==EOFCH)
+ {sendtext(&ps_start,p_first,p_ch-1,TRUE); return;}
+
+ /* Otherwise we have some more (non-white) text to scan. */
+ /* We can then send a non-white text token. */
+ while (ch!=specialch && ch!=EOFCH)
+ NEXTCH;
+ sendtext(&ps_start,p_first,p_ch-1,FALSE);
+}
+
+/******************************************************************************/
+
+LOCAL void scan_file(p_fname)
+/* This function scans a single file. It's argument is the name of the file */
+/* to be scanned. scan_file calls the mapper to map in the file and then */
+/* scans the text of the mapped file using the liner mini-package. The result */
+/* of the scan is additions to the line and token list, and diagnostics sent */
+/* to the lister package. If an include directive is encountered, this */
+/* function is called recursively. */
+char *p_fname;
+{
+ char *p_mapped; /* Pointer to the mapped file. */
+ ulong length; /* Number of bytes in the mapped file. */
+ char *errstr; /* Error string returned by mapper. */
+ bool addedeol; /* Did we have to add an EOL to the end of the last line? */
+
+ /* Check to see if the file exists. */
+ if (!fexists(p_fname))
+ {
+ if (inclevel==0)
+ {
+ /* Failure to find the main file is a severe error. */
+ if (option.op_b7_b)
+ sprintf(linet1,"S: Error opening input file \"%s\".",SUPPNAME);
+ else
+ sprintf(linet1,"S: Error opening input file \"%s\".",p_fname);
+ wl_l(linet1);
+ /* Although strictly speaking we should suppress this error from the */
+ /* screen stream unless option.op_s_b is set, absence of an input file */
+ /* is such an important error, that we write it out anyway. */
+ /* if (option.op_s_b) */
+ wl_sj(linet1);
+ num_sev++;
+ return;
+ }
+ else
+ {
+ /* Failure to find an include file is an ordinary error. */
+ ps_t ps;
+ ps.ps_line = globalno;
+ ps.ps_column = 4;
+ /* ABC { */
+ ps.ps_localno = localno;
+ ps.ps_fnam = src_cur;
+ ps.ps_declQ = TRUE;
+ /* } ABC */
+ lr_err(&ps,"Error opening include file.");
+ if (option.op_b7_b)
+ sprintf(linet1,
+ "The include file's expanded name was \"%s\".",SUPPNAME);
+ else
+ sprintf(linet1,
+ "The include file's expanded name was \"%s\".",p_fname);
+ lr_mes(&ps,linet1);
+ return;
+ }
+ }
+
+ /* ABC { */
+ /* Set the current file in the filename list */
+ fl_set(p_fname);
+ /* } ABC */
+
+ /* Map the specified file into memory. We need to change from the scanner */
+ /* clock to the mapper clock to keep the time accounting correct here. */
+ ck_stop(p_scan);
+ ck_start(p_mapp);
+ errstr=map_file(p_fname,&p_mapped,&length);
+ ck_stop(p_mapp);
+ ck_start(p_scan);
+
+ /* Abort if the mapping was not possible. */
+ if (errstr != NULL)
+ if (inclevel==0)
+ {
+ /* Failure to map the main file is a severe error. */
+ if (option.op_b7_b)
+ sprintf(linet1,"S: Error reading input file \"%s\".",SUPPNAME);
+ else
+ sprintf(linet1,"S: Error reading input file \"%s\".",p_fname);
+ wl_l(linet1); if (option.op_s_b) wl_sj(linet1);
+ wl_l(errstr); if (option.op_s_b) wl_sj(errstr);
+ num_sev++;
+ return;
+ }
+ else
+ {
+ /* Failure to find an include file is an ordinary error. */
+ ps_t ps;
+ ps.ps_line = globalno;
+ ps.ps_column = 4;
+ /* ABC { */
+ ps.ps_localno = localno;
+ ps.ps_fnam = src_cur;
+ ps.ps_declQ = TRUE;
+ /* } ABC */
+ lr_err(&ps,"Error reading include file.");
+ lr_mes(&ps,errstr);
+ if (option.op_b7_b)
+ sprintf(linet1,"The include file's expanded name was \"%s\".",
+ SUPPNAME);
+ else
+ sprintf(linet1,"The include file's expanded name was \"%s\".",
+ p_fname);
+ lr_mes(&ps,linet1);
+ return;
+ }
+
+ /* Dump the mapped file if requested. */
+ if (option.op_b1_b)
+ {
+ if (option.op_b7_b)
+ sprintf(linet1,"Dump of mapped file \"%s\".",SUPPNAME);
+ else
+ sprintf(linet1,"Dump of mapped file \"%s\".",p_fname);
+ wl_l(linet1);
+ dm_mem(&f_l,p_mapped,length);
+ }
+
+ /* If the file is absolutely empty, we have to warn the user. Also, this is */
+ /* a special case we can do without, and so we return here if file is empty. */
+ if (length==0)
+ {
+ ps_t ps;
+ /* The empty file could be the main file or an include file. */
+ /* If the empty file is the main file, we want the diagnostic to point to */
+ /* the EOF marker which will appear as line 1. */
+ /* If the empty file is an include file, we wish to point the diagnostic */
+ /* to the line containing the include command. This is globalno. */
+ /* In both cases, we want the diagnostic to point to column 1. */
+ ps.ps_column=1;
+ /* ABC { */
+ ps.ps_fnam = src_cur;
+ ps.ps_declQ = TRUE;
+ /* } ABC */
+ if (inclevel==0)
+ {
+ ps.ps_line=1;
+ /* ABC { */
+ ps.ps_localno = 1;
+ /* } ABC */
+ lr_war(&ps,"Input file is empty (not a byte in syte)!");
+ }
+ else
+ {
+ ps.ps_line=globalno;
+ /* ABC { */
+ ps.ps_localno = localno;
+ /* } ABC */
+ lr_war(&ps,"Include file is empty (not a byte in syte)!");
+ }
+ return;
+ }
+
+ /* Scanning is considerably simplified if we can guarantee that we will not */
+ /* run into an EOF without first hitting an EOL. The following code takes */
+ /* care of this by tacking one on the end if necessary and also adds an */
+ /* EOF character on the end, which also simplifies the scanning. We can get */
+ /* away with all this because the mapper purposefully leaves at least two */
+ /* bytes free for us at the end of the mapped file. */
+ addedeol=FALSE;
+ if (p_mapped[length-1] != EOL)
+ {p_mapped[length++]=EOL; addedeol=TRUE;}
+ p_mapped[length]=EOFCH;
+
+ /* Initialize the variables "instantiated over a single file". */
+ inln_max = 80;
+ specialch = CH_DSPE;
+ localno = 0;
+ p_eof = &p_mapped[length];
+
+ /* Crank up the line subscanner system with a call to prepline. */
+ /* Then enter the main scanning loop. */
+ /* All input consists of alternating special and text sequences */
+ /* terminated by EOF. */
+ prepline(p_mapped);
+ while (ch!=EOFCH)
+ if (ch==specialch)
+ scanspec();
+ else
+ scantext();
+
+ /* Now that we are at the end of the scanned file and the scanning markers */
+ /* are all sitting on the end of the file, it is a good time to issue */
+ /* diagnostics about problems at the end of the file. */
+ if (addedeol)
+ {
+ ps_t ps;
+ /* We want the diagnostic to point to the EOF line. Hence "global+1". */
+ ps.ps_line = globalno+1;
+ ps.ps_column = 1;
+ /* ABC { */
+ ps.ps_localno = localno;
+ ps.ps_fnam = src_cur;
+ ps.ps_declQ = TRUE;
+ /* } ABC */
+ if (inclevel==0)
+ lr_war(&ps,"The last line of the input file was terminated by EOF.");
+ else
+ lr_war(&ps,"The last line of the include file was terminated by EOF.");
+ lr_mes(&ps,"An EOL was inserted at the end of the last line.");
+ }
+}
+
+/******************************************************************************/
+
+EXPORT void scanner(p_amapp,p_ascan)
+/* This is the scanner's main routine and the only exported function. */
+p_ck_t p_amapp; /* Mapper's clock (stopped). */
+p_ck_t p_ascan; /* Scanner's clock (running). */
+{
+ srcnmac_t newtype;
+ /* Copy the arguments into globals where we can get at them. */
+ p_mapp=p_amapp;
+ p_scan=p_ascan;
+
+ /* Apart from diagnostic messages sent to the lister, the only output of */
+ /* the scanner is two global lists holding a list of lines and a list of */
+ /* tokens. The scanner creates these lists simultaneously. */
+ /* We have to initialize them here before we get into 'scan_file' which */
+ /* calls itself recursively if an include file command is encountered. */
+ line_list =ls_cre(sizeof(ln_t));
+ token_list=ls_cre(sizeof(tk_t));
+
+ /* Initialize all the variables instantiated throughout the entire scan. */
+ globalno = 0;
+ inclevel = 0;
+ seenind = FALSE;
+ seentyp = FALSE;
+ seenlimo = FALSE;
+ /* ABC { */
+ src_1st = (p_fnam_t)0;
+ src_cur = (p_fnam_t)0;
+ /* } ABC */
+
+ /* We also have to initialize localno in case the input file is empty and */
+ /* it never gets initialized before being sucked into being used as the */
+ /* local number for the end of file marker. */
+ localno=0;
+
+ /* Initialize the global indentation flag to the default value. */
+ tgindent=TRUE;
+
+ /* Initialize the global product line length limit to the default value. */
+ tglinmax=80;
+
+ /* Initialize the global typesetter flag to the default value. */
+ tr_codes=TR_NONE;
+
+/* ABC { */
+ /* Initialise the global TeX header inclusion flag. */
+ doc_incQ = TRUE; /* Whether to include TeX/HTML header at weave time. */
+
+ /* Initialise the raw TeX/HTML macro/section names flag. */
+ /* Whether to allow raw TeX/HTML in macro/section names at weave time. */
+ raw_namQ = FALSE;
+
+ /* Whether to ignore text on a line after `@-' */
+ igntxtQ = FALSE;
+
+ /* Whether to suppress <P> markups for HTML modes */
+ no_pmrkQ = FALSE;
+
+ /* Initially, extra source code types are not allowed. */
+ xsrctypesQ = FALSE;
+
+ /* The source code type list and a first element are created *
+ * here. */
+ srctlist = ls_cre(sizeof(srcnmac_t));
+ newtype.typnam = newtype.lnmac = NULL;
+ ls_add(srctlist, (p_lsel_t)&newtype);
+
+ /* Initialise the #line macro offset. */
+ lin_off = 1; /* C and C++ offset */
+
+ /* Initialise the #line macro unwind depth. */
+ lin_dep = 1; /* as used in ccline.fwi example */
+/* } ABC */
+
+ /* Scan the top level file whose name is obtained from the command line. */
+ as_cold(option.op_f_b,"scanner: -F!!!!");
+
+ /* Work out what the input file name should be. */
+ {
+ fn_t fname;
+ strcpy(fname,""); /* Start with an empty string. */
+ fn_ins(fname,".fw");
+ fn_ins(fname,option.op_f_s);
+ scan_file(fname);
+ }
+
+ /* The scan_file function scans the main input file and all of its included */
+ /* files, but it does not append a TK_EOF token to the end. This call does */
+ /* this and also adds a line to the line list for EOF. */
+ add_eof();
+}
+
+/******************************************************************************/
+/* End of SCANNER.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/scanner.h b/web/funnelAC/fwACsrc/scanner.h
new file mode 100644
index 0000000000..859538db3c
--- /dev/null
+++ b/web/funnelAC/fwACsrc/scanner.h
@@ -0,0 +1,67 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* SCANNER.H */
+/******************************************************************************/
+/* */
+/* This package contains the scanner. When called (though the only exported */
+/* routine below), the scanner maps in the file whose filename is given in */
+/* the global option.op_f_s variable. The scanner scans the file, mapping in */
+/* any included files, and builds two lists in the global list variables */
+/* 'line_list' and 'token_list'. The line list contains a list of the lines */
+/* of the input. The token list contains a tokenized form of the input, which */
+/* is used by the parser. The scanner also sends diagnostics to the lister */
+/* package which has the effect of possibly incrementing the global error */
+/* counters num_*. See data.h for more information on data structures. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "clock.h"
+
+/******************************************************************************/
+
+EXPORT void scanner P_((p_ck_t,p_ck_t));
+/* The arguments are first a mapper clock, and second a scanner clock. The */
+/* scanner should turn off the scanner clock and turn on the mapper clock */
+/* when calling the mapper. */
+
+/******************************************************************************/
+/* End of SCANNER.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/section.c b/web/funnelAC/fwACsrc/section.c
new file mode 100644
index 0000000000..7b9d99ac4e
--- /dev/null
+++ b/web/funnelAC/fwACsrc/section.c
@@ -0,0 +1,151 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 16-Sep-1993 ABC Changed all constants *_MAX to *_FWMAX to avoid
+ conflict with some standard UNIX constants.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* SECTION.C */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "as.h"
+#include "section.h"
+
+/******************************************************************************/
+
+#define MAGIC (89201129L) /* Magic number detects uninitialized sections. */
+#define SECMAX (30000L) /* Maximum value of a single level's section num. */
+
+/******************************************************************************/
+
+LOCAL void sn_chk P_((p_sn_t));
+LOCAL void sn_chk(p_sn)
+/* Checks that the given section object has a legal internal state. */
+p_sn_t p_sn;
+{
+ ubyte i;
+
+ as_cold(p_sn->sn_magic==MAGIC,"sn_chk: Section has bad magic number.");
+ as_cold(p_sn->sn_lev<=SECLEV_FWMAX,
+ "sn_chk: Section has bad level number.");
+ for (i=1;i<=p_sn->sn_lev;i++)
+ as_cold(p_sn->sn_num[i]>0,
+ "sn_chk: Section has zero hierarchical number.");
+}
+
+/******************************************************************************/
+
+EXPORT void sn_ini(p_sn)
+p_sn_t p_sn;
+{
+ p_sn->sn_magic = MAGIC;
+ p_sn->sn_lev = 0;
+}
+
+/******************************************************************************/
+
+EXPORT void sn_set(p_sn,level)
+p_sn_t p_sn;
+ubyte level;
+{
+ ubyte i;
+ sn_chk(p_sn);
+ as_cold(level>0 && level<=SECLEV_FWMAX,
+ "sn_set: Specified level is too high.");
+ p_sn->sn_lev=level;
+ for(i=1;i<=level;i++)
+ p_sn->sn_num[i]=1;
+}
+
+/******************************************************************************/
+
+EXPORT void sn_inc (p_sn,lev)
+p_sn_t p_sn;
+ubyte lev;
+{
+ sn_chk(p_sn);
+
+ /* Check the parameter level. */
+ as_cold(1<=lev && lev<=SECLEV_FWMAX,"sn_inc: Bad level number specified.");
+
+ /* Check that we are not skipping a hierarchical level. */
+ as_cold(lev<=p_sn->sn_lev+1,"sn_inc: Discountinuous level increment.");
+
+ /* Actually increment the section. */
+ if (lev==p_sn->sn_lev+1) p_sn->sn_num[lev]=0;
+ p_sn->sn_lev=lev;
+ p_sn->sn_num[lev]++;
+
+ /* Check that the section number hasn't got too big. */
+ as_cold(p_sn->sn_num[lev]<=SECMAX,"sn_inc: Section number is too large.");
+}
+
+/******************************************************************************/
+
+EXPORT ubyte sn_lev(p_sn)
+p_sn_t p_sn;
+{
+ sn_chk(p_sn);
+ return p_sn->sn_lev;
+}
+
+/******************************************************************************/
+
+EXPORT void sn_str(p_sn,s)
+p_sn_t p_sn;
+char *s;
+{
+ char t[20];
+ ubyte i;
+
+ sn_chk(p_sn);
+
+ s[0]=EOS;
+ for (i=1;i<=p_sn->sn_lev;i++)
+ {
+ if (i>1) strcat(s,".");
+ sprintf(t,"%u",(unsigned) p_sn->sn_num[i]);
+ strcat(s,t);
+ }
+}
+
+/******************************************************************************/
+/* End of SECTION.C */
+/******************************************************************************/
+
diff --git a/web/funnelAC/fwACsrc/section.h b/web/funnelAC/fwACsrc/section.h
new file mode 100644
index 0000000000..04b6538044
--- /dev/null
+++ b/web/funnelAC/fwACsrc/section.h
@@ -0,0 +1,123 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 16-Sep-1993 ABC Changed all constants *_MAX to *_FWMAX to avoid
+ conflict with some standard UNIX constants.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* SECTION.H */
+/******************************************************************************/
+/* */
+/* This package provides a very simple, very small abstraction for a section */
+/* number. A section number is a hierarchical group of numbers such as is */
+/* used to number the sections in documents. For example: 4.5.1.3 is a */
+/* section number. This package provides an abstraction for these numbers */
+/* that assists in their incrementing at different levels and in writing them */
+/* out. The package also checks for hierarchical inconsistencies. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_SECTION
+#define DONE_SECTION
+
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+/* The following constant defines the maximum number of levels that a */
+/* FunnelWeb document can have. @A corresponds to level 1. */
+#define SECLEV_FWMAX 5
+
+/* The following constant defines the maximum length of a string representing */
+/* a section. This is calculated as the maximum number of levels multiplied */
+/* by 1 (for the separating dots) plus a safe size for a decimal number. */
+#define SECSTR_FWMAX (SECLEV_FWMAX*(1+10))
+
+/* The following structure stores a single section number. The sc_level */
+/* field is the level of this field and is in the range [1,SECLEV_FWMAX]. The */
+/* sc_num field is defined only for elements [1,level] and contains the */
+/* hierarchy number at each level. */
+/* Example: For SECLEVMAX=4 and "3.4.1", level=3 and num=[?,3,4,1,?]. */
+/* Note: The first question mark is for element zero which is always unknown. */
+typedef struct
+ {
+ ulong sn_magic; /* Used to detect uninitialized sn objects. */
+ ubyte_ sn_lev; /* Level number of section. */
+ uword_ sn_num[SECLEV_FWMAX+1]; /* Hierarchical level numbers. */
+ } sn_t;
+
+typedef sn_t *p_sn_t;
+
+/******************************************************************************/
+
+EXPORT void sn_ini P_((p_sn_t));
+/* Initializes the specified section object to the empty section at level 0. */
+/* All sections must be initialized before any other operations are performed.*/
+
+EXPORT void sn_set P_((p_sn_t,ubyte));
+/* Sets the specified section to 1.1.1.1.1.1... at the given level. */
+/* Example: sn_set(p_sn,3) yields a section set to 1.1.1. */
+/* Raises an error if the specified level is out of range. */
+
+EXPORT void sn_inc P_((p_sn_t,ubyte));
+/* Increments the number of the specified section object at the specified */
+/* level. This also has the effect of setting all lower levels to 0. For */
+/* example, 3.4.5.1 followed by sn_inc(&sn,2) would become 3.5. */
+/* Raises an error if the level is two or more lower than the current level */
+/* Example: You can't increment 2.4.1 at level 5. */
+/* Raises an error if the specified level is out of range. */
+/* Raises an error if a number at any level becomes too large (>60000). */
+
+EXPORT ubyte sn_lev P_((p_sn_t));
+/* Returns the level number of the specified section. */
+
+EXPORT void sn_str P_((p_sn_t,char *));
+/* Writes a textual representation of the specified section into the given */
+/* string. The string must be able to hold at least SECSTRMAX characters. */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of SECTION.H */
+/******************************************************************************/
+
diff --git a/web/funnelAC/fwACsrc/style.h b/web/funnelAC/fwACsrc/style.h
new file mode 100644
index 0000000000..5cd8f94fe2
--- /dev/null
+++ b/web/funnelAC/fwACsrc/style.h
@@ -0,0 +1,270 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 09-Sep-1993 ABC Adjusted data types to match OSF/1 definitions.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* STYLE.H */
+/******************************************************************************/
+/* */
+/* WARNING: DO NOT ADD ANY MACHINE OR PROGRAM DEPENDENT DEFINITIONS. */
+/* */
+/* This style.h file contains program-independent, machine-independent */
+/* definitions that assist C programming in general. Nothing in this file */
+/* should require modification if this file is moved to a new machine or used */
+/* in a new computer program. However, it may use abstracted second-order */
+/* definitions from the machine-dependent, program independent module */
+/* "environ". */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_STYLE
+#define DONE_STYLE
+
+/******************************************************************************/
+
+/* System File Inclusions */
+/* ---------------------- */
+/* In order to support a readable programming style, symbols such as TRUE and */
+/* NULL are essential. However, environments differ as to whether and where */
+/* these symbols are defined. This can lead to multiple definition errors */
+/* where (say) this style.h file is included in a .C file before <stdlib.h>. */
+/* I did a quick survey of all the .C FunnelWeb modules and found the */
+/* following: */
+/* */
+/* Total files = 54 */
+/* Number .C files = 22 */
+/* Number .H files = 32 */
+/* Used <stdlib.h> = 19 */
+/* Used <stdio.h> = 16 */
+/* Used <string.h> = 12 */
+/* Used <ctype.h> = 6 */
+/* Used <stddef.h> = 4 */
+/* Used <limits.h> = 2 */
+/* Used <setjmp.h> = 1 */
+/* */
+/* Most of these inclusions were in the .C files. */
+/* It therefore seemed sensible to include some very commonly used system */
+/* header files here and header files that cause problems if not included */
+/* before style.h (<stddef.h>). */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+
+/******************************************************************************/
+
+/* Although this file is machine independent, it still needs some generic */
+/* definitions whose values vary from machine to machine (see above). */
+#include "environ.h"
+
+/******************************************************************************/
+
+/* The following types provide a clear and consistent collection of names for */
+/* C's arithmetic types. Each name describes only the portable range that the */
+/* underlying type supports. As in C, there are no guarantees about the */
+/* MAXIMUM size of each underlying type and these types can provide no */
+/* guarantees either. In the normal case, they translate to the most speed */
+/* efficient type that will support the specified range. However, to support */
+/* the situations where space efficiency is required, types ending in */
+/* underscores have been defined that strive to conserve memory. */
+/* Note: The signedness of a type does not change when an _ is added. */
+/* ABC { */
+/* Note: a _t added to a name does *not* imply space efficiency. Such names */
+/* are for compatibility with OSF/1. */
+/* } ABC */
+/* */
+/* The following terminology may be a touch vaxcentric, but it works for me. */
+/* A BYTE is an 8 bit quantity. */
+/* A WORD is a 16 bit quantity. */
+/* A LONG is a 32 bit quantity. */
+/* ABC { */
+/* A WIDE is an address-sized quantity */
+/* (as such, the wide types are not defined here, but in environ.h) */
+
+/* FunnelWeb types */
+typedef uint_t ubyte ; /* Unsigned, [0,255]. */
+typedef uchar_t ubyte_ ; /* Unsigned, [0,255]. Space first. */
+typedef int_t word; /* Signed , [-32767,+32767]. */
+typedef short_t word_ ; /* Signed , [-32767,+32767]. Space first. */
+typedef uint_t uword ; /* Unsigned, [0,65535]. */
+typedef ushort_t uword_ ; /* Unsigned, [0,+65535]. Space first. */
+/* ulong ; ** Unsigned, [0,(2^32)-1]. */
+
+typedef uint_t bool ; /* Unsigned, [0,1]. */
+typedef uchar_t bool_ ; /* Unsigned, [0,1]. Space first. */
+
+typedef int_t sign ; /* Signed , [-1,0,1]. */
+
+/* } ABC */
+
+/******************************************************************************/
+
+/* C overloads the attribute keyword "static" horribly giving it meaning on */
+/* both the scoping and lifetime dimensions. This section gives definitions */
+/* that clarify its use. If these macros are used, there should be no need */
+/* for the keyword "static" in programs using this style file. */
+
+/* The following macros assist in making the scope of functions clearer. In */
+/* deciding on the names of these macros, I chose from the following lists: */
+/* file scope: PRIVATE, LOCAL, HIDDEN. */
+/* program scope: EXPORT, PUBLIC, GLOBAL. */
+/* In the end I chose LOCAL and EXPORT. Note: I didn't want to allow more */
+/* than one form as that would have created too much confusion. */
+#define LOCAL static
+#define EXPORT
+
+/* It is desirable to use separate keywords for variables. This makes it */
+/* easier to search for them without stopping at every function. There are */
+/* four classes of variable that we wish to tag, along the two dimensions */
+/* scope:(local,global) and lifetime:(permanent,temporary). In C, all */
+/* variables declared outside of functions have permanent lifetime and so */
+/* the following two names (which should be used only to tag variables not */
+/* declared within a function) have been designed to emphasise the scope */
+/* dimension which is the principal concern for these variables. */
+#define LOCVAR static
+#define GLOVAR
+
+/* Variables local to functions always have local scope and so the dimension */
+/* to emphasise is the lifetime. Automatic variables are the most common in */
+/* C and it would be messy to declare them all using a keyword. Far better */
+/* just to tag static local variables, emphasising their lifetime (STAtic). */
+#define STAVAR static
+
+/******************************************************************************/
+
+/* The following definitions are useful for dealing with void. */
+/* The typedefed definition "p_void" should always be used instead of */
+/* "void *" so as to improve portability. */
+/* The definition of "void" and "p_void" come from environ.h */
+typedef p_void *p_p_void;
+#define PV (p_void)
+#define PPV (p_p_void)
+
+/******************************************************************************/
+
+/* The following symbols are more mnemonic than character escape sequences. */
+#define EOS '\0'
+#define EOL '\n'
+
+/******************************************************************************/
+
+/* The ANSI library functions use many different techniques for returning */
+/* status information. For example, fopen returns NULL upon failure, but */
+/* fclose returns EOF upon failure. The result is that it is hard to */
+/* proofread calls to these routines without constantly referring to the */
+/* library manual. To avoid this problem, we define symbols with helpful */
+/* names for the different values returned. This makes the code obvious. */
+
+/* 07-Feb-1992: During porting I ran into a problem here with FPUTS_S. I had */
+/* defined it to be zero, as stated in the THINK C V4 ANSI library guide. */
+/* However, it turned out that fputs() returns EOF (-1) on failure and the */
+/* value that it returns on success is non negative! (See ANSI (7.9.7.4)). */
+/* Caught by an overspecification by the THINK C people! The lesson is that */
+/* it is very important to make sure that each function's status check symbol */
+/* is defined on the "right" side (success or failure) - that is, the side */
+/* for which a single value for that status is guaranteed portably. */
+/* The following values have all been checked for this. */
+
+/* Note: _F=Failure, _S=Success, _FE=Failure or End of File. */
+
+#define FOPEN_F (NULL)
+#define FSEEK_S (0)
+#define FTELL_F (-1L)
+#define FGETC_FE (EOF)
+#define FGETS_FE (NULL)
+#define FPUTC_F (EOF)
+#define FPUTS_F (EOF)
+#define FFLUSH_S (0)
+#define FCLOSE_F (EOF)
+#define REMOVE_S (0)
+#define RENAME_S (0)
+#define MALLOC_F (NULL)
+
+/******************************************************************************/
+
+/* The following macro functions are handy. However, be sure not to hand them */
+/* an argument with a non-idempotent side effect!!! (e.g. MAX(a++,b)). */
+#define MIN(A,B) ((A)<(B) ? (A) : (B))
+#define MAX(A,B) ((A)>(B) ? (A) : (B))
+
+/******************************************************************************/
+
+/* Some environments don't define some stuff we need so we do it here. */
+/* Cautiously! */
+
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE (-1)
+#endif
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS (0)
+#endif
+
+/******************************************************************************/
+
+/* The standard library macro/function "isprint" can be too loose in some */
+/* circumstances on some machines and it is convenient to define a macro */
+/* that provides a more strict 7-bit ASCII definition of "printable". */
+#define isascprn(ch) ((' '<=ch) && (ch<='~'))
+
+/******************************************************************************/
+
+/* Some compilers (GCC at least) complain about characters as a type in a */
+/* function argument. The following typedef is a quick hack that lets me say */
+/* that I really wanted the function argument to be a character, while */
+/* actually supplying an integer. */
+typedef int intchar;
+
+/******************************************************************************/
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of STYLE.H */
+/******************************************************************************/
+
diff --git a/web/funnelAC/fwACsrc/table.c b/web/funnelAC/fwACsrc/table.c
new file mode 100644
index 0000000000..155b7e146c
--- /dev/null
+++ b/web/funnelAC/fwACsrc/table.c
@@ -0,0 +1,433 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 08-Aug-1995 ABC Changed include file name from "memory.h"
+ to "fwmem.h" to avoid a clash with the C++
+ standard header file "memory.h".
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* TABLE.C */
+/******************************************************************************/
+/* */
+/* Notes */
+/* ----- */
+/* - There are few comments at the start of each function. As definitions */
+/* appear in the .H file, and it is dangerous to duplicate definitions, I */
+/* have simply omitted them here. */
+/* */
+/* About The Cache */
+/* --------------- */
+/* A typical usage sequence for tables is for the user to first call tb_itb */
+/* to see if a key is in the table and then call either tb_loo or tb_ins */
+/* to lookup the value or to add a new (key,value) pair to the table. */
+/* In order to avoid performing TWO searches down the binary tree in such */
+/* cases, a CACHE is maintained in the table data structure between calls. */
+/* */
+/* ca_valid stores whether the cache contents are valid. If TRUE then: */
+/* ca_p_key points to a key. */
+/* ca_p_node points to the node in the tree containing the key, or contains */
+/* NULL if no such node exists. */
+/* ca_p_parent points to the node in the tree that is the parent of the node */
+/* ca_p_node in the tree, or (if ca_p_node==NULL) WOULD BE the parent if a */
+/* node containing the key were inserted in the tree. If the tree is */
+/* currently empty, ca_p_parent will be NULL. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "as.h"
+#include "machin.h"
+#include "fwmem.h"
+
+/******************************************************************************/
+
+/* In order to catch uninitialized and corrupted tables, the first and last */
+/* fields of legitimate table objects contain magic numbers. The following */
+/* #defines give the values of these numbers. The first thing that each */
+/* function of this package does is to check the two magic number fields of */
+/* the table it has just been passed, and bomb the package if the fields have */
+/* the wrong values. This technique is likely to pick uninitialized tables, */
+/* as well as tables that have been partially overwritten. */
+#define MAGIC_HEAD_VALUE (53456839L)
+#define MAGIC_TAIL_VALUE (28434290L)
+
+/* Comparing keys is messy and so we define a macro to help us out. */
+#define key_compare(a,b) ((*(p_tb->p_kycm))((a),(b)))
+
+/******************************************************************************/
+
+/* The functions of the table abstraction pass keys and values exclusively */
+/* using pointers. These two definitions define types for these pointers. */
+/* Although the two types are both 'p_void', the different types are useful */
+/* to indicate what is expected in each position of the parameter lists. */
+typedef p_void p_tbky_t;
+typedef p_void p_tbvl_t;
+
+/* Define a type for a function to compare two keys. Such functions are */
+/* needed to organize the storage of (key,value) pairs inside the table. */
+/* Given the arguments are (a,b), the function should return: */
+/* -1 if a<b */
+/* 0 if a==b */
+/* 1 if a>b */
+/* The user must create such a function and hand it to the 'tb_create' */
+/* function when creating new a new table. */
+typedef sign (*p_kycm_t) P_((p_tbky_t,p_tbky_t));
+
+/* The (key,value) pairs in the table are stored in a binary tree. The tree */
+/* is ordered by the key ordering function passed in at table creation. */
+typedef struct node_t_
+ {
+ struct node_t_ *p_left;
+ struct node_t_ *p_right;
+ struct node_t_ *p_parent;
+ p_tbky_t p_key;
+ p_tbvl_t p_value;
+ }
+ node_t;
+typedef node_t *p_node_t;
+
+/* The type tb_t (table type) defines the root table data record. This */
+/* record stores attributes of the table along with the main binary tree of */
+/* (key,value) pairs. */
+typedef struct
+ {
+ ulong magic_head; /* Magic number to allow corruption checks. */
+ size_t key_bytes; /* Number of bytes in a key. */
+ size_t value_bytes; /* Number of bytes in a value. */
+ p_kycm_t p_kycm; /* Pointer to function to compare keys. */
+ p_node_t tree; /* Ptr to root of (key,value) binary tree. */
+ ulong num_keys; /* Number of (k,v) pairs in the table. */
+ bool ca_valid; /* Cache: TRUE iff cache contents are valid. */
+ p_tbky_t ca_p_key; /* Cache: Key value cache contents refer to. */
+ p_node_t ca_p_node; /* Cache: Pointer to node in binary tree. */
+ p_node_t ca_p_parent; /* Cache: Pointer to parent of ca_p_node. */
+ p_node_t p_read_next; /* Pointer to next node to be read. */
+ ulong magic_tail; /* Magic number to allow corruption checks. */
+ } tb_t;
+
+typedef tb_t *p_tb_t; /* Pointer to main table record. */
+
+/* Defining INTABLEC hides the abstract definition. */
+#define INTABLEC
+#include "table.h"
+
+/******************************************************************************/
+/* PRIVATE FUNCTIONS */
+/******************************************************************************/
+
+LOCAL p_node_t new_node P_((p_tb_t,p_tbky_t,p_tbvl_t));
+LOCAL p_node_t new_node(p_tb,p_tbky,p_tbvl)
+/* Creates a new tree node and returns a pointer to it. */
+/* p_tb is the table for which the new node is to be created. */
+/* p_tbky and p_tbvl point to the key and value to go in the new node. */
+/* Assumes that a tb_check(p_tb) has already been performed by the caller. */
+p_tb_t p_tb;
+p_tbky_t p_tbky;
+p_tbvl_t p_tbvl;
+{
+ p_node_t p_node;
+
+ p_node=(p_node_t) mm_temp(sizeof(node_t));
+
+ p_node->p_left = NULL;
+ p_node->p_right = NULL;
+ p_node->p_parent = NULL;
+ p_node->p_key = mm_temp(p_tb->key_bytes );
+ p_node->p_value = mm_temp(p_tb->value_bytes);
+
+ memcpy(p_node->p_key ,p_tbky,p_tb->key_bytes );
+ memcpy(p_node->p_value,p_tbvl,p_tb->value_bytes);
+
+ return p_node;
+}
+
+/******************************************************************************/
+
+LOCAL void tb_check P_((p_tb_t));
+LOCAL void tb_check(p_tb)
+/* Accepts a pointer to a table and performs a series of checks to make sure */
+/* that the table has not been corrupted in some way. */
+p_tb_t p_tb;
+{
+ as_cold(p_tb!=NULL,"tb_check: Table pointer is NULL.");
+ as_cold(p_tb->magic_head==MAGIC_HEAD_VALUE,
+ "tb_check: Magic number at head of record is incorrect.");
+ as_cold(p_tb->magic_tail==MAGIC_TAIL_VALUE,
+ "tb_check: Magic number at tail of record is incorrect.");
+}
+
+/******************************************************************************/
+
+LOCAL p_node_t min_leaf P_((p_node_t));
+LOCAL p_node_t min_leaf(p_node)
+/* Returns a pointer to the node that is leftmost (has the smallest value */
+/* according to the ordering function) in the specified node's subtree. */
+p_node_t p_node;
+{
+ if (p_node==NULL)
+ return NULL;
+ while (p_node->p_left != NULL)
+ p_node=p_node->p_left;
+ return p_node;
+}
+
+/******************************************************************************/
+
+LOCAL p_node_t next_node P_((p_node_t));
+LOCAL p_node_t next_node(p_node)
+/* Give a pointer to a node in the binary tree, returns a pointer to the next */
+/* node (in sequence defined by the order function) or NULL if the given node */
+/* is the last node in the ordered sequence. */
+p_node_t p_node;
+{
+ /* If there is a right subtree, we need the minimum node of that subtree. */
+ if (p_node->p_right != NULL)
+ return min_leaf(p_node->p_right);
+
+ /* Otherwise go up as far as possible through right arcs. */
+ while (p_node->p_parent!=NULL && p_node->p_parent->p_right==p_node)
+ p_node=p_node->p_parent;
+ return p_node->p_parent;
+}
+
+/******************************************************************************/
+
+LOCAL void tb_search P_((p_tb_t,p_tbky_t));
+LOCAL void tb_search(p_tb,p_tbky)
+/* Calling this function with a particular key value results in the cache */
+/* becoming valid and containing the specified key. */
+p_tb_t p_tb;
+p_tbky_t p_tbky;
+{
+ p_node_t p,p_parent;
+
+ tb_check(p_tb);
+
+ /* Return if the cache is already up to date. */
+ if (p_tb->ca_valid)
+ if (key_compare(p_tbky,p_tb->ca_p_key) == 0)
+ return;
+
+ p_parent=NULL;
+ p=p_tb->tree;
+ while (p != NULL)
+ switch(key_compare(p_tbky,p->p_key))
+ {
+ case -1: p_parent=p; p=p->p_left; break;
+ case 1: p_parent=p; p=p->p_right; break;
+ case 0: goto found;
+ default:
+ as_bomb("tb_search: Key comparison function returned bad value.");
+ }
+ found:
+ p_tb->ca_valid = TRUE;
+ memcpy(p_tb->ca_p_key,p_tbky,p_tb->key_bytes);
+ p_tb->ca_p_node = p;
+ p_tb->ca_p_parent = p_parent;
+}
+
+/******************************************************************************/
+
+LOCAL void des_tree P_((p_node_t));
+LOCAL void des_tree(p_root)
+p_node_t p_root;
+{
+ if (p_root==NULL)
+ return;
+ des_tree(p_root->p_left);
+ des_tree(p_root->p_right);
+
+ /* This is what we would need if it wasn't for the MM watermark system. */
+ /* DEALLOCATE(PV p_root); */
+}
+
+/******************************************************************************/
+/* EXPORTED FUNCTIONS */
+/******************************************************************************/
+
+EXPORT p_tb_t tb_cre(key_bytes,value_bytes,p_kycm)
+size_t key_bytes;
+size_t value_bytes;
+p_kycm_t p_kycm;
+{
+ p_tb_t p_tb;
+
+ p_tb = (p_tb_t) mm_temp(sizeof(tb_t));
+ p_tb->magic_head = MAGIC_HEAD_VALUE;
+ p_tb->key_bytes = key_bytes;
+ p_tb->value_bytes = value_bytes;
+ p_tb->p_kycm = p_kycm;
+ p_tb->tree = NULL;
+ p_tb->num_keys = 0;
+ p_tb->ca_valid = FALSE;
+ p_tb->ca_p_key = (p_tbky_t) mm_temp(key_bytes);
+ p_tb->ca_p_node = NULL; /* This initialization not strictly necessary. */
+ p_tb->ca_p_parent = NULL; /* This initialization not strictly necessary. */
+ p_tb->p_read_next = NULL;
+ p_tb->magic_tail = MAGIC_TAIL_VALUE;
+
+ return p_tb;
+}
+
+/******************************************************************************/
+
+EXPORT bool tb_itb(p_tb,p_tbky)
+p_tb_t p_tb;
+p_tbky_t p_tbky;
+{
+ tb_check(p_tb);
+
+ tb_search(p_tb,p_tbky);
+ return p_tb->ca_p_node != NULL;
+}
+
+/******************************************************************************/
+
+EXPORT void tb_loo(p_tb,p_tbky,p_tbvl)
+p_tb_t p_tb;
+p_tbky_t p_tbky;
+p_tbvl_t p_tbvl;
+{
+ tb_check(p_tb);
+
+ tb_search(p_tb,p_tbky);
+ as_cold(p_tb->ca_p_node!=NULL,"tb_loo: Requested key is absent.");
+ memcpy(p_tbvl,p_tb->ca_p_node->p_value,p_tb->value_bytes);
+}
+
+/******************************************************************************/
+
+EXPORT void tb_ins(p_tb,p_tbky,p_tbvl)
+p_tb_t p_tb;
+p_tbky_t p_tbky;
+p_tbvl_t p_tbvl;
+{
+ p_node_t p_new;
+
+ tb_check(p_tb);
+
+ /* Validate the cache. Note: tb_search does it's own cache check. */
+ tb_search(p_tb,p_tbky);
+
+ /* Ensure that the table does not already contain the key. */
+ as_cold(p_tb->ca_p_node==NULL,"tb_ins: Key is already present in the p_tb.");
+
+ /* Create the new node. */
+ p_new=new_node(p_tb,p_tbky,p_tbvl);
+
+ /* Insert the new node into the tree. */
+ if (p_tb->ca_p_parent==NULL)
+ p_tb->tree=p_new;
+ else {
+ switch(key_compare(p_tbky,p_tb->ca_p_parent->p_key))
+ {
+ case -1: p_tb->ca_p_parent->p_left =p_new; break;
+ case 1: p_tb->ca_p_parent->p_right=p_new; break;
+ default: as_bomb("tb_ins: Key comparison function is inconsistent.");
+ }
+ } /* end if */
+ p_new->p_parent=p_tb->ca_p_parent;
+
+ /* Need to fiddle cache to make it correct, and inc num_keys. */
+ p_tb->ca_p_node=p_new;
+ p_tb->num_keys++;
+}
+
+/******************************************************************************/
+
+EXPORT ulong tb_len(p_tb)
+p_tb_t p_tb;
+{
+ tb_check(p_tb);
+ return p_tb->num_keys;
+}
+
+/******************************************************************************/
+
+EXPORT void tb_fir(p_tb)
+p_tb_t p_tb;
+{
+ tb_check(p_tb);
+
+ p_tb->p_read_next=min_leaf(p_tb->tree);
+}
+
+/******************************************************************************/
+
+EXPORT bool tb_rea(p_tb,p_tbky,p_tbvl)
+p_tb_t p_tb;
+p_tbky_t p_tbky;
+p_tbvl_t p_tbvl;
+{
+ tb_check(p_tb);
+
+ if (p_tb->p_read_next == NULL)
+ return FALSE;
+
+ memcpy(p_tbky,p_tb->p_read_next->p_key ,p_tb->key_bytes );
+ memcpy(p_tbvl,p_tb->p_read_next->p_value,p_tb->value_bytes);
+
+ p_tb->p_read_next=next_node(p_tb->p_read_next);
+
+ return TRUE;
+}
+
+/******************************************************************************/
+
+#if FALSE
+EXPORT void tb_des(p_tb)
+p_tb_t p_tb;
+{
+ /* This routine now unused because of the watermark system. */
+ return;
+
+ /* tb_check(p_tb); */
+
+ /* Zap the magic numbers in case the memory is re-used in same alignment. */
+ /* p_tb->magic_head=0; */
+ /* p_tb->magic_tail=0; */
+
+ /* This is what we would need if it wasn't for the MM watermark system. */
+ /* des_tree(p_tb->tree); */ /* Zap the binary tree. */
+ /* DEALLOCATE(PV p_tb); */ /* Zap the node itself. */
+}
+#endif
+
+/******************************************************************************/
+/* TABLE.C */
+/******************************************************************************/
+
diff --git a/web/funnelAC/fwACsrc/table.h b/web/funnelAC/fwACsrc/table.h
new file mode 100644
index 0000000000..ba8ec90d6a
--- /dev/null
+++ b/web/funnelAC/fwACsrc/table.h
@@ -0,0 +1,189 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* TABLE.H */
+/******************************************************************************/
+/* */
+/* Introduction */
+/* ------------ */
+/* This table package (table.h and table.c) implements a table abstraction. */
+/* */
+/* Facts about Tables */
+/* ------------------ */
+/* - A TABLE stores zero or more (KEY,VALUE) PAIRS. */
+/* - The user decides the types of keys and values and provides a */
+/* COMPARISON FUNCTION providing a complete ordering of the set of keys. */
+/* - The comparison function must be consistent between calls. */
+/* - Tables store pairs in key order. */
+/* - A table cannot store more than one pair with the same key. */
+/* - Pairs can be added, but not deleted. */
+/* - A table can return the value corresponding to a given key. */
+/* - The pairs in a table can be read sequentially in key order. At all */
+/* times, the table has an imaginary MARKER positioned on one of its pairs */
+/* (or after the last pair). You can move the marker to the first pair and */
+/* you can move the marker to the next pair, reading the pair as you go. */
+/* Upon table creation, a table's marker is at the end-of-table position. */
+/* - If you try to perform an illegal operation on a table, the table package */
+/* will call "error" to write out an error message and bomb the program. */
+/* - Tables store copies of (key,value) pairs. They do not hold pointers to */
+/* outside data (unless your keys or values are pointers themselves). */
+/* - If the keys are pointers themselves and point to other data which is */
+/* used by the comparison function, then that data must not be modified */
+/* in a way that will change the order of pairs in the table. */
+/* - A table can hold from zero to about 2^31 pairs. */
+/* - The identifier "tb" is used as an abbreviation for "table". */
+/* - The identifier "ky" is used as an abbreviation for "key". */
+/* - The identifier "vl" is used as an abbreviation for "value". */
+/* - The author would like to use longer names, but has chosen to use the */
+/* abbreviations so as to enhance the portability of the code. */
+/* - IMPORTANT: Tables get all their memory using mm_temp calls. */
+/* */
+/* How To Use This Table Package */
+/* ----------------------------- */
+/* 1. Include this .H file in your program file. */
+/* 2. Identify the key and value types that you are going to use. */
+/* 3. Define a function (having two parameters being pointers to keys) */
+/* that compares two keys and returns [-1,0,1] accordingly. */
+/* 4. Define a variable of type p_tb as a view to a table. */
+/* 5. Use the tb_* functions to perform the desired operations. */
+/* Start with a call to tb_cre and (optionally) end with a call to tb_des. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_TABLE
+#define DONE_TABLE
+
+/******************************************************************************/
+
+#include <stddef.h>
+#include "style.h"
+
+/******************************************************************************/
+
+/* Hide the exported abstract definition of a table from the table.c package. */
+/* Table.c defines INTABLEC so as to prevent itself from seeing the following */
+/* definitions. It defines its own more concrete definitions. */
+#ifndef INTABLEC
+
+/* The functions of the table abstraction pass keys and values exclusively */
+/* using pointers. These two definitions define types for these pointers. */
+/* Although the two types are both 'p_void', the different types are useful */
+/* to indicate what is expected in each position of the parameter lists. */
+typedef p_void p_tbky_t;
+typedef p_void p_tbvl_t;
+
+/* Define a type for a function to compare two keys. Such functions are */
+/* needed to organize the storage of (key,value) pairs inside the table. */
+/* Given the arguments are (a,b), the function should return: */
+/* -1 if a<b */
+/* 0 if a==b */
+/* 1 if a>b */
+/* The user must create such a function and hand it to the 'tb_create' */
+/* function when creating new a new table. */
+typedef sign (*p_kycm_t) P_((p_tbky_t,p_tbky_t));
+
+/* Users manipulate tables through pointers to tables. Here the actual table */
+/* internals are hidden from the user. */
+typedef struct {word NEVER_USE_THIS_FIELD_UQJTKC;} tb_t;
+typedef tb_t *p_tb_t;
+
+#endif
+
+/******************************************************************************/
+
+/* General Notes About These Functions */
+/* ----------------------------------- */
+/* - All tables, keys, and values are passed by pointer. Whether a parameter */
+/* is read or written is determined by it's functions description. */
+/* - Each function (except tb_cre) accepts a single pointer to a table and */
+/* each function's description is assumed to be referring to the table. */
+/* - "Raising an error" means calling the external function "error" to */
+/* write out a message and bomb the program. */
+/* - You must create a table using tb_cre before performing any operations */
+/* upon it. The table operations will usually raise an error if they are */
+/* handed a pointer that does not point to a properly CREated table. */
+
+/* The Functions */
+/* ------------- */
+EXPORT p_tb_t tb_cre P_((size_t,size_t,p_kycm_t));
+/* CREate. This function creates a new table and returns a pointer to the */
+/* table. The user must supply 1) the size in bytes of keys, 2) the size in */
+/* bytes of values, 3) a pointer to a function that compares two keys. */
+
+EXPORT bool tb_itb P_((p_tb_t,p_tbky_t));
+/* InTaBle. Returns TRUE iff the given key is in the table. */
+
+EXPORT void tb_loo P_((p_tb_t,p_tbky_t,p_tbvl_t));
+/* LOOkup. Feed this function a table and a key and it will return (in the */
+/* p_tbvl_t parameter) the value corresponding to the key. The function */
+/* raises an error if the table does not contain the key. */
+
+EXPORT void tb_ins P_((p_tb_t,p_tbky_t,p_tbvl_t));
+/* INSert. Inserts the (key,value) pair into the table. Raises an error if */
+/* the key is already in the table. */
+
+EXPORT ulong tb_len P_((p_tb_t));
+/* LENgth. Returns the number of pairs in the table. */
+
+EXPORT void tb_fir P_((p_tb_t));
+/* FIRst. Set's the table's marker to the first pair in the table (or the end */
+/* of table position if the table is empty. */
+
+EXPORT bool tb_rea P_((p_tb_t,p_tbky_t,p_tbvl_t));
+/* REAd. Returns in (p_tbky_t,p_tbvl_t) the (key,value) pair corresponding to */
+/* the marker and them moves the marker onto the next pair. */
+/* Returns TRUE => Returned a pair. */
+/* Returns FALSE => Did not return a pair. No more pairs left. */
+/* of key) to be read from the table. Returns TRUE if it returns a pair */
+/* This function will not raise an error if it is called more than once with */
+/* the marker at the end of the table (it just keeps returning FALSE). */
+
+#if FALSE
+void tb_des P_((p_tb_t));
+/* DEStroy. Destroys a table, deallocating all its memory. */
+#endif
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of TABLE.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/tangle.c b/web/funnelAC/fwACsrc/tangle.c
new file mode 100644
index 0000000000..121995f2c0
--- /dev/null
+++ b/web/funnelAC/fwACsrc/tangle.c
@@ -0,0 +1,887 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 31-Aug-1993 ABC Added support for EL_SPEC.
+ Added an extra parameter, for the position of the
+ parent macro call, to many of the functions
+ ex_ex...
+ 10-May-1994 ABC Added DYN_NAMES option to allow macro and
+ section names to be allocated dynamically
+ instead of statically.
+ 18-Sep-1994 ABC Added support for the automatic insertion of
+ line directives when `aldmname' is a non-null
+ string referring to a macro without parameters.
+ 25-Jul-1995 ABC Replaced `aldmname' with a list of structures
+ containing a source code type name (or NULL)
+ and a corresponding automatic line directive
+ insertion macro name.
+ 08-Aug-1995 ABC Changed include file name from "memory.h"
+ to "fwmem.h" to avoid a clash with the C++
+ standard header file "memory.h".
+ 10-Aug-1995 ABC Added support for SF_TMS (#timestamp) internal
+ macro.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* TANGLE.C */
+/******************************************************************************/
+
+/* Note: In this module, "ex_" at the start of a function name means "expand" */
+/* rather than the standard meaning of "ex" of "expression. */
+
+/******************************************************************************/
+
+#include "style.h"
+/* ABC { */
+/* The ANSI time functions are required for the #timestamp macro */
+#include <time.h>
+/* } ABC */
+
+#include "as.h"
+#include "data.h"
+#include "lister.h"
+#include "fwmem.h"
+#include "misc.h"
+#include "table.h"
+#include "tangle.h"
+#include "writfile.h"
+
+/******************************************************************************/
+
+/* The following variable keeps track of the output line number. This is */
+/* needed to report lines that are too long. */
+LOCVAR ulong lineno;
+
+/* Last line for which error message was generated. */
+LOCVAR ulong errlin;
+
+/* Number of too-long lines seen so far in this file. */
+LOCVAR ulong numlong;
+/* Number of long line error messages we can tolerate per product file. */
+#define LONGMESS 5
+
+/* Note: An indentation of n means n blanks before current material. */
+/* tgindent is a global variable set by the scanner. It is TRUE if blank */
+/* indenting is required and FALSE if no indenting is required. */
+LOCVAR ulong ind_base; /* Base indenting level of macro being expanded. */
+LOCVAR ulong ind_curr; /* Current indenting position. */
+
+LOCVAR char *fn_targ; /* Name of current (target) product file. */
+LOCVAR wf_t f_o; /* Current product file. */
+/* ABC { */
+LOCVAR bool inaldmQ; /* Whether inside the automatic line directive */
+ /* insertion macro or not. */
+LOCVAR bool Need_aldmQ; /* Whether to insert a line directive before the */
+ /* next scrap. */
+LOCVAR bool no_next_aldmQ; /* Whether to suppress the next line directive */
+ /* before a scrap. */
+/* } ABC */
+
+/******************************************************************************/
+
+/* The expression expansion function has to have a forward declaration. */
+/* ABC { The second parameter points to the parent invocation. } */
+LOCAL void ex_ex P_((p_ells_t,p_el_t,p_srcnmac_t));
+
+/******************************************************************************/
+
+LOCAL void eolblank P_((ulong));
+LOCAL void eolblank(n)
+/* Writes an EOL followed by n blanks to the product file. Efficiently! */
+ulong n;
+{
+ /* The whole aim of this routine is to write blanks EFFICIENTLY. In */
+ /* particular avoiding any per-char procedure call overhead (e.g. calls to */
+ /* wf_chr). The best way to avoid this is to create a static array of blanks */
+ /* and write out large blocks of blanks all at once. */
+#define BLANKLEN 100 /* Number of BLANKS in blank array. */
+ STAVAR bool notinit=TRUE; /* Has blank array been initialized? */
+ STAVAR char blanks[1+BLANKLEN]; /* EOL followed by BLANKLEN blanks. */
+
+ /* Set up the blank array. This only ever done once because of the static */
+ /* boolean. Note that use of an initialized static here does not make the */
+ /* code non-reentrant, as the state does not change after initialization. */
+ if (notinit)
+ {blanks[0]=EOL; memset(blanks+1,' ',(size_t) BLANKLEN); notinit=FALSE;}
+
+ /* The most common case will be a small indentation. Do this case fast. */
+ if (n<=BLANKLEN)
+ wf_blk(&f_o,&blanks[0],(size_t) n+1);
+ else
+ {
+ /* We now know that n>=BLANKLEN. Write out a long line with \n at front. */
+ wf_blk(&f_o,&blanks[0],BLANKLEN+1); n-=BLANKLEN;
+
+ /* Now get into large scale blank production! */
+ while (n>0)
+ {
+ ulong len=MIN(n,BLANKLEN);
+ wf_blk(&f_o,&blanks[1],(size_t) len); n-=len;
+ }
+ }
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void blank P_((ulong));
+LOCAL void blank(n)
+/* Writes an EOL followed by n blanks to the product file. Efficiently! */
+/* This is like `eolblank', but without the `eol' first. */
+ulong n;
+{
+ /* The whole aim of this routine is to write blanks EFFICIENTLY. In */
+ /* particular avoiding any per-char procedure call overhead (e.g. calls to */
+ /* wf_chr). The best way to avoid this is to create a static array of blanks */
+ /* and write out large blocks of blanks all at once. */
+#define BLANKLEN 100 /* Number of BLANKS in blank array. */
+ STAVAR bool notinit=TRUE; /* Has blank array been initialized? */
+ STAVAR char blanks[BLANKLEN]; /* EOL followed by BLANKLEN blanks. */
+
+ /* Set up the blank array. This only ever done once because of the static */
+ /* boolean. Note that use of an initialized static here does not make the */
+ /* code non-reentrant, as the state does not change after initialization. */
+ if (notinit)
+ {memset(blanks,' ',(size_t) BLANKLEN); notinit=FALSE;}
+
+ /* The most common case will be a small indentation. Do this case fast. */
+ if (n<=BLANKLEN)
+ wf_blk(&f_o,&blanks[0],(size_t) n);
+ else
+ {
+ /* We now know that n>=BLANKLEN. Write out a long line with \n at front. */
+ wf_blk(&f_o,&blanks[0],BLANKLEN); n-=BLANKLEN;
+
+ /* Now get into large scale blank production! */
+ while (n>0)
+ {
+ ulong len=MIN(n,BLANKLEN);
+ wf_blk(&f_o,&blanks[0],(size_t) len); n-=len;
+ }
+ }
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void ex_call P_((char*,p_ps_t,p_srcnmac_t));
+LOCAL void ex_call(mcname,p_ps,p_srctype)
+/* This function calls the named FunnelWeb macro without parameters.
+ */
+char *mcname;
+p_ps_t p_ps;
+p_srcnmac_t p_srctype;
+{
+ STAVAR el_t el = {
+ EL_INVC, /* el_kind */
+ NULL, /* el_text */
+ NULL, /* el_p_mac */
+ NULL, /* el_parls */
+ NULL, /* el_pretx */
+ NULL, /* el_postx */
+ NULL, /* el_p_par */
+ NULL, /* el_which */
+ 0, /* el_parno */
+ SF_ERR, /* el_selec */
+ { 0, 0, 0, NULL, FALSE } /* el_ps */
+ };
+ p_ma_t p_ma;
+ p_bp_t p_bp;
+ ulong ind_save;
+ p_void p_mark;
+ bool oldaldmQ = inaldmQ;
+
+ /* Save the current indentation base and set it to the current level. */
+ ind_save=ind_base;
+ ind_base=ind_curr;
+
+ /* Get up the macro parameters */
+ tb_loo(macro_table, PV mcname, PV &p_ma);
+
+ /* Note if macro is that used for automatic line directives */
+ if ((p_srctype != NULL) && (p_srctype->lnmac != NULL))
+ inaldmQ |= !strcmp(mcname, p_srctype->lnmac);
+
+ /* Set up an empty actual parameter list */
+ el.el_p_mac = p_ma;
+ if (el.el_parls == NULL) el.el_parls = ls_cre(sizeof(p_ells_t));
+ if (el.el_pretx == NULL) el.el_pretx = ls_cre(sizeof(p_scls_t));
+ if (el.el_postx == NULL) el.el_postx = ls_cre(sizeof(p_scls_t));
+ el.el_ps = *p_ps;
+
+ /* Push the actual parameter list onto the invoked macro's activation list. */
+ ls_add(p_ma->ma_actn,PV &el.el_parls);
+
+ /* Expand each body part expression. */
+ ls_fir(p_ma->ma_defn.md_body);
+ while (TRUE)
+ {
+ ls_nxt(p_ma->ma_defn.md_body,PPV &p_bp);
+ if (p_bp==NULL) break;
+ p_mark=ls_mar(p_ma->ma_defn.md_body); /* Protect againt recursion. */
+ ex_ex(p_bp->bp_ex, &el, p_srctype);
+ ls_set(p_ma->ma_defn.md_body,p_mark);
+ }
+
+ /* Pop the activated macro's parameter list. */
+ ls_lop(p_ma->ma_actn);
+
+ /* Restore the indentation base. */
+ ind_base=ind_save;
+
+ /* ABC { */
+ /* Restore the initial state of `inaldmQ' */
+ inaldmQ = oldaldmQ;
+ /* } ABC */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+#define SENDLINE {wl_l(linet1); if (option.op_s_b) wl_sj(linet1);}
+
+/* ABC { */
+LOCAL void ex_sc P_((p_sc_t,p_ps_t,p_srcnmac_t));
+LOCAL void ex_sc(p_sc,p_ps,p_srctype)
+/* } ABC */
+/* This function writes the specified scrap to the product file. It also */
+/* performs two other tasks: */
+/* If tgindent==TRUE, inserts indentation at the start of each line. */
+/* If tglinmax>0, checks for product file lines longer than tglinmax. */
+/* Note: The speed of this routine is fairly critical. */
+p_sc_t p_sc;
+p_ps_t p_ps;
+p_srcnmac_t p_srctype;
+{
+ /* Add an automatic line insertion macro if necessary, *
+ * taking care of preserving the indenting */
+ if (
+ (p_srctype != NULL)
+ && (p_srctype->lnmac != NULL)
+ && !(inaldmQ) && Need_aldmQ && !no_next_aldmQ
+ && (p_ps != NULL)
+ ) {
+ int ind_save = ind_curr;
+ if (ind_curr > 0) wf_chr(&f_o, '\n');
+ ind_curr = 0; /* directive starts at beginning of line */
+ ex_call(p_srctype->lnmac,p_ps,p_srctype);
+ if (ind_curr > 0) wf_chr(&f_o, '\n');
+ if (ind_save > 0) blank(ind_save);
+ ind_curr = ind_save;
+ } /* end if */
+ Need_aldmQ = FALSE;
+ /* } ABC */
+
+ /* Output of a scrap is straightforward if we are not inserting indentation */
+ /* or watching for lines that are too long. If neither of these tasks have */
+ /* to be performed, we can bang the scrap out directly with a wf_blk. */
+ if (!tgindent && tglinmax==TGMAXINF)
+ {
+ wf_blk(&f_o, p_sc->sc_first, (size_t) (p_sc->sc_last-p_sc->sc_first+1));
+ return;
+ }
+
+ /* Otherwise it gets rather messy. Basically, we have to watch for end of */
+ /* lines and perform special actions there. */
+ /* ind_curr is the number of characters already written to the current line. */
+ {
+ char *p = p_sc->sc_first;
+ char *p_post = p_sc->sc_last+1;
+ while (TRUE)
+ {
+ char *p_sot = p; /* SOT=Start of Text. */
+
+ /* Scan scrap until we hit either its end or an EOL. */
+ while (p!=p_post && *p!=EOL) p++;
+
+ /* Assert: p==p_post || (p_sot<=p<p_post && *p==EOL). */
+
+ /* If we scanned any non-EOL text, write out what we scanned. */
+ if (p>p_sot) {wf_blk(&f_o,p_sot,(size_t) (p-p_sot));ind_curr+=p-p_sot;}
+
+ /* Check that what we have written so far is not too long. */
+ /* Performing this check here rather than with the EOL processing */
+ /* means that we will detect overlong final non-EOL terminated lines. */
+ /* Use of errlin suppresses multiple errors on the same line. */
+ /* Note: We assume that TGMAXINF is very large. */
+ if (ind_curr>tglinmax && lineno!=errlin)
+ {
+ numlong++;
+ if (numlong <= LONGMESS)
+ {
+ if (option.op_b7_b)
+ sprintf(linet1,
+ "E: Product file line is too long (line %lu of \"%s\").",
+ (ulong) lineno,SUPPNAME);
+ else
+ sprintf(linet1,
+ "E: Product file line is too long (line %lu of \"%s\").",
+ (ulong) lineno,fn_targ);
+ SENDLINE;
+ if (numlong==1)
+ {
+ sprintf(linet1," Product file line length limit is %lu characters.",
+ (ulong) tglinmax);
+ SENDLINE;
+ sprintf(linet1," Note: You can change the limit by specifying.");
+ SENDLINE;
+ sprintf(linet1," @p maximum_output_line_length = <desired length>");
+ SENDLINE;
+ sprintf(linet1," somewhere in the input file.");
+ SENDLINE;
+ }
+ errlin=lineno;
+ num_err++;
+ }
+ if (numlong == LONGMESS+1)
+ {
+ sprintf(linet1,
+ "Further line-too-long warnings for file \"%s\" have been suppressed.",
+ fn_targ);
+ SENDLINE;
+ }
+ }
+
+ /* Exit if we hit the end of the scrap. */
+ if (p==p_post) break;
+
+ /* Move past the EOL and bump up the line counter. */
+ p++; lineno++;
+
+ /* Output an EOL with indentation if desired. */
+ if (tgindent)
+ eolblank(ind_base);
+ else
+ wf_chr(&f_o,EOL);
+ ind_curr=ind_base;
+ }
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void ex_eltx P_((p_el_t,p_el_t,p_srcnmac_t));
+LOCAL void ex_eltx(p_el,p_par,p_srctype)
+/* Writes the given text element to the product file. */
+p_el_t p_el;
+p_el_t p_par;
+p_srcnmac_t p_srctype;
+{
+ p_sc_t p_sc;
+
+ /* Make sure that we have actually been handed a text element. */
+ as_cold(p_el->el_kind==EL_TEXT,"ex_eltx: Not a text element!");
+
+ /* Write all the scraps in the text list to the product file. */
+ ls_fir(p_el->el_text);
+ while (TRUE)
+ {
+ ls_nxt(p_el->el_text,PPV &p_sc);
+ if (p_sc==NULL) break;
+ /* ABC { */
+ ex_sc(p_sc,&(p_el->el_ps),p_srctype);
+ /* } ABC */
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void ex_elpr P_((p_el_t,p_el_t,p_srcnmac_t));
+LOCAL void ex_elpr(p_el,p_par,p_srctype)
+/* Write the expansion of the given parameter element to the product file. */
+p_el_t p_el;
+p_el_t p_par;
+p_srcnmac_t p_srctype;
+{
+ p_ell3_t actn = p_el->el_which->ma_actn;
+ p_elll_t *pp_parls;
+ p_ells_t *pp_exp;
+ ulong ind_save;
+
+ /* Make sure that we have been handed a parameter element. */
+ as_cold(p_el->el_kind==EL_PARM,"ex_elpr: Not a parameter element!");
+
+ /* Save the current indentation base and set it to the current level. */
+ ind_save=ind_base;
+ ind_base=ind_curr;
+
+ /* Get a pointer to the most recent parameter list of the target macro. */
+ ls_loo(actn,ls_len(actn),PPV &pp_parls);
+
+ /* Get the expression corresponding to the el_parno'th parameter. */
+ ls_loo(*pp_parls,p_el->el_parno,PPV &pp_exp);
+
+ /* Expand that expression. */
+ ex_ex(*pp_exp,p_el,p_srctype);
+
+ /* Restore the indentation base. */
+ ind_base=ind_save;
+}
+
+/******************************************************************************/
+
+LOCAL void ex_elin P_((p_el_t,p_el_t,p_srcnmac_t));
+LOCAL void ex_elin(p_el,p_par,p_srctype)
+/* Expand invocation element. */
+p_el_t p_el;
+p_el_t p_par;
+p_srcnmac_t p_srctype;
+{
+ p_ma_t p_ma;
+ p_bp_t p_bp;
+ ulong ind_save;
+ p_void p_mark;
+ /* ABC { */
+ bool oldaldmQ = inaldmQ;
+ /* } ABC */
+
+ /* Make sure that we have been handed an invocation element. */
+ as_cold(p_el->el_kind==EL_INVC,"ex_elin: Not an invocation element!");
+
+ /* Save the current indentation base and set it to the current level. */
+ ind_save=ind_base;
+ ind_base=ind_curr;
+
+ /* ABC { */
+ /* Mark parent */
+ p_el->el_p_par = p_par;
+ /* } ABC */
+
+ /* Grab a pointer to the macro being invoked. */
+ p_ma=p_el->el_p_mac;
+
+ /* ABC { */
+ /* Note if macro is that used for automatic line directives */
+ if ((p_srctype != NULL) && (p_srctype->lnmac != NULL))
+ inaldmQ |= !strcmp(p_ma->ma_name, p_srctype->lnmac);
+ /* } ABC */
+
+ /* Push the actual parameter list onto the invoked macro's activation list. */
+ ls_add(p_ma->ma_actn,PV &p_el->el_parls);
+
+ /* Expand each body part expression. */
+ ls_fir(p_ma->ma_defn.md_body);
+ while (TRUE)
+ {
+ ls_nxt(p_ma->ma_defn.md_body,PPV &p_bp);
+ if (p_bp==NULL) break;
+ p_mark=ls_mar(p_ma->ma_defn.md_body); /* Protect againt recursion. */
+ /* ABC { */
+ /* May need a line directive for each part of the macro */
+ if (!inaldmQ) Need_aldmQ = TRUE;
+ /* } ABC */
+ ex_ex(p_bp->bp_ex, p_el, p_srctype);
+ ls_set(p_ma->ma_defn.md_body,p_mark);
+ }
+
+ /* Pop the activated macro's parameter list. */
+ ls_lop(p_ma->ma_actn);
+
+ /* Restore the indentation base. */
+ ind_base=ind_save;
+
+ /* ABC { */
+ /* May need a line directive for the end of the macro */
+ if (!inaldmQ) Need_aldmQ = TRUE;
+ /* Restore the initial state of `inaldmQ' */
+ inaldmQ = oldaldmQ;
+ /* } ABC */
+}
+
+/* ABC { */
+/******************************************************************************/
+
+#define ELSP_NUMSZ (32)
+
+LOCAL void ex_tstamp P_((char*));
+LOCAL void ex_tstamp(strptr)
+/* Copies the FunnelWeb timestamp into the argument string. */
+char *strptr;
+{
+ static bool unfixedQ = TRUE;
+ static char timestamp[ELSP_NUMSZ];
+ time_t current = -1; /* time_t is defined in `time.h' */
+
+ if (unfixedQ) {
+ /* Initialise on the first call. */
+ current = time(NULL);
+ if (current == -1) {
+ /* `time' failed */
+ strcpy(timestamp, "????/??/??/??/??/??");
+ } else {
+ /* `time' was successful */
+ strftime(
+ timestamp, ELSP_NUMSZ,
+ "%Y/%m/%d/%H/%M/%S",
+ localtime(&current)
+ );
+ } /* end if */
+ unfixedQ = FALSE;
+ } /* end if */
+
+ strcpy(strptr, timestamp);
+}
+
+/******************************************************************************/
+
+LOCAL void ex_elsp P_((p_el_t,p_el_t,p_srcnmac_t));
+LOCAL void ex_elsp(p_el,p_par,p_srctype)
+/* Writes the given internal function result to the product file. */
+p_el_t p_el;
+p_el_t p_par;
+p_srcnmac_t p_srctype;
+{
+ p_sc_t p_sc;
+ char *p_res = NULL;
+ char errmss[32];
+ p_el_t punwnd;
+ uword i;
+
+ /* Make sure that we have actually been handed a text element. */
+ as_cold(p_el->el_kind==EL_SPEC,"ex_elsp: Not a special function!");
+
+ /* Check special function and write result string. */
+ p_sc = (p_sc_t)mm_temp(sizeof(sc_t));
+ switch (p_el->el_selec) {
+ case SF_LIN :
+ if (p_par) {
+ punwnd = p_par;
+ for (i=0; (i<lin_dep)&&punwnd; i++) punwnd = punwnd->el_p_par;
+ if (punwnd) {
+ p_res = (char *)mm_temp(ELSP_NUMSZ*sizeof(char));
+ sprintf(p_res, "%lu", punwnd->el_ps.ps_localno+lin_off);
+ p_sc->sc_white = FALSE;
+ } /* end if */
+ } /* end if */
+ break;
+ case SF_FIL :
+ if (p_par) {
+ punwnd = p_par;
+ for (i=0; (i<lin_dep)&&punwnd; i++) punwnd = punwnd->el_p_par;
+ if (punwnd) {
+ p_res = (char *)mm_temp(
+ (strlen(punwnd->el_ps.ps_fnam->fnam_name)+1) * sizeof(char)
+ );
+ strcpy(p_res, punwnd->el_ps.ps_fnam->fnam_name);
+ p_sc->sc_white = FALSE;
+ } /* end if */
+ } /* end if */
+ break;
+ case SF_TMS :
+ p_res = (char *)mm_temp(ELSP_NUMSZ*sizeof(char));
+ ex_tstamp(p_res);
+ p_sc->sc_white = FALSE;
+ break;
+ case SF_ERR :
+ default :
+ wl_sjl("An erroneous internal function designator was seen.");
+ if (p_el->el_selec == SF_ERR) {
+ wl_sjl("Type: SF_ERR");
+ } else {
+ sprintf(errmss, "Type: SF_??? = %lu", (ulong)p_el->el_selec);
+ wl_sjl(errmss);
+ } /* end if */
+ wl_sjl("Aborted internal function.");
+ return;
+ } /* end switch */
+
+ /* Write internal result to the product file. */
+ p_sc->sc_first = p_res;
+ p_sc->sc_last = p_res + strlen(p_res) - 1;
+ ex_sc(p_sc, NULL, NULL);
+}
+
+/* } ABC */
+
+/******************************************************************************/
+
+LOCAL void ex_ex(p_exp,p_par,p_srctype)
+/* Expand the specified expression. */
+p_ells_t p_exp;
+p_el_t p_par;
+p_srcnmac_t p_srctype;
+{
+ p_void p_mark;
+
+ /* We need to save the current position in the expression list in case we */
+ /* are being recursively invoked (e.g. in @<X@>@(@"@<X@>@(@"sloth@"@)@"@). */
+ ls_fir(p_exp);
+ while (TRUE)
+ {
+ p_el_t p_el;
+ ls_nxt(p_exp,PPV &p_el);
+ if (p_el==NULL) break;
+ p_mark=ls_mar(p_exp);
+ switch (p_el->el_kind)
+ {
+ /* ABC { */
+ case EL_TEXT: ex_eltx(p_el,p_par,p_srctype);
+ no_next_aldmQ = FALSE; break;
+ case EL_INVC: ex_elin(p_el,p_par,p_srctype); break;
+ case EL_PARM: ex_elpr(p_el,p_par,p_srctype); break;
+ case EL_SPEC: ex_elsp(p_el,p_par,p_srctype);
+ no_next_aldmQ = TRUE; break;
+ /* } ABC */
+ default : as_bomb("ex_ex: Case defaulted.");
+ }
+ ls_set(p_exp,p_mark);
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void ex_file P_((p_ma_t));
+LOCAL void ex_file(p_ma)
+/* This function accepts a pointer to a macro. It creates a product file */
+/* with the same name as the macro (inheriting any filename parts given in */
+/* the command line) and expands the macro, writing the expansion to the */
+/* product file. */
+p_ma_t p_ma;
+{
+ fn_t fn_tmp; /* Name of temporary file. */
+ bool renfil; /* Do we wish to rename product file? */
+ bool istarg; /* Does a target file already exist? */
+/* ABC { */
+ p_srcnmac_t p_srctype; /* Source code type */
+/* } ABC */
+
+ /* Writing product files differs to the other output files. With non */
+ /* critical files such as the listing file that are really just logs, */
+ /* generation of half a listing file is acceptable if not desirable. However */
+ /* in the case of product files, it is very bad to generate half a product */
+ /* file; far better to generate none at all. For this reason, and also */
+ /* because of the presence of the D option (which prohibits the writing */
+ /* of product files identical to existing files (to prevent MAKE */
+ /* propagations)) it is best to write a temporary file and then rename it. */
+
+ /* Construct the target file name. */
+ strcpy(fn_targ,""); /* Start with an empty name. */
+ fn_ins(fn_targ,&option.op_o_s[0]);
+ /* ABC { */
+#if DYN_NAMES
+ fn_ins(fn_targ,p_ma->ma_name);
+#else /* !DYN_NAMES */
+ fn_ins(fn_targ,&p_ma->ma_name[0]);
+#endif /* DYN_NAMES */
+ /* } ABC */
+
+ /* The temporary file has to inherit too, because the output directory may */
+ /* not be the default directory and some computers can't rename across */
+ /* directories (and we have to rename it later). */
+ strcpy(fn_tmp,fn_targ);
+ fn_ins(fn_tmp,fn_temp());
+
+/* ABC { */
+ /* Set the source code type */
+ p_srctype = p_ma->ma_defn.md_aldm;
+/* } ABC */
+
+ /* Expand the macro to the temporary file. */
+ wf_ini(&f_o,TRUE);
+ wf_ope(&f_o,fn_tmp);
+ if (wf_err(&f_o))
+ {
+ sprintf(linet1,"Error creating temporary product file \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ (void) remove(fn_tmp);
+ goto severe;
+ }
+
+ /* Now expand the target macro into the file. */
+ /* ABC { */
+ /* An automatic line directive may be needed at the start */
+ Need_aldmQ = TRUE;
+ no_next_aldmQ = FALSE;
+ /* } ABC */
+ {
+ el_t el;
+ el.el_kind = EL_INVC;
+ el.el_p_mac = p_ma;
+ el.el_parls = ls_cre(sizeof(p_ells_t));
+ /* Note: We don't set el_pretx and el_postx as they are not used here. */
+ ind_base = 0;
+ ind_curr = 0;
+ lineno = 1;
+ errlin = 0;
+ numlong = 0;
+ ex_elin(&el, (p_el_t)0, p_srctype);
+ }
+
+ /* Make sure that there weren't any errors writing to the product file. */
+ if (wf_err(&f_o))
+ {
+ sprintf(linet1,"S: Error writing to temporary product file \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ (void) remove(fn_tmp);
+ goto severe;
+ }
+
+ /* Close the product file. */
+ wf_clo(&f_o);
+ if (wf_err(&f_o))
+ {
+ sprintf(linet1,"S: Error closing temporary product file \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ (void) remove(fn_tmp);
+ goto severe;
+ }
+
+ /* The rest of the code in this function copes with the renaming. */
+
+ /* By default, we wish to rename the temporary file. */
+ renfil=TRUE;
+
+ /* Deal with any existing file of the target name. */
+ istarg=fexists(fn_targ);
+ if (istarg && option.op_d_b)
+ {
+ /* A target already exists, and the D option is on. If the target is */
+ /* identical to the temporary, we can simply delete the temporary! */
+ char *errstr;
+ bool same;
+ errstr=eq_files(fn_tmp,fn_targ,&same);
+ if (errstr != NULL)
+ {
+ wl_sjl("S: Error comparing temporary file with previous product file.");
+ wl_sjl("(A comparison was attempted because the D option was turned on.)");
+ wl_sjl("Error from comparison routine was as follows (first=temp):");
+ wr_sjl(" ");wl_sjl(errstr);
+ sprintf(linet1,"Temporary file name was \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ sprintf(linet1,"Product file name was \"%s\".",fn_targ);
+ wl_sjl(linet1);
+ wl_sjl("FunnelWeb will leave both files intact so you can look at them.");
+ goto severe;
+ }
+ /* If the two files are the same, we can simply delete the temporary. */
+ if (same)
+ {
+ int status;
+ status=remove(fn_tmp);
+ if (status != REMOVE_S)
+ {
+ sprintf(linet1,"S: Error deleting (under +D option) temporary file \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ goto severe;
+ }
+ sprintf(linet1,"Deleted identical product file \"%s\".",fn_targ);
+ wl_sjl(linet1);
+ renfil=FALSE;
+ }
+ }
+
+ if (renfil)
+ {
+ int status;
+ /* We need to delete any existing file of the target name. */
+ if (istarg)
+ {
+ status=remove(fn_targ);
+ if (status != REMOVE_S)
+ {
+ sprintf(linet1,"S: Error deleting existing product file \"%s\".",fn_targ);
+ wl_sjl(linet1);
+ goto severe;
+ }
+ }
+ /* Rename the temporary file to the product file. */
+ status=rename(fn_tmp,fn_targ);
+ if (status != RENAME_S)
+ {
+ wl_sjl("S: Error renaming temporary product file to product file.");
+ sprintf(linet1,"Temporary file name was \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ sprintf(linet1,"Product file name was \"%s\".",fn_targ);
+ wl_sjl(linet1);
+ wl_sjl("FunnelWeb will leave both files intact so you can look at them.");
+ goto severe;
+ }
+ }
+
+ /* Tell everyone that we have written a product file. */
+ /* Note that we use the macro name. The full name is usually too messy. */
+ /* ABC { */
+#if DYN_NAMES
+ sprintf(linet1,"Tangle: Completed %s.",p_ma->ma_name);
+#else /* !DYN_NAMES */
+ sprintf(linet1,"Tangle: Completed %s.",&p_ma->ma_name[0]);
+#endif /* DYN_NAMES */
+ /* } ABC */
+ wl_sjl(linet1);
+ return;
+
+ /* Jump here is a nasty file error occurs. */
+ severe:
+ sprintf(linet1,"A problem occurred during the generation of product file \"%s\".",&fn_targ[0]);
+ wl_sjl(linet1);
+ wl_sjl("S: Aborting...");
+ num_sev++;
+ return;
+
+}
+
+/******************************************************************************/
+
+EXPORT void tangle()
+{
+ name_t dummyname;
+ p_ma_t p_ma;
+
+ /* ABC { */
+ /* Initialise inaldmQ: not in auto line directive macro */
+ inaldmQ = FALSE;
+ /* Initialise Need_aldmQ: no directive needed before next scrap */
+ Need_aldmQ = FALSE;
+ /* } ABC */
+
+ /* Possibly decrease tglinmax if W option is turned on. */
+ if (option.op_w_b)
+ tglinmax=MIN(tglinmax,option.op_w_i);
+
+ /* Some compilers do not allow much space for statics so we allocate fn_targ */
+ /* dynamically to save static space. */
+ fn_targ=(char *) mm_temp(sizeof(fn_t));
+
+ /* Generate each file contained in the file table. */
+ tb_fir(file_table);
+ while (num_sev==0 && tb_rea(file_table,PV dummyname,PV &p_ma))
+ ex_file(p_ma);
+}
+
+/******************************************************************************/
+/* End of TANGLE.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/tangle.h b/web/funnelAC/fwACsrc/tangle.h
new file mode 100644
index 0000000000..800a609cad
--- /dev/null
+++ b/web/funnelAC/fwACsrc/tangle.h
@@ -0,0 +1,56 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* TANGLE.H */
+/******************************************************************************/
+/* */
+/* This package exports a single function "tangle" that generates all the */
+/* product files for FunnelWeb. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+EXPORT void tangle P_((void));
+/* Generate product files. */
+
+/******************************************************************************/
+/* End of TANGLE.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/texhead.c b/web/funnelAC/fwACsrc/texhead.c
new file mode 100644
index 0000000000..8a94553471
--- /dev/null
+++ b/web/funnelAC/fwACsrc/texhead.c
@@ -0,0 +1,108 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* TEXHEAD.C */
+/******************************************************************************/
+/* */
+/* TEX HEADER PACKAGE */
+/* ================== */
+/* This package contains a single function that writes the TeX header */
+/* (containing all the Weave macros) to the specified stream. The package */
+/* consists of: */
+/* */
+/* texhead.tex - The header file ("source code" for texhead.ctx). */
+/* texhead.ctx - Automatically generated C code based on texhead.tex. */
+/* texhead.h - Exported header file containing function definition. */
+/* texhead.c - Contains the function body and the codified header file. */
+/* */
+/* WARNING: THE ONLY FILE THAT SHOULD EVER BE MODIFIED BY HAND IS TEXHEAD.TEX.*/
+/* From this can be generated a new version of texhead.ctx. Here's how: */
+/* 1. Edit texhead.tex as desired. */
+/* 2. Fire up the FunnelWeb shell and give the command: */
+/* codify texhead.tex texhead.ctx */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "texhead.h"
+#include "writfile.h"
+
+/******************************************************************************/
+
+EXPORT void tex_head(p_wf)
+p_wf_t p_wf;
+/* Writes the FunnelWeb TeX header block to the argument stream. */
+{
+
+ /*#############################################################################
+ IMPORTANT COPYRIGHT NOTICE
+ --------------------------
+ The set of FunnelWeb TeX definitions, embodied in C code in the file
+ included by the #include directive below, is a public domain work.
+
+ Notwithstanding the fact that the public domain set of FunnelWeb TeX
+ definitions is represented in the form of strings in C code #included by the
+ FunnelWeb literate-programming preprocessor program released under GNU General
+ Public License Version 2, the set of TeX definitions themselves do not fall
+ under GNU license. Instead, the set of FunnelWeb TeX definitions is classified
+ as a public domain work that is distributed with FunnelWeb as a "separate
+ work". The set of definitions is included as strings in the FunnelWeb code for
+ the sole reason that this organization avoids FunnelWeb having to locate the
+ file at run time. Thus, when FunnelWeb writes the set of TeX definitions to a
+ .TeX output file, it is not generating a work based on itself, but is merely
+ copying a public domain file (which it happened to represent in the form of
+ code rather than data) into the output file.
+
+ The motivation for rigorously clarifying the status of the set of
+ FunnelWeb TeX definitions is that it will appear in TeX output files
+ generated by FunnelWeb, and I do not want any output files generated by
+ FunnelWeb to be under any copyright restrictions.
+
+ -- Ross N. Williams, 5:42pm 07-May-1992, Adelaide, Australia.
+
+ #############################################################################*/
+
+#define WX(STR) wf_wl(p_wf,STR)
+
+#include "texhead.ctx"
+}
+
+/******************************************************************************/
+/* End of TEXHEAD.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/texhead.ctx b/web/funnelAC/fwACsrc/texhead.ctx
new file mode 100644
index 0000000000..b873bd70ba
--- /dev/null
+++ b/web/funnelAC/fwACsrc/texhead.ctx
@@ -0,0 +1,320 @@
+ WX("%===================== Start of FunnelWeb TeX Definitions ======================");
+ WX("");
+ WX("");
+ WX("% Version");
+ WX("% -------");
+ WX("% This is FunnelWeb TeX Macro Library Version 1.0.");
+ WX("");
+ WX("");
+ WX("% Copyright");
+ WX("% ---------");
+ WX("% This set of FunnelWeb TeX definitions was written by Ross Williams and was");
+ WX("% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,");
+ WX("% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions");
+ WX("% and hereby authorize that the set of TeX definitions pass into the public");
+ WX("% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.");
+ WX("");
+ WX("");
+ WX("% Modification");
+ WX("% ------------");
+ WX("% Please record all modifications to these TeX definitions here. Unless");
+ WX("% otherwise specified, all modified definitions fall in the public domain too.");
+ WX("%");
+ WX("% Programmers:");
+ WX("% RNW Ross N. Williams ross@spam.adelaide.edu.au");
+ WX("%");
+ WX("% Changes:");
+ WX("% 07-May-1992 RNW Prepared this work for public domain release.");
+ WX("%");
+ WX("");
+ WX("");
+ WX("% General Comments");
+ WX("% ----------------");
+ WX("% This set of TeX definitions exists for two reasons:");
+ WX("%");
+ WX("% 1. To shorten and neaten the FunnelWeb TeX output.");
+ WX("% 2. To allow users to fiddle with the output format in their input files");
+ WX("% (by inserting redefining \"\\def\"s) without having to resort to");
+ WX("% modifying the FunnelWeb code.");
+ WX("%");
+ WX("% The user is warned that these definitions may be changed from time to time");
+ WX("% (but probably not much). The user should not be too sneaky. In particular,");
+ WX("% users wishing to redefine some of these macros should do so in an explicitly");
+ WX("% defined section at the top of their input file. This will mean that in the");
+ WX("% event of problems, that section can simply be deleted or commented out to");
+ WX("% allow the document to at least be typeset in the default format. Users should");
+ WX("% limit themselves to redefining these macros in such a section and should");
+ WX("% refrain from using the macros throughout their documents.");
+ WX("");
+ WX("");
+ WX("% Environment Parameters");
+ WX("% ----------------------");
+ WX("% \\tolerance tells TeX how tolerant it should be about making bad line and");
+ WX("% page breaks. Here we set it to it's maximum, as");
+ WX("% 1) Computer programs are likely to cause lots of bad breaks.");
+ WX("% 2) In most cases the user would probably rather get the TeX file through");
+ WX("% TeX without any errors than fiddle with spacings for perfection.");
+ WX("\\tolerance=10000");
+ WX("");
+ WX("% I don't like indentation as it makes the page look more busy. Instead,");
+ WX("% paragraphs are separated by a little space (see next).");
+ WX("\\parindent=0pt");
+ WX("");
+ WX("% In many cases, users will produce documents with long runs of paragraphs.");
+ WX("% In order to space out these paragraphs, it is convenient to maintain a");
+ WX("% prevailing non-zero \\parskip (end-of-paragaph skip). The only trouble is");
+ WX("% that the skip becomes a problem in macro definitions which require no skip");
+ WX("% and so we have to turn the skip on and off. The following two macros");
+ WX("% simplify this process.");
+ WX("\\def\\fwparskipon{\\parskip=\\medskipamount}");
+ WX("\\def\\fwparskipoff{\\parskip=0pt}");
+ WX("\\fwparskipon");
+ WX("");
+ WX("% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the");
+ WX("% page in order to better vertically align the rest of the page (e.g. skips");
+ WX("% won't stretch as much). It also means that headings are less likely to be");
+ WX("% isolated at the bottom of the page without any following text.");
+ WX("\\raggedbottom");
+ WX("");
+ WX("");
+ WX("% Fonts");
+ WX("% -----");
+ WX("% Most of the typeset output is set in 10pt roman and 10pt tt font.");
+ WX("% The major extra font needs spring from titles and headings.");
+ WX("% For portability's sake we use only the following fonts:");
+ WX("% cmr10");
+ WX("% cmbx10");
+ WX("% cmtt10");
+ WX("% and some enlargements of them. These fonts are all \"standard\" fonts");
+ WX("% in Plain TeX. See The TeXbook p.350.");
+ WX("\\font\\fwfontnote=cmr7");
+ WX("");
+ WX("\\font\\fwfontnorm=cmr10");
+ WX("\\font\\fwfontnorma=cmr10 scaled \\magstep1");
+ WX("\\font\\fwfontnormb=cmr10 scaled \\magstep2");
+ WX("");
+ WX("\\font\\fwfontbold=cmbx10");
+ WX("\\font\\fwfontbolda=cmbx10 scaled \\magstep1");
+ WX("\\font\\fwfontboldb=cmbx10 scaled \\magstep2");
+ WX("\\font\\fwfontboldc=cmbx10 scaled \\magstep3");
+ WX("\\font\\fwfontboldd=cmbx10 scaled \\magstep4");
+ WX("");
+ WX("");
+ WX("% Macros for Stylistic Details");
+ WX("% ----------------------------");
+ WX("% This section contains all the fiddly little macros for setting the details");
+ WX("% of each macro definition.");
+ WX("");
+ WX("% Macro definitions are sandwiched by calls to these macros which can be used");
+ WX("% to sort out the spacing before and after the macro definition.");
+ WX("\\def\\fwbeginmacro{\\fwparskipoff\\bigskip}");
+ WX("\\def\\fwendmacro{\\fwparskipon\\par}");
+ WX("");
+ WX("% These macros deal with the macro name and definition line.");
+ WX("\\def\\fwmacroname#1#2{{\\sl #1\\/}$\\lbrack$#2$\\rbrack$}");
+ WX("\\def\\fwfilename#1#2{{\\bf #1}$\\lbrack$#2$\\rbrack$}");
+ WX("\\def\\fwzero#1{{\\bf Z}}");
+ WX("\\def\\fwmany#1{{\\bf M}}");
+ WX("\\def\\fwequals{ $\\equiv$}");
+ WX("\\def\\fwplusequals{ $+\\equiv$}");
+ WX("");
+ WX("% Now for the actual body of the definition. It looks nice to have the tt");
+ WX("% code indented a little. Again, we use macros instead of writing direct TeX,");
+ WX("% so as to allow the user to fiddle this stuff to taste without having to");
+ WX("% modify the FunnelWeb C code.");
+ WX("\\def\\fwodef{\\parindent=15pt\\vskip0pt$\\lbrace$\\parindent=20pt}");
+ WX("\\def\\fwcdef{$\\rbrace$\\vskip0pt\\parindent=0pt}");
+ WX("\\def\\fwoquote{`}");
+ WX("\\def\\fwcquote{'}");
+ WX("\\def\\fwoparen{$($}");
+ WX("\\def\\fwcomma{$,$}");
+ WX("\\def\\fwcparen{$)$}");
+ WX("\\def\\fwparam#1{$\\diamond #1$}");
+ WX("\\def\\fwparams#1{$(\\diamond #1)$}");
+ WX("");
+ WX("% These macros deal with the notes that are appended at the end of each");
+ WX("% macro definition. Note that even though \\fwisafile,\\fwusedin, and \\fwseealso");
+ WX("% have the same definition, they are given different names so as to allow the");
+ WX("% user to redefine these macros to typeset each kind of information differently");
+ WX("% if desired.");
+ WX("\\def\\fwbeginmacronotes{\\begingroup\\baselineskip=9pt\\smallskip}");
+ WX("\\def\\fwnote#1{{\\fwfontnote #1}\\par}");
+ WX("\\def\\fwisafile#1{\\fwnote{#1}}");
+ WX("\\def\\fwusedin#1{\\fwnote{#1}}");
+ WX("\\def\\fwseealso#1{\\fwnote{#1}}");
+ WX("\\def\\fwendmacronotes{\\endgroup}");
+ WX("");
+ WX("");
+ WX("% Macros to Typeset Program Code Verbatim");
+ WX("% ---------------------------------------");
+ WX("% This is by far the hairiest and most difficult part of the typesetting task");
+ WX("% because we have to turn off most of TeX's natural instincts in order to");
+ WX("% typeset the program text exactly as it appears in the input file.");
+ WX("% Two macros are defined to pull this off: \\fwbtx and \\fwverbatimgobble.");
+ WX("% Their code was inspired by the following sections of \"The TeXbook\":");
+ WX("% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.");
+ WX("% Appendix E: Example Formats, p.421.");
+ WX("% The \\fwbtx[ (for \"FunnelWeb Begin TeXt\") macro does most of the hard work.");
+ WX("% The liberal use of \"%\" is because I don't understand TeX well enough to");
+ WX("% understand when an end of line will cause trouble, and I am playing it safe.");
+ WX("");
+ WX("% Before defining the main \\fwbtx macro, we have to stash away some definitions");
+ WX("% in the hidden part of TeX's environment. Let's hope that these \"hidden\"");
+ WX("% definitions don't affect anything except what is desired to be affected.");
+ WX("");
+ WX("% The tt font in which we wish to set the text has two Latin lurking ligatures!");
+ WX("% These are ?` and !`. To disable them, we define the left quote when ACTIVE");
+ WX("% to be defined in such a way as to prevent ligatures. The main TeX text will");
+ WX("% normally not be exposed to this definition because normally the leftquote");
+ WX("% character is not active. The \\fwbtx macro temporarily makes the left quote");
+ WX("% character active thus activating the deactivation of left quote ligatures.");
+ WX("% See The TeXbook p.381.");
+ WX("{\\catcode`\\`=\\active \\gdef`{\\relax\\lq}}");
+ WX("");
+ WX("% TeX is fairly carefree about spaces and so we have to make it more serious.");
+ WX("% To do so we pull the same trick as above, setting up a definition for active");
+ WX("% space, but only making space active during the span of the verbatim text.");
+ WX("% In Plain TeX the active space is defined to be simply a space, but here we");
+ WX("% define it to be a control space. This ensures that the space cannot");
+ WX("% be gobbled up by one of TeX's mysterious mechanisms when activated.");
+ WX("% See The TeXbook, p.381 and p.352.");
+ WX("{\\obeyspaces\\global\\let =\\ }");
+ WX("");
+ WX("% Here is the main \\fwbtx verbatim text macro.");
+ WX("% Note: The order in which all these pieces of business have to be done is");
+ WX("% still a partial mystery to me. Don't fiddle with this stuff unless you");
+ WX("% think you know what you are doing.");
+ WX("\\def\\fwbtx[{%");
+ WX("%");
+ WX("% The funnies involved in getting verbatim output are safely housed inside");
+ WX("% this \\begingroup, and the \\endgroup in \\fwverbatimgobble. Groups are used");
+ WX("% instead of curly braces because we have to be able to signal the end of");
+ WX("% this macro with a curly brace.");
+ WX("\\begingroup%");
+ WX("%");
+ WX("% \\pars at the end of empty lines in the verbatim text won't come out normally");
+ WX("% because TeX is in vertical mode and they get gobbled up. To prevent this,");
+ WX("% we force \\par to exit vertical mode first. See The TeXbook p.381.");
+ WX("\\def\\par{\\leavevmode\\endgraf}%");
+ WX("%");
+ WX("% Activate the leftquote character so as to avoid ligatures (see above).");
+ WX("\\catcode`\\`=\\active%");
+ WX("%");
+ WX("% The \\obeylines macro simply defines end of line (^M) to be \\par. This ensures");
+ WX("% that TeX will treat each verbatim line as a new paragraph.");
+ WX("\\obeylines%");
+ WX("%");
+ WX("% To get verbatim output, we have to desex all the special characters. This");
+ WX("% is explained in detail in The TeXbook p.380.");
+ WX("\\def\\do##1{\\catcode`##1=12 }\\dospecials%");
+ WX("%");
+ WX("% Activate the space character so as to make TeX treat blanks seriously.");
+ WX("% This activation invokes an eralier definition (see above).");
+ WX("\\obeyspaces");
+ WX("%");
+ WX("% Interparagraph skips do not help the cause.");
+ WX("% Note: We have to preserve the indentation though, as the code is actually");
+ WX("% indented in the final output. See \\fwodef in an earlier section.");
+ WX("\\parskip=0pt%");
+ WX("%");
+ WX("% We typeset the verbatim text in tt font (courier on the Macintosh) for a");
+ WX("% number of reasons:");
+ WX("% - tt font has the same horizontal spacing for each character.");
+ WX("% - tt font covers the ASCII character set.");
+ WX("% - tt font doesn't have many surprises (e.g. ligatures).");
+ WX("% - tt font looks much what you might see on a computer terminal screen.");
+ WX("\\tt%");
+ WX("%");
+ WX("% Having set up an environment for verbatim, we are ready to use it.");
+ WX("% By invoking \\fwverbatimgobble, this \\fwbtx macro gobbles up text verbatim (as");
+ WX("% part of the parameter of \\fwverbatimgobble) until it sees the termination");
+ WX("% string \"]fwetx=\" (the \"=\" was thrown in to add obscurity as this sequence");
+ WX("% must never occur in the verbatim text).");
+ WX("\\fwverbatimgobble}");
+ WX("");
+ WX("% The \\fwverbatimgobble macro exists to allow \\fwbtx to bracket verbatim text.");
+ WX("\\def\\fwverbatimgobble#1]fwetx={#1\\endgroup}");
+ WX("");
+ WX("");
+ WX("% Table of Contents");
+ WX("% -----------------");
+ WX("% The five levels of table of contents that FunnelWeb supports are identified");
+ WX("% by the five letters [A..E]. These are used throughout the following macros.");
+ WX("");
+ WX("% The following macros are utilities to the TOC macros to follow.");
+ WX("\\def\\fwrule{\\medskip\\hrule\\medskip}");
+ WX("\\def\\fwqh{\\hskip1.5em\\relax}");
+ WX("\\def\\fwbeforesec{\\penalty-200\\bigskip\\medskip\\par}");
+ WX("");
+ WX("% The following macros are used to typeset the table of contents.");
+ WX("\\def\\fwtocstart#1{\\fwrule\\leftline{\\fwfontbolda Table of Contents}\\fwrule}");
+ WX("\\def\\fwtoca#1#2{\\leftline{{\\bf #1 #2}}}");
+ WX("\\def\\fwtocb#1#2{\\leftline{\\fwqh #1 #2}}");
+ WX("\\def\\fwtocc#1#2{\\leftline{\\fwqh\\fwqh #1 #2}}");
+ WX("\\def\\fwtocd#1#2{\\leftline{\\fwqh\\fwqh\\fwqh #1 #2}}");
+ WX("\\def\\fwtoce#1#2{\\leftline{\\fwqh\\fwqh\\fwqh\\fwqh #1 #2}}");
+ WX("\\def\\fwtocfinish#1{\\fwrule}");
+ WX("");
+ WX("% The following \"library\" macros define five different strengths of headings");
+ WX("% which can be used later in the section macros.");
+ WX("\\def\\fwliba#1#2{\\vfill\\eject{\\fwfontboldc #1 #2}\\penalty200\\smallskip}");
+ WX("\\def\\fwlibb#1#2{\\fwbeforesec{\\fwfontboldb #1 #2}\\penalty200\\smallskip}");
+ WX("\\def\\fwlibc#1#2{\\fwbeforesec{\\fwfontnormb #1 #2}\\penalty200\\smallskip}");
+ WX("\\def\\fwlibd#1#2{\\fwbeforesec{\\bf #1 #2}\\penalty200}");
+ WX("\\def\\fwlibe#1#2{\\fwbeforesec{\\bf #1 #2}}");
+ WX("");
+ WX("% Here are the macros that actually typeset the section headings throughout");
+ WX("% the document. The fwlib system has been employed so as to easily allow the");
+ WX("% user to redefine the strengths of headings to taste. For example, the");
+ WX("% user could insert in the input document a similar set of definitions to these");
+ WX("% but with the b..e headings set to \\fwlibc. This would tone down the output.");
+ WX("\\def\\fwseca#1#2{\\fwliba{#1}{#2}}");
+ WX("\\def\\fwsecb#1#2{\\fwlibb{#1}{#2}}");
+ WX("\\def\\fwsecc#1#2{\\fwlibc{#1}{#2}}");
+ WX("\\def\\fwsecd#1#2{\\fwlibd{#1}{#2}}");
+ WX("\\def\\fwsece#1#2{\\fwlibe{#1}{#2}}");
+ WX("");
+ WX("");
+ WX("% Support for Explicit Typesetting");
+ WX("% --------------------------------");
+ WX("% FunnelWeb supports pragmas and other constructs that allow");
+ WX("% typesetter-independent typesetting commands to be given. The");
+ WX("% following macros support these features.");
+ WX("");
+ WX("% The in-text literal @{sloth@} and emphasise @[walrus@] features.");
+ WX("\\def\\fwlit#1{{\\tt #1}}");
+ WX("\\def\\fwemp#1{{\\it #1}}");
+ WX("");
+ WX("% The \"@p new_page\" pragma.");
+ WX("\\def\\fwnewpage{\\vfill\\eject}");
+ WX("");
+ WX("% The \"@p vskip Nmm\" pragma.");
+ WX("\\def\\fwvskip#1{\\null\\vskip #1mm}");
+ WX("");
+ WX("% The \"@p title <font> <align> <text>\" pragma.");
+ WX("\\def\\fwfontnormal#1{{\\fwfontnorm {#1}}}");
+ WX("\\def\\fwfonttitle#1{{\\fwfontboldd {#1}}}");
+ WX("\\def\\fwfontsmalltitle#1{{\\fwfontboldb {#1}}}");
+ WX("\\def\\fwleftline#1{\\leftline{#1}}");
+ WX("\\def\\fwcenterline#1{\\centerline{#1}}");
+ WX("\\def\\fwrightline#1{\\rightline{#1}}");
+ WX("");
+ WX("");
+ WX("% Support for Old FunnelWeb");
+ WX("% -------------------------");
+ WX("% The following macros were used extensively in the first version of");
+ WX("% FunnelWeb and are retained so that these older input files will still");
+ WX("% typeset cleanly.");
+ WX("\\def\\p#1{{\\tt #1}} % P for Program text.");
+ WX("\\def\\flagpage#1#2{");
+ WX(" \\null");
+ WX(" \\vfill");
+ WX(" \\centerline{\\fwfontboldd #1}");
+ WX(" \\vskip 1cm");
+ WX(" \\centerline{\\fwfontboldd #2}");
+ WX(" \\vfill");
+ WX(" \\null");
+ WX(" \\vfill");
+ WX("}");
+ WX("");
+ WX("%====================== End of FunnelWeb TeX Definitions =======================");
diff --git a/web/funnelAC/fwACsrc/texhead.h b/web/funnelAC/fwACsrc/texhead.h
new file mode 100644
index 0000000000..cc5c31fcd9
--- /dev/null
+++ b/web/funnelAC/fwACsrc/texhead.h
@@ -0,0 +1,125 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* TEXHEAD.H */
+/******************************************************************************/
+/* */
+/* TEX HEADER PACKAGE */
+/* ================== */
+/* This package contains a single function that writes the TeX header */
+/* (containing all the Weave macros) to the specified stream. The package */
+/* consists of: */
+/* */
+/* texhead.tex - The header file ("source code" for texhead.ctx). */
+/* texhead.ctx - C code automatically generated by texhead.tex. */
+/* texhead.h - This file, containing a function definition. */
+/* texhead.c - Contains a function body. */
+/* */
+/* The first version of FunnelWeb (1986) generated TeX output files that used */
+/* a collection of macros to neaten and simplify the bulk of the TeX output */
+/* file. For example, the macro \fwbtx provided a simple way to specify */
+/* verbatim text. This system worked extremely well, the only inconvenience */
+/* being that each FunnelWeb TeX output file had to "\input" the TeX header */
+/* file containing all the macros. At the time, this seemed a sensible */
+/* factorization of the macros, and, within the limited environment in which */
+/* FunnelWeb was operating, worked well. */
+/* */
+/* In NEW, IMPROVED FunnelWeb, "\input"ing the header file has the potential */
+/* to cause lots of problems, the major ones being: */
+/* */
+/* - The header file would have to be installed as part of the FunnelWeb */
+/* system. Currently this means that it would be the ONLY other file */
+/* necessary apart from the FunnelWeb executable. It would be far more */
+/* desirable to avoid having to install the header file. */
+/* */
+/* - The header file would have to be referred to somehow by the TeX file. */
+/* As it makes sense to have only one copy of the header file on a machine, */
+/* TeX files would have to refer to that copy. This would require one of a */
+/* number of messy machine-specific mechanisms such as (VMS) logical name */
+/* translation or environment variable translation. */
+/* */
+/* - TeX files could not be easily moved to other machines (particularly */
+/* those not running FunnelWeb themselves) without also sending the header */
+/* file. */
+/* */
+/* - If FunnelWeb and the header file were ever jointly modified, the dynamic */
+/* binding of old TeX files would mean that they may no longer be printable.*/
+/* */
+/* For all these reasons, the decision was made to write the library of TeX */
+/* macros at the start of each TeX output file, thus making each TeX output */
+/* file entirely self-contained. To do this, the header file had to be */
+/* converted into a sequence of C output statments. To this end, a new */
+/* FunnelWeb shell command CODIFY was added that performs this transformation.*/
+/* CODIFY could have been a separate utility program, but if it was, it might */
+/* somehow be separated from the rest of FunnelWeb during distribution. By */
+/* building CODIFY into FunnelWeb itself, this possibility is eliminated. */
+/* */
+/* This package encapsulates the automatically generated C code. This header */
+/* file defines a function that writes it to a specified stream. The package */
+/* body texhead.c contains the body of the function which consists mainly of */
+/* a #include of the automatically generated C code in texhead.ctx. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_TEXH
+#define DONE_TEXH
+
+/******************************************************************************/
+
+/* Define NO_HEADER to suppress inclusion of the FunnelWeb tex header
+ (for users of the LaTeX include file 'fw-latex.sty' who wish must
+ define a document style such as '\documentstyle[fw-latex]{report}'). */
+
+#include "style.h"
+
+#include "writfile.h"
+
+/******************************************************************************/
+
+EXPORT void tex_head P_((p_wf_t));
+/* Writes the FunnelWeb TeX header block to the argument stream. */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of TEXHEAD.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/texhead.tex b/web/funnelAC/fwACsrc/texhead.tex
new file mode 100644
index 0000000000..0109a04fb0
--- /dev/null
+++ b/web/funnelAC/fwACsrc/texhead.tex
@@ -0,0 +1,320 @@
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
diff --git a/web/funnelAC/fwACsrc/weave.c b/web/funnelAC/fwACsrc/weave.c
new file mode 100644
index 0000000000..f530285dc2
--- /dev/null
+++ b/web/funnelAC/fwACsrc/weave.c
@@ -0,0 +1,2330 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 31-Aug-1993 ABC Added support for EL_SPEC
+ 11-Jan-1994 ABC Added MAXINV which defines the maximum
+ number of macro invocation citations
+ which should be put on the one TeX line.
+ 15-Apr-1994 ABC Added hypertext typesetter types
+ TR_HTXT and TR_HTML, which are to HTML hypertext
+ what TR_NONE and TR_TEX are to TeX respectively.
+ 15-Apr-1994 ABC Added doc_incQ flag for inclusion or not of
+ FunnelWeb TeX/HTML header. If FALSE, also
+ suppresses the "\bye" at the end of TeX files
+ and the <HTML>...</HTML> markup surrounding
+ HTML files.
+ 20-May-1994 ABC Added raw_namQ flag for allowing or not of
+ raw TeX/HTML in macro/section names
+ (TR_TEX or TR_HTML modes only).
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* WEAVE.C */
+/******************************************************************************/
+
+#include <ctype.h>
+#include "style.h"
+
+#include "as.h"
+#include "data.h"
+#include "lister.h"
+#include "machin.h"
+#include "misc.h"
+#include "table.h"
+#include "texhead.h"
+/* ABC { */
+#include "htmlhead.h"
+/* } ABC */
+#include "weave.h"
+
+/* ABC { */
+/* MAXINV is the maximum number of macro invocation references */
+/* that should be put on one TeX line */
+/* This stops line to big for the TeX buffer from being created. */
+#define MAXINV 20
+/* } ABC */
+
+/* IMPORTANT WARNING: The Macintosh THINK C compiler sets up strings that */
+/* start with \p or \P as PASCAL strings rather than C strings. So be very */
+/* careful not to start any strings with \p or \P. */
+
+/******************************************************************************/
+
+LOCVAR wf_t f_t; /* Variable representing documentation file. */
+LOCVAR bool literal; /* True if we are inside a literal @{. */
+/* ABC { */
+LOCVAR bool title1Q; /* True if a title is the first for the document. */
+LOCVAR bool lastEOLQ; /* last written text scrap finished with EOL? */
+/* } ABC */
+
+/******************************************************************************/
+
+LOCAL void wv_ex P_((p_ells_t));
+
+/******************************************************************************/
+
+LOCAL char * fn_nodir P_((char *));
+LOCAL char * fn_nodir (p)
+/* Given a pointer to a string, returns a pointer to the character just past */
+/* the last occurrance of FN_DELIM, or a pointer to the start of the string */
+/* if it does not occur. In other words, given a filename, return a pointer */
+/* to the start of the name field. */
+char *p;
+{
+ char *q = strrchr(p,FN_DELIM);
+ if (q==NULL)
+ return p;
+ else
+ return q+1;
+}
+
+/******************************************************************************/
+
+LOCAL void wf_dec P_((p_wf_t,ulong));
+LOCAL void wf_dec(p_wf,n)
+/* Writes the unsigned number n to the specified output stream as a decimal. */
+/* This function has been named wf_dec so that it can be moved to the wf */
+/* package if it turns out to be popular. */
+p_wf_t p_wf;
+ulong n;
+{
+ char t[20];
+ sprintf(t,"%lu",n);
+ wf_wr(p_wf,t);
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txugch P_((int));
+LOCAL void wv_txugch(ch)
+/* WeaVe TeX UGly CHaracter. */
+/* } ABC */
+/* Sometimes it is necessary to output text without causing the typesetting */
+/* program (TeX) to interpret it as control sequences and generate errors. */
+/* There are two ways of doing this. First, we can get the typesetter to do */
+/* the work by making it less sensitive. This has been done with the */
+/* typesetting of the main macro text. The other approach is to convert each */
+/* offending character into the typesetter control sequence that will simply */
+/* output the character. For example, in TeX, "$" becomes "\$". This function */
+/* accepts a single character and writes out its safe equivalent. */
+/* The term "ugly" is used to describe potentially harmful text/characters. */
+int ch;
+{
+ /* End of lines are the only non-printable allowed. */
+ if (ch==EOL) {wf_chr(&f_t,EOL); return;}
+
+ /* All other non-printables result in a bullet. In the absence of bugs, the */
+ /* only way a non-printable can get to us here is as a result of the user */
+ /* explicitly inserting one using the scanner's @^ control sequence. */
+ if (!isascprn(ch))
+ {
+ wf_wr(&f_t,"$\\bullet$");
+ return;
+ }
+ /* If it IS printable, then print it ... carefully! */
+ switch (ch)
+ {
+ /* Go through the printables in ASCII order. */
+ /* ' ': is an ordinary character. */
+ /* '!': is an ordinary character. */
+ case '\"': wf_wr(&f_t,"\\char`\\\""); break;
+ case '#': wf_wr(&f_t,"\\#"); break;
+ case '$': wf_wr(&f_t,"\\$"); break;
+ /* Note: The string "\\%" triggers a unknown sequence "\%" in GNUC. */
+ case '%': wf_chr(&f_t,'\\'); wf_chr(&f_t,'%'); break;
+ case '&': wf_wr(&f_t,"\\&"); break;
+ /* ''': is an ordinary character. */
+ /* '(': is an ordinary character. */
+ /* ')': is an ordinary character. */
+ /* '*': is an ordinary character. */
+ /* '+': is an ordinary character. */
+ /* ',': is an ordinary character. */
+ /* '-': is an ordinary character. */
+ /* '.': is an ordinary character. */
+ /* '/': is an ordinary character. */
+ /* '0-9': are ordinary characters.*/
+ /* ':': is an ordinary character. */
+ /* ';': is an ordinary character. */
+ /* Note: Some \chars work well in roman. Others don't. */
+ case '<': if (literal)
+ wf_wr(&f_t,"\\char`\\<");
+ else
+ wf_wr(&f_t,"$<$");
+ break;
+ /* '=': is an ordinary character. */
+ case '>': if (literal)
+ wf_wr(&f_t,"\\char`\\>");
+ else
+ wf_wr(&f_t,"$>$");
+ break;
+ /* '?': is an ordinary character. */
+ /* '@': is an ordinary character. */
+ /* 'A-Z': are ordinary characters.*/
+ /* '[': is an ordinary character. */
+ case '\\': if (literal)
+ wf_wr(&f_t,"\\char`\\\\");
+ else
+ wf_wr(&f_t,"$\\backslash$");
+ break;
+ /* ']': is an ordinary character. */
+ case '^': wf_wr(&f_t,"\\char`\\^"); break;
+ case '_': wf_wr(&f_t,"\\_"); break;
+ /* '`': is an ordinary character. */
+ /* 'a-z': are ordinary characters.*/
+ case '{': if (literal)
+ wf_wr(&f_t,"\\char`\\{");
+ else
+ wf_wr(&f_t,"$\\{$");
+ break;
+ case '|': if (literal)
+ wf_wr(&f_t,"\\char`\\|");
+ else
+ wf_wr(&f_t,"$|$");
+ break;
+ case '}': if (literal)
+ wf_wr(&f_t,"\\char`\\}");
+ else
+ wf_wr(&f_t,"$\\}$");
+ break;
+ case '~': wf_wr(&f_t,"\\char`\\~"); break;
+ default: wf_chr(&f_t,ch); break;
+ }
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htugch P_((int));
+LOCAL void wv_htugch(ch)
+/* WeaVe HTml UGly CHaracter. */
+/* Sometimes it is necessary to output text without causing the typesetting */
+/* program (HTML displayer) to interpret it as control sequences and generate */
+/* errors. */
+/* There are two ways of doing this. First, we can get the typesetter to do */
+/* the work by making it less sensitive. This has been done with the */
+/* typesetting of the main macro text. The other approach is to convert each */
+/* offending character into the typesetter control sequence that will simply */
+/* output the character. For example, in HTML, "<" becomes "&lt;". This */
+/* function accepts a single character and writes out its safe equivalent. */
+/* The term "ugly" is used to describe potentially harmful text/characters. */
+int ch;
+{
+ /* End of lines are the only non-printable allowed. */
+ if (ch==EOL) {wf_chr(&f_t,EOL); return;}
+
+ /* All other non-printables result in an inverted question mark. In the */
+ /* absence of bugs, the only way a non-printable can get to us here is as a */
+ /* result of the user explicitly inserting one using the scanner's @^ */
+ /* control sequence. */
+ if (!isascprn(ch))
+ {
+ wf_wr(&f_t,"&#191;"); /* inverted question mark */
+ return;
+ }
+ /* If it IS printable, then print it ... carefully! */
+ switch (ch)
+ {
+ /* Go through the printables in ASCII order. */
+ /* ' ': is an ordinary character. */
+ /* '!': is an ordinary character. */
+ /* '\"': is an ordinary character. */
+ /* '#': is an ordinary character. */
+ /* '$': is an ordinary character. */
+ /* '%': is an ordinary character. */
+ case '&': wf_wr(&f_t,"&amp;");
+ break;
+ /* ''': is an ordinary character. */
+ /* '(': is an ordinary character. */
+ /* ')': is an ordinary character. */
+ /* '*': is an ordinary character. */
+ /* '+': is an ordinary character. */
+ /* ',': is an ordinary character. */
+ /* '-': is an ordinary character. */
+ /* '.': is an ordinary character. */
+ /* '/': is an ordinary character. */
+ /* '0-9': are ordinary characters.*/
+ /* ':': is an ordinary character. */
+ /* ';': is an ordinary character. */
+ case '<': wf_wr(&f_t,"&lt;");
+ break;
+ /* '=': is an ordinary character. */
+ case '>': wf_wr(&f_t,"&gt;");
+ break;
+ /* '?': is an ordinary character. */
+ /* '@': is an ordinary character. */
+ /* 'A-Z': are ordinary characters.*/
+ /* '[': is an ordinary character. */
+ /* '\\': is an ordinary character. */
+ /* ']': is an ordinary character. */
+ /* '^': is an ordinary character. */
+ /* '_': is an ordinary character. */
+ /* '`': is an ordinary character. */
+ /* 'a-z': are ordinary characters.*/
+ /* '{': is an ordinary character. */
+ /* '|': is an ordinary character. */
+ /* '}': is an ordinary character. */
+ /* '~': is an ordinary character. */
+ default: wf_chr(&f_t,ch); break;
+ }
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_ugch P_((int));
+LOCAL void wv_ugch(ch)
+/* WeaVe TeX UGly CHaracter. */
+/* Selects either the TeX or HTML ugly character pre-processing function. */
+int ch;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txugch(ch); break;
+ case TR_HTXT :
+ case TR_HTML : wv_htugch(ch); break;
+ default : as_bomb("wv_ugch:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+LOCAL void wv_ugstr P_((char *));
+LOCAL void wv_ugstr(s)
+/* Writes out a potentially ugly string. */
+char *s;
+{
+ while (*s != EOS)
+ wv_ugch(*s++);
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txugsc P_((p_sc_t));
+LOCAL void wv_txugsc(p_sc)
+/* } ABC */
+/* Writes out a potentially ugly TeX text scrap. */
+p_sc_t p_sc;
+{
+ char *p = p_sc->sc_first;
+ char *p_last = p_sc->sc_last;
+
+ while (p<=p_last)
+ wv_ugch(*p++);
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htugsc P_((p_sc_t));
+LOCAL void wv_htugsc(p_sc)
+/* Writes out a potentially ugly HTML text scrap. */
+/* This is where paragraph (<P>) markups may be added for */
+/* hypertext mode wherever groups of contiguous blank */
+/* lines are left in the text (not inside macros). */
+p_sc_t p_sc;
+{
+ char *p_first = p_sc->sc_first;
+ char *p_last = p_sc->sc_last;
+ char *p = p_first;
+
+ if (no_pmrkQ) {
+ while (p<=p_last) wv_ugch(*p++);
+ } else {
+ if ((f_t.wf_last == EOL) && (*p == EOL)) {
+ /* if two EOLs in a row are found, it signals */
+ /* the start of a new HTML paragraph */
+ wf_wl(&f_t, "<P>");
+ /* scan past further EOLs in a row */
+ while ((*(++p) == EOL) && (p <= p_last));
+ } /* end if */
+ while (p<=p_last) {
+ /* if two EOLs in a row are found, it signals */
+ /* the start of a new HTML paragraph */
+ if ((*p == EOL) && (p != p_first) && (*(p-1) == EOL)) {
+ wf_wl(&f_t, "<P>");
+ /* scan past further EOLs in a row */
+ while ((*(++p) == EOL) && (p <= p_last));
+ } else {
+ wv_ugch(*p++);
+ } /* end if */
+ } /* end while */
+ } /* end if */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htsc P_((p_sc_t));
+LOCAL void wv_htsc(p_sc)
+/* Writes out a potentially ugly HTML text code scrap. */
+/* This function does not insert paragraph markups. */
+p_sc_t p_sc;
+{
+ char *p_first = p_sc->sc_first;
+ char *p_last = p_sc->sc_last;
+ char *p = p_first;
+
+ while (p<=p_last) wv_ugch(*p++);
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_ugsc P_((p_sc_t));
+LOCAL void wv_ugsc(p_sc)
+/* Writes out a potentially ugly text scrap. */
+p_sc_t p_sc;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txugsc(p_sc); break;
+ case TR_HTXT :
+ case TR_HTML : wv_htugsc(p_sc); break;
+ default : as_bomb("wv_ugsc:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+LOCAL void wv_ugscls P_((p_scls_t));
+LOCAL void wv_ugscls(p_scls)
+/* This function writes the specified text list to the output stream. It */
+/* writes it cleaning up all ugly characters. */
+p_scls_t p_scls;
+{
+ ls_fir(p_scls);
+ while (TRUE)
+ {
+ p_sc_t p_sc;
+ ls_nxt(p_scls,PPV &p_sc);
+ if (p_sc==NULL) break;
+ wv_ugsc(p_sc);
+ }
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txmanm P_((p_ma_t,ulong));
+LOCAL void wv_txmanm(p_ma,part)
+/* } ABC */
+/* This function writes the specified macro name and no. in TeX. */
+/* The part number is the part to write out. */
+p_ma_t p_ma;
+ulong part;
+{
+ p_bp_t p_bp;
+
+ /* ABC { */
+ if (p_ma->ma_defn.md_isfil) {
+ wf_wr(&f_t,"\\fwfilename{");
+ wv_ugstr(p_ma->ma_name);
+ } else {
+ wf_wr(&f_t,"\\fwmacroname{");
+ if (raw_namQ && (tr_codes==TR_TEX)) {
+ wf_wr(&f_t,p_ma->ma_name);
+ } else {
+ wv_ugstr(p_ma->ma_name);
+ } /* end if */
+ } /* end if */
+ /* } ABC */
+ wf_wr(&f_t,"}{");
+ ls_loo(p_ma->ma_defn.md_body,part,PPV &p_bp);
+ wf_dec(&f_t,(ulong) p_bp->bp_seq);
+ wf_wr(&f_t,"}");
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htmanm P_((p_ma_t,ulong));
+LOCAL void wv_htmanm(p_ma,part)
+/* This function writes the specified macro name and no. in HTML. */
+/* The part number is the part to write out. */
+p_ma_t p_ma;
+ulong part;
+{
+ p_bp_t p_bp;
+
+ if (p_ma->ma_defn.md_isfil) {
+ wf_wr(&f_t,"<STRONG>");
+ wv_ugstr(p_ma->ma_name);
+ } else {
+ wf_wr(&f_t,"<CITE>");
+ if (raw_namQ && (tr_codes==TR_HTML)) {
+ wf_wr(&f_t,p_ma->ma_name);
+ } else {
+ wv_ugstr(p_ma->ma_name);
+ } /* end if */
+ } /* end if */
+ if (p_ma->ma_defn.md_isfil)
+ wf_wr(&f_t,"</STRONG>");
+ else
+ wf_wr(&f_t,"</CITE>");
+ wf_wr(&f_t,"[");
+ ls_loo(p_ma->ma_defn.md_body,part,PPV &p_bp);
+ wf_dec(&f_t,(ulong) p_bp->bp_seq);
+ wf_wr(&f_t,"]");
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_manm P_((p_ma_t,ulong));
+LOCAL void wv_manm(p_ma,part)
+/* This function writes the specified macro name and no. */
+/* The part number is the part to write out. */
+p_ma_t p_ma;
+ulong part;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txmanm(p_ma,part); break;
+ case TR_HTXT :
+ case TR_HTML : wv_htmanm(p_ma,part); break;
+ default : as_bomb("wv_manm:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_mano P_((p_ma_t,ulong));
+LOCAL void wv_mano(p_ma,part)
+/* This function writes the specified macro no. */
+/* The part number is the part to write out. */
+p_ma_t p_ma;
+ulong part;
+{
+ p_bp_t p_bp;
+
+ ls_loo(p_ma->ma_defn.md_body,part,PPV &p_bp);
+ wf_dec(&f_t,(ulong) p_bp->bp_seq);
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txsecnn P_((p_ty_t));
+LOCAL void wv_txsecnn(p_ty)
+/* } ABC */
+/* Write out the section number and name, each in curly braces. */
+p_ty_t p_ty;
+{
+ /* Write as arguments the section number and name. */
+ wf_chr(&f_t,'{');
+ sn_str(&p_ty->ty_sn,linet1);
+ wf_wr(&f_t,linet1);
+ wf_wr(&f_t,"}{");
+ /* ABC { */
+ if (raw_namQ && (tr_codes==TR_TEX)) {
+ wf_wr(&f_t,p_ty->ty_name);
+ } else {
+ wv_ugstr(p_ty->ty_name);
+ } /* end if */
+ /* } ABC */
+ wf_chr(&f_t,'}');
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htsecnn P_((p_ty_t));
+LOCAL void wv_htsecnn(p_ty)
+/* Write out the section number and name. */
+p_ty_t p_ty;
+{
+ /* Write as arguments the section number and name. */
+ sn_str(&p_ty->ty_sn,linet1);
+ wf_wr(&f_t,linet1);
+ wf_wr(&f_t," ");
+ /* ABC { */
+ if (raw_namQ && (tr_codes==TR_HTML)) {
+ wf_wr(&f_t,p_ty->ty_name);
+ } else {
+ wv_ugstr(p_ty->ty_name);
+ } /* end if */
+ /* } ABC */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_secnn P_((p_ty_t));
+LOCAL void wv_secnn(p_ty)
+/* Write out the section number and name. */
+p_ty_t p_ty;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txsecnn(p_ty); break;
+ case TR_HTXT :
+ case TR_HTML : wv_htsecnn(p_ty); break;
+ default : as_bomb("wv_secnn:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txecho P_((p_scls_t));
+LOCAL void wv_txecho(p_scls)
+/* This function writes the specified text list to the output stream. It */
+/* writes it just as it is, with no modifications whatsoever. */
+p_scls_t p_scls;
+{
+ ls_fir(p_scls);
+ while (TRUE)
+ {
+ p_sc_t p_sc;
+ ls_nxt(p_scls,PPV &p_sc);
+ if (p_sc==NULL) break;
+ wf_blk(&f_t,p_sc->sc_first,(size_t)
+ (p_sc->sc_last-p_sc->sc_first+1));
+ }
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htecho P_((p_scls_t));
+LOCAL void wv_htecho(p_scls)
+/* This function writes the specified text list to the output stream. It */
+/* writes it just as it is, except that '<' --> "&lt;" and '>' --> "&gt;" */
+/* and '&' --> "&amp;". */
+p_scls_t p_scls;
+{
+ ls_fir(p_scls);
+ while (TRUE)
+ {
+ p_sc_t p_sc;
+ ls_nxt(p_scls,PPV &p_sc);
+ if (p_sc==NULL) break;
+ wv_htsc(p_sc);
+ }
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+/* This function writes the specified text list to the output stream. It */
+/* writes it just as it is, changing as few characters as possible . */
+LOCAL void wv_echo P_((p_scls_t));
+LOCAL void wv_echo(p_scls)
+p_scls_t p_scls;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txecho(p_scls); break;
+ case TR_HTXT :
+ case TR_HTML : wv_htecho(p_scls); break;
+ default : as_bomb("wv_echo:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txverb P_((p_scls_t));
+LOCAL void wv_txverb(p_scls)
+/* } ABC */
+/* Writes a TeX text list verbetim, but brackets it with sequences that */
+/* instruct the typesetter not to interpret the text in any special way. */
+p_scls_t p_scls;
+{
+ if (ls_len(p_scls) > 0)
+ {
+ wf_wr(&f_t,"\\fwbtx[");
+ wv_echo(p_scls);
+ wf_wl(&f_t,"]fwetx=%");
+ }
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htverb P_((p_scls_t));
+LOCAL void wv_htverb(p_scls)
+/* } ABC */
+/* Writes an HTML text list verbetim, but brackets it with sequences that */
+/* instruct the typesetter not to interpret the text in any special way. */
+p_scls_t p_scls;
+{
+ if (ls_len(p_scls) > 0)
+ {
+ wf_wr(&f_t,"<CODE>");
+ wv_echo(p_scls);
+ wf_wr(&f_t,"</CODE>");
+ }
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_verb P_((p_scls_t));
+LOCAL void wv_verb(p_scls)
+/* } ABC */
+/* Writes a text list verbetim, but brackets it with sequences that */
+/* instruct the typesetter not to interpret the text in any special way. */
+p_scls_t p_scls;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txverb(p_scls); break;
+ case TR_HTXT :
+ case TR_HTML : wv_htverb(p_scls); break;
+ default : as_bomb("wv_verb:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txhead P_((void));
+LOCAL void wv_txhead()
+/* } ABC */
+{
+ wf_wl(&f_t,"");
+ wf_wl(&f_t,"%*******************************************************************************");
+ wf_wl(&f_t,"%* START OF AUTOMATICALLY GENERATED TEX FILE *");
+ wf_wl(&f_t,"%*******************************************************************************");
+ wf_wl(&f_t,"%* *");
+ wf_wl(&f_t,"%* This TeX file was automatically generated by the FunnelWeb preprocessor. *");
+ wf_wl(&f_t,"%* You can typeset this file to produce printed documentation by running it *");
+ wf_wl(&f_t,"%* through the TeX typesetter using a command such as: *");
+ /* ABC { */
+ if (doc_incQ) {
+ wf_wl(&f_t,"%* tex thisfilename *");
+ } else {
+ wf_wl(&f_t,"%* latex thisfilename *");
+ wf_wl(&f_t,"%* (the standard TeX header was not included, due to the presence of a *");
+ wf_wl(&f_t,"%* `@p no_doc_header' pragma in the original FunnelWeb source file. *");
+ wf_wl(&f_t,"%* It is hence assumed that the FunnelWeb code was in the form of a LaTeX *");
+ wf_wl(&f_t,"%* file starting with a line of the form *");
+ wf_wl(&f_t,"%* \\documentstyle[fw-latex,...]{...} *");
+ wf_wl(&f_t,"%* If not, don't blame FunnelWeb for the resulting TeX or LaTeX errors ... *");
+ wf_wl(&f_t,"%* The file `fw-latex.sty' can be found at the ftp archive noted below.) *");
+ } /* end if */
+ /* } ABC */
+ wf_wl(&f_t,"%* The resultant file thisfilename.dvi can be printed using a command such as: *");
+ wf_wl(&f_t,"%* lpr -Pcslw -d thisfilename.dvi *");
+ wf_wl(&f_t,"%* *");
+ wf_wl(&f_t,"%* FunnelWeb is a preprocessor that allows programmers to weave programs and *");
+ wf_wl(&f_t,"%* their documentation together in a single document. The FunnelWeb program *");
+ wf_wl(&f_t,"%* analyses such documents producing both program files and typeset *");
+ wf_wl(&f_t,"%* documentation such as this TeX file. *");
+ wf_wl(&f_t,"%* FunnelWeb was created by Ross Williams. *");
+ wf_wl(&f_t,"%* *");
+ wf_wl(&f_t,"%* For more information on FunnelWeb look in the following FTP archive: *");
+ wf_wl(&f_t,"%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *");
+ wf_wl(&f_t,"%* Directory: ~pub/funnelweb/ *");
+ wf_wl(&f_t,"%* (or some other appropriately named directory). *");
+ wf_wl(&f_t,"%* or email Ross Williams at ross@spam.adelaide.edu.au *");
+ if (!doc_incQ) {
+ wf_wl(&f_t,"%* (Tony Coates at coates@physics.uq.edu.au for pragma `no_doc_header') *");
+ } /* end if */
+ if (raw_namQ) {
+ wf_wl(&f_t,"%* (Tony Coates at coates@physics.uq.edu.au for pragma `raw_macro_and_section_names') *");
+ } /* end if */
+ wf_wl(&f_t,"%* *");
+ wf_wl(&f_t,"%*******************************************************************************");
+ wf_wl(&f_t,"");
+ wf_wl(&f_t,"");
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_hthead P_((void));
+LOCAL void wv_hthead()
+{
+ wf_wl(&f_t,"");
+ wf_wl(&f_t,"<!--*************************************************************************-->");
+ wf_wl(&f_t,"<!-- START OF AUTOMATICALLY GENERATED HTML FILE -->");
+ wf_wl(&f_t,"<!--*************************************************************************-->");
+ wf_wl(&f_t,"<!-- -->");
+ wf_wl(&f_t,"<!--This HTML file was automatically generated by the FunnelWeb preprocessor.-->");
+ wf_wl(&f_t,"<!--You can view this file using an HTML viewer such as `Mosaic'. -->");
+ wf_wl(&f_t,"<!--FunnelWeb is a preprocessor that allows programmers to weave programs and-->");
+ wf_wl(&f_t,"<!--their documentation together in a single document. The FunnelWeb program -->");
+ wf_wl(&f_t,"<!--analyses such documents producing both program files and typeset -->");
+ wf_wl(&f_t,"<!--documentation such as this HTML file. -->");
+ wf_wl(&f_t,"<!--FunnelWeb was created by Ross Williams. -->");
+ wf_wl(&f_t,"<!-- -->");
+ wf_wl(&f_t,"<!--For more information on FunnelWeb look in the following FTP archive: -->");
+ wf_wl(&f_t,"<!-- Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. -->");
+ wf_wl(&f_t,"<!-- Directory: ~pub/funnelweb/ -->");
+ wf_wl(&f_t,"<!-- (or some other appropriately named directory). -->");
+ wf_wl(&f_t,"<!--or email Ross Williams at ross@spam.adelaide.edu.au -->");
+ wf_wl(&f_t,"<!-- (Tony Coates at coates@physics.uq.edu.au for HTML support) -->");
+ wf_wl(&f_t,"<!-- -->");
+ wf_wl(&f_t,"<!--*************************************************************************-->");
+ wf_wl(&f_t,"");
+ wf_wl(&f_t,"");
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_head P_((void));
+LOCAL void wv_head()
+{
+ if ((tr_codes==TR_HTXT) || (tr_codes==TR_HTML)) wv_hthead();
+ else wv_txhead();
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txtail P_((void));
+LOCAL void wv_txtail()
+/* } ABC */
+{
+ wf_wl(&f_t,"");
+ wf_wl(&f_t,"");
+ wf_wl(&f_t,"%*******************************************************************************");
+ wf_wl(&f_t,"%* END OF AUTOMATICALLY GENERATED TEX FILE *");
+ wf_wl(&f_t,"%*******************************************************************************");
+ wf_wl(&f_t,"");
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_httail P_((void));
+LOCAL void wv_httail()
+{
+ wf_wl(&f_t,"");
+ wf_wl(&f_t,"");
+ wf_wl(&f_t,"<!--*************************************************************************-->");
+ wf_wl(&f_t,"<!-- END OF AUTOMATICALLY GENERATED HTML FILE -->");
+ wf_wl(&f_t,"<!--*************************************************************************-->");
+ wf_wl(&f_t,"");
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_tail P_((void));
+LOCAL void wv_tail()
+{
+ if ((tr_codes==TR_HTXT) || (tr_codes==TR_HTML)) wv_httail();
+ else wv_txtail();
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txnsec P_((p_ty_t));
+LOCAL void wv_txnsec(p_ty)
+/* } ABC */
+/* Weaves the start of a new TeX section. */
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_NSEC,"wv_txnsec: Not a section!");
+
+ /* Work out what kind of section macro should be used. */
+ switch (sn_lev(&p_ty->ty_sn))
+ {
+ case 1: wf_wr(&f_t,"\\fwseca"); break;
+ case 2: wf_wr(&f_t,"\\fwsecb"); break;
+ case 3: wf_wr(&f_t,"\\fwsecc"); break;
+ case 4: wf_wr(&f_t,"\\fwsecd"); break;
+ case 5: wf_wr(&f_t,"\\fwsece"); break;
+ default: as_bomb("wv_txnsec:case defaulted.");
+ }
+
+ /* Write out the section number and name. */
+ wv_secnn(p_ty);
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htnsec P_((p_ty_t));
+LOCAL void wv_htnsec(p_ty)
+/* Weaves the start of a new HTML section. */
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_NSEC,"wv_htnsec: Not a section!");
+
+ /* Work out what kind of section macro should be used. */
+ switch (sn_lev(&p_ty->ty_sn))
+ {
+ case 1: wf_wr(&f_t,"<H1>"); break;
+ case 2: wf_wr(&f_t,"<H2>"); break;
+ case 3: wf_wr(&f_t,"<H3>"); break;
+ case 4: wf_wr(&f_t,"<H4>"); break;
+ case 5: wf_wr(&f_t,"<H5>"); break;
+ default: as_bomb("wv_htnsec:case defaulted.");
+ }
+
+ /* Write out an HTML anchor, which will be attached to
+ * the index if any
+ */
+ wf_wr(&f_t,"<A NAME=\"");
+ wv_secnn(p_ty);
+ wf_wr(&f_t,"\">");
+
+ /* Write out the section number and name. */
+ wv_secnn(p_ty);
+
+ /* Close anchor */
+ wf_wr(&f_t,"</A>");
+
+ /* Close section heading. */
+ switch (sn_lev(&p_ty->ty_sn))
+ {
+ case 1: wf_wr(&f_t,"</H1>"); break;
+ case 2: wf_wr(&f_t,"</H2>"); break;
+ case 3: wf_wr(&f_t,"</H3>"); break;
+ case 4: wf_wr(&f_t,"</H4>"); break;
+ case 5: wf_wr(&f_t,"</H5>"); break;
+ default: as_bomb("wv_htnsec:case defaulted.");
+ }
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_nsec P_((p_ty_t));
+LOCAL void wv_nsec(p_ty)
+/* Weaves the start of a new section. */
+p_ty_t p_ty;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txnsec(p_ty); break;
+ case TR_HTXT :
+ case TR_HTML : wv_htnsec(p_ty); break;
+ default : as_bomb("wv_nsec:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txolit P_((p_ty_t));
+LOCAL void wv_txolit(p_ty)
+/* } ABC */
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_OLIT,"wv_txolit: Not an open literal!");
+ wf_wr(&f_t,"\\fwlit{");
+ literal=TRUE;
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htolit P_((p_ty_t));
+LOCAL void wv_htolit(p_ty)
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_OLIT,"wv_htolit: Not an open literal!");
+ wf_wr(&f_t,"<CODE>");
+ literal=TRUE;
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_olit P_((p_ty_t));
+LOCAL void wv_olit(p_ty)
+p_ty_t p_ty;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txolit(p_ty); break;
+ case TR_HTXT :
+ case TR_HTML : wv_htolit(p_ty); break;
+ default : as_bomb("wv_olit:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txclit P_((p_ty_t));
+LOCAL void wv_txclit(p_ty)
+/* } ABC */
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_CLIT,"wv_txclit: Not a close literal!");
+ wf_wr(&f_t,"}");
+ literal=FALSE;
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htclit P_((p_ty_t));
+LOCAL void wv_htclit(p_ty)
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_CLIT,"wv_htclit: Not a close literal!");
+ wf_wr(&f_t,"</CODE>");
+ literal=FALSE;
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_clit P_((p_ty_t));
+LOCAL void wv_clit(p_ty)
+p_ty_t p_ty;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txclit(p_ty); break;
+ case TR_HTXT :
+ case TR_HTML : wv_htclit(p_ty); break;
+ default : as_bomb("wv_clit:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txoemp P_((p_ty_t));
+LOCAL void wv_txoemp(p_ty)
+/* } ABC */
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_OEMP,"wv_txoemp: Not an open emphasize!");
+ wf_wr(&f_t,"\\fwemp{");
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htoemp P_((p_ty_t));
+LOCAL void wv_htoemp(p_ty)
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_OEMP,"wv_htoemp: Not an open emphasize!");
+ wf_wr(&f_t,"<EM>");
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_oemp P_((p_ty_t));
+LOCAL void wv_oemp(p_ty)
+p_ty_t p_ty;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txoemp(p_ty); break;
+ case TR_HTXT :
+ case TR_HTML : wv_htoemp(p_ty); break;
+ default : as_bomb("wv_oemp:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txcemp P_((p_ty_t));
+LOCAL void wv_txcemp(p_ty)
+/* } ABC */
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_CEMP,"wv_txcemp: Not a close emphasize!");
+ wf_wr(&f_t,"}");
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htcemp P_((p_ty_t));
+LOCAL void wv_htcemp(p_ty)
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_CEMP,"wv_htcemp: Not a close emphasize!");
+ wf_wr(&f_t,"</EM>");
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_cemp P_((p_ty_t));
+LOCAL void wv_cemp(p_ty)
+p_ty_t p_ty;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txcemp(p_ty); break;
+ case TR_HTXT :
+ case TR_HTML : wv_htcemp(p_ty); break;
+ default : as_bomb("wv_cemp:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txnpag P_((p_ty_t));
+LOCAL void wv_txnpag(p_ty)
+/* } ABC */
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_NPAG,"wv_txnpag: Not a new page!");
+ wf_wl(&f_t,"");
+ wf_wl(&f_t,"\\fwnewpage");
+ wf_wl(&f_t,"");
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htnpag P_((p_ty_t));
+LOCAL void wv_htnpag(p_ty)
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_NPAG,"wv_htnpag: Not a new page!");
+ /* new pages are currently ignored for HTML */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_npag P_((p_ty_t));
+LOCAL void wv_npag(p_ty)
+p_ty_t p_ty;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txnpag(p_ty); break;
+ case TR_HTXT :
+ case TR_HTML : wv_htnpag(p_ty); break;
+ default : as_bomb("wv_npag:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txtocs P_((p_ty_t));
+LOCAL void wv_txtocs(p_ty)
+/* } ABC */
+/* Writes a TeX table of contents to the weave output file. */
+p_ty_t p_ty;
+{
+ /* We need to save the document list position as the rest of the weaver is */
+ /* in the process of traversing it!!! */
+ p_void p_mark = ls_mar(document_list);
+
+ as_cold(p_ty->ty_kind==TY_TOCS,"wv_txtocs: Not a table of contents!");
+
+ wf_wl(&f_t,"");
+ wf_wl(&f_t,"\\fwtocstart{}");
+ ls_fir(document_list);
+ while (TRUE)
+ {
+ p_dc_t p_dc;
+ ls_nxt(document_list,PPV &p_dc);
+ if (p_dc == NULL) break;
+ if (p_dc->dc_kind==DC_TYPE && p_dc->dc_ty.ty_kind==TY_NSEC)
+ {
+ switch(sn_lev(&p_dc->dc_ty.ty_sn))
+ {
+ case 1: wf_wr(&f_t,"\\fwtoca"); break;
+ case 2: wf_wr(&f_t,"\\fwtocb"); break;
+ case 3: wf_wr(&f_t,"\\fwtocc"); break;
+ case 4: wf_wr(&f_t,"\\fwtocd"); break;
+ case 5: wf_wr(&f_t,"\\fwtoce"); break;
+ default: as_bomb("wv_txtocs: switch defaulted.");
+ }
+ wv_secnn(&p_dc->dc_ty);
+ wf_wl(&f_t,"");
+ }
+ }
+ wf_wl(&f_t,"\\fwtocfinish{}");
+ wf_wl(&f_t,"");
+
+ /* Restore the document list position. */
+ ls_set(document_list,p_mark);
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_httocs P_((p_ty_t));
+LOCAL void wv_httocs(p_ty)
+/* Writes a table of contents to the weave output file. */
+p_ty_t p_ty;
+{
+ /* We need to save the document list position as the rest of the weaver is */
+ /* in the process of traversing it!!! */
+ p_void p_mark = ls_mar(document_list);
+
+ as_cold(p_ty->ty_kind==TY_TOCS,"wv_httocs: Not a table of contents!");
+
+ wf_wl(&f_t,"<HR>");
+ wf_wl(&f_t,"<H1>Table of Contents</H1>");
+ wf_wl(&f_t,"<HR>");
+ ls_fir(document_list);
+ while (TRUE)
+ {
+ p_dc_t p_dc;
+ ls_nxt(document_list,PPV &p_dc);
+ if (p_dc == NULL) break;
+ if (p_dc->dc_kind==DC_TYPE && p_dc->dc_ty.ty_kind==TY_NSEC)
+ {
+ switch(sn_lev(&p_dc->dc_ty.ty_sn))
+ {
+ case 1: wf_wr(&f_t,"<H2>"); break;
+ case 2: wf_wr(&f_t,"<H3>"); break;
+ case 3: wf_wr(&f_t,"<H4>"); break;
+ case 4: wf_wr(&f_t,"<H5>"); break;
+ case 5: wf_wr(&f_t,"<H6>"); break;
+ default: as_bomb("wv_httoc: switch defaulted.");
+ }
+ wf_wr(&f_t,"<A HREF=\"#");
+ wv_secnn(&p_dc->dc_ty);
+ wf_wr(&f_t,"\">");
+ wv_secnn(&p_dc->dc_ty);
+ wf_wr(&f_t,"</A>");
+ switch(sn_lev(&p_dc->dc_ty.ty_sn))
+ {
+ case 1: wf_wl(&f_t,"</H2>"); break;
+ case 2: wf_wl(&f_t,"</H3>"); break;
+ case 3: wf_wl(&f_t,"</H4>"); break;
+ case 4: wf_wl(&f_t,"</H5>"); break;
+ case 5: wf_wl(&f_t,"</H6>"); break;
+ default: as_bomb("wv_httoc: switch defaulted.");
+ }
+ }
+ }
+ wf_wl(&f_t,"<HR>");
+
+ /* Restore the document list position. */
+ ls_set(document_list,p_mark);
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_tocs P_((p_ty_t));
+LOCAL void wv_tocs(p_ty)
+/* Writes a table of contents to the weave output file. */
+p_ty_t p_ty;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txtocs(p_ty); break;
+ case TR_HTXT :
+ case TR_HTML : wv_httocs(p_ty); break;
+ default : as_bomb("wv_tocs:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txskip P_((p_ty_t));
+LOCAL void wv_txskip(p_ty)
+/* } ABC */
+/* Writes a vertical space to the output file. */
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_SKIP,"wv_txskip: Not a skip directive!");
+
+ sprintf(linet1,"\\fwvskip{%lu}",(ulong) p_ty->ty_mm);
+ wf_wl(&f_t,linet1);
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htskip P_((p_ty_t));
+LOCAL void wv_htskip(p_ty)
+/* Writes a vertical space to the output file. */
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_SKIP,"wv_htskip: Not a skip directive!");
+
+ /* no skipping is currently done for HTML files */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_skip P_((p_ty_t));
+LOCAL void wv_skip(p_ty)
+/* Writes a vertical space to the output file. */
+p_ty_t p_ty;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txskip(p_ty); break;
+ case TR_HTXT :
+ case TR_HTML : wv_htskip(p_ty); break;
+ default : as_bomb("wv_skip:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txtitl P_((p_ty_t));
+LOCAL void wv_txtitl(p_ty)
+/* Writes a TeX title line to the output file. */
+/* } ABC */
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_TITL,"wv_txtitl: Not a title!");
+
+ switch(p_ty->ty_align)
+ {
+ case LR_LEFT: wf_wr(&f_t,"\\fwleftline{"); break;
+ case LR_RIGH: wf_wr(&f_t,"\\fwrightline{"); break;
+ case LR_CENT: wf_wr(&f_t,"\\fwcenterline{"); break;
+ default: as_bomb("wv_txtitle: Alignment switch defaulted.");
+ }
+ switch(p_ty->ty_font)
+ {
+ case FT_NORM: wf_wr(&f_t,"\\fwfontnormal{"); break;
+ case FT_TITL: wf_wr(&f_t,"\\fwfonttitle{"); break;
+ case FT_STIT: wf_wr(&f_t,"\\fwfontsmalltitle{"); break;
+ default: as_bomb("wv_txtitle: Font switch defaulted.");
+ }
+ wv_ugsc(&p_ty->ty_sc);
+ wf_wl(&f_t,"}}");
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_httitl P_((p_ty_t));
+LOCAL void wv_httitl(p_ty)
+/* Writes an HTML title line to the output file,
+ * creating a document title if the title line is the
+ * first for the document.
+ */
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_TITL,"wv_httitl: Not a title!");
+
+ if (title1Q) {
+ title1Q = FALSE;
+ wf_wl(&f_t, "<TITLE>");
+ switch(p_ty->ty_align)
+ {
+ /* Title alignment is currently ignored */
+ case LR_LEFT:
+ case LR_RIGH:
+ case LR_CENT: break;
+ default: as_bomb("wv_httitle: Alignment switch defaulted.");
+ }
+ switch(p_ty->ty_font)
+ {
+ /* Title font is currently ignored */
+ case FT_NORM:
+ case FT_TITL:
+ case FT_STIT: break;
+ default: as_bomb("wv_httitle: Font switch defaulted.");
+ }
+ wv_ugsc(&p_ty->ty_sc);
+ if (*(p_ty->ty_sc.sc_last) != '.') {
+ /* there may be more title lines to come */
+ wf_wr(&f_t," ...");
+ } /* end if */
+ wf_wl(&f_t,"\n</TITLE>");
+ } /* end if */
+
+ wf_wl(&f_t, "<H1>");
+ switch(p_ty->ty_align)
+ {
+ /* Title alignment is currently ignored */
+ case LR_LEFT:
+ case LR_RIGH:
+ case LR_CENT: break;
+ default: as_bomb("wv_httitle: Alignment switch defaulted.");
+ }
+ switch(p_ty->ty_font)
+ {
+ /* Title font is currently ignored */
+ case FT_NORM:
+ case FT_TITL:
+ case FT_STIT: break;
+ default: as_bomb("wv_httitle: Font switch defaulted.");
+ }
+ wv_ugsc(&p_ty->ty_sc);
+ wf_wl(&f_t,"\n</H1>");
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_titl P_((p_ty_t));
+LOCAL void wv_titl(p_ty)
+/* Writes a title line to the output file. */
+p_ty_t p_ty;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txtitl(p_ty); break;
+ case TR_HTXT :
+ case TR_HTML : wv_httitl(p_ty); break;
+ default : as_bomb("wv_titl:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+LOCAL void wv_dcty P_((p_dc_t));
+LOCAL void wv_dcty(p_dc)
+/* Weaves a document typesetter element. */
+p_dc_t p_dc;
+{
+ p_ty_t p_ty = &p_dc->dc_ty;
+
+ as_cold(p_dc->dc_kind==DC_TYPE,"wv_dcty: Not a typesetter component!");
+
+ switch (p_ty->ty_kind)
+ {
+ case TY_NSEC: wv_nsec(p_ty); break;
+ case TY_OLIT: wv_olit(p_ty); break;
+ case TY_CLIT: wv_clit(p_ty); break;
+ case TY_OEMP: wv_oemp(p_ty); break;
+ case TY_CEMP: wv_cemp(p_ty); break;
+ case TY_NPAG: wv_npag(p_ty); break;
+ case TY_TOCS: wv_tocs(p_ty); break;
+ case TY_SKIP: wv_skip(p_ty); break;
+ case TY_TITL: wv_titl(p_ty); break;
+ default : as_bomb("wv_dcty: Switch defaulted.");
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void wv_dctx P_((p_dc_t));
+LOCAL void wv_dctx(p_dc)
+/* Write out a document text item. */
+p_dc_t p_dc;
+{
+ as_cold(p_dc->dc_kind==DC_TEXT,"wv_dctx: Not text.");
+
+/* ABC { */
+ if (literal || (tr_codes==TR_NONE) || (tr_codes==TR_HTXT))
+/* } ABC */
+ wv_ugscls(p_dc->dc_text);
+ else
+ wv_echo(p_dc->dc_text);
+}
+
+/******************************************************************************/
+
+LOCAL void wv_eltx P_((p_el_t));
+LOCAL void wv_eltx(p_el)
+/* Weaves a text element. */
+p_el_t p_el;
+{
+ as_cold(p_el->el_kind==EL_TEXT,"wv_eltx: Not text.");
+ wv_verb(p_el->el_text);
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_ohtdf P_((void));
+LOCAL void wv_ohtdf()
+/* Write a macro definition tag opening */
+{
+ wf_wr(&f_t, "FWDEF[");
+}
+/* ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_chtdf P_((void));
+LOCAL void wv_chtdf()
+/* Write a macro definition tag closing */
+{
+ wf_wr(&f_t, "]DEFFW");
+}
+/* ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txelin P_((p_el_t));
+LOCAL void wv_txelin(p_el)
+/* } ABC */
+/* Weaves a TeX invocation element. */
+p_el_t p_el;
+{
+ as_cold(p_el->el_kind==EL_INVC,"wv_txelin: Not an invocation.");
+
+ /* Write out the macro call proper. */
+ wv_manm(p_el->el_p_mac,1L);
+
+ /* Write out the actual parameter list, if any. */
+ if (ls_len(p_el->el_parls) > 0)
+ {
+ ulong parnum;
+ wf_wr(&f_t,"\\fwoparen ");
+ ls_fir(p_el->el_parls); /* List of actual parameter expressions. */
+ ls_fir(p_el->el_pretx); /* List of crud before each expression. */
+ ls_fir(p_el->el_postx); /* List of crud after each expression. */
+ parnum=1;
+ while (TRUE)
+ {
+ p_ells_t *pp_exp;
+ p_scls_t *pp_scls1;
+ p_scls_t *pp_scls2;
+ ls_nxt(p_el->el_parls,PPV &pp_exp);
+ ls_nxt(p_el->el_pretx,PPV &pp_scls1);
+ ls_nxt(p_el->el_postx,PPV &pp_scls2);
+ if (pp_exp==NULL) break;
+ if (parnum++>1) wf_wr(&f_t,"\\fwcomma ");
+ wv_verb(*pp_scls1);
+ wf_wr(&f_t,"\\fwoquote"); wv_ex(*pp_exp); wf_wr(&f_t,"\\fwcquote");
+ wv_verb(*pp_scls2);
+ }
+ wf_wr(&f_t,"\\fwcparen ");
+ }
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htelin P_((p_el_t));
+LOCAL void wv_htelin(p_el)
+/* Weaves an HTML invocation element. */
+p_el_t p_el;
+{
+ as_cold(p_el->el_kind==EL_INVC,"wv_htelin: Not an invocation.");
+
+ /* Write an anchor to reference the definition */
+ wf_wr(&f_t, "<A HREF=\"#");
+ wv_ohtdf();
+
+ /* Write out the macro no. */
+ wv_mano(p_el->el_p_mac,1L);
+
+ /* Close the anchor name */
+ wv_chtdf();
+ wf_wr(&f_t, "\">");
+
+ /* Write out the macro call proper. */
+ wv_manm(p_el->el_p_mac,1L);
+
+ /* Close anchor */
+ wf_wr(&f_t, "</A>");
+
+ /* Write out the actual parameter list, if any. */
+ if (ls_len(p_el->el_parls) > 0)
+ {
+ ulong parnum;
+ wf_wr(&f_t,"(");
+ ls_fir(p_el->el_parls); /* List of actual parameter expressions. */
+ ls_fir(p_el->el_pretx); /* List of crud before each expression. */
+ ls_fir(p_el->el_postx); /* List of crud after each expression. */
+ parnum=1;
+ while (TRUE)
+ {
+ p_ells_t *pp_exp;
+ p_scls_t *pp_scls1;
+ p_scls_t *pp_scls2;
+ ls_nxt(p_el->el_parls,PPV &pp_exp);
+ ls_nxt(p_el->el_pretx,PPV &pp_scls1);
+ ls_nxt(p_el->el_postx,PPV &pp_scls2);
+ if (pp_exp==NULL) break;
+ if (parnum++>1) wf_wr(&f_t,",");
+ wv_verb(*pp_scls1);
+ wf_wr(&f_t,"`"); wv_ex(*pp_exp); wf_wr(&f_t,"'");
+ wv_verb(*pp_scls2);
+ }
+ wf_wr(&f_t,")");
+ }
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_elin P_((p_el_t));
+LOCAL void wv_elin(p_el)
+/* Weaves an invocation element. */
+p_el_t p_el;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txelin(p_el); break;
+ case TR_HTXT :
+ case TR_HTML : wv_htelin(p_el); break;
+ default : as_bomb("wv_elin:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txelpr P_((p_el_t));
+LOCAL void wv_txelpr(p_el)
+/* } ABC */
+/* Weaves a TeX parameter element. */
+p_el_t p_el;
+{
+ as_cold(p_el->el_kind==EL_PARM,"wv_txelpr: Not a parameter.");
+ wf_wr (&f_t,"\\fwparam{");
+ wf_dec(&f_t,(ulong) p_el->el_parno);
+ wf_wr (&f_t,"}");
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htelpr P_((p_el_t));
+LOCAL void wv_htelpr(p_el)
+/* Weaves an HTML parameter element. */
+p_el_t p_el;
+{
+ as_cold(p_el->el_kind==EL_PARM,"wv_htelpr: Not a parameter.");
+ wf_wr (&f_t,"#");
+ wf_dec(&f_t,(ulong) p_el->el_parno);
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_elpr P_((p_el_t));
+LOCAL void wv_elpr(p_el)
+/* Weaves a parameter element. */
+p_el_t p_el;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txelpr(p_el); break;
+ case TR_HTXT :
+ case TR_HTML : wv_htelpr(p_el); break;
+ default : as_bomb("wv_elpr:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/* ABC { */
+/******************************************************************************/
+
+LOCAL void wv_elsp P_((p_el_t));
+LOCAL void wv_elsp(p_el)
+/* Weaves a special function element. */
+p_el_t p_el;
+{
+ as_cold(p_el->el_kind==EL_SPEC,"wv_elsp: Not an internal function.");
+}
+
+/* } ABC */
+
+/******************************************************************************/
+
+LOCAL void wv_ex(p_exp)
+/* Weaves a expression. */
+p_ells_t p_exp;
+{
+
+ ls_fir(p_exp);
+ while (TRUE)
+ {
+ p_el_t p_el;
+ ls_nxt(p_exp,PPV &p_el);
+ if (p_el==NULL) break;
+ switch (p_el->el_kind)
+ {
+ case EL_TEXT: wv_eltx(p_el); break;
+ case EL_INVC: wv_elin(p_el); break;
+ case EL_PARM: wv_elpr(p_el); break;
+ /* ABC { */
+ case EL_SPEC: wv_elsp(p_el); break;
+ /* } ABC */
+ default: as_bomb("wv_ex: Case defaulted.");
+ }
+ }
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txusage P_((p_ma_t));
+LOCAL void wv_txusage(p_ma)
+/* } ABC */
+/* Weaves a TeX list of all the sections in which the specified macro is used. */
+p_ma_t p_ma;
+{
+ ulong no_calls = ls_len(p_ma->ma_calls);
+ ulong callno;
+
+ /* If it is a file macro then it is not allowed to be called. */
+ if (p_ma->ma_defn.md_isfil)
+ {
+ wf_wl(&f_t,"\\fwisafile{This macro is attached to an output file.}");
+ return;
+ }
+
+ if (no_calls==0)
+ {
+ wf_wl(&f_t,"\\fwusedin{This macro is NEVER invoked.}");
+ return;
+ }
+
+ wf_wr(&f_t,"\\fwusedin{This macro is invoked in definition");
+ if (no_calls>1) wf_chr(&f_t,'s');
+ wf_chr(&f_t,' ');
+ ls_fir(p_ma->ma_calls);
+ for (callno=1;callno<=no_calls;callno++)
+ {
+ p_mc_t p_mc;
+ ls_nxt(p_ma->ma_calls,PPV &p_mc);
+ as_cold(p_mc!=NULL,"wv_txusage: Awk!");
+ wf_dec(&f_t,(ulong) p_mc->mc_seq);
+ if (callno < no_calls-1) {
+ wf_wr(&f_t,", ");
+ /* ABC{ */
+ /* add return if necessary [ABC] */
+ if (callno % MAXINV == 0) wf_wr(&f_t,"\n");
+ /* } ABC */
+ } else
+ if (callno==no_calls-1)
+ if (no_calls>2)
+ wf_wr(&f_t,", and ");
+ else
+ wf_wr(&f_t," and ");
+ }
+ wf_wl(&f_t,".}");
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htusage P_((p_ma_t));
+LOCAL void wv_htusage(p_ma)
+/* Weaves an HTML list of all the sections in which the specified macro is used. */
+p_ma_t p_ma;
+{
+ ulong no_calls = ls_len(p_ma->ma_calls);
+ ulong callno;
+
+ /* If it is a file macro then it is not allowed to be called. */
+ if (p_ma->ma_defn.md_isfil)
+ {
+ wf_wr(&f_t,"<CITE>");
+ wf_wr(&f_t,"This macro is attached to an output file.");
+ wf_wl(&f_t,"</CITE>");
+ return;
+ }
+
+ if (no_calls==0)
+ {
+ wf_wl(&f_t,"<CITE>This macro is NEVER invoked.</CITE>");
+ return;
+ }
+
+ wf_wr(&f_t,"<CITE>This macro is invoked in definition");
+ if (no_calls>1) wf_chr(&f_t,'s');
+ wf_chr(&f_t,' ');
+ ls_fir(p_ma->ma_calls);
+ for (callno=1;callno<=no_calls;callno++)
+ {
+ p_mc_t p_mc;
+ ls_nxt(p_ma->ma_calls,PPV &p_mc);
+ as_cold(p_mc!=NULL,"wv_htusage: Awk!");
+ wf_wr(&f_t, "<A HREF=\"#");
+ wv_ohtdf();
+ wf_dec(&f_t,(ulong) p_mc->mc_seq);
+ wv_chtdf();
+ wf_wr(&f_t, "\">");
+ wf_dec(&f_t,(ulong) p_mc->mc_seq);
+ wf_wr(&f_t, "</A>");
+ if (callno < no_calls-1) {
+ wf_wr(&f_t,", ");
+ /* ABC{ */
+ /* add HTML return if necessary [ABC] */
+ if (callno % MAXINV == 0) wf_wr(&f_t,"\n");
+ /* } ABC */
+ } else
+ if (callno==no_calls-1)
+ if (no_calls>2)
+ wf_wr(&f_t,", and ");
+ else
+ wf_wr(&f_t," and ");
+ }
+ wf_wl(&f_t,".</CITE>");
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_usage P_((p_ma_t));
+LOCAL void wv_usage(p_ma)
+/* Weaves a list of all the sections in which the specified macro is used. */
+p_ma_t p_ma;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txusage(p_ma); break;
+ case TR_HTXT :
+ case TR_HTML : wv_htusage(p_ma); break;
+ default : as_bomb("wv_usage:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txdefin P_((p_ma_t));
+LOCAL void wv_txdefin(p_ma)
+/* } ABC */
+/* Just after each macro body part definition comes a note listing the */
+/* containing the macro's body parts. This function weaves that list. */
+p_ma_t p_ma;
+{
+ ulong no_parts = ls_len(p_ma->ma_defn.md_body);
+ ulong partno;
+
+ /* If it's not an additive macro, we don't write anything. */
+ if (!p_ma->ma_defn.md_isadd) return;
+
+ wf_wr(&f_t,"\\fwseealso{This macro is defined in definitions ");
+ ls_fir(p_ma->ma_defn.md_body);
+ for (partno=1;partno<=no_parts;partno++)
+ {
+ p_bp_t p_bp;
+ ls_nxt(p_ma->ma_defn.md_body,PPV &p_bp);
+ as_cold(p_bp!=NULL,"wv_txdefin: Awk!");
+ wf_dec(&f_t,(ulong) p_bp->bp_seq);
+ if (partno<no_parts-1)
+ wf_wr(&f_t,", ");
+ else
+ if (partno==no_parts-1)
+ if (no_parts>2)
+ wf_wr(&f_t,", and ");
+ else
+ wf_wr(&f_t," and ");
+ }
+ wf_wl(&f_t,".}");
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htdefin P_((p_ma_t));
+LOCAL void wv_htdefin(p_ma)
+/* Just after each macro body part definition comes a note listing the */
+/* containing the macro's body parts. This function weaves that list. */
+p_ma_t p_ma;
+{
+ ulong no_parts = ls_len(p_ma->ma_defn.md_body);
+ ulong partno;
+
+ /* If it's not an additive macro, we don't write anything. */
+ if (!p_ma->ma_defn.md_isadd) return;
+
+ wf_wr(&f_t,"<CITE>This macro is defined in definitions ");
+ ls_fir(p_ma->ma_defn.md_body);
+ for (partno=1;partno<=no_parts;partno++)
+ {
+ p_bp_t p_bp;
+ ls_nxt(p_ma->ma_defn.md_body,PPV &p_bp);
+ as_cold(p_bp!=NULL,"wv_htdefin: Awk!");
+ wf_wr(&f_t, "<A HREF=\"#");
+ wv_ohtdf();
+ wf_dec(&f_t,(ulong) p_bp->bp_seq);
+ wv_chtdf();
+ wf_wr(&f_t, "\">");
+ wf_dec(&f_t,(ulong) p_bp->bp_seq);
+ wf_wr(&f_t, "</A>");
+ if (partno<no_parts-1)
+ wf_wr(&f_t,", ");
+ else
+ if (partno==no_parts-1)
+ if (no_parts>2)
+ wf_wr(&f_t,", and ");
+ else
+ wf_wr(&f_t," and ");
+ }
+ wf_wl(&f_t,".</CITE>");
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_defin P_((p_ma_t));
+LOCAL void wv_defin(p_ma)
+/* Just after each macro body part definition comes a note listing the */
+/* containing the macro's body parts. This function weaves that list. */
+p_ma_t p_ma;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txdefin(p_ma); break;
+ case TR_HTXT :
+ case TR_HTML : wv_htdefin(p_ma); break;
+ default : as_bomb("wv_defin:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_txdcma P_((p_dc_t));
+LOCAL void wv_txdcma(p_dc)
+/* } ABC */
+/* Weaves a macro definition in TeX. */
+p_dc_t p_dc;
+{
+ p_bp_t p_bp;
+
+ /* Macro calls sandwich the definition itsef. */
+ wf_wl(&f_t,"\\fwbeginmacro");
+
+ /* Write out the macro's name. */
+ wv_manm(p_dc->dc_p_ma,p_dc->dc_part);
+
+ /* Write the formal parameter list. */
+ if (p_dc->dc_p_ma->ma_defn.md_npar>0)
+ {
+ wf_wr(&f_t,"\\fwparams{");
+ wf_dec(&f_t,(ulong) p_dc->dc_p_ma->ma_defn.md_npar);
+ wf_wr(&f_t,"}");
+ }
+
+ /* Zero and many options are indicated by bold letters. */
+ if (p_dc->dc_p_ma->ma_defn.md_iszer) wf_wr(&f_t,"\\fwzero{}");
+ if (p_dc->dc_p_ma->ma_defn.md_isman) wf_wr(&f_t,"\\fwmany{}");
+
+ /* Write the "equals". */
+ if (p_dc->dc_p_ma->ma_defn.md_isadd)
+ wf_wr(&f_t,"\\fwplusequals ");
+ else
+ wf_wr(&f_t,"\\fwequals ");
+
+ /* Write out this particular body part. */
+ ls_loo(p_dc->dc_p_ma->ma_defn.md_body,p_dc->dc_part,PPV &p_bp);
+ wf_wr(&f_t,"\\fwodef ");
+ wv_ex(p_bp->bp_ex);
+ wf_wl(&f_t,"\\fwcdef ");
+
+ /* After the macro definition, write out notes on the macro. */
+ wf_wl(&f_t,"\\fwbeginmacronotes");
+ wv_defin(p_dc->dc_p_ma); /* A list of the macro's body parts. */
+ wv_usage(p_dc->dc_p_ma); /* A list of where the macro is used. */
+ wf_wl(&f_t,"\\fwendmacronotes");
+
+ /* The macro definition is sandwiched by macro calls. */
+ wf_wl(&f_t,"\\fwendmacro");
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_htdcma P_((p_dc_t));
+LOCAL void wv_htdcma(p_dc)
+/* } ABC */
+/* Weaves a macro definition in HTML. */
+p_dc_t p_dc;
+{
+ p_bp_t p_bp;
+
+ /* Write an anchor for the macro */
+ wf_wr(&f_t, "<PRE><A NAME=\"");
+ wv_ohtdf();
+
+ /* Write out the macro's number. */
+ wv_mano(p_dc->dc_p_ma,p_dc->dc_part);
+
+ /* Finish anchor name */
+ wv_chtdf();
+ wf_wr(&f_t, "\">");
+
+ /* Write out the macro's name. */
+ wv_manm(p_dc->dc_p_ma,p_dc->dc_part);
+
+ /* Close anchor */
+ wf_wr(&f_t, "</A>");
+
+ /* Write the formal parameter list. */
+ if (p_dc->dc_p_ma->ma_defn.md_npar>0)
+ {
+ wf_wr(&f_t,"(#");
+ wf_dec(&f_t,(ulong) p_dc->dc_p_ma->ma_defn.md_npar);
+ wf_wr(&f_t,")");
+ }
+
+ /* Zero and many options are indicated by bold letters. */
+ if (p_dc->dc_p_ma->ma_defn.md_iszer)
+ wf_wr(&f_t,"<STRONG>Z</STRONG>");
+ if (p_dc->dc_p_ma->ma_defn.md_isman)
+ wf_wr(&f_t,"<STRONG>M</STRONG>");
+
+ /* Write the "equals". */
+ if (p_dc->dc_p_ma->ma_defn.md_isadd)
+ wf_wl(&f_t,"+=");
+ else
+ wf_wl(&f_t,"=");
+
+ /* Write out this particular body part. */
+ ls_loo(p_dc->dc_p_ma->ma_defn.md_body,p_dc->dc_part,PPV &p_bp);
+ wf_wr(&f_t,"{");
+ wv_ex(p_bp->bp_ex);
+ wf_wl(&f_t,"}");
+
+ /* After the macro definition, write out notes on the macro. */
+ wv_defin(p_dc->dc_p_ma); /* A list of the macro's body parts. */
+ wv_usage(p_dc->dc_p_ma); /* A list of where the macro is used. */
+ wf_wl(&f_t,"</PRE>");
+}
+
+/******************************************************************************/
+
+/* ABC { */
+LOCAL void wv_dcma P_((p_dc_t));
+LOCAL void wv_dcma(p_dc)
+/* } ABC */
+/* Weaves a macro definition. */
+p_dc_t p_dc;
+{
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : wv_txdcma(p_dc); break;
+ case TR_HTXT :
+ case TR_HTML : wv_htdcma(p_dc); break;
+ default : as_bomb("wv_dcma:case defaulted.");
+ } /* end switch */
+}
+/* } ABC */
+
+/******************************************************************************/
+
+LOCAL void wv_dc P_((p_dc_t));
+LOCAL void wv_dc(p_dc)
+/* Weaves a document component (p_dc). */
+p_dc_t p_dc;
+{
+ switch (p_dc->dc_kind)
+ {
+ case DC_TEXT: wv_dctx(p_dc); break;
+ case DC_TYPE: wv_dcty(p_dc); break;
+ case DC_MACR: wv_dcma(p_dc); break;
+ default : as_bomb("wv_dc: Case defaulted.");
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void wv_docnt P_((void));
+LOCAL void wv_docnt()
+/* Weaves the entire document. This functions and most functions above assume */
+/* that the output stream f_t is prepared for writing. */
+{
+ /* Write the typeset header. */
+ wv_head();
+
+ /* Writes the library macros. */
+ /* ABC { */
+ if (doc_incQ) {
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : tex_head(&f_t); break;
+ case TR_HTXT :
+ case TR_HTML : html_head(&f_t); break;
+ default : as_bomb("wv_docnt:case defaulted.");
+ } /* end switch */
+ } /* end if */
+ if (
+ (tr_codes==TR_HTXT)
+ || ((tr_codes==TR_HTML) && doc_incQ)
+ ) {
+ /* Writes the opening HTML markup */
+ wf_wl(&f_t,"<HTML>");
+ } /* end if */
+ /* } ABC */
+
+ ls_fir(document_list);
+ literal=FALSE;
+ while (TRUE)
+ {
+ p_dc_t p_dc;
+ ls_nxt(document_list,PPV &p_dc);
+ if (p_dc == NULL) break;
+ wv_dc(p_dc);
+ }
+ /* ABC { */
+ if (
+ (tr_codes==TR_NONE)
+ || ((tr_codes==TR_TEX) && doc_incQ)
+ ) {
+ /* Writes the closing TeX command */
+ wf_wl(&f_t,"\\bye");
+ } else if (
+ (tr_codes==TR_HTXT)
+ || ((tr_codes==TR_HTML) && doc_incQ)
+ ) {
+ /* Writes the closing HTML markup */
+ wf_wl(&f_t,"</HTML>");
+ } /* end if */
+ /* } ABC */
+
+ /* Write the typeset trailer. */
+ wv_tail();
+}
+
+/******************************************************************************/
+
+EXPORT void weave()
+/* Writes out the documentation file. */
+{
+ fn_t fn_tmp; /* Name of temporary file. */
+ fn_t fn_targ; /* Name of documentation file. */
+ bool renfil; /* Do we wish to rename output file? */
+ bool istarg; /* Does a target file already exist? */
+
+ /* Writing the documentation file differs from some other output files. With */
+ /* non critical files such as the listing file that are really just logs, */
+ /* generation of half a listing file is acceptable if not desirable. However */
+ /* in the case of the documentation file, it is very bad to generate half an */
+ /* output file; far better to generate none at all. For this reason, and */
+ /* also because of the presence of the D option (which prevents the writing */
+ /* of output files identical to existing files (to prevent MAKE */
+ /* propagations)) it is best to write a temporary file and then rename it. */
+
+ /* We shouldn't be here if the weave option is off! */
+ as_cold(option.op_t_b,"weave: option.op_t_b==FALSE!");
+
+ /* ABC { */
+ /* There are no titles yet, so the next is the first */
+ title1Q = TRUE;
+ /* No text scraps have been written yet */
+ lastEOLQ = FALSE;
+ /* } ABC */
+
+ /* Work out what the typeset file's name should be. */
+ strcpy(fn_targ,""); /* Start with an empty string. */
+ fn_ins(fn_targ,option.op_f_s);
+ /* ABC { */
+ switch (tr_codes) {
+ case TR_NONE :
+ case TR_TEX : fn_ins(fn_targ,".tex"); break;
+ case TR_HTXT :
+ case TR_HTML :
+#if PC
+ fn_ins(fn_targ,".htm");
+#else /* !PC */
+ fn_ins(fn_targ,".html");
+#endif /* PC */
+ break;
+ default : as_bomb("weave:case defaulted.");
+ } /* end switch */
+ /* } ABC */
+ fn_ins(fn_targ,option.op_t_s);
+
+ /* The temporary file has to inherit too, because the output directory may */
+ /* not be the default directory and some computers can't rename across */
+ /* directories (and we have to rename it later). */
+ strcpy(fn_tmp,fn_targ);
+ fn_ins(fn_tmp,fn_temp());
+
+ /* Expand the macro to the temporary file. */
+ wf_ini(&f_t,TRUE);
+ wf_ope(&f_t,fn_tmp);
+ if (wf_err(&f_t))
+ {
+ sprintf(linet1,"Error creating temporary documentation file \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ (void) remove(fn_tmp);
+ goto severe;
+ }
+
+ wv_docnt();
+
+ /* Make sure that there weren't any errors writing to the temporary file. */
+ if (wf_err(&f_t))
+ {
+ sprintf(linet1,"Error writing to temporary documentation file \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ (void) remove(fn_tmp);
+ goto severe;
+ }
+
+ /* Close the temporary file. */
+ wf_clo(&f_t);
+ if (wf_err(&f_t))
+ {
+ sprintf(linet1,"Error closing temporary documentation file \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ remove(fn_tmp);
+ goto severe;
+ }
+
+ /* The rest of the code in this function copes with the renaming. */
+
+ /* By default, we wish to rename the temporary file. */
+ renfil=TRUE;
+
+ /* Deal with any existing file of the target name. */
+ istarg=fexists(fn_targ);
+ if (istarg && option.op_d_b)
+ {
+ /* A target already exists, and the D option is on. If the target is */
+ /* identical to the temporary, we can simply delete the temporary! */
+ char *errstr;
+ bool same;
+ errstr=eq_files(fn_tmp,fn_targ,&same);
+ if (errstr != NULL)
+ {
+ wl_sjl("Error comparing temporary file with previous documentation file.");
+ wl_sjl("(A comparison was attempted because the D option was turned on.)");
+ wl_sjl("Error from comparison routine was as follows (first=temp):");
+ wr_sjl(" ");wl_sjl(errstr);
+ sprintf(linet1,"Temporary file name was \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ sprintf(linet1,"Output file name was \"%s\".",&fn_targ[0]);
+ wl_sjl(linet1);
+ wl_sjl("FunnelWeb will leave both files intact so you can look at them.");
+ goto severe;
+ }
+ /* If the two files are the same, we can simply delete the temporary. */
+ if (same)
+ {
+ int status;
+ status=remove(fn_tmp);
+ if (status != REMOVE_S)
+ {
+ sprintf(linet1,"Error deleting (under +D option) temporary file \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ goto severe;
+ }
+ sprintf(linet1,"Deleted identical documentation file \"%s\".",&fn_targ[0]);
+ wl_sjl(linet1);
+ renfil=FALSE;
+ }
+ }
+
+ if (renfil)
+ {
+ int status;
+ /* We need to delete any existing file of the target name. */
+ if (istarg)
+ {
+ status=remove(fn_targ);
+ if (status != REMOVE_S)
+ {
+ sprintf(linet1,"Error deleting existing documentation file \"%s\".",&fn_targ[0]);
+ wl_sjl(linet1);
+ goto severe;
+ }
+ }
+ /* Rename the temporary file to the output file. */
+ status=rename(fn_tmp,fn_targ);
+ if (status != RENAME_S)
+ {
+ wl_sjl("Error renaming temporary documentation file to documentation file.");
+ sprintf(linet1,"Temporary file name was \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ sprintf(linet1,"Output file name was \"%s\".",&fn_targ[0]);
+ wl_sjl(linet1);
+ wl_sjl("FunnelWeb will leave both files intact so you can look at them.");
+ goto severe;
+ }
+ }
+
+ /* Tell everyone that we have written an output file. */
+ sprintf(linet1,"Weave : Completed %s.",fn_nodir(&fn_targ[0]));
+ wl_s(linet1);
+ if (option.op_b7_b)
+ sprintf(linet1,"Weave: Completed %s.",SUPPNAME);
+ wl_j(linet1);
+ wl_l(linet1);
+ return;
+
+ /* Jump here is a nasty file error occurs. */
+ severe:
+ sprintf(linet1,"A problem occurred during the generation of documentation file \"%s\".",&fn_targ[0]);
+ wl_sjl(linet1);
+ wl_sjl("S: Aborting...");
+ num_sev++;
+ return;
+}
+
+/******************************************************************************/
+
diff --git a/web/funnelAC/fwACsrc/weave.h b/web/funnelAC/fwACsrc/weave.h
new file mode 100644
index 0000000000..9ca3d4357a
--- /dev/null
+++ b/web/funnelAC/fwACsrc/weave.h
@@ -0,0 +1,55 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* WEAVE.H */
+/******************************************************************************/
+/* */
+/* This package exports a single function "weave" that generates the typeset */
+/* output file. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+EXPORT void weave P_((void));
+
+/******************************************************************************/
+/* End of WEAVE.H */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/writfile.c b/web/funnelAC/fwACsrc/writfile.c
new file mode 100644
index 0000000000..3a94717a68
--- /dev/null
+++ b/web/funnelAC/fwACsrc/writfile.c
@@ -0,0 +1,319 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 28-May-1994 ABC Added `wf_last' member to `wf_t' structure to
+ aid in inserting `<P>' paragraph markups
+ into hypertext documents. This member stores
+ the last character written to the file.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* WRITFILE.C */
+/******************************************************************************/
+/* */
+/* Implementation Notes */
+/* -------------------- */
+/* The .H file gives most of the details of what this package does. Here we */
+/* just give some notes on how it is implemented. */
+/* */
+/* MAGIC NUMBERS: These are placed at the head and tail of wf_t records so as */
+/* to assist in the detection of uninitialized or corrupted variables. */
+/* */
+/* TEXT VS BINARY: A big problem arises in choosing whether to write binary */
+/* or text files. Binary files are far faster because they allow us to write */
+/* out large slabs of text using fwrite. The only catch is that they do not */
+/* translate EOL characters in the end of line representation of the host */
+/* environment. Text files, on the other hand are slower (because we have */
+/* only fputc and fputs) but do provide the translation. The solution we */
+/* adopt is to use binary if the host environment's representation for end of */
+/* file is EOL (='\n'), but text otherwise. We can determine this by testing */
+/* the symbol UNIX_EOL defined in machin.h. If binary output is chosen, */
+/* only fwrite is called as we don't know if fwrite and fputc calls can be */
+/* mixed (it would seem not). */
+/* Note: We could test the preprocessor symbol in each function. However, */
+/* the wf_att function introduces a problem as we may be attaching to a text */
+/* file in a UNIX_EOL environment (e.g. stdout). So we make the text/binary */
+/* attribute and attribute of each file, rather than the environment which we */
+/* use only to direct us in how to create and tag (as binary or text) a file. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "as.h"
+#include "machin.h"
+#include "writfile.h"
+
+/******************************************************************************/
+
+#define MGC_HEAD (4837295L)
+#define MGC_TAIL (1213839L)
+
+/* Set the following to TRUE to bomb the package upon the first error. */
+/* This is a good idea during debugging if no output appears. */
+#define BOMB_ON_ERROR FALSE
+
+/******************************************************************************/
+
+LOCAL void wf_check P_((p_wf_t));
+LOCAL void wf_check(p_wf)
+p_wf_t p_wf;
+{
+ as_cold(p_wf!=NULL,"wf_check: p_wf==NULL.");
+
+ as_cold(p_wf->wf_mhead==MGC_HEAD,
+ "wf_check: Magic header field has non-magic value.");
+
+ as_cold(p_wf->wf_mtail==MGC_TAIL,
+ "wf_check: Magic trailer field has non-magic value.");
+
+ as_cold(p_wf->wf_isope || p_wf->wf_pfile==NULL,
+ "wf_check: WF is closed but wf_pfile!=NULL.");
+}
+
+/******************************************************************************/
+
+LOCAL void wf_errlg P_((p_wf_t, char *));
+LOCAL void wf_errlg(p_wf,mess)
+/* This function is called whenever an error occurs on a stream. The main */
+/* responsibility of this function is to set the error flag in the stream. */
+/* However, it can do other stuff too such as log the error to the screen. */
+p_wf_t p_wf;
+char *mess;
+{
+ p_wf->wf_iserr=TRUE;
+#if BOMB_ON_ERROR
+ if (p_wf->wf_pfile == stdout)
+ fprintf(stderr,"The output file error occurred on STANDARD OUTPUT.\n");
+ else
+ fprintf(stderr,"The output file error occurred on an ordinary file.\n");
+ as_bomb(mess);
+#endif
+}
+
+/******************************************************************************/
+
+EXPORT void wf_ini(p_wf,normal)
+p_wf_t p_wf;
+bool normal;
+{
+ p_wf->wf_mhead = MGC_HEAD;
+ p_wf->wf_iserr = !normal;
+ p_wf->wf_isope = FALSE;
+ p_wf->wf_istxt = FALSE;
+ p_wf->wf_pfile = NULL;
+ /* ABC { */
+ p_wf->wf_last = (char)0;
+ /* } ABC */
+ p_wf->wf_mtail = MGC_TAIL;
+}
+
+/******************************************************************************/
+
+EXPORT void wf_att(p_wf,wf_pfile)
+p_wf_t p_wf;
+FILE *wf_pfile;
+{
+ wf_check(p_wf);
+ if (p_wf->wf_iserr) return;
+ as_cold(!p_wf->wf_isope,"wf_att: WF is already open.");
+
+ p_wf->wf_pfile = wf_pfile;
+ p_wf->wf_isope = TRUE;
+ p_wf->wf_istxt = TRUE; /* Play it safe with files we didn't open. */
+ wf_check(p_wf);
+}
+
+/******************************************************************************/
+
+EXPORT void wf_ope(p_wf,p_name)
+p_wf_t p_wf;
+char *p_name;
+{
+ FILE *result;
+
+ wf_check(p_wf);
+ if (p_wf->wf_iserr) return;
+ as_cold(!p_wf->wf_isope,"wf_ope: WF is already open.");
+
+/* Whether we open the file as text or binary depends on whether EOL maps */
+/* to an end of line in the current environment. */
+#if UNIX_EOL
+ result=fopen(p_name,"wb"); p_wf->wf_istxt=FALSE;
+#else
+ result=fopen(p_name,"w"); p_wf->wf_istxt=TRUE;
+#endif
+
+ if (result == FOPEN_F)
+ {
+ /* TRACE printf("Output file in error is \"%s\".\n",p_name); */
+ wf_errlg(p_wf,"wf_ope: Error opening output file.");
+ }
+ else
+ {p_wf->wf_isope=TRUE; p_wf->wf_pfile=result;}
+ wf_check(p_wf);
+}
+
+/******************************************************************************/
+
+EXPORT void wf_chr(p_wf,ch)
+p_wf_t p_wf;
+intchar ch;
+{
+ wf_check(p_wf);
+ if ( p_wf->wf_iserr) return;
+ as_cold(p_wf->wf_isope,"wf_chr: WF is closed.");
+
+ if (p_wf->wf_istxt)
+ {
+ if (fputc((int) ch,p_wf->wf_pfile) == FPUTC_F)
+ wf_errlg(p_wf,"wf_chr: Error fputc()ing to output file.");
+ }
+ else
+ {
+ if (fwrite(&ch,(size_t) 1,(size_t) 1,p_wf->wf_pfile) != 1)
+ wf_errlg(p_wf,"wf_chr: Error fwrite()ing to output file.");
+ }
+ /* ABC { */
+ p_wf->wf_last = ch;
+ /* } ABC */
+ wf_check(p_wf);
+}
+
+/******************************************************************************/
+
+EXPORT void wf_wr(p_wf,p_str)
+p_wf_t p_wf;
+char *p_str;
+{
+ /* ABC { */
+ size_t len = strlen(p_str);
+ /* } ABC */
+ wf_check(p_wf);
+ if ( p_wf->wf_iserr) return;
+ as_cold(p_wf->wf_isope,"wf_wr: WF is closed.");
+
+ if (p_wf->wf_istxt)
+ {
+ if (fputs(p_str,p_wf->wf_pfile) == FPUTS_F)
+ wf_errlg(p_wf,"wf_wr: Error fputs()ing to output file.");
+ }
+ else
+ {
+ /* [ABC] *** size_t len = strlen(p_str); */
+ if (fwrite(p_str,(size_t) 1,(size_t) len,p_wf->wf_pfile) != len)
+ wf_errlg(p_wf,"wf_wr: Error fwrite()ing to output file.");
+ }
+ /* ABC { */
+ p_wf->wf_last = p_str[len-1];
+ /* } ABC */
+ wf_check(p_wf);
+}
+
+/******************************************************************************/
+
+EXPORT void wf_blk(p_wf,p_blk,blk_len)
+p_wf_t p_wf;
+char *p_blk;
+size_t blk_len;
+{
+ wf_check(p_wf);
+ if ( p_wf->wf_iserr) return;
+ as_cold(p_wf->wf_isope,"wf_blk: WF is closed.");
+
+ if (p_wf->wf_istxt)
+ {
+ /* Amazingly, fputc seems to be the only way to write out a block of */
+ /* bytes with end of line translation. Shocking, but true. */
+ /* See Section B1.4 (p.246-247) of Kernighan and Ritchie. */
+ /* Note: We can't use fputs because that requires a terminating nul. */
+ char *p;
+ char *p_post = p_blk+blk_len;
+ for (p=p_blk; p<p_post; p++)
+ if (fputc(*p,p_wf->wf_pfile) == FPUTC_F)
+ {
+ wf_errlg(p_wf,"wf_blk: Error fputc()ing to output file.");
+ break;
+ }
+ }
+ else
+ if (fwrite(p_blk,(size_t) 1,(size_t) blk_len,p_wf->wf_pfile) != blk_len)
+ wf_errlg(p_wf,"wf_blk: Error fwrite()ing to output file.");
+ wf_check(p_wf);
+ /* ABC { */
+ p_wf->wf_last = p_blk[blk_len-1];
+ /* } ABC */
+}
+
+/******************************************************************************/
+
+EXPORT void wf_wl(p_wf,p_str)
+p_wf_t p_wf;
+char *p_str;
+{
+ wf_wr(p_wf,p_str);
+ wf_chr(p_wf,'\n');
+}
+
+/******************************************************************************/
+
+EXPORT void wf_clo(p_wf)
+p_wf_t p_wf;
+{
+ wf_check(p_wf);
+ if ( p_wf->wf_iserr) return;
+ as_cold(p_wf->wf_isope,"wf_clo: WF is not open.");
+ if (fflush(p_wf->wf_pfile) != FFLUSH_S)
+ wf_errlg(p_wf,"wf_clo: Error fflush()ing output file.");
+ if (fclose(p_wf->wf_pfile) == FCLOSE_F)
+ wf_errlg(p_wf,"wf_clo: Error fclose()ing output file.");
+ p_wf->wf_isope=FALSE;
+ p_wf->wf_pfile=NULL;
+ wf_check(p_wf);
+}
+
+/******************************************************************************/
+
+EXPORT bool wf_err(p_wf)
+p_wf_t p_wf;
+{
+ wf_check(p_wf);
+ return p_wf->wf_iserr;
+}
+
+/******************************************************************************/
+/* End of WRITFILE.C */
+/******************************************************************************/
diff --git a/web/funnelAC/fwACsrc/writfile.h b/web/funnelAC/fwACsrc/writfile.h
new file mode 100644
index 0000000000..c56db567a9
--- /dev/null
+++ b/web/funnelAC/fwACsrc/writfile.h
@@ -0,0 +1,196 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+ ABC Anthony B. Coates coates@physics.uq.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+ 28-May-1994 ABC Added `wf_last' member to `wf_t' structure to
+ aid in inserting `<P>' paragraph markups
+ into hypertext documents.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* WRITFILE.H */
+/******************************************************************************/
+/* */
+/* Introduction */
+/* ------------ */
+/* This package performs all of FunnelWeb's file output. */
+/* FunnelWeb performs lots of output to lots of different files: */
+/* */
+/* - Standard output (to write to the screen). */
+/* - The journal file. */
+/* - The listing file. */
+/* - The tangle output files. */
+/* - The weave output file. */
+/* */
+/* Error Detection */
+/* --------------- */
+/* As we are serious about detecting errors, every call to every IO function */
+/* must have its status checked. Unfortunately this makes everything very */
+/* messy. Having to check result statuses and react to them can be very */
+/* awkward in deeply nested pieces of code, particularly as C does not have */
+/* exceptions. As a result, the policy adopted in FunnelWeb is to RECORD when */
+/* an error occurs on an output stream and silently shut down that stream. */
+/* Then later, at a convenient time, the error status of the stream can be */
+/* checked, and an error message issued. */
+/* */
+/* The C libraries make an effort to be helpful here by providing the ferror */
+/* function. However, it is not useful here for two reasons: */
+/* */
+/* 1. Some calls (e.g. fwrite) are not listed as setting the error status. */
+/* 2. It is not guaranteed that IO calls to a stream with error status */
+/* will not cause a crash. */
+/* 3. Even if ferror were used, it may not be supported by older compilers.*/
+/* */
+/* This package was created to take care of the vexing problems of IO errors */
+/* in output streams. It is a layer above the ANSI file library that provides */
+/* the elementary calls for writing. It differs in that if an error occurs, */
+/* the package records that fact and simply ignores all further operations */
+/* on the file. At any time, it is possible to find out whether a file is in */
+/* normal mode or error mode. All this means that a piece of code can use */
+/* this package to create and write to a file without worrying about errors. */
+/* Then later, when the dust settles, the package can check the status of */
+/* the file, and take appropriate action if an error has been detected. */
+/* */
+/* Text vs Binary */
+/* -------------- */
+/* This package translates all '\n' (contained in the data it has been given */
+/* to write) into the appropriate environment specific representation. */
+/* */
+/* Facts About WF Objects */
+/* ---------------------- */
+/* - A WF object is either in NORMAL or ERROR mode. */
+/* - A WF object in NORMAL mode is also either in OPEN or CLOSED mode. */
+/* - The term "raise an error" means bomb the program with a message. */
+/* - The comments attached to the functions given below are meant to be read */
+/* sequentially with each action or check being performed before the next. */
+/* - This package can not guarantee to detect uninitialized WF objects. The */
+/* reason is that policing is performed using magic number mechanism and it */
+/* is possible that a piece of random memory may contain just the right */
+/* numbers to fool the package. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_WRITFILE
+#define DONE_WRITFILE
+
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+/* We really don't want to show all the guts of this record here, but as */
+/* users of the package have to be able to declare objects of this type and */
+/* make them the right size, it seems as if we have no choice. */
+typedef struct
+ {
+ ulong wf_mhead; /* Helps detect uninitialized and corrupted records. */
+ bool wf_iserr; /* TRUE=>ERROR, FALSE=>NORMAL. */
+ bool wf_isope; /* TRUE=>OPEN, FALSE=>CLOSED. */
+ bool wf_istxt; /* TRUE=>TEXT, FALSE=>BINARY. */
+ FILE *wf_pfile; /* Pointer to the file object. */
+ /* ABC { */
+ char wf_last; /* Last character written to file. */
+ /* } ABC */
+ ulong wf_mtail; /* Helps detect uninitialized and corrupted records. */
+ } wf_t;
+
+typedef wf_t *p_wf_t;
+
+/******************************************************************************/
+
+EXPORT void wf_ini P_((p_wf_t,bool));
+/* Initializes a WF to a well defined state in accordance with the boolean. */
+/* FALSE => State=(ERROR). */
+/* TRUE => State=(NORMAL,CLOSED). */
+/* wf_ini must be applied to a WF before any other operation. */
+/* It can be re-applied repeatedly. */
+
+EXPORT void wf_att P_((p_wf_t,FILE *));
+/* If WF is uninitialized, raises an error (probably). */
+/* If WF is in ERROR mode, returns with no effect. */
+/* If WF is OPEN, raises an error. */
+/* Attaches an already opened output file to the specified FW object. */
+/* Changes the WF to the OPEN state. */
+/* The memory that the second parameter points to must be stable. */
+
+EXPORT void wf_ope P_((p_wf_t,char *));
+/* If WF is uninitialized, raises an error (probably). */
+/* If WF is in ERROR mode, returns with no effect. */
+/* If WF is OPEN, raises an error. */
+/* Creates an output file of the specified name and prepares it for writing. */
+/* Changes the WF to the OPEN state. */
+/* Sets the WF to the ERROR state if the file cannot be opened for writing. */
+
+EXPORT void wf_chr P_((p_wf_t,intchar));
+/* If WF is uninitialized, raises an error (probably). */
+/* If WF is in ERROR mode, returns with no effect. */
+/* If WF is CLOSED, raises an error. */
+/* Writes the specified character to the output file associated with WF. */
+/* Sets WF to the ERROR state if an error occurs during the write. */
+
+EXPORT void wf_wr P_((p_wf_t,char *));
+/* Same as wf_chr except that it writes an entire string. */
+
+EXPORT void wf_wl P_((p_wf_t,char *));
+/* Same as wf_wr except that appends a '\n'. */
+
+EXPORT void wf_blk P_((p_wf_t,char *,size_t));
+/* Same as wf_wr but writes a block of bytes whose address is given by the */
+/* second parameter and whose length (in bytes) is given by the third */
+/* parameter. */
+
+EXPORT void wf_clo P_((p_wf_t));
+/* If WF is uninitialized, raises an error (probably). */
+/* If WF is in ERROR mode, returns with no effect. */
+/* If WF is CLOSED, raises an error. */
+/* Flushes and closes the output file attached to WF. */
+/* Sets WF to the CLOSED state. */
+/* Sets WF to the ERROR state if an error occurs during the close. */
+
+EXPORT bool wf_err P_((p_wf_t));
+/* If WF is uninitialized, raises an error (probably). */
+/* Returns TRUE iff WF is in the ERROR state, otherwise FALSE. */
+/* This function can be called at any time so long as the WF is initialized. */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of WRITFILE.H */
+/******************************************************************************/
diff --git a/web/funnelAC/hackman/h_ch0.tex b/web/funnelAC/hackman/h_ch0.tex
new file mode 100644
index 0000000000..597479506e
--- /dev/null
+++ b/web/funnelAC/hackman/h_ch0.tex
@@ -0,0 +1,180 @@
+%==============================================================================%
+% Start of Ch0.tex %
+%==============================================================================%
+%
+% Copyright
+% ---------
+% Copyright (C) 1992 Ross N. Williams.
+% This file contains a chapter of the FunnelWeb Hacker's Manual.
+% See the main TeX file for this manual for further information.
+%
+%==============================================================================%
+
+\vbox{\relax}
+\vfill
+
+\hrule
+
+\medskip
+
+Copyright \copyright{} 1992 Ross~N.~Williams.
+\xn{Ross}{Williams}\xx{copyright}{notice}
+
+Permission is granted to make and distribute verbatim copies of this manual
+provided that the copyright notice and this permission notice are preserved
+on all copies.\note{This paragraph was copied from the GNU Emacs manual to
+avoid my having to get a legal opinion on something I could cook up.}
+
+\medskip
+
+\hrule
+
+\newpage
+
+%==============================================================================
+
+\tableofcontents
+
+\newpage
+
+%==============================================================================
+
+%I am not using LaTeX's figures and tables numbering so these are commented out.
+%\pseudochapter{List of Figures}
+%\pseudochapter{List of Tables}
+
+%==============================================================================
+
+% No forward.
+%\pseudochapter{Foreword}
+%\x{foreword}
+
+%==============================================================================
+
+\pseudochapter{Preface}
+\x{preface}
+
+This manual is for hackers! Anyone who wants to
+bash,
+diddle,
+frob,
+grind,
+mangle,
+patch,
+poke,
+toggle,
+twiddle,
+zap,
+or generally hack FunnelWeb should at least take a look at this manual.
+
+This document has been created to serve two purposes:
+
+\begin{enumerate}
+
+\item To act as a repository for specific design and implementation
+information not appropriate to be included in program comments.
+
+\item To guide those interested in modifying the program.
+
+\end{enumerate}
+
+As a result, this document has grown in fits and starts.
+This manual is not a particularly polished or well-balanced document
+but it should be of assistance to those (including myself) involved with
+modifying FunnelWeb.
+
+\bigskip
+
+\leftline{\b{Ross~N.~Williams}}
+\leftline{\b{Adelaide, Australia}}
+\leftline{\b{May~1992}}
+
+%==============================================================================
+
+\pseudochapter{Acknowledgements}
+\x{acknowledgements}
+
+Many thanks to \b{David Hulse}\xn{David}{Hulse}
+(\p{dave@cs.adelaide.edu.au}) for
+translating the original version of FunnelWeb
+(FunnelWeb~V1) from Ada\x{Ada} into~C
+and getting it to work on Unix and a PC.
+The C code written by David (FunnelWeb~V2) formed
+the basis of FunnelWeb~V3, but was
+entirely rewritten during the intensive refinement and feature-injection
+period leading up to this release (FunnelWeb~V3 is about three times
+the size of FunnelWeb~V2).
+Nevertheless, without this important first translation step,
+I would probably not have found the motivation to develop FunnelWeb to its
+present state.
+
+Thanks go to \b{Simon Hackett}\xn{Simon}{Hackett}
+(\p{simon@internode.com.au}) of Internode Systems
+Pty Ltd for the use of his Sun, Mac, and PC, for assistance in porting
+FunnelWeb to the Sun and PC, and for helpful discussions.
+
+Thanks go to \b{Jeremy Begg}\xn{Jeremy}{Begg}
+(\p{jeremy@vsm.com.au}) of VSM Software Services
+for the use of his VAX, and for assistance with the VMS-specific code.
+
+Thanks to \b{Barry Dwyer}\xn{Barry}{Dwyer} (\p{dwyer@cs.adelaide.edu.au})
+and \b{Roger Brissenden}\xn{Roger}{Brissenden} (\p{rjb@koala.harvard.edu})
+for trying out FunnelWeb Version~1 in 1987 and providing valuable feedback.
+
+Thanks to Donald Knuth\xn{Donald}{Knuth}
+for establishing the idea of literate programming in the first place.
+
+\bigskip
+
+\leftline{\b{Ross~N.~Williams}}
+\leftline{\b{Adelaide, Australia}}
+\leftline{\b{May~1992}}
+
+%==============================================================================
+
+\pseudochapter{Presentation Notes}
+\x{presentation notes}
+
+\thing{References:} All references are set in bold and are
+cited in square brackets in the form
+\b{[}$<$\i{firstauthor}$><$\i{year}$>$\b{]}.
+All references cited in the text appear in the reference list and the index.
+
+\thing{Special terms:} New or important terminology has been set in bold
+face and appears in the index.
+
+\thing{Typesetting:} This\x{typesetting}
+document was prepared by the author using Andrew
+Trevorrow's\xn{Andrew}{Trevorrow} (\p{akt150@cscgpo.anu.edu.au})\checked{}
+implementation (OzTeX\x{OzTeX}) of the
+\TeX{}/\LaTeX{}\paper{Knuth84}\paper{Lamport86}\x{TeX}\x{LaTeX}
+typesetting system running on a Macintosh-SE.\x{Macintosh}
+
+\thing{Graphics:} All diagrams have been constructed out of text using
+the \LaTeX{}\x{LaTeX} \p{verbatim} environment so as to allow this document to
+be disseminated electronically and printed using \LaTeX{} without access
+to the author's drawing tools.
+
+% I think I've got rid of all the fix-it-up footnotes.
+%\thing{Correction footnotes:} Footnotes\x{footnotes}
+%commencing with dots ($\bullet$) are
+%notes to remind the author about something in the document that must be
+%attended to.\fix{This is an example of such a footnote.} These footnotes
+%will be attended to and eliminated in later versions.
+
+\thing{Known typesetting problems:} While every attempt has been made
+to give a good presentation within the
+time available, some shortcuts have had to be taken. In particular, the author
+has
+been unable to work out how to get \LaTeX{} to suppress blank pages at the
+start of chapters.
+
+%==============================================================================
+
+% No abstract.
+%\pseudochapter{Abstract}
+%\x{abstract}
+
+%==============================================================================%
+% End of Ch0.tex %
+%==============================================================================%
diff --git a/web/funnelAC/hackman/h_ch1.tex b/web/funnelAC/hackman/h_ch1.tex
new file mode 100644
index 0000000000..75b59696f8
--- /dev/null
+++ b/web/funnelAC/hackman/h_ch1.tex
@@ -0,0 +1,1107 @@
+%==============================================================================%
+% Start of Ch1.tex %
+%==============================================================================%
+%
+% Copyright
+% ---------
+% Copyright (C) 1992 Ross N. Williams.
+% This file contains a chapter of the FunnelWeb Hacker's Manual.
+% See the main TeX file for this manual for further information.
+%
+%==============================================================================%
+
+\chapter{FunnelWeb Design}
+\label{chapdesign}\xx{FunnelWeb}{design}
+
+This chapter contains notes on the design of FunnelWeb. These notes were
+not created \dq{from scratch}, as the original
+version of FunnelWeb (\newterm{FunnelWeb V1}) was designed
+and constructed in a hurry late in 1986, and no design notes were ever
+recorded.
+These notes are in fact the result of a complete review of the
+FunnelWeb design that took place in late 1991 as part
+of the process of upgrading it for public release.
+
+Throughout the design process I tried to stick to the principles of
+simplicity and clarity. As a rule, it was considered more important
+that a feature be simple and not allow the user to outsmart himself than it
+was for the feature to be particularly crisp. For example, the FunnelWeb
+macro calling syntax is not as crisp as the C syntax, but is
+more visible.
+
+To some extent the design review was influenced by the requirements of
+backward compatibility.\xx{backwards}{compatibility}
+During the review it was hard not to think about
+all the source files in FunnelWeb~V1 format that I have written over the
+years that would have to be
+converted were I to significantly deviate from the old input language.
+Luckily it turned out that there was little clash between these
+interests, and the resulting design is both clean and does not require
+much conversion of old source files.
+The main revision is in the document structuring facility.
+FunnelWeb~V1 had just two levels of heading indicated by \p{@*@*}
+(for major headings) and
+\p{@*} (for minor headings). This scheme (which was copied from Knuth's
+Web) has been replaced by a hierarchical scheme of five heading levels
+levels (\p{@A}$\ldots$\p{@E}).
+
+This chapter is rather unstructured, acting as it has, mainly as a
+dumping ground for random ideas about FunnelWeb.
+
+\section{Motivation for FunnelWeb}
+\xx{FunnelWeb}{motivation}
+
+During 1986, I was exposed to Donald Knuth's\xn{Donald}{Knuth}
+\p{WEB} literate
+programming system in the
+form of Jon Bentley's\xn{Jon}{Bentley}
+\i{Programming Pearls}\x{programming pearls}
+column in \i{Communications\x{Communications of the ACM} of
+the ACM}\/\paper{Bentley86}.\footnote{As it happens, this was somewhat of a
+lucky encounter. I had only just joined the ACM and
+the May 1986 issue of CACM in which the column appeared was the first
+issue I received.} This prompted me to obtain a copy of the
+report on the Web system\paper{Knuth83}
+and to try out the program which had been installed on the local Vaxen.
+
+Web was the best system that I had seen for producing printed and
+online, inline documentation. To me
+the most extraordinary aspect of the system was
+its success despite the fact that it had been built into the horribly antiquated
+file/batch processing systems that we all know and love (and use). I had
+imagined sophisticated documentation systems before this time, but had always
+assumed that they would be parts of complex programming environments.
+Knuth showed that, to some extent, it can be done using 1960s
+software technology (excluding the 1980s typesetting technology).
+This was exciting.
+
+The Web system was enticing and promising but to me suffered from many
+drawbacks, many of which Knuth had promoted as advantages. The following highly
+subjective list of disadvantages formed a springboard for the construction of
+FunnelWeb.
+
+\begin{itemize}
+
+\item Web can only process Pascal\x{Pascal} programs.
+
+\item Web can produce only one output file. In many instances it is
+desirable to generate more than one output file. For example, when programming
+in Ada, it is desirable to write a package specification and a package body
+together in the same file.\xx{number}{output files}
+
+\item Web enforces Knuth's individual style of indentation. Web supplies
+commands to over-ride the automatic indentation but it is an uphill battle and
+the code becomes clogged up with format directives.\x{indentation}
+
+\item Web does not cater for non-standard Pascal programs. In particular, all
+identifiers are truncated to about eight characters.
+
+\item Web formats the program output file into a form that is unreadable to
+humans.
+
+\item Web does not provide an include facility.
+This was considered a feature essential for supporting macro libraries.
+
+\item Web provides macros with at most one parameter. Knuth
+describes a hack that can
+extract a multiple parameter macro facility from a single parameter one,
+but it is hardly satisfactory.
+
+\item Web does not provide conditionals.
+
+\end{itemize}
+
+Most of these objections boiled down to two points:
+that Web is far too
+specialized, and that Knuth's \dq{Occam's Razor}\x{Occam's razor}
+had cut too far.
+What I wanted was
+a documentation system that employed all the same principles as Web
+but was far
+more general. The result was FunnelWeb~V1, which can
+process programs in any
+language or any combination of languages at the cost of typesetting the text in
+\p{tt font}.
+
+Originally, it was intended that FunnelWeb would be typesetter independent as
+well as language independent. It was intended that a format file consisting of a
+set of productions describing how the document file was to be formatted would be
+handed to FunnelWeb along with the input file. In the end, time pressures forced
+me to take the back door and hack up a \TeX{} document file generator. This
+compromise has found its way into FunnelWeb~V3.0 which is still reliant
+on \TeX{}, although V3.0 at least encourages input files to be typesetter
+independent. It is hoped that future versions of FunnelWeb will include
+more sophisticated typesetting facilities.
+
+\section{Indentation}
+\x{indentation}\xx{indentation}{no}%
+\xx{indentation}{blank}\xx{indentation}{text}
+
+A macro call that does not appear at the left margin is called an
+\newterm{indented macro call} and seems to lead to three different
+alternatives for its expansion: \newterm{no indentation}, \newterm{blank
+indentation}, and \newterm{text indentation}. Here are examples of each kind
+of indentation. First the example problem.
+
+\begin{verbatim}
+@$@<Sloth@>==@{@-
+Aardvark
+Walrus@}
+
+@O@<Output@>==@{@-
+Zebra@<Sloth@>
+Giraffe
+@}
+\end{verbatim}
+
+There are three ways that the second line of the \p{Sloth} macro
+can be indented.
+
+\thing{No indentation:}
+\begin{verbatim}
+ ZebraAardvark
+ Walrus
+ Giraffe
+\end{verbatim}
+
+\thing{Blank indentation:}
+\begin{verbatim}
+ ZebraAardvark
+ Walrus
+ Giraffe
+\end{verbatim}
+
+\thing{Text indentation:}
+\begin{verbatim}
+ ZebraAardvark
+ ZebraWalrus
+ Giraffe
+\end{verbatim}
+
+No indentation is useful where the user wishes to deal with the output
+stream as a pure output stream. Blank indentation is useful when the user
+wishes to generate indented computer programs.
+Text indentation is useful where the user wishes to prefix each line of an
+entire macro invocation with a string. This can be useful for
+commenting out code (\eg{}in Ada using \p{--}), and for prepending things
+like a dollar sign at the start of each line an a VAX VMS DCL script
+command file.\x{DCL}
+
+FunnelWeb~V1 provided a choice of no indentation or blank indentation.
+The choice was made in the command line and could not be overridden.
+
+The design questions are as follows:
+
+\begin{enumerate}
+\item Which of the three kinds of indentation should FunnelWeb support?
+\item What should be the granularity of swapping between indentation modes?
+\item Are particular indentation modes dangerous?
+\item Is the presence of particular combinations of indentation modes
+ confusing to the user?
+\item How and when should the choice of indentation be specified?
+\end{enumerate}
+
+All sorts of schemes were considered, including a finely grained system in
+which the user could specify at the point of call which indentation mode
+should be used for the called macro expansion.
+
+After a lot of thought, the dominant factor that should affect the design
+was decided to be the \i{clarity} in the user's mind of the indentation facility
+and the \i{danger} associated with misunderstanding it. Here are two
+examples that show how easily a confusion or
+misunderstanding of the indenting being used can cause danger.
+The first example shows how blank or no indentation might be
+misused.
+
+\begin{verbatim}
+--Misuse of blank (and no) indentation.
+--@<Sloth@>
+\end{verbatim}
+
+Here the user has assumed that text indentation is in action and has
+placed an Ada comment symbol \dqp{--} before the invocation of the macro
+\p{@<Sloth@>} in the hope that the entire text of the macro would be prefixed by
+\dqp{--}. The result could be passed by the compiler which would activate all
+but the first statement in the expansion of macro \p{@<Sloth@>}.
+
+The next example demonstrates how text indentation could be
+misused.\xx{indentation}{dangers}
+
+\begin{verbatim}
+--Misuse of text indentation:
+a++; @<Sloth@>
+\end{verbatim}
+
+Here the user has placed the call to \p{@<Sloth@>} after the incrementing of
+variable
+\p{a}. The result is that there is a good chance that the \dqp{a++;}
+prepended to
+each line of the expansion of \p{@<Sloth@>} will be passed by the compiler and
+will cause \p{a} to be overincremented.
+
+These examples are not to be laughed at. It is possible that FunnelWeb will
+be used widely, and the problems above may cause problems in critical systems.
+The examples above are particularly scary because they are reflexive. One cannot
+simply pin the blame on one particular indentation form. A little thought
+reveals that the greatest danger lies in \i{confusion} in the user's mind.
+If the
+user is confused between text or blank indenting, problems will arise.
+
+There seem to be two ways to solve the problem. The first is to ban all
+macro calls that are preceded by non-blank text. This is not a good option
+because there are so many cases where it is desirable to expand more than one
+single line macros on the same line. A second option is to eliminate one of
+the two forms so as to reduce the potential for ambiguity in the user's
+mind. I choose the latter option. Of the two forms, the clear choice for
+elimination is text indenting for the following reasons:
+
+\begin{enumerate}
+\item It actually introduces extra text which gives it an a priori
+ potential for problems.
+\item It is harder to implement and would slow down Tangle.
+\item It would not be compatible with FunnelWeb~V1 which uses blank
+ indentation.
+\end{enumerate}
+
+The only other decision is the level of granularity of choice between the
+remaining options: no indentation and blank indentation. FunnelWeb~V1
+allowed this choice to be made in the command line. In retrospect, this
+was bad design because the user might unwittingly code certain macro calls
+relying on one or the other mode. A better system is to allow the user
+to specify which mode in the input file itself. This has been done in
+FunnelWeb~V3.
+
+Again, to avoid confusion, it seems sensible to allow the user only
+one indentation mode per FunnelWeb input file. In most cases, the user
+will be happy with blank indentation (the default) and there will be
+no need for change anyway.
+
+\thing{Decision:} Implement only \dq{no indentation} and \dq{blank indentation}.
+Make the
+choice of indentation a static attribute of a particular FunnelWeb run
+that is specified in the input file. This solution is the same as FunnelWeb~V1
+except that the choice has been moved from the command line to the
+input file.
+
+\section{Review of FunnelWeb Syntax}
+\xx{FunnelWeb}{syntax}
+
+One of the distressing aspects of FunnelWeb~V1 was its clumsy macro
+definition and calling syntax.
+Compared to (say) the C preprocessor, FunnelWeb's macro call syntax is
+like a freight train in a china show.
+During the FunnelWeb redesign, a complete review of this syntax took place to
+try to neaten it up. Surprisingly, the V1 syntax survived unscathed
+with the exception that \dqp{==}\x{==} in macro definitions was made optional.
+The survival of this clumsy syntax was a product of the design goal of
+making everything simple, explicit, and not subject to subtle errors.
+
+\subsection{Review of Macro Definition Syntax}
+\xx{macro definition}{syntax}
+
+FunnelWeb~V1 used a macro definition syntax that resulted in macro
+definitions such as the following.
+
+\begin{verbatim}
+@$@<Put out the cat@>==@{@-
+Open the door
+Say out
+Close the door@}
+\end{verbatim}
+
+This is messy, but I couldn't think of anything better at the time.
+The \p{@\$} is necessary to cue a definition. Without it, the definition
+might somehow be mistaken for an invocation.
+The \p{@<} and \p{@>} delimit the name.
+The \p{@$\{$} and \p{@$\}$} delimit the text.
+The \p{@-} is a product of the rule
+\dq{exactly the text between the \p{@$\{$} and \p{@$\}$}}.
+
+The only real target is the \dqp{+=} and \dqp{==} which really break all
+the rules
+and should be changed. Unfortunately I couldn't
+think of anything to change them
+to. If there was no \p{+=} mechanism, we could use:
+
+\begin{verbatim}
+@$@<Put out the cat@>@{
+Open the door
+Say out
+Close the door@}
+\end{verbatim}
+
+In fact, eliminating \p{+=} is thinkable because it does not appear in
+many of my existing FunnelWeb source files. This indicates at least that
+it was not needed much by myself.
+
+A minimalist construct could be
+
+\begin{verbatim}
+@<Put out the cat@>
+Open the door
+Say out
+Close the door@}
+\end{verbatim}
+
+but this is too dangerous for my tastes.
+
+\thing{Decision:} For compatibility reasons,
+retain the old \p{+=} and \p{==} constructs, but make them optional.
+The new syntax for defining macros is:
+
+\begin{verbatim}
+@$@<Put out the cat@>@{
+Open the door
+Say out
+Close the door@}
+\end{verbatim}
+
+Next we turn to parameterized macro
+definitions.\xx{parameterized macro definitions}{syntax}
+A conventional FunnelWeb parameterized macro definition looks like this:
+
+\begin{verbatim}
+@$@<Put out the cat@>@(@3@)==@{@-
+Open the door
+Say out
+Close the door@}
+\end{verbatim}
+
+which is a bit messy. The natural alternative is even worse:
+
+\begin{verbatim}
+@$@<Put out the cat@>@(@1@,@2@,@3@)==@{@-
+Open the door
+Say out
+Close the door@}
+\end{verbatim}
+
+Thus, just specifying the number of parameters seems sensible. However,
+perhaps the syntax could be trimmed to
+
+\begin{verbatim}
+@$@<Put out the cat@>@3==@{@-
+Open the door
+Say out
+Close the door@}
+\end{verbatim}
+
+I decided to reject this in favour of the old syntax.
+
+\thing{Decision:} Retain the old syntax of $\ldots$\p{@(@3@)}$\ldots$
+
+\subsection{Review of Macro Call Syntax}
+\xx{macro call}{syntax}
+
+Here are some ideas for alternatives to the FunnelWeb~V1 macro call syntax.
+
+\begin{verbatim}
+Open the door
+@<Say Out@> @! FunnelWeb~V1 style.
+Close the door
+
+Open the door
+@<Say out>@
+Close the door
+
+Open the door
+@"Say out@"
+Close the door
+
+Open the door
+@(Say out@)
+Close the door
+
+Open the door
+@<Say out>
+Close the door
+\end{verbatim}
+
+\thing{Decision:} Continue with the old notation. It may not be neat, but at
+least it is clear and consistent. The main temptation is the format
+\p{@<say out>@}
+which looks rather good. However, it breaks the special sequence
+rational and hence is too confusing.
+
+\subsection{Review of Parameterized Macro Call Syntax}
+\xx{parameterized macro call}{syntax}
+
+FunnelWeb~V1 provided a messy parameterized macro call syntax:
+
+\begin{verbatim}
+@<Say Out@>@(@"firstparam@" @, @"Secondparam@" @, @"thirdparam@" @)
+\end{verbatim}
+
+This syntax can be cleaned up considerably by making the \p{@"} symbols
+optional. This results in calls such as the following:
+
+\begin{verbatim}
+@<Say Out@>@(firstparam@,Secondparam@,thirdparam@)
+\end{verbatim}
+
+As the first form allows the alignment of complicated parameters by
+allowing white space to be inserted outside the \p{@"}, and the second
+form is cleaner, both are retained simply by making the quotes optional.
+
+\thing{Decision:} Make the double quotes optional.
+
+\section{Document Structuring}
+\xx{document}{structure}\x{headings}\x{sections}
+
+Experience with FunnelWeb~V1, which provided only two levels of
+headings (major and minor)
+proved that there was a strong need for fully hierarchical
+multiple-level headings.
+The only question was how it should be done.
+
+Here are some ideas that were considered.
+
+\begin{verbatim}
+@*@<Main Program@>
+@**@<Read the Message@>
+@***@<Encrypt the Buffer@>
+
+@*@<Main Program@>
+@*@*@<Read the Message@>
+@*@*@*@<Encrypt the Buffer@>
+
+@s@<Main Program@>
+@ss@<Read the Message@>
+@sss@<Encrypt the Buffer@>
+
+@s@<Main Program@>
+@s@s@<Read the Message@>
+@s@s@s@<Encrypt the Buffer@>
+
+@S@<Main Program@>
+@SS@<Read the Message@>
+@SSS@<Encrypt the Buffer@>
+
+@S@<Main Program@>
+@S@S@<Read the Message@>
+@S@S@S@<Encrypt the Buffer@>
+
+@A@<Main Program@> -- The syntax finally chosen.
+@B@<Read the Message@>
+@C@<Encrypt the Buffer@>
+
+@A Main Program
+@B Read the Message
+@C Encrypt the Buffer
+
+@*A Main Program
+@*B Read the Message
+@*C Encrypt the Buffer
+
+@1@<Main Program@>
+@2@<Read the Message@>
+@3@<Encrypt the Buffer@>
+(using @A..@I@ as macro parameters or overload @1..@9)
+
+@*@1@<Main Program@>
+@*@2@<Read the Message@>
+@*@3@<Encrypt the Buffer@>
+(using @A..@I@ as macro parameters or overload @1..@9)
+\end{verbatim}
+
+Choosing between these alternatives was not easy. The following thoughts
+contributed to the decision.
+
+\begin{itemize}
+
+\item Syntaxes that require visual counting are probably not a good idea.
+
+\item Syntaxes that do not delimit the heading name somehow are likely
+to cause problems where heading names are omitted. Users will be
+tempted to start paragraphs after the start of heading symbol and the
+result is that the first line of the paragraph will be sucked into the
+heading.
+
+\item Overloading the \p{@1}, $\ldots$, \p{@9} sequences is undesirable.
+
+
+\end{itemize}
+
+\thing{Decision:} Use \p{@A}$\ldots$\p{@E} with optional following
+macro name syntax for the section name.
+Note: We stop at \p{@E} because five levels is probably sufficient, and we
+may wish later to use \p{@F} for \b{F}ile (to augment or replace \p{@O}).
+
+
+\section{Discussion of Some Miscellaneous Issues}
+\xx{miscellaneous}{issues}
+
+\thing{Comment duplication:} If\xx{comment}{duplication}
+the FunnelWeb user inserts
+comments into the target code (in the \p{.fw} file) as well as into the
+documentation (free text)
+part of the \p{.fw} file, then it is possible for the
+situation to get a bit silly. \b{Decision:} This is a problem for the
+programmer, not for FunnelWeb.
+
+\thing{Out-of-date documentation:} Sometimes\xx{out of date}{documentation}
+it is all too easy for the
+programmer to modify the code without updating the surrounding documentation.
+\b{Decision:} This is a serious and major problem. In an automated environment,
+it may be possible to create a system of dependencies between scraps of
+code and scraps of documentation. However, it is hard to see how a tool
+such as FunnelWeb could provide support for prevention of this sort of error.
+
+\thing{Meta-macro-level parameterization:} Sometimes, when using FunnelWeb,
+the facility to use one macro to construct the name of another has been
+needed. \b{Decision:} Allowing macro names
+to be constructed would lose the simple
+nature of the preprocessor and so this suggestion is rejected.
+
+\thing{Clumsy notation:} The \p{@} notation can be clumsy.
+\b{Decision:} This is necessary to maintain the simplicity of the translation.
+
+\section{Automated Regression Testing}
+\xx{regression}{testing}
+
+Automated regression testing is extremely important for two reasons:
+
+\begin{enumerate}
+
+\item It provides confidence that changes made to the program have
+not introduced bugs.
+
+\item It allows portability problems to be pinpointed when the program is
+moved to a new machine.
+
+\end{enumerate}
+
+The simplest way to set up automated regression testing is to construct
+a suite of test cases (and their solutions) and then write a
+script in the target machine's command language to run through the suite.
+Unfortunately, there is no command language that is shared among the
+machines to which FunnelWeb must be ported. These machines are at least:
+Macintosh, IBM-PC, Sun, VMS Vax.
+
+One option is simply to rewrite the script in each machine's particular
+command language. This would be a feasible option were it not for the fact
+that the Macintosh (the machine upon which FunnelWeb was developed) does
+not have a command language!
+
+After some thought, I decided that the best solution to the problem was
+to create a command language \i{within FunnelWeb}. FunnelWeb could then
+be invoked in two modes, one-shot command line or interactive/script. This
+approach had the benefit of providing total control over the command
+language and its complete portability.
+
+The result is described in the \i{FunnelWeb User's Manual}.
+
+\section{Command Line Interface}
+\xx{command line}{interface}
+
+FunnelWeb~V1 was implemented in Ada\x{Ada} and runs on a VMS VAX.\xx{vms}{vax}
+As such it
+has a full VMS DCL command line interface. Here is the \dqp{.CLD}
+file\xx{.cld}{file} for the
+DCL command line interface.
+
+\beginsmall
+\begin{verbatim}
+! FUNNELWEB Command Definition
+! ============================
+! Ross Williams. 28 April 1987.
+
+module command_table
+ define verb dummy_command
+ parameter p1 , label=input_file ,value(required,type=$file)
+ qualifier include_files, label=include_files,value(type=$file) ,default
+ qualifier output_files , label=output_files ,value(type=$file) ,default
+ qualifier delete , label=delete ,default
+ qualifier tex_file , label=tex_file ,value(type=$file) ,default
+ qualifier listing_file , label=listing_file ,value(type=$file) ,default
+ qualifier brief , label=brief,value(type=$number,default=5),default
+ qualifier screen , label=screen ,value(type=$number,default=0)
+ qualifier trace , label=trace
+ qualifier file_spec , label=file_spec
+ qualifier compare
+\end{verbatim}
+\endsmall
+
+As portability was a key goal of FunnelWeb~V3, it was obvious that the
+command line interface would have to be redesigned. The design goals for the
+new command line interface were:\xx{design goals}{command line interface}
+
+\begin{enumerate}
+
+\item The interface should not \i{depend} on case. However, it must allow
+ case-sensitive filenames to be transmitted on systems that have
+ case-sensitive filenames.
+
+\item Each option must have a symmetric positive and negative form. For
+ example, it is confusing for \p{-X} to turn on a feature and \p{-Q}
+ to turn it off.
+
+\item The interface must be extensible to allow inclusion of more features
+ at a later date.
+
+\item Options should be consistent and memorable.
+
+\end{enumerate}
+
+The result is described in the \i{FunnelWeb User's Manual}.
+
+\section{File Name Management}
+\xx{file}{names}
+
+File names present a host of problems for a program like FunnelWeb.
+First, FunnelWeb can generate so many different kinds of files that
+conventions must be adopted to prevent them from becoming unmanageable.
+Second, the constraints on file names, and even the structure of file
+names themselves varies considerably from machine to machine. These two
+problems have combined to result in the sophisticated and
+rather complicated way in which FunnelWeb~V3 handles filenames.
+
+To summarize, the three problems are:
+
+\begin{enumerate}
+\item What filename extensions should be chosen for various kinds of file?
+\item What filename inheritance should take place?
+\item How should FunnelWeb cope with the variations in filename structure
+between machines?
+\end{enumerate}
+
+The following three sections address these questions.
+
+\subsection{Filename Extensions}
+\xx{filename}{extensions}
+
+FunnelWeb is capable of reading and writing a variety of different kinds
+of files. In particular, FunnelWeb must often operates in an environment where
+the same information is stored in many forms (\eg{}prog.fw, prog.c, proc.exe).
+File extensions are an essential tool in managing this situation.
+The filename extensions chosen for FunnelWeb are:
+
+\begin{verbatim}
+FunnelWeb : .fw
+Product : None.
+Documentation : .tex
+Listing : .lis
+Journal : .jrn
+\end{verbatim}
+
+Lowercase will be used in systems that are case sensitive.
+
+Readers who are wondering how FunnelWeb copes in environments such as UNIX
+where there are no file extensions should refer to
+Section~\ref{portablefilenames}.
+
+\subsection{Filename Inheritance}
+\xx{filename}{inheritance}
+
+Inheritance in filenames refers to how input and output files inherit parts
+of their name from other filenames and their environment. For example if
+the command
+
+\begin{verbatim}
+ fw sloth +J +L +T
+\end{verbatim}
+
+was issued,
+you would expect to see output files \p{sloth.jrn}, \p{sloth.lis}, and
+\p{sloth.tex}.
+The output file names have inherited the \dqp{sloth}. The following table
+gives the hierarchy devised for FunnelWeb.
+
+\begin{center}
+\begin{tabular}{|l|l|l|l|l|l|l|l|} \hline
+ & Script & Input & Include & Journal & List & Document & Product \\ \hline
+1 & & & \p{@i} & & & & \p{@o} \\
+2 & \p{+x} & \p{+f} & \p{+i} & \p{+j} & \p{+l} & \p{+t} & \p{+o} \\
+3 & \dqp{.fws} & \dqp{.fw} & \dqp{.fwi} & \dqp{.jrn} & \dqp{.lis} & \dqp{.tex} & \\
+4 & & & \p{+f} & \p{+f} & \p{+f} & \p{+f} & \\
+5 & DefDir & Defdir & Defdir & Defdir & Defdir & Defdir & Defdir \\ \hline
+\end{tabular}
+\end{center}
+
+The following notes explain the table.
+
+\begin{enumerate}
+
+\item This scheme is similar to that used in FunnelWeb~V1.
+
+\item The journal, list, and documentation
+files all fall in the same pattern and
+can be considered as a single case.
+
+\item Level~1 has the highest priority because it is a direct specification
+by the user in the input file.
+
+\item Level~2 comes next because this is also a direct specification
+from the user on the command line.
+
+\item Level~3 provides the default file extensions.
+Product files do not inherit an
+extension as they could be of any type.
+
+\item Level~5 is built into most operating systems' file specification systems.
+If I specify file \dqp{x.y}, it is taken to mean on the default disk in the
+default directory.
+
+\item Level~4 looks straightforward, but secretly conceals a difficult design
+decision. By the time we get down to this level of inheritance, we know for
+sure that the filename has already picked up a file extension. So all that
+is left to inherit is the path and the filename proper. Obviously we
+have to inherit the filename proper (e.g. \p{sloth} in \p{sloth.tex}), but
+should we inherit the input file path? If we do inherit the input file
+path, files will be placed in the same directory as the input file. If we
+don't inherit the input file path, files will be placed in the current
+directory. The choice I have made is to send all the logging type files
+into the same directory as the input file. This means, for example,
+that \p{sloth.lis} and \p{sloth.tex} will generally land in the same directory
+as \p{sloth.fw}. However, I have decided that output files should be sent to
+the default directory (if not earlier specified) as this is where the
+action is. In normal use, the main product of FunnelWeb will be product files
+and so the user will expect them to appear in the current directory by
+default.
+
+\end{enumerate}
+
+\subsection{Portable Structure of File Names}
+\label{portablefilenames}\xx{file}{names}\xx{portable}{filenames}
+
+Another problem with file names is the variation of their structure
+between environments. Here are examples of some of the formats that prevail:
+
+\begin{verbatim}
+ UNIX /device/dir1/dir2/name
+ VMS node::device:[dir1.dir2]name.ext;vn
+ MSDOS device:\dir1\dir2\name.ext
+ MAC device:dir1:dir2:name
+\end{verbatim}
+
+Isn't it amazing that none of these popular systems use the same format?
+
+The solution to dealing with these different formats is to classify them
+as non-portable and hide the functions that manipulate them
+in the machine-specific module of FunnelWeb.
+Luckily there are not many such functions.
+
+The main problem is coping with
+file systems that do not
+explicitly support file extensions.
+With so many possible input and output files, FunnelWeb all but
+needs such extensions. Machines that do not support them pose difficult
+design decisions.
+If the user specifies \dqp{sloth} as an input file on such
+a non-extension-supporting system,
+should FunnelWeb look for \p{sloth}
+or \p{sloth.fw}? If the user specifies \p{walrus} as a listing file, should
+it generate \p{walrus} or \p{walrus.lis}?
+
+Some possible solutions are:
+
+\begin{enumerate}
+
+\item Regard the filename \p{sloth} as having an empty extension. It will then
+default to \p{sloth.fw}.
+
+\item Regard the filename \p{sloth} as having a blank but full extension.
+That is, it cannot be overwritten by inheritance, but it remains blank.
+
+\item Provide an extra syntactic mechanism to allow the user to specify one or
+other of the two options above.
+
+\end{enumerate}
+
+My solution was to choose the first option. Use of FunnelWeb
+results in lots of files lying around (\eg{}\p{sloth.lis}) and it is hard
+to see how
+the user will cope with them all
+without some kind of naming discipline. If a naming discipline
+has to be used, it might as well be the FunnelWeb one.
+
+Thus the names of all files read and written by FunnelWeb will have a file
+extension of from zero to three letters separated from the rest of the filename
+by a \dqp{.}.
+
+The only exception is product files whose extension is left
+undefined. Product files need not
+contain a \dqp{.} and a file extension,
+although they can inherit one if the user wishes.
+
+\section{Specifying Constraints on the Number of Instantiations}
+\xx{invocations}{number}
+
+Experience with FunnelWeb~V1 demonstrated
+the need to be able to specify in
+macro definitions how many times it was expected that the macro would
+be used. FunnelWeb~V1 generates an error if a macro is not used, but
+permits macros to be called more than once. This caused problems for macro
+libraries, which would be included, but whose macros were often not called.
+
+By default, FunnelWeb~V3 requires that each macro (except for the ones
+attached to output files) be called exactly once.
+However, it also provides
+syntax that allows the user to specify that a macro be allowed
+to be called zero times or many times.
+This allows a macro to be specified with the following permissible ranges
+of numbers of calls depending on the presence or absence of \dqp{@Z} and
+\dqp{@M}:
+
+\begin{verbatim}
+ 0..1 @$@<Sloth@>@Z==...
+ 1 @$@<Sloth@>==...
+ 1..n @$@<Sloth@>@M==...
+ 0.....n @$@<Sloth@>@Z@M==...
+\end{verbatim}
+
+The only two problems with this scheme are:
+
+\begin{enumerate}
+
+\item It is incompatible with
+FunnelWeb~V1 files, as the default in FunnelWeb~V1 is $1 \ldots n$
+whereas the default in new FunnelWeb is $1$. This is not a big problem because
+most macros in the old files were used exactly once. Only a few macros will
+have to be changed.
+
+\item What should the syntax be? (above is a sneak preview only!)
+
+\end{enumerate}
+
+The initial proposal for syntax was to allow the user to insert zero, one,
+or both of \p{@?} and \p{@M} just after the \p{@\$} of a macro definition.
+However, this has the following drawbacks:
+
+\begin{enumerate}
+
+\item It uses two sequences that are desirable to reserve
+ (\p{@?} for conditionals and \p{@M} for macro).
+
+\item It stops the user from searching for the string \p{@\$@<name} to find
+ the definition of a macro.
+
+\end{enumerate}
+
+These are significant problems.
+Here are some alternative
+ideas for where to position the modifiers in the macro definition:
+
+\begin{verbatim}
+@?@M@$@<Slothy dogs@>@(@5@)==@{@-
+This is a short macro.
+With only a line or two@}
+
+@$@<Slothy dogs@>@?@M@(@5@)==@{@-
+This is a short macro.
+With only a line or two@}
+
+@$@<Slothy dogs@>@(@5@)@?@M==@{@-
+This is a short macro.
+With only a line or two@
+\end{verbatim}
+
+The first form puts me off because I think that it is a good visual rule
+to start all the macros with \p{@\$}. The second form puts me off because it
+detaches the macro name from the parameter list, thus making it look
+less like a call, which is desirable syntactic resonance. The third form
+is messy but probably workable. Because we are right next to the tested
+constant string (either \p{==} or \p{+=}) we could augment it further. For
+example, \p{01==} could allow a macro to be called from 0 to 1 times.
+The main problem with this is that we are trying to phase out \p{==} anyway!
+
+Nevertheless, all the logic points to after the parameter list as the best
+place to locate this information.
+
+After some thought, it was decided that the \dqp{@?} sequence be reserved
+for a possible future conditional facility, and so \p{@Z} was used
+instead.
+
+\thing{Decision:} The position is after the parameter list. The notation
+is \p{@Z} for zero, and \p{@M} for many.\x{@Z}\x{@M}
+
+Example of final syntax:
+
+\begin{verbatim}
+@$@<Slothy dogs@>@(@5@)@Z@M+=@{@-
+This is a short macro.
+With only a line or two@}
+\end{verbatim}
+
+\section{The Relationship Between Document Structure and Macro Structure}
+\xx{document structure}{macro structure}%
+\xx{document}{structure}\xx{macro}{structure}\note{01-Dec-1991}%
+\xx{hierarchical}{structure}
+
+Having already decided upon a fully hierarchical document
+structure, I determined to refine the details.
+The issues to be addressed were as follows:
+
+\begin{itemize}
+
+\item How should the hierarchical structure connect to the macro structure?
+\item How can backwards compatibility be achieved? Should it?
+\item Should the macros be cross referenced by section or by definition?
+\item Should nameless sections inherit macro names as headings?
+\item Should we simply use \TeX{} macros to structure the document?
+
+\end{itemize}
+
+After some thought, I arrived at the following thoughts:
+
+\thing{Basically a \TeX{} file:} One option is simply
+to treat each \p{.fw} file as a \TeX{}\x{TeX} file
+laced with macros. That is, a \p{.fw} file could be
+structured as a real \TeX{} file from which FunnelWeb could
+extract macro definitions. This approach is feasible because
+\TeX{} could be programmed to
+respond to the \p{@} sequences in the same way that
+FunnelWeb responds to them. Thus, there would be no need for Weave.
+
+I rejected this approach, first because it is too typesetter-dependent,
+and second because it complicates the inclusion of any sort of
+complicated post-processing in the documentation file. This would have to
+be implemented in \TeX{}.
+
+A better approach is
+to use an invented section notation (e.g. \p{@A @B @C}). This maintains
+FunnelWeb's typesetter independence and can easily be
+converted into \TeX{} sectioning macros by Weave.
+
+In the same spirit, it might be worth introducing a few \p{@} sequences for
+certain general typesetting operations such as italics and program code.
+
+\thing{Confusion in FunnelWeb~V1 Heading Numbering:} FunnelWeb~V1
+uses two levels of section headings, but numbers all
+the headings sequentially. In this, it is a little confused. Clearly
+with a fully hierarchical document structure, the headings cannot be
+numbered sequentially --- the numbering must reflect the structure
+(\eg{}3.2.1).
+
+\thing{Hierarchical numbering is messy for macros:} Unfortunately,
+hierarchical numbering\xx{section}{numbering} is messy
+and confusing when applied to macro names.
+In FunnelWeb~V1's typeset output, each macro
+call has appended in square brackets the number of the section in which the
+macro is defined. Use of hierarchical numbering would be somewhat messy.
+For example, a macro call might look like.
+
+\begin{verbatim}
+ Write out the output[6.7.4.3]
+\end{verbatim}
+
+Similarly, cross reference lists would be messy:
+
+\begin{verbatim}
+ This macro is used in 3.4.5, 1.2, 7.8.9, 7.4, 2.2.1.1.
+\end{verbatim}
+
+\thing{Separate numbering for macros and headings:} One
+idea is to use hierarchical numbering for the sections, but to
+number the macros sequentially. This could be a little confusing in
+documents without much structure, but would be very much less messy than
+cross referencing using hierarchical numbering.
+Also, it will be easier to find macros
+indexed by a sequential number than by section,
+which has a less direct relationship
+with page bulk and number. By macro numbering is meant the sequential
+numbering of each macro body part through the whole document.
+
+\thing{Input format matters more than output format:} At this point we
+realize that a distinction should be made between
+the \i{input format} and the \i{typeset output}.
+The critical issue here is not how the
+program should be formatted for printing, but rather the format of its
+\p{.fw} file. The typeset output can always be changed simply by fiddling
+with Weave. However, as soon as the document structuring features of FunnelWeb
+are fixed, they will be used in dozens or hundreds of documents and it will
+be very difficult indeed to change them. Therefore, the important thing is to
+provide as sensible and expressive a \p{.fw} format as possible.
+
+It is therefore a separate decision as to whether we should number macros
+by section or by sequence number. The important thing is to address the
+format and rules for the expression of structure.
+
+\thing{Naming sections:} The naming
+of sections requires some thought. In many cases (especially
+in the case of high-level sections) the writer will provide an explicit
+name for a section. In other cases, provision of such a name will merely
+duplicate the name of the macro contained within the section. It therefore
+makes sense to allow the user to omit the name from a section, with Weave
+naming the section after the first macro definition in the section. If a
+macro is unnamed and there
+is no macro in the section, an error can be generated.
+
+All these thoughts lead to the following scheme:
+
+\begin{itemize}
+\item Documents will be hierarchically structured using \p{@A}, \p{@B} etc.
+\item Each section can be given a name delimited by \p{@<@>}.
+\item Sections that do not have names inherit the name of their first macro.
+\item If a section does not have a name or a macro, it is erroneous.
+\item Sections will be numbered hierarchically either by FunnelWeb or by \TeX{}.
+\item Macro body parts will be numbered sequentially by FunnelWeb and cross
+ referenced by these numbers.
+\end{itemize}
+
+All this results in a system which:
+
+\begin{itemize}
+
+\item Provides a hierarchical document structuring capability.
+\item Is typesetter independent.
+\item Does not require duplication between heading and macro names.
+\item Separates the heading and macro systems so that Weave can be configured
+ at a later date to cross reference in different ways without requiring
+ input files to be reworked.
+\end{itemize}
+
+\section{Diagnostic Messages}
+\xx{diagnostic}{messages}
+
+In FunnelWeb, all error messages commence with an indicator indicating
+the severity of the error message. Here are some of the formats that
+I investigated before settling on the final format:
+
+\begin{verbatim}
+W--Error creating sloth.
+E--Error opening output file.
+S--I'm a teapot.
+F--Can't open output file.
+
+W-Error creating sloth.
+E-Error opening output file.
+S-I'm a teapot.
+F-Can't open output file.
+
+W:Error creating sloth.
+E:Error opening output file.
+S:I'm a teapot.
+F:Can't open output file.
+
+W: Error creating sloth. -- Format chosen.
+E: Error opening output file.
+S: I'm a teapot.
+F: Can't open output file.
+
+War-Error creating sloth.
+Err-Error opening output file.
+Sev-I'm a teapot.
+Fat-Can't open output file.
+
+W-Old fashioned feature.
+
+W-Old fashioned feature.
+
+W--Old fashioned feature.
+
+W: Old fashioned feature.
+
+W:Old fashioned feature.
+\end{verbatim}
+
+\section{Summary}
+
+This rather unstructured chapter has addressed some of the key design
+decisions of FunnelWeb. In many cases, the alternatives have been
+unpleasant, but I am confident that in all cases, a fully workable solution
+has been found.
+
+%==============================================================================%
+% Start of Ch1.tex %
+%==============================================================================%
diff --git a/web/funnelAC/hackman/h_ch2.tex b/web/funnelAC/hackman/h_ch2.tex
new file mode 100644
index 0000000000..89cdf6fc86
--- /dev/null
+++ b/web/funnelAC/hackman/h_ch2.tex
@@ -0,0 +1,443 @@
+%==============================================================================%
+% Start of Ch2.tex %
+%==============================================================================%
+%
+% Copyright
+% ---------
+% Copyright (C) 1992 Ross N. Williams.
+% This file contains a chapter of the FunnelWeb Hacker's Manual.
+% See the main TeX file for this manual for further information.
+%
+%==============================================================================%
+
+\chapter{FunnelWeb Implementation}
+\label{chapimplementation}\xx{FunnelWeb}{implementation}
+
+\section{Introduction}
+
+This chapter contains notes on the actual C code that implements
+FunnelWeb~V3. This chapter is rather patchy. It has acted mainly as
+a dumping ground for ideas that I bothered to write about during
+development.
+
+\section{History of FunnelWeb Implementations}
+\xx{FunnelWeb}{history}\x{FunnelWeb version 1}\x{FunnelWeb version 2}%
+\x{FunnelWeb version 3}
+
+The first implementation of FunnelWeb (FunnelWeb~V1) was written in
+Ada\x{Ada}
+in December 1986. The project was initially canned as requiring too
+much time, but was resurrected when I decided to commit to
+Ada\paper{USDOD83} and
+realized that I needed a program to write to help me to learn Ada.
+FunnelWeb~V1 was, in fact, my first Ada program. It took about one
+month to write.
+
+FunnelWeb~V1 was used intensively by myself to write Ada programs
+from January~1986 to July~1989 at which time
+I finished my Ph.D.\x{Ph.D.} and lost access to
+the VAX. During this time at least twenty thousand lines of code were generated
+using FunnelWeb. Hardly anyone but myself used
+FunnelWeb.\xx{FunnelWeb}{past use}
+
+After losing access to Ada and the Vax (and hence to FunnelWeb), I was forced
+back to programming the non-literate way. From time to time I found that I
+needed to use some of my old programs that I had written using Ada and
+FunnelWeb. I knew that Ada would become available on more machines, but
+certainly FunnelWeb wouldn't. I recognised a strong need for a portable
+version of FunnelWeb written in~C but didn't have the time or energy
+to create one.
+
+About this time (late 1989), David Hulse,\xn{David}{Hulse}
+at the time a student in
+Computer Science at the University of Adelaide,\xx{University}{Adelaide}
+volunteered to translate the 4000 line Ada version of FunnelWeb into~C.
+To my knowledge this translation process took about three weeks
+(in December 1989). The result was called FunnelWeb~V2 and was
+formally signed into the public domain on 5~May 1992.
+
+In general, David Hulse did a good job. However, the resultant code
+suffered from one or few serious defects, the most serious of which was
+a lack of portability.
+
+Lack of portability of the C~code, combined with the need for a rather
+solid design review, combined with the need to
+strengthen the program to bring it up to production standard, resulted
+in my performing a complete reworking of the code. The C code was
+entirely, but incrementally, replaced or reformatted.
+The code was also strengthened and new features were added.
+This process took about two months (November and December 1991).
+A further two months (approx) were spent writing documentation, constructing
+a regression test suite, porting the program to different machines,
+and sorting out the legal issues involved in its release.
+
+I would like to take this opportunity to record a debt of gratitude to
+David Hulse who translated FunnelWeb from Ada to~C. Although my
+reworking of his C~code obliterated most of his code,
+his translation was pivotal to the development process.
+Without his effort in moving from Ada to~C, I'm not sure that I
+would have mustered the energy and time to complete the process and
+bring FunnelWeb up to its current standard.
+
+\section{Why FunnelWeb Wasn't Used to Write Itself}
+\xx{FunnelWeb}{writing itself}
+
+After Knuth created the Web literate preprocessing system, he
+re-wrote it using Web and distributed the source code in Web source form.
+To allow the Web source code to be tangled by users not yet having a
+copy of Web, he also included the tangled Pascal code for the Tangler.
+
+While this approach is heroic and serves to convey a commitment and
+a confidence in literate programming, it seemed to me that writing FunnelWeb
+in FunnelWeb would simply be asking for trouble.\xx{trouble}{asking for}
+For a start, it would be
+very hard to modify any feature of FunnelWeb that had been used to write
+FunnelWeb, and the thought of what would happen if the working executable
+became inoperative for some reason does not bear thinking upon.
+
+One million billion computer programs were written in the non-literate
+style before FunnelWeb was created. Why not one more?
+
+\section{Coding Style}
+\xx{coding}{style}
+
+Although FunnelWeb wasn't coded under any particular coding standard,
+it was coded in accordance with a fairly strict personal style of C
+which developed during the development of FunnelWeb. This style was
+subsequently embodied in a real C coding standard prepared for the
+South\x{South Australian Government Department of Lands}
+Australian Government
+Department of Lands.\footnote{The standard
+is currently unavailable, but is likely to be released or
+published eventually.} Unfortunately, FunnelWeb was not
+formally developed under the standard and so some holes remain in
+FunnelWeb's coding style. This section aims to describe some of the more
+important aspects of the coding style.
+
+\thing{Portability:} This\x{portability}
+was a major goal of the FunnelWeb implementation.
+Two excellent books guided this move to portability.
+They were \paper{Rabinowitz90} (which deals with C code itself)
+and \paper{Horton90} (which deals with the portability of various library
+calls). Other works such as \paper{Kernighan88} and
+\paper{ANSI} were also helpful.
+
+\thing{Identifiers:} \paper{Rabinowitz90}\x{identifier}{length}
+specifies that for
+wide portability, identifiers of block and file scope should be unique to
+eight characters, and identifiers of program scope should be unique to
+six characters. I have gone further in FunnelWeb and actually made these
+restrictions actual limits on identifier length.
+
+Because names must be so short, a system of abbreviations was developed to
+organize the identifiers used within FunnelWeb. Each abbreviation consists
+of a letter pair. Here are \i{some} of the abbreviations
+used:\xx{identifier}{abbreviations}
+
+\begin{verbatim}
+bp - Body Part.
+cm - Compare. Used to prefix comparison routines that return [-1,0,1].
+dc - Document component.
+dm - Dump package.
+el - Element.
+eq - Equal. Used to prefix comparison routines that return a boolean.
+ex - Expression.
+f - Global files.
+ll - List of lists.
+ln - Line record.
+ls - List Package.
+lr - Lister package.
+ma - Macro.
+mc - Macro Call.
+mn - Macro Name.
+op - Options package.
+pr - Parser.
+ps - Position record.
+sc - Scrap record.
+sn - Section.
+tb - Table package.
+ty - Typesetter directive.
+wf - Write file package.
+wl - Write with EOL (misc.c).
+wr - Write (misc.c).
+\end{verbatim}
+
+\thing{Pointers:} Variables or types denoting
+pointers\xx{pointers}{naming} start with \dqp{p\_}.
+
+\thing{Types:} Names denoting types end in \dqp{\_t}.
+Thus, a type for a pointer to a table would be named
+\p{p\_tb\_t}.\xx{types}{naming}
+
+\thing{File names:} All files\xx{filenames}{length}
+used in FunnelWeb have file names that are
+from one to eight characters long and file extensions that are from one to
+three characters long. This ensures that the files can be portably moved
+to all kinds of machines, even MSDOS!\x{MSDOS}
+
+\section{Use of Memory}
+\xx{use of}{memory}
+
+FunnelWeb is not a memory-stressed program. However, during its development,
+problems with the management of memory seemed to crop up again and again.
+This section documents some of these problems and the solutions adopted.
+
+There are three places where memory can be obtained: the heap, the stack,
+and from static variables. The following three sections deal with each
+of these areas.
+
+\section{The Heap}
+\xx{heap}{memory}
+
+One of the great frustrations of being a user is to find that a computer
+program is complaining about lack of memory when one knows full well that
+one has allocated at least ten times as much memory to the program as it
+would ever need to do its job. The reason for such error messages usually
+has to do with the programmer setting a fixed \dq{reasonable} limit to
+a particular data structure and then locking it up into an array whose
+bound is specified by a constant. While the use of arrays can increase the
+speed of a program, it also means that the user cannot increase the capacity
+of the program without obtaining the source code and recompiling it,
+which is usually a daunting option.
+
+The alternative is to use the heap for all data structures that can
+grow in proportion to the size of the user's input. This rule has been
+followed rigorously in FunnelWeb. This means that as memory spaces
+increase, users will be able to hand their version of FunnelWeb more
+memory without having to recompile it.
+
+\topicbreak
+
+Some problems arose early on the Macintosh\x{Macintosh}
+in the use of the heap. It seems
+that some of the allocations I was attempting to make were failing for some
+obscure reason, possibly my fault. Whatever it was, it went away when I
+replaced direct calls to \p{malloc}\x{malloc}
+with calls to a mini package I wrote
+(called \p{memory}) that allocated large chunks of memory and then doled out
+small pieces as required by the rest of the
+program.\xx{memory}{package}
+
+Having a package to manage all the memory allocation had two other benefits.
+
+First, only one check was required in the entire program to see if memory
+had run out (in the memory package), and if that failed, the program could
+be brought to a screaming halt. This organization was far preferable to
+having each piece of code that needed to allocate memory having to check
+to see if \p{malloc} had failed.
+
+Second, the decision to construct a mini-shell within FunnelWeb to
+support regression testing meant that FunnelWeb proper could be run
+many times in any given invocation of FunnelWeb. As a consequence it was
+necessary to make sure that there was no memory
+leakage\xx{memory}{leakage} between invocations
+of FunnelWeb proper. This was accomplished by reworking the memory package
+to operate a watermark system. The user of the package, when requesting
+memory, could request \dq{temporary} or \dq{permanent}. If permanent, the
+memory package forgot that it had allocated the memory. If temporary, the
+memory package places the allocated block on a list. There was then a
+function in the memory package that could be called to deallocate all the
+temporary memory. Thus, so long as all requests for memory within FunnelWeb
+proper were for temporary memory, and that memory was freed at the end of
+every run, one could be sure that there was no memory leakage.
+
+\section{The Stack}
+\xx{stack}{memory}\xx{stack}{size}
+
+For a while during the development of FunnelWeb a particularly nasty bug
+proved extremely hard to find. The symptom was that FunnelWeb would crash,
+sometimes at random, but more often upon entering a particular function.
+In the end about a day of specific debugging was required before the problem
+was tracked down to a stack problem. It turned out that somehow
+(either the fault of the Macintosh or the THINK~C language system), only
+6K was being allocated for stack space!!!!!!!
+
+This experience led me immediately to go through the entire program and
+eliminate (or remove to the heap) any automatic variable declarations that
+used more than one hundred or so bytes.
+
+The lesson is clearly that C~programs that use more than a few thousand bytes of
+stack space are risking their portability. All large data structures should be
+placed in the heap.
+
+\section{Static Variables}
+\xx{memory}{static}\xx{static}{variables}
+
+Static variables also proved a problem on the Macintosh.
+It turns out that
+the Macintosh\x{Macintosh} THINK~C compiler\xx{ThinkC}{compiler}
+does not allow more than 32K of statics
+\i{in the entire program}. For a while this restriction was
+a serious threat to the program as it was discovered that constant strings
+were included in this total! However, some searching revealed a compiler
+option that removed the strings from the static category.
+
+Nevertheless, the 32K limit is rather severe. Again, it seems that for
+portability reasons, C~programs that use a lot of static variables are risking
+their portability. As a result, the FunnelWeb code avoids static variables
+where possible in favour of the heap.
+
+\section{Implementing Text Indentation}
+\xx{text}{indentation}
+
+At one point during the development of FunnelWeb, text indentation was
+fully implemented. However, it was subsequently removed because it was
+considered a dangerous feature. This section records the way in which
+text indentation was implemented so that if the feature ever has to be put
+back, this technique can be used again.
+
+
+1. Create a new field in the \p{sc\_t} record call \p{sc\_postn}.
+
+\begin{verbatim}
+ char *sc_postn; /* Pointer in the range [sc_first,sc_last+1]. */
+ /* It is the minimum possible value of sc_postn for */
+ /* which EOL does not appear in *sc_postn..*sc_last. */
+ /* i.e. Points to the byte following the first EOL in */
+ /* the scrap or sc_first if EOL does not appear. */
+\end{verbatim}
+
+2. Modify the scanner so that it generates this field.
+Sendtext should be modified so that
+it accepts an argument for the \p{p\_postn} value.
+
+\begin{verbatim}
+LOCAL void sendtext P_((p_ps_t,char *,char *,char *,bool));
+LOCAL void sendtext(p_tkps,p_first,p_last,p_postn,is_white)
+/* Appends a text token to the end of the token list. */
+/* IN: p_ps is a pointer to a position structure giving the position of the */
+/* first character of the token. */
+/* IN: p_first and p_last point to the first and last byte of the text scrap. */
+/* IN: p_postn has the same definition as sc_postn (see fwdata.h). */
+/* IN: is_white should be set to TRUE iff scrap is entirely whitespace. */
+p_ps_t p_tkps;
+char *p_first;
+char *p_last;
+char *p_postn;
+bool is_white;
+{
+ tk_t token;
+
+ /* Empty text scraps should never be generated. */
+ assert(p_first<=p_last,"sendtext: Text scrap bounds are bad.");
+
+ /* If ch=EOL then we should be scanning more text, not shipping it! */
+ assert(ch!=EOL,"senttext: Shipping text while still more to scan.");
+
+ /* Check that p_postn is in range. See definition in fwdata.h. */
+ assert(p_first<=p_postn && p_postn<=p_last+1,
+ "sendtext: p_postn is out of range.");
+
+ /* Debug: Check the p_postn field using a brute force check. */
+ {
+ char *i,*j;
+ j=p_first;
+ for (i=p_first;i<=p_last;i++)
+ if (*i==EOL)
+ j=i+1;
+ assert(j==p_postn,"sendtext: sc_postn field is incorrect.");
+ }
+
+ /* Load the text token. */
+ token.tk_kind = TK_TEXT;
+ ASSIGN(token.tk_ps,*p_tkps);
+ token.tk_sc.sc_first = p_first;
+ token.tk_sc.sc_last = p_last;
+ token.tk_sc.sc_postn = p_postn;
+ token.tk_white = is_white;
+ token.tk_parno = 0;
+ ls_add(token_list,PV &token);
+}
+\end{verbatim}
+
+Then all the calls to sendtext have to be changed:
+
+\begin{verbatim}
+/* @ instructs FunnelWeb to replace the special construct with the */
+/* special character. Luckily one appears just before the @ !! */
+/* Note: FALSE is OK because space is not a legal specialch. */
+/* Note: Setting parameter p_postn to p_ch-1 is OK as EOL is not a */
+/* legal specialch. */
+sendtext(&ps_spec,p_ch-1,p_ch-1,p_ch-1,FALSE);
+break;
+
+/* + instructs FunnelWeb to insert an EOL. We can't look to the end of */
+/* the previous line to find an EOL as this might be the first line. */
+/* Running ahead to the end of the line is expensive, and having the */
+/* liner mini-package maintain a variable for it would be extra */
+/* housekeeping. Instead of all this, we just point to a static. */
+{CONST static char stateol = EOL;
+ sendtext(&ps_spec,&stateol,&stateol,(&stateol)+1,TRUE);}
+break;
+
+/* If we hit something that ends a text token */
+/* then we can transmit a white text token. */
+if (ch==specialch || ch==EOFCH)
+ {sendtext(&ps_start,p_first,p_ch-1,MAX(p_sol,p_first),TRUE); return;}
+
+/* Otherwise we have some more (non-white) text to scan. */
+/* We can then send a non-white text token. */
+while (ch!=specialch && ch!=EOFCH)
+ NEXTCH;
+sendtext(&ps_start,p_first,p_ch-1,MAX(p_sol,p_first),FALSE);
+\end{verbatim}
+
+The dump code needs to be changed too!
+
+\begin{verbatim}
+ wf_str(p_wf,"\"");
+assert(token->tk_sc.sc_first !=NULL,"dm_tkls: NULL ptr1.");
+assert(token->tk_sc.sc_last !=NULL,"dm_tkls: NULL ptr2.");
+for (i=token->tk_sc.sc_first; i<=token->tk_sc.sc_last; i++)
+ {
+ if (i==token->tk_sc.sc_postn)
+ wf_str(p_wf,"<postn>");
+ if (*i=='\n')
+ wf_wl(p_wf,"");
+ else
+ dm_byte(p_wf,*((ubyte_ *) i));
+ }
+if (i==token->tk_sc.sc_postn)
+ wf_str(p_wf,"<postn>");
+wf_str(p_wf,"\"");
+}
+\end{verbatim}
+
+3. Over in the Tangle module, create a massive array of pointers to scraps
+to be used as a stack. Maintain pointers into the stack called \p{current} and
+\i{base} (similar to the blank indentation variables). Implement the following:
+
+\begin{itemize}
+
+\item To write out a scrap, scan it byte by byte. Output each byte. When
+you hit an EOL, pop the stack back to \p{base}. Then write out an EOL
+followed by the stack contents but writing each scrap only from \p{postn} to
+end end of each scrap.
+When you have finished the new scrap, push it on the stack.
+
+\item When you hit a new macro to expand, save \p{base}. Restore it later.
+
+\end{itemize}
+
+The \p{postn} field solves the big problem of
+how to cope with something like this:
+
+\begin{verbatim}
+The rain in Spain
+falls mainly @<on the plain@>
+\end{verbatim}
+
+The trouble is that we want to text indent the lines in
+\p{@<on the plain@>} with
+just \dqp{falls mainly~}. However, this string is only part of a scrap. The
+solution is to get the scanner to record, in the \p{postn} field of each scrap,
+the position of the first byte with a EOL-free run to the end of the scrap.
+
+This scheme is very efficient because all we are doing is pushing and popping
+pointers to scraps on a stack array. The main disadvantage is that the
+array must necessarily be finite and would impose a limit on the depth
+of indentation nesting (not a big problem).
+
+%==============================================================================%
+% Start of Ch2.tex %
+%==============================================================================%
diff --git a/web/funnelAC/hackman/h_ch3.tex b/web/funnelAC/hackman/h_ch3.tex
new file mode 100644
index 0000000000..5d4a5dd226
--- /dev/null
+++ b/web/funnelAC/hackman/h_ch3.tex
@@ -0,0 +1,549 @@
+%==============================================================================%
+% Start of Ch3.tex %
+%==============================================================================%
+%
+% Copyright
+% ---------
+% Copyright (C) 1992 Ross N. Williams.
+% This file contains a chapter of the FunnelWeb Hacker's Manual.
+% See the main TeX file for this manual for further information.
+%
+%==============================================================================%
+
+\chapter{FunnelWeb Modification}
+\label{chapmod}\xx{FunnelWeb}{modification}
+
+\section{Introduction}
+
+This chapter deals with modifications to FunnelWeb. Although the
+GNU license\xx{GNU}{license}
+under which FunnelWeb is distributed allows anyone to
+modify FunnelWeb and distribute the modified versions, there are a number of
+dangers in doing this. This chapter explains the dangers and presents
+some issues that you should think about if you intend to
+distribute modified versions of FunnelWeb.
+
+\section{The Danger of Modifying Languages}
+\xx{changes}{dangers}\xx{languages}{dangers}
+
+Whenever someone modifies a computer program they should always ask
+themselves \dq{what is the impact of these changes going to be on
+users}. For mature products, the degree of impact is largely determined
+by the investment that users have made in particular file formats
+supported by the product.
+
+At the two extremes, there are the video game\x{video game} and the
+compiler.\x{compiler}
+If one changes a video game, the change affects only the future games
+played. However, if one changes a compiler in particular ways,
+it is likely that thousands of users will be forced to change millions
+of source files to accommodate the new version. Thus the impact of changes
+to a program depends largely on the investment made by users, in
+source files, training, and even muscle memory!
+
+FunnelWeb lies very much at the compiler end of this spectrum. In fact
+it lies even further. Not only does it implement a language, but it is
+currently the \i{only} implementation of that language! This means that,
+although they shouldn't, people will be tempted to treat the FunnelWeb
+program as the definition of its input language instead of
+the definition chapter in the \i{FunnelWeb User's Manual},
+which takes precedence.
+
+Because FunnelWeb defines an input language, and people will write programs
+using that language, particular kinds of changes in the language will
+impact severely on users. Three different kinds of change are discussed
+below.
+
+\narrowthing{Removing features:}{Removal\xx{removing}{features}
+of features (featurectomy) is extremely
+difficult once the user base has started using them. If a feature is
+removed, users of the program will have to go through all their
+programs and find a way to simulate the effect of the removed feature
+with other features. Often this is so unthinkable, that bad language
+constructs are tolerated far beyond their useful lifetime.}
+
+\narrowthing{Modifying features:}{Modification\xx{features}{modification}
+of features has less
+direct impact than the removal of features, but can cause more subtle errors.
+For example, consider the sorts of subtle errors that might arise if the
+semantics of the FunnelWeb comment \p{@!} were changed so that it no
+longer includes the end of line marker. Anyone modifying features should
+be sure that they are not inadvertently laying traps.}
+
+\narrowthing{Adding features:}{Although\xx{features}{adding}
+the addition of features is
+generally the most painless for the user community, as Hoare points
+out, it is also the most dangerous in the long run.}
+
+\begin{quotation}
+\dq{When any new language design project is nearing completion, there is
+always a mad rush to get new features added before standardization.
+The rush is mad indeed, because it leads into a trap from which there is
+no escape. A feature which is omitted can always be added later, when its
+design and its implications are well understood. A feature which is
+included before it is fully understood can never be removed
+later.}\paper{Hoare80}
+\end{quotation}
+
+These problems exist even when there is a central authority.
+If we consider the case where there is no central authority, and
+users modify a language and its implementations and distribute the
+modified versions, the result is even worse. For a start, the
+structure of the genealogy of the program\xx{genealogy}{program}
+changes from a list to a tree.
+This makes it impossible to impose an ordering on the different versions
+and makes it difficult to merge them once they diverge. Second, it
+reduces the portability of files created under different versions.
+Third, it makes adding features hazardous. If a feature is added in
+one version, files will be created that use it. These files will
+immediately become non-portable. Furthermore, two programmers may
+introduce different features that use the same syntactical constructs,
+thus preventing the two versions from ever being merged. Worse, two
+programmers could introduce \i{similar} features that use the
+same syntactical constructs, producing even more subtle problems.
+
+The only way to avoid all these problems is to create some sort of
+central design authority,\xx{design}{authority}
+(or, at the very least, some sort of design
+synchronization) that controls the language and its implementation.
+
+The benefits of tight control over the language are enormous.
+
+\narrowthing{Universal portability:}{Source files can be treated as portable.
+If all the language
+implementations in the world are singing the same tune, then someone
+in Sydney could send a file to someone in New York and be
+sure that it will be successfully processed.}
+
+\narrowthing{Clear semantics:}{Doubt about the semantics of the
+language will be greatly minimized.
+So long as more than one slightly differing version of a language exists,
+there will be confusion over the semantics of its constructs. A good
+example is the confusion between the AT\&T Unix\x{Unix}
+and Berkeley Unix shell languages.}
+
+While changes to the language supported by a piece of software is the
+most serious problem associated with multiple versions of software,
+the lesser problem of keeping track of changes that don't affect the
+language that the software implements can also cause trouble. Merging
+different versions of software is extremely tedious as anyone who
+has tried it will verify. However, changes not affecting the
+language are far less serious because they impact only on the program
+itself, not on the far more numerous source files that depend on it.
+
+\section{Authority vs User Security}
+\xx{security}{authority}
+
+There are a number of ways of providing the
+strong central design authority required to produce
+the portability and semantic security desired by users,
+
+\begin{itemize}
+
+\item Trade mark\x{trademark}
+the name of the language. Publish a specification of the
+language under the trade name. Warn all users not to trust any
+implementation that does not guarantee that it implements the language.
+Then control implementations by only licensing the trade mark to conforming
+implementations.
+
+\item Create a single implementation of the language. Do not release
+the source code to the implementation. Release only binary executables.
+
+\item Release the source code to the implementation, but under a license
+that prohibits the distribution of modified versions.
+
+\end{itemize}
+
+Many other variations on these themes are possible, but they are all
+based on the idea of regulating either the \dq{official}
+definition of the language
+or all of its existing implementations.
+
+At about this stage, a conflict arises. While users want the language
+they are using to be tightly controlled, they also want to feel secure
+about the availability of its implementations. If hundreds of source
+files are to be created in the language, there had better be one or
+more translators available when the time comes to use them.
+
+In the case of widely-used programming languages such as~C, the problem of
+securing implementations does not arise. If you don't get your
+compiler from Borland, you can get it from Microsoft. However, in the
+case of a newly introduced language such as FunnelWeb, there may be
+very few implementations, or even just one implementation,
+and this poses a danger to the
+user who is committing to that format. Despite the best intentions of the
+copyright owner, there are a variety of ways in which a computer
+program can suddenly become
+unavailable.\xx{program}{availability} Here are some examples:
+
+\begin{itemize}
+
+\item If the program is owned by a company and the company goes broke,
+the liquidators may not bother to place the software in the public domain.
+
+\item If the program is owned by a kindly individual who issues licenses
+for free, and that individual suddenly dies, users might suddenly find
+themselves negotiating with hard-nosed estate executors for the rights
+to continue using the program.
+
+\item If whoever owns the program does not upgrade the program every so
+often, it is actually possible for the released
+executables to \dq{expire} when new operating system upgrades appear.
+
+\end{itemize}
+
+These possibilities mean that users about to invest in a newly
+introduced programming
+tool such as FunnelWeb have legitimate concerns when they worry
+about the tool's availability. For non-commercially
+distributed tools such as FunnelWeb, the simplest solution to this
+problem is to make the source code available, either by placing it
+into the public domain, or by releasing it under some kind of
+public license, such as a GNU license.
+The trouble with releasing the source code
+is that it removes control from the design
+authority. Once the code is \dq{out} there is no stopping anyone
+from modifying the program and distributing modified versions.
+All chaos can ensue.
+
+One solution to this conflict is to take the trade mark approach. This
+separates the right of the design authority to control the language and
+its implementations, and the right of the users to use the source
+code in any way they like (but they may have to change its name!).
+However, the trade mark approach is expensive.
+
+The solution that I (Ross Williams (\p{ross@spam.adelaide.edu.au}))
+have adopted is to release the FunnelWeb source code under a GNU license
+and then to write this chapter in the \i{FunnelWeb
+Hacker's Manual} to dissuade possible hackers from
+releasing modified versions under the FunnelWeb name.
+This is about as close to the GNU/trademark approach
+I can get without forking out about \$1200 for a US trademark
+or paying even more to get a lawyer to attempt to draft a contract
+stating \dq{thou shalt not modify the FunnelWeb language}.
+
+\section{What I Want to Protect}
+\xx{protection}{FunnelWeb}\xx{protection}{file extension}
+
+The concerns expressed in the previous section about modifications to the
+FunnelWeb program do not preclude modifications. They merely imply that
+some conditions be observed when modifications are made.
+In fact,
+having formally released the sources under GNU, there is nothing that
+I can do to stop people distributing modified versions and the conditions
+to be described must be imposed voluntarily.
+
+In the end there are two things that I want to protect/maintain:
+
+\begin{enumerate}
+
+\item Restriction of the name \dq{FunnelWeb} only to computer programs
+that exactly implement my \dq{official} definition of the language.
+
+\item Restriction of the FunnelWeb source file extensions \dqp{.fw}
+(input files) and \dqp{.fwi} (include files) only
+to source files that conform to my \dq{official} definition of the
+language.
+
+\end{enumerate}
+
+So long as these conditions hold, source files created under \dq{FunnelWeb}
+will be portable, and the language will have the potential to
+be stable and well-defined. Here are my suggestions for how to
+obey these rules. These suggestions are in addition to the GNU license
+rules about documenting any changes that you make in the source files.
+
+\narrowthing{Modifications that do not affect functionality:}{If you
+change the FunnelWeb program in a manner that does not
+affect the functionality of the program in any way (\eg{}port
+it to a new machine, or just speed it up),
+then you should modify the program to write out a message when it
+starts up saying that
+it is a modified version of FunnelWeb. No other actions need be taken.}
+
+\narrowthing{Modifications that affect functionality:}{If you make changes
+to FunnelWeb that affect its functionality (\eg{}changes to command line
+options, the command language, or the input language)
+you should change the name of the program so that the name
+no longer contains the word
+\dq{FunnelWeb}, and should choose alternative input and include-file
+file extensions (the current ones are \dqp{.fw} and \dqp{.fwi}). For example,
+you might call your program \dq{BananaWeb} and use the file extensions
+\dqp{.bw} and \dqp{.bwi}.}
+
+These rules are not very restrictive. Basically you can do what you like
+so long as you change the name of the resulting program. I do not wish to
+restrict anyone who might want to use FunnelWeb as a foundation for a more
+sophisticated literate programming system. My sole aim here is to
+protect the integrity of what already exists.
+
+\section{Modifying the Manuals}
+\xx{modifying}{manuals}
+
+While it is permitted to modify the FunnelWeb program, no license has been
+granted
+to modify its documentation (\i{The FunnelWeb User's Manual} and
+\i{The FunnelWeb Hacker's Manual}). The only operation that can be
+performed on the FunnelWeb documentation is a verbatim copy in any medium.
+
+If you have created a modified version of FunnelWeb and wish to document it,
+either write your own manual from scratch, or write a manual that can be
+used in conjunction with the existing manuals.
+
+\section{How Copyright Law Works}
+\xx{copyright}{law}
+
+In order to understand the next section, some understanding of copyright
+law is required. The assertions made in this section are not legal opinions;
+they are merely approximations of the law, based on my understanding of it.
+
+By default, whoever creates a \newterm{work} owns \newterm{copyright}
+over it. This means that by default, that person is the only person in the
+world who has the legal right to make copies of the work.
+
+Copyright over a work usually covers all direct derivations of this work.
+For example, if someone owns the source code to a computer program
+then they also own any direct derivations such as the binary executable.
+
+More than one person may own copyright over a work. If this is the case,
+then the work cannot be copied without the permission of all of the people
+owning the copyright.
+
+A person (or group) owning copyright over a work
+can \newterm{license} the right to make copies
+of the work to anyone he likes under any conditions he likes.
+
+If a work is modified, the result is called a \newterm{derived work}.
+
+If copyright on a work is owned by $A$ is the work is modified by $B$,
+copyright on the derived work is owned by both $A$ and $B$.
+
+Copyright is not ownership over particular configurations of information,
+but rather is the right to restrict the copying of information derived
+from particular sources. For example, if two people point their cameras
+out a window and take identical photographs, each person has the right
+to restrict the copying of \i{their} photograph regardless of the
+fact that the other person has copyright over an identical photograph.
+In the unlikely event that two people wrote
+novels that were letter for letter identical and it could be proven that
+there was no contact between the two people when they wrote the novels,
+then copyright law would each protect the right of each person to
+restrict the copying of the novel originating from \i{them}. In practice,
+the probability of such an event occurring is so low that the law
+assumes that if two works are close or identical, that there has been
+some information interchange at some point.
+
+Thus, if I own copyright on computer program $X$, and I create
+an identical copy of $X$
+called $Y$ and distribute it under the terms of a license agreement,
+then that license agreement does not cover the copy $X$. Once the
+license agreement is signed, there is nothing I can do to undo the
+license; $Y$ has gone. However, I still have total control over $X$.
+
+Version~2 of the GNU General Public License\xx{GNU}{license}
+(under which FunnelWeb is
+released) specifies (in a nutshell) that software can be copied freely
+so long as it is not sold, and that it can be modified and copied
+freely so long as the modifications are logged and it is not sold.
+In both cases, it requires that the
+result of the copy or modification operation
+be copied only under the conditions of the license.
+
+Once a declaration is issued licensing a copy of a program under GNU
+license, that license cannot be retracted.
+
+\section{Management of the Official FunnelWeb}
+\xx{FunnelWeb}{management}\xx{FunnelWeb}{official}
+
+I intend to maintain an official copy of FunnelWeb and release it under
+GNU license from time to time so that everyone can use it. Unfortunately
+its going to be a little messy.
+
+For a variety of reasons, I want to maintain
+total control over \i{my} copy of the official version of FunnelWeb.
+Some of the reasons are:
+
+\begin{itemize}
+
+\item If it turns out that there is an enormous demand for
+FunnelWeb (unlikely) then
+I want to be able to create a business based on it, or at least
+be able to bundle it with other products.
+This would be difficult if the only up-to-date copy available was a GNU copy.
+Note: If this happens, all the GNU releases of FunnelWeb will remain
+valid.
+
+\item I want to be able to copy code from my version of FunnelWeb
+into commercial products without having to worry about the GNU license.
+
+\end{itemize}
+
+The trouble is that (in my understanding of copyright law),
+once a copy of FunnelWeb has been released under GNU license, then it
+and any works derived from it fall under GNU license too. This means that
+if you modify a GNU release of
+FunnelWeb and send me your modifications, and I incorporate
+them into my version, then I no longer own copyright on the version I
+modified. Basically, if GNU touches a work, then that copy is gone forever.
+
+My solution to the problem is to keep a copy of FunnelWeb that is
+GNU-clean and only make modifications to it that are GNU-clean. So
+long as my official copy is GNU clean, any modifications that I make
+myself will be GNU clean. The problem comes when someone else modifies
+the GNU version and then wants me to incorporate the modifications into
+my official version. As I understand the law, by default, the programmer
+owns the modifications (because he made them), but the result of making
+the modifications falls under GNU license. What I propose is that those
+who want their modifications included in the official copy of FunnelWeb
+sign an agreement transferring copyright of the modifications over to
+me on condition that the result be released under GNU license within
+a certain time period. \figlicense{} demonstrates the process.
+
+\begin{figure}[htbp]
+\begin{verbatim}
+
+ +---------->----------+--------------<-------------+
+ |(modifications by | |
+ | me) V |
+ | +----------------------------------+ |
+ +--<--| My Official Copy of FunnelWeb | |
+ | Copyright (C) Ross Williams | |
+ +----------------------------------+ |
+ | (Periodic releases) / \
+ V / \ Programmers
+ +------------------+ /Legal\ sign away
+ | GNU Release Copy | \Filte/ copyright on
+ +------------------+ \ r / modifications
+ | \ /
+ | (Modifications made by |
+ V random programmers) --->--+
+ +-----------------------+
+ | Modified GNU Version |
+ +-----------------------+
+
+\end{verbatim}
+\mylabel{\figlicense{}: How I am going to maintain copyright over FunnelWeb.}{%
+%
+Once a work is released under GNU license, all derived works fall under
+GNU license. However, this diagram shows how copyright can be maintained
+over a work, while still making it available under GNU license.
+Unfortunately, this scheme requires that copyright on
+modifications to FunnelWeb be signed off by the people who make the
+modifications.
+%
+}
+\end{figure}
+
+There are two main disadvantages to this scheme:
+
+\begin{enumerate}
+
+\item Getting each person who contributes modifications to FunnelWeb
+to sign and send a piece of paper signing away copyright will be tedious.
+
+\item Programmers may be reluctant to sign away copyright on modifications
+because the result could be used by me for commercial purposes
+by me at a later date (Note: But it must be released under GNU as well).
+
+\end{enumerate}
+
+These disadvantages are regrettable consequences of my decision to retain
+total control over the \dq{official} version of FunnelWeb.
+
+The upshot of all this is that:
+
+\begin{itemize}
+
+\item I will never allow any code from a GNU release of FunnelWeb to
+touch my official copy. Only modifications will be acceptable.
+
+\item If you make a modification to FunnelWeb and send it to me for
+inclusion in the official version, I will not incorporate your
+modification until I have received a signed declaration transferring copyright.
+I will prepare such a contract when the first person sends me a worthy
+modification!
+
+\item If you intend to make changes to FunnelWeb that are so massive that they
+will involve wide-scale modification of the source files, and you want
+the modification to be part of the official version,
+it might be a good idea to contact me before doing so. There are two
+reasons for doing this. First, it allows me a chance to comment on your
+proposed modifications and give my opinion on whether they are likely to be
+incorporated into the official version. Second, I can send you a copy
+(under special license) of the GNU-clean official version to work on. This will
+allow you to ship back your changes as files rather than as change sections.
+
+\end{itemize}
+
+As a separate point from the legal issues, I am likely to turn out to be
+pretty picky about what modifications I will incorporate into the
+official copy. Whether a modification will be accepted will depend,
+amongst other things, on the following criteria.
+
+\begin{itemize}
+
+\item Does the modification fit in with the design goals of FunnelWeb, or
+is it just a case of creeping featurism?
+
+\item How well coded is the modification? Would it reduce the quality of the
+code?
+
+\item If the modification changes FunnelWeb's functionality, is this a
+desirable change? How will it impact on existing users?
+
+\item Would it be quicker for me to make the modification myself than
+to work out how to incorporate the submitted modification?
+
+\end{itemize}
+
+It is my goal to guard the integrity of the design and code of the
+official version of FunnelWeb and so I will probably be rather
+fussy about what I regard as a worthwhile modification. I do not wish to
+lose control of the code, either technically or legally.
+
+\section{A GNU Version?}
+\xx{GNU}{version}
+
+The controls on the official version of FunnelWeb described in the previous
+section will have at most a minor impact on FunnelWeb development if
+FunnelWeb already serves the needs of most of its users. However, if it
+turns out that FunnelWeb is both popular, \i{and} needs
+widespread modifications and enhancements, then the official feedback loop
+described in the previous section will become unworkable, and there will be
+a GNU breakout.
+
+A \newterm{GNU breakout}\xs{breakout}{GNU}
+will occur if FunnelWeb users become
+organized enough and annoyed enough (at the official development cycle)
+to start maintaining a coherent version of FunnelWeb that
+diverges from the official version.
+If a GNU breakout occurs, I would appreciate, as requested earlier, that
+a different name and file extensions be chosen for the diverging version.
+
+\section{Summary}
+
+Decentralized modifications to a programming language and its implementations
+can seriously damage the language's portability and semantic clarity.
+Unfortunately, there is a tension between centralizing control of a
+programming language and providing source code security to nervous users.
+In FunnelWeb, this trade-off has been resolved to some extent by
+releasing the source code along with a request
+that if the functionality of the program is modified,
+that the program's name be changed and a different file
+extension be chosen for input files created under the modified program.
+The author of FunnelWeb has decided to maintain an official version of
+FunnelWeb over which he will own copyright, but which he will release
+under GNU license from time to time. This means that copyright
+on all changes to FunnelWeb must be signed over to the author before they
+have a chance of being incorporated in the official version. Finally, it is
+possible that this reluctance of the author to remove his copyrighted
+version from the development cycle of the official version
+will result in a GNU breakout in which a diverging GNU
+version of FunnelWeb will be maintained by the GNU community. The author
+hopes this won't be necessary and requests,
+if this happens, that the diverging GNU version be renamed.
+
+%==============================================================================%
+% Start of Ch3.tex %
+%==============================================================================%
diff --git a/web/funnelAC/hackman/h_ch4.tex b/web/funnelAC/hackman/h_ch4.tex
new file mode 100644
index 0000000000..b4df3706a8
--- /dev/null
+++ b/web/funnelAC/hackman/h_ch4.tex
@@ -0,0 +1,401 @@
+%==============================================================================%
+% Start of Ch4.tex %
+%==============================================================================%
+%
+% Copyright
+% ---------
+% Copyright (C) 1992 Ross N. Williams.
+% This file contains a chapter of the FunnelWeb Hacker's Manual.
+% See the main TeX file for this manual for further information.
+%
+%==============================================================================%
+
+\chapter{FunnelWeb Future}
+\label{chapfuture}\xx{FunnelWeb}{future}
+
+Previous chapters have explained the design of FunnelWeb and given reasons
+for why it is the way it is. This chapter goes through each of the
+aspects of FunnelWeb, and explores their problems, how they can be solved,
+and lists opportunities for improvement.
+
+\section{Documentation}
+\x{documentation}
+
+\thing{An official example:} A official example program written using
+FunnelWeb should be constructed and made available.\xx{official}{example}
+
+\thing{Index program:} In order to typeset the documentation, a portable
+index sorting program is required. One should be written and added to the
+distribution kit.\xx{index}{program} Perhaps this could be the official
+example!
+
+\section{Command Line Interface}
+\xx{command}{interface}
+
+\thing{Buffer length:} Currently the FunnelWeb shell uses the
+\p{COMLINE\_MAX} constant to size its internal command line buffers.
+This is untenable. The maximum length of a shell command line should
+not be machine dependent.
+
+\thing{Antiquated Features:} As the FunnelWeb language develops, it is likely
+that some changes will have to be made that will render one or more
+language constructs obsolete. When this happens, it may be necessary to
+add a command line option that has the power to turn on and off warnings or
+errors flagging antiquated features.\xx{antiquated}{features}
+
+\section{Shell Interpreter}
+\xx{shell}{interpreter}\xx{command}{interpreter}
+
+\thing{SETALL command:} When writing FunnelWeb scripts, it is sometimes
+desirable to set \i{all} of FunnelWeb's options\x{options}
+to some particular value
+so that the script is not vulnerable to changes in FunnelWeb's default
+values which might occur from time to time. To this end, it may be worth
+creating a \dqp{SETALL} command that is identical to the \dqp{SET} command
+except that it will generate an error if the value of an option is not
+specified explicitly.\xx{setall}{command}
+
+\thing{Recursion test:} A test should be added to test for recursive
+invocation in a shellscript.\xx{recursion}{test}
+
+\thing{Diagnostic counting:} The code for counting diagnostics in the
+script interpreter is rather messy and perhaps even buggy. It should be
+cleaned up and commented.\xx{diagnostic}{counting}
+
+\thing{Argument counting:} In the \p{command.c} module, there is a variable
+that counts the arguments to a command. Currently it takes the value of
+the number of parameters including the command verb. This has turned out
+to make the code less readable. It should be changed to be the number of
+arguments to the command verb.
+
+\thing{Make facility:} It may be worth building some sort of make facility
+into the script language so as to support machines such as the Macintosh
+that do not already have this facility.\x{make}
+
+\thing{Signature file:} One problem with using FunnelWeb in conjunction with
+an external \p{Make} facility is that a user might change a FunnelWeb source
+file without making changes that will affect the files that it generates.
+If FunnelWeb is then run and the \dqp{+D} option is on, then the output
+files will be deleted (to avoid further \p{Make} propagations).
+If \p{Make} then has a production linking the \p{.fw} file to its output
+files, then it may conclude that the output files are still out of date.
+To solve the problem, FunnelWeb could be changed to write a \p{.sig} file
+whenever it processes a \p{.fw} file. The \p{Make} production could then
+be wired up to link
+the \p{.fw} file to the \p{.sig} file instead of to the output
+files.\xx{signature}{file}
+
+\section{Language Design}
+\xx{language}{design}
+
+Some proposed changes to FunnelWeb do not correspond to
+any particular component of FunnelWeb
+and are really to do with the design of the input language.
+
+\thing{Output or file?:} The \dqp{@O} special sequence for defining an output
+file is somewhat non-mnemonic and can be confused with zero (\dqp{0}). Perhaps
+it should be replaced by the \dqp{@F} sequence.
+
+\thing{Syntax of section names:} Currently section names use
+the same syntax as macro names. For example \dqp{@<Sloth@>}. It can be
+argued that angle brackets should be reserved only for macro names and that
+some other syntax should be found for delimiting section names. This is not
+a clear issue. It could also be argued that they are both names, and that
+because sections can inherit their names from the macros they contain, that
+the names are of the same \dq{type}.\xx{section}{syntax}
+
+\thing{One macro per section:} One particular style of using FunnelWeb is
+to have at most one macro definition per section. It may be worth adding
+a pragma that instructs FunnelWeb to enforce this.
+
+\thing{Should @\{ suppress EOL?:} When defining a macro in FunnelWeb, it
+seems to be rule rather than the exception that the
+\dqp{@\{} be followed by \dqp{@-}. This suppresses the EOL on the definition
+line, allowing the first line of the macro to be placed immediately
+above and in line with the other
+lines without introducing an EOL at the start of the macro text.
+One option is to introduce a pragma to determine whether to suppress EOLs
+following \dqp{@\{}.
+
+\thing{Pragma syntax:} It is not clear how \dq{loose} the syntax of pragmas
+should be. Perhaps they should be case insensitive.\xx{pragma}{syntax}
+
+\thing{Conditionals:} Depending on demand, it may be worth reintroducing
+some sort of conditional feature into FunnelWeb. However, it would have to
+be very simple to compete with the various ways in which conditionals
+can already be fudged within FunnelWeb as it stands.\x{conditionals}
+
+\thing{File markers:} It might be worth modifying the language so that
+a special syntactical marker is required at the start and end of files.
+This will assist in detecting truncations and other
+corruptions.\xx{file}{markers}
+
+\thing{Formal parameter lists:} It might be worth changing over to a
+syntax for formal parameter lists that does not require the \p{@(} and
+\p{@)}. However, they could be retained as optional for backward
+compatibility.\xx{parameter list}{formal}
+
+\section{Scanner/Mapper}
+\x{scanner}\x{mapper}
+
+\thing{All non-contiguous mappings:} Currently FunnelWeb requires that all
+input files be mapped into a contiguous lump of memory. This caused problems
+for two reasons. First, to do this, one has to allocate the memory first,
+and to do that, you have to know how long the file is, and it turns out that
+finding out the length of a file in a portable manner is very inefficient.
+Second, although IBM PC compatibles may have megabytes of memory, it is
+segmented into blocks of at most 64K. This means that FunnelWeb currently
+cannot read a file longer than 64K on a PC.\xx{contiguous}{memory}
+
+These problems could be avoided if the mapper and scanner were reorganized to
+allow input files to be read in and stored as a linked list of chunks of text
+rather than a contiguous block.
+
+\thing{EOL is unspecifiable:} FunnelWeb uses ASCII character decimal ten (10)
+internally to represent logical end-of-line and is currently organized so that
+if one of these is inserted into the text by the user using a
+\dqp{@\circumflex{}D(10)}, it will be written out as a logical end of line,
+rather than as a single ASCII character 10. This should be
+fixed.\xx{representation}{EOL}
+
+\thing{Allow mnemonics for unprintables:} FunnelWeb allows users to insert
+unprintable characters into the output using the \dqp{@\circumflex{}D(ddd)}
+special sequence. Perhaps it would be changed so that it understands ASCII
+standard mnemonics such as \dqp{LF} as well as ASCII
+numbers.\xx{ASCII}{mnemonics}
+
+\thing{Version pragma:} A \dqp{version} pragma should be added that allows
+the user to specify in the input file the version of FunnelWeb that was
+around when the input file was created. At a later date, such a construct
+would be very useful for determining how an input file should be updated
+if the FunnelWeb language has changed between
+versions.\xx{version}{pragma}
+
+\section{Parser}
+\x{parser}
+
+There are no proposals to change the parser except as a consequence of
+other proposals.
+
+\section{Analyser}
+\x{analyser}
+
+\thing{Recursion detection:} Currently the FunnelWeb analyser flags, with
+an error, all macros with an infinite expansion. This would be best
+changed to flagging all macros that are directly or indirectly recursive.
+To do this, Tarjan's algorithm\paper{Tarjan72}\xn{Robert Endre}{Tarjan}
+for the detection of strong components should
+be installed.\xx{recursion}{detection}
+
+\thing{Once only macros:} By default FunnelWeb prevents a macro from being
+called more than once unless it has a \dqp{@M} associated with it. However,
+FunnelWeb does allow a macro that calls such a macro to be called more
+than once. Perhaps this \dq{loophole} should be plugged somehow.
+
+
+\section{Tangle}
+\x{tangle}
+
+The Tangler is one of the cleanest components of FunnelWeb, as basically all it
+has to do is expand some very well-defined macros.
+
+\thing{Text indentation:} Currently FunnelWeb supports \i{no indentation}
+and \i{blank indentation}. A third form could be added if it was considered
+necessary. \i{Text indentation} is the same as \i{blank indentation} except
+that instead of indenting with blanks, FunnelWeb would indent with the
+text to the left of the called macro. This facility could be useful for
+commenting out large bodies of text in languages that do not have
+multi-line comments (e.g. Ada). A discussion of the pros and cons of this
+form of indentation appears earlier.\xx{text}{indentation}
+
+\section{Weave}
+\x{weave}
+
+Perhaps FunnelWeb's weakest aspect is its typesetting facility.
+
+
+\thing{Align table of contents:} When FunnelWeb generates a table of contents,
+the section numbers are not quite aligned with the start of the controlling
+heading above them.\x{table of contents}
+
+\thing{Typesetting strength:} It should be possible to specify the
+level of typesetting strength for headings so that short documents do not
+look overdone when typeset. A new pragma would be good for
+this.\xx{strength}{typesetting}
+
+\thing{Typeset a portion:} Sometimes it is desirable to typeset just a
+portion of a program. A command line option could be added to do
+this. The option could accept as its argument, a string containing a list
+of section numbers or heading names.
+
+\thing{Generic typesetter option:} In addition to building in a number
+of different versions of Weave, one for each popular typesetter, it would be
+possible to add a special generic format where the typeset output is
+expressed in terms of \i{FunnelWeb macros}. The user could then specify
+macro definitions for a non-supported typesetter and run the output
+through FunnelWeb Tangle to get a typeset file in a format suitable for the
+unsupported typesetter.\xx{typesetter}{generic}
+
+\thing{Suppression of include files:} It should be possible to specify
+in the input file that particular included files not appear in the
+typeset output. Currently, the fact that an inclusion has occurred is
+not even represented in the typeset output. Suppression of inclusions
+is particularly necessary where a library of macros has been included
+at the top of each of a group of source files.\xx{include file}{suppression}
+
+\thing{Cross reference of identifiers:} WEB provides a list of identifiers
+and a list of all the definitions in which they are used. A similar
+feature could be added to FunnelWeb.\xx{cross}{references}
+
+\thing{Support for non-printables:} Currently FunnelWeb does not provide
+support for typesetting the special \dqp{@\circumflex(num)} sequences.
+This should be added.
+
+\thing{Support for @+ sequences:} Currently Weave does not see \dqp{@+}
+sequences as such. Instead it perceives them as ordinary EOLs. However,
+there are arguments for typesetting them specially.
+
+\thing{Typeset text in macro bodies:} One of the much-loved features
+of WEB is the way that it allows the user to switch recursively between
+document and program formats. FunnelWeb does not allow this, but
+should. In FunnelWeb, the delimiters \dqp{@\{} and \dqp{@\}} are already
+used consistently to delimit macro text. The \dqp{@[} and \dqp{@]} sequences
+have been reserved for the delimitation of documentation text.
+
+\thing{Non-tt typesetting:} The current version of FunnelWeb sets all its
+macro text in \p{tt font}. This is both a blessing and a curse. It is a
+blessing because it connects the reader directly to the code, with no
+complicated intermediary. It is a curse because it looks ugly compared to
+the beautifully typeset programs produced by other literate programming
+tools.
+
+The difficulty with adding such beautiful typesetting is that it is
+necessarily language-specific. Keywords and syntax differ from language
+to language and it would not be easy to come up with a set of language
+independent rules.
+
+One approach is to write a set of Weave back-ends, one for each language.
+Another approach is to \i{generate} back ends. This is the approach
+taken in the \i{Spider} system\paper{Ramsey89}.\x{spider}
+In the \i{Spider} system,
+the programmer writes production rules for converting lexical components
+of the program text into typesetter instructions. The \i{Spider} program
+reads these rules and generates a new version of WEB suited for the target
+language.
+
+For FunnelWeb a slightly different system is proposed in which Spider-like
+rules appear in the input file and are used directly by Weave to perform the
+typesetting. An intermediate abstract typesetting language could be used
+so that the productions can be made language specific, but not typesetter
+specific.
+
+\section{Lister}
+\x{lister}
+
+\thing{Glue factor:} A glue factor could be added that determines how many
+lines can be in between two diagnostics in the listing before the two
+groups of lines are joined together in the listing with no intervening
+ellipsis.\xx{glue}{factor}
+
+\section{Diagnostics}
+\x{diagnostics}
+
+\thing{Advisory information:} Some of FunnelWeb's diagnostics provide
+a detailed explanatory paragraph. While this information might be useful the
+first time, it has the capacity to clog up a listing file if the user has
+made the same error many times. To solve this problem, FunnelWeb could be
+modified so that such explanations are only displayed the first time the
+error occurs.
+
+\thing{Abort after n errors:} A facility could be added to prevent
+FunnelWeb's scanning, parsing, and analysing phases from continuing if
+a certain number of errors have already been issued.
+
+
+\section{Speed}
+\x{speed}\x{efficiency}
+
+\thing{Measurement of speed:} Although FunnelWeb can generate a breakdown
+of where it is spending its time, it does not give a final rating in
+lines per minute. This should be added.
+
+\thing{Find the hot spots:} Although FunnelWeb has been designed to allow
+high speed, not much effort has so far been made to make it fast. This should
+be done.
+
+\thing{Change some declarations:} FunnelWeb is full of variable declarations
+where the variables are wider than they need be. Replacing these might speed
+it up.
+
+\section{Correctness}
+\x{correctness}
+
+\thing{Bounds analysis:} Not much effort has gone into the design of
+FunnelWeb's input boundaries. An analysis should be made of FunnelWeb's
+behaviour when the following quantities are stretched:
+
+\begin{itemize}
+\item Input line length.
+\item Input file size.
+\item Number of macros.
+\item Length of macro.
+\end{itemize}
+
+In particular, FunnelWeb's behaviour at 32K and 64K boundaries should be
+observed.
+
+\thing{Stack detection:} Macintosh THINK-C provides just 6K of memory for
+the stack. It might be worth adding checks to make sure that the stack is
+not being blown.
+
+\section{Test Suite}
+\xx{test}{suite}
+
+The following tests should be added to the test suite:
+
+\begin{verbatim}
+Lister
+------
+ LR01: Test with a full listing with no diagnostics.
+ LR02: Test with a full listing with diagnostics.
+ LR03: Test with an abbreviated listing with no diagnostics.
+ LR04: Test with an abbreviated listing with diagnostics.
+ LR05: Test error context system with nearby diagnostics.
+
+Boundary Cases
+--------------
+Static analysis might preclude the need for most of these tests.
+ BC01: Test what happens when memory runs out.
+ BC02: Test on a file with a single line of a megabyte.
+ BC03: Test on a file of a megabyte of EOLs.
+ BC04: Generate an output file with an extremely long line.
+ BC05: Generate an output file with one million lines.
+ BC06: Test on a file with very many macros.
+
+General
+-------
+ GN01: A large legal input file exercising as many features as possible.
+ 1. Test listing file.
+ 2. Test output files.
+ 3. Test typeset file.
+ GN... A selection of ten real-life FunnelWeb files.
+\end{verbatim}
+
+\section{Machine-Specific Changes}
+
+\thing{Icon for the Macintosh:} Currently no icon is supplied for the
+Macintosh version of FunnelWeb. An icon depicting a spider or a funnelled
+web of some kind would seem appropriate.
+
+\section{Summary}
+
+This chapter has describes some of the problems with FunnelWeb and some of the
+opportunities that exist for improving it. The direction and speed in which
+FunnelWeb will develop will depend largely on user feedback. If you have any
+strong feelings on where FunnelWeb should go, please email them to
+Ross Williams (\p{ross@spam.adelaide.edu.au}).
+
+
+%==============================================================================%
+% Start of Ch4.tex %
+%==============================================================================%
diff --git a/web/funnelAC/hackman/h_cha.tex b/web/funnelAC/hackman/h_cha.tex
new file mode 100644
index 0000000000..9098358be5
--- /dev/null
+++ b/web/funnelAC/hackman/h_cha.tex
@@ -0,0 +1,441 @@
+%==============================================================================%
+% Start of Cha.tex %
+%==============================================================================%
+%
+% Copyright
+% ---------
+% Copyright (C) 1992 Ross N. Williams.
+% This file contains a chapter of the FunnelWeb Hacker's Manual.
+% See the main TeX file for this manual for further information.
+%
+%==============================================================================%
+
+\appendix
+
+%==============================================================================
+
+\chapter{GNU General Public License Version 2}
+\xx{GNU}{License}
+
+This appendix contains a verbatim copy of Version~2 of the GNU
+General Public License under which the FunnelWeb computer program is
+released. Note that the \i{FunnelWeb User's Manual} and
+\i{FunnelWeb Hacker's
+Manual} are released under a much simpler license that does not allow
+modifications.
+
+\bigskip
+
+\hrule
+
+\bigskip
+
+\begin{verbatim}
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
+ type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+\end{verbatim}
+
+\bigskip
+
+\hrule
+
+%==============================================================================
+
+\chapter{References}
+\x{references}
+
+\paper{ANSI} Australian Standard AS~3955-1991, \dq{Programming Languages --- C},
+(ISBN: 0-7262-6970-0), 12~July~1991. Identical to:
+International Standard ISO/IEC 9899:
+1990 Programming Languages --- C.\checked{}
+
+\paper{Bentley86} Bentley~J., \dq{Programming Pearls: Literate Programming},
+\i{Communications of the ACM}, Vol.~29, No.~5, pp.~364--369, 1986.\checked{}
+
+\paper{Hoare80} Hoare~C.A.R., \dq{The Emperor's Old Clothes},
+Turing Award Lecture, 1980, from \dq{ACM Turing Award Lectures: The
+First Twenty Years 1966--1985},
+ACM Press, New York, (ISBN: 0-201-07794-9), 1987 (see p.~155).\checked{}
+
+\paper{Horton90} Horton~M.R., \dq{Portable C Software},
+Prentice Hall, (ISBN: 0-13-868050-7), 1990.\checked{}
+
+\paper{Kernighan88} Kernighan~B.W., Ritchie~D.M., \dq{The~C Programming
+Language}, (second edition,\dq{ANSI~C}), Prentice Hall,
+(ISBN: 0-13-110362-8), 1988.\checked{}
+
+\paper{Knuth83} Knuth~D.E., \dq{The WEB System of Structured
+Documentation}, (Web User Manual, Version~2.5, November, 1983),
+Stanford University, 1983.\checked{}
+
+\paper{Knuth84} Knuth~D.E., \dq{The \TeX{}book}, Addison-Wesley,
+(ISBN: 0-201-13448-9), 1984.
+
+\paper{Lamport86} Lamport~L., \dq{\LaTeX{}: A Document Preparation System},
+Addison-Wesley, (ISBN: 0-201-15790-X),
+1986.\checked{}
+
+\paper{Rabinowitz90} Rabinowitz~H., Schaap~C., \dq{Portable~C}, Prentice Hall,
+(ISBN:0-13-685967-4) 1990.\checked{}
+
+\paper{Ramsey89} Ramsey~N., \dq{Weaving a Language-Independent WEB},
+\i{Communications of the ACM}, Vol.~32, No.~9, pp.~1051--1055, 1989.\checked{}
+
+\paper{Tarjan72} Tarjan~R.E.,
+\dq{Depth-First Search and Linear Graph Algorithms},
+\i{SIAM Journal of Computing}, Vol.~1, No.~2, pp.~146--160,
+June 1972.\checked{}
+
+\paper{USDOD83} \dq{The Programming Language Ada Reference Manual},
+American National Standards Institute Inc,
+ANSI/MIL-STD-1815A-1983, 1983.\checked{}
+
+%==============================================================================
+
+\addcontentsline{toc}{chapter}{Index}
+\def\indexentry#1#2{\item #1~#2}
+\begin{theindex}
+\input h_manual.sin
+\end{theindex}
+
+%==============================================================================%
+% End of Cha.tex %
+%==============================================================================%
diff --git a/web/funnelAC/hackman/h_manual.aux b/web/funnelAC/hackman/h_manual.aux
new file mode 100644
index 0000000000..fc25ea43c0
--- /dev/null
+++ b/web/funnelAC/hackman/h_manual.aux
@@ -0,0 +1,80 @@
+\relax
+\@writefile{toc}{\string\contentsline\space {chapter}{Preface}{5}}
+\@writefile{toc}{\string\contentsline\space {chapter}{Acknowledgements}{7}}
+\@writefile{toc}{\string\contentsline\space {chapter}{Presentation Notes}{9}}
+\@writefile{toc}{\string\contentsline\space {chapter}{\string\numberline\space {1}FunnelWeb Design}{11}}
+\@writefile{lof}{\string\addvspace\space {10pt}}
+\@writefile{lot}{\string\addvspace\space {10pt}}
+\newlabel{chapdesign}{{1}{11}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.1}Motivation for FunnelWeb}{11}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.2}Indentation}{12}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.3}Review of FunnelWeb Syntax}{14}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.3.1}Review of Macro Definition Syntax}{14}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.3.2}Review of Macro Call Syntax}{16}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.3.3}Review of Parameterized Macro Call Syntax}{16}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.4}Document Structuring}{16}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.5}Discussion of Some Miscellaneous Issues}{18}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.6}Automated Regression Testing}{18}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.7}Command Line Interface}{18}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.8}File Name Management}{19}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.8.1}Filename Extensions}{20}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.8.2}Filename Inheritance}{20}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.8.3}Portable Structure of File Names}{21}}
+\newlabel{portablefilenames}{{1.8.3}{21}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.9}Specifying Constraints on the Number of Instantiations}{22}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.10}The Relationship Between Document Structure and Macro Structure}{23}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.11}Diagnostic Messages}{25}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.12}Summary}{25}}
+\@writefile{toc}{\string\contentsline\space {chapter}{\string\numberline\space {2}FunnelWeb Implementation}{27}}
+\@writefile{lof}{\string\addvspace\space {10pt}}
+\@writefile{lot}{\string\addvspace\space {10pt}}
+\newlabel{chapimplementation}{{2}{27}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.1}Introduction}{27}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.2}History of FunnelWeb Implementations}{27}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.3}Why FunnelWeb Wasn't Used to Write Itself}{28}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.4}Coding Style}{28}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.5}Use of Memory}{29}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.6}The Heap}{29}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.7}The Stack}{30}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.8}Static Variables}{30}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.9}Implementing Text Indentation}{30}}
+\@writefile{toc}{\string\contentsline\space {chapter}{\string\numberline\space {3}FunnelWeb Modification}{35}}
+\@writefile{lof}{\string\addvspace\space {10pt}}
+\@writefile{lot}{\string\addvspace\space {10pt}}
+\newlabel{chapmod}{{3}{35}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.1}Introduction}{35}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.2}The Danger of Modifying Languages}{35}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.3}Authority vs User Security}{36}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.4}What I Want to Protect}{37}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.5}Modifying the Manuals}{38}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.6}How Copyright Law Works}{38}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.7}Management of the Official FunnelWeb}{39}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.8}A GNU Version?}{41}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.9}Summary}{41}}
+\@writefile{toc}{\string\contentsline\space {chapter}{\string\numberline\space {4}FunnelWeb Future}{43}}
+\@writefile{lof}{\string\addvspace\space {10pt}}
+\@writefile{lot}{\string\addvspace\space {10pt}}
+\newlabel{chapfuture}{{4}{43}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.1}Documentation}{43}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.2}Command Line Interface}{43}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.3}Shell Interpreter}{43}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.4}Language Design}{44}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.5}Scanner/Mapper}{44}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.6}Parser}{45}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.7}Analyser}{45}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.8}Tangle}{45}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.9}Weave}{45}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.10}Lister}{46}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.11}Diagnostics}{47}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.12}Speed}{47}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.13}Correctness}{47}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.14}Test Suite}{47}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.15}Machine-Specific Changes}{48}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.16}Summary}{48}}
+\@writefile{toc}{\string\contentsline\space {chapter}{\string\numberline\space {A}GNU General Public License Version 2}{49}}
+\@writefile{lof}{\string\addvspace\space {10pt}}
+\@writefile{lot}{\string\addvspace\space {10pt}}
+\@writefile{toc}{\string\contentsline\space {chapter}{\string\numberline\space {B}References}{57}}
+\@writefile{lof}{\string\addvspace\space {10pt}}
+\@writefile{lot}{\string\addvspace\space {10pt}}
+\@writefile{toc}{\string\contentsline\space {chapter}{Index}{57}}
diff --git a/web/funnelAC/hackman/h_manual.dvi b/web/funnelAC/hackman/h_manual.dvi
new file mode 100644
index 0000000000..956cf6322e
--- /dev/null
+++ b/web/funnelAC/hackman/h_manual.dvi
Binary files differ
diff --git a/web/funnelAC/hackman/h_manual.idx b/web/funnelAC/hackman/h_manual.idx
new file mode 100644
index 0000000000..3ba19d0562
--- /dev/null
+++ b/web/funnelAC/hackman/h_manual.idx
@@ -0,0 +1,326 @@
+\indexentry{Ross Williams}{1}
+\indexentry{Williams Ross}{1}
+\indexentry{copyright notice}{1}
+\indexentry{notice copyright}{1}
+\indexentry{preface}{5}
+\indexentry{acknowledgements}{7}
+\indexentry{David Hulse}{7}
+\indexentry{Hulse David}{7}
+\indexentry{Ada}{7}
+\indexentry{Simon Hackett}{7}
+\indexentry{Hackett Simon}{7}
+\indexentry{Jeremy Begg}{7}
+\indexentry{Begg Jeremy}{7}
+\indexentry{Barry Dwyer}{7}
+\indexentry{Dwyer Barry}{7}
+\indexentry{Roger Brissenden}{7}
+\indexentry{Brissenden Roger}{7}
+\indexentry{Donald Knuth}{7}
+\indexentry{Knuth Donald}{7}
+\indexentry{presentation notes}{9}
+\indexentry{typesetting}{9}
+\indexentry{Andrew Trevorrow}{9}
+\indexentry{Trevorrow Andrew}{9}
+\indexentry{OzTeX}{9}
+\indexentry{Knuth84}{9}
+\indexentry{Lamport86}{9}
+\indexentry{TeX}{9}
+\indexentry{LaTeX}{9}
+\indexentry{Macintosh}{9}
+\indexentry{LaTeX}{9}
+\indexentry{FunnelWeb design}{11}
+\indexentry{design FunnelWeb}{11}
+\indexentry{FunnelWeb V1}{11}
+\indexentry{backwards compatibility}{11}
+\indexentry{compatibility backwards}{11}
+\indexentry{FunnelWeb motivation}{11}
+\indexentry{motivation FunnelWeb}{11}
+\indexentry{Donald Knuth}{11}
+\indexentry{Knuth Donald}{11}
+\indexentry{Jon Bentley}{11}
+\indexentry{Bentley Jon}{11}
+\indexentry{programming pearls}{11}
+\indexentry{Communications of the ACM}{11}
+\indexentry{Bentley86}{11}
+\indexentry{Knuth83}{11}
+\indexentry{Pascal}{12}
+\indexentry{number output files}{12}
+\indexentry{output files number}{12}
+\indexentry{indentation}{12}
+\indexentry{Occam's razor}{12}
+\indexentry{indentation}{12}
+\indexentry{indentation no}{12}
+\indexentry{no indentation}{12}
+\indexentry{indentation blank}{12}
+\indexentry{blank indentation}{12}
+\indexentry{indentation text}{12}
+\indexentry{text indentation}{12}
+\indexentry{indented macro call}{12}
+\indexentry{no indentation}{12}
+\indexentry{blank indentation}{12}
+\indexentry{text indentation}{12}
+\indexentry{DCL}{13}
+\indexentry{indentation dangers}{13}
+\indexentry{dangers indentation}{13}
+\indexentry{FunnelWeb syntax}{14}
+\indexentry{syntax FunnelWeb}{14}
+\indexentry{==}{14}
+\indexentry{macro definition syntax}{14}
+\indexentry{syntax macro definition}{14}
+\indexentry{parameterized macro definitions syntax}{15}
+\indexentry{syntax parameterized macro definitions}{15}
+\indexentry{macro call syntax}{16}
+\indexentry{syntax macro call}{16}
+\indexentry{parameterized macro call syntax}{16}
+\indexentry{syntax parameterized macro call}{16}
+\indexentry{document structure}{16}
+\indexentry{structure document}{16}
+\indexentry{headings}{16}
+\indexentry{sections}{16}
+\indexentry{miscellaneous issues}{18}
+\indexentry{issues miscellaneous}{18}
+\indexentry{comment duplication}{18}
+\indexentry{duplication comment}{18}
+\indexentry{out of date documentation}{18}
+\indexentry{documentation out of date}{18}
+\indexentry{regression testing}{18}
+\indexentry{testing regression}{18}
+\indexentry{command line interface}{18}
+\indexentry{interface command line}{18}
+\indexentry{Ada}{18}
+\indexentry{vms vax}{18}
+\indexentry{vax vms}{18}
+\indexentry{.cld file}{18}
+\indexentry{file .cld}{18}
+\indexentry{design goals command line interface}{19}
+\indexentry{command line interface design goals}{19}
+\indexentry{file names}{19}
+\indexentry{names file}{19}
+\indexentry{filename extensions}{20}
+\indexentry{extensions filename}{20}
+\indexentry{filename inheritance}{20}
+\indexentry{inheritance filename}{20}
+\indexentry{file names}{21}
+\indexentry{names file}{21}
+\indexentry{portable filenames}{21}
+\indexentry{filenames portable}{21}
+\indexentry{invocations number}{22}
+\indexentry{number invocations}{22}
+\indexentry{@Z}{23}
+\indexentry{@M}{23}
+\indexentry{document structure macro structure}{23}
+\indexentry{macro structure document structure}{23}
+\indexentry{document structure}{23}
+\indexentry{structure document}{23}
+\indexentry{macro structure}{23}
+\indexentry{structure macro}{23}
+\indexentry{hierarchical structure}{23}
+\indexentry{structure hierarchical}{23}
+\indexentry{TeX}{23}
+\indexentry{section numbering}{23}
+\indexentry{numbering section}{23}
+\indexentry{diagnostic messages}{25}
+\indexentry{messages diagnostic}{25}
+\indexentry{FunnelWeb implementation}{27}
+\indexentry{implementation FunnelWeb}{27}
+\indexentry{FunnelWeb history}{27}
+\indexentry{history FunnelWeb}{27}
+\indexentry{FunnelWeb version 1}{27}
+\indexentry{FunnelWeb version 2}{27}
+\indexentry{FunnelWeb version 3}{27}
+\indexentry{Ada}{27}
+\indexentry{USDOD83}{27}
+\indexentry{Ph.D.}{27}
+\indexentry{FunnelWeb past use}{27}
+\indexentry{past use FunnelWeb}{27}
+\indexentry{David Hulse}{27}
+\indexentry{Hulse David}{27}
+\indexentry{University Adelaide}{27}
+\indexentry{Adelaide University}{27}
+\indexentry{FunnelWeb writing itself}{28}
+\indexentry{writing itself FunnelWeb}{28}
+\indexentry{trouble asking for}{28}
+\indexentry{asking for trouble}{28}
+\indexentry{coding style}{28}
+\indexentry{style coding}{28}
+\indexentry{South Australian Government Department of Lands}{28}
+\indexentry{portability}{28}
+\indexentry{Rabinowitz90}{28}
+\indexentry{Horton90}{28}
+\indexentry{Kernighan88}{28}
+\indexentry{ANSI}{28}
+\indexentry{Rabinowitz90}{28}
+\indexentry{identifier}{28}
+\indexentry{identifier abbreviations}{28}
+\indexentry{abbreviations identifier}{28}
+\indexentry{pointers naming}{29}
+\indexentry{naming pointers}{29}
+\indexentry{types naming}{29}
+\indexentry{naming types}{29}
+\indexentry{filenames length}{29}
+\indexentry{length filenames}{29}
+\indexentry{MSDOS}{29}
+\indexentry{use of memory}{29}
+\indexentry{memory use of}{29}
+\indexentry{heap memory}{29}
+\indexentry{memory heap}{29}
+\indexentry{Macintosh}{29}
+\indexentry{malloc}{29}
+\indexentry{memory package}{29}
+\indexentry{package memory}{29}
+\indexentry{memory leakage}{30}
+\indexentry{leakage memory}{30}
+\indexentry{stack memory}{30}
+\indexentry{memory stack}{30}
+\indexentry{stack size}{30}
+\indexentry{size stack}{30}
+\indexentry{memory static}{30}
+\indexentry{static memory}{30}
+\indexentry{static variables}{30}
+\indexentry{variables static}{30}
+\indexentry{Macintosh}{30}
+\indexentry{ThinkC compiler}{30}
+\indexentry{compiler ThinkC}{30}
+\indexentry{text indentation}{30}
+\indexentry{indentation text}{30}
+\indexentry{FunnelWeb modification}{35}
+\indexentry{modification FunnelWeb}{35}
+\indexentry{GNU license}{35}
+\indexentry{license GNU}{35}
+\indexentry{changes dangers}{35}
+\indexentry{dangers changes}{35}
+\indexentry{languages dangers}{35}
+\indexentry{dangers languages}{35}
+\indexentry{video game}{35}
+\indexentry{compiler}{35}
+\indexentry{removing features}{35}
+\indexentry{features removing}{35}
+\indexentry{features modification}{35}
+\indexentry{modification features}{35}
+\indexentry{features adding}{36}
+\indexentry{adding features}{36}
+\indexentry{Hoare80}{36}
+\indexentry{genealogy program}{36}
+\indexentry{program genealogy}{36}
+\indexentry{design authority}{36}
+\indexentry{authority design}{36}
+\indexentry{Unix}{36}
+\indexentry{security authority}{36}
+\indexentry{authority security}{36}
+\indexentry{trademark}{36}
+\indexentry{program availability}{37}
+\indexentry{availability program}{37}
+\indexentry{protection FunnelWeb}{37}
+\indexentry{FunnelWeb protection}{37}
+\indexentry{protection file extension}{37}
+\indexentry{file extension protection}{37}
+\indexentry{modifying manuals}{38}
+\indexentry{manuals modifying}{38}
+\indexentry{copyright law}{38}
+\indexentry{law copyright}{38}
+\indexentry{work}{38}
+\indexentry{copyright}{38}
+\indexentry{license}{38}
+\indexentry{derived work}{38}
+\indexentry{GNU license}{39}
+\indexentry{license GNU}{39}
+\indexentry{FunnelWeb management}{39}
+\indexentry{management FunnelWeb}{39}
+\indexentry{FunnelWeb official}{39}
+\indexentry{official FunnelWeb}{39}
+\indexentry{GNU version}{41}
+\indexentry{version GNU}{41}
+\indexentry{GNU breakout}{41}
+\indexentry{breakout, GNU}{41}
+\indexentry{FunnelWeb future}{43}
+\indexentry{future FunnelWeb}{43}
+\indexentry{documentation}{43}
+\indexentry{official example}{43}
+\indexentry{example official}{43}
+\indexentry{index program}{43}
+\indexentry{program index}{43}
+\indexentry{command interface}{43}
+\indexentry{interface command}{43}
+\indexentry{antiquated features}{43}
+\indexentry{features antiquated}{43}
+\indexentry{shell interpreter}{43}
+\indexentry{interpreter shell}{43}
+\indexentry{command interpreter}{43}
+\indexentry{interpreter command}{43}
+\indexentry{options}{43}
+\indexentry{setall command}{43}
+\indexentry{command setall}{43}
+\indexentry{recursion test}{43}
+\indexentry{test recursion}{43}
+\indexentry{diagnostic counting}{43}
+\indexentry{counting diagnostic}{43}
+\indexentry{make}{44}
+\indexentry{signature file}{44}
+\indexentry{file signature}{44}
+\indexentry{language design}{44}
+\indexentry{design language}{44}
+\indexentry{section syntax}{44}
+\indexentry{syntax section}{44}
+\indexentry{pragma syntax}{44}
+\indexentry{syntax pragma}{44}
+\indexentry{conditionals}{44}
+\indexentry{file markers}{44}
+\indexentry{markers file}{44}
+\indexentry{parameter list formal}{44}
+\indexentry{formal parameter list}{44}
+\indexentry{scanner}{44}
+\indexentry{mapper}{44}
+\indexentry{contiguous memory}{45}
+\indexentry{memory contiguous}{45}
+\indexentry{representation EOL}{45}
+\indexentry{EOL representation}{45}
+\indexentry{ASCII mnemonics}{45}
+\indexentry{mnemonics ASCII}{45}
+\indexentry{version pragma}{45}
+\indexentry{pragma version}{45}
+\indexentry{parser}{45}
+\indexentry{analyser}{45}
+\indexentry{Tarjan72}{45}
+\indexentry{Robert Endre Tarjan}{45}
+\indexentry{Tarjan Robert Endre}{45}
+\indexentry{recursion detection}{45}
+\indexentry{detection recursion}{45}
+\indexentry{tangle}{45}
+\indexentry{text indentation}{45}
+\indexentry{indentation text}{45}
+\indexentry{weave}{45}
+\indexentry{table of contents}{45}
+\indexentry{strength typesetting}{46}
+\indexentry{typesetting strength}{46}
+\indexentry{typesetter generic}{46}
+\indexentry{generic typesetter}{46}
+\indexentry{include file suppression}{46}
+\indexentry{suppression include file}{46}
+\indexentry{cross references}{46}
+\indexentry{references cross}{46}
+\indexentry{Ramsey89}{46}
+\indexentry{spider}{46}
+\indexentry{lister}{46}
+\indexentry{glue factor}{46}
+\indexentry{factor glue}{46}
+\indexentry{diagnostics}{47}
+\indexentry{speed}{47}
+\indexentry{efficiency}{47}
+\indexentry{correctness}{47}
+\indexentry{test suite}{47}
+\indexentry{suite test}{47}
+\indexentry{GNU License}{49}
+\indexentry{License GNU}{49}
+\indexentry{references}{57}
+\indexentry{ANSI}{57}
+\indexentry{Bentley86}{57}
+\indexentry{Hoare80}{57}
+\indexentry{Horton90}{57}
+\indexentry{Kernighan88}{57}
+\indexentry{Knuth83}{57}
+\indexentry{Knuth84}{57}
+\indexentry{Lamport86}{57}
+\indexentry{Rabinowitz90}{57}
+\indexentry{Ramsey89}{57}
+\indexentry{Tarjan72}{57}
+\indexentry{USDOD83}{57}
diff --git a/web/funnelAC/hackman/h_manual.log b/web/funnelAC/hackman/h_manual.log
new file mode 100644
index 0000000000..c536c1cd23
--- /dev/null
+++ b/web/funnelAC/hackman/h_manual.log
@@ -0,0 +1,213 @@
+This is TeX, Version 3.0 (preloaded format=lplain 90.9.16) 27 MAY 1992 12:56
+**&LaTeX h_manual.tex
+(h_manual.tex
+LaTeX Version 2.09 <13 Jun 1989>
+(:TeX-inputs:book.sty
+Document Style `book' <24 May 89>.
+(:TeX-inputs:bk10.sty)
+\descriptionmargin=\dimen99
+\c@part=\count78
+\c@chapter=\count79
+\c@section=\count80
+\c@subsection=\count81
+\c@subsubsection=\count82
+\c@paragraph=\count83
+\c@subparagraph=\count84
+\c@figure=\count85
+\c@table=\count86
+) (:TeX-inputs:titlepage.sty) [0
+
+
+]
+\@indexfile=\write3
+
+Writing index file h_manual.idx
+(h_manual.aux)
+(h_ch0.tex [1] [2
+
+] (h_manual.toc [3])
+\tf@toc=\write4
+ [4] [5
+
+] [6
+
+]
+Underfull \hbox (badness 10000) in paragraph at lines 120--123
+[]\tenrm Thanks to \tenbf Barry Dwyer[][] \tenrm (\tentt dwyer@cs.adelaide.edu.
+au\tenrm ) and \tenbf Roger Bris-senden[][]
+
+\hbox(7.5+2.5)x426.79134, glue set 5.25278
+.\hbox(0.0+0.0)x0.0
+.\tenrm T
+.\tenrm h
+.\tenrm a
+.\tenrm n
+.etc.
+
+[7] [8
+
+]
+Underfull \hbox (badness 5652) in paragraph at lines 146--152
+[]\tenbf Typesetting: \tenrm This[] doc-u-ment was pre-pared by the au-thor us-
+ing An-drew Trevor-
+
+\hbox(6.94444+1.94444)x426.79134, glue set 3.83969
+.\hbox(0.0+0.0)x0.0
+.\tenbf T
+.\kern-0.31944
+.\tenbf y
+.\tenbf p
+.etc.
+
+
+Underfull \hbox (badness 1117) in paragraph at lines 146--152
+\tenrm row's[][] (\tentt akt150@cscgpo.anu.edu.au\tenrm ) im-ple-men-ta-tion (O
+z-TeX[]) of the T[]X/L[]T[]X\tenbf [Knuth84][]
+
+\hbox(7.5+3.01385)x426.79134, glue set 2.23746
+.\tenrm r
+.\tenrm o
+.\kern-0.27779
+.\tenrm w
+.\tenrm '
+.etc.
+
+) (h_ch1.tex [9] [10
+
+]
+Chapter 1.
+[11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24])
+(h_ch2.tex [25] [26
+
+]
+Chapter 2.
+[27] [28] [29] [30] [31] [32]) (h_ch3.tex [33] [34
+
+]
+Chapter 3.
+[35] [36] [37] [38] [39] [40]) (h_ch4.tex [41] [42
+
+]
+Chapter 4.
+[43] [44] [45] [46] [47]) (h_cha.tex [48]
+Appendix A.
+[49
+
+]
+Underfull \vbox (badness 10000) has occurred while \output is active
+\vbox(682.86613+0.0)x426.79134
+.\glue(\topskip) 10.0
+.\hbox(0.0+0.0)x0.0
+.\glue(\parskip) 0.0
+.\glue(\baselineskip) 5.88889
+.\hbox(6.11111+2.22223)x426.79134, glue set 80.29436fil
+..\hbox(0.0+0.0)x0.0
+..\penalty 10000
+..\glue 5.24995
+..\penalty 10000
+..\glue 5.24995
+..etc.
+.etc.
+
+ [50]
+Underfull \vbox (badness 10000) has occurred while \output is active
+\vbox(682.86613+0.0)x426.79134
+.\glue(\topskip) 10.0
+.\hbox(0.0+0.0)x0.0
+.\glue(\parskip) 0.0
+.\glue(\baselineskip) 5.88889
+.\hbox(6.11111+2.22223)x426.79134, glue set 64.5445fil
+..\hbox(0.0+0.0)x0.0
+..\penalty 10000
+..\glue 5.24995
+..\penalty 10000
+..\glue 5.24995
+..etc.
+.etc.
+
+ [51]
+Underfull \vbox (badness 10000) has occurred while \output is active
+\vbox(682.86613+0.0)x426.79134
+.\glue(\topskip) 3.88889
+.\hbox(6.11111+0.0)x426.79134, glue set 64.5445fil
+..\hbox(0.0+0.0)x0.0
+..\penalty 10000
+..\glue 5.24995
+..\penalty 10000
+..\glue 5.24995
+..etc.
+.\glue(\parskip) 0.0
+.\glue(\baselineskip) 5.88889
+.\hbox(6.11111+2.22223)x426.79134, glue set 164.29362fil
+..\hbox(0.0+0.0)x0.0
+..\penalty 10000
+..\glue 5.24995
+..\penalty 10000
+..\glue 5.24995
+..etc.
+.etc.
+
+ [52]
+Underfull \vbox (badness 10000) has occurred while \output is active
+\vbox(682.86613+0.0)x426.79134
+.\glue(\topskip) 3.88889
+.\hbox(6.11111+2.22223)x426.79134, glue set 59.29454fil
+..\hbox(0.0+0.0)x0.0
+..\tentt L
+..\tentt i
+..\tentt c
+..\tentt e
+..etc.
+.\glue(\parskip) 0.0
+.\glue(\baselineskip) 3.66666
+.\hbox(6.11111+2.22223)x426.79134, glue set 90.79427fil
+..\hbox(0.0+0.0)x0.0
+..\tentt m
+..\tentt a
+..\tentt y
+..\penalty 10000
+..etc.
+.etc.
+
+ [53]
+Underfull \vbox (badness 10000) has occurred while \output is active
+\vbox(682.86613+0.0)x426.79134
+.\glue(\topskip) 3.88889
+.\hbox(6.11111+1.38887)x426.79134, glue set 38.29472fil
+..\hbox(0.0+0.0)x0.0
+..\penalty 10000
+..\glue 5.24995
+..\penalty 10000
+..\glue 5.24995
+..etc.
+.\glue(\parskip) 0.0
+.\glue(\baselineskip) 4.50002
+.\hbox(6.11111+1.38887)x426.79134, glue set 48.79463fil
+..\hbox(0.0+0.0)x0.0
+..\tentt F
+..\tentt O
+..\tentt R
+..\penalty 10000
+..etc.
+.etc.
+
+ [54]
+[55] [56
+
+]
+Appendix B.
+[57] (h_manual.sin [58
+
+] [59] [60]) [61
+
+]) (h_manual.aux) )
+Here is how much of TeX's memory you used:
+ 220 strings out of 1960
+ 1908 string characters out of 13235
+ 54264 words of memory out of 60001
+ 2151 multiletter control sequences out of 2500
+ 19914 words of font info for 75 fonts, out of 27000 for 100
+ 14 hyphenation exceptions out of 307
+ 15i,6n,15p,200b,226s stack positions out of 200i,40n,60p,500b,600s
+
+Output written on h_manual.dvi (62 pages, 181584 bytes).
diff --git a/web/funnelAC/hackman/h_manual.ps b/web/funnelAC/hackman/h_manual.ps
new file mode 100644
index 0000000000..3fa3273717
--- /dev/null
+++ b/web/funnelAC/hackman/h_manual.ps
@@ -0,0 +1,5210 @@
+%!PS-Adobe-2.0
+%%Creator: dvips 5.493 Copyright 1986, 1992 Radical Eye Software
+%%Title: h_manual.dvi
+%%CreationDate: Sat Aug 14 17:07:29 1993
+%%Pages: 62
+%%PageOrder: Ascend
+%%BoundingBox: 0 0 612 792
+%%EndComments
+%DVIPSCommandLine: dvips h_manual
+%DVIPSSource: TeX output 1993.08.14:1707
+%%BeginProcSet: tex.pro
+/TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}
+B /TR{translate}N /isls false N /vsize 11 72 mul N /@rigin{isls{[0 -1 1 0 0 0]
+concat}if 72 Resolution div 72 VResolution div neg scale isls{Resolution hsize
+-72 div mul 0 TR}if Resolution VResolution vsize -72 div 1 add mul TR matrix
+currentmatrix dup dup 4 get round 4 exch put dup dup 5 get round 5 exch put
+setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed
+true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N
+/IE 0 N /ctr 0 N /df-tail{/nn 8 dict N nn begin /FontType 3 N /FontMatrix
+fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{
+CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn
+put /ctr 0 N[}B /df{/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0
+0 sf neg 0 0]N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data
+dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{128
+ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127
+sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type
+/stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N
+/cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get
+S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height
+sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0
+-1 -.1 ch-xoff sub ch-yoff .1 add]{ch-image}imagemask restore}B /D{/cc X dup
+type /stringtype ne{]}if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1
+ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}
+B /I{cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin
+0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add
+.99 lt{/FV}{/RV}ifelse load def pop pop}N /eop{SI restore showpage userdict
+/eop-hook known{eop-hook}if}N /@start{userdict /start-hook known{start-hook}
+if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255
+{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76
+div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N
+/ruley 0 N /v{/ruley X /rulex X V}B /V{}B /RV statusdict begin /product where{
+pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4
+getinterval(NeXT)eq or}{pop false}ifelse}{false}ifelse end{{gsave TR -.1 -.1
+TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1
+-.1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /FV{
+gsave transform round exch round exch itransform moveto rulex 0 rlineto 0
+ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N
+/tail{dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M}
+B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{4 M}B
+/w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{p 1 w}B /r{
+p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save
+N}B /eos{SS restore}B end
+%%EndProcSet
+TeXDict begin 40258437 52099154 1000 300 300
+(/users/onl2/coates/startup/tmp/funnelweb/hackman/h_manual.dvi)
+@start /Fa 37 123 df<000FF000007FFC0001F80E0003E01F0007C03F000F803F000F803F00
+0F801E000F800C000F8000000F8000000F8000000F800000FFFFFF00FFFFFF000F801F000F801F
+000F801F000F801F000F801F000F801F000F801F000F801F000F801F000F801F000F801F000F80
+1F000F801F000F801F000F801F000F801F000F801F000F801F007FF0FFE07FF0FFE01B237FA21F
+>12 D<387CFEFEFE7C3807077C8610>46 D<00180000780001F800FFF800FFF80001F80001F800
+01F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001F800
+01F80001F80001F80001F80001F80001F80001F80001F80001F80001F8007FFFE07FFFE013207C
+9F1C>49 D<03FC000FFF003C1FC07007E07C07F0FE03F0FE03F8FE03F8FE01F87C01F83803F800
+03F80003F00003F00007E00007C0000F80001F00003E0000380000700000E01801C01803801807
+00180E00380FFFF01FFFF03FFFF07FFFF0FFFFF0FFFFF015207D9F1C>I<00FE0007FFC00F07E0
+1E03F03F03F03F81F83F81F83F81F81F03F81F03F00003F00003E00007C0001F8001FE0001FF00
+0007C00001F00001F80000FC0000FC3C00FE7E00FEFF00FEFF00FEFF00FEFF00FC7E01FC7801F8
+1E07F00FFFC001FE0017207E9F1C>I<00FE0003FFC00703E00E00F01C00F01C00783C00783E00
+783F00783F80783FE0F01FF9E01FFFC00FFF8007FFC003FFE007FFF01E7FF83C1FFC7807FC7801
+FEF000FEF0003EF0001EF0001EF0001CF8001C7800383C00381F01F00FFFC001FF0017207E9F1C
+>56 D<0003FE0080001FFF818000FF01E38001F8003F8003E0001F8007C0000F800F800007801F
+800007803F000003803F000003807F000001807E000001807E00000180FE00000000FE00000000
+FE00000000FE00000000FE00000000FE00000000FE00000000FE000000007E000000007E000001
+807F000001803F000001803F000003801F800003000F8000030007C000060003F0000C0001F800
+380000FF00F000001FFFC0000003FE000021227DA128>67 D<FFFFFF8000FFFFFFF00007F003FC
+0007F0007E0007F0003F0007F0001F8007F0000FC007F00007E007F00007E007F00007F007F000
+03F007F00003F007F00003F007F00003F807F00003F807F00003F807F00003F807F00003F807F0
+0003F807F00003F807F00003F807F00003F807F00003F007F00003F007F00003F007F00007E007
+F00007E007F0000FC007F0001F8007F0003F0007F0007E0007F003FC00FFFFFFF000FFFFFF8000
+25227EA12B>I<FFFFFFFCFFFFFFFC07F000FC07F0003C07F0001C07F0000C07F0000E07F0000E
+07F0000607F0180607F0180607F0180607F0180007F0380007F0780007FFF80007FFF80007F078
+0007F0380007F0180007F0180007F0180307F0180307F0000307F0000607F0000607F0000607F0
+000E07F0000E07F0001E07F0003E07F001FCFFFFFFFCFFFFFFFC20227EA125>I<FFFFFFF8FFFF
+FFF807F001F807F0007807F0003807F0001807F0001C07F0001C07F0000C07F0000C07F0180C07
+F0180C07F0180007F0180007F0380007F0780007FFF80007FFF80007F0780007F0380007F01800
+07F0180007F0180007F0180007F0000007F0000007F0000007F0000007F0000007F0000007F000
+0007F00000FFFFE000FFFFE0001E227EA123>I<FFFFE0FFFFE003F80003F80003F80003F80003
+F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003
+F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F800FF
+FFE0FFFFE013227FA115>73 D<FFF000000FFFFFF800001FFF07F800001FE006FC000037E006FC
+000037E006FC000037E0067E000067E0067E000067E0063F0000C7E0063F0000C7E0061F800187
+E0061F800187E0060FC00307E0060FC00307E0060FC00307E00607E00607E00607E00607E00603
+F00C07E00603F00C07E00601F81807E00601F81807E00601F81807E00600FC3007E00600FC3007
+E006007E6007E006007E6007E006003FC007E006003FC007E006001F8007E006001F8007E00600
+1F8007E006000F0007E0FFF00F00FFFFFFF00600FFFF30227EA135>77 D<FFF8001FFEFFFC001F
+FE07FC0000C007FE0000C006FF0000C0067F8000C0063FC000C0061FE000C0060FE000C0060FF0
+00C00607F800C00603FC00C00601FE00C00600FE00C00600FF00C006007F80C006003FC0C00600
+1FE0C006000FF0C0060007F0C0060007F8C0060003FCC0060001FEC0060000FFC00600007FC006
+00007FC00600003FC00600001FC00600000FC006000007C006000003C006000003C0FFF00001C0
+FFF00000C027227EA12C>I<FFFFFF00FFFFFFE007F007F007F001FC07F000FC07F0007E07F000
+7E07F0007F07F0007F07F0007F07F0007F07F0007F07F0007E07F0007E07F000FC07F001FC07F0
+07F007FFFFE007FFFF0007F0000007F0000007F0000007F0000007F0000007F0000007F0000007
+F0000007F0000007F0000007F0000007F0000007F00000FFFF8000FFFF800020227EA126>80
+D<FFFFFE0000FFFFFFC00007F007F00007F001F80007F000FC0007F0007E0007F0007F0007F000
+7F0007F0007F0007F0007F0007F0007F0007F0007F0007F0007E0007F000FC0007F001F80007F0
+07F00007FFFFC00007FFFF800007F00FE00007F007F00007F003F80007F001FC0007F001FC0007
+F001FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC0607F000FE06
+07F000FF0CFFFF803FF8FFFF800FF027227EA12A>82 D<01FC0407FF8C1F03FC3C007C7C003C78
+001C78001CF8000CF8000CFC000CFC0000FF0000FFE0007FFF007FFFC03FFFF01FFFF80FFFFC03
+FFFE003FFE0003FF00007F00003F00003FC0001FC0001FC0001FE0001EE0001EF0003CFC003CFF
+00F8C7FFE080FF8018227DA11F>I<07FC001FFF803F07C03F03E03F01E03F01F01E01F00001F0
+0001F0003FF003FDF01FC1F03F01F07E01F0FC01F0FC01F0FC01F0FC01F07E02F07E0CF81FF87F
+07E03F18167E951B>97 D<FF000000FF0000001F0000001F0000001F0000001F0000001F000000
+1F0000001F0000001F0000001F0000001F0000001F0000001F0FE0001F3FF8001FF07C001F801E
+001F001F001F000F801F000F801F000FC01F000FC01F000FC01F000FC01F000FC01F000FC01F00
+0FC01F000FC01F000F801F001F801F801F001FC03E001EE07C001C3FF800180FC0001A237EA21F
+>I<00FF8007FFE00F83F01F03F03E03F07E03F07C01E07C0000FC0000FC0000FC0000FC0000FC
+0000FC00007C00007E00007E00003E00301F00600FC0E007FF8000FE0014167E9519>I<0001FE
+000001FE0000003E0000003E0000003E0000003E0000003E0000003E0000003E0000003E000000
+3E0000003E0000003E0001FC3E0007FFBE000F81FE001F007E003E003E007E003E007C003E00FC
+003E00FC003E00FC003E00FC003E00FC003E00FC003E00FC003E00FC003E007C003E007C003E00
+3E007E001E00FE000F83BE0007FF3FC001FC3FC01A237EA21F>I<00FE0007FF800F87C01E01E0
+3E01F07C00F07C00F8FC00F8FC00F8FFFFF8FFFFF8FC0000FC0000FC00007C00007C00007E0000
+3E00181F00300FC07003FFC000FF0015167E951A>I<003F8000FFC001E3E003C7E007C7E00F87
+E00F83C00F80000F80000F80000F80000F80000F8000FFFC00FFFC000F80000F80000F80000F80
+000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80
+000F80007FF8007FF80013237FA211>I<FF000000FF0000001F0000001F0000001F0000001F00
+00001F0000001F0000001F0000001F0000001F0000001F0000001F0000001F07E0001F1FF8001F
+307C001F403C001F803E001F803E001F003E001F003E001F003E001F003E001F003E001F003E00
+1F003E001F003E001F003E001F003E001F003E001F003E001F003E001F003E00FFE1FFC0FFE1FF
+C01A237EA21F>104 D<1C003E007F007F007F003E001C000000000000000000000000000000FF
+00FF001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F00
+FFE0FFE00B247EA310>I<FF00FF001F001F001F001F001F001F001F001F001F001F001F001F00
+1F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F00FF
+E0FFE00B237EA210>108 D<FF07F007F000FF1FFC1FFC001F303E303E001F403E403E001F801F
+801F001F801F801F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F00
+1F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F
+001F001F001F001F001F001F001F00FFE0FFE0FFE0FFE0FFE0FFE02B167E9530>I<FF07E000FF
+1FF8001F307C001F403C001F803E001F803E001F003E001F003E001F003E001F003E001F003E00
+1F003E001F003E001F003E001F003E001F003E001F003E001F003E001F003E001F003E00FFE1FF
+C0FFE1FFC01A167E951F>I<00FE0007FFC00F83E01E00F03E00F87C007C7C007C7C007CFC007E
+FC007EFC007EFC007EFC007EFC007EFC007E7C007C7C007C3E00F81F01F00F83E007FFC000FE00
+17167E951C>I<FE1F00FE3FC01E67E01EC7E01E87E01E87E01F83C01F00001F00001F00001F00
+001F00001F00001F00001F00001F00001F00001F00001F00001F0000FFF000FFF00013167E9517
+>114 D<0FF3003FFF00781F00600700E00300E00300F00300FC00007FE0007FF8003FFE000FFF
+0001FF00000F80C00780C00380E00380E00380F00700FC0E00EFFC00C7F00011167E9516>I<01
+80000180000180000180000380000380000780000780000F80003F8000FFFF00FFFF000F80000F
+80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F81800F81800F81800F
+81800F81800F830007C30003FE0000F80011207F9F16>I<FF01FE00FF01FE001F003E001F003E
+001F003E001F003E001F003E001F003E001F003E001F003E001F003E001F003E001F003E001F00
+3E001F003E001F003E001F003E001F007E001F00FE000F81BE0007FF3FC001FC3FC01A167E951F
+>I<FFE01FE0FFE01FE00F8006000F8006000FC00E0007C00C0007E01C0003E0180003E0180001
+F0300001F0300000F8600000F86000007CC000007CC000007FC000003F8000003F8000001F0000
+001F0000000E0000000E00001B167F951E>I<FFE7FF07F8FFE7FF07F81F007800C00F80780180
+0F807C01800F807C018007C07E030007C0DE030007E0DE070003E0DF060003E18F060001F18F0C
+0001F38F8C0001FB079C0000FB07D80000FE03D800007E03F000007E03F000007C01F000003C01
+E000003800E000001800C00025167F9528>I<FFE07FC0FFE07FC00F801C0007C0380003E07000
+03F0600001F8C00000F98000007F8000003F0000001F0000001F8000003FC0000037C0000063E0
+0000C1F00001C0F8000380FC0007007E000E003E00FF80FFE0FF80FFE01B167F951E>I<FFE01F
+E0FFE01FE00F8006000F8006000FC00E0007C00C0007E01C0003E0180003E0180001F0300001F0
+300000F8600000F86000007CC000007CC000007FC000003F8000003F8000001F0000001F000000
+0E0000000E0000000C0000000C00000018000078180000FC380000FC300000FC60000069C00000
+7F8000001F0000001B207F951E>I<7FFFF07FFFF07C03E07007C0600FC0E01F80C01F00C03E00
+C07E0000FC0000F80001F00003F03007E03007C0300F80701F80703F00603E00E07C03E0FFFFE0
+FFFFE014167E9519>I E /Fb 44 122 df<00FCF807839C0E079C1C07081C07001C07001C0700
+1C07001C0700FFFFE01C07001C07001C07001C07001C07001C07001C07001C07001C07001C0700
+1C07001C0700FF1FE01617809615>11 D<00FC000782000E07001C07001C02001C00001C00001C
+00001C0000FFFF001C07001C07001C07001C07001C07001C07001C07001C07001C07001C07001C
+07001C0700FF1FE01317809614>I<60F0F070101020204040040A7D830A>44
+D<60F0F06004047D830A>46 D<03000700FF000700070007000700070007000700070007000700
+07000700070007000700070007007FF00C157E9412>49 D<01F00608080C181C301C70006000E0
+00E3E0EC30F018F00CE00EE00EE00E600E600E300C3018183007C00F157F9412>54
+D<07E018302018600C600C700C78183E101F600FC00FF018F8607C601EC00EC006C006C004600C
+38300FE00F157F9412>56 D<07C0183030186018E00CE00CE00EE00EE00E601E301E186E0F8E00
+0E000C001C70187018603020C01F800F157F9412>I<001000003800003800003800005C00005C
+00005C00008E00008E00008E0001070001070003078002038002038007FFC00401C00401C00800
+E00800E01800E03800F0FE03FE17177F961A>65 D<00FC100383300E00B01C0070380030300030
+700010600010E00010E00000E00000E00000E00000E00000E00010600010700010300020380020
+1C00400E008003830000FC0014177E9619>67 D<FFFFE01C00E01C00601C00201C00101C00101C
+00101C04001C04001C04001C0C001FFC001C0C001C04001C04001C04001C00001C00001C00001C
+00001C00001C0000FFC00014177F9617>70 D<007E080381980600580C00381800183000187000
+08700008E00008E00000E00000E00000E00000E003FEE000387000387000383000381800380C00
+380600380380D8007F0817177E961C>I<FF83FE1C00701C00701C00701C00701C00701C00701C
+00701C00701C00701C00701FFFF01C00701C00701C00701C00701C00701C00701C00701C00701C
+00701C0070FF83FE17177F961A>I<FFE00E000E000E000E000E000E000E000E000E000E000E00
+0E000E000E000E000E000E000E000E000E000E00FFE00B177F960D>I<FE0003F81E0003C01700
+05C0170005C0170005C0138009C0138009C011C011C011C011C011C011C010E021C010E021C010
+7041C0107041C0107041C0103881C0103881C0101D01C0101D01C0100E01C0100E01C0380E01C0
+FE040FF81D177F9620>77 D<FC00FE1E00381F001017001013801011C01011C01010E010107010
+103810103810101C10100E10100F101007101003901001D01001D01000F0100070100030380030
+FE001017177F961A>I<00FC000303000E01C01C00E0380070300030700038600018E0001CE000
+1CE0001CE0001CE0001CE0001CE0001C7000387000383000303800701C00E00E01C003030000FC
+0016177E961B>I<7FFFF860381840380840380880380480380480380400380000380000380000
+380000380000380000380000380000380000380000380000380000380000380000380007FFC016
+177F9619>84 D<FF80FE1C00381C00101C00101C00101C00101C00101C00101C00101C00101C00
+101C00101C00101C00101C00101C00101C00101C00100E0020060020030040018180007E001717
+7F961A>I<FF07FC3F803C01E00E001C00E004001C00E004001C017004000E017008000E017008
+000E023808000702381000070238100007041C100003841C200003841C200003880E200001C80E
+400001C80E400001D80F400000F007800000F007800000F0078000006003000000600300000060
+03000021177F9624>87 D<1FC0386038301038003803F81E3830387038E039E039E07970FF1F1E
+100E7F8D12>97 D<FC00001C00001C00001C00001C00001C00001C00001C00001C00001CF8001F
+06001C03001C03801C01801C01C01C01C01C01C01C01C01C01801C03801C03001B0E0010F80012
+17809614>I<07F01838303870106000E000E000E000E000600070083008183007C00D0E7F8D10>
+I<007E00000E00000E00000E00000E00000E00000E00000E00000E0007CE001C3E00300E00700E
+00600E00E00E00E00E00E00E00E00E00600E00700E00301E00182E0007CFC012177F9614>I<0F
+C0186030307038E018FFF8E000E000E000600070083010183007C00D0E7F8D10>I<03E006700E
+701C201C001C001C001C001C00FF801C001C001C001C001C001C001C001C001C001C001C001C00
+FF800C1780960B>I<0F9E18E33060707070707070306018C02F80200060003FE03FF83FFC600E
+C006C006C006600C38380FE010157F8D12>I<FC00001C00001C00001C00001C00001C00001C00
+001C00001C00001C7C001D8E001E07001C07001C07001C07001C07001C07001C07001C07001C07
+001C07001C0700FF9FE01317809614>I<183C3C1800000000007C1C1C1C1C1C1C1C1C1C1C1C1C
+FF081780960A>I<0300078007800300000000000000000000001F800380038003800380038003
+800380038003800380038003800380038003804380E300E7007C00091D82960B>I<FC00001C00
+001C00001C00001C00001C00001C00001C00001C00001C3F801C1C001C18001C20001C40001CC0
+001FE0001CF0001C70001C78001C3C001C1E001C1E00FF3FC01217809613>I<FC001C001C001C
+001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C00FF80
+091780960A>I<FC7C1F001D8E63801E0781C01C0701C01C0701C01C0701C01C0701C01C0701C0
+1C0701C01C0701C01C0701C01C0701C01C0701C0FF9FE7F81D0E808D1E>I<FC7C001D8E001E07
+001C07001C07001C07001C07001C07001C07001C07001C07001C07001C0700FF9FE0130E808D14
+>I<07C018303018600C600CE00EE00EE00EE00EE00E701C3018183007C00F0E7F8D12>I<FCF800
+1F0E001C03001C03801C01801C01C01C01C01C01C01C01C01C01801C03801C07001F0E001CF800
+1C00001C00001C00001C00001C0000FF80001214808D14>I<07C2001C2600381E00700E00600E
+00E00E00E00E00E00E00E00E00600E00700E00301E001C2E0007CE00000E00000E00000E00000E
+00000E00007FC012147F8D13>I<FCF01D381E381C101C001C001C001C001C001C001C001C001C
+00FF800D0E808D0E>I<1F4060C0C040C040E000FF007F801FC001E080608060C060E0C09F000B
+0E7F8D0E>I<080008000800180018003800FF8038003800380038003800380038003840384038
+4038401C800F000A147F930E>I<FC3F001C07001C07001C07001C07001C07001C07001C07001C
+07001C07001C07001C0F000E170003E7E0130E808D14>I<FE1F3C0E3C0C1C081C080E100E1007
+20072003C003C003C001800180100E7F8D13>I<FCFE7C3838383838101C3C201C3C201C4C200E
+4E400E4E400E8640078780078780070380030300030300160E7F8D19>I<FE1F3C0E3C0C1C081C
+080E100E100720072003C003C003C00180018001000100E200E200A400780010147F8D13>121
+D E /Fc 1 50 df<0C003C00CC000C000C000C000C000C000C000C000C000C000C000C000C00FF
+8009107E8F0F>49 D E /Fd 1 50 df<0C001C00EC000C000C000C000C000C000C000C000C000C
+000C000C000C000C000C000C00FFC00A137D9211>49 D E /Fe 59 122
+df<0001FF0000001FFFC000007F80F00000FC00F80001F801F80003F803FC0007F003FC0007F0
+03FC0007F003FC0007F001F80007F000F00007F000000007F000000007F000000007F0000000FF
+FFFFFC00FFFFFFFC00FFFFFFFC0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC00
+07F001FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC
+0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001
+FC007FFF1FFFC07FFF1FFFC07FFF1FFFC0222A7FA926>12 D<0001FF803FE000001FFFE3FFF800
+007F80FFF01E0000FE007F801F0001F800FF003F0003F801FF007F8007F001FE007F8007F001FE
+007F8007F001FE007F8007F000FE003F0007F000FE001E0007F000FE00000007F000FE00000007
+F000FE00000007F000FE000000FFFFFFFFFFFF80FFFFFFFFFFFF80FFFFFFFFFFFF8007F000FE00
+3F8007F000FE003F8007F000FE003F8007F000FE003F8007F000FE003F8007F000FE003F8007F0
+00FE003F8007F000FE003F8007F000FE003F8007F000FE003F8007F000FE003F8007F000FE003F
+8007F000FE003F8007F000FE003F8007F000FE003F8007F000FE003F8007F000FE003F8007F000
+FE003F8007F000FE003F8007F000FE003F8007F000FE003F807FFF0FFFE3FFF87FFF0FFFE3FFF8
+7FFF0FFFE3FFF8352A7FA939>14 D<1C007F007F00FF80FFC0FFC07FC07FC01CC000C000C00180
+018001800300030006000C001800300020000A157BA913>39 D<FFFF80FFFF80FFFF80FFFF80FF
+FF80FFFF8011067F9017>45 D<1C003E007F00FF80FF80FF807F003E001C0009097B8813>I<00
+000300000007800000078000000F8000000F0000000F0000001F0000001E0000003E0000003C00
+00003C0000007C0000007800000078000000F8000000F0000001F0000001E0000001E0000003E0
+000003C0000003C0000007C00000078000000F8000000F0000000F0000001F0000001E0000003E
+0000003C0000003C0000007C0000007800000078000000F8000000F0000001F0000001E0000001
+E0000003E0000003C0000003C0000007C00000078000000F8000000F0000000F0000001F000000
+1E0000001E0000003E0000003C0000007C0000007800000078000000F8000000F0000000F00000
+0060000000193C7CAC22>I<003F800001FFF00007E0FC000FC07E001F803F001F803F003F001F
+803F001F807F001FC07F001FC07F001FC07F001FC0FF001FE0FF001FE0FF001FE0FF001FE0FF00
+1FE0FF001FE0FF001FE0FF001FE0FF001FE0FF001FE0FF001FE0FF001FE0FF001FE0FF001FE0FF
+001FE07F001FC07F001FC07F001FC07F001FC03F001F803F001F801F803F001F803F000FC07E00
+07E0FC0001FFF000003F80001B277DA622>I<000E00001E00007E0007FE00FFFE00FFFE00F8FE
+0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE
+0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE
+0000FE0000FE0000FE007FFFFE7FFFFE7FFFFE17277BA622>I<00FF800003FFF0000FFFFC001F
+03FE003800FF007C007F80FE003FC0FF003FC0FF003FE0FF001FE0FF001FE07E001FE03C003FE0
+00003FE000003FC000003FC000007F8000007F000000FE000000FC000001F8000003F0000003E0
+0000078000000F0000001E0000003C00E0007000E000E000E001C001C0038001C0070001C00FFF
+FFC01FFFFFC03FFFFFC07FFFFFC0FFFFFF80FFFFFF80FFFFFF801B277DA622>I<007F800003FF
+F00007FFFC000F81FE001F00FF003F80FF003F807F803F807F803F807F801F807F800F007F8000
+00FF000000FF000000FE000001FC000001F8000007F00000FFC00000FFF0000001FC0000007E00
+00007F0000007F8000003FC000003FC000003FE000003FE03C003FE07E003FE0FF003FE0FF003F
+E0FF003FC0FF007FC07E007F807C007F003F01FE001FFFFC0007FFF00000FF80001B277DA622>
+I<00000E0000001E0000003E0000007E000000FE000000FE000001FE000003FE0000077E00000E
+7E00000E7E00001C7E0000387E0000707E0000E07E0000E07E0001C07E0003807E0007007E000E
+007E000E007E001C007E0038007E0070007E00E0007E00FFFFFFF8FFFFFFF8FFFFFFF80000FE00
+0000FE000000FE000000FE000000FE000000FE000000FE000000FE00007FFFF8007FFFF8007FFF
+F81D277EA622>I<0C0003000F803F000FFFFE000FFFFC000FFFF8000FFFF0000FFFE0000FFFC0
+000FFE00000E0000000E0000000E0000000E0000000E0000000E0000000E7FC0000FFFF8000F80
+FC000E003E000C003F0000001F8000001FC000001FC000001FE000001FE018001FE07C001FE0FE
+001FE0FE001FE0FE001FE0FE001FC0FC001FC078003F8078003F803C007F001F01FE000FFFF800
+03FFF00000FF80001B277DA622>I<0007F000003FFC0000FFFE0001FC0F0003F01F8007E03F80
+0FC03F801FC03F801F803F803F801F003F8000007F0000007F0000007F000000FF000000FF0FC0
+00FF3FF800FF707C00FFC03E00FFC03F00FF801F80FF801FC0FF001FC0FF001FE0FF001FE0FF00
+1FE07F001FE07F001FE07F001FE07F001FE03F001FE03F001FC01F801FC01F803F800FC03F0007
+E07E0003FFFC0000FFF000003FC0001B277DA622>I<380000003E0000003FFFFFF03FFFFFF03F
+FFFFF07FFFFFE07FFFFFC07FFFFF807FFFFF0070000E0070000E0070001C00E0003800E0007000
+E000E0000000E0000001C000000380000007800000078000000F0000000F0000001F0000001F00
+00003F0000003E0000003E0000007E0000007E0000007E0000007E000000FE000000FE000000FE
+000000FE000000FE000000FE000000FE000000FE0000007C0000003800001C297CA822>I<003F
+C00001FFF00003FFFC0007C07E000F003F001E001F001E000F803E000F803E000F803F000F803F
+000F803FC00F003FF01F001FFC1E001FFE3C000FFFF80007FFE00003FFF80001FFFC0001FFFE00
+07FFFF000F0FFF801E03FFC03C01FFC07C007FE078001FE0F80007E0F80007E0F80003E0F80003
+E0F80003E0F80003C07C0003C07C0007803F000F001FC03E000FFFFC0003FFF800007FC0001B27
+7DA622>I<007F800001FFF00007FFF8000FE0FC001F807E003F803F007F003F007F001F80FF00
+1F80FF001FC0FF001FC0FF001FC0FF001FE0FF001FE0FF001FE0FF001FE07F001FE07F003FE03F
+003FE01F807FE00F807FE007C1DFE003FF9FE0007E1FE000001FE000001FC000001FC000001FC0
+00003F801F003F803F803F003F803F003F807E003F807C001F01F8001E03F0000FFFE00007FF80
+0001FE00001B277DA622>I<01FF000FFFE01E03F03801F87801FCFC01FEFE01FEFE01FEFE01FE
+7C01FE3801FC0003F80007F00007C0000F80001F00001E00003C00003800003800007800007000
+00700000700000700000700000700000000000000000000000000000000000000000700000F800
+01FC0003FE0003FE0003FE0001FC0000F800007000172A7CA920>63 D<000003800000000007C0
+0000000007C0000000000FE0000000000FE0000000000FE0000000001FF0000000001FF0000000
+003FF8000000003FF8000000003FF80000000073FC0000000073FC00000000F3FE00000000E1FE
+00000000E1FE00000001C0FF00000001C0FF00000003C0FF80000003807F80000007807FC00000
+07003FC0000007003FC000000E003FE000000E001FE000001E001FF000001C000FF000001FFFFF
+F000003FFFFFF800003FFFFFF80000780007FC0000700003FC0000700003FC0000E00001FE0000
+E00001FE0001E00001FF0001C00000FF0001C00000FF00FFFE001FFFFEFFFE001FFFFEFFFE001F
+FFFE2F297EA834>65 D<FFFFFFF80000FFFFFFFF8000FFFFFFFFC00003F8001FF00003F8000FF8
+0003F80007FC0003F80003FC0003F80003FC0003F80003FE0003F80001FE0003F80001FE0003F8
+0001FE0003F80003FE0003F80003FC0003F80003FC0003F80007F80003F8000FF00003F8001FE0
+0003F800FFC00003FFFFFE000003FFFFFFE00003F80007F00003F80003FC0003F80001FE0003F8
+0001FE0003F80000FF0003F80000FF0003F80000FF8003F80000FF8003F80000FF8003F80000FF
+8003F80000FF8003F80000FF8003F80000FF0003F80001FF0003F80003FE0003F80007FC0003F8
+001FF800FFFFFFFFF000FFFFFFFFC000FFFFFFFE000029297DA831>I<00003FF001800003FFFE
+0380000FFFFF8780003FF007DF8000FF8001FF8001FE00007F8003FC00003F8007F000001F800F
+F000000F801FE0000007801FE0000007803FC0000007803FC0000003807FC0000003807F800000
+03807F8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF
+8000000000FF8000000000FF8000000000FF80000000007F80000000007F80000000007FC00000
+03803FC0000003803FC0000003801FE0000003801FE0000007000FF00000070007F000000E0003
+FC00001E0001FE00003C0000FF8000F800003FF007E000000FFFFFC0000003FFFF000000003FF8
+000029297CA832>I<FFFFFFF80000FFFFFFFF8000FFFFFFFFE00003FC001FF80003FC0007FC00
+03FC0001FE0003FC0000FF0003FC00007F8003FC00003FC003FC00001FC003FC00001FE003FC00
+001FE003FC00000FF003FC00000FF003FC00000FF003FC00000FF003FC00000FF803FC00000FF8
+03FC00000FF803FC00000FF803FC00000FF803FC00000FF803FC00000FF803FC00000FF803FC00
+000FF803FC00000FF803FC00000FF003FC00000FF003FC00000FF003FC00001FE003FC00001FE0
+03FC00001FC003FC00003FC003FC00007F8003FC00007F0003FC0001FE0003FC0003FC0003FC00
+1FF800FFFFFFFFE000FFFFFFFF8000FFFFFFFC00002D297DA835>I<FFFFFFFFC0FFFFFFFFC0FF
+FFFFFFC003FC003FC003FC000FE003FC0003E003FC0001E003FC0001E003FC0000E003FC0000E0
+03FC0000E003FC0000F003FC03807003FC03807003FC03807003FC03800003FC07800003FC0780
+0003FC1F800003FFFF800003FFFF800003FFFF800003FC1F800003FC07800003FC07800003FC03
+800003FC03800003FC03800003FC03800003FC00000003FC00000003FC00000003FC00000003FC
+00000003FC00000003FC00000003FC00000003FC000000FFFFFC0000FFFFFC0000FFFFFC000024
+297DA82B>70 D<00007FE003000003FFFC0700001FFFFF0F00003FF00FFF0000FF8001FF0001FE
+0000FF0003F800003F0007F000003F000FF000001F001FE000000F001FE000000F003FC000000F
+003FC0000007007FC0000007007F80000007007F8000000000FF8000000000FF8000000000FF80
+00000000FF8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF8001FFFF
+F87F8001FFFFF87F8001FFFFF87FC00000FF003FC00000FF003FC00000FF001FE00000FF001FE0
+0000FF000FF00000FF0007F00000FF0003F80000FF0001FE0000FF0000FF8001FF00003FF007BF
+00001FFFFF1F000003FFFE0F0000007FF003002D297CA836>I<FFFFF01FFFFEFFFFF01FFFFEFF
+FFF01FFFFE03FC00007F8003FC00007F8003FC00007F8003FC00007F8003FC00007F8003FC0000
+7F8003FC00007F8003FC00007F8003FC00007F8003FC00007F8003FC00007F8003FC00007F8003
+FC00007F8003FC00007F8003FC00007F8003FFFFFFFF8003FFFFFFFF8003FFFFFFFF8003FC0000
+7F8003FC00007F8003FC00007F8003FC00007F8003FC00007F8003FC00007F8003FC00007F8003
+FC00007F8003FC00007F8003FC00007F8003FC00007F8003FC00007F8003FC00007F8003FC0000
+7F8003FC00007F8003FC00007F8003FC00007F80FFFFF01FFFFEFFFFF01FFFFEFFFFF01FFFFE2F
+297DA836>I<FFFFFCFFFFFCFFFFFC01FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE00
+01FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE00
+01FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE00
+01FE00FFFFFCFFFFFCFFFFFC16297EA81A>I<FFFFFC0000FFFFFC0000FFFFFC000003FC000000
+03FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC0000
+0003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00
+000003FC00000003FC00000003FC00000003FC00000003FC0001C003FC0001C003FC0001C003FC
+0001C003FC0003C003FC00038003FC00038003FC00078003FC00078003FC000F8003FC000F8003
+FC001F8003FC007F8003FC01FF00FFFFFFFF00FFFFFFFF00FFFFFFFF0022297DA829>76
+D<FFFE0000001FFFC0FFFE0000001FFFC0FFFF0000003FFFC003FF0000003FF00003FF0000003F
+F00003BF80000077F00003BF80000077F000039FC00000E7F000039FC00000E7F000038FE00001
+C7F000038FE00001C7F0000387F0000387F0000387F0000387F0000387F0000387F0000383F800
+0707F0000383F8000707F0000381FC000E07F0000381FC000E07F0000380FE001C07F0000380FE
+001C07F0000380FF003807F00003807F003807F00003807F003807F00003803F807007F0000380
+3F807007F00003801FC0E007F00003801FC0E007F00003800FE1C007F00003800FE1C007F00003
+800FE1C007F000038007F38007F000038007F38007F000038003FF0007F000038003FF0007F000
+038001FE0007F000038001FE0007F000038000FC0007F000038000FC0007F000FFFE00FC01FFFF
+C0FFFE007801FFFFC0FFFE007801FFFFC03A297DA841>I<FFFC0000FFFEFFFE0000FFFEFFFF00
+00FFFE03FF8000038003FF8000038003BFC0000380039FE0000380039FF0000380038FF8000380
+0387F80003800383FC0003800381FE0003800381FF0003800380FF80038003807FC0038003803F
+C0038003801FE0038003800FF0038003800FF80380038007FC0380038003FC0380038001FE0380
+038000FF0380038000FF83800380007FC3800380003FE3800380001FE3800380000FF380038000
+07FB8003800007FF8003800003FF8003800001FF8003800000FF80038000007F80038000007F80
+038000003F80038000001F80038000000F80FFFE00000780FFFE00000380FFFE000003802F297D
+A836>I<0000FFE000000007FFFC0000003FC07F8000007F001FC00001FC0007F00003F80003F8
+0007F00001FC000FF00001FE001FE00000FF001FE00000FF003FC000007F803FC000007F807FC0
+00007FC07F8000003FC07F8000003FC07F8000003FC0FF8000003FE0FF8000003FE0FF8000003F
+E0FF8000003FE0FF8000003FE0FF8000003FE0FF8000003FE0FF8000003FE0FF8000003FE0FF80
+00003FE07F8000003FC07FC000007FC07FC000007FC03FC000007F803FC000007F801FE00000FF
+001FE00000FF000FF00001FE0007F00001FC0003F80003F80001FC0007F00000FF001FE000003F
+C07F8000000FFFFE00000000FFE000002B297CA834>I<FFFFFFF800FFFFFFFF00FFFFFFFFC003
+FC003FE003FC000FF003FC0007F803FC0007FC03FC0003FC03FC0003FE03FC0003FE03FC0003FE
+03FC0003FE03FC0003FE03FC0003FE03FC0003FE03FC0003FC03FC0007FC03FC0007F803FC000F
+F003FC003FE003FFFFFF8003FFFFFE0003FC00000003FC00000003FC00000003FC00000003FC00
+000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC
+00000003FC00000003FC00000003FC000000FFFFF00000FFFFF00000FFFFF0000027297DA82F>
+I<FFFFFFE00000FFFFFFFE0000FFFFFFFF800003FC007FE00003FC000FF00003FC0007F80003FC
+0007FC0003FC0003FC0003FC0003FE0003FC0003FE0003FC0003FE0003FC0003FE0003FC0003FE
+0003FC0003FE0003FC0003FC0003FC0007F80003FC0007F80003FC001FE00003FC007FC00003FF
+FFFE000003FFFFF0000003FC00FC000003FC007F000003FC003F800003FC003F800003FC001FC0
+0003FC001FE00003FC001FE00003FC001FE00003FC001FE00003FC001FE00003FC001FF00003FC
+001FF00003FC001FF00003FC001FF00703FC001FF80703FC000FF80703FC0007F80EFFFFF003FE
+1CFFFFF001FFF8FFFFF0003FF030297DA834>82 D<007F806003FFF0E007FFF9E00F807FE01F00
+1FE03E0007E07C0003E07C0001E0FC0001E0FC0001E0FC0000E0FE0000E0FE0000E0FF000000FF
+C000007FFE00007FFFE0003FFFFC001FFFFE000FFFFF8007FFFFC003FFFFE000FFFFE00007FFF0
+00007FF000000FF8000007F8000003F8600001F8E00001F8E00001F8E00001F8F00001F0F00001
+F0F80003F0FC0003E0FF0007C0FFE01F80F3FFFF00E0FFFE00C01FF0001D297CA826>I<7FFFFF
+FFFFC07FFFFFFFFFC07FFFFFFFFFC07F803FC03FC07E003FC007C078003FC003C078003FC003C0
+70003FC001C0F0003FC001E0F0003FC001E0E0003FC000E0E0003FC000E0E0003FC000E0E0003F
+C000E0E0003FC000E000003FC0000000003FC0000000003FC0000000003FC0000000003FC00000
+00003FC0000000003FC0000000003FC0000000003FC0000000003FC0000000003FC0000000003F
+C0000000003FC0000000003FC0000000003FC0000000003FC0000000003FC0000000003FC00000
+00003FC0000000003FC0000000003FC0000000003FC00000007FFFFFE000007FFFFFE000007FFF
+FFE0002B287EA730>I<FFFFF001FFFCFFFFF001FFFCFFFFF001FFFC03FC0000070003FC000007
+0003FC0000070003FC0000070003FC0000070003FC0000070003FC0000070003FC0000070003FC
+0000070003FC0000070003FC0000070003FC0000070003FC0000070003FC0000070003FC000007
+0003FC0000070003FC0000070003FC0000070003FC0000070003FC0000070003FC0000070003FC
+0000070003FC0000070003FC0000070003FC0000070003FC0000070003FC0000070003FC000007
+0001FC00000E0001FE00000E0000FE00001C00007E00001C00007F00003800003FC000F000000F
+F007E0000007FFFFC0000001FFFF000000001FF800002E297DA835>I<FFFFF0003FFF80FFFFF0
+003FFF80FFFFF0003FFF8003FE000001E00001FE000001C00001FF000003C00000FF0000038000
+00FF0000038000007F8000070000007F8000070000007FC0000F0000003FC0000E0000003FE000
+1E0000001FE0001C0000001FF0001C0000000FF000380000000FF0003800000007F80070000000
+07F8007000000007FC00F000000003FC00E000000003FE01E000000001FE01C000000001FF01C0
+00000000FF038000000000FF038000000000FF8780000000007F8700000000007FCF0000000000
+3FCE00000000003FFE00000000001FFC00000000001FFC00000000000FF800000000000FF80000
+0000000FF8000000000007F0000000000007F0000000000003E0000000000003E0000000000001
+C000000031297FA834>I<FFFFE07FFFF007FFF0FFFFE07FFFF007FFF0FFFFE07FFFF007FFF003
+FC0001FE00001C0003FC0001FE00001C0001FE0001FF0000380001FE0000FF0000380001FF0000
+FF0000780000FF0000FF8000700000FF0000FF8000700000FF8000FF8000F000007F8001FFC000
+E000007F8001FFC000E000003FC003FFE001C000003FC0039FE001C000003FE0039FE003C00000
+1FE0070FF0038000001FE0070FF0038000001FF00F0FF0078000000FF00E07F8070000000FF00E
+07F80700000007F81E07FC0E00000007F81C03FC0E00000007FC1C03FC1E00000003FC3801FE1C
+00000003FC3801FE1C00000001FE7801FF3800000001FE7000FF3800000001FE7000FF38000000
+00FFF000FFF000000000FFE0007FF000000000FFE0007FF0000000007FC0003FE0000000007FC0
+003FE0000000003FC0003FC0000000003F80001FC0000000003F80001FC0000000001F80001F80
+000000001F00000F80000000001F00000F80000000000E00000700000044297FA847>I<01FF80
+0007FFF0000F81F8001FC07E001FC07E001FC03F000F803F8007003F8000003F8000003F800000
+3F80000FFF8000FFFF8007FC3F800FE03F803F803F803F003F807F003F80FE003F80FE003F80FE
+003F80FE003F807E007F807F00DF803F839FFC0FFF0FFC01FC03FC1E1B7E9A21>97
+D<FFE0000000FFE0000000FFE00000000FE00000000FE00000000FE00000000FE00000000FE000
+00000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE1
+FE00000FE7FF80000FFE07E0000FF801F0000FF000F8000FE000FC000FE000FE000FE0007F000F
+E0007F000FE0007F000FE0007F800FE0007F800FE0007F800FE0007F800FE0007F800FE0007F80
+0FE0007F800FE0007F000FE0007F000FE0007F000FE000FE000FE000FC000FF001F8000FF803F0
+000F9E07E0000F07FF80000E01FC0000212A7EA926>I<001FF80000FFFE0003F01F0007E03F80
+0FC03F801F803F803F801F007F800E007F0000007F000000FF000000FF000000FF000000FF0000
+00FF000000FF000000FF0000007F0000007F0000007F8000003F8001C01F8001C00FC0038007E0
+070003F01E0000FFFC00001FE0001A1B7E9A1F>I<00003FF80000003FF80000003FF800000003
+F800000003F800000003F800000003F800000003F800000003F800000003F800000003F8000000
+03F800000003F800000003F800000003F800001FE3F80000FFFBF80003F03FF80007E00FF8000F
+C007F8001F8003F8003F8003F8007F0003F8007F0003F8007F0003F800FF0003F800FF0003F800
+FF0003F800FF0003F800FF0003F800FF0003F800FF0003F8007F0003F8007F0003F8007F0003F8
+003F8003F8001F8003F8000F8007F80007C00FF80003F03BFF8000FFF3FF80003FC3FF80212A7E
+A926>I<003FE00001FFF80003F07E0007C01F000F801F801F800F803F800FC07F000FC07F0007
+C07F0007E0FF0007E0FF0007E0FFFFFFE0FFFFFFE0FF000000FF000000FF0000007F0000007F00
+00007F0000003F8000E01F8000E00FC001C007E0038003F81F0000FFFE00001FF0001B1B7E9A20
+>I<0007F0003FFC00FE3E01F87F03F87F03F07F07F07F07F03E07F00007F00007F00007F00007
+F00007F00007F000FFFFC0FFFFC0FFFFC007F00007F00007F00007F00007F00007F00007F00007
+F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007
+F0007FFF807FFF807FFF80182A7EA915>I<00FF81F003FFE7F80FC1FE7C1F80FC7C1F007C383F
+007E107F007F007F007F007F007F007F007F007F007F007F007F003F007E001F007C001F80FC00
+0FC1F8001FFFE00018FF800038000000380000003C0000003E0000003FFFF8001FFFFF001FFFFF
+800FFFFFC007FFFFE01FFFFFF03E0007F07C0001F8F80000F8F80000F8F80000F8F80000F87C00
+01F03C0001E01F0007C00FC01F8003FFFE00007FF0001E287E9A22>I<FFE0000000FFE0000000
+FFE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000
+000FE00000000FE00000000FE00000000FE00000000FE00000000FE07F00000FE1FFC0000FE787
+E0000FEE03F0000FF803F0000FF803F8000FF003F8000FF003F8000FE003F8000FE003F8000FE0
+03F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000F
+E003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F800FFFE3FFF80FFFE3FFF80
+FFFE3FFF80212A7DA926>I<07000F801FC03FE03FE03FE01FC00F800700000000000000000000
+0000000000FFE0FFE0FFE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE0
+0FE00FE00FE00FE00FE00FE00FE0FFFEFFFEFFFE0F2B7DAA14>I<FFE00000FFE00000FFE00000
+0FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000
+000FE000000FE000000FE01FFC0FE01FFC0FE01FFC0FE007800FE00F000FE01E000FE03C000FE0
+78000FE0E0000FE3C0000FE7C0000FEFE0000FFFE0000FFFF0000FF3F8000FE3F8000FC1FC000F
+C0FE000FC07F000FC07F000FC03F800FC01FC00FC00FC00FC00FE0FFFC3FFEFFFC3FFEFFFC3FFE
+1F2A7EA924>107 D<FFE0FFE0FFE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE0
+0FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00F
+E00FE00FE00FE00FE0FFFEFFFEFFFE0F2A7DA914>I<FFC07F800FF000FFC1FFE03FFC00FFC383
+F0707E000FC603F8C07F000FCC01F9803F000FD801FF003F800FF001FE003F800FF001FE003F80
+0FE001FC003F800FE001FC003F800FE001FC003F800FE001FC003F800FE001FC003F800FE001FC
+003F800FE001FC003F800FE001FC003F800FE001FC003F800FE001FC003F800FE001FC003F800F
+E001FC003F800FE001FC003F800FE001FC003F800FE001FC003F800FE001FC003F80FFFE1FFFC3
+FFF8FFFE1FFFC3FFF8FFFE1FFFC3FFF8351B7D9A3A>I<FFC07F0000FFC1FFC000FFC787E0000F
+CE03F0000FD803F0000FD803F8000FF003F8000FF003F8000FE003F8000FE003F8000FE003F800
+0FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8
+000FE003F8000FE003F8000FE003F8000FE003F8000FE003F800FFFE3FFF80FFFE3FFF80FFFE3F
+FF80211B7D9A26>I<003FE00001FFFC0003F07E000FC01F801F800FC03F800FE03F0007E07F00
+07F07F0007F07F0007F0FF0007F8FF0007F8FF0007F8FF0007F8FF0007F8FF0007F8FF0007F8FF
+0007F87F0007F07F0007F03F800FE03F800FE01F800FC00FC01F8007F07F0001FFFC00003FE000
+1D1B7E9A22>I<FFE1FE0000FFE7FF8000FFFE07E0000FF803F0000FF001F8000FE000FC000FE0
+00FE000FE000FF000FE0007F000FE0007F000FE0007F800FE0007F800FE0007F800FE0007F800F
+E0007F800FE0007F800FE0007F800FE0007F000FE000FF000FE000FF000FE000FE000FE001FC00
+0FF001F8000FF803F0000FFE0FE0000FE7FF80000FE1FC00000FE00000000FE00000000FE00000
+000FE00000000FE00000000FE00000000FE00000000FE00000000FE0000000FFFE000000FFFE00
+0000FFFE00000021277E9A26>I<FFC1F0FFC7FCFFCE3E0FD87F0FD87F0FF07F0FF03E0FF01C0F
+E0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000F
+E0000FE0000FE000FFFF00FFFF00FFFF00181B7E9A1C>114 D<03FE300FFFF01E03F03800F070
+0070F00070F00070F80070FC0000FFE0007FFE007FFF803FFFE01FFFF007FFF800FFF80003FC00
+00FC60007CE0003CF0003CF00038F80038FC0070FF01E0F7FFC0C1FF00161B7E9A1B>I<007000
+00700000700000700000F00000F00000F00001F00003F00003F00007F0001FFFF0FFFFF0FFFFF0
+07F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F000
+07F03807F03807F03807F03807F03807F03803F03803F87001F86000FFC0001F8015267FA51B>
+I<FFE03FF800FFE03FF800FFE03FF8000FE003F8000FE003F8000FE003F8000FE003F8000FE003
+F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE0
+03F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE007F80007E007F80007
+E00FF80003F03BFF8001FFF3FF80003FC3FF80211B7D9A26>I<FFFE03FF80FFFE03FF80FFFE03
+FF8007F000700007F000700007F800F00003F800E00003FC01E00001FC01C00001FC01C00000FE
+03800000FE038000007F070000007F070000007F8F0000003F8E0000003FDE0000001FDC000000
+1FDC0000000FF80000000FF80000000FF800000007F000000007F000000003E000000003E00000
+0001C00000211B7F9A24>I<FFFE7FFC0FFEFFFE7FFC0FFEFFFE7FFC0FFE0FE007E000E007F003
+F001C007F003F001C007F807F803C003F807F8038003F807F8038001FC0EFC070001FC0EFC0700
+01FE1EFC0F0000FE1C7E0E0000FE1C7E0E0000FF383F1E00007F383F1C00007F783F3C00003FF0
+1FB800003FF01FB800003FF01FF800001FE00FF000001FE00FF000000FC007E000000FC007E000
+000FC007E00000078003C00000078003C0002F1B7F9A32>I<FFFC0FFF00FFFC0FFF00FFFC0FFF
+0007F003C00003F807800001FC07800000FE0F000000FF1E0000007F3C0000003FF80000001FF0
+0000000FF00000000FF000000007F000000007F80000000FFC0000001FFE0000001EFE0000003C
+7F000000783F800000F01FC00001E01FE00001C00FE00003C007F000FFF01FFF80FFF01FFF80FF
+F01FFF80211B7F9A24>I<FFFE03FF80FFFE03FF80FFFE03FF8007F000700007F000700007F800
+F00003F800E00003FC01E00001FC01C00001FC01C00000FE03800000FE038000007F070000007F
+070000007F8F0000003F8E0000003FDE0000001FDC0000001FDC0000000FF80000000FF8000000
+0FF800000007F000000007F000000003E000000003E000000001C000000001C000000003800000
+000380000038078000007C07000000FE0F000000FE0E000000FE1E000000FE3C0000007C780000
+003FE00000000FC000000021277F9A24>I E /Ff 17 121 df<00001E000000003E00000000FE
+00000003FE0000003FFE0000FFFFFE0000FFFFFE0000FFFFFE0000FFCFFE0000000FFE0000000F
+FE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE000000
+0FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000
+000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE00
+00000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE
+0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000F
+FE0000000FFE0000000FFE00007FFFFFFFC07FFFFFFFC07FFFFFFFC07FFFFFFFC0223879B731>
+49 D<0007FE0000007FFFE00001FFFFF80003FFFFFE0007F01FFF000F8007FF801F0001FFC03E
+0000FFE07F8000FFF07FC0007FF0FFE0007FF8FFF0003FF8FFF0003FFCFFF0003FFCFFF0003FFC
+FFF0003FFC7FE0003FFC3FC0003FFC1F80003FFC0000003FFC0000003FF80000007FF80000007F
+F00000007FF0000000FFE0000000FFC0000001FF80000001FF00000003FE00000007FC00000007
+F80000000FF00000001FC00000003F800000007F00000000FC00000001F800000001F0003C0003
+E0003C0007C0003C000F000078001E000078003C00007800780000F800F00000F801FFFFFFF803
+FFFFFFF007FFFFFFF00FFFFFFFF01FFFFFFFF03FFFFFFFF07FFFFFFFF0FFFFFFFFF0FFFFFFFFE0
+FFFFFFFFE0FFFFFFFFE026387BB731>I<0003FF8000001FFFF000007FFFFE0000FE03FF0001F0
+00FF8003C000FFC00780007FE00FF0007FF00FF8007FF01FFC007FF81FFE007FF81FFE007FF81F
+FE007FF81FFE007FF81FFE007FF80FFC007FF007F8007FF003F0007FF0000000FFE0000000FFC0
+000001FF80000001FF00000003FE00000007FC0000001FF000000FFFC000000FFF8000000FFFF8
+00000003FE00000000FF800000007FE00000003FF00000003FF80000003FFC0000001FFC000000
+1FFE0000001FFE0200001FFF1FC0001FFF3FE0001FFF7FF0001FFF7FF0001FFFFFF8001FFFFFF8
+001FFFFFF8001FFEFFF8001FFEFFF0001FFE7FF0003FFC7FE0003FFC3FC0003FF81F80007FF01F
+E000FFE007FC03FFC003FFFFFF0001FFFFFE00003FFFF0000007FF800028397CB731>I<000000
+07C0000000000FC0000000000FC0000000001FC0000000003FC0000000007FC000000000FFC000
+000000FFC000000001FFC000000003FFC000000007FFC00000000FFFC00000000FFFC00000001E
+FFC00000003CFFC00000007CFFC0000000F8FFC0000000F0FFC0000001E0FFC0000003C0FFC000
+0007C0FFC000000F80FFC000000F00FFC000001E00FFC000003C00FFC000007C00FFC00000F800
+FFC00000F000FFC00001E000FFC00003C000FFC00007C000FFC0000F8000FFC0000F0000FFC000
+1E0000FFC0003C0000FFC0007C0000FFC000F80000FFC000FFFFFFFFFFC0FFFFFFFFFFC0FFFFFF
+FFFFC0FFFFFFFFFFC0000001FFC000000001FFC000000001FFC000000001FFC000000001FFC000
+000001FFC000000001FFC000000001FFC000000001FFC000000001FFC0000007FFFFFFC00007FF
+FFFFC00007FFFFFFC00007FFFFFFC02A377DB631>I<00000001F80000000000000001F8000000
+0000000003FC0000000000000003FC0000000000000007FE0000000000000007FE000000000000
+0007FE000000000000000FFF000000000000000FFF000000000000001FFF800000000000001FFF
+800000000000001FFF800000000000003FFFC00000000000003FFFC00000000000007FFFE00000
+000000007DFFE00000000000007DFFE0000000000000FDFFF0000000000000F8FFF00000000000
+01F8FFF8000000000001F07FF8000000000001F07FF8000000000003F07FFC000000000003E03F
+FC000000000007E03FFE000000000007C01FFE00000000000FC01FFF00000000000F801FFF0000
+0000000F800FFF00000000001F800FFF80000000001F0007FF80000000003F0007FFC000000000
+3E0003FFC0000000003E0003FFC0000000007E0003FFE0000000007C0001FFE000000000FC0001
+FFF000000000F80000FFF000000000F80000FFF000000001FFFFFFFFF800000001FFFFFFFFF800
+000003FFFFFFFFFC00000003FFFFFFFFFC00000003E000003FFC00000007E000003FFE00000007
+C000001FFE0000000FC000001FFF0000000F8000000FFF0000001F8000000FFF8000001F000000
+0FFF8000001F00000007FF8000003F00000007FFC000003E00000003FFC000007E00000003FFE0
+0000FF00000001FFE000FFFFFC0001FFFFFFF0FFFFFC0001FFFFFFF0FFFFFC0001FFFFFFF0FFFF
+FC0001FFFFFFF0443B7DBA4B>65 D<FFFFFFFFFFC00000FFFFFFFFFFFC0000FFFFFFFFFFFF0000
+FFFFFFFFFFFFC000007FF00001FFF000007FF000007FF800007FF000003FFC00007FF000001FFE
+00007FF000001FFE00007FF000000FFF00007FF000000FFF00007FF0000007FF80007FF0000007
+FF80007FF0000007FF80007FF0000007FF80007FF0000007FF80007FF0000007FF80007FF00000
+07FF80007FF0000007FF00007FF000000FFF00007FF000000FFF00007FF000001FFE00007FF000
+001FFC00007FF000003FF800007FF000007FF000007FF00001FFE000007FF0000FFF8000007FFF
+FFFFFE0000007FFFFFFFFE0000007FFFFFFFFFC000007FF000007FF000007FF000001FFC00007F
+F000000FFE00007FF0000007FF00007FF0000007FF80007FF0000003FFC0007FF0000003FFC000
+7FF0000001FFE0007FF0000001FFE0007FF0000001FFF0007FF0000001FFF0007FF0000001FFF0
+007FF0000001FFF0007FF0000001FFF0007FF0000001FFF0007FF0000001FFF0007FF0000001FF
+F0007FF0000001FFE0007FF0000003FFE0007FF0000003FFC0007FF0000007FFC0007FF000000F
+FF80007FF000001FFF00007FF000003FFE00007FF00001FFFC00FFFFFFFFFFFFF800FFFFFFFFFF
+FFE000FFFFFFFFFFFF8000FFFFFFFFFFF800003C3B7CBA46>I<0000001FFF000030000001FFFF
+E000F000000FFFFFFC01F000007FFFFFFE03F00001FFFE007F87F00003FFE0000FCFF0000FFF00
+0003FFF0001FFC000001FFF0003FF80000007FF0007FF00000003FF000FFC00000003FF001FFC0
+0000001FF003FF800000000FF007FF000000000FF00FFF0000000007F00FFE0000000007F01FFE
+0000000003F01FFE0000000003F03FFC0000000003F03FFC0000000001F03FFC0000000001F07F
+FC0000000001F07FF80000000001F07FF80000000000007FF8000000000000FFF8000000000000
+FFF8000000000000FFF8000000000000FFF8000000000000FFF8000000000000FFF80000000000
+00FFF8000000000000FFF8000000000000FFF8000000000000FFF8000000000000FFF800000000
+00007FF80000000000007FF80000000000007FF80000000000007FFC0000000000F03FFC000000
+0000F03FFC0000000000F03FFC0000000000F01FFE0000000000F01FFE0000000001E00FFE0000
+000001E00FFF0000000001E007FF0000000003C003FF8000000003C001FFC0000000078000FFE0
+0000000F00007FF00000001F00003FF80000003E00001FFC0000007C00000FFF000001F8000003
+FFE00007F0000001FFFE003FC00000007FFFFFFF000000000FFFFFFC0000000001FFFFF0000000
+00001FFF0000003C3D7BBB47>I<001FFF00000001FFFFF0000003FFFFFC000007F007FE00000F
+F801FF00001FFC00FF80001FFC007FC0001FFC007FE0001FFC003FE0000FF8003FF0000FF8003F
+F00007F0003FF00001C0003FF0000000003FF0000000003FF0000000003FF0000000FFFFF00000
+0FFFFFF000007FF83FF00001FF803FF00007FE003FF0000FF8003FF0001FF0003FF0003FE0003F
+F0007FE0003FF0007FE0003FF000FFC0003FF000FFC0003FF000FFC0003FF000FFC0003FF000FF
+C0007FF0007FE0007FF0007FE000DFF0003FF0039FF8001FFC0F0FFFF007FFFE0FFFF001FFFC07
+FFF0003FE000FFF02C267DA530>97 D<000000003FC00000003FFFC00000003FFFC00000003FFF
+C00000003FFFC000000001FFC000000000FFC000000000FFC000000000FFC000000000FFC00000
+0000FFC000000000FFC000000000FFC000000000FFC000000000FFC000000000FFC000000000FF
+C000000000FFC000000000FFC000000000FFC000000000FFC000000000FFC00000FFC0FFC0000F
+FFF8FFC0003FFFFEFFC000FFE03FFFC001FF000FFFC003FE0003FFC007FC0001FFC00FF80000FF
+C01FF00000FFC01FF00000FFC03FF00000FFC03FE00000FFC07FE00000FFC07FE00000FFC07FE0
+0000FFC0FFE00000FFC0FFE00000FFC0FFE00000FFC0FFE00000FFC0FFE00000FFC0FFE00000FF
+C0FFE00000FFC0FFE00000FFC0FFE00000FFC07FE00000FFC07FE00000FFC07FE00000FFC03FF0
+0000FFC03FF00000FFC01FF00000FFC00FF80001FFC007F80003FFC003FC0007FFC001FE000FFF
+E000FFC07EFFFF003FFFFCFFFF000FFFF0FFFF0001FF80FFFF303C7DBB37>100
+D<0001FFC000000FFFF800003FFFFE0000FF80FF0001FE003F8007FC001FC00FF8000FE00FF800
+0FF01FF00007F03FF00007F83FF00007F87FE00007F87FE00003FC7FE00003FC7FE00003FCFFE0
+0003FCFFFFFFFFFCFFFFFFFFFCFFFFFFFFFCFFE0000000FFE0000000FFE0000000FFE00000007F
+E00000007FE00000007FE00000003FE00000003FF000003C1FF000003C1FF000003C0FF8000078
+07FC0000F803FE0001F001FF0007E000FFC03FC0003FFFFF000007FFFC000000FFE00026267DA5
+2D>I<00FF00000000FFFF00000000FFFF00000000FFFF00000000FFFF0000000007FF00000000
+03FF0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF00
+00000003FF0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF00000000
+03FF0000000003FF0000000003FF0000000003FF007FC00003FF01FFF80003FF07FFFC0003FF0F
+03FE0003FF1C01FF0003FF3001FF8003FF6000FF8003FFE000FFC003FFC000FFC003FF8000FFC0
+03FF8000FFC003FF8000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF00
+00FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC0
+03FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF00
+00FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC0FFFFFC3FFFFFFFFFFC3FFFFF
+FFFFFC3FFFFFFFFFFC3FFFFF303C7CBB37>104 D<01F00007FC000FFE000FFE001FFF001FFF00
+1FFF001FFF001FFF000FFE000FFE0007FC0001F000000000000000000000000000000000000000
+00000000000000000000000000FF00FFFF00FFFF00FFFF00FFFF0007FF0003FF0003FF0003FF00
+03FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF00
+03FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF00FFFFF8
+FFFFF8FFFFF8FFFFF8153D7DBC1B>I<00FE007FC000FFFE01FFF800FFFE07FFFC00FFFE0F03FE
+00FFFE1C01FF0007FE3001FF8003FE6000FF8003FEE000FFC003FEC000FFC003FF8000FFC003FF
+8000FFC003FF8000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FF
+C003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF
+0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FF
+C003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC0FFFFFC3FFFFFFFFFFC3FFFFFFFFF
+FC3FFFFFFFFFFC3FFFFF30267CA537>110 D<00FF01FF8000FFFF0FFFF000FFFF3FFFFC00FFFF
+FE03FF00FFFFF000FF8003FFC0007FC003FF80003FE003FF00003FF003FF00001FF803FF00001F
+FC03FF00000FFC03FF00000FFE03FF00000FFE03FF000007FE03FF000007FF03FF000007FF03FF
+000007FF03FF000007FF03FF000007FF03FF000007FF03FF000007FF03FF000007FF03FF000007
+FF03FF000007FE03FF000007FE03FF00000FFE03FF00000FFC03FF00000FFC03FF00001FF803FF
+00001FF803FF00003FF003FF80003FE003FFC0007FC003FFF001FF8003FFFC07FF0003FF3FFFFC
+0003FF0FFFF00003FF01FF000003FF0000000003FF0000000003FF0000000003FF0000000003FF
+0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF000000
+0003FF0000000003FF00000000FFFFFC000000FFFFFC000000FFFFFC000000FFFFFC0000003037
+7DA537>112 D<00FE03F000FFFE0FFE00FFFE1FFF00FFFE3C3F80FFFE707FC007FE60FFE003FE
+E0FFE003FEC0FFE003FFC0FFE003FF807FC003FF807FC003FF803F8003FF800E0003FF00000003
+FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF000000
+03FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF0000
+0003FF00000003FF00000003FF00000003FF000000FFFFFE0000FFFFFE0000FFFFFE0000FFFFFE
+000023267DA529>114 D<0007800000078000000780000007800000078000000F8000000F8000
+000F8000000F8000001F8000001F8000003F8000003F8000007F800000FF800001FF800007FF80
+001FFFFFF0FFFFFFF0FFFFFFF0FFFFFFF001FF800001FF800001FF800001FF800001FF800001FF
+800001FF800001FF800001FF800001FF800001FF800001FF800001FF800001FF800001FF800001
+FF800001FF800001FF800001FF800001FF803C01FF803C01FF803C01FF803C01FF803C01FF803C
+01FF803C01FF803C00FF807800FFC078007FC070003FE0E0001FFFC00007FF800001FF001E377E
+B626>116 D<FFFFF007FFFCFFFFF007FFFCFFFFF007FFFCFFFFF007FFFC01FF8000FC0000FFC0
+00F80000FFE001F000007FF003E000003FF007C000001FF80FC000000FFC1F8000000FFE1F0000
+0007FF3E00000003FFFC00000001FFF800000000FFF0000000007FE0000000007FF0000000003F
+F8000000001FF8000000001FFC000000003FFE000000007FFF00000000FBFF80000001F9FF8000
+0003F0FFC0000003E07FE0000007C07FF000000F803FF800001F001FFC00003E000FFC00007C00
+07FE0000FC0003FF0001FC0003FF80FFFF801FFFFEFFFF801FFFFEFFFF801FFFFEFFFF801FFFFE
+2F267EA534>120 D E /Fg 1 98 df<00200000700000700000700000B80000B80000B800011C
+00011C00011C00020E00020E0004070004070007FF000803800803800803801801C03803C0FE0F
+F815157F9419>97 D E /Fh 36 122 df<0001FC000703000C03001C07001C0300180000380000
+380000380000380000700007FFFC00701C00701C00701C00E03800E03800E03800E03800E07001
+C07001C07001C07001C0E201C0E201C0E20380E4038064038038038000030000070000060000C6
+0000E40000CC00007000001825819C17>12 D<183C3C3C0404080810204080060C779C0D>39
+D<0000180000001800000038000000380000007800000078000000B8000001B800000138000002
+380000023C0000041C0000041C0000081C0000181C0000101C0000201C0000201C00007FFC0000
+401C0000801C0001801C0001001C0002001C0002001C0004000E000C000E001C001E00FF00FFC0
+1A1D7E9C1F>65 D<0003F020001E0C60003002E000E003C001C001C0038001C0070000C00E0000
+801E0000801C0000803C0000803C000000780000007800000078000000F0000000F0000000F000
+0000F0000000F0000400F0000400F0000400F0000800700008007000100038002000180040000C
+0180000706000001F800001B1E7A9C1E>67 D<01FFFFC0003C01C0003800C00038008000380080
+003800800070008000700080007020800070200000E0400000E0400000E0C00000FFC00001C080
+0001C0800001C0800001C080000381000003800000038000000380000007000000070000000700
+0000070000000F000000FFF000001A1C7D9B1B>70 D<01FFCFFE003C01E0003801C0003801C000
+3801C0003801C00070038000700380007003800070038000E0070000E0070000E0070000FFFF00
+01C00E0001C00E0001C00E0001C00E0003801C0003801C0003801C0003801C0007003800070038
+0007003800070038000F007800FFE7FF001F1C7D9B1F>72 D<01FFC0003C000038000038000038
+0000380000700000700000700000700000E00000E00000E00000E00001C00001C00001C00001C0
+000380000380000380000380000700000700000700000700000F0000FFE000121C7E9B10>I<00
+7FF0000780000700000700000700000700000E00000E00000E00000E00001C00001C00001C0000
+1C0000380000380000380000380000700000700000700000700060E000E0E000C0C00081C00083
+80004700003C0000141D7B9B16>I<01FE0007F8003E000780002E000F00002E001700002E0017
+00002E002700004E002E00004E004E00004E004E00004E008E00008E011C00008E011C00008E02
+1C00008E021C000107043800010704380001070838000107103800020710700002072070000207
+2070000207407000040740E000040780E000040700E0000C0700E0001C0601E000FF861FFC0025
+1C7D9B25>77 D<01FFFC00003C070000380380003801C0003801C0003801C0007003C0007003C0
+007003C00070038000E0078000E0070000E00E0000E0380001FFE00001C0000001C0000001C000
+0003800000038000000380000003800000070000000700000007000000070000000F000000FFE0
+00001A1C7D9B1C>80 D<000F8400304C00403C0080180100180300180300180600100600100600
+0007000007000003E00003FC0001FF00007F800007C00001C00001C00000C00000C02000C02000
+C0600180600180600300600200F00400CC180083E000161E7D9C17>83 D<1FFFFFC01C0701C030
+0E00C0200E0080600E0080400E0080401C0080801C0080801C0080001C00000038000000380000
+00380000003800000070000000700000007000000070000000E0000000E0000000E0000000E000
+0001C0000001C0000001C0000001C0000003C000007FFE00001A1C799B1E>I<7FF0FF800F001C
+000E0018000E0010000E0010000E0010001C0020001C0020001C0020001C002000380040003800
+4000380040003800400070008000700080007000800070008000E0010000E0010000E0010000E0
+020000E0020000E0040000E00400006008000030300000104000000F800000191D779B1F>I<FF
+83FF0FF03C007001C038007001803800F001003800F00200380170020038017004003802700400
+38027008001C047008001C047010001C087010001C087020001C107020001C107040001C207040
+001C207080001C407180001C407100001C807200001D807200001D007400001E007400001E0078
+00001C007800001C00700000180070000018006000001000600000241D779B29>87
+D<03CC063C0C3C181C3838303870387038E070E070E070E070E0E2C0E2C0E261E462643C380F12
+7B9115>97 D<3F00070007000E000E000E000E001C001C001C001C0039C03E6038303830703870
+3870387038E070E070E070E060E0E0C0C0C1C0618063003C000D1D7B9C13>I<01F007080C0818
+1C3838300070007000E000E000E000E000E000E008E010602030C01F000E127B9113>I<001F80
+000380000380000700000700000700000700000E00000E00000E00000E0003DC00063C000C3C00
+181C00383800303800703800703800E07000E07000E07000E07000E0E200C0E200C0E20061E400
+6264003C3800111D7B9C15>I<01E007100C1018083810701070607F80E000E000E000E000E000
+E0086010602030C01F000D127B9113>I<0003C0000670000C70001C60001C00001C0000380000
+380000380000380000380003FF8000700000700000700000700000700000E00000E00000E00000
+E00000E00001C00001C00001C00001C00001C000038000038000038000030000030000070000C6
+0000E60000CC00007800001425819C0D>I<00F3018F030F06070E0E0C0E1C0E1C0E381C381C38
+1C381C383830383038187818F00F700070007000E000E0C0C0E1C0C3007E00101A7D9113>I<0F
+C00001C00001C0000380000380000380000380000700000700000700000700000E78000E8C000F
+0E000E0E001C0E001C0E001C0E001C0E00381C00381C00381C0038380070388070388070708070
+7100E03200601C00111D7D9C15>I<01800380010000000000000000000000000000001C002600
+470047008E008E000E001C001C001C0038003800710071007100720072003C00091C7C9B0D>I<
+0FC00001C00001C0000380000380000380000380000700000700000700000700000E0F000E1100
+0E23800E43801C83001C80001D00001E00003F800039C00038E00038E00070E20070E20070E200
+70E400E06400603800111D7D9C13>107 D<1F800380038007000700070007000E000E000E000E
+001C001C001C001C0038003800380038007000700070007000E400E400E400E40068003800091D
+7C9C0B>I<3C1E0780266318C04683A0E04703C0E08E0380E08E0380E00E0380E00E0380E01C07
+01C01C0701C01C0701C01C070380380E0388380E0388380E0708380E0710701C0320300C01C01D
+127C9122>I<3C3C002646004687004707008E07008E07000E07000E07001C0E001C0E001C0E00
+1C1C00381C40381C40383840383880701900300E0012127C9117>I<01E007180C0C180C380C30
+0E700E700EE01CE01CE01CE018E038E030E06060C031801E000F127B9115>I<07870004D98008
+E0C008E0C011C0E011C0E001C0E001C0E00381C00381C00381C003818007038007030007070007
+06000E8C000E70000E00000E00001C00001C00001C00001C00003C0000FF8000131A7F9115>I<
+3C3C26C2468747078E068E000E000E001C001C001C001C0038003800380038007000300010127C
+9112>114 D<01F006080C080C1C18181C001F001FC00FF007F0007800386030E030C030806060
+C01F000E127D9111>I<00C001C001C001C00380038003800380FFE00700070007000E000E000E
+000E001C001C001C001C00384038403840388019000E000B1A7D990E>I<1E0300270700470700
+470700870E00870E000E0E000E0E001C1C001C1C001C1C001C1C00383880383880183880183900
+1C5900078E0011127C9116>I<1E01832703874703874703838707018707010E07010E07011C0E
+021C0E021C0E021C0E04180C04181C04181C081C1C100C263007C3C018127C911C>119
+D<070E0019910010E38020E38041C30041C00001C00001C0000380000380000380000380000702
+00670200E70400CB04008B080070F00011127D9113>I<1E03270747074707870E870E0E0E0E0E
+1C1C1C1C1C1C1C1C38383838183818381C7007F00070007000E0E0C0E1C0818047003C00101A7C
+9114>I E /Fi 91 127 df<60F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0600000000060F0F0600419
+779816>33 D<E038F078F078F078F078F078F078F078E038E03860300D0B7C9816>I<00C00001
+C00001C00001C00007F0001FFC003FFE007DCF0071C780E1C380E1C780E1C780F1C30079C0003F
+C0001FF00007FC0001FE0001CF0001C70061C380F1C380F1C380E1C38071C70079DF003FFE001F
+F80007E00001C00001C00000C00011207E9C16>36 D<03800007E0000FE0001E70001C70001C70
+001C70001C77E01CE7E01DE7E00FC7000F8E000F0E001E0E003F1C007F1C00739C00E3F800E1F8
+00E0F1C0E0F1C071F9C07FFFC03F9F801E070013197F9816>38 D<30787C3C1C1C1C1C3878F0E0
+40060D789816>I<00E001E0038007000E001C001C0038003800700070007000E000E000E000E0
+00E000E000E000E000E000700070007000380038001C001C000E000700038001E000E00B217A9C
+16>I<C000E000700038001C000E000E000700070003800380038001C001C001C001C001C001C0
+01C001C001C0038003800380070007000E000E001C0038007000E000C0000A217B9C16>I<01C0
+0001C00001C00001C00071C700F9CF807FFF001FFC0007F00007F0001FFC007FFF00F9CF8071C7
+0001C00001C00001C00001C00011127E9516>I<01C00001C00001C00001C00001C00001C00001
+C00001C000FFFF80FFFF80FFFF8001C00001C00001C00001C00001C00001C00001C00001C00011
+137E9516>I<387C7E7E3E0E1E1C78F060070B798416>I<FFFF80FFFF80FFFF8011037E8D16>I<
+70F8F8F8700505788416>I<000180000380000380000700000700000E00000E00001C00001C00
+00380000380000700000700000E00000E00001C00001C0000380000380000700000700000E0000
+0E00001C00001C0000380000380000700000700000E00000E00000C0000011207E9C16>I<03E0
+000FF8001FFC001E3C00380E00780F00700700700700E00380E00380E00380E00380E00380E003
+80E00380E00380F00780700700700700780F003C1E001E3C001FFC000FF80003E00011197E9816
+>I<01800380038007800F807F80FF807380038003800380038003800380038003800380038003
+800380038003807FF87FFC7FF80E197C9816>I<07E0001FF8003FFC00783E00E00700F00780F0
+0380600380000380000380000700000700000E00001C0000380000700000E00001C0000380000F
+00001E03803803807FFF80FFFF807FFF8011197E9816>I<07E0001FF8003FFC00781E00780700
+300700000700000700000E00003E0007FC0007F00007FC00001E00000700000300000380000380
+600380F00380E00700781E003FFC001FF80007E00011197E9816>I<007C0000FC0000DC0001DC
+00039C00039C00071C000F1C000E1C001E1C003C1C00381C00781C00F01C00FFFFE0FFFFE0FFFF
+E0001C00001C00001C00001C00001C0001FFC001FFC001FFC013197F9816>I<3FFE003FFE003F
+FE003800003800003800003800003800003800003800003BF0003FFC003FFE003C0F0030070000
+0380000380600380F00380F00380E00700781E003FFC001FF80007E00011197E9816>I<00F800
+03FC0007FE000F07001C0F00380F00780600700000700000E3F800EFFC00FFFE00F80F00F00700
+F00380E00380E003807003807003807007803807003C1E001FFC000FF80003E00011197E9816>
+I<E00000FFFF80FFFF80FFFF80E00F00E01E00001C0000380000780000700000E00000E00001C0
+0001C00001C0000380000380000380000380000700000700000700000700000700000700000700
+00111A7E9916>I<07F0001FFC003FFE007C1F00F00780E00380E00380E003807007007C1F001F
+FC0007F0001FFC003C1E00700700F00780E00380E00380E00380F007807007007C1F003FFE001F
+FC0007F00011197E9816>I<03E0000FF8001FFC003C1E00700E00700700E00700E00780E00380
+E00380E00780700780780F803FFF801FFB800FE380000700000700300700780E00781C00707800
+3FF0001FE0000F800011197E9816>I<70F8F8F870000000000000000070F8F8F8700512789116>
+I<387C7C7C38000000000000000038787C7C3C1C1C3870E0400618799116>I<00018000078000
+1F80003E0000F80001F00007C0000F80003E0000FC0000F00000FC00003E00000F800007C00001
+F00000F800003E00001F8000078000018011157E9616>I<7FFF00FFFF80FFFF80000000000000
+000000000000000000FFFF80FFFF807FFF00110B7E9116>I<C00000F00000FC00003E00000F80
+0007C00001F00000F800003E00001F80000780001F80003E0000F80001F00007C0000F80003E00
+00FC0000F00000C0000011157E9616>I<0FE03FF87FFCF01EF00EF00E601E003C007800F001C0
+038003800380038003800300000000000000000003000780078003000F197D9816>I<00F80003
+FC0007FE000F07001C3F80387F8078FF8071C3C071C3C0E381C0E381C0E381C0E381C0E381C0E3
+81C0E381C071C38071C38078FF00387E001C3C000F03C007FFC003FF0000FC0012197E9816>I<
+00E00001F00001F00001B00001B00003B80003B80003B800031800071C00071C00071C00071C00
+071C000E0E000E0E000FFE000FFE001FFF001C07001C07001C07007F1FC0FF1FE07F1FC013197F
+9816>I<7FF800FFFE007FFF001C0F001C07801C03801C03801C03801C07801C07001FFF001FFE
+001FFE001C1F001C03801C03C01C01C01C01C01C01C01C01C01C03C01C07807FFF80FFFF007FFC
+0012197F9816>I<01F18007FB800FFF801F0F803C0780380380700380700380F00000E00000E0
+0000E00000E00000E00000E00000E00000F000007003807003803803803C07001F0F000FFE0007
+FC0001F00011197E9816>I<7FF800FFFE007FFF001C0F001C07801C03C01C01C01C01C01C01E0
+1C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C01C01C01C01C03C01C07801C0F80
+7FFF00FFFE007FF8001319809816>I<7FFFC0FFFFC07FFFC01C01C01C01C01C01C01C01C01C00
+001C00001C1C001C1C001FFC001FFC001FFC001C1C001C1C001C00001C00E01C00E01C00E01C00
+E01C00E07FFFE0FFFFE07FFFE013197F9816>I<FFFFE0FFFFE0FFFFE01C00E01C00E01C00E01C
+00E01C00001C00001C1C001C1C001FFC001FFC001FFC001C1C001C1C001C00001C00001C00001C
+00001C00001C0000FF8000FFC000FF800013197F9816>I<03E30007FF000FFF001E1F003C0F00
+380700700700700700F00000E00000E00000E00000E00000E03F80E07FC0E03F80F00700700700
+700700380F003C0F001E1F000FFF0007F70003E70012197E9816>I<7F1FC0FFBFE07F1FC01C07
+001C07001C07001C07001C07001C07001C07001FFF001FFF001FFF001C07001C07001C07001C07
+001C07001C07001C07001C07001C07007F1FC0FFBFE07F1FC013197F9816>I<FFFEFFFEFFFE03
+80038003800380038003800380038003800380038003800380038003800380038003800380FFFE
+FFFEFFFE0F197D9816>I<07FE07FF07FE00380038003800380038003800380038003800380038
+003800380038003800386038F038F0707FF07FE01F8010197D9816>I<7F0FE0FF8FF07F0FE01C
+07801C0F001C0E001C1C001C3C001C78001CF0001CE0001DF0001FF0001FF8001F38001E1C001C
+1C001C0E001C0E001C07001C07001C03807F07E0FF8FF07F07E01419809816>I<FFC000FFC000
+FFC0001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C0000
+1C00001C00001C00401C00E01C00E01C00E01C00E0FFFFE0FFFFE0FFFFE013197F9816>I<FC07
+E0FE0FE0FE0FE03A0B803B1B803B1B803B1B803B1B803B1B803BBB8039B38039B38039B38039B3
+8039F38038E38038E380380380380380380380380380380380FE0FE0FE0FE0FE0FE013197F9816
+>I<7E1FC0FF3FE07F1FC01D07001D87001D87001D87001DC7001DC7001CC7001CC7001CE7001C
+E7001CE7001C67001C67001C77001C77001C37001C37001C37001C17007F1F00FF9F007F0F0013
+197F9816>I<1FFC003FFE007FFF00780F00F00780E00380E00380E00380E00380E00380E00380
+E00380E00380E00380E00380E00380E00380E00380E00380F00780F00780780F007FFF003FFE00
+1FFC0011197E9816>I<7FF800FFFE007FFF001C0F801C03801C03C01C01C01C01C01C01C01C03
+C01C03801C0F801FFF001FFE001FF8001C00001C00001C00001C00001C00001C00001C00007F00
+00FF80007F000012197F9816>I<1FFC003FFE007FFF00780F00F00780E00380E00380E00380E0
+0380E00380E00380E00380E00380E00380E00380E00380E00380E00380E0E380E1E380F0F78078
+7F007FFF003FFE001FFC00001C00001E00000E00000F00000700000700111F7E9816>I<7FE000
+FFF8007FFC001C1E001C0F001C07001C07001C07001C07001C0F001C1E001FFC001FF8001FFC00
+1C1C001C0E001C0E001C0E001C0E001C0E201C0E701C0E707F07E0FF87E07F03C014197F9816>
+I<07E3001FFF003FFF00781F00F00700E00700E00700E00000F000007800003F80001FF00007FC
+0000FE00000F00000700000380000380600380E00380E00700F80F00FFFE00FFFC00C7F0001119
+7E9816>I<7FFFE0FFFFE0FFFFE0E0E0E0E0E0E0E0E0E0E0E0E000E00000E00000E00000E00000
+E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00007FC000FFE0007
+FC0013197F9816>I<7F07F0FF8FF87F07F01C01C01C01C01C01C01C01C01C01C01C01C01C01C0
+1C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C00E03800E038007070007FF00
+03FE0000F8001519809816>I<FE0FE0FF1FE0FE0FE03803801C07001C07001C07001C07000E0E
+000E0E000E0E000E0E00060C00071C00071C00071C00071C0003180003B80003B80003B80001B0
+0001F00001F00000E00013197F9816>I<FC07E0FE0FE0FC07E07001C07001C07001C030018038
+038038038038038038E38039F38039F38039B38019B30019B30019B30019B30019B30019B30019
+13001B1B000F1E000F1E000E0E0013197F9816>I<7F1F807F3F807F1F800E1E000E1C00073C00
+07380003B80003F00001F00001E00000E00001E00001F00003F00003B80007B800071C00071C00
+0E0E000E0E001C07007F1FC0FF1FE07F1FC013197F9816>I<FE0FE0FF1FE0FE0FE01C07001C07
+000E0E000E0E00071C00071C00071C0003B80003B80001F00001F00000E00000E00000E00000E0
+0000E00000E00000E00000E00003F80007FC0003F80013197F9816>I<7FFF80FFFF80FFFF80E0
+0700E00F00E01E00E01C00003C0000780000700000F00001E00001C00003C0000780000700000F
+00001E03801C03803C0380780380700380FFFF80FFFF80FFFF8011197E9816>I<FFF0FFF0FFF0
+E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E0
+00E000E000E000E000E000E000FFF0FFF0FFF00C20789C16>I<C00000E00000E0000070000070
+00003800003800001C00001C00000E00000E000007000007000003800003800001C00001C00000
+E00000E000007000007000003800003800001C00001C00000E00000E0000070000070000038000
+038000018011207E9C16>I<FFF0FFF0FFF0007000700070007000700070007000700070007000
+70007000700070007000700070007000700070007000700070007000700070FFF0FFF0FFF00C20
+7F9C16>I<03000F803FE0FDF8F07840100D067C9816>I<FFFF80FFFF80FFFF8011037E7E16>I<
+081C3C7870E0E0E0E0F0F87830060D789B16>I<1FE0003FF0007FF800783C00300E00000E0000
+0E0003FE001FFE003E0E00700E00E00E00E00E00E00E00783E007FFFE03FE7E00F83E013127E91
+16>I<7E0000FE00007E00000E00000E00000E00000E00000E3E000EFF000FFF800F83C00F00E0
+0E00E00E00700E00700E00700E00700E00700E00700E00E00F01E00F83C00FFF800EFF00063C00
+1419809816>I<03F80FFC1FFE3C1E780C7000E000E000E000E000E000F000700778073E0E1FFC
+0FF803F010127D9116>I<003F00007F00003F0000070000070000070000070003C7000FF7001F
+FF003C1F00780F00700700E00700E00700E00700E00700E00700E00700700F00700F003C1F001F
+FFE00FE7F007C7E014197F9816>I<03E00FF81FFC3C1E780E7007E007FFFFFFFFFFFFE000E000
+700778073C0F1FFE0FFC03F010127D9116>I<001F00007F8000FF8001E78001C30001C00001C0
+007FFF00FFFF00FFFF0001C00001C00001C00001C00001C00001C00001C00001C00001C00001C0
+0001C00001C0003FFE007FFF003FFE0011197F9816>I<03E3C007F7E00FFFE01C1CC0380E0038
+0E00380E00380E00380E001C1C000FF8001FF0001BE0003800001800001FFC001FFF003FFF8078
+03C0E000E0E000E0E000E0E000E07001C07C07C03FFF800FFE0003F800131C7F9116>I<7E0000
+FE00007E00000E00000E00000E00000E00000E3C000EFE000FFF000F87800F03800E03800E0380
+0E03800E03800E03800E03800E03800E03800E03800E03807FC7F0FFE7F87FC7F01519809816>
+I<018003C003C0018000000000000000007FC07FC07FC001C001C001C001C001C001C001C001C0
+01C001C001C001C07FFFFFFF7FFF101A7D9916>I<003000780078003000000000000000001FF8
+1FF81FF80038003800380038003800380038003800380038003800380038003800380038003800
+3800386070F0F0FFE07FC03F800D237E9916>I<7E0000FE00007E00000E00000E00000E00000E
+00000E7FE00E7FE00E7FE00E0F000E1E000E3C000E78000EF0000FF0000FF8000FBC000F1E000E
+0E000E07000E07807F87F0FFCFF07F87F01419809816>I<FFC000FFC000FFC00001C00001C000
+01C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C000
+01C00001C00001C00001C000FFFF80FFFF80FFFF8011197E9816>I<F9C380FFEFC0FFFFE03C78
+E03C78E03870E03870E03870E03870E03870E03870E03870E03870E03870E03870E0FE7CF8FE7C
+F8FE3C781512809116>I<7E3C00FEFE007FFF000F87800F03800E03800E03800E03800E03800E
+03800E03800E03800E03800E03800E03807FC7F0FFE7F87FC7F01512809116>I<03E0000FF800
+1FFC003C1E00780F00700700E00380E00380E00380E00380E00380F00780700700780F003C1E00
+1FFC000FF80003E00011127E9116>I<7E3E00FEFF007FFF800F83C00F00E00E00E00E00700E00
+700E00700E00700E00700E00700E00E00F01E00F83C00FFF800EFF000E3C000E00000E00000E00
+000E00000E00000E00007FC000FFE0007FC000141B809116>I<07C7000FE7001FF7003C1F0070
+0F00700F00E00700E00700E00700E00700E00700E00700700F00700F003C3F003FF7001FE70007
+C700000700000700000700000700000700000700003FE0007FF0003FE0141B7E9116>I<FF0FC0
+FF3FE0FF7FE007F04007C000078000078000070000070000070000070000070000070000070000
+070000FFFC00FFFC00FFFC0013127F9116>I<0FEC3FFC7FFCF03CE01CE01C70007F801FF007F8
+003C600EE00EF00EF81EFFFCFFF8C7E00F127D9116>I<0300000700000700000700000700007F
+FF00FFFF00FFFF0007000007000007000007000007000007000007000007010007038007038007
+038007870003FE0001FC0000F80011177F9616>I<7E1F80FE3F807E1F800E03800E03800E0380
+0E03800E03800E03800E03800E03800E03800E03800E03800E0F800FFFF007FBF803E3F0151280
+9116>I<7F1FC0FF1FE07F1FC01C07001E0F000E0E000E0E000E0E00071C00071C00071C00071C
+0003B80003B80003B80001F00001F00000E00013127F9116>I<FF1FE0FFBFE0FF1FE038038038
+038038038038038038E38019F30019F30019B3001DB7001DB7001DB7001DB7000F1E000F1E000F
+1E0013127F9116>I<7F1FC07F3FC07F1FC00F1C00073C0003B80003F00001F00000E00001E000
+01F00003B800073C00071C000E0E007F1FC0FF3FE07F1FC013127F9116>I<7F1FC0FF9FE07F1F
+C01C07000E07000E0E000E0E00070E00071C00071C00039C00039C0003980001B80001B80000F0
+0000F00000F00000E00000E00000E00001C00079C0007BC0007F80003F00003C0000131B7F9116
+>I<001F80007F8000FF8001E00001C00001C00001C00001C00001C00001C00001C00001C00001
+C00003C0007F8000FF0000FF00007F800003C00001C00001C00001C00001C00001C00001C00001
+C00001C00001C00001E00000FF80007F80001F8011207E9C16>123 D<E0E0E0E0E0E0E0E0E0E0
+E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E00320779C16>I<7C0000FF0000FF800003
+C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001E00000FF00007F8000
+7F8000FF0001E00001C00001C00001C00001C00001C00001C00001C00001C00001C00003C000FF
+8000FF00007C000011207E9C16>I<1C303F78FFF8F7E061C00D057C9816>I
+E /Fj 8 111 df<60F0F06004047C830C>58 D<0000038000000F0000003C000000F0000003C0
+00000F0000003C000000F0000003C000000F0000003C000000F0000000F00000003C0000000F00
+000003C0000000F00000003C0000000F00000003C0000000F00000003C0000000F000000038019
+187D9520>60 D<E0000000780000001E0000000780000001E0000000780000001E000000078000
+0001E0000000780000001E00000007800000078000001E00000078000001E00000078000001E00
+000078000001E00000078000001E00000078000000E000000019187D9520>62
+D<00000C0000000C0000001C0000001C0000003C0000007C0000005C0000009C0000008E000001
+0E0000010E0000020E0000040E0000040E0000080E0000080E0000100E0000200E00003FFE0000
+400700004007000080070001000700010007000200070002000700060007001E000700FF807FF0
+1C1D7F9C1F>65 D<01FFFF00003C01C0003800E0003800F0003800700038007000700070007000
+F0007000F0007001E000E003C000E0078000E01F0000FFFC0001C00F0001C0078001C003C001C0
+03C0038003C0038003C0038003C0038003C0070007800700070007000E0007001C000E007800FF
+FFC0001C1C7E9B1F>I<01FFC0FF80001E003C00001E003000000E002000000F00400000070080
+000007010000000782000000038400000003C800000001D000000001F000000000E000000000E0
+00000000F00000000170000000027000000004380000000838000000103C000000201C00000040
+1E000000800E000001800E000003000F000006000700001E000F8000FF803FF000211C7F9B22>
+88 D<FFE007F80F0001E00F0001800700010007000200078004000380080003C0100001C03000
+01C0200001E0400000E0800000F100000072000000760000007C00000038000000380000007000
+0000700000007000000070000000E0000000E0000000E0000000E0000001C000001FFC00001D1C
+7F9B18>I<381F004E61804681C04701C08F01C08E01C00E01C00E01C01C03801C03801C03801C
+0700380710380710380E10380E2070064030038014127E9119>110 D E
+/Fk 71 123 df<003FE3F801F03F1C03C03E3E07C07C3E0F807C3E0F807C1C0F807C000F807C00
+0F807C000F807C000F807C00FFFFFFC0FFFFFFC00F807C000F807C000F807C000F807C000F807C
+000F807C000F807C000F807C000F807C000F807C000F807C000F807C000F807C000F807C007FE1
+FFC07FE1FFC01F1D809C1C>11 D<003FC00001F0300003C0380007C07C000F807C000F807C000F
+8038000F8000000F8000000F8000000F800000FFFFFC00FFFFFC000F807C000F807C000F807C00
+0F807C000F807C000F807C000F807C000F807C000F807C000F807C000F807C000F807C000F807C
+000F807C007FE1FF807FE1FF80191D809C1B>I<003FC1FE0001F03F818003C03E01C007C07E03
+E00F807C03E00F807C03E00F807C01C00F807C00000F807C00000F807C00000F807C0000FFFFFF
+FFE0FFFFFFFFE00F807C03E00F807C03E00F807C03E00F807C03E00F807C03E00F807C03E00F80
+7C03E00F807C03E00F807C03E00F807C03E00F807C03E00F807C03E00F807C03E00F807C03E07F
+E1FF0FFC7FE1FF0FFC261D809C28>14 D<00038000000380000003800000038000000380000003
+80000003800000038000000380000003800000038000000380000003800000038000FFFFFFFCFF
+FFFFFCFFFFFFFC0003800000038000000380000003800000038000000380000003800000038000
+0003800000038000000380000003800000038000000380001E1F7D9925>43
+D<78FCFCFEFE7A0202040408083040070E7D850D>I<FFE0FFE0FFE0FFE00B047F8A10>I<78FCFC
+FCFC7806067D850D>I<03F8000F1E001C07003C07803803807803C07803C07803C0F803E0F803
+E0F803E0F803E0F803E0F803E0F803E0F803E0F803E0F803E0F803E0F803E07803C07803C03803
+803C07801C07000F1E0003F800131B7E9A18>48 D<00600001E0000FE000FFE000F3E00003E000
+03E00003E00003E00003E00003E00003E00003E00003E00003E00003E00003E00003E00003E000
+03E00003E00003E00003E00003E00003E0007FFF807FFF80111B7D9A18>I<07F8001FFE00383F
+80780FC0FC07C0FC07E0FC03E0FC03E07803E00007E00007C00007C0000F80001F00001E000038
+0000700000E0000180600300600600600800E01FFFC03FFFC07FFFC0FFFFC0FFFFC0131B7E9A18
+>I<03F8001FFE003C1F003C0F807C07C07E07C07C07C03807C0000F80000F80001E00003C0003
+F800001E00000F800007C00007C00007E03007E07807E0FC07E0FC07E0FC07C0780F80781F001F
+FE0007F800131B7E9A18>I<000180000380000780000F80001F80003F80006F8000CF80008F80
+018F80030F80060F800C0F80180F80300F80600F80C00F80FFFFF8FFFFF8000F80000F80000F80
+000F80000F80000F8001FFF801FFF8151B7F9A18>I<1801801FFF001FFE001FFC001FF8001FC0
+0018000018000018000018000019F8001E0E00180F801007800007C00007E00007E00007E07807
+E0F807E0F807E0F807C0F007C0600F80381F001FFE0007F000131B7E9A18>I<007E0003FF0007
+81800F03C01E07C03C07C03C0380780000780000F80000F8F800FB0E00FA0780FC0380FC03C0F8
+03E0F803E0F803E0F803E07803E07803E07803C03C03C03C07801E0F0007FE0003F800131B7E9A
+18>I<6000007FFFE07FFFE07FFFC07FFF807FFF80E00300C00600C00C00C01800003000003000
+00600000E00000E00001E00001C00003C00003C00003C00003C00007C00007C00007C00007C000
+07C00007C000038000131C7D9B18>I<03F8000FFE001E0F803807803803C07803C07803C07E03
+C07F83807FC7003FFE001FFC000FFE0007FF801DFF80387FC0781FE0F007E0F003E0F001E0F001
+E0F001E07801C07803803E07801FFE0003F800131B7E9A18>I<03F8000FFE001E0F003C078078
+07807803C0F803C0F803C0F803E0F803E0F803E0F803E07807E03807E03C0BE00E1BE003E3E000
+03E00003C00003C03807C07C07807C0700780F00383C001FF8000FE000131B7E9A18>I<78FCFC
+FCFC7800000000000078FCFCFCFC7806127D910D>I<0FF0303C601EF01FF81FF81F701F003E00
+3C007000E001C00180018003000300030003000300000000000000000007800FC00FC00FC00FC0
+0780101D7D9C17>63 D<001FE00000E01C0003000300060001800C0000C018000060300FC03020
+38601060F0101860F01F18C1E01F0CC1E01F0CC3E01F0CC3E01F0CC3E01F0CC3E01F0CC3E01F0C
+C1E01F0CC1E01F0C60F01F0860F01F1820386F10300FC7E0180000000C00000006000000030000
+3C00E007F0001FFC001E1D7D9C25>I<00038000000380000007C0000007C0000007C000000FE0
+00000FE000001FF000001BF000001BF0000031F8000031F8000061FC000060FC0000E0FE0000C0
+7E0000C07E0001803F0001FFFF0003FFFF8003001F8003001F8006000FC006000FC00E000FE00C
+0007E0FFC07FFEFFC07FFE1F1C7E9B24>I<FFFFF800FFFFFF000FC01F800FC00FC00FC007C00F
+C007E00FC007E00FC007E00FC007E00FC007E00FC007C00FC00F800FC03F000FFFFE000FC00F80
+0FC007C00FC007E00FC003E00FC003F00FC003F00FC003F00FC003F00FC003F00FC007E00FC007
+E00FC01FC0FFFFFF00FFFFFC001C1C7E9B22>I<001FE02000FFF8E003F80FE007C003E00F8001
+E01F0000E03E0000E03E0000607E0000607C000060FC000000FC000000FC000000FC000000FC00
+0000FC000000FC000000FC0000007C0000607E0000603E0000603E0000C01F0000C00F80018007
+C0030003F80E0000FFFC00001FE0001B1C7D9B22>I<FFFFF800FFFFFF000FC01FC00FC007E00F
+C001F00FC001F80FC000F80FC000FC0FC0007C0FC0007C0FC0007E0FC0007E0FC0007E0FC0007E
+0FC0007E0FC0007E0FC0007E0FC0007E0FC0007C0FC0007C0FC0007C0FC000F80FC000F80FC001
+F00FC007E00FC01FC0FFFFFF00FFFFF8001F1C7E9B25>I<FFFFFF00FFFFFF000FC01F000FC007
+000FC003000FC003800FC003800FC181800FC181800FC181800FC180000FC380000FFF80000FFF
+80000FC380000FC180000FC180000FC180600FC180600FC000E00FC000C00FC000C00FC001C00F
+C001C00FC003C00FC00F80FFFFFF80FFFFFF801B1C7E9B1F>I<FFFFFF00FFFFFF000FC01F000F
+C007000FC003000FC003800FC003800FC001800FC181800FC181800FC180000FC180000FC38000
+0FFF80000FFF80000FC380000FC180000FC180000FC180000FC180000FC000000FC000000FC000
+000FC000000FC000000FC00000FFFF0000FFFF0000191C7E9B1E>I<000FF008007FFE3801FC07
+F807E001F80F8000781F0000783F0000383E0000387E0000187C000018FC000000FC000000FC00
+0000FC000000FC000000FC000000FC007FFFFC007FFF7C0001F87E0001F83E0001F83F0001F81F
+0001F80F8001F807E001F801FC07F8007FFE78000FF818201C7D9B26>I<FFFC3FFFFFFC3FFF0F
+C003F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F0
+0FFFFFF00FFFFFF00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003
+F00FC003F00FC003F00FC003F00FC003F0FFFC3FFFFFFC3FFF201C7E9B25>I<FFFFFFFF07E007
+E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E0
+07E007E007E0FFFFFFFF101C7F9B12>I<07FFF007FFF0001F80001F80001F80001F80001F8000
+1F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001F8030
+1F80781F80FC1F80FC1F80FC1F00783E00387C000FF000141C7F9B19>I<FFFC07FFFFFC07FF0F
+C000E00FC001C00FC003800FC006000FC00C000FC038000FC070000FC0E0000FC1C0000FC3C000
+0FC7E0000FCFE0000FFBF0000FF3F8000FE1F8000FC0FC000FC0FE000FC07E000FC03F000FC01F
+800FC01FC00FC00FC00FC007E00FC007F0FFFC3FFFFFFC3FFF201C7E9B25>I<FFFF00FFFF000F
+C0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000F
+C0000FC0000FC0030FC0030FC0030FC0070FC0070FC0060FC00E0FC01E0FC07EFFFFFEFFFFFE18
+1C7E9B1D>I<FFC00003FFFFE00007FF0FE00007F00DF0000DF00DF0000DF00DF0000DF00CF800
+19F00CF80019F00C7C0031F00C7C0031F00C3E0061F00C3E0061F00C1F00C1F00C1F00C1F00C1F
+00C1F00C0F8181F00C0F8181F00C07C301F00C07C301F00C03E601F00C03E601F00C01FC01F00C
+01FC01F00C01FC01F00C00F801F00C00F801F0FFC0701FFFFFC0701FFF281C7E9B2D>I<FFE003
+FFFFE003FF0FF000300FF800300DFC00300CFE00300C7E00300C3F00300C1F80300C1FC0300C0F
+E0300C07F0300C03F0300C01F8300C01FC300C00FE300C007F300C003F300C001FB00C001FF00C
+000FF00C0007F00C0003F00C0001F00C0000F00C0000F0FFC00070FFC00030201C7E9B25>I<00
+3FE00001F07C0003C01E000F800F801F0007C01E0003C03E0003E07E0003F07C0001F07C0001F0
+FC0001F8FC0001F8FC0001F8FC0001F8FC0001F8FC0001F8FC0001F8FC0001F87C0001F07E0003
+F07E0003F03E0003E03F0007E01F0007C00F800F8003C01E0001F07C00003FE0001D1C7D9B24>
+I<FFFFF800FFFFFE000FC03F800FC00F800FC007C00FC007E00FC007E00FC007E00FC007E00FC0
+07E00FC007C00FC007C00FC00F800FC03F000FFFFC000FC000000FC000000FC000000FC000000F
+C000000FC000000FC000000FC000000FC000000FC000000FC00000FFFC0000FFFC00001B1C7E9B
+21>I<FFFFF00000FFFFFE00000FC03F00000FC00F80000FC007C0000FC007E0000FC007E0000F
+C007E0000FC007E0000FC007E0000FC007C0000FC00F80000FC03E00000FFFF000000FC07C0000
+0FC03E00000FC03F00000FC01F80000FC01F80000FC01F80000FC01F80000FC01F80000FC01F80
+000FC01F81800FC01F81800FC00FC180FFFC07C300FFFC01FE00211C7E9B24>82
+D<07F8201FFEE03C07E07801E07000E0F000E0F00060F00060F80000FE0000FFE0007FFE003FFF
+003FFF800FFFC007FFE0007FE00003F00001F00000F0C000F0C000F0C000E0E000E0F001C0FC03
+C0EFFF0083FC00141C7D9B1B>I<7FFFFFE07FFFFFE0781F81E0701F80E0601F8060E01F8070C0
+1F8030C01F8030C01F8030C01F8030001F8000001F8000001F8000001F8000001F8000001F8000
+001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F80
+0007FFFE0007FFFE001C1C7E9B21>I<FFFC03FFFFFC03FF0FC000300FC000300FC000300FC000
+300FC000300FC000300FC000300FC000300FC000300FC000300FC000300FC000300FC000300FC0
+00300FC000300FC000300FC000300FC000300FC0003007C0003007C0006003E000E001F001C000
+FC0780007FFE00000FF800201C7E9B25>I<FFFC01FF80FFFC01FF800FC000180007E000300007
+E000300007F000700003F000600003F800E00001F800C00001FC00C00000FC01800000FC018000
+007E030000007E030000007F070000003F060000003F8E0000001F8C0000001FCC0000000FD800
+00000FD800000007F000000007F000000007F000000003E000000003E000000001C000000001C0
+0000211C7F9B24>I<FFFC7FFE0FFCFFFC7FFE0FFC0FC007E000C00FC007F000C00FE003F001C0
+07E003F0018007E007F8018003F007F8030003F007F8030003F80CFC070001F80CFC060001F81C
+FE060001FC187E0E0000FC187E0C0000FC387F0C00007E303F1800007E303F1800007F601FB800
+003F601FB000003FE01FF000003FC00FF000001FC00FE000001FC00FE000000F8007C000000F80
+07C000000F0003C0000007000380000007000380002E1C7F9B31>I<7FFE1FFE007FFE1FFE0007
+F001800003F803800001FC07000000FC06000000FE0C0000007F1C0000003F380000003FB00000
+001FE00000000FE00000000FE000000007F000000003F800000007F80000000FFC0000000CFE00
+0000187E000000387F000000703F800000601F800000C01FC00001C00FE000018007F000030007
+F000FFF03FFF80FFF03FFF80211C7F9B24>I<FEFEFEE0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0
+E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0FEFEFE07297C9E0D>91 D<FEFEFE0E0E0E0E0E0E0E
+0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0EFEFEFE07297F9E0D>93
+D<0FF8001C1E003E0F803E07803E07C01C07C00007C0007FC007E7C01F07C03C07C07C07C0F807
+C0F807C0F807C0780BC03E13F80FE1F815127F9117>97 D<FF0000FF00001F00001F00001F0000
+1F00001F00001F00001F00001F00001F00001F3F801FE1E01F80701F00781F003C1F003C1F003E
+1F003E1F003E1F003E1F003E1F003E1F003C1F003C1F00781F80701EC1E01C3F00171D7F9C1B>
+I<03FC000E0E001C1F003C1F00781F00780E00F80000F80000F80000F80000F80000F800007800
+007801803C01801C03000E0E0003F80011127E9115>I<000FF0000FF00001F00001F00001F000
+01F00001F00001F00001F00001F00001F001F9F00F07F01C03F03C01F07801F07801F0F801F0F8
+01F0F801F0F801F0F801F0F801F07801F07801F03C01F01C03F00F0FFE03F9FE171D7E9C1B>I<
+01FC000F07001C03803C01C07801C07801E0F801E0F801E0FFFFE0F80000F80000F80000780000
+7C00603C00601E00C00F038001FC0013127F9116>I<007F0001E38003C7C00787C00F87C00F83
+800F80000F80000F80000F80000F8000FFF800FFF8000F80000F80000F80000F80000F80000F80
+000F80000F80000F80000F80000F80000F80000F80000F80007FF8007FF800121D809C0F>I<03
+F8F00E0F381E0F381C07303C07803C07803C07803C07801C07001E0F000E0E001BF80010000018
+00001800001FFF001FFFC00FFFE01FFFF07801F8F00078F00078F000787000707800F01E03C007
+FF00151B7F9118>I<FF0000FF00001F00001F00001F00001F00001F00001F00001F00001F0000
+1F00001F0FC01F31E01F40F01F80F81F80F81F00F81F00F81F00F81F00F81F00F81F00F81F00F8
+1F00F81F00F81F00F81F00F8FFE7FFFFE7FF181D7F9C1B>I<1E003F003F003F003F001E000000
+00000000000000000000FF00FF001F001F001F001F001F001F001F001F001F001F001F001F001F
+001F00FFE0FFE00B1E7F9D0E>I<007800FC00FC00FC00FC007800000000000000000000000003
+FC03FC007C007C007C007C007C007C007C007C007C007C007C007C007C007C007C007C007C007C
+707CF87CF878F8F070E01F800E26839D0F>I<FF0000FF00001F00001F00001F00001F00001F00
+001F00001F00001F00001F00001F0FF81F0FF81F03801F07001F0C001F18001F70001FF8001FFC
+001FBC001F3E001F1F001F0F001F0F801F07C01F03E0FFC7FCFFC7FC161D7F9C19>I<FF00FF00
+1F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F
+001F001F001F001F001F00FFE0FFE00B1D7F9C0E>I<FF0FC07E00FF31E18F001F40F207801F80
+FC07C01F80FC07C01F00F807C01F00F807C01F00F807C01F00F807C01F00F807C01F00F807C01F
+00F807C01F00F807C01F00F807C01F00F807C01F00F807C0FFE7FF3FF8FFE7FF3FF825127F9128
+>I<FF0FC0FF31E01F40F01F80F81F80F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F
+00F81F00F81F00F81F00F8FFE7FFFFE7FF18127F911B>I<01FC000F07801C01C03C01E07800F0
+7800F0F800F8F800F8F800F8F800F8F800F8F800F87800F07800F03C01E01E03C00F078001FC00
+15127F9118>I<FF3F80FFE1E01F80F01F00781F007C1F003C1F003E1F003E1F003E1F003E1F00
+3E1F003E1F003C1F007C1F00781F80F01FC1E01F3F001F00001F00001F00001F00001F00001F00
+00FFE000FFE000171A7F911B>I<03F0600F0CE01E07E03C03E07C03E07803E0F803E0F803E0F8
+03E0F803E0F803E0F803E07803E07C03E03C03E01C07E00E0FE003F3E00003E00003E00003E000
+03E00003E00003E0001FFC001FFC161A7E9119>I<FE3E00FE47001E8F801E8F801E8F801F0700
+1F00001F00001F00001F00001F00001F00001F00001F00001F00001F0000FFF000FFF00011127F
+9114>I<1FD830786018E018E018F000FF807FE07FF01FF807FC007CC01CC01CE01CE018F830CF
+C00E127E9113>I<0300030003000300070007000F000F003FFCFFFC1F001F001F001F001F001F
+001F001F001F001F0C1F0C1F0C1F0C0F08079803F00E1A7F9913>I<FF07F8FF07F81F00F81F00
+F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F01F80F01F80786
+FF01F8FF18127F911B>I<FFC1FCFFC1FC1F00601F80E00F80C00FC0C007C18007C18003E30003
+E30001F60001F60001FE0000FC0000FC0000780000780000300016127F9119>I<FF8FF8FEFF8F
+F8FE1F03E0301F03E0301F83E0700F83F0600F86F06007C6F0C007CEF8C007EC79C003EC7D8003
+F83D8001F83F0001F83F0001F01F0000F01E0000E00E0000E00E001F127F9122>I<FFC7FCFFC7
+FC1F81800F838007C70003EE0001FC0001F80000F800007C0000FE0001DF00039F00070F800607
+C00C03E0FF07FCFF07FC16127F9119>I<FFC1FCFFC1FC1F00601F80E00F80C00FC0C007C18007
+C18003E30003E30001F70001F60000FE0000FC0000FC0000780000780000300000300000700070
+6000F86000F8C000F980007300003E0000161A7F9119>I<3FFF803C1F00303F00303E00607C00
+60FC0060F80001F00003F00007E00007C1800F81801F81801F03803E03007E07007C0F00FFFF00
+11127F9115>I E /Fl 36 121 df<00000007FF800000000001FFFFF0000000000FFFFFFC0000
+00003FFFFFFE00000000FFFC00FF00000001FFC0003F80000007FF00007FC000000FFE0001FFC0
+00001FFC0001FFE000001FF80003FFE000003FF00003FFE000003FF00003FFE000007FE00003FF
+E000007FE00003FFE000007FE00003FFE000007FE00003FFE000007FE00001FFC000007FE00000
+FF8000007FE000003E0000007FE00000000000007FE00000000000007FE00000000000007FE000
+00000000007FE00000000000007FE00000000000007FE0003FFFF000FFFFFFFFFFFFF000FFFFFF
+FFFFFFF000FFFFFFFFFFFFF000FFFFFFFFFFFFF000FFFFFFFFFFFFF000007FF00000FFF000007F
+F000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF00000
+7FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000
+007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF0
+00007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007F
+F000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF00000
+7FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000
+007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF0
+00007FF0003FFFFFE03FFFFFE03FFFFFE03FFFFFE03FFFFFE03FFFFFE03FFFFFE03FFFFFE03FFF
+FFE03FFFFFE03B487EC742>12 D<0000FFE00000000FFFFE0000003FFFFFC00000FFFFFFF00003
+FFFFFFFC0007FC01FFFE000FE0007FFF001FC0001FFF803F80000FFFC03FE00007FFE07FF80007
+FFE07FFC0003FFF0FFFC0003FFF0FFFE0001FFF8FFFE0001FFF8FFFE0001FFF8FFFE0000FFFCFF
+FE0000FFFC7FFC0000FFFC7FFC0000FFFC3FF80000FFFC1FF00000FFFC0FE00000FFFC00000001
+FFFC00000001FFF800000001FFF800000001FFF000000003FFF000000003FFE000000003FFE000
+000007FFC000000007FF800000000FFF800000001FFF000000001FFE000000003FFC000000007F
+F8000000007FE000000000FFC000000001FF8000000003FF0000000007FC000000000FF8000000
+001FF0000000003FC0000000007F80007C0000FF00007C0000FE00007C0001FC00007C0003F000
+00F80007E00000F8000FC00000F8001F800000F8003F000001F8007C000003F800FFFFFFFFF801
+FFFFFFFFF003FFFFFFFFF007FFFFFFFFF00FFFFFFFFFF01FFFFFFFFFF03FFFFFFFFFF07FFFFFFF
+FFF07FFFFFFFFFF0FFFFFFFFFFE0FFFFFFFFFFE0FFFFFFFFFFE0FFFFFFFFFFE02E447AC33B>50
+D<0000000003E000000000000000000007F000000000000000000007F00000000000000000000F
+F80000000000000000000FF80000000000000000000FF80000000000000000001FFC0000000000
+000000001FFC0000000000000000003FFE0000000000000000003FFE0000000000000000007FFF
+0000000000000000007FFF0000000000000000007FFF000000000000000000FFFF800000000000
+000000FFFF800000000000000001FFFFC00000000000000001FFFFC00000000000000001FFFFC0
+0000000000000003FFFFE00000000000000003EFFFE00000000000000007EFFFF0000000000000
+0007CFFFF00000000000000007C7FFF0000000000000000FC7FFF8000000000000000F83FFF800
+0000000000001F83FFFC000000000000001F03FFFC000000000000001F01FFFC00000000000000
+3F01FFFE000000000000003E00FFFE000000000000007E00FFFF000000000000007C007FFF0000
+0000000000FC007FFF80000000000000F8007FFF80000000000000F8003FFF80000000000001F8
+003FFFC0000000000001F0001FFFC0000000000003F0001FFFE0000000000003E0001FFFE00000
+00000003E0000FFFE0000000000007E0000FFFF0000000000007C00007FFF000000000000FC000
+07FFF800000000000F800007FFF800000000000F800003FFF800000000001F800003FFFC000000
+00001F000001FFFC00000000003FFFFFFFFFFE00000000003FFFFFFFFFFE00000000007FFFFFFF
+FFFF00000000007FFFFFFFFFFF00000000007FFFFFFFFFFF0000000000FC0000007FFF80000000
+00F80000003FFF8000000001F80000003FFFC000000001F00000003FFFC000000001F00000001F
+FFC000000003F00000001FFFE000000003E00000000FFFE000000007E00000000FFFF000000007
+C00000000FFFF000000007C000000007FFF00000000FC000000007FFF80000000F8000000003FF
+F80000001F8000000003FFFC0000001F0000000003FFFC0000007FC000000001FFFC0000FFFFFF
+C00007FFFFFFFF80FFFFFFC00007FFFFFFFF80FFFFFFC00007FFFFFFFF80FFFFFFC00007FFFFFF
+FF80FFFFFFC00007FFFFFFFF8051487CC75A>65 D<000000003FFE00000E0000000FFFFFC0001E
+0000007FFFFFF8003E000003FFFFFFFE00FE00000FFFFFFFFF81FE00003FFFF800FFC3FE0000FF
+FF80000FF7FE0001FFFC000003FFFE0007FFF0000001FFFE000FFFC00000007FFE001FFF800000
+003FFE003FFF000000001FFE007FFE000000000FFE00FFFC0000000007FE01FFF80000000007FE
+03FFF00000000003FE03FFF00000000001FE07FFE00000000001FE07FFE00000000000FE0FFFC0
+0000000000FE0FFFC000000000007E1FFFC000000000007E1FFF8000000000007E3FFF80000000
+00007E3FFF8000000000003E3FFF8000000000003E7FFF8000000000003E7FFF0000000000003E
+7FFF000000000000007FFF00000000000000FFFF00000000000000FFFF00000000000000FFFF00
+000000000000FFFF00000000000000FFFF00000000000000FFFF00000000000000FFFF00000000
+000000FFFF00000000000000FFFF00000000000000FFFF00000000000000FFFF00000000000000
+FFFF00000000000000FFFF000000000000007FFF000000000000007FFF000000000000007FFF00
+0000000000007FFF8000000000003E3FFF8000000000003E3FFF8000000000003E3FFF80000000
+00003E1FFF8000000000003E1FFFC000000000003E0FFFC000000000007C0FFFC000000000007C
+07FFE000000000007C07FFE00000000000F803FFF00000000000F803FFF00000000001F801FFF8
+0000000001F000FFFC0000000003E0007FFE0000000007E0003FFF000000000FC0001FFF800000
+001F80000FFFC00000003F000007FFF0000000FE000001FFFC000001FC000000FFFF80000FF800
+00003FFFF8007FF00000000FFFFFFFFFC000000003FFFFFFFF00000000007FFFFFFC0000000000
+0FFFFFE00000000000003FFE000000474979C756>67 D<FFFFFFFFFFFFC0000000FFFFFFFFFFFF
+FE000000FFFFFFFFFFFFFFC00000FFFFFFFFFFFFFFF00000FFFFFFFFFFFFFFFC0000001FFF8000
+07FFFF0000001FFF8000007FFF8000001FFF8000000FFFE000001FFF80000007FFF000001FFF80
+000001FFF800001FFF80000000FFFC00001FFF800000007FFE00001FFF800000003FFF00001FFF
+800000001FFF00001FFF800000000FFF80001FFF800000000FFFC0001FFF8000000007FFC0001F
+FF8000000007FFE0001FFF8000000003FFE0001FFF8000000003FFF0001FFF8000000003FFF000
+1FFF8000000003FFF8001FFF8000000001FFF8001FFF8000000001FFF8001FFF8000000001FFFC
+001FFF8000000001FFFC001FFF8000000001FFFC001FFF8000000001FFFC001FFF8000000001FF
+FC001FFF8000000001FFFE001FFF8000000000FFFE001FFF8000000000FFFE001FFF8000000000
+FFFE001FFF8000000000FFFE001FFF8000000000FFFE001FFF8000000000FFFE001FFF80000000
+00FFFE001FFF8000000000FFFE001FFF8000000000FFFE001FFF8000000000FFFE001FFF800000
+0000FFFE001FFF8000000000FFFE001FFF8000000001FFFE001FFF8000000001FFFC001FFF8000
+000001FFFC001FFF8000000001FFFC001FFF8000000001FFFC001FFF8000000001FFF8001FFF80
+00000001FFF8001FFF8000000001FFF8001FFF8000000003FFF0001FFF8000000003FFF0001FFF
+8000000003FFF0001FFF8000000007FFE0001FFF8000000007FFE0001FFF800000000FFFC0001F
+FF800000000FFF80001FFF800000001FFF80001FFF800000003FFF00001FFF800000003FFE0000
+1FFF800000007FFC00001FFF80000001FFF800001FFF80000003FFF000001FFF8000000FFFE000
+001FFF8000007FFFC000001FFF800003FFFF0000FFFFFFFFFFFFFFFE0000FFFFFFFFFFFFFFF800
+00FFFFFFFFFFFFFFC00000FFFFFFFFFFFFFE000000FFFFFFFFFFFFC00000004F477CC65B>I<FF
+FFFFFFFFFFFFFC00FFFFFFFFFFFFFFFC00FFFFFFFFFFFFFFFC00FFFFFFFFFFFFFFFC00FFFFFFFF
+FFFFFFFE00001FFFC00003FFFE00001FFFC000003FFE00001FFFC000000FFE00001FFFC0000003
+FE00001FFFC0000001FE00001FFFC0000000FE00001FFFC0000000FE00001FFFC00000007E0000
+1FFFC00000007F00001FFFC00000003F00001FFFC00000003F00001FFFC00000001F00001FFFC0
+0000001F00001FFFC00000001F00001FFFC00000001F00001FFFC0007C001F00001FFFC0007C00
+0F80001FFFC0007C000F80001FFFC0007C000F80001FFFC0007C000F80001FFFC0007C00000000
+1FFFC000FC000000001FFFC000FC000000001FFFC000FC000000001FFFC001FC000000001FFFC0
+03FC000000001FFFC01FFC000000001FFFFFFFFC000000001FFFFFFFFC000000001FFFFFFFFC00
+0000001FFFFFFFFC000000001FFFFFFFFC000000001FFFC01FFC000000001FFFC003FC00000000
+1FFFC001FC000000001FFFC000FC000000001FFFC000FC000000001FFFC000FC000000001FFFC0
+007C000000001FFFC0007C000000001FFFC0007C000000001FFFC0007C000000001FFFC0007C00
+0000001FFFC0007C000000001FFFC00000000000001FFFC00000000000001FFFC0000000000000
+1FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC0
+0000000000001FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC0000000
+0000001FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC00000000000FF
+FFFFFFFF00000000FFFFFFFFFF00000000FFFFFFFFFF00000000FFFFFFFFFF00000000FFFFFFFF
+FF0000000041467CC54B>70 D<000000003FFE00000E000000000FFFFFC0001E000000007FFFFF
+F8003E00000003FFFFFFFE00FE0000000FFFFFFFFF81FE0000003FFFF800FFC3FE000000FFFF80
+000FF7FE000001FFFC000003FFFE000007FFF0000001FFFE00000FFFC00000007FFE00001FFF80
+0000003FFE00003FFF000000001FFE00007FFE000000000FFE0000FFFC0000000007FE0001FFF8
+0000000007FE0003FFF00000000003FE0003FFF00000000001FE0007FFE00000000001FE0007FF
+E00000000000FE000FFFC00000000000FE000FFFC000000000007E001FFFC000000000007E001F
+FF8000000000007E003FFF8000000000007E003FFF8000000000003E003FFF8000000000003E00
+7FFF8000000000003E007FFF0000000000003E007FFF00000000000000007FFF00000000000000
+00FFFF0000000000000000FFFF0000000000000000FFFF0000000000000000FFFF000000000000
+0000FFFF0000000000000000FFFF0000000000000000FFFF0000000000000000FFFF0000000000
+000000FFFF0000000000000000FFFF0000000000000000FFFF0000000000000000FFFF00000000
+00000000FFFF0000007FFFFFFFFE7FFF0000007FFFFFFFFE7FFF0000007FFFFFFFFE7FFF800000
+7FFFFFFFFE7FFF8000007FFFFFFFFE3FFF8000000000FFFE003FFF8000000000FFFE003FFF8000
+000000FFFE001FFF8000000000FFFE001FFFC000000000FFFE000FFFC000000000FFFE000FFFC0
+00000000FFFE0007FFE000000000FFFE0007FFE000000000FFFE0003FFF000000000FFFE0003FF
+F800000000FFFE0001FFF800000000FFFE0000FFFC00000000FFFE00007FFE00000000FFFE0000
+3FFF00000000FFFE00001FFF80000000FFFE00000FFFE0000001FFFE000007FFF0000003FFFE00
+0001FFFC000007FFFE000000FFFF80001FFFFE0000003FFFFC00FFC7FE0000000FFFFFFFFF83FE
+00000003FFFFFFFE00FE000000007FFFFFF8003E000000000FFFFFE0000E00000000003FFE0000
+00004F4979C75D>I<FFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFE000FFFE000
+000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE0
+00000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFF
+E000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000F
+FFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE00000
+0FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000
+000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE0
+00000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFF
+E000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000FFFFFFFFFEFFFFFFFFFEFFFF
+FFFFFEFFFFFFFFFEFFFFFFFFFE27477DC62D>73 D<FFFFFFFFFF000000FFFFFFFFFF000000FFFF
+FFFFFF000000FFFFFFFFFF000000FFFFFFFFFF000000001FFFC000000000001FFFC00000000000
+1FFFC000000000001FFFC000000000001FFFC000000000001FFFC000000000001FFFC000000000
+001FFFC000000000001FFFC000000000001FFFC000000000001FFFC000000000001FFFC0000000
+00001FFFC000000000001FFFC000000000001FFFC000000000001FFFC000000000001FFFC00000
+0000001FFFC000000000001FFFC000000000001FFFC000000000001FFFC000000000001FFFC000
+000000001FFFC000000000001FFFC000000000001FFFC000000000001FFFC000000000001FFFC0
+00000000001FFFC000000000001FFFC000000000001FFFC000000000001FFFC000000000001FFF
+C000000000001FFFC000000000001FFFC000000000001FFFC000000000001FFFC000000000001F
+FFC000000000001FFFC000000000001FFFC0000000F8001FFFC0000000F8001FFFC0000000F800
+1FFFC0000000F8001FFFC0000001F0001FFFC0000001F0001FFFC0000001F0001FFFC0000001F0
+001FFFC0000001F0001FFFC0000003F0001FFFC0000003F0001FFFC0000003F0001FFFC0000007
+F0001FFFC0000007F0001FFFC000000FE0001FFFC000001FE0001FFFC000001FE0001FFFC00000
+3FE0001FFFC000007FE0001FFFC00000FFE0001FFFC00003FFE0001FFFC0000FFFE0001FFFC000
+7FFFE0FFFFFFFFFFFFFFC0FFFFFFFFFFFFFFC0FFFFFFFFFFFFFFC0FFFFFFFFFFFFFFC0FFFFFFFF
+FFFFFFC03D477CC647>76 D<FFFFFFE0000000000003FFFFFFFFFFFFF0000000000007FFFFFFFF
+FFFFF0000000000007FFFFFFFFFFFFF800000000000FFFFFFFFFFFFFF800000000000FFFFFFF00
+1FFFF800000000000FFFF800001FFFFC00000000001EFFF800001FFFFC00000000001EFFF80000
+1FBFFE00000000003CFFF800001FBFFE00000000003CFFF800001F9FFF000000000078FFF80000
+1F9FFF000000000078FFF800001F8FFF8000000000F0FFF800001F8FFF8000000000F0FFF80000
+1F87FFC000000001E0FFF800001F87FFC000000001E0FFF800001F87FFC000000001E0FFF80000
+1F83FFE000000003C0FFF800001F83FFE000000003C0FFF800001F81FFF00000000780FFF80000
+1F81FFF00000000780FFF800001F80FFF80000000F00FFF800001F80FFF80000000F00FFF80000
+1F807FFC0000001E00FFF800001F807FFC0000001E00FFF800001F807FFC0000001E00FFF80000
+1F803FFE0000003C00FFF800001F803FFE0000003C00FFF800001F801FFF0000007800FFF80000
+1F801FFF0000007800FFF800001F800FFF800000F000FFF800001F800FFF800000F000FFF80000
+1F8007FFC00001E000FFF800001F8007FFC00001E000FFF800001F8003FFE00003C000FFF80000
+1F8003FFE00003C000FFF800001F8003FFE00003C000FFF800001F8001FFF000078000FFF80000
+1F8001FFF000078000FFF800001F8000FFF8000F0000FFF800001F8000FFF8000F0000FFF80000
+1F80007FFC001E0000FFF800001F80007FFC001E0000FFF800001F80003FFE003C0000FFF80000
+1F80003FFE003C0000FFF800001F80001FFF00780000FFF800001F80001FFF00780000FFF80000
+1F80001FFF00780000FFF800001F80000FFF80F00000FFF800001F80000FFF80F00000FFF80000
+1F800007FFC1E00000FFF800001F800007FFC1E00000FFF800001F800003FFE3C00000FFF80000
+1F800003FFE3C00000FFF800001F800001FFF7800000FFF800001F800001FFF7800000FFF80000
+1F800001FFF7800000FFF800001F800000FFFF000000FFF800001F800000FFFF000000FFF80000
+1F8000007FFE000000FFF800001F8000007FFE000000FFF800001F8000003FFC000000FFF80000
+1F8000003FFC000000FFF800001F8000001FF8000000FFF800001F8000001FF8000000FFF80000
+7FE000000FF0000000FFF800FFFFFFF0000FF00007FFFFFFFFFFFFFFF0000FF00007FFFFFFFFFF
+FFFFF00007E00007FFFFFFFFFFFFFFF00007E00007FFFFFFFFFFFFFFF00003C00007FFFFFFFF68
+477CC671>I<FFFFFFC0000000FFFFFFF0FFFFFFE0000000FFFFFFF0FFFFFFF0000000FFFFFFF0
+FFFFFFF8000000FFFFFFF0FFFFFFFC000000FFFFFFF0001FFFFC000000007FE000001FFFFE0000
+00001F8000001FFFFF000000001F8000001FFFFF800000001F8000001FFFFFC00000001F800000
+1FBFFFE00000001F8000001F9FFFE00000001F8000001F9FFFF00000001F8000001F8FFFF80000
+001F8000001F87FFFC0000001F8000001F83FFFE0000001F8000001F81FFFF0000001F8000001F
+80FFFF0000001F8000001F80FFFF8000001F8000001F807FFFC000001F8000001F803FFFE00000
+1F8000001F801FFFF000001F8000001F800FFFF800001F8000001F8007FFF800001F8000001F80
+07FFFC00001F8000001F8003FFFE00001F8000001F8001FFFF00001F8000001F8000FFFF80001F
+8000001F80007FFFC0001F8000001F80003FFFC0001F8000001F80003FFFE0001F8000001F8000
+1FFFF0001F8000001F80000FFFF8001F8000001F800007FFFC001F8000001F800003FFFE001F80
+00001F800001FFFF001F8000001F800001FFFF001F8000001F800000FFFF801F8000001F800000
+7FFFC01F8000001F8000003FFFE01F8000001F8000001FFFF01F8000001F8000000FFFF81F8000
+001F8000000FFFF81F8000001F80000007FFFC1F8000001F80000003FFFE1F8000001F80000001
+FFFF1F8000001F80000000FFFF9F8000001F800000007FFFDF8000001F800000007FFFDF800000
+1F800000003FFFFF8000001F800000001FFFFF8000001F800000000FFFFF8000001F8000000007
+FFFF8000001F8000000003FFFF8000001F8000000003FFFF8000001F8000000001FFFF8000001F
+8000000000FFFF8000001F80000000007FFF8000001F80000000003FFF8000001F80000000001F
+FF8000001F80000000001FFF8000001F80000000000FFF8000001F800000000007FF8000001F80
+0000000003FF8000001F800000000001FF8000007FE00000000000FF8000FFFFFFF000000000FF
+8000FFFFFFF0000000007F8000FFFFFFF0000000003F8000FFFFFFF0000000001F8000FFFFFFF0
+000000000F000054477CC65D>I<FFFFFFFFFFFF800000FFFFFFFFFFFFFC0000FFFFFFFFFFFFFF
+0000FFFFFFFFFFFFFFC000FFFFFFFFFFFFFFF000001FFF80000FFFFC00001FFF800001FFFE0000
+1FFF8000007FFF00001FFF8000003FFF80001FFF8000001FFFC0001FFF8000000FFFC0001FFF80
+00000FFFE0001FFF8000000FFFE0001FFF80000007FFF0001FFF80000007FFF0001FFF80000007
+FFF0001FFF80000007FFF8001FFF80000007FFF8001FFF80000007FFF8001FFF80000007FFF800
+1FFF80000007FFF8001FFF80000007FFF8001FFF80000007FFF8001FFF80000007FFF8001FFF80
+000007FFF0001FFF80000007FFF0001FFF80000007FFF0001FFF8000000FFFE0001FFF8000000F
+FFE0001FFF8000000FFFC0001FFF8000001FFF80001FFF8000003FFF80001FFF8000007FFF0000
+1FFF800001FFFE00001FFF80000FFFF800001FFFFFFFFFFFF000001FFFFFFFFFFFC000001FFFFF
+FFFFFE0000001FFFFFFFFFF00000001FFFC00000000000001FFFC00000000000001FFFC0000000
+0000001FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC0000000000000
+1FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC0
+0000000000001FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC0000000
+0000001FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC0000000000000
+1FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC0
+0000000000001FFFC00000000000001FFFC00000000000FFFFFFFFF800000000FFFFFFFFF80000
+0000FFFFFFFFF800000000FFFFFFFFF800000000FFFFFFFFF80000000045477CC651>80
+D<FFFFFFFFFFFC0000000000FFFFFFFFFFFFF000000000FFFFFFFFFFFFFE00000000FFFFFFFFFF
+FFFF80000000FFFFFFFFFFFFFFE0000000001FFF80001FFFF8000000001FFF800001FFFC000000
+001FFF8000007FFF000000001FFF8000003FFF800000001FFF8000001FFF800000001FFF800000
+0FFFC00000001FFF8000000FFFE00000001FFF8000000FFFE00000001FFF80000007FFF0000000
+1FFF80000007FFF00000001FFF80000007FFF80000001FFF80000007FFF80000001FFF80000007
+FFF80000001FFF80000007FFF80000001FFF80000007FFF80000001FFF80000007FFF80000001F
+FF80000007FFF80000001FFF80000007FFF80000001FFF80000007FFF00000001FFF80000007FF
+F00000001FFF8000000FFFE00000001FFF8000000FFFE00000001FFF8000000FFFC00000001FFF
+8000001FFF800000001FFF8000003FFF000000001FFF800000FFFE000000001FFF800003FFF800
+0000001FFF80001FFFF0000000001FFFFFFFFFFFC0000000001FFFFFFFFFFE00000000001FFFFF
+FFFFF800000000001FFFFFFFFFFE00000000001FFF80007FFF80000000001FFF80001FFFC00000
+00001FFF800007FFE0000000001FFF800003FFF0000000001FFF800001FFF8000000001FFF8000
+01FFFC000000001FFF800000FFFE000000001FFF800000FFFE000000001FFF8000007FFE000000
+001FFF8000007FFF000000001FFF8000007FFF000000001FFF8000007FFF000000001FFF800000
+7FFF000000001FFF8000007FFF000000001FFF8000007FFF000000001FFF8000007FFF00000000
+1FFF8000007FFF800000001FFF8000007FFF800000001FFF8000007FFF800000001FFF8000007F
+FF800000001FFF8000007FFF800000001FFF8000007FFF8000E0001FFF8000007FFF8001F0001F
+FF8000007FFFC001F0001FFF8000007FFFC001F0001FFF8000003FFFC001F0001FFF8000003FFF
+C003F0001FFF8000001FFFE003E0001FFF8000000FFFE007E0FFFFFFFFF00007FFF007C0FFFFFF
+FFF00003FFFC1F80FFFFFFFFF00001FFFFFF00FFFFFFFFF000007FFFFE00FFFFFFFFF000001FFF
+FC000000000000000000FFF00054487CC659>82 D<FFFFFFFFF80001FFFFFFC0FFFFFFFFF80001
+FFFFFFC0FFFFFFFFF80001FFFFFFC0FFFFFFFFF80001FFFFFFC0FFFFFFFFF80001FFFFFFC0001F
+FFC000000000FF8000001FFFC0000000003E0000001FFFC0000000003E0000001FFFC000000000
+3E0000001FFFC0000000003E0000001FFFC0000000003E0000001FFFC0000000003E0000001FFF
+C0000000003E0000001FFFC0000000003E0000001FFFC0000000003E0000001FFFC0000000003E
+0000001FFFC0000000003E0000001FFFC0000000003E0000001FFFC0000000003E0000001FFFC0
+000000003E0000001FFFC0000000003E0000001FFFC0000000003E0000001FFFC0000000003E00
+00001FFFC0000000003E0000001FFFC0000000003E0000001FFFC0000000003E0000001FFFC000
+0000003E0000001FFFC0000000003E0000001FFFC0000000003E0000001FFFC0000000003E0000
+001FFFC0000000003E0000001FFFC0000000003E0000001FFFC0000000003E0000001FFFC00000
+00003E0000001FFFC0000000003E0000001FFFC0000000003E0000001FFFC0000000003E000000
+1FFFC0000000003E0000001FFFC0000000003E0000001FFFC0000000003E0000001FFFC0000000
+003E0000001FFFC0000000003E0000001FFFC0000000003E0000001FFFC0000000003E0000001F
+FFC0000000003E0000001FFFC0000000003E0000001FFFC0000000003E0000001FFFC000000000
+3E0000001FFFC0000000003E0000001FFFC0000000003E0000001FFFC0000000003E0000001FFF
+C0000000003E0000000FFFC0000000007E0000000FFFC0000000007C0000000FFFE0000000007C
+0000000FFFE000000000FC00000007FFE000000000F800000007FFE000000001F800000003FFF0
+00000001F800000001FFF000000003F000000001FFF800000007E000000000FFF800000007E000
+0000007FFC0000001FC0000000003FFE0000003F80000000001FFF800000FF00000000000FFFE0
+0007FE000000000003FFFE007FFC000000000001FFFFFFFFF00000000000007FFFFFFFE0000000
+0000000FFFFFFF8000000000000001FFFFFC00000000000000000FFFC00000000052487CC65B>
+85 D<FFFFFFFFE000001FFFFFE0FFFFFFFFE000001FFFFFE0FFFFFFFFE000001FFFFFE0FFFFFF
+FFE000001FFFFFE0FFFFFFFFE000001FFFFFE0007FFF80000000003FE000003FFFC0000000000F
+8000003FFFC0000000001F8000001FFFE0000000001F0000001FFFE0000000003F0000000FFFE0
+000000003E0000000FFFF0000000007E00000007FFF0000000007C00000007FFF8000000007C00
+000007FFF800000000FC00000003FFFC00000000F800000003FFFC00000001F800000001FFFE00
+000001F000000001FFFE00000003F000000000FFFE00000003E000000000FFFF00000007E00000
+00007FFF00000007C0000000007FFF80000007C0000000007FFF8000000FC0000000003FFFC000
+000F80000000003FFFC000001F80000000001FFFC000001F00000000001FFFE000003F00000000
+000FFFE000003E00000000000FFFF000007E00000000000FFFF000007E000000000007FFF80000
+7C000000000007FFF80000FC000000000003FFFC0000F8000000000003FFFC0001F80000000000
+01FFFC0001F0000000000001FFFE0003F0000000000000FFFE0003E0000000000000FFFF0003E0
+000000000000FFFF0007E00000000000007FFF8007C00000000000007FFF800FC0000000000000
+3FFFC00F800000000000003FFFC01F800000000000001FFFC01F000000000000001FFFE03F0000
+00000000000FFFE03E000000000000000FFFF03E000000000000000FFFF07E0000000000000007
+FFF87C0000000000000007FFF8FC0000000000000003FFF8F80000000000000003FFFDF8000000
+0000000001FFFDF00000000000000001FFFFF00000000000000001FFFFF00000000000000000FF
+FFE00000000000000000FFFFE000000000000000007FFFC000000000000000007FFFC000000000
+000000003FFF8000000000000000003FFF8000000000000000001FFF0000000000000000001FFF
+0000000000000000001FFF0000000000000000000FFE0000000000000000000FFE000000000000
+00000007FC00000000000000000007FC00000000000000000003F800000000000000000003F800
+000000000000000001F0000000000053487DC65A>I<FFFFFFFFC03FFFFFFFF0001FFFFFF0FFFF
+FFFFC03FFFFFFFF0001FFFFFF0FFFFFFFFC03FFFFFFFF0001FFFFFF0FFFFFFFFC03FFFFFFFF000
+1FFFFFF0FFFFFFFFC03FFFFFFFF0001FFFFFF0007FFF0000001FFFE00000000FF800007FFF0000
+000FFFE000000003E000007FFF8000000FFFE000000007E000003FFF8000000FFFF000000007C0
+00003FFFC0000007FFF000000007C000003FFFC0000007FFF80000000FC000001FFFC0000003FF
+F80000000F8000001FFFE0000003FFF80000001F8000000FFFE0000003FFFC0000001F0000000F
+FFE0000001FFFC0000001F0000000FFFF0000001FFFE0000003F00000007FFF0000001FFFE0000
+003E00000007FFF8000001FFFE0000007E00000003FFF8000003FFFF0000007C00000003FFF800
+0003FFFF0000007C00000003FFFC000003FFFF000000FC00000001FFFC000007FFFF800000F800
+000001FFFE000007FFFF800000F800000001FFFE000007FFFFC00001F800000000FFFE00000F9F
+FFC00001F000000000FFFF00000F9FFFC00003F0000000007FFF00001F9FFFE00003E000000000
+7FFF00001F0FFFE00003E0000000007FFF80001F0FFFE00007E0000000003FFF80003F0FFFF000
+07C0000000003FFFC0003E07FFF00007C0000000001FFFC0007E07FFF8000F80000000001FFFC0
+007C03FFF8000F80000000001FFFE0007C03FFF8001F80000000000FFFE000FC03FFFC001F0000
+0000000FFFE000F801FFFC001F00000000000FFFF000F801FFFE003F000000000007FFF001F801
+FFFE003E000000000007FFF801F000FFFE007E000000000003FFF803F000FFFF007C0000000000
+03FFF803E0007FFF007C000000000003FFFC03E0007FFF00FC000000000001FFFC07E0007FFF80
+F8000000000001FFFE07C0003FFF80F8000000000001FFFE0FC0003FFFC1F8000000000000FFFE
+0F80001FFFC1F0000000000000FFFF0F80001FFFC3F00000000000007FFF1F80001FFFE3E00000
+000000007FFF1F00000FFFE3E00000000000007FFF9F00000FFFF7E00000000000003FFFBF0000
+0FFFF7C00000000000003FFFFE000007FFFFC00000000000001FFFFE000007FFFF800000000000
+001FFFFC000003FFFF800000000000001FFFFC000003FFFF800000000000000FFFFC000003FFFF
+000000000000000FFFF8000001FFFF000000000000000FFFF8000001FFFF0000000000000007FF
+F0000000FFFE0000000000000007FFF0000000FFFE0000000000000003FFF0000000FFFC000000
+0000000003FFE00000007FFC0000000000000003FFE00000007FFC0000000000000001FFE00000
+007FF80000000000000001FFC00000003FF80000000000000001FFC00000003FF8000000000000
+0000FF800000001FF00000000000000000FF800000001FF000000000000000007F800000001FE0
+00000000000000007F000000000FE000000000000000007F000000000FE000000000000000003E
+0000000007C00000000074487DC67B>I<0007FFFC000000007FFFFFC0000001FFFFFFF8000003
+FFFFFFFE000007FE001FFF000007FF0003FFC0000FFF8001FFE0000FFF8000FFF0000FFF80007F
+F0000FFF80007FF8000FFF80007FF80007FF00003FFC0007FF00003FFC0003FE00003FFC0000F8
+00003FFC00000000003FFC00000000003FFC00000000003FFC00000000003FFC00000007FFFFFC
+000000FFFFFFFC000007FFFFFFFC00003FFFE03FFC0000FFFE003FFC0003FFF0003FFC0007FFC0
+003FFC000FFF00003FFC001FFE00003FFC003FFC00003FFC007FF800003FFC007FF800003FFC00
+FFF000003FFC00FFF000003FFC00FFF000003FFC00FFF000003FFC00FFF000003FFC00FFF00000
+7FFC007FF80000FFFC007FF80001EFFC003FFC0003EFFC003FFF0007CFFF000FFFC03F8FFFF807
+FFFFFF07FFFC01FFFFFC03FFFC007FFFF001FFFC0003FF80007FF8362E7DAD3A>97
+D<007FC00000000000FFFFC00000000000FFFFC00000000000FFFFC00000000000FFFFC0000000
+0000FFFFC0000000000003FFC0000000000001FFC0000000000001FFC0000000000001FFC00000
+00000001FFC0000000000001FFC0000000000001FFC0000000000001FFC0000000000001FFC000
+0000000001FFC0000000000001FFC0000000000001FFC0000000000001FFC0000000000001FFC0
+000000000001FFC0000000000001FFC0000000000001FFC0000000000001FFC0000000000001FF
+C0000000000001FFC0000000000001FFC00FFC00000001FFC07FFFC0000001FFC3FFFFF0000001
+FFCFFFFFFC000001FFDFF00FFF000001FFFF8003FF800001FFFE0001FFC00001FFF800007FE000
+01FFF000007FF00001FFE000003FF80001FFE000001FFC0001FFE000001FFC0001FFE000001FFE
+0001FFE000001FFE0001FFE000000FFF0001FFE000000FFF0001FFE000000FFF0001FFE000000F
+FF0001FFE000000FFF8001FFE000000FFF8001FFE000000FFF8001FFE000000FFF8001FFE00000
+0FFF8001FFE000000FFF8001FFE000000FFF8001FFE000000FFF8001FFE000000FFF8001FFE000
+000FFF8001FFE000000FFF0001FFE000000FFF0001FFE000000FFF0001FFE000001FFE0001FFE0
+00001FFE0001FFE000001FFC0001FFE000001FFC0001FFE000003FF80001FFF000003FF80001FF
+F800007FF00001FFFC0000FFE00001FFFE0001FFC00001FFBF0007FF800001FF1FE01FFE000001
+FE0FFFFFFC000001FC03FFFFF0000001F800FFFF80000001F0001FF800000039487CC742>I<00
+001FFFC0000000FFFFF8000007FFFFFE00001FFFFFFF80007FFC00FFC000FFE001FFC001FFC003
+FFE003FF8003FFE007FF0003FFE00FFE0003FFE00FFE0003FFE01FFC0001FFC01FFC0001FFC03F
+FC0000FF803FFC00003E007FF8000000007FF8000000007FF800000000FFF800000000FFF80000
+0000FFF800000000FFF800000000FFF800000000FFF800000000FFF800000000FFF800000000FF
+F800000000FFF8000000007FF8000000007FF8000000007FFC000000003FFC000000003FFC0000
+00001FFC000000F81FFE000000F80FFE000000F80FFF000001F007FF800003F003FFC00007E001
+FFE0000FC000FFF0001F80007FFE00FF00001FFFFFFE000007FFFFF8000000FFFFE00000001FFE
+00002D2E7CAD35>I<00000000007FC00000000000FFFFC00000000000FFFFC00000000000FFFF
+C00000000000FFFFC00000000000FFFFC0000000000003FFC0000000000001FFC0000000000001
+FFC0000000000001FFC0000000000001FFC0000000000001FFC0000000000001FFC00000000000
+01FFC0000000000001FFC0000000000001FFC0000000000001FFC0000000000001FFC000000000
+0001FFC0000000000001FFC0000000000001FFC0000000000001FFC0000000000001FFC0000000
+000001FFC0000000000001FFC0000000000001FFC00000000FFC01FFC0000000FFFF81FFC00000
+07FFFFE1FFC000001FFFFFF9FFC000007FFC03FFFFC00000FFF0007FFFC00001FFC0001FFFC000
+03FF80000FFFC00007FF000007FFC0000FFE000003FFC0000FFE000003FFC0001FFC000003FFC0
+001FFC000003FFC0003FFC000003FFC0003FFC000003FFC0007FF8000003FFC0007FF8000003FF
+C0007FF8000003FFC000FFF8000003FFC000FFF8000003FFC000FFF8000003FFC000FFF8000003
+FFC000FFF8000003FFC000FFF8000003FFC000FFF8000003FFC000FFF8000003FFC000FFF80000
+03FFC000FFF8000003FFC0007FF8000003FFC0007FF8000003FFC0007FF8000003FFC0003FF800
+0003FFC0003FFC000003FFC0003FFC000003FFC0001FFC000003FFC0001FFC000003FFC0000FFE
+000007FFC00007FF00000FFFC00003FF00001FFFC00001FFC0003FFFC00000FFE000FFFFE00000
+7FF807FBFFFF80001FFFFFF3FFFF800007FFFFC3FFFF800001FFFF03FFFF8000001FF803FFFF80
+39487CC742>I<00001FFE00000001FFFFE0000007FFFFF800001FFFFFFE00007FFC07FF0000FF
+E001FF8001FFC0007FC003FF80003FE007FF00003FF00FFE00001FF01FFE00000FF81FFC00000F
+F83FFC00000FFC3FFC000007FC7FFC000007FC7FF8000007FC7FF8000007FE7FF8000007FEFFF8
+000007FEFFF8000007FEFFFFFFFFFFFEFFFFFFFFFFFEFFFFFFFFFFFEFFFFFFFFFFFCFFF8000000
+00FFF800000000FFF800000000FFF8000000007FF8000000007FF8000000007FFC000000003FFC
+000000003FFC000000003FFC0000001C1FFE0000003E0FFE0000003E07FF0000007E07FF000000
+FC03FF800001F801FFC00003F0007FF0001FE0003FFE00FFC0001FFFFFFF800007FFFFFE000000
+FFFFF80000000FFF80002F2E7DAD36>I<000000FFC000000007FFF80000003FFFFC000000FFFF
+FF000001FFC1FF000007FF03FF80000FFC03FF80000FF807FFC0001FF807FFC0003FF007FFC000
+3FF007FFC0003FE003FF80007FE003FF80007FE001FF00007FE000FE00007FE0003800007FE000
+0000007FE0000000007FE0000000007FE0000000007FE0000000007FE0000000007FE000000000
+7FE0000000007FE0000000007FE0000000FFFFFFFE0000FFFFFFFE0000FFFFFFFE0000FFFFFFFE
+0000FFFFFFFE0000007FF0000000007FF0000000007FF0000000007FF0000000007FF000000000
+7FF0000000007FF0000000007FF0000000007FF0000000007FF0000000007FF0000000007FF000
+0000007FF0000000007FF0000000007FF0000000007FF0000000007FF0000000007FF000000000
+7FF0000000007FF0000000007FF0000000007FF0000000007FF0000000007FF0000000007FF000
+0000007FF0000000007FF0000000007FF0000000007FF0000000007FF0000000007FF000000000
+7FF0000000007FF0000000007FF0000000007FF0000000007FF00000003FFFFFF800003FFFFFF8
+00003FFFFFF800003FFFFFF800003FFFFFF800002A487DC724>I<00000000001F8000007FF000
+FFE00007FFFF03FFF0001FFFFFC7FFF0007FFFFFFFC7F800FFE03FFE0FF801FF800FFC0FF803FF
+0007FE0FF807FE0003FF07F007FE0003FF07F00FFC0001FF81C00FFC0001FF80000FFC0001FF80
+001FFC0001FFC0001FFC0001FFC0001FFC0001FFC0001FFC0001FFC0001FFC0001FFC0001FFC00
+01FFC0000FFC0001FF80000FFC0001FF80000FFC0001FF800007FE0003FF000007FE0003FF0000
+03FF0007FE000001FF800FFC000000FFE03FF8000001FFFFFFF0000001DFFFFFC0000003C7FFFF
+00000003C07FF000000007C0000000000007C0000000000007C0000000000007C0000000000007
+E0000000000007F0000000000007F8000000000007FFFFFFF0000007FFFFFFFF000003FFFFFFFF
+E00003FFFFFFFFF80001FFFFFFFFFE0001FFFFFFFFFF0000FFFFFFFFFF80007FFFFFFFFF8003FF
+FFFFFFFFC00FFFFFFFFFFFC01FF800001FFFE03FE0000001FFE07FC00000007FF07FC00000003F
+F0FF800000001FF0FF800000001FF0FF800000001FF0FF800000001FF0FF800000001FF07FC000
+00003FE07FC00000003FE03FE00000007FC03FF0000000FFC01FFC000003FF800FFF00000FFF00
+03FFF000FFFC0000FFFFFFFFF000003FFFFFFFC0000007FFFFFE000000003FFFC0000035447DAE
+3B>I<00FC0001FE0003FF0007FF800FFFC01FFFE01FFFE01FFFE01FFFE01FFFE01FFFE00FFFC0
+07FF8003FF0001FE0000FC00000000000000000000000000000000000000000000000000000000
+000000000000007FC0FFFFC0FFFFC0FFFFC0FFFFC0FFFFC003FFC001FFC001FFC001FFC001FFC0
+01FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC0
+01FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC0
+01FFC001FFC001FFC001FFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18497CC820>105
+D<007FC000000000FFFFC000000000FFFFC000000000FFFFC000000000FFFFC000000000FFFFC0
+0000000003FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC000000000
+01FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC000
+00000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001
+FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC0007FFFF801FFC0007F
+FFF801FFC0007FFFF801FFC0007FFFF801FFC0007FFFF801FFC0000FFE0001FFC00007F00001FF
+C0000FE00001FFC0003FC00001FFC0007F800001FFC000FE000001FFC001FC000001FFC007F800
+0001FFC00FF0000001FFC01FC0000001FFC03F80000001FFC0FF00000001FFC1FE00000001FFC3
+FF00000001FFCFFF80000001FFDFFFC0000001FFFFFFC0000001FFFFFFE0000001FFFFFFF00000
+01FFFCFFF8000001FFF87FFC000001FFE03FFC000001FFC01FFE000001FFC01FFF000001FFC00F
+FF800001FFC007FFC00001FFC003FFC00001FFC001FFE00001FFC001FFF00001FFC000FFF80001
+FFC0007FFC0001FFC0003FFC0001FFC0001FFE0001FFC0000FFF0001FFC0000FFF8001FFC0000F
+FFC0FFFFFF807FFFFFFFFFFF807FFFFFFFFFFF807FFFFFFFFFFF807FFFFFFFFFFF807FFFFF3848
+7CC73F>107 D<007FC000FFFFC000FFFFC000FFFFC000FFFFC000FFFFC00003FFC00001FFC000
+01FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC0
+0001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FF
+C00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001
+FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC000
+01FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC0
+0001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FF
+C000FFFFFF80FFFFFF80FFFFFF80FFFFFF80FFFFFF8019487CC720>I<007FC001FFC00000FFE0
+0000FFFFC00FFFF80007FFFC0000FFFFC03FFFFE001FFFFF0000FFFFC0FFFFFF007FFFFF8000FF
+FFC1FC07FF80FE03FFC000FFFFC3E003FFC1F001FFE00003FFC7C001FFC3E000FFE00001FFCF00
+01FFE78000FFF00001FFDE0000FFEF00007FF00001FFDC0000FFEE00007FF00001FFFC0000FFFE
+00007FF80001FFF80000FFFC00007FF80001FFF00000FFF800007FF80001FFF00000FFF800007F
+F80001FFF00000FFF800007FF80001FFE00000FFF000007FF80001FFE00000FFF000007FF80001
+FFE00000FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF000007FF80001FFE000
+00FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF0
+00007FF80001FFE00000FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF000007F
+F80001FFE00000FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF000007FF80001
+FFE00000FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF000007FF80001FFE000
+00FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF0
+00007FF80001FFE00000FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF000007F
+F80001FFE00000FFF000007FF800FFFFFFC07FFFFFE03FFFFFF0FFFFFFC07FFFFFE03FFFFFF0FF
+FFFFC07FFFFFE03FFFFFF0FFFFFFC07FFFFFE03FFFFFF0FFFFFFC07FFFFFE03FFFFFF05C2E7CAD
+63>I<007FC001FFC00000FFFFC00FFFF80000FFFFC03FFFFE0000FFFFC0FFFFFF0000FFFFC1FC
+07FF8000FFFFC3E003FFC00003FFC7C001FFC00001FFCF0001FFE00001FFDE0000FFE00001FFDC
+0000FFE00001FFFC0000FFF00001FFF80000FFF00001FFF00000FFF00001FFF00000FFF00001FF
+F00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001
+FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF000
+01FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF0
+0001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FF
+F00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000
+FFF00001FFE00000FFF00001FFE00000FFF000FFFFFFC07FFFFFE0FFFFFFC07FFFFFE0FFFFFFC0
+7FFFFFE0FFFFFFC07FFFFFE0FFFFFFC07FFFFFE03B2E7CAD42>I<00000FFF0000000000FFFFF0
+00000007FFFFFE0000001FFFFFFF8000003FFC03FFC00000FFE0007FF00001FF80001FF80003FF
+00000FFC0007FE000007FE000FFE000007FF000FFC000003FF001FFC000003FF803FFC000003FF
+C03FF8000001FFC03FF8000001FFC07FF8000001FFE07FF8000001FFE07FF8000001FFE0FFF800
+0001FFF0FFF8000001FFF0FFF8000001FFF0FFF8000001FFF0FFF8000001FFF0FFF8000001FFF0
+FFF8000001FFF0FFF8000001FFF0FFF8000001FFF0FFF8000001FFF07FF8000001FFE07FF80000
+01FFE07FF8000001FFE07FF8000001FFE03FFC000003FFC03FFC000003FFC01FFC000003FF801F
+FE000007FF800FFE000007FF0007FF00000FFE0003FF80001FFC0001FFC0003FF80000FFE0007F
+F000007FFC03FFE000001FFFFFFF80000007FFFFFE00000000FFFFF0000000000FFF000000342E
+7DAD3B>I<007FC00FFC000000FFFFC07FFFC00000FFFFC3FFFFF00000FFFFCFFFFFFC0000FFFF
+DFF01FFF0000FFFFFF8007FF800003FFFE0001FFC00001FFF80000FFE00001FFF00000FFF00001
+FFE000007FF80001FFE000003FFC0001FFE000003FFC0001FFE000003FFE0001FFE000001FFE00
+01FFE000001FFF0001FFE000001FFF0001FFE000001FFF0001FFE000000FFF0001FFE000000FFF
+8001FFE000000FFF8001FFE000000FFF8001FFE000000FFF8001FFE000000FFF8001FFE000000F
+FF8001FFE000000FFF8001FFE000000FFF8001FFE000000FFF8001FFE000000FFF8001FFE00000
+0FFF0001FFE000001FFF0001FFE000001FFF0001FFE000001FFE0001FFE000001FFE0001FFE000
+003FFC0001FFE000003FFC0001FFE000007FF80001FFF000007FF80001FFF80000FFF00001FFFC
+0001FFE00001FFFE0003FFC00001FFFF0007FF800001FFFFE03FFE000001FFEFFFFFFC000001FF
+E3FFFFF0000001FFE0FFFF80000001FFE01FF800000001FFE0000000000001FFE0000000000001
+FFE0000000000001FFE0000000000001FFE0000000000001FFE0000000000001FFE00000000000
+01FFE0000000000001FFE0000000000001FFE0000000000001FFE0000000000001FFE000000000
+0001FFE0000000000001FFE0000000000001FFE00000000000FFFFFFC000000000FFFFFFC00000
+0000FFFFFFC000000000FFFFFFC000000000FFFFFFC00000000039427CAD42>I<00FF803F8000
+FFFF80FFF000FFFF83FFFC00FFFF87FFFE00FFFF8FC3FF00FFFF8F07FF0003FF9E0FFF8001FFBC
+0FFF8001FFB80FFF8001FFF80FFF8001FFF00FFF8001FFF007FF0001FFF007FF0001FFE003FE00
+01FFE000F80001FFE000000001FFE000000001FFC000000001FFC000000001FFC000000001FFC0
+00000001FFC000000001FFC000000001FFC000000001FFC000000001FFC000000001FFC0000000
+01FFC000000001FFC000000001FFC000000001FFC000000001FFC000000001FFC000000001FFC0
+00000001FFC000000001FFC000000001FFC000000001FFC000000001FFC000000001FFC0000000
+01FFC0000000FFFFFFE00000FFFFFFE00000FFFFFFE00000FFFFFFE00000FFFFFFE00000292E7C
+AD31>114 D<000FFF00E0007FFFF3E001FFFFFFE007FFFFFFE00FF800FFE01FC0001FE03F8000
+0FE03F000007E07F000003E07F000003E0FF000003E0FF000003E0FF800003E0FFC0000000FFF0
+000000FFFE000000FFFFF800007FFFFFC0007FFFFFF0003FFFFFFC001FFFFFFF000FFFFFFF8007
+FFFFFFC003FFFFFFE000FFFFFFF0003FFFFFF00003FFFFF800001FFFF8000000FFFC0000001FFC
+7800000FFCF8000007FCF8000003FCFC000003FCFC000003FCFE000003F8FE000003F8FF000003
+F8FF800007F0FFC0000FF0FFF0001FE0FFFC00FFC0FFFFFFFF80FC7FFFFE00F81FFFF800E003FF
+8000262E7CAD2F>I<0001F000000001F000000001F000000001F000000001F000000001F00000
+0003F000000003F000000003F000000007F000000007F000000007F00000000FF00000000FF000
+00001FF00000003FF00000003FF00000007FF0000001FFF0000003FFF000000FFFFFFFC0FFFFFF
+FFC0FFFFFFFFC0FFFFFFFFC0FFFFFFFFC000FFF0000000FFF0000000FFF0000000FFF0000000FF
+F0000000FFF0000000FFF0000000FFF0000000FFF0000000FFF0000000FFF0000000FFF0000000
+FFF0000000FFF0000000FFF0000000FFF0000000FFF0000000FFF0000000FFF0000000FFF00000
+00FFF0000000FFF0000000FFF0000000FFF001F000FFF001F000FFF001F000FFF001F000FFF001
+F000FFF001F000FFF001F000FFF001F000FFF001F0007FF001E0007FF803E0003FF803E0003FFC
+07C0001FFE0F80000FFFFF800007FFFE000001FFFC0000001FF00024427EC12E>I<007FE00000
+3FF000FFFFE0007FFFF000FFFFE0007FFFF000FFFFE0007FFFF000FFFFE0007FFFF000FFFFE000
+7FFFF00003FFE00001FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE0
+0000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FF
+E00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001
+FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF000
+01FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF0
+0001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00001FFF00001FFE00001FF
+F00001FFE00001FFF00001FFE00003FFF00000FFE00007FFF00000FFE0000F7FF000007FE0001F
+7FF000007FF0003E7FF800003FFC00FC7FFFE0001FFFFFF87FFFE00007FFFFE07FFFE00001FFFF
+807FFFE000003FFE007FFFE03B2E7CAD42>I<FFFFFF07FFFFE007FFFEFFFFFF07FFFFE007FFFE
+FFFFFF07FFFFE007FFFEFFFFFF07FFFFE007FFFEFFFFFF07FFFFE007FFFE03FFC0001FFC00003F
+C003FFE0000FFC00001F8001FFE0000FFC00001F0001FFE0000FFE00001F0001FFF00007FE0000
+3F0000FFF0000FFF00003E0000FFF8000FFF00007E00007FF8000FFF00007C00007FF8001FFF80
+007C00003FFC001FFF8000F800003FFC003FFFC000F800003FFE003EFFC001F800001FFE003EFF
+C001F000001FFE007EFFE003F000000FFF007C7FE003E000000FFF00FC7FF003E000000FFF80F8
+3FF007E0000007FF80F83FF007C0000007FF81F83FF80FC0000003FFC1F01FF80F80000003FFC3
+F01FFC0F80000003FFE3E00FFC1F80000001FFE3E00FFC1F00000001FFE7E00FFE3F00000000FF
+F7C007FE3E00000000FFFFC007FF3E00000000FFFF8003FF7E000000007FFF8003FF7C00000000
+7FFF8003FFFC000000003FFF0001FFF8000000003FFF0001FFF8000000003FFE0000FFF8000000
+001FFE0000FFF0000000001FFE0000FFF0000000000FFC00007FE0000000000FFC00007FE00000
+00000FF800003FE00000000007F800003FC00000000007F800003FC00000000003F000001F8000
+00000001E000000F0000004F2E7DAD56>119 D<7FFFFF801FFFFF007FFFFF801FFFFF007FFFFF
+801FFFFF007FFFFF801FFFFF007FFFFF801FFFFF00007FF80001FF0000007FFC0001FC0000003F
+FE0003F80000001FFF0007F00000000FFF0007E000000007FF800FC000000003FFC01F80000000
+03FFE03F8000000001FFF07F0000000000FFF8FE00000000007FF9FC00000000003FFFF8000000
+00003FFFF000000000001FFFE000000000000FFFC0000000000007FFC0000000000003FFC00000
+00000001FFE0000000000001FFF0000000000001FFF8000000000003FFFC000000000003FFFE00
+0000000007FFFE00000000000FEFFF00000000001FCFFF80000000003F87FFC0000000007F03FF
+E000000000FE01FFE000000001FC00FFF000000001F8007FF800000003F0007FFC00000007F000
+3FFE0000000FE0001FFF0000001FC0000FFF0000003F800007FF800000FF800007FFC000FFFFF8
+003FFFFFC0FFFFF8003FFFFFC0FFFFF8003FFFFFC0FFFFF8003FFFFFC0FFFFF8003FFFFFC03A2E
+7EAD3F>I E /Fm 5 121 df<0003FE0000000FFF8000003C01E00000F000780001C0001C000300
+00060006000003000C0000018018000000C018000000C030000000603000000060600000003060
+000000306000000030C000000018C000000018C000000018C000000018C000000018C000000018
+C000000018C000000018C000000018600000003060000000306000000030300000006030000000
+6018000000C018000000C00C000001800600000300030000060001C0001C0000F0007800003C01
+E000000FFF80000003FE000025277E9D2A>13 D<03C00FF01FF83FFC7FFE7FFEFFFFFFFFFFFFFF
+FF7FFE7FFE3FFC1FF80FF003C010107E9115>15 D<003C00E001C0018003800380038003800380
+03800380038003800380038003800380030007001C00F0001C0007000300038003800380038003
+8003800380038003800380038003800380018001C000E0003C0E297D9E15>102
+D<F0001C00070003000380038003800380038003800380038003800380038003800380018001C0
+00E0003C00E001C001800380038003800380038003800380038003800380038003800380030007
+001C00F0000E297D9E15>I<1F00308070406060E0E0E0E0E040E00060007000300018001C0033
+00718061C0E0C0E0E0E0E0E0E060E070C031C0198007000300018001C000C000E040E0E0E0E0E0
+C0C041C021801F000B257D9C12>120 D E /Fn 84 125 df<007E1F0001C1B1800303E3C00703
+C3C00E03C1800E01C0000E01C0000E01C0000E01C0000E01C0000E01C000FFFFFC000E01C0000E
+01C0000E01C0000E01C0000E01C0000E01C0000E01C0000E01C0000E01C0000E01C0000E01C000
+0E01C0000E01C0000E01C0000E01C0000E01C0007F87FC001A1D809C18>11
+D<007E0001C1800301800703C00E03C00E01800E00000E00000E00000E00000E0000FFFFC00E01
+C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01
+C00E01C00E01C07F87F8151D809C17>I<007FC001C1C00303C00703C00E01C00E01C00E01C00E
+01C00E01C00E01C00E01C0FFFFC00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E
+01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C07FCFF8151D809C17>I<003F07E00001
+C09C18000380F018000701F03C000E01E03C000E00E018000E00E000000E00E000000E00E00000
+0E00E000000E00E00000FFFFFFFC000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C
+000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C000E00E0
+1C000E00E01C000E00E01C000E00E01C007FC7FCFF80211D809C23>I<60F0F0F0F0F0F0F06060
+6060606060606060606060000000000060F0F060041E7C9D0C>33 D<6060F0F0F8F86868080808
+080808101010102020404080800D0C7F9C15>I<0080008007E01898308460824081C087C08FC0
+8FC086E080F0807E803FC01FF00FF803FC00BE008E00876087F083F083E0838082408240842088
+189007E00080008010217E9E15>36 D<00E0000001900000030800000308000007080000070800
+0007080000070800000710000007100000072000000740000003C03FE003800F00038006000380
+040005C0040009C0080010E0100030E010006070200060702000E0384000E03C4000E01C8000E0
+0F0020E0070020700780403009C0401830E18007C03E001B1F7E9D20>38
+D<60F0F8680808081010204080050C7C9C0C>I<004000800100020006000C000C001800180030
+0030007000600060006000E000E000E000E000E000E000E000E000E000E000E000E00060006000
+6000700030003000180018000C000C00060002000100008000400A2A7D9E10>I<800040002000
+100018000C000C000600060003000300038001800180018001C001C001C001C001C001C001C001
+C001C001C001C001C0018001800180038003000300060006000C000C0018001000200040008000
+0A2A7E9E10>I<60F0F0701010101020204080040C7C830C>44 D<FFE0FFE00B0280890E>I<60F0
+F06004047C830C>I<00010003000600060006000C000C000C0018001800180030003000300060
+006000C000C000C0018001800180030003000300060006000C000C000C00180018001800300030
+003000600060006000C000C00010297E9E15>I<03C00C301818300C300C700E60066006E007E0
+07E007E007E007E007E007E007E007E007E007E007E00760066006700E300C300C18180C3007E0
+101D7E9B15>I<030007003F00C700070007000700070007000700070007000700070007000700
+07000700070007000700070007000700070007000F80FFF80D1C7C9B15>I<07C01830201C400C
+400EF00FF80FF807F8077007000F000E000E001C001C00380070006000C00180030006010C0118
+0110023FFE7FFEFFFE101C7E9B15>I<07E01830201C201C781E780E781E381E001C001C001800
+30006007E00030001C001C000E000F000F700FF80FF80FF80FF00E401C201C183007E0101D7E9B
+15>I<000C00000C00001C00003C00003C00005C0000DC00009C00011C00031C00021C00041C00
+0C1C00081C00101C00301C00201C00401C00C01C00FFFFC0001C00001C00001C00001C00001C00
+001C00001C0001FFC0121C7F9B15>I<300C3FF83FF03FC020002000200020002000200023E024
+302818301C200E000E000F000F000F600FF00FF00FF00F800E401E401C2038187007C0101D7E9B
+15>I<00F0030C06040C0E181E301E300C700070006000E3E0E430E818F00CF00EE006E007E007
+E007E007E007600760077006300E300C18180C3003E0101D7E9B15>I<4000007FFF807FFF007F
+FF0040020080040080040080080000100000100000200000600000400000C00000C00001C00001
+800001800003800003800003800003800007800007800007800007800007800007800003000011
+1D7E9B15>I<03E00C301008200C20066006600660067006780C3E083FB01FE007F007F818FC30
+7E601E600FC007C003C003C003C00360026004300C1C1007E0101D7E9B15>I<03C00C30181830
+0C700C600EE006E006E007E007E007E007E0076007700F300F18170C2707C700060006000E300C
+780C78187010203030C00F80101D7E9B15>I<60F0F0600000000000000000000060F0F0600412
+7C910C>I<60F0F0600000000000000000000060F0F0701010101020204080041A7C910C>I<7FFF
+FFC0FFFFFFE00000000000000000000000000000000000000000000000000000000000000000FF
+FFFFE07FFFFFC01B0C7E8F20>61 D<0FE03038401CE00EF00EF00EF00E000C001C0030006000C0
+008001800100010001000100010001000000000000000000000003000780078003000F1D7E9C14
+>63 D<003F800000C0600003001800040004000800020010000100201F00802070808040E04040
+40C0384041C038408180382083803820838038208380382083803820838038208180382041C038
+2040C0384040E0784020709880201F0F00100000000800000004000000030001E000C01F80003F
+F0001B1D7E9C20>I<000600000006000000060000000F0000000F0000000F0000001780000017
+8000001780000023C0000023C0000023C0000041E0000041E0000041E0000080F0000080F00001
+80F8000100780001FFF80003007C0002003C0002003C0006003E0004001E0004001E000C001F00
+1E001F00FF80FFF01C1D7F9C1F>I<FFFFC00F00F00F00380F003C0F001C0F001E0F001E0F001E
+0F001E0F001C0F003C0F00780F01F00FFFE00F00780F003C0F001E0F000E0F000F0F000F0F000F
+0F000F0F000F0F001E0F001E0F003C0F0078FFFFE0181C7E9B1D>I<001F808000E06180018019
+80070007800E0003801C0003801C00018038000180780000807800008070000080F0000000F000
+0000F0000000F0000000F0000000F0000000F0000000F000000070000080780000807800008038
+0000801C0001001C0001000E000200070004000180080000E03000001FC000191E7E9C1E>I<FF
+FFC0000F00F0000F003C000F000E000F0007000F0007000F0003800F0003C00F0001C00F0001C0
+0F0001E00F0001E00F0001E00F0001E00F0001E00F0001E00F0001E00F0001E00F0001C00F0001
+C00F0003C00F0003800F0007800F0007000F000E000F001C000F007000FFFFC0001B1C7E9B20>
+I<FFFFFC0F003C0F000C0F00040F00040F00060F00020F00020F02020F02000F02000F02000F06
+000FFE000F06000F02000F02000F02000F02010F00010F00020F00020F00020F00060F00060F00
+0C0F003CFFFFFC181C7E9B1C>I<FFFFF80F00780F00180F00080F00080F000C0F00040F00040F
+02040F02000F02000F02000F06000FFE000F06000F02000F02000F02000F02000F00000F00000F
+00000F00000F00000F00000F00000F8000FFF800161C7E9B1B>I<001F808000E0618001801980
+070007800E0003801C0003801C00018038000180780000807800008070000080F0000000F00000
+00F0000000F0000000F0000000F0000000F000FFF0F0000F807000078078000780780007803800
+07801C0007801C0007800E00078007000B800180118000E06080001F80001C1E7E9C21>I<FFF3
+FFC00F003C000F003C000F003C000F003C000F003C000F003C000F003C000F003C000F003C000F
+003C000F003C000F003C000FFFFC000F003C000F003C000F003C000F003C000F003C000F003C00
+0F003C000F003C000F003C000F003C000F003C000F003C000F003C00FFF3FFC01A1C7E9B1F>I<
+FFF00F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F
+000F000F000F000F000F000F000F00FFF00C1C7F9B0F>I<1FFF00F80078007800780078007800
+7800780078007800780078007800780078007800780078007800787078F878F878F878F0F040E0
+21C01F00101D7F9B15>I<FFF03FE00F000F000F000C000F0008000F0010000F0020000F004000
+0F0080000F0100000F0200000F0400000F0E00000F1F00000F2F00000F2780000F4780000F83C0
+000F01E0000F01E0000F00F0000F00F8000F0078000F003C000F003C000F001E000F001F000F00
+1F80FFF07FF01C1C7E9B20>I<FFF8000F80000F00000F00000F00000F00000F00000F00000F00
+000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00080F00080F00080F00
+180F00180F00100F00300F00700F01F0FFFFF0151C7E9B1A>I<FF8000FF800F8000F8000F8000
+F8000BC00178000BC00178000BC001780009E002780009E002780008F004780008F004780008F0
+047800087808780008780878000878087800083C107800083C107800083C107800081E20780008
+1E207800081E207800080F407800080F4078000807807800080780780008078078000803007800
+1C03007800FF8307FF80211C7E9B26>I<FF007FC00F800E000F8004000BC0040009E0040009E0
+040008F0040008F8040008780400083C0400083C0400081E0400080F0400080F04000807840008
+07C4000803C4000801E4000801E4000800F40008007C0008007C0008003C0008003C0008001C00
+08000C001C000C00FF8004001A1C7E9B1F>I<003F800000E0E0000380380007001C000E000E00
+1C0007003C00078038000380780003C0780003C0700001C0F00001E0F00001E0F00001E0F00001
+E0F00001E0F00001E0F00001E0F00001E0700001C0780003C0780003C0380003803C0007801C00
+07000E000E0007001C000380380000E0E000003F80001B1E7E9C20>I<FFFF800F00E00F00780F
+003C0F001C0F001E0F001E0F001E0F001E0F001E0F001C0F003C0F00780F00E00FFF800F00000F
+00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F0000FFF000171C7E9B
+1C>I<FFFF00000F01E0000F0078000F003C000F001C000F001E000F001E000F001E000F001E00
+0F001C000F003C000F0078000F01E0000FFF00000F03C0000F00E0000F00F0000F0078000F0078
+000F0078000F0078000F0078000F0078000F0078100F0078100F0038100F003C20FFF01C200000
+07C01C1D7E9B1F>82 D<07E0801C1980300580700380600180E00180E00080E00080E00080F000
+00F800007C00007FC0003FF8001FFE0007FF0000FF80000F800007C00003C00001C08001C08001
+C08001C0C00180C00180E00300D00200CC0C0083F800121E7E9C17>I<7FFFFFC0700F01C0600F
+00C0400F0040400F0040C00F0020800F0020800F0020800F0020000F0000000F0000000F000000
+0F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000
+000F0000000F0000000F0000000F0000001F800003FFFC001B1C7F9B1E>I<FFF07FC00F000E00
+0F0004000F0004000F0004000F0004000F0004000F0004000F0004000F0004000F0004000F0004
+000F0004000F0004000F0004000F0004000F0004000F0004000F0004000F0004000F0004000F00
+04000700080007800800038010000180100000C020000070C000001F00001A1D7E9B1F>I<FFE0
+0FF01F0003C00F0001800F0001000F800300078002000780020003C0040003C0040003C0040001
+E0080001E0080001F0080000F0100000F0100000F830000078200000782000003C4000003C4000
+003C4000001E8000001E8000001F8000000F0000000F00000006000000060000000600001C1D7F
+9B1F>I<FFE0FFE0FF1F001F003C1E001E00180F001F00100F001F00100F001F001007801F0020
+0780278020078027802003C027804003C043C04003C043C04003E043C04001E081E08001E081E0
+8001E081E08000F100F10000F100F10000F100F100007900FA00007A007A00007A007A00003E00
+7C00003C003C00003C003C00003C003C00001800180000180018000018001800281D7F9B2B>I<
+7FF0FFC00FC03E000780180003C0180003E0100001E0200001F0600000F0400000788000007D80
+00003D0000001E0000001F0000000F0000000F8000000F80000013C0000023E0000021E0000041
+F00000C0F8000080780001007C0003003C0002001E0006001F001F003F80FFC0FFF01C1C7F9B1F
+>I<FFF007FC0F8001E00780008007C0018003C0010003E0020001F0020000F0040000F8040000
+780800007C1800003C1000001E2000001F2000000F4000000FC000000780000007800000078000
+0007800000078000000780000007800000078000000780000007800000078000007FF8001E1C80
+9B1F>I<7FFFF07C01F07001E06003C06003C0400780400F80400F00401E00001E00003C00007C
+0000780000F00000F00001E00003E00003C0100780100780100F00101F00301E00203C00203C00
+607800E0F803E0FFFFE0141C7E9B19>I<08081010202040404040808080808080B0B0F8F87878
+30300D0C7A9C15>92 D<1FC000307000783800781C00301C00001C00001C0001FC000F1C00381C
+00701C00601C00E01C40E01C40E01C40603C40304E801F870012127E9115>97
+D<FC00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C7C001D86
+001E03001C01801C01C01C00C01C00E01C00E01C00E01C00E01C00E01C00E01C00C01C01C01C01
+801E030019060010F800131D7F9C17>I<07E00C301878307870306000E000E000E000E000E000
+E00060007004300418080C3007C00E127E9112>I<003F00000700000700000700000700000700
+00070000070000070000070000070003E7000C1700180F00300700700700600700E00700E00700
+E00700E00700E00700E00700600700700700300700180F000C370007C7E0131D7E9C17>I<03E0
+0C301818300C700E6006E006FFFEE000E000E000E00060007002300218040C1803E00F127F9112
+>I<00F8018C071E061E0E0C0E000E000E000E000E000E00FFE00E000E000E000E000E000E000E
+000E000E000E000E000E000E000E000E000E007FE00F1D809C0D>I<00038003C4C00C38C01C38
+80181800381C00381C00381C00381C001818001C38000C300013C0001000003000001800001FF8
+001FFF001FFF803003806001C0C000C0C000C0C000C06001803003001C0E0007F800121C7F9215
+>I<FC00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C7C001C
+87001D03001E03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C
+03801C03801C0380FF9FF0141D7F9C17>I<18003C003C00180000000000000000000000000000
+00FC001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C00FF80091D
+7F9C0C>I<00C001E001E000C000000000000000000000000000000FE000E000E000E000E000E0
+00E000E000E000E000E000E000E000E000E000E000E000E000E000E000E060E0F0C0F1C061803E
+000B25839C0D>I<FC00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C
+00001C3FC01C0F001C0C001C08001C10001C20001C40001CE0001DE0001E70001C78001C38001C
+3C001C1C001C0E001C0F001C0F80FF9FE0131D7F9C16>I<FC001C001C001C001C001C001C001C
+001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C00
+1C00FF80091D7F9C0C>I<FC7E07E0001C838838001D019018001E01E01C001C01C01C001C01C0
+1C001C01C01C001C01C01C001C01C01C001C01C01C001C01C01C001C01C01C001C01C01C001C01
+C01C001C01C01C001C01C01C001C01C01C00FF8FF8FF8021127F9124>I<FC7C001C87001D0300
+1E03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C0380
+1C0380FF9FF014127F9117>I<03F0000E1C00180600300300700380600180E001C0E001C0E001
+C0E001C0E001C0E001C06001807003803003001806000E1C0003F00012127F9115>I<FC7C001D
+86001E03001C01801C01C01C00C01C00E01C00E01C00E01C00E01C00E01C00E01C01C01C01C01C
+01801E03001D06001CF8001C00001C00001C00001C00001C00001C00001C0000FF8000131A7F91
+17>I<03C1000C3300180B00300F00700700700700E00700E00700E00700E00700E00700E00700
+600700700700300F00180F000C370007C700000700000700000700000700000700000700000700
+003FE0131A7E9116>I<FCE01D301E781E781C301C001C001C001C001C001C001C001C001C001C
+001C001C00FFC00D127F9110>I<1F9030704030C010C010E010F8007F803FE00FF000F8803880
+18C018C018E010D0608FC00D127F9110>I<04000400040004000C000C001C003C00FFE01C001C
+001C001C001C001C001C001C001C001C101C101C101C101C100C100E2003C00C1A7F9910>I<FC
+1F801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C
+03801C07800C07800E1B8003E3F014127F9117>I<FF07E03C03801C01001C01000E02000E0200
+07040007040007040003880003880003D80001D00001D00000E00000E00000E00000400013127F
+9116>I<FF3FCFE03C0F03801C0701801C0701001C0B01000E0B82000E0B82000E1182000711C4
+000711C4000720C40003A0E80003A0E80003C0680001C0700001C0700001803000008020001B12
+7F911E>I<7F8FF00F03800F030007020003840001C80001D80000F00000700000780000F80000
+9C00010E00020E000607000403801E07C0FF0FF81512809116>I<FF07E03C03801C01001C0100
+0E02000E020007040007040007040003880003880003D80001D00001D00000E00000E00000E000
+004000004000008000008000F08000F10000F300006600003C0000131A7F9116>I<7FFC703860
+38407040F040E041C003C0038007000F040E041C043C0C380870087038FFF80E127F9112>I<FF
+FFF01401808B15>I<FFFFFFFFFF802901808B2A>I E /Fo 20 122 df<78FCFCFCFC7806067B85
+11>46 D<007F000001C1C0000780F0000F0078000E0038001C001C003C001E003C001E003C001E
+0078000F0078000F0078000F0078000F00F8000F80F8000F80F8000F80F8000F80F8000F80F800
+0F80F8000F80F8000F80F8000F80F8000F80F8000F80F8000F80F8000F80F8000F80F8000F8078
+000F0078000F0078000F0078000F003C001E003C001E003C001E001C001C000E0038000F007800
+0780F00001C1C000007F000019297EA71E>48 D<00100000700001F0000FF000FEF000F0F00000
+F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000
+F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000
+F00000F00000F00000F00000F00001F8007FFFE07FFFE013287BA71E>I<00FE0007FF800E07E0
+1803F02001F82000F840007C40007CF8007EFC007EFC003EFC003EFC003E78007E00007E00007C
+00007C0000F80000F80001F00001E00003C0000780000700000E00001C00003800007000006000
+00C0000180020300020600040C000418000410000C3FFFFC7FFFF8FFFFF8FFFFF817287DA71E>
+I<007F000003FFC0000701F0000C00F80010007C001C007C003E007E003E003E003E003E001E00
+3E000C007E0000007C0000007C00000078000000F0000000E0000001C0000007000000FF000000
+01E0000000F0000000780000003C0000003E0000001F0000001F0000001F8000001F8030001F80
+78001F80FC001F80FC001F80FC001F00F8001F0040003F0040003E0030007C001800F8000F01F0
+0003FFC000007F000019297EA71E>I<007F000001FFC00007C1E0000F0070001E0038001C003C
+003C001C0078001E0078001E00F8000F00F8000F00F8000F00F8000F00F8000F80F8000F80F800
+0F80F8000F8078000F8078001F803C001F803C001F801C002F800E004F800700CF8003810F8000
+7E0F8000000F0000000F0000000F0000001E0000001E0000001E0000003C001C003C003E007800
+3E0070003C00E0001801C0001C0780000FFE000003F8000019297EA71E>57
+D<FFFFFFFF00FFFFFFFF0007E0003F0003E000070003E000038003E000018003E000018003E000
+008003E000008003E000008003E000008003E000004003E002004003E002004003E002000003E0
+02000003E002000003E006000003E00E000003FFFE000003FFFE000003E00E000003E006000003
+E002000003E002000003E002000003E002000003E002000003E000000003E000000003E0000000
+03E000000003E000000003E000000003E000000003E000000003E000000003E000000007F00000
+00FFFFE00000FFFFE0000022297EA827>70 D<FFE0000003FFC0FFE0000003FFC007E0000003F8
+0002F0000005F00002F0000005F0000278000009F0000278000009F0000278000009F000023C00
+0011F000023C000011F000021E000021F000021E000021F000021E000021F000020F000041F000
+020F000041F0000207800081F0000207800081F0000207800081F0000203C00101F0000203C001
+01F0000203E00201F0000201E00201F0000201E00201F0000200F00401F0000200F00401F00002
+00F00401F0000200780801F0000200780801F00002003C1001F00002003C1001F00002003C1001
+F00002001E2001F00002001E2001F00002000F4001F00002000F4001F00002000F4001F0000200
+078001F0000700078001F0000F80030003F800FFF803007FFFC0FFF803007FFFC032297EA837>
+77 D<FFFF0003FFC0FFFF0003FFC007F000007E0003E00000380003E00000100001F000002000
+01F00000200001F00000200000F80000400000F80000400000FC0000C000007C00008000007C00
+008000003E00010000003E00010000003F00010000001F00020000001F00020000001F80060000
+000F80040000000F800400000007C00800000007C00800000007E00800000003E01000000003E0
+1000000001F02000000001F02000000001F02000000000F84000000000F84000000000FCC00000
+00007C80000000007C80000000003F00000000003F00000000003F00000000001E00000000001E
+00000000000C00000000000C00000000000C0000002A2A7FA82D>86 D<FFFE03FFF803FFC0FFFE
+03FFF803FFC00FE0003F80007E0007C0001F0000180003E0001F0000180003E0000F8000100003
+E0000F8000100001F0000F8000200001F0000FC000200001F0000FC000200000F8000FC0004000
+00F80013E000400000F80013E000400000FC0013E000C000007C0033F0008000007C0021F00080
+00007E0021F0008000003E0021F8010000003E0040F8010000003E0040F8010000001F0040F802
+0000001F00807C020000001F00807C020000000F80807C040000000F81003E040000000F81003E
+0400000007C1003E0800000007C2001F0800000007C2001F0800000003E2001F1000000003E400
+0F9000000003E4000F9000000001F4000FA000000001F80007E000000001F80007E000000000F8
+0007C000000000F00003C000000000F00003C00000000070000380000000006000018000000000
+60000180000000006000018000003A2A7FA83D>I<01FC00000E0780001001C0003C00E0003E00
+F0003E0078001C00780008007800000078000000780000007800007FF80003E078000F8078001F
+0078003E0078007C00780078007820F8007820F8007820F8007820F800F8207C00F8203C013C40
+1F063FC007F80F001B1A7E991E>97 D<07800000FF800000FF8000000F80000007800000078000
+000780000007800000078000000780000007800000078000000780000007800000078000000780
+00000783F000078C1C0007B0070007A0038007C003C0078001E0078001E0078000F0078000F007
+8000F8078000F8078000F8078000F8078000F8078000F8078000F8078000F0078000F0078001F0
+078001E0078001C007C003C00740078007200E0006181C000407E0001D2A7FA921>I<007E0003
+C3800700E00E00F01C00703C00783C003878003C78003CF8003CF8003CFFFFFCF80000F80000F8
+0000F80000F800007800007C00003C00043C00041E00080E001007002001C0C0007F00161A7E99
+1B>101 D<001F000070C000E1E001C3E003C3E00381C007808007800007800007800007800007
+8000078000078000078000078000FFFE00FFFE0007800007800007800007800007800007800007
+800007800007800007800007800007800007800007800007800007800007800007800007800007
+800007800007C000FFFE00FFFE00132A7FA912>I<0780FF80FF800F8007800780078007800780
+078007800780078007800780078007800780078007800780078007800780078007800780078007
+8007800780078007800780078007800780078007800780FFFCFFFC0E2A7FA911>108
+D<0783F800FF8C1C00FF900E000FA0070007A0078007C0078007C0078007800780078007800780
+078007800780078007800780078007800780078007800780078007800780078007800780078007
+80078007800780078007800780078007800780FFFCFFFCFFFCFFFC1E1A7F9921>110
+D<007F000001C1C000070070000E0038001C001C003C001E003C001E0078000F0078000F00F800
+0F80F8000F80F8000F80F8000F80F8000F80F8000F80F8000F80F8000F8078000F0078000F003C
+001E003C001E001E003C000E0038000700700001C1C000007F0000191A7E991E>I<0787C0FF98
+E0FF91F00FA1F007C1F007C0E007C0000780000780000780000780000780000780000780000780
+0007800007800007800007800007800007800007800007800007C000FFFE00FFFE00141A7F9917
+>114 D<07800780FF80FF80FF80FF800F800F8007800780078007800780078007800780078007
+800780078007800780078007800780078007800780078007800780078007800780078007800780
+07800780078007800F8007800F800380178001C027C000E047FC003F87FC1E1A7F9921>117
+D<FFF00FF8FFF00FF80F8003C0078003800780010003C0020003C0020003E0020001E0040001E0
+040000F0080000F0080000F818000078100000781000003C2000003C2000003E6000001E400000
+1E4000000F8000000F800000070000000700000007000000020000000200000004000000040000
+000400000008000070080000F8100000F8100000F8200000F0400000608000001F0000001D267F
+9920>121 D E /Fp 10 116 df<78FCFCFCFC7806067A8512>46 D<FFE00007FFC0FFF00007FF
+C003F000007C0002F80000380002FC00001000027C00001000023E00001000023E00001000021F
+00001000021F80001000020F800010000207C00010000207E00010000203E00010000203F00010
+000201F00010000200F80010000200FC00100002007C00100002007E00100002003E0010000200
+1F00100002001F80100002000F80100002000FC01000020007C01000020003E01000020003F010
+00020001F01000020000F81000020000F810000200007C10000200007E10000200003E10000200
+001F10000200001F10000200000F90000200000FD00002000007D00002000003F00002000003F0
+0002000001F00002000001F00002000000F0000200000070000700000070000F8000003000FFF8
+00003000FFF8000010002A317CB032>78 D<FFFFFF000000FFFFFFF0000007E001FC000003E000
+3E000003E0000F800003E00007C00003E00003E00003E00001E00003E00001F00003E00000F000
+03E00000F80003E00000F80003E00000F80003E00000F80003E00000F80003E00000F80003E000
+00F00003E00001F00003E00001E00003E00003C00003E00007800003E0000F000003E0003C0000
+03E001F0000003FFFF00000003E001F0000003E0007C000003E0001E000003E0000F800003E000
+07800003E00007C00003E00003E00003E00003E00003E00003E00003E00003E00003E00003E000
+03E00003E00003E00003E00003E00003E00003E00003E00003E00003E00003E00003E00003E000
+03E00803E00003E00803E00001E00803E00001E00807F00000F010FFFF80007010FFFF80003860
+000000000F802D327CB031>82 D<FFFE003FFF8001FFC0FFFE003FFF8001FFC00FE00003F80000
+7E0007C00001F000003C0007C00001F00000180003E00000F80000100003E00000F80000100003
+E00000F80000100001F00000FC0000200001F00000FC0000200001F00000FC0000200000F80001
+3E0000400000F800013E0000400000F800013E0000400000FC00033F0000C000007C00021F0000
+8000007C00021F00008000007E00021F80008000003E00040F80010000003E00040F8001000000
+3E00040F80010000001F000807C0020000001F000807C0020000001F000807C0020000000F8010
+03E0040000000F801003E0040000000F801003E0040000000FC02001F00C00000007C02001F008
+00000007C02001F00800000007E02001F80800000003E04000F81000000003E04000F810000000
+03E04000F81000000001F080007C2000000001F080007C2000000001F080007C2000000000F900
+003E4000000000F900003E4000000000F900003E40000000007E00001F80000000007E00001F80
+000000007E00001F80000000007E00001F80000000003C00000F00000000003C00000F00000000
+003C00000F00000000001800000600000000001800000600000000001800000600000042327FB0
+44>87 D<00FE00000303C0000C00E00010007000100038003C003C003E001C003E001E003E001E
+0008001E0000001E0000001E0000001E00000FFE0000FC1E0003E01E000F801E001F001E003E00
+1E003C001E007C001E00F8001E04F8001E04F8001E04F8003E04F8003E0478003E047C005E043E
+008F080F0307F003FC03E01E1F7D9E21>97 D<0F001F801F801F801F800F000000000000000000
+00000000000000000000000000000780FF80FF800F800780078007800780078007800780078007
+800780078007800780078007800780078007800780078007800780078007800FC0FFF8FFF80D30
+7EAF12>105 D<0780FF80FF800F80078007800780078007800780078007800780078007800780
+078007800780078007800780078007800780078007800780078007800780078007800780078007
+80078007800780078007800780078007800780078007800FC0FFFCFFFC0E327EB112>108
+D<0780FE001FC000FF83078060F000FF8C03C18078000F9001E2003C0007A001E4003C0007A000
+F4001E0007C000F8001E0007C000F8001E00078000F0001E00078000F0001E00078000F0001E00
+078000F0001E00078000F0001E00078000F0001E00078000F0001E00078000F0001E00078000F0
+001E00078000F0001E00078000F0001E00078000F0001E00078000F0001E00078000F0001E0007
+8000F0001E00078000F0001E00078000F0001E00078000F0001E00078000F0001E00078000F000
+1E000FC001F8003F00FFFC1FFF83FFF0FFFC1FFF83FFF0341F7E9E38>I<001FC00000F0780001
+C01C00070007000F0007801E0003C01C0001C03C0001E03C0001E0780000F0780000F0780000F0
+F80000F8F80000F8F80000F8F80000F8F80000F8F80000F8F80000F8F80000F8780000F07C0001
+F03C0001E03C0001E01E0003C01E0003C00F00078007800F0001C01C0000F07800001FC0001D1F
+7E9E21>111 D<01FC100E03301800F0300070600030E00030E00010E00010E00010F00010F800
+007E00003FF0001FFF000FFFC003FFE0003FF00001F80000F880003C80003C80001CC0001CC000
+1CE0001CE00018F00038F00030CC0060C301C080FE00161F7E9E1A>115
+D E /Fq 15 118 df<1F003F807FC0FFC0FFE0FFE0FFF0FFF07FF03FB01F300030003000300030
+003000600060006000C000C000C0018001800300060006000C001800300020000C1F77C71D>39
+D<FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00007FF800001FFF00003FF0000001
+FF80001FF00000007F80001FF00000003F80001FF00000001F80001FF00000000F80001FF00000
+000780001FF00000000780001FF00000000380001FF000000003C0001FF000000003C0001FF000
+000001C0001FF000000001C0001FF000000001C0001FF000000001C0001FF000000001C0001FF0
+00000000E0001FF000000000E0001FF000000000E0001FF00001C000E0001FF00001C00000001F
+F00001C00000001FF00001C00000001FF00001C00000001FF00001C00000001FF00001C0000000
+1FF00003C00000001FF00003C00000001FF00007C00000001FF0000FC00000001FF0003FC00000
+001FFFFFFFC00000001FFFFFFFC00000001FFFFFFFC00000001FF0003FC00000001FF0000FC000
+00001FF00007C00000001FF00003C00000001FF00003C00000001FF00001C00000001FF00001C0
+0000001FF00001C00000001FF00001C00000001FF00001C00000001FF00001C00000001FF00001
+C00000001FF00000000000001FF00000000000001FF00000000000001FF00000000000001FF000
+00000000001FF00000000000001FF00000000000001FF00000000000001FF00000000000001FF0
+0000000000001FF00000000000001FF00000000000001FF00000000000001FF00000000000001F
+F00000000000001FF00000000000001FF00000000000003FF80000000000007FFE0000000000FF
+FFFFFF80000000FFFFFFFF80000000FFFFFFFF800000003B477DC643>70
+D<FFFFFFFE01FFFFFFFCFFFFFFFE01FFFFFFFCFFFFFFFE01FFFFFFFC007FFC000000FFF800003F
+F80000007FF000001FF00000003FE000001FF00000003FE000001FF00000003FE000001FF00000
+003FE000001FF00000003FE000001FF00000003FE000001FF00000003FE000001FF00000003FE0
+00001FF00000003FE000001FF00000003FE000001FF00000003FE000001FF00000003FE000001F
+F00000003FE000001FF00000003FE000001FF00000003FE000001FF00000003FE000001FF00000
+003FE000001FF00000003FE000001FF00000003FE000001FF00000003FE000001FF00000003FE0
+00001FF00000003FE000001FF00000003FE000001FF00000003FE000001FF00000003FE000001F
+F00000003FE000001FF00000003FE000001FF00000003FE000001FFFFFFFFFFFE000001FFFFFFF
+FFFFE000001FFFFFFFFFFFE000001FF00000003FE000001FF00000003FE000001FF00000003FE0
+00001FF00000003FE000001FF00000003FE000001FF00000003FE000001FF00000003FE000001F
+F00000003FE000001FF00000003FE000001FF00000003FE000001FF00000003FE000001FF00000
+003FE000001FF00000003FE000001FF00000003FE000001FF00000003FE000001FF00000003FE0
+00001FF00000003FE000001FF00000003FE000001FF00000003FE000001FF00000003FE000001F
+F00000003FE000001FF00000003FE000001FF00000003FE000001FF00000003FE000001FF00000
+003FE000001FF00000003FE000001FF00000003FE000001FF00000003FE000001FF00000003FE0
+00001FF00000003FE000003FF80000007FF000007FFC000000FFF800FFFFFFFE01FFFFFFFCFFFF
+FFFE01FFFFFFFCFFFFFFFE01FFFFFFFC46477DC64D>72 D<FFFFF800000000001FFFFFFFFFF800
+000000001FFFFFFFFFF800000000001FFFFF007FFC00000000003FFE00003FFC00000000003FFC
+00001DFE000000000077F800001DFE000000000077F800001DFE000000000077F800001CFF0000
+000000E7F800001CFF0000000000E7F800001C7F8000000001C7F800001C7F8000000001C7F800
+001C7F8000000001C7F800001C3FC00000000387F800001C3FC00000000387F800001C1FE00000
+000707F800001C1FE00000000707F800001C1FE00000000707F800001C0FF00000000E07F80000
+1C0FF00000000E07F800001C0FF00000000E07F800001C07F80000001C07F800001C07F8000000
+1C07F800001C03FC0000003807F800001C03FC0000003807F800001C03FC0000003807F800001C
+01FE0000007007F800001C01FE0000007007F800001C00FF000000E007F800001C00FF000000E0
+07F800001C00FF000000E007F800001C007F800001C007F800001C007F800001C007F800001C00
+7F800001C007F800001C003FC000038007F800001C003FC000038007F800001C001FE000070007
+F800001C001FE000070007F800001C001FE000070007F800001C000FF0000E0007F800001C000F
+F0000E0007F800001C0007F8001C0007F800001C0007F8001C0007F800001C0007F8001C0007F8
+00001C0003FC00380007F800001C0003FC00380007F800001C0001FE00700007F800001C0001FE
+00700007F800001C0001FE00700007F800001C0000FF00E00007F800001C0000FF00E00007F800
+001C0000FF00E00007F800001C00007F81C00007F800001C00007F81C00007F800001C00003FC3
+800007F800001C00003FC3800007F800001C00003FC3800007F800001C00001FE7000007F80000
+1C00001FE7000007F800001C00000FFE000007F800001C00000FFE000007F800001C00000FFE00
+0007F800001C000007FC000007F800001C000007FC000007F800003E000007FC000007F800007F
+000003F8000007F80000FF800003F800000FFC0003FFE00001F000001FFE00FFFFFF8001F0003F
+FFFFFFFFFFFF8001F0003FFFFFFFFFFFFF8000E0003FFFFFFF58477DC65F>77
+D<FFFFFFE003FFFFFF8001FFFFF8FFFFFFE003FFFFFF8001FFFFF8FFFFFFE003FFFFFF8001FFFF
+F803FFF800000FFFE000001FFF8000FFE0000003FF80000007FE00007FC0000001FF00000001FC
+00007FC0000001FF00000000F800007FC0000001FF80000000F000003FE0000000FF80000000E0
+00003FE0000000FF80000000E000003FE0000000FF80000000E000001FF00000007FC0000001C0
+00001FF00000007FC0000001C000001FF00000007FC0000001C000001FF8000000FFE0000003C0
+00000FF8000000FFE00000038000000FF8000000FFE00000038000000FFC000001DFF000000780
+000007FC000001DFF000000700000007FC000001DFF000000700000007FE0000038FF800000F00
+000003FE0000038FF800000E00000003FE0000038FF800000E00000003FF0000078FFC00001E00
+000001FF00000707FC00001C00000001FF00000707FC00001C00000001FF00000F07FE00001C00
+000000FF80000E03FE00003800000000FF80000E03FE00003800000000FF80001E03FF00003800
+0000007FC0001C01FF000070000000007FC0001C01FF000070000000007FC0003C01FF80007000
+0000003FE0003800FF8000E0000000003FE0003800FF8000E0000000003FE0003800FF8000E000
+0000001FF00070007FC001C0000000001FF00070007FC001C0000000001FF00070007FC001C000
+0000001FF800E0003FE003C0000000000FF800E0003FE00380000000000FF800E0003FE0038000
+0000000FFC01C0001FF007800000000007FC01C0001FF007000000000007FC01C0001FF0070000
+00000007FE0380000FF80F000000000003FE0380000FF80E000000000003FE0380000FF80E0000
+00000003FF0780000FFC1E000000000001FF07000007FC1C000000000001FF07000007FC1C0000
+00000001FF0F000007FE1C000000000000FF8E000003FE38000000000000FF8E000003FE380000
+00000000FF9E000003FF380000000000007FDC000001FF700000000000007FDC000001FF700000
+000000007FFC000001FFF00000000000003FF8000000FFE00000000000003FF8000000FFE00000
+000000003FF8000000FFE00000000000001FF00000007FC00000000000001FF00000007FC00000
+000000001FF00000007FC00000000000001FE00000003FC00000000000000FE00000003F800000
+000000000FE00000003F800000000000000FC00000001F8000000000000007C00000001F000000
+0000000007C00000001F0000000000000007800000000F0000000000000003800000000E000000
+0065487EC66A>87 D<0003FE000000001FFFC00000007E03F0000000F000FC000001C0007E0000
+0380003F000007C0001F800007F0001FC0000FF0000FC0000FF8000FE0000FF8000FE0000FF800
+07F00007F00007F00007F00007F00001C00007F00000000007F00000000007F00000000007F000
+00000007F000000001FFF00000007FFFF0000003FF87F000001FF007F000007F8007F00001FE00
+07F00003F80007F00007F00007F0000FE00007F0001FC00007F0003FC00007F0003F800007F000
+7F800007F01C7F800007F01CFF000007F01CFF000007F01CFF000007F01CFF00000FF01CFF0000
+0FF01CFF00000FF01C7F80001BF01C7F800033F01C3FC00031F8381FC00061F8380FF001C0FC70
+03FC0780FFE000FFFE003FC0001FF8001F802E2F7CAD34>97 D<01FE0000000000FFFE00000000
+00FFFE0000000000FFFE000000000003FE000000000001FE000000000000FE000000000000FE00
+0000000000FE000000000000FE000000000000FE000000000000FE000000000000FE0000000000
+00FE000000000000FE000000000000FE000000000000FE000000000000FE000000000000FE0000
+00000000FE000000000000FE000000000000FE000000000000FE000000000000FE000000000000
+FE000000000000FE000000000000FE000000000000FE00FF00000000FE07FFF0000000FE1F01FC
+000000FE38003E000000FE70001F800000FEC0000FC00000FF800007E00000FF800003F00000FF
+000003F80000FE000001FC0000FE000001FC0000FE000000FE0000FE000000FE0000FE000000FF
+0000FE000000FF0000FE0000007F8000FE0000007F8000FE0000007F8000FE0000007FC000FE00
+00007FC000FE0000007FC000FE0000007FC000FE0000007FC000FE0000007FC000FE0000007FC0
+00FE0000007FC000FE0000007FC000FE0000007FC000FE0000007F8000FE0000007F8000FE0000
+00FF8000FE000000FF0000FE000000FF0000FE000000FE0000FE000001FE0000FE000001FC0000
+FE000001F80000FF000003F00000FF800007F00000FD800007E00000F9C0000F800000F8E0003F
+000000F078007E000000F01E03F8000000E00FFFE00000000001FE00000032497DC739>I<0000
+3FE0000001FFFE000007E01F80001F8003C0003E0000E0007C00007001F80000F803F80003F803
+F00003FC07F00007FC0FE00007FC1FE00007FC1FC00003F83FC00003F83FC00000E03FC0000000
+7FC00000007F800000007F80000000FF80000000FF80000000FF80000000FF80000000FF800000
+00FF80000000FF80000000FF80000000FF80000000FF800000007F800000007F800000007FC000
+00003FC00000003FC000000E1FC000000E1FE000000E0FE000001C0FF000001C07F000003803F8
+00003801F800007000FC0000E0007E0001C0001F800780000FE03E000001FFFC0000003FE00027
+2F7DAD2E>I<00007F80000003FFF000000FC0FC00003F003F00007C001F8000F8000FC001F800
+07E003F00007E007E00003F00FE00003F80FE00003F81FC00001FC1FC00001FC3FC00001FC3FC0
+0001FC7F800001FE7F800000FE7F800000FEFF800000FEFF800000FEFFFFFFFFFEFFFFFFFFFEFF
+80000000FF80000000FF80000000FF80000000FF80000000FF800000007F800000007F80000000
+7F800000007FC00000003FC00000003FC000000E1FC000000E1FE000000E0FE000001C07E00000
+1C07F000003803F000007001F800007000FC0000E0003E0003C0001F8007000007E03E000001FF
+F80000003FC000272F7DAD2E>101 D<01FE0000000000FFFE0000000000FFFE0000000000FFFE
+000000000003FE000000000001FE000000000000FE000000000000FE000000000000FE00000000
+0000FE000000000000FE000000000000FE000000000000FE000000000000FE000000000000FE00
+0000000000FE000000000000FE000000000000FE000000000000FE000000000000FE0000000000
+00FE000000000000FE000000000000FE000000000000FE000000000000FE000000000000FE0000
+00000000FE000000000000FE000000000000FE001FFFFE0000FE001FFFFE0000FE001FFFFE0000
+FE0007FFE00000FE0003FF000000FE0001FC000000FE0001F0000000FE0003E0000000FE0003C0
+000000FE000780000000FE000E00000000FE001C00000000FE007800000000FE00F000000000FE
+01E000000000FE03C000000000FE07C000000000FE0FC000000000FE1FE000000000FE3FF00000
+0000FEF3F000000000FFE3F800000000FFC1FC00000000FF80FE00000000FF00FE00000000FE00
+7F00000000FC003F80000000FC003F80000000FC001FC0000000FC000FE0000000FC000FE00000
+00FC0007F0000000FC0003F8000000FC0001F8000000FC0001FC000000FC0000FE000000FC0000
+FF000000FC00007F000000FC00007F800000FC00007FC00003FF0000FFF000FFFFFC07FFFF80FF
+FFFC07FFFF80FFFFFC07FFFF8031487DC737>107 D<01FE00FFFE00FFFE00FFFE0003FE0001FE
+0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE
+0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE
+0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE
+0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE
+0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0003FF80FFFFFEFFFF
+FEFFFFFE17487DC71C>I<01FC007F800000FFFC03FFF00000FFFC0781F80000FFFC0C007C0000
+03FC18007E000001FC30003F000000FC60003F800000FCC0001F800000FD80001F800000FD8000
+1FC00000FF00001FC00000FF00001FC00000FF00001FC00000FE00001FC00000FE00001FC00000
+FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001F
+C00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE
+00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC0
+0000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00
+001FC00000FE00001FC00000FE00001FC00000FE00001FC00003FF80007FF000FFFFFE1FFFFFC0
+FFFFFE1FFFFFC0FFFFFE1FFFFFC0322D7CAC39>110 D<01FC01F800FFFC07FE00FFFC1E1F00FF
+FC383F8003FC607FC001FC607FC000FCC07FC000FCC07FC000FD803F8000FD801F0000FF000E00
+00FF00000000FF00000000FF00000000FE00000000FE00000000FE00000000FE00000000FE0000
+0000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00
+000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE
+00000000FE00000000FE00000000FE00000000FE00000000FE00000000FF00000003FF800000FF
+FFFF8000FFFFFF8000FFFFFF8000222D7DAC28>114 D<001FF8060000FFFF0E0003F0079E0007
+8001FE000E00007E001C00003E003C00003E007800001E007800001E00F800001E00F800000E00
+F800000E00FC00000E00FC00000E00FE00000E00FF000000007FC00000007FF80000003FFFE000
+001FFFFE00000FFFFF800007FFFFE00003FFFFF00000FFFFFC00001FFFFE000001FFFE0000000F
+FF00000001FF800000007F806000001FC0E000001FC0E000000FC0F000000FC0F0000007C0F000
+0007C0F0000007C0F8000007C0F800000780FC00000780FC00000F00FE00000F00FF00001E00FF
+80003C00F9E0007800F0F803E000E03FFFC000C007FC0000222F7DAD29>I<01FE00003FC000FF
+FE001FFFC000FFFE001FFFC000FFFE001FFFC00003FE00007FC00001FE00003FC00000FE00001F
+C00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE
+00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC0
+0000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00
+001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC000
+00FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00003FC00000FE0000
+3FC00000FE00003FC00000FE00007FC000007E00007FC000007E00007FC000003F0000DFC00000
+3F00019FE000001F00031FF000000F80061FFFC00007F01C1FFFC00001FFF81FFFC000003FE01F
+E000322E7CAC39>117 D E end
+%%EndProlog
+%%BeginSetup
+%%Feature: *Resolution 300dpi
+TeXDict begin
+
+%%EndSetup
+%%Page: 0 1
+0 0 bop 206 823 a Fq(F)-9 b(unnelW)g(eb)37 b(Hac)m(k)m(er's)d(Man)m(ual)603
+1151 y Fp(Ross)21 b(N.)g(Williams)519 1343 y Fo(V1.0)e(for)h(F)-5
+b(unnelW)g(eb)20 b(V3.0)725 1536 y(Ma)n(y)g(1992)p eop
+%%Page: 1 2
+1 1 bop 177 2597 1772 2 v 177 2675 a Fn(Cop)o(yrigh)o(t)384
+2674 y(c)372 2675 y Fm(\015)14 b Fn(1992)e(Ross)i(N.)g(William)o(s.)177
+2750 y(P)o(ermission)j(is)g(gran)o(ted)g(to)h(mak)o(e)d(and)j(distribute)g(v)
+o(erbatim)d(copies)j(of)f(this)h(man)o(ual)c(pro)o(vided)k(that)f(the)177
+2800 y(cop)o(yrigh)o(t)d(notice)g(and)g(this)g(p)q(ermission)e(notice)j(are)f
+(preserv)o(ed)i(on)e(all)e(copies.)p 177 2835 V 1053 2940 a(1)p
+eop
+%%Page: 2 3
+2 2 bop 1053 2940 a Fn(2)p eop
+%%Page: 3 4
+3 3 bop 177 397 a Fl(Con)m(ten)m(ts)177 679 y Fk(Preface)1592
+b(5)177 794 y(Ac)o(kno)o(wledgemen)o(ts)1348 b(7)177 909 y(Presen)o(tation)12
+b(Notes)1347 b(9)177 1024 y(1)38 b(F)l(unnelW)l(eb)14 b(Design)1268
+b(11)239 1098 y Fn(1.1)42 b(Motiv)n(ation)12 b(for)i(F)m(unnelW)m(eb)k
+Fj(:)j(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)
+h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(11)239
+1172 y(1.2)42 b(Inden)o(tation)30 b Fj(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(12)239
+1245 y(1.3)42 b(Review)14 b(of)f(F)m(unnelW)m(eb)g(Syn)o(tax)28
+b Fj(:)20 b(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(14)335
+1319 y(1.3.1)46 b(Review)13 b(of)h(Macro)g(De\014nition)f(Syn)o(tax)k
+Fj(:)j(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)
+g(:)h(:)f(:)g(:)61 b Fn(14)335 1393 y(1.3.2)46 b(Review)13
+b(of)h(Macro)g(Call)e(Syn)o(tax)26 b Fj(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)
+h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(16)335 1467 y(1.3.3)46 b(Review)13 b(of)h(P)o(arameterized)g(Macro)g
+(Call)f(Syn)o(tax)42 b Fj(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)61 b Fn(16)239 1540 y(1.4)42 b(Do)q(cumen)o(t)13
+b(Structuring)27 b Fj(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)61 b Fn(16)239 1614 y(1.5)42 b(Discussion)14 b(of)f(Some)g
+(Miscellaneous)h(Issues)30 b Fj(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)
+h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(18)239
+1688 y(1.6)42 b(Automated)13 b(Regression)h(T)m(esting)38 b
+Fj(:)20 b(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(18)239 1761
+y(1.7)42 b(Command)11 b(Line)i(In)o(terface)j Fj(:)k(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(18)239 1835 y(1.8)42 b(File)13
+b(Name)g(Managemen)o(t)31 b Fj(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)61 b Fn(19)335 1909 y(1.8.1)46 b(Filename)12 b(Extensions)24
+b Fj(:)c(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(20)335
+1982 y(1.8.2)46 b(Filename)12 b(Inheritance)k Fj(:)k(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)61 b Fn(20)335 2056 y(1.8.3)46 b(P)o(ortable)14
+b(Structure)h(of)f(File)f(Names)20 b Fj(:)g(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(21)239 2130 y(1.9)42 b(Sp)q(ecifying)13 b(Constrain)o(ts)i(on)e(the)i
+(Num)o(b)q(er)e(of)g(Instan)o(tiations)38 b Fj(:)20 b(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(22)239 2204 y(1.10)21
+b(The)14 b(Relationship)f(Bet)o(w)o(een)i(Do)q(cumen)o(t)e(Structure)j(and)e
+(Macro)g(Structure)19 b Fj(:)h(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(23)239 2277 y(1.11)21 b(Diagnostic)13 b(Messages)32 b
+Fj(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(25)239 2351 y(1.12)21 b(Summary)31 b Fj(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(25)177 2466 y Fk(2)38 b(F)l(unnelW)l(eb)14 b(Implemen)o(tati)o(on)1077
+b(27)239 2540 y Fn(2.1)42 b(In)o(tro)q(duction)13 b Fj(:)20
+b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)61 b Fn(27)239 2614 y(2.2)42 b(History)14 b(of)f(F)m(unnelW)m(eb)g
+(Implemen)o(tations)40 b Fj(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)
+f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(27)239
+2687 y(2.3)42 b(Wh)o(y)13 b(F)m(unnelW)m(eb)h(W)m(asn't)e(Used)j(to)f(W)m
+(rite)g(Itself)35 b Fj(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(28)239 2761 y(2.4)42
+b(Co)q(ding)13 b(St)o(yle)38 b Fj(:)21 b(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(28)239 2835
+y(2.5)42 b(Use)15 b(of)e(Memory)27 b Fj(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)
+g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(29)1053 2940
+y(3)p eop
+%%Page: 4 5
+4 4 bop 239 42 a Fn(2.6)42 b(The)14 b(Heap)30 b Fj(:)20 b(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(29)239 116 y(2.7)42 b(The)14 b(Stac)o(k)24 b Fj(:)c(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(30)239 191 y(2.8)42 b(Static)14 b(V)m(ariables)k Fj(:)i(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b
+Fn(30)239 266 y(2.9)42 b(Implemen)o(ting)11 b(T)m(ext)j(Inden)o(tation)25
+b Fj(:)20 b(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(30)177
+382 y Fk(3)38 b(F)l(unnelW)l(eb)14 b(Mo)q(di\014cation)1145
+b(35)239 457 y Fn(3.1)42 b(In)o(tro)q(duction)13 b Fj(:)20
+b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)61 b Fn(35)239 531 y(3.2)42 b(The)14 b(Danger)g(of)f(Mo)q(difying)g
+(Languages)26 b Fj(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(35)239
+606 y(3.3)42 b(Authorit)o(y)14 b(vs)g(User)h(Securit)o(y)43
+b Fj(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b
+Fn(36)239 681 y(3.4)42 b(What)13 b(I)h(W)m(an)o(t)f(to)h(Protect)25
+b Fj(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(37)239 756 y(3.5)42 b(Mo)q(difying)12 b(the)j(Man)o(uals)c
+Fj(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(38)239 830 y(3.6)42 b(Ho)o(w)13 b(Cop)o(yrigh)o(t)g(La)o(w)h(W)m(orks)37
+b Fj(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b
+Fn(38)239 905 y(3.7)42 b(Managemen)o(t)13 b(of)g(the)h(O\016cial)f(F)m
+(unnelW)m(eb)f Fj(:)21 b(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(39)239 980
+y(3.8)42 b(A)14 b(GNU)g(V)m(ersion?)29 b Fj(:)20 b(:)g(:)h(:)f(:)g(:)h(:)f(:)
+g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(41)239 1054
+y(3.9)42 b(Summary)31 b Fj(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(41)177 1171
+y Fk(4)38 b(F)l(unnelW)l(eb)14 b(F)l(uture)1270 b(43)239 1245
+y Fn(4.1)42 b(Do)q(cumen)o(tation)25 b Fj(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(43)239 1320
+y(4.2)42 b(Command)11 b(Line)i(In)o(terface)j Fj(:)k(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(43)239 1395 y(4.3)42 b(Shell)13
+b(In)o(terpreter)42 b Fj(:)20 b(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)61 b Fn(43)239 1469 y(4.4)42 b(Language)13
+b(Design)28 b Fj(:)20 b(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)61 b Fn(44)239 1544 y(4.5)42 b(Scanner/Mapp)q(er)34
+b Fj(:)20 b(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)61 b Fn(44)239 1619 y(4.6)42 b(P)o(arser)29 b Fj(:)20 b(:)h(:)f(:)g(:)h(:)
+f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(45)239 1694 y(4.7)42 b(Analyser)16 b Fj(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(45)239 1768 y(4.8)42 b(T)m(angle)21 b Fj(:)f(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(45)239 1843 y(4.9)42 b(W)m(ea)o(v)o(e)26 b Fj(:)20 b(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(45)239 1918 y(4.10)21 b(Lister)39 b Fj(:)20 b(:)h(:)f(:)g(:)h(:)f(:)g(:)
+g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(46)239 1993 y(4.11)21 b(Diagnostics)32 b Fj(:)20 b(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(47)239 2067 y(4.12)21 b(Sp)q(eed)37 b Fj(:)20 b(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(47)239 2142 y(4.13)21 b(Correctness)32 b Fj(:)20 b(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(47)239 2217 y(4.14)21 b(T)m(est)14 b(Suite)25 b Fj(:)20
+b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)61 b Fn(47)239 2291 y(4.15)21 b(Mac)o(hine-Sp)q(eci\014c)15
+b(Changes)29 b Fj(:)21 b(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(48)239 2366 y(4.16)21 b(Summary)31 b Fj(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fn(48)177 2482 y Fk(A)26 b(GNU)16 b(General)e(Public)f(License)h(V)l
+(ersion)g(2)841 b(49)177 2599 y(B)28 b(References)1436 b(57)177
+2715 y(Index)1605 b(57)1053 2940 y Fn(4)p eop
+%%Page: 5 6
+5 5 bop 177 399 a Fl(Preface)177 639 y Fn(This)15 b(man)o(ual)d(is)j(for)f
+(hac)o(k)o(ers!)22 b(An)o(y)o(one)15 b(who)g(w)o(an)o(ts)f(to)h(bash,)g
+(diddle,)f(frob,)g(grind,)h(mangle,)d(patc)o(h,)j(p)q(ok)o(e,)177
+689 y(toggle,)e(t)o(widdle,)g(zap,)h(or)f(generally)h(hac)o(k)g(F)m(unnelW)m
+(eb)f(should)h(at)g(least)g(tak)o(e)g(a)f(lo)q(ok)g(at)h(this)g(man)o(ual.)
+177 764 y(This)g(do)q(cumen)o(t)f(has)h(b)q(een)h(created)h(to)e(serv)o(e)h
+(t)o(w)o(o)e(purp)q(oses:)228 880 y(1.)20 b(T)m(o)12 b(act)h(as)f(a)h(rep)q
+(ository)g(for)f(sp)q(eci\014c)j(design)d(and)h(implemen)o(tatio)o(n)d
+(information)g(not)i(appropriate)h(to)281 930 y(b)q(e)h(included)g(in)g
+(program)e(commen)o(ts.)228 1013 y(2.)20 b(T)m(o)13 b(guide)h(those)g(in)o
+(terested)i(in)d(mo)q(difying)e(the)k(program.)177 1129 y(As)e(a)g(result,)g
+(this)g(do)q(cumen)o(t)f(has)h(gro)o(wn)g(in)f(\014ts)i(and)e(starts.)19
+b(This)13 b(man)o(ual)d(is)j(not)f(a)h(particularly)f(p)q(olished)177
+1179 y(or)h(w)o(ell-balanced)e(do)q(cumen)o(t)h(but)h(it)f(should)h(b)q(e)g
+(of)f(assistance)h(to)g(those)g(\(including)f(m)o(yself)s(\))f(in)o(v)o(olv)o
+(ed)g(with)177 1229 y(mo)q(difying)g(F)m(unnelW)m(eb.)177 1328
+y Fk(Ross)k(N.)i(Williams)177 1378 y(Adelaide,)d(Australia)177
+1428 y(Ma)o(y)i(1992)1053 2940 y Fn(5)p eop
+%%Page: 6 7
+6 6 bop 1053 2940 a Fn(6)p eop
+%%Page: 7 8
+7 7 bop 177 399 a Fl(Ac)m(kno)m(wledgemen)m(ts)177 645 y Fn(Man)o(y)16
+b(thanks)h(to)g Fk(Da)o(vid)h(Hulse)d Fn(\()p Fi(dave@cs.adelaide.e)o(du.au)o
+Fn(\))f(for)j(translating)f(the)h(original)e(v)o(ersion)177
+695 y(of)g(F)m(unnelW)m(eb)g(\(F)m(unnelW)m(eb)h(V1\))f(from)f(Ada)i(in)o(to)
+f(C)g(and)h(getting)f(it)h(to)f(w)o(ork)g(on)h(Unix)f(and)h(a)f(PC.)g(The)177
+744 y(C)i(co)q(de)h(written)f(b)o(y)g(Da)o(vid)e(\(F)m(unnelW)m(eb)i(V2\))f
+(formed)g(the)h(basis)g(of)g(F)m(unnelW)m(eb)f(V3,)h(but)g(w)o(as)g(en)o
+(tirely)177 794 y(rewritten)h(during)f(the)h(in)o(tensiv)o(e)f(re\014nemen)o
+(t)h(and)e(feature-injection)i(p)q(erio)q(d)f(leading)f(up)h(to)g(this)h
+(release)177 844 y(\(F)m(unnelW)m(eb)12 b(V3)g(is)f(ab)q(out)h(three)h(times)
+e(the)i(size)g(of)e(F)m(unnelW)m(eb)g(V2\).)18 b(Nev)o(ertheless,)c(without)e
+(this)g(imp)q(or-)177 894 y(tan)o(t)h(\014rst)i(translation)d(step,)i(I)g(w)o
+(ould)e(probably)h(not)g(ha)o(v)o(e)g(found)g(the)h(motiv)n(ation)d(to)i(dev)
+o(elop)g(F)m(unnelW)m(eb)177 944 y(to)h(its)g(presen)o(t)h(state.)177
+1018 y(Thanks)f(go)e(to)h Fk(Simon)h(Hac)o(k)o(ett)e Fn(\()p
+Fi(simon@internode.com)o(.au)p Fn(\))e(of)j(In)o(terno)q(de)h(Systems)f(Pt)o
+(y)h(Ltd)f(for)g(the)177 1068 y(use)18 b(of)e(his)h(Sun,)h(Mac,)g(and)e(PC,)h
+(for)g(assistance)h(in)f(p)q(orting)f(F)m(unnelW)m(eb)h(to)g(the)g(Sun)h(and)
+e(PC,)h(and)g(for)177 1118 y(helpful)c(discussions.)177 1193
+y(Thanks)j(go)g(to)f Fk(Jerem)o(y)i(Begg)f Fn(\()p Fi(jeremy@vsm.com.au)o
+Fn(\))d(of)j(VSM)g(Soft)o(w)o(are)f(Services)j(for)d(the)i(use)g(of)e(his)177
+1243 y(V)-5 b(AX,)14 b(and)g(for)g(assistance)h(with)e(the)i(VMS-sp)q
+(eci\014c)g(co)q(de.)177 1317 y(Thanks)50 b(to)h Fk(Barry)57
+b(Dwy)o(er)50 b Fn(\()p Fi(dwyer@cs.adelaid)o(e.edu)o(.au)p
+Fn(\))d(and)j Fk(Roger)57 b(Brissenden)177 1367 y Fn(\()p Fi
+(rjb@koala.harvard.e)o(du)p Fn(\))15 b(for)j(trying)g(out)g(F)m(unnelW)m(eb)g
+(V)m(ersion)g(1)g(in)g(1987)f(and)h(pro)o(viding)f(v)n(aluable)177
+1417 y(feedbac)o(k.)177 1492 y(Thanks)d(to)g(Donald)f(Kn)o(uth)h(for)f
+(establishing)h(the)g(idea)g(of)f(literate)h(programming)d(in)i(the)i
+(\014rst)f(place.)177 1591 y Fk(Ross)h(N.)i(Williams)177 1641
+y(Adelaide,)d(Australia)177 1691 y(Ma)o(y)i(1992)1053 2940
+y Fn(7)p eop
+%%Page: 8 9
+8 8 bop 1053 2940 a Fn(8)p eop
+%%Page: 9 10
+9 9 bop 177 399 a Fl(Presen)m(tation)42 b(Notes)177 639 y Fk(References:)e
+Fn(All)24 b(references)29 b(are)c(set)i(in)e(b)q(old)f(and)i(are)f(cited)h
+(in)f(square)h(brac)o(k)o(ets)h(in)e(the)h(form)177 689 y Fk([)p
+Fj(<)p Fh(\014rstauthor)p Fj(><)p Fh(ye)n(ar)p Fj(>)p Fk(])p
+Fn(.)19 b(All)13 b(references)j(cited)e(in)f(the)g(text)h(app)q(ear)g(in)f
+(the)h(reference)h(list)e(and)g(the)h(index.)177 764 y Fk(Sp)q(ecial)d
+(terms:)17 b Fn(New)12 b(or)f(imp)q(ortan)o(t)f(terminology)f(has)i(b)q(een)i
+(set)f(in)f(b)q(old)g(face)h(and)f(app)q(ears)h(in)f(the)h(index.)177
+839 y Fk(T)o(yp)q(esetting:)69 b Fn(This)41 b(do)q(cumen)o(t)f(w)o(as)g
+(prepared)i(b)o(y)e(the)h(author)f(using)h(Andrew)g(T)m(rev)o(or-)177
+888 y(ro)o(w's)29 b(\()p Fi(akt150@cscgpo.anu.e)o(du.au)o Fn(\))e(implemen)o
+(tatio)o(n)g(\(OzT)m(eX\))j(of)f(the)h(T)1558 897 y(E)1581
+888 y(X/L)1644 883 y Fg(a)1663 888 y Fn(T)1686 901 y(E)1709
+888 y(X)p Fk([Kn)o(uth84])177 938 y([Lamp)q(ort86])13 b Fn(t)o(yp)q(esetting)
+i(system)e(running)h(on)g(a)f(Macin)o(tosh-SE.)177 1013 y Fk(Graphics:)i
+Fn(All)c(diagrams)e(ha)o(v)o(e)i(b)q(een)i(constructed)g(out)e(of)g(text)h
+(using)f(the)h(L)1431 1008 y Fg(a)1450 1013 y Fn(T)1473 1025
+y(E)1496 1013 y(X)f Fi(verbatim)f Fn(en)o(vironmen)o(t)177
+1063 y(so)17 b(as)f(to)h(allo)o(w)e(this)h(do)q(cumen)o(t)g(to)h(b)q(e)g
+(disseminated)e(electronically)i(and)f(prin)o(ted)h(using)f(L)1695
+1058 y Fg(a)1714 1063 y Fn(T)1737 1075 y(E)1761 1063 y(X)g(without)177
+1112 y(access)g(to)e(the)g(author's)g(dra)o(wing)f(to)q(ols.)177
+1187 y Fk(Kno)o(wn)g(t)o(yp)q(esetting)d(problems:)k Fn(While)d(ev)o(ery)h
+(attempt)f(has)h(b)q(een)g(made)e(to)i(giv)o(e)f(a)g(go)q(o)q(d)g(presen)o
+(tation)177 1237 y(within)h(the)h(time)e(a)o(v)n(ailable,)f(some)i(shortcuts)
+i(ha)o(v)o(e)e(had)g(to)g(b)q(e)h(tak)o(en.)18 b(In)13 b(particular,)f(the)h
+(author)f(has)h(b)q(een)177 1287 y(unable)h(to)g(w)o(ork)f(out)h(ho)o(w)g(to)
+f(get)h(L)754 1282 y Fg(a)773 1287 y Fn(T)796 1299 y(E)820
+1287 y(X)g(to)g(suppress)h(blank)f(pages)g(at)f(the)i(start)f(of)g(c)o
+(hapters.)1053 2940 y(9)p eop
+%%Page: 10 11
+10 10 bop 1042 2940 a Fn(10)p eop
+%%Page: 11 12
+11 11 bop 177 381 a Ff(Chapter)34 b(1)177 617 y Fl(F)-10 b(unnelW)g(eb)41
+b(Design)177 861 y Fn(This)18 b(c)o(hapter)i(con)o(tains)e(notes)h(on)f(the)h
+(design)f(of)g(F)m(unnelW)m(eb.)31 b(These)19 b(notes)g(w)o(ere)h(not)e
+(created)i(\\from)177 911 y(scratc)o(h",)d(as)f(the)g(original)e(v)o(ersion)i
+(of)f(F)m(unnelW)m(eb)g(\()p Fk(F)l(unnelW)l(eb)h(V1)p Fn(\))g(w)o(as)g
+(designed)g(and)g(constructed)177 961 y(in)d(a)h(h)o(urry)f(late)h(in)f
+(1986,)f(and)h(no)h(design)f(notes)i(w)o(ere)f(ev)o(er)h(recorded.)k(These)c
+(notes)f(are)g(in)f(fact)h(the)g(result)177 1011 y(of)g(a)h(complete)f
+(review)h(of)f(the)h(F)m(unnelW)m(eb)f(design)h(that)g(to)q(ok)f(place)h(in)f
+(late)h(1991)e(as)i(part)g(of)f(the)h(pro)q(cess)177 1061 y(of)e(upgrading)h
+(it)f(for)h(public)f(release.)177 1139 y(Throughout)f(the)h(design)g(pro)q
+(cess)h(I)f(tried)g(to)f(stic)o(k)g(to)h(the)g(principles)g(of)e(simplicit)o
+(y)f(and)i(clarit)o(y)m(.)17 b(As)c(a)f(rule,)177 1188 y(it)17
+b(w)o(as)h(considered)h(more)e(imp)q(ortan)o(t)f(that)i(a)f(feature)h(b)q(e)h
+(simple)d(and)h(not)h(allo)o(w)e(the)i(user)h(to)f(outsmart)177
+1238 y(himself)d(than)h(it)g(w)o(as)g(for)g(the)h(feature)f(to)h(b)q(e)f
+(particularly)g(crisp.)26 b(F)m(or)15 b(example,)g(the)i(F)m(unnelW)m(eb)f
+(macro)177 1288 y(calling)d(syn)o(tax)g(is)h(not)g(as)g(crisp)g(as)g(the)h(C)
+f(syn)o(tax,)f(but)h(is)g(more)f(visible.)177 1366 y(T)m(o)i(some)f(exten)o
+(t)i(the)g(design)f(review)h(w)o(as)f(in\015uenced)i(b)o(y)e(the)h
+(requiremen)o(ts)f(of)g(bac)o(kw)o(ard)g(compatibilit)o(y)l(.)177
+1416 y(During)d(the)h(review)g(it)g(w)o(as)f(hard)h(not)f(to)h(think)f(ab)q
+(out)g(all)g(the)h(source)h(\014les)e(in)h(F)m(unnelW)m(eb)f(V1)g(format)f
+(that)177 1466 y(I)j(ha)o(v)o(e)f(written)i(o)o(v)o(er)f(the)g(y)o(ears)g
+(that)g(w)o(ould)f(ha)o(v)o(e)h(to)f(b)q(e)i(con)o(v)o(erted)g(w)o(ere)f(I)g
+(to)g(signi\014can)o(tly)e(deviate)j(from)177 1516 y(the)h(old)f(input)g
+(language.)22 b(Luc)o(kily)14 b(it)h(turned)i(out)e(that)h(there)g(w)o(as)g
+(little)e(clash)i(b)q(et)o(w)o(een)h(these)g(in)o(terests,)177
+1565 y(and)g(the)h(resulting)f(design)g(is)g(b)q(oth)g(clean)g(and)g(do)q(es)
+h(not)f(require)h(m)o(uc)o(h)e(con)o(v)o(ersion)h(of)f(old)h(source)h
+(\014les.)177 1615 y(The)f(main)d(revision)i(is)h(in)f(the)h(do)q(cumen)o(t)e
+(structuring)j(facilit)o(y)m(.)23 b(F)m(unnelW)m(eb)16 b(V1)g(had)g(just)h(t)
+o(w)o(o)f(lev)o(els)g(of)177 1665 y(heading)d(indicated)g(b)o(y)g
+Fi(@*@*)g Fn(\(for)g(ma)r(jor)e(headings\))j(and)f Fi(@*)g
+Fn(\(for)g(minor)e(headings\).)18 b(This)13 b(sc)o(heme)h(\(whic)o(h)177
+1715 y(w)o(as)i(copied)g(from)e(Kn)o(uth's)i(W)m(eb\))f(has)h(b)q(een)h
+(replaced)g(b)o(y)e(a)h(hierarc)o(hical)f(sc)o(heme)h(of)f(\014v)o(e)h
+(heading)g(lev)o(els)177 1765 y(lev)o(els)e(\()p Fi(@A)p Fj(:)7
+b(:)g(:)n Fi(@E)p Fn(\).)177 1843 y(This)18 b(c)o(hapter)h(is)e(rather)i
+(unstructured,)i(acting)c(as)h(it)g(has,)g(mainly)e(as)i(a)f(dumping)f
+(ground)i(for)f(random)177 1893 y(ideas)d(ab)q(out)g(F)m(unnelW)m(eb.)177
+2066 y Fe(1.1)70 b(Motiv)l(ation)22 b(for)i(F)-6 b(unnelW)g(eb)177
+2186 y Fn(During)16 b(1986,)f(I)h(w)o(as)g(exp)q(osed)i(to)e(Donald)f(Kn)o
+(uth's)i Fi(WEB)e Fn(literate)i(programmi)o(ng)c(system)j(in)g(the)h(form)d
+(of)177 2236 y(Jon)j(Ben)o(tley's)h Fh(Pr)n(o)n(gr)n(amming)f(Pe)n(arls)f
+Fn(column)f(in)h Fh(Communic)n(ations)i(of)g(the)g(A)o(CM)7
+b Fk([Ben)o(tley86])p Fn(.)1825 2221 y Fd(1)1868 2236 y Fn(This)177
+2286 y(prompted)17 b(me)f(to)h(obtain)g(a)g(cop)o(y)g(of)g(the)h(rep)q(ort)g
+(on)f(the)h(W)m(eb)f(system)p Fk([Kn)o(uth83])f Fn(and)h(to)g(try)h(out)f
+(the)177 2336 y(program)12 b(whic)o(h)i(had)g(b)q(een)h(installed)e(on)h(the)
+g(lo)q(cal)f(V)m(axen.)177 2414 y(W)m(eb)h(w)o(as)f(the)i(b)q(est)f(system)g
+(that)g(I)f(had)h(seen)h(for)e(pro)q(ducing)h(prin)o(ted)g(and)g(online,)f
+(inline)f(do)q(cumen)o(tation.)177 2464 y(T)m(o)k(me)g(the)i(most)e
+(extraordinary)h(asp)q(ect)h(of)f(the)g(system)g(w)o(as)g(its)g(success)j
+(despite)e(the)f(fact)g(that)g(it)g(had)177 2514 y(b)q(een)h(built)e(in)o(to)
+h(the)g(horribly)g(an)o(tiquated)f(\014le/batc)o(h)h(pro)q(cessing)h(systems)
+f(that)g(w)o(e)h(all)d(kno)o(w)i(and)f(lo)o(v)o(e)177 2563
+y(\(and)f(use\).)20 b(I)15 b(had)f(imagined)e(sophisticated)j(do)q(cumen)o
+(tation)f(systems)g(b)q(efore)h(this)g(time,)e(but)i(had)f(alw)o(a)o(ys)177
+2613 y(assumed)i(that)h(they)g(w)o(ould)f(b)q(e)i(parts)f(of)f(complex)f
+(programming)e(en)o(vironmen)o(ts.)26 b(Kn)o(uth)17 b(sho)o(w)o(ed)g(that,)
+177 2663 y(to)f(some)e(exten)o(t,)j(it)e(can)h(b)q(e)g(done)g(using)f(1960s)g
+(soft)o(w)o(are)h(tec)o(hnology)f(\(excluding)h(the)g(1980s)f(t)o(yp)q
+(esetting)177 2713 y(tec)o(hnology\).)j(This)c(w)o(as)g(exciting.)p
+177 2757 709 2 v 223 2783 a Fc(1)241 2795 y Fb(As)g(it)g(happ)q(ens,)e(this)h
+(w)o(as)h(somewhat)f(of)g(a)h(luc)o(ky)e(encoun)o(ter.)20 b(I)14
+b(had)f(only)g(just)g(joined)f(the)h(A)o(CM)i(and)e(the)h(Ma)o(y)f(1986)177
+2835 y(issue)e(of)g(CA)o(CM)j(in)d(whic)o(h)g(the)f(column)g(app)q(eared)f(w)
+o(as)j(the)e(\014rst)h(issue)g(I)g(receiv)o(ed.)1042 2940 y
+Fn(11)p eop
+%%Page: 12 13
+12 12 bop 177 42 a Fn(The)16 b(W)m(eb)g(system)f(w)o(as)h(en)o(ticing)f(and)h
+(promising)d(but)j(to)g(me)e(su\013ered)k(from)c(man)o(y)g(dra)o(wbac)o(ks,)i
+(man)o(y)d(of)177 91 y(whic)o(h)j(Kn)o(uth)g(had)g(promoted)f(as)h(adv)n(an)o
+(tages.)23 b(The)17 b(follo)o(wing)c(highly)i(sub)r(jectiv)o(e)i(list)e(of)g
+(disadv)n(an)o(tages)177 141 y(formed)e(a)g(springb)q(oard)h(for)g(the)g
+(construction)h(of)f(F)m(unnelW)m(eb.)239 247 y Fm(\017)21
+b Fn(W)m(eb)13 b(can)i(only)e(pro)q(cess)i(P)o(ascal)f(programs.)239
+327 y Fm(\017)21 b Fn(W)m(eb)16 b(can)h(pro)q(duce)h(only)e(one)h(output)f
+(\014le.)27 b(In)16 b(man)o(y)f(instances)j(it)e(is)g(desirable)h(to)g
+(generate)h(more)281 377 y(than)g(one)h(output)g(\014le.)31
+b(F)m(or)18 b(example,)g(when)h(programming)c(in)j(Ada,)h(it)f(is)g
+(desirable)h(to)f(write)h(a)281 427 y(pac)o(k)n(age)13 b(sp)q(eci\014cation)i
+(and)f(a)f(pac)o(k)n(age)h(b)q(o)q(dy)g(together)h(in)e(the)i(same)e(\014le.)
+239 507 y Fm(\017)21 b Fn(W)m(eb)15 b(enforces)h(Kn)o(uth's)f(individual)e
+(st)o(yle)j(of)e(inden)o(tation.)21 b(W)m(eb)15 b(supplies)g(commands)e(to)i
+(o)o(v)o(er-ride)281 557 y(the)h(automatic)e(inden)o(tation)h(but)g(it)g(is)h
+(an)f(uphill)f(battle)i(and)f(the)h(co)q(de)h(b)q(ecomes)e(clogged)h(up)f
+(with)281 606 y(format)d(directiv)o(es.)239 686 y Fm(\017)21
+b Fn(W)m(eb)f(do)q(es)i(not)f(cater)g(for)g(non-standard)g(P)o(ascal)f
+(programs.)38 b(In)21 b(particular,)g(all)f(iden)o(ti\014ers)h(are)281
+736 y(truncated)15 b(to)f(ab)q(out)g(eigh)o(t)f(c)o(haracters.)239
+816 y Fm(\017)21 b Fn(W)m(eb)13 b(formats)g(the)h(program)f(output)h(\014le)g
+(in)o(to)f(a)g(form)g(that)g(is)h(unreadable)g(to)g(h)o(umans.)239
+896 y Fm(\017)21 b Fn(W)m(eb)11 b(do)q(es)i(not)f(pro)o(vide)g(an)f(include)h
+(facilit)o(y)m(.)j(This)d(w)o(as)g(considered)h(a)f(feature)g(essen)o(tial)h
+(for)e(supp)q(ort-)281 946 y(ing)i(macro)g(libraries.)239 1026
+y Fm(\017)21 b Fn(W)m(eb)13 b(pro)o(vides)h(macros)f(with)g(at)h(most)e(one)i
+(parameter.)k(Kn)o(uth)c(describ)q(es)i(a)d(hac)o(k)h(that)g(can)g(extract)
+281 1076 y(a)d(m)o(ultiple)f(parameter)h(macro)g(facilit)o(y)f(from)g(a)h
+(single)g(parameter)h(one,)g(but)g(it)f(is)g(hardly)h(satisfactory)m(.)239
+1156 y Fm(\017)21 b Fn(W)m(eb)13 b(do)q(es)i(not)f(pro)o(vide)g
+(conditionals.)177 1262 y(Most)19 b(of)e(these)j(ob)r(jections)f(b)q(oiled)e
+(do)o(wn)h(to)g(t)o(w)o(o)g(p)q(oin)o(ts:)27 b(that)18 b(W)m(eb)g(is)g(far)g
+(to)q(o)g(sp)q(ecialized,)i(and)e(that)177 1312 y(Kn)o(uth's)h(\\Occam's)f
+(Razor")h(had)g(cut)g(to)q(o)g(far.)33 b(What)18 b(I)h(w)o(an)o(ted)g(w)o(as)
+g(a)f(do)q(cumen)o(tation)g(system)h(that)177 1362 y(emplo)o(y)o(ed)11
+b(all)g(the)i(same)f(principles)h(as)f(W)m(eb)g(but)h(w)o(as)g(far)f(more)f
+(general.)18 b(The)13 b(result)g(w)o(as)f(F)m(unnelW)m(eb)g(V1,)177
+1412 y(whic)o(h)i(can)g(pro)q(cess)i(programs)c(in)h(an)o(y)h(language)f(or)h
+(an)o(y)f(com)o(bination)e(of)i(languages)h(at)f(the)i(cost)f(of)f(t)o(yp)q
+(e-)177 1461 y(setting)h(the)h(text)f(in)g Fi(tt)21 b(font)p
+Fn(.)177 1533 y(Originally)m(,)13 b(it)i(w)o(as)g(in)o(tended)h(that)f(F)m
+(unnelW)m(eb)f(w)o(ould)h(b)q(e)h(t)o(yp)q(esetter)h(indep)q(enden)o(t)g(as)e
+(w)o(ell)f(as)i(language)177 1583 y(indep)q(enden)o(t.)23 b(It)15
+b(w)o(as)f(in)o(tended)i(that)f(a)f(format)f(\014le)i(consisting)g(of)g(a)f
+(set)i(of)e(pro)q(ductions)i(describing)f(ho)o(w)177 1633 y(the)h(do)q(cumen)
+o(t)e(\014le)i(w)o(as)f(to)f(b)q(e)i(formatted)e(w)o(ould)g(b)q(e)i(handed)g
+(to)e(F)m(unnelW)m(eb)h(along)f(with)h(the)g(input)g(\014le.)177
+1683 y(In)k(the)g(end,)g(time)e(pressures)k(forced)e(me)f(to)g(tak)o(e)g(the)
+h(bac)o(k)g(do)q(or)f(and)g(hac)o(k)h(up)f(a)g(T)1627 1691
+y(E)1650 1683 y(X)h(do)q(cumen)o(t)f(\014le)177 1732 y(generator.)h(This)14
+b(compromise)d(has)j(found)f(its)h(w)o(a)o(y)f(in)o(to)g(F)m(unnelW)m(eb)g
+(V3.0)g(whic)o(h)g(is)h(still)e(relian)o(t)i(on)f(T)1883 1741
+y(E)1906 1732 y(X,)177 1782 y(although)f(V3.0)g(at)h(least)g(encourages)h
+(input)f(\014les)g(to)g(b)q(e)g(t)o(yp)q(esetter)i(indep)q(enden)o(t.)k(It)13
+b(is)g(hop)q(ed)g(that)g(future)177 1832 y(v)o(ersions)i(of)e(F)m(unnelW)m
+(eb)g(will)g(include)h(more)e(sophisticated)j(t)o(yp)q(esetting)g
+(facilities.)177 1990 y Fe(1.2)70 b(Inden)n(tation)177 2103
+y Fn(A)12 b(macro)f(call)h(that)g(do)q(es)h(not)f(app)q(ear)h(at)f(the)h
+(left)e(margin)g(is)h(called)g(an)f Fk(inden)o(ted)g(macro)i(call)f
+Fn(and)g(seems)177 2153 y(to)f(lead)h(to)f(three)h(di\013eren)o(t)h
+(alternativ)o(es)e(for)g(its)h(expansion:)k Fk(no)d(inden)o(tat)o(ion)o
+Fn(,)8 b Fk(blank)k(inden)o(tati)o(on)p Fn(,)c(and)177 2202
+y Fk(text)15 b(inden)o(tati)o(on)p Fn(.)g(Here)g(are)f(examples)f(of)g(eac)o
+(h)i(kind)e(of)g(inden)o(tation.)18 b(First)c(the)g(example)f(problem.)177
+2308 y Fi(@$@<Sloth@>==@{@-)177 2358 y(Aardvark)177 2408 y(Walrus@})177
+2508 y(@O@<Output@>==@{@-)177 2557 y(Zebra@<Sloth@>)177 2607
+y(Giraffe)177 2657 y(@})177 2763 y Fn(There)i(are)g(three)g(w)o(a)o(ys)e
+(that)h(the)h(second)g(line)e(of)g(the)i Fi(Sloth)e Fn(macro)f(can)i(b)q(e)h
+(inden)o(ted.)177 2835 y Fk(No)h(inden)o(tati)o(on:)1042 2940
+y Fn(12)p eop
+%%Page: 13 14
+13 13 bop 286 42 a Fi(ZebraAardvark)286 91 y(Walrus)286 141
+y(Giraffe)177 252 y Fk(Blank)15 b(inden)o(tati)o(on:)286 362
+y Fi(ZebraAardvark)395 412 y(Walrus)286 462 y(Giraffe)177 572
+y Fk(T)l(ext)h(inden)o(tati)o(on)o(:)286 683 y Fi(ZebraAardvark)286
+733 y(ZebraWalrus)286 783 y(Giraffe)177 893 y Fn(No)g(inden)o(tation)f(is)h
+(useful)g(where)i(the)e(user)h(wishes)g(to)f(deal)g(with)g(the)g(output)g
+(stream)g(as)g(a)g(pure)h(output)177 943 y(stream.)g(Blank)11
+b(inden)o(tation)g(is)g(useful)g(when)h(the)g(user)h(wishes)f(to)f(generate)h
+(inden)o(ted)g(computer)f(programs.)177 993 y(T)m(ext)k(inden)o(tation)f(is)g
+(useful)h(where)h(the)f(user)h(wishes)f(to)g(pre\014x)g(eac)o(h)h(line)e(of)g
+(an)g(en)o(tire)i(macro)d(in)o(v)o(o)q(cation)177 1043 y(with)c(a)h(string.)
+16 b(This)10 b(can)f(b)q(e)i(useful)e(for)g(commen)o(ting)e(out)j(co)q(de)g
+(\(e.g.)f(in)g(Ada)g(using)h Fi(--)p Fn(\),)f(and)h(for)f(prep)q(ending)177
+1092 y(things)14 b(lik)o(e)f(a)h(dollar)e(sign)i(at)g(the)g(start)h(of)e(eac)
+o(h)h(line)g(an)f(a)h(V)-5 b(AX)15 b(VMS)f(DCL)f(script)i(command)c(\014le.)
+177 1168 y(F)m(unnelW)m(eb)i(V1)h(pro)o(vided)g(a)f(c)o(hoice)i(of)e(no)h
+(inden)o(tation)f(or)h(blank)f(inden)o(tation.)k(The)d(c)o(hoice)h(w)o(as)f
+(made)e(in)177 1218 y(the)j(command)c(line)i(and)h(could)g(not)f(b)q(e)i(o)o
+(v)o(erridden.)177 1294 y(The)f(design)h(questions)f(are)g(as)g(follo)o(ws:)
+228 1414 y(1.)20 b(Whic)o(h)13 b(of)h(the)g(three)h(kinds)f(of)f(inden)o
+(tation)h(should)f(F)m(unnelW)m(eb)h(supp)q(ort?)228 1499 y(2.)20
+b(What)13 b(should)h(b)q(e)h(the)f(gran)o(ularit)o(y)f(of)g(sw)o(apping)g(b)q
+(et)o(w)o(een)i(inden)o(tation)f(mo)q(des?)228 1585 y(3.)20
+b(Are)15 b(particular)e(inden)o(tation)h(mo)q(des)f(dangerous?)228
+1671 y(4.)20 b(Is)14 b(the)h(presence)h(of)d(particular)h(com)o(binations)e
+(of)h(inden)o(tation)g(mo)q(des)g(confusing)h(to)g(the)g(user?)228
+1756 y(5.)20 b(Ho)o(w)13 b(and)h(when)h(should)e(the)i(c)o(hoice)f(of)f
+(inden)o(tation)h(b)q(e)g(sp)q(eci\014ed?)177 1876 y(All)j(sorts)h(of)f(sc)o
+(hemes)g(w)o(ere)i(considered,)g(including)d(a)h(\014nely)g(grained)g(system)
+h(in)e(whic)o(h)i(the)g(user)g(could)177 1926 y(sp)q(ecify)13
+b(at)g(the)g(p)q(oin)o(t)f(of)g(call)g(whic)o(h)g(inden)o(tation)g(mo)q(de)f
+(should)i(b)q(e)g(used)g(for)g(the)g(called)f(macro)f(expansion.)177
+2002 y(After)f(a)f(lot)g(of)g(though)o(t,)g(the)i(dominan)o(t)c(factor)i
+(that)h(should)f(a\013ect)h(the)g(design)g(w)o(as)f(decided)h(to)g(b)q(e)g
+(the)g Fh(clarity)177 2051 y Fn(in)k(the)g(user's)h(mind)d(of)h(the)i(inden)o
+(tation)e(facilit)o(y)f(and)i(the)g Fh(danger)h Fn(asso)q(ciated)f(with)g
+(misunderstanding)f(it.)177 2101 y(Here)f(are)f(t)o(w)o(o)f(examples)f(that)i
+(sho)o(w)f(ho)o(w)g(easily)g(a)h(confusion)f(or)g(misunderstanding)g(of)g
+(the)h(inden)o(ting)f(b)q(eing)177 2151 y(used)15 b(can)f(cause)h(danger.)j
+(The)d(\014rst)f(example)f(sho)o(ws)h(ho)o(w)g(blank)f(or)h(no)f(inden)o
+(tation)g(migh)o(t)f(b)q(e)j(misused.)177 2271 y Fi(--Misuse)20
+b(of)i(blank)e(\(and)h(no\))h(indentation.)177 2320 y(--@<Sloth@>)177
+2440 y Fn(Here)d(the)g(user)g(has)g(assumed)e(that)h(text)h(inden)o(tation)e
+(is)h(in)g(action)g(and)g(has)g(placed)g(an)g(Ada)g(commen)o(t)177
+2490 y(sym)o(b)q(ol)12 b(\\)p Fi(--)p Fn(")g(b)q(efore)i(the)g(in)o(v)o(o)q
+(cation)e(of)h(the)h(macro)e Fi(@<Sloth@>)f Fn(in)i(the)h(hop)q(e)g(that)f
+(the)h(en)o(tire)g(text)g(of)f(the)177 2539 y(macro)d(w)o(ould)h(b)q(e)g
+(pre\014xed)i(b)o(y)e(\\)p Fi(--)p Fn(".)16 b(The)c(result)g(could)f(b)q(e)h
+(passed)g(b)o(y)f(the)h(compiler)d(whic)o(h)j(w)o(ould)e(activ)n(ate)177
+2589 y(all)j(but)h(the)g(\014rst)h(statemen)o(t)f(in)f(the)i(expansion)f(of)f
+(macro)g Fi(@<Sloth@>)p Fn(.)177 2665 y(The)h(next)h(example)d(demonstrates)j
+(ho)o(w)e(text)i(inden)o(tation)e(could)h(b)q(e)g(misused.)177
+2785 y Fi(--Misuse)20 b(of)i(text)f(indentation:)177 2835 y(a++;)g(@<Sloth@>)
+1042 2940 y Fn(13)p eop
+%%Page: 14 15
+14 14 bop 177 42 a Fn(Here)15 b(the)g(user)g(has)f(placed)g(the)h(call)e(to)h
+Fi(@<Sloth@>)e Fn(after)i(the)h(incremen)o(ting)e(of)g(v)n(ariable)g
+Fi(a)p Fn(.)18 b(The)c(result)h(is)177 91 y(that)e(there)h(is)e(a)h(go)q(o)q
+(d)f(c)o(hance)i(that)e(the)i(\\)p Fi(a++;)p Fn(")d(prep)q(ended)k(to)d(eac)o
+(h)i(line)e(of)g(the)h(expansion)g(of)f Fi(@<Sloth@>)177 141
+y Fn(will)h(b)q(e)h(passed)h(b)o(y)f(the)g(compiler)f(and)g(will)g(cause)i
+Fi(a)e Fn(to)h(b)q(e)h(o)o(v)o(erincremen)o(ted.)177 216 y(These)h(examples)e
+(are)h(not)g(to)f(b)q(e)i(laughed)e(at.)20 b(It)15 b(is)g(p)q(ossible)f(that)
+h(F)m(unnelW)m(eb)f(will)g(b)q(e)h(used)h(widely)m(,)d(and)177
+266 y(the)i(problems)e(ab)q(o)o(v)o(e)h(ma)o(y)f(cause)i(problems)e(in)h
+(critical)g(systems.)20 b(The)14 b(examples)g(ab)q(o)o(v)o(e)g(are)h
+(particularly)177 316 y(scary)h(b)q(ecause)g(they)g(are)f(re\015exiv)o(e.)22
+b(One)15 b(cannot)g(simply)e(pin)h(the)i(blame)d(on)i(one)g(particular)f
+(inden)o(tation)177 366 y(form.)j(A)d(little)g(though)o(t)f(rev)o(eals)i
+(that)f(the)h(greatest)g(danger)g(lies)f(in)f Fh(c)n(onfusion)i
+Fn(in)f(the)g(user's)i(mind.)g(If)e(the)177 416 y(user)h(is)f(confused)h(b)q
+(et)o(w)o(een)g(text)f(or)g(blank)f(inden)o(ting,)g(problems)g(will)g(arise.)
+177 491 y(There)20 b(seem)e(to)h(b)q(e)g(t)o(w)o(o)f(w)o(a)o(ys)g(to)g(solv)o
+(e)h(the)g(problem.)31 b(The)19 b(\014rst)g(is)f(to)h(ban)f(all)f(macro)h
+(calls)g(that)g(are)177 541 y(preceded)f(b)o(y)e(non-blank)f(text.)23
+b(This)15 b(is)g(not)g(a)f(go)q(o)q(d)h(option)f(b)q(ecause)j(there)g(are)e
+(so)g(man)o(y)e(cases)k(where)f(it)177 591 y(is)g(desirable)g(to)f(expand)h
+(more)f(than)g(one)h(single)g(line)f(macros)g(on)g(the)h(same)f(line.)23
+b(A)16 b(second)g(option)f(is)h(to)177 640 y(eliminate)e(one)i(of)g(the)g(t)o
+(w)o(o)g(forms)e(so)i(as)g(to)g(reduce)i(the)e(p)q(oten)o(tial)g(for)f(am)o
+(biguit)o(y)e(in)j(the)g(user's)h(mind.)23 b(I)177 690 y(c)o(ho)q(ose)17
+b(the)g(latter)f(option.)24 b(Of)16 b(the)g(t)o(w)o(o)g(forms,)f(the)h(clear)
+h(c)o(hoice)f(for)g(elimination)d(is)j(text)h(inden)o(ting)e(for)177
+740 y(the)g(follo)o(wing)c(reasons:)228 858 y(1.)20 b(It)14
+b(actually)f(in)o(tro)q(duces)i(extra)f(text)h(whic)o(h)e(giv)o(es)h(it)g(an)
+f(a)h(priori)f(p)q(oten)o(tial)g(for)h(problems.)228 942 y(2.)20
+b(It)14 b(is)g(harder)g(to)g(implemen)o(t)d(and)j(w)o(ould)f(slo)o(w)g(do)o
+(wn)h(T)m(angle.)228 1026 y(3.)20 b(It)14 b(w)o(ould)f(not)h(b)q(e)g
+(compatible)e(with)i(F)m(unnelW)m(eb)f(V1)h(whic)o(h)g(uses)h(blank)e(inden)o
+(tation.)177 1144 y(The)18 b(only)f(other)h(decision)g(is)f(the)i(lev)o(el)e
+(of)g(gran)o(ularit)o(y)f(of)h(c)o(hoice)h(b)q(et)o(w)o(een)h(the)f
+(remaining)e(options:)25 b(no)177 1194 y(inden)o(tation)11
+b(and)h(blank)f(inden)o(tation.)17 b(F)m(unnelW)m(eb)11 b(V1)h(allo)o(w)o(ed)
+e(this)i(c)o(hoice)g(to)g(b)q(e)g(made)f(in)g(the)i(command)177
+1243 y(line.)27 b(In)17 b(retrosp)q(ect,)j(this)d(w)o(as)g(bad)g(design)g(b)q
+(ecause)i(the)f(user)g(migh)o(t)d(un)o(wittingly)g(co)q(de)j(certain)g(macro)
+177 1293 y(calls)12 b(relying)h(on)f(one)h(or)g(the)g(other)h(mo)q(de.)i(A)d
+(b)q(etter)h(system)f(is)f(to)h(allo)o(w)e(the)i(user)h(to)f(sp)q(ecify)g
+(whic)o(h)g(mo)q(de)177 1343 y(in)h(the)g(input)g(\014le)g(itself.)j(This)d
+(has)g(b)q(een)h(done)f(in)g(F)m(unnelW)m(eb)f(V3.)177 1418
+y(Again,)20 b(to)g(a)o(v)o(oid)f(confusion,)i(it)f(seems)g(sensible)h(to)f
+(allo)o(w)e(the)j(user)g(only)e(one)h(inden)o(tation)g(mo)q(de)f(p)q(er)177
+1468 y(F)m(unnelW)m(eb)14 b(input)h(\014le.)20 b(In)15 b(most)e(cases,)j(the)
+g(user)f(will)f(b)q(e)h(happ)o(y)f(with)h(blank)f(inden)o(tation)g(\(the)h
+(default\))177 1518 y(and)f(there)h(will)d(b)q(e)j(no)f(need)h(for)e(c)o
+(hange)h(an)o(yw)o(a)o(y)m(.)177 1593 y Fk(Decision:)j Fn(Implemen)o(t)12
+b(only)i(\\no)g(inden)o(tation")f(and)h(\\blank)g(inden)o(tation".)k(Mak)o(e)
+c(the)h(c)o(hoice)g(of)f(inden-)177 1643 y(tation)j(a)g(static)h(attribute)g
+(of)f(a)g(particular)h(F)m(unnelW)m(eb)f(run)g(that)h(is)f(sp)q(eci\014ed)i
+(in)e(the)i(input)e(\014le.)29 b(This)177 1693 y(solution)13
+b(is)h(the)h(same)e(as)h(F)m(unnelW)m(eb)f(V1)h(except)h(that)f(the)h(c)o
+(hoice)f(has)g(b)q(een)h(mo)o(v)o(ed)e(from)f(the)j(command)177
+1743 y(line)f(to)f(the)i(input)e(\014le.)177 1907 y Fe(1.3)70
+b(Review)20 b(of)k(F)-6 b(unnelW)g(eb)22 b(Syn)n(tax)177 2023
+y Fn(One)12 b(of)e(the)i(distressing)g(asp)q(ects)h(of)d(F)m(unnelW)m(eb)h
+(V1)f(w)o(as)h(its)g(clumsy)f(macro)g(de\014nition)h(and)g(calling)e(syn)o
+(tax.)177 2073 y(Compared)14 b(to)h(\(sa)o(y\))g(the)g(C)g(prepro)q(cessor,)i
+(F)m(unnelW)m(eb's)d(macro)g(call)g(syn)o(tax)h(is)g(lik)o(e)f(a)g(freigh)o
+(t)h(train)g(in)f(a)177 2123 y(c)o(hina)i(sho)o(w.)24 b(During)15
+b(the)h(F)m(unnelW)m(eb)f(redesign,)i(a)f(complete)f(review)h(of)g(this)f
+(syn)o(tax)h(to)q(ok)g(place)g(to)g(try)177 2173 y(to)f(neaten)h(it)f(up.)22
+b(Surprisingly)m(,)14 b(the)i(V1)f(syn)o(tax)g(surviv)o(ed)h(unscathed)g
+(with)f(the)h(exception)g(that)f(\\)p Fi(==)p Fn(")f(in)177
+2223 y(macro)i(de\014nitions)i(w)o(as)f(made)g(optional.)27
+b(The)18 b(surviv)n(al)f(of)g(this)g(clumsy)g(syn)o(tax)g(w)o(as)h(a)f(pro)q
+(duct)h(of)f(the)177 2272 y(design)d(goal)f(of)g(making)f(ev)o(erything)i
+(simple,)e(explicit,)h(and)g(not)h(sub)r(ject)i(to)d(subtle)i(errors.)177
+2415 y Fa(1.3.1)55 b(Review)18 b(of)g(Macro)h(De\014nition)f(Syn)n(tax)177
+2518 y Fn(F)m(unnelW)m(eb)i(V1)h(used)g(a)f(macro)g(de\014nition)g(syn)o(tax)
+h(that)f(resulted)i(in)e(macro)g(de\014nitions)g(suc)o(h)h(as)g(the)177
+2568 y(follo)o(wing.)177 2685 y Fi(@$@<Put)g(out)g(the)g(cat@>==@{@-)177
+2735 y(Open)g(the)g(door)177 2785 y(Say)g(out)177 2835 y(Close)g(the)g
+(door@})1042 2940 y Fn(14)p eop
+%%Page: 15 16
+15 15 bop 177 42 a Fn(This)16 b(is)f(messy)m(,)g(but)h(I)g(couldn't)f(think)h
+(of)f(an)o(ything)g(b)q(etter)i(at)e(the)i(time.)22 b(The)16
+b Fi(@$)f Fn(is)h(necessary)i(to)d(cue)i(a)177 91 y(de\014nition.)k(Without)
+14 b(it,)h(the)g(de\014nition)g(migh)o(t)e(someho)o(w)g(b)q(e)j(mistak)o(en)e
+(for)g(an)h(in)o(v)o(o)q(cation.)20 b(The)15 b Fi(@<)g Fn(and)177
+141 y Fi(@>)e Fn(delimit)d(the)k(name.)j(The)c Fi(@)p Fm(f)g
+Fn(and)f Fi(@)p Fm(g)h Fn(delimit)e(the)i(text.)19 b(The)13
+b Fi(@-)g Fn(is)f(a)h(pro)q(duct)h(of)e(the)i(rule)f(\\exactly)g(the)177
+191 y(text)i(b)q(et)o(w)o(een)g(the)f Fi(@)p Fm(f)g Fn(and)g
+Fi(@)p Fm(g)p Fn(".)177 260 y(The)g(only)f(real)h(target)g(is)g(the)g(\\)p
+Fi(+=)p Fn(")f(and)g(\\)p Fi(==)p Fn(")g(whic)o(h)h(really)f(break)h(all)f
+(the)h(rules)g(and)g(should)f(b)q(e)i(c)o(hanged.)177 310 y(Unfortunately)f
+(I)h(couldn't)e(think)h(of)g(an)o(ything)f(to)h(c)o(hange)h(them)e(to.)19
+b(If)14 b(there)i(w)o(as)e(no)g Fi(+=)g Fn(mec)o(hanism,)e(w)o(e)177
+360 y(could)i(use:)177 458 y Fi(@$@<Put)21 b(out)g(the)g(cat@>@{)177
+507 y(Open)g(the)g(door)177 557 y(Say)g(out)177 607 y(Close)g(the)g(door@})
+177 705 y Fn(In)14 b(fact,)f(eliminating)d Fi(+=)j Fn(is)h(think)n(able)e(b)q
+(ecause)k(it)d(do)q(es)h(not)g(app)q(ear)g(in)f(man)o(y)e(of)i(m)o(y)f
+(existing)h(F)m(unnelW)m(eb)177 754 y(source)i(\014les.)k(This)14
+b(indicates)g(at)f(least)i(that)e(it)h(w)o(as)g(not)g(needed)h(m)o(uc)o(h)e
+(b)o(y)g(m)o(yself.)177 824 y(A)h(minim)o(ali)o(st)e(construct)j(could)f(b)q
+(e)177 921 y Fi(@<Put)21 b(out)g(the)g(cat@>)177 971 y(Open)g(the)g(door)177
+1021 y(Say)g(out)177 1071 y(Close)g(the)g(door@})177 1168 y
+Fn(but)14 b(this)g(is)g(to)q(o)g(dangerous)g(for)g(m)o(y)e(tastes.)177
+1238 y Fk(Decision:)j Fn(F)m(or)c(compatibili)o(t)o(y)d(reasons,)k(retain)g
+(the)f(old)g Fi(+=)f Fn(and)h Fi(==)g Fn(constructs,)i(but)e(mak)o(e)e(them)i
+(optional.)177 1287 y(The)j(new)h(syn)o(tax)f(for)f(de\014ning)h(macros)f
+(is:)177 1385 y Fi(@$@<Put)21 b(out)g(the)g(cat@>@{)177 1435
+y(Open)g(the)g(door)177 1485 y(Say)g(out)177 1534 y(Close)g(the)g(door@})177
+1632 y Fn(Next)12 b(w)o(e)f(turn)h(to)f(parameterized)g(macro)f
+(de\014nitions.)17 b(A)11 b(con)o(v)o(en)o(tional)f(F)m(unnelW)m(eb)h
+(parameterized)g(macro)177 1682 y(de\014nition)j(lo)q(oks)f(lik)o(e)g(this:)
+177 1779 y Fi(@$@<Put)21 b(out)g(the)g(cat@>@\(@3@\)==@{@-)177
+1829 y(Open)g(the)g(door)177 1879 y(Say)g(out)177 1929 y(Close)g(the)g
+(door@})177 2026 y Fn(whic)o(h)14 b(is)g(a)f(bit)h(messy)m(.)j(The)d(natural)
+g(alternativ)o(e)f(is)h(ev)o(en)h(w)o(orse:)177 2124 y Fi(@$@<Put)21
+b(out)g(the)g(cat@>@\(@1@,@2@,@3)o(@\)==@)o({@-)177 2174 y(Open)g(the)g(door)
+177 2224 y(Say)g(out)177 2273 y(Close)g(the)g(door@})177 2371
+y Fn(Th)o(us,)12 b(just)g(sp)q(ecifying)f(the)h(n)o(um)o(b)q(er)f(of)g
+(parameters)h(seems)g(sensible.)18 b(Ho)o(w)o(ev)o(er,)12 b(p)q(erhaps)g(the)
+g(syn)o(tax)g(could)177 2421 y(b)q(e)j(trimmed)c(to)177 2518
+y Fi(@$@<Put)21 b(out)g(the)g(cat@>@3==@{@-)177 2568 y(Open)g(the)g(door)177
+2618 y(Say)g(out)177 2668 y(Close)g(the)g(door@})177 2765 y
+Fn(I)14 b(decided)h(to)f(reject)h(this)f(in)f(fa)o(v)o(our)g(of)h(the)g(old)f
+(syn)o(tax.)177 2835 y Fk(Decision:)j Fn(Retain)e(the)g(old)f(syn)o(tax)h(of)
+f Fj(:)7 b(:)g(:)o Fi(@\(@3@\))p Fj(:)g(:)g(:)1042 2940 y Fn(15)p
+eop
+%%Page: 16 17
+16 16 bop 177 42 a Fa(1.3.2)55 b(Review)18 b(of)g(Macro)h(Call)g(Syn)n(tax)
+177 147 y Fn(Here)c(are)g(some)e(ideas)h(for)f(alternativ)o(es)h(to)g(the)g
+(F)m(unnelW)m(eb)g(V1)f(macro)g(call)g(syn)o(tax.)177 270 y
+Fi(Open)21 b(the)g(door)177 320 y(@<Say)g(Out@>)195 b(@!)21
+b(FunnelWeb~V1)f(style.)177 370 y(Close)h(the)g(door)177 470
+y(Open)g(the)g(door)177 520 y(@<Say)g(out>@)177 569 y(Close)g(the)g(door)177
+669 y(Open)g(the)g(door)177 719 y(@"Say)g(out@")177 769 y(Close)g(the)g(door)
+177 868 y(Open)g(the)g(door)177 918 y(@\(Say)g(out@\))177 968
+y(Close)g(the)g(door)177 1068 y(Open)g(the)g(door)177 1117
+y(@<Say)g(out>)177 1167 y(Close)g(the)g(door)177 1291 y Fk(Decision:)29
+b Fn(Con)o(tin)o(ue)20 b(with)g(the)g(old)g(notation.)36 b(It)20
+b(ma)o(y)e(not)i(b)q(e)h(neat,)h(but)e(at)g(least)h(it)e(is)h(clear)h(and)177
+1340 y(consisten)o(t.)j(The)16 b(main)d(temptation)h(is)h(the)h(format)e
+Fi(@<say)21 b(out>@)14 b Fn(whic)o(h)h(lo)q(oks)g(rather)i(go)q(o)q(d.)22
+b(Ho)o(w)o(ev)o(er,)177 1390 y(it)14 b(breaks)g(the)h(sp)q(ecial)f(sequence)i
+(rational)d(and)g(hence)j(is)d(to)q(o)h(confusing.)177 1540
+y Fa(1.3.3)55 b(Review)18 b(of)g(P)n(arameterized)f(Macro)i(Call)f(Syn)n(tax)
+177 1646 y Fn(F)m(unnelW)m(eb)c(V1)f(pro)o(vided)h(a)g(messy)f(parameterized)
+h(macro)f(call)g(syn)o(tax:)177 1769 y Fi(@<Say)21 b(Out@>@\(@"firstpar)o
+(am@")d(@,)k(@"Secondparam@")c(@,)k(@"thirdparam@")d(@\))177
+1893 y Fn(This)d(syn)o(tax)g(can)g(b)q(e)g(cleaned)h(up)f(considerably)g(b)o
+(y)g(making)d(the)k Fi(@")e Fn(sym)o(b)q(ols)g(optional.)22
+b(This)16 b(results)h(in)177 1942 y(calls)d(suc)o(h)g(as)g(the)h(follo)o
+(wing:)177 2066 y Fi(@<Say)21 b(Out@>@\(firstparam)o(@,Sec)o(ondpa)o(ram@,)o
+(thir)o(dpara)o(m@\))177 2189 y Fn(As)c(the)g(\014rst)g(form)e(allo)o(ws)g
+(the)i(alignmen)o(t)d(of)h(complicated)h(parameters)g(b)o(y)g(allo)o(wing)e
+(white)j(space)g(to)f(b)q(e)177 2239 y(inserted)h(outside)f(the)g
+Fi(@")p Fn(,)f(and)h(the)g(second)h(form)d(is)h(cleaner,)i(b)q(oth)f(are)g
+(retained)g(simply)e(b)o(y)h(making)e(the)177 2289 y(quotes)i(optional.)177
+2366 y Fk(Decision:)h Fn(Mak)o(e)e(the)h(double)e(quotes)i(optional.)177
+2538 y Fe(1.4)70 b(Do)r(cumen)n(t)21 b(Structuring)177 2657
+y Fn(Exp)q(erience)e(with)e(F)m(unnelW)m(eb)f(V1,)h(whic)o(h)g(pro)o(vided)g
+(only)f(t)o(w)o(o)h(lev)o(els)g(of)f(headings)h(\(ma)r(jor)f(and)g(minor\))
+177 2707 y(pro)o(v)o(ed)10 b(that)h(there)g(w)o(as)f(a)g(strong)g(need)h(for)
+f(fully)f(hierarc)o(hical)h(m)o(ultiple-lev)o(el)d(headings.)17
+b(The)10 b(only)g(question)177 2757 y(w)o(as)k(ho)o(w)f(it)h(should)g(b)q(e)g
+(done.)177 2835 y(Here)h(are)g(some)e(ideas)h(that)g(w)o(ere)g(considered.)
+1042 2940 y(16)p eop
+%%Page: 17 18
+17 17 bop 177 42 a Fi(@*@<Main)20 b(Program@>)177 91 y(@**@<Read)g(the)h
+(Message@>)177 141 y(@***@<Encrypt)e(the)i(Buffer@>)177 241
+y(@*@<Main)f(Program@>)177 291 y(@*@*@<Read)g(the)h(Message@>)177
+340 y(@*@*@*@<Encrypt)e(the)i(Buffer@>)177 440 y(@s@<Main)f(Program@>)177
+490 y(@ss@<Read)g(the)h(Message@>)177 540 y(@sss@<Encrypt)e(the)i(Buffer@>)
+177 639 y(@s@<Main)f(Program@>)177 689 y(@s@s@<Read)g(the)h(Message@>)177
+739 y(@s@s@s@<Encrypt)e(the)i(Buffer@>)177 839 y(@S@<Main)f(Program@>)177
+888 y(@SS@<Read)g(the)h(Message@>)177 938 y(@SSS@<Encrypt)e(the)i(Buffer@>)
+177 1038 y(@S@<Main)f(Program@>)177 1088 y(@S@S@<Read)g(the)h(Message@>)177
+1137 y(@S@S@S@<Encrypt)e(the)i(Buffer@>)177 1237 y(@A@<Main)f(Program@>)238
+b(--)22 b(The)f(syntax)f(finally)h(chosen.)177 1287 y(@B@<Read)f(the)h
+(Message@>)177 1337 y(@C@<Encrypt)f(the)h(Buffer@>)177 1436
+y(@A)h(Main)f(Program)177 1486 y(@B)h(Read)f(the)g(Message)177
+1536 y(@C)h(Encrypt)e(the)h(Buffer)177 1636 y(@*A)g(Main)g(Program)177
+1685 y(@*B)g(Read)g(the)g(Message)177 1735 y(@*C)g(Encrypt)g(the)g(Buffer)177
+1835 y(@1@<Main)f(Program@>)177 1885 y(@2@<Read)g(the)h(Message@>)177
+1934 y(@3@<Encrypt)f(the)h(Buffer@>)177 1984 y(\(using)g(@A..@I@)f(as)h
+(macro)g(parameters)f(or)h(overload)f(@1..@9\))177 2084 y(@*@1@<Main)g
+(Program@>)177 2134 y(@*@2@<Read)g(the)h(Message@>)177 2183
+y(@*@3@<Encrypt)e(the)i(Buffer@>)177 2233 y(\(using)g(@A..@I@)f(as)h(macro)g
+(parameters)f(or)h(overload)f(@1..@9\))177 2351 y Fn(Cho)q(osing)f(b)q(et)o
+(w)o(een)i(these)g(alternativ)o(es)e(w)o(as)h(not)f(easy)m(.)35
+b(The)20 b(follo)o(wing)d(though)o(ts)j(con)o(tributed)g(to)f(the)177
+2400 y(decision.)239 2518 y Fm(\017)i Fn(Syn)o(taxes)14 b(that)g(require)h
+(visual)e(coun)o(ting)g(are)i(probably)e(not)h(a)f(go)q(o)q(d)h(idea.)239
+2601 y Fm(\017)21 b Fn(Syn)o(taxes)14 b(that)f(do)g(not)h(delimit)d(the)j
+(heading)f(name)f(someho)o(w)h(are)g(lik)o(ely)f(to)i(cause)g(problems)f
+(where)281 2651 y(heading)18 b(names)f(are)h(omitted.)30 b(Users)19
+b(will)e(b)q(e)i(tempted)f(to)g(start)g(paragraphs)h(after)f(the)h(start)f
+(of)281 2701 y(heading)c(sym)o(b)q(ol)f(and)h(the)h(result)g(is)f(that)h(the)
+g(\014rst)g(line)f(of)g(the)h(paragraph)f(will)f(b)q(e)i(suc)o(k)o(ed)g(in)o
+(to)f(the)281 2751 y(heading.)239 2835 y Fm(\017)21 b Fn(Ov)o(erloading)13
+b(the)h Fi(@1)p Fn(,)f Fj(:)7 b(:)g(:)o Fn(,)13 b Fi(@9)h Fn(sequences)i(is)e
+(undesirable.)1042 2940 y(17)p eop
+%%Page: 18 19
+18 18 bop 177 42 a Fk(Decision:)21 b Fn(Use)c Fi(@A)p Fj(:)7
+b(:)g(:)n Fi(@E)16 b Fn(with)g(optional)f(follo)o(wing)e(macro)i(name)g(syn)o
+(tax)h(for)g(the)h(section)g(name.)24 b(Note:)177 91 y(W)m(e)15
+b(stop)g(at)g Fi(@E)f Fn(b)q(ecause)j(\014v)o(e)e(lev)o(els)g(is)g(probably)f
+(su\016cien)o(t,)i(and)e(w)o(e)i(ma)o(y)d(wish)h(later)i(to)e(use)i
+Fi(@F)f Fn(for)f Fk(F)p Fn(ile)177 141 y(\(to)g(augmen)o(t)f(or)g(replace)i
+Fi(@O)p Fn(\).)177 321 y Fe(1.5)70 b(Discussion)21 b(of)j(Some)e(Miscell)o
+(aneous)f(Issues)177 445 y Fk(Commen)o(t)d(duplication)o(:)k
+Fn(If)17 b(the)h(F)m(unnelW)m(eb)f(user)h(inserts)g(commen)o(ts)d(in)o(to)i
+(the)h(target)f(co)q(de)h(\(in)f(the)177 495 y Fi(.fw)12 b
+Fn(\014le\))g(as)g(w)o(ell)f(as)h(in)o(to)g(the)g(do)q(cumen)o(tation)f
+(\(free)i(text\))g(part)f(of)g(the)g Fi(.fw)g Fn(\014le,)g(then)h(it)e(is)h
+(p)q(ossible)g(for)g(the)177 544 y(situation)h(to)h(get)g(a)g(bit)f(silly)m
+(.)k Fk(Decision:)f Fn(This)e(is)g(a)f(problem)g(for)g(the)i(programmer,)c
+(not)j(for)f(F)m(unnelW)m(eb.)177 625 y Fk(Out-of-date)k(do)q(cumen)o(tation)
+o(:)22 b Fn(Sometimes)14 b(it)j(is)f(all)g(to)q(o)h(easy)g(for)f(the)i
+(programmer)c(to)j(mo)q(dify)d(the)177 674 y(co)q(de)k(without)e(up)q(dating)
+g(the)h(surrounding)g(do)q(cumen)o(tation.)24 b Fk(Decision:)e
+Fn(This)16 b(is)h(a)f(serious)h(and)f(ma)r(jor)177 724 y(problem.)27
+b(In)17 b(an)g(automated)f(en)o(vironmen)o(t,)g(it)h(ma)o(y)e(b)q(e)j(p)q
+(ossible)f(to)g(create)i(a)e(system)g(of)f(dep)q(endencies)177
+774 y(b)q(et)o(w)o(een)h(scraps)g(of)d(co)q(de)i(and)g(scraps)g(of)f(do)q
+(cumen)o(tation.)21 b(Ho)o(w)o(ev)o(er,)16 b(it)f(is)g(hard)h(to)f(see)h(ho)o
+(w)f(a)g(to)q(ol)g(suc)o(h)177 824 y(as)f(F)m(unnelW)m(eb)f(could)h(pro)o
+(vide)g(supp)q(ort)h(for)e(prev)o(en)o(tion)h(of)g(this)g(sort)g(of)f(error.)
+177 904 y Fk(Meta-macro-lev)o(el)j(parameterization:)k Fn(Sometimes,)14
+b(when)j(using)f(F)m(unnelW)m(eb,)g(the)g(facilit)o(y)f(to)h(use)177
+954 y(one)11 b(macro)f(to)h(construct)i(the)e(name)f(of)h(another)g(has)g(b)q
+(een)h(needed.)19 b Fk(Decision:)c Fn(Allo)o(wing)9 b(macro)h(names)g(to)177
+1004 y(b)q(e)k(constructed)h(w)o(ould)e(lose)g(the)h(simple)d(nature)j(of)f
+(the)h(prepro)q(cessor)h(and)e(so)h(this)f(suggestion)g(is)g(rejected.)177
+1084 y Fk(Clumsy)j(notation:)h Fn(The)e Fi(@)f Fn(notation)f(can)i(b)q(e)g
+(clumsy)m(.)j Fk(Decision:)f Fn(This)e(is)f(necessary)i(to)f(main)o(tain)c
+(the)177 1134 y(simplicit)o(y)h(of)h(the)h(translation.)177
+1314 y Fe(1.6)70 b(Automated)22 b(Regression)g(T)-6 b(esting)177
+1438 y Fn(Automated)13 b(regression)i(testing)f(is)g(extremely)g(imp)q(ortan)
+o(t)e(for)h(t)o(w)o(o)h(reasons:)228 1568 y(1.)20 b(It)14 b(pro)o(vides)g
+(con\014dence)i(that)e(c)o(hanges)g(made)f(to)h(the)g(program)e(ha)o(v)o(e)i
+(not)g(in)o(tro)q(duced)h(bugs.)228 1662 y(2.)20 b(It)11 b(allo)o(ws)e(p)q
+(ortabilit)o(y)g(problems)h(to)g(b)q(e)i(pinp)q(oin)o(ted)e(when)h(the)g
+(program)e(is)i(mo)o(v)o(ed)e(to)h(a)g(new)i(mac)o(hine.)177
+1792 y(The)j(simplest)e(w)o(a)o(y)g(to)h(set)h(up)g(automated)d(regression)k
+(testing)e(is)g(to)g(construct)i(a)e(suite)h(of)e(test)i(cases)h(\(and)177
+1842 y(their)e(solutions\))e(and)h(then)h(write)f(a)g(script)g(in)g(the)g
+(target)h(mac)o(hine's)d(command)g(language)h(to)g(run)i(through)177
+1892 y(the)k(suite.)29 b(Unfortunately)m(,)17 b(there)i(is)e(no)g(command)d
+(language)j(that)g(is)g(shared)h(among)e(the)i(mac)o(hines)e(to)177
+1941 y(whic)o(h)f(F)m(unnelW)m(eb)f(m)o(ust)g(b)q(e)h(p)q(orted.)22
+b(These)16 b(mac)o(hines)e(are)i(at)e(least:)20 b(Macin)o(tosh,)15
+b(IBM-PC,)g(Sun,)g(VMS)177 1991 y(V)m(ax.)177 2072 y(One)h(option)e(is)h
+(simply)e(to)i(rewrite)h(the)g(script)g(in)e(eac)o(h)i(mac)o(hine's)d
+(particular)i(command)d(language.)21 b(This)177 2121 y(w)o(ould)15
+b(b)q(e)i(a)e(feasible)h(option)f(w)o(ere)i(it)e(not)h(for)f(the)i(fact)f
+(that)g(the)g(Macin)o(tosh)g(\(the)g(mac)o(hine)f(up)q(on)h(whic)o(h)177
+2171 y(F)m(unnelW)m(eb)e(w)o(as)f(dev)o(elop)q(ed\))i(do)q(es)g(not)e(ha)o(v)
+o(e)h(a)g(command)d(language!)177 2252 y(After)i(some)f(though)o(t,)g(I)g
+(decided)i(that)e(the)h(b)q(est)h(solution)e(to)g(the)h(problem)e(w)o(as)i
+(to)f(create)i(a)e(command)e(lan-)177 2301 y(guage)i Fh(within)h(F)m
+(unnelWeb)p Fn(.)18 b(F)m(unnelW)m(eb)12 b(could)g(then)h(b)q(e)f(in)o(v)o
+(ok)o(ed)g(in)f(t)o(w)o(o)h(mo)q(des,)f(one-shot)i(command)c(line)177
+2351 y(or)15 b(in)o(teractiv)o(e/script.)20 b(This)15 b(approac)o(h)f(had)g
+(the)h(b)q(ene\014t)h(of)e(pro)o(viding)f(total)h(con)o(trol)g(o)o(v)o(er)g
+(the)i(command)177 2401 y(language)d(and)h(its)g(complete)f(p)q(ortabilit)o
+(y)m(.)177 2481 y(The)h(result)h(is)f(describ)q(ed)i(in)d(the)h
+Fh(F)m(unnelWeb)j(User's)d(Manual)p Fn(.)177 2661 y Fe(1.7)70
+b(Command)22 b(Line)g(In)n(terface)177 2785 y Fn(F)m(unnelW)m(eb)12
+b(V1)g(w)o(as)g(implemen)o(ted)e(in)i(Ada)g(and)g(runs)h(on)f(a)g(VMS)g(V)-5
+b(AX.)13 b(As)g(suc)o(h)g(it)e(has)i(a)f(full)f(VMS)h(DCL)177
+2835 y(command)f(line)j(in)o(terface.)k(Here)d(is)f(the)h(\\)p
+Fi(.CLD)p Fn(")d(\014le)i(for)g(the)g(DCL)g(command)d(line)i(in)o(terface.)
+1042 2940 y(18)p eop
+%%Page: 19 20
+19 19 bop 177 42 a Fi(!)22 b(FUNNELWEB)e(Command)g(Definition)177
+91 y(!)i(================)o(=====)o(=====)o(==)177 141 y(!)g(Ross)f
+(Williams.)f(28)h(April)g(1987.)177 241 y(module)g(command_table)243
+291 y(define)f(verb)h(dummy_command)243 340 y(parameter)e(p1)240
+b(,)21 b(label=input_file)62 b(,value\(required,type)o(=$fi)o(le\))243
+390 y(qualifier)19 b(include_files,)g(label=include_files)o(,valu)o(e\(typ)o
+(e=$fi)o(le\))g(,default)243 440 y(qualifier)g(output_files)h(,)h
+(label=output_files)d(,value\(type=$file\))h(,default)243 490
+y(qualifier)g(delete)152 b(,)21 b(label=delete)565 b(,default)243
+540 y(qualifier)19 b(tex_file)108 b(,)21 b(label=tex_file)106
+b(,value\(type=$file\))19 b(,default)243 589 y(qualifier)g(listing_file)h(,)h
+(label=listing_file)d(,value\(type=$file\))h(,default)243 639
+y(qualifier)g(brief)174 b(,)21 b(label=brief,value\(t)o(ype=$)o(numbe)o
+(r,def)o(ault=)o(5\),d)o(efaul)o(t)243 689 y(qualifier)e(screen)152
+b(,)21 b(label=screen)150 b(,value\(type=$number,)o(defa)o(ult=0)o(\))243
+739 y(qualifier)19 b(trace)174 b(,)21 b(label=trace)243 789
+y(qualifier)e(file_spec)86 b(,)21 b(label=file_spec)243 839
+y(qualifier)e(compare)177 981 y Fn(As)d(p)q(ortabilit)o(y)f(w)o(as)g(a)h(k)o
+(ey)g(goal)e(of)h(F)m(unnelW)m(eb)g(V3,)h(it)f(w)o(as)h(ob)o(vious)f(that)h
+(the)g(command)d(line)i(in)o(terface)177 1031 y(w)o(ould)e(ha)o(v)o(e)h(to)g
+(b)q(e)g(redesigned.)20 b(The)14 b(design)g(goals)f(for)h(the)g(new)g
+(command)d(line)j(in)o(terface)g(w)o(ere:)228 1174 y(1.)20
+b(The)15 b(in)o(terface)g(should)f(not)g Fh(dep)n(end)i Fn(on)e(case.)21
+b(Ho)o(w)o(ev)o(er,)14 b(it)g(m)o(ust)g(allo)o(w)e(case-sensitiv)o(e)k
+(\014lenames)e(to)281 1224 y(b)q(e)g(transmitted)g(on)f(systems)i(that)e(ha)o
+(v)o(e)h(case-sensitiv)o(e)i(\014lenames.)228 1328 y(2.)k(Eac)o(h)13
+b(option)f(m)o(ust)g(ha)o(v)o(e)h(a)f(symmetric)f(p)q(ositiv)o(e)i(and)g
+(negativ)o(e)f(form.)k(F)m(or)d(example,)e(it)h(is)h(confusing)281
+1378 y(for)g Fi(-X)h Fn(to)g(turn)g(on)g(a)f(feature)i(and)f
+Fi(-Q)f Fn(to)h(turn)g(it)g(o\013.)228 1482 y(3.)20 b(The)14
+b(in)o(terface)h(m)o(ust)e(b)q(e)h(extensible)h(to)f(allo)o(w)e(inclusion)h
+(of)g(more)g(features)i(at)f(a)g(later)g(date.)228 1586 y(4.)20
+b(Options)14 b(should)g(b)q(e)g(consisten)o(t)h(and)f(memorable.)177
+1729 y(The)g(result)h(is)f(describ)q(ed)i(in)d(the)h Fh(F)m(unnelWeb)j
+(User's)d(Manual)p Fn(.)177 1925 y Fe(1.8)70 b(File)21 b(Name)h(Managemen)n
+(t)177 2056 y Fn(File)e(names)f(presen)o(t)j(a)e(host)g(of)g(problems)f(for)h
+(a)f(program)g(lik)o(e)g(F)m(unnelW)m(eb.)36 b(First,)22 b(F)m(unnelW)m(eb)e
+(can)177 2106 y(generate)c(so)f(man)o(y)e(di\013eren)o(t)j(kinds)f(of)f
+(\014les)h(that)g(con)o(v)o(en)o(tions)g(m)o(ust)f(b)q(e)i(adopted)f(to)g
+(prev)o(en)o(t)g(them)g(from)177 2156 y(b)q(ecoming)9 b(unmanageable.)15
+b(Second,)c(the)f(constrain)o(ts)g(on)g(\014le)g(names,)f(and)h(ev)o(en)g
+(the)h(structure)h(of)d(\014le)h(names)177 2205 y(themselv)o(es)16
+b(v)n(aries)f(considerably)h(from)e(mac)o(hine)g(to)h(mac)o(hine.)22
+b(These)17 b(t)o(w)o(o)e(problems)f(ha)o(v)o(e)i(com)o(bined)e(to)177
+2255 y(result)g(in)e(the)i(sophisticated)g(and)e(rather)i(complicated)e(w)o
+(a)o(y)g(in)h(whic)o(h)g(F)m(unnelW)m(eb)f(V3)h(handles)g(\014lenames.)177
+2340 y(T)m(o)g(summarize,)f(the)i(three)h(problems)e(are:)228
+2483 y(1.)20 b(What)13 b(\014lename)g(extensions)i(should)f(b)q(e)g(c)o
+(hosen)h(for)f(v)n(arious)f(kinds)h(of)f(\014le?)228 2588 y(2.)20
+b(What)13 b(\014lename)g(inheritance)i(should)e(tak)o(e)h(place?)228
+2692 y(3.)20 b(Ho)o(w)13 b(should)h(F)m(unnelW)m(eb)g(cop)q(e)g(with)g(the)g
+(v)n(ariations)f(in)g(\014lename)g(structure)j(b)q(et)o(w)o(een)f(mac)o
+(hines?)177 2835 y(The)f(follo)o(wing)e(three)j(sections)g(address)g(these)g
+(questions.)1042 2940 y(19)p eop
+%%Page: 20 21
+20 20 bop 177 42 a Fa(1.8.1)55 b(Filename)17 b(Extensions)177
+147 y Fn(F)m(unnelW)m(eb)11 b(is)h(capable)f(of)g(reading)h(and)f(writing)g
+(a)g(v)n(ariet)o(y)g(of)g(di\013eren)o(t)i(kinds)f(of)f(\014les.)17
+b(In)12 b(particular,)f(F)m(un-)177 197 y(nelW)m(eb)g(m)o(ust)f(often)h(op)q
+(erates)h(in)f(an)g(en)o(vironmen)o(t)f(where)i(the)f(same)f(information)f
+(is)h(stored)i(in)f(man)o(y)e(forms)177 247 y(\(e.g.)16 b(prog.fw,)f(prog.c,)
+i(pro)q(c.exe\).)26 b(File)16 b(extensions)i(are)e(an)h(essen)o(tial)f(to)q
+(ol)g(in)g(managing)e(this)i(situation.)177 297 y(The)e(\014lename)f
+(extensions)i(c)o(hosen)g(for)f(F)m(unnelW)m(eb)f(are:)177
+421 y Fi(FunnelWeb)107 b(:)22 b(.fw)177 471 y(Product)151 b(:)22
+b(None.)177 521 y(Documentation)d(:)j(.tex)177 570 y(Listing)151
+b(:)22 b(.lis)177 620 y(Journal)151 b(:)22 b(.jrn)177 744 y
+Fn(Lo)o(w)o(ercase)15 b(will)e(b)q(e)h(used)h(in)e(systems)h(that)g(are)h
+(case)f(sensitiv)o(e.)177 822 y(Readers)g(who)f(are)h(w)o(ondering)e(ho)o(w)h
+(F)m(unnelW)m(eb)g(cop)q(es)h(in)f(en)o(vironmen)o(ts)f(suc)o(h)i(as)f(UNIX)h
+(where)g(there)g(are)177 872 y(no)g(\014le)g(extensions)h(should)e(refer)i
+(to)f(Section)g(1.8.3.)177 1023 y Fa(1.8.2)55 b(Filename)17
+b(Inheritance)177 1129 y Fn(Inheritance)d(in)d(\014lenames)h(refers)i(to)e
+(ho)o(w)g(input)g(and)g(output)g(\014les)h(inherit)f(parts)h(of)f(their)h
+(name)e(from)f(other)177 1178 y(\014lenames)j(and)h(their)g(en)o(vironmen)o
+(t.)j(F)m(or)d(example)e(if)h(the)i(command)243 1302 y Fi(fw)21
+b(sloth)g(+J)g(+L)g(+T)177 1426 y Fn(w)o(as)d(issued,)i(y)o(ou)e(w)o(ould)f
+(exp)q(ect)j(to)e(see)h(output)g(\014les)f Fi(sloth.jrn)p Fn(,)f
+Fi(sloth.lis)p Fn(,)g(and)h Fi(sloth.tex)p Fn(.)29 b(The)177
+1476 y(output)14 b(\014le)h(names)e(ha)o(v)o(e)h(inherited)g(the)h(\\)p
+Fi(sloth)p Fn(".)i(The)e(follo)o(wing)c(table)j(giv)o(es)g(the)h(hierarc)o(h)
+o(y)f(devised)h(for)177 1526 y(F)m(unnelW)m(eb.)p 366 1606
+1394 2 v 365 1656 2 50 v 436 1656 V 462 1641 a(Script)p 615
+1656 V 70 w(Input)p 778 1656 V 64 w(Include)p 961 1656 V 50
+w(Journal)p 1147 1656 V 50 w(List)p 1326 1656 V 108 w(Do)q(cumen)o(t)p
+1562 1656 V 49 w(Pro)q(duct)p 1759 1656 V 366 1658 1394 2 v
+365 1707 2 50 v 391 1692 a(1)p 436 1707 V 615 1707 V 778 1707
+V 392 w Fi(@i)p 961 1707 V 1147 1707 V 1326 1707 V 1562 1707
+V 739 w(@o)p 1759 1707 V 365 1757 V 391 1742 a Fn(2)p 436 1757
+V 50 w Fi(+x)p 615 1757 V 134 w(+f)p 778 1757 V 120 w(+i)p
+961 1757 V 138 w(+j)p 1147 1757 V 143 w(+l)p 1326 1757 V 134
+w(+t)p 1562 1757 V 192 w(+o)p 1759 1757 V 365 1807 V 391 1792
+a Fn(3)p 436 1807 V 50 w(\\)p Fi(.fws)p Fn(")p 615 1807 V 48
+w(\\)p Fi(.fw)p Fn(")p 778 1807 V 56 w(\\)p Fi(.fwi)p Fn(")p
+961 1807 V 52 w(\\)p Fi(.jrn)p Fn(")p 1147 1807 V 57 w(\\)p
+Fi(.lis)p Fn(")p 1326 1807 V 48 w(\\)p Fi(.tex)p Fn(")p 1562
+1807 V 1759 1807 V 365 1857 V 391 1842 a(4)p 436 1857 V 615
+1857 V 778 1857 V 392 w Fi(+f)p 961 1857 V 138 w(+f)p 1147
+1857 V 143 w(+f)p 1326 1857 V 134 w(+f)p 1562 1857 V 1759 1857
+V 365 1907 V 391 1892 a Fn(5)p 436 1907 V 50 w(DefDir)p 615
+1907 V 55 w(Defdir)p 778 1907 V 50 w(Defdir)p 961 1907 V 68
+w(Defdir)p 1147 1907 V 73 w(Defdir)p 1326 1907 V 64 w(Defdir)p
+1562 1907 V 122 w(Defdir)p 1759 1907 V 366 1908 1394 2 v 177
+2015 a(The)f(follo)o(wing)e(notes)i(explain)g(the)g(table.)228
+2139 y(1.)20 b(This)14 b(sc)o(heme)g(is)g(similar)d(to)j(that)g(used)g(in)g
+(F)m(unnelW)m(eb)f(V1.)228 2229 y(2.)20 b(The)14 b(journal,)f(list,)f(and)i
+(do)q(cumen)o(tation)e(\014les)j(all)d(fall)g(in)i(the)g(same)f(pattern)h
+(and)g(can)g(b)q(e)g(considered)281 2278 y(as)g(a)g(single)f(case.)228
+2368 y(3.)20 b(Lev)o(el)15 b(1)h(has)f(the)h(highest)g(priorit)o(y)e(b)q
+(ecause)k(it)d(is)g(a)g(direct)h(sp)q(eci\014cation)g(b)o(y)g(the)g(user)g
+(in)f(the)h(input)281 2418 y(\014le.)228 2507 y(4.)k(Lev)o(el)14
+b(2)f(comes)h(next)g(b)q(ecause)h(this)f(is)g(also)f(a)g(direct)i(sp)q
+(eci\014cation)f(from)e(the)j(user)g(on)e(the)i(command)281
+2557 y(line.)228 2646 y(5.)20 b(Lev)o(el)13 b(3)f(pro)o(vides)h(the)h
+(default)e(\014le)h(extensions.)19 b(Pro)q(duct)14 b(\014les)f(do)g(not)f
+(inherit)h(an)g(extension)g(as)g(they)281 2696 y(could)h(b)q(e)g(of)f(an)o(y)
+h(t)o(yp)q(e.)228 2785 y(6.)20 b(Lev)o(el)12 b(5)h(is)f(built)g(in)o(to)f
+(most)h(op)q(erating)g(systems')g(\014le)h(sp)q(eci\014cation)g(systems.)k
+(If)c(I)f(sp)q(ecify)h(\014le)f(\\)p Fi(x.y)p Fn(",)281 2835
+y(it)h(is)h(tak)o(en)g(to)g(mean)f(on)g(the)i(default)e(disk)h(in)f(the)i
+(default)e(directory)m(.)1042 2940 y(20)p eop
+%%Page: 21 22
+21 21 bop 228 42 a Fn(7.)20 b(Lev)o(el)15 b(4)g(lo)q(oks)g(straigh)o(tforw)o
+(ard,)f(but)i(secretly)h(conceals)f(a)f(di\016cult)f(design)i(decision.)22
+b(By)15 b(the)h(time)281 91 y(w)o(e)j(get)g(do)o(wn)f(to)g(this)h(lev)o(el)f
+(of)g(inheritance,)i(w)o(e)e(kno)o(w)h(for)f(sure)h(that)g(the)g(\014lename)e
+(has)i(already)281 141 y(pic)o(k)o(ed)c(up)g(a)f(\014le)h(extension.)21
+b(So)15 b(all)e(that)i(is)g(left)f(to)h(inherit)g(is)g(the)g(path)g(and)f
+(the)i(\014lename)d(prop)q(er.)281 191 y(Ob)o(viously)g(w)o(e)h(ha)o(v)o(e)g
+(to)g(inherit)g(the)h(\014lename)e(prop)q(er)i(\(e.g.)j Fi(sloth)13
+b Fn(in)h Fi(sloth.tex)p Fn(\),)d(but)k(should)f(w)o(e)281
+241 y(inherit)j(the)g(input)g(\014le)g(path?)26 b(If)17 b(w)o(e)g(do)f
+(inherit)h(the)g(input)g(\014le)g(path,)g(\014les)g(will)e(b)q(e)j(placed)f
+(in)f(the)281 291 y(same)f(directory)h(as)g(the)g(input)g(\014le.)23
+b(If)16 b(w)o(e)g(don't)f(inherit)h(the)g(input)f(\014le)h(path,)g(\014les)g
+(will)e(b)q(e)j(placed)281 340 y(in)c(the)h(curren)o(t)h(directory)m(.)j(The)
+c(c)o(hoice)g(I)f(ha)o(v)o(e)h(made)e(is)h(to)g(send)i(all)d(the)i(logging)e
+(t)o(yp)q(e)i(\014les)f(in)o(to)g(the)281 390 y(same)h(directory)j(as)e(the)h
+(input)f(\014le.)23 b(This)15 b(means,)g(for)g(example,)f(that)h
+Fi(sloth.lis)e Fn(and)j Fi(sloth.tex)281 440 y Fn(will)c(generally)i(land)f
+(in)g(the)i(same)e(directory)h(as)g Fi(sloth.fw)p Fn(.)j(Ho)o(w)o(ev)o(er,)c
+(I)h(ha)o(v)o(e)g(decided)h(that)f(output)281 490 y(\014les)e(should)f(b)q(e)
+h(sen)o(t)g(to)f(the)h(default)f(directory)h(\(if)f(not)g(earlier)h(sp)q
+(eci\014ed\))h(as)e(this)g(is)h(where)g(the)g(action)281 540
+y(is.)19 b(In)c(normal)d(use,)j(the)g(main)d(pro)q(duct)j(of)f(F)m(unnelW)m
+(eb)g(will)e(b)q(e)j(pro)q(duct)h(\014les)e(and)g(so)h(the)g(user)g(will)281
+589 y(exp)q(ect)g(them)e(to)h(app)q(ear)h(in)e(the)h(curren)o(t)i(directory)e
+(b)o(y)g(default.)177 757 y Fa(1.8.3)55 b(P)n(ortable)19 b(Structure)f(of)h
+(File)e(Names)177 871 y Fn(Another)g(problem)e(with)g(\014le)h(names)f(is)h
+(the)h(v)n(ariation)d(of)h(their)i(structure)h(b)q(et)o(w)o(een)f(en)o
+(vironmen)o(ts.)24 b(Here)177 921 y(are)14 b(examples)f(of)h(some)f(of)g(the)
+h(formats)f(that)h(prev)n(ail:)243 1059 y Fi(UNIX)64 b(/device/dir1/dir2/)o
+(name)243 1108 y(VMS)86 b(node::device:[dir1)o(.dir2)o(]name)o(.ext)o(;vn)243
+1158 y(MSDOS)42 b(device:\\dir1\\dir2\\)o(name.)o(ext)243 1208
+y(MAC)86 b(device:dir1:dir2:n)o(ame)177 1345 y Fn(Isn't)14
+b(it)g(amazing)d(that)j(none)g(of)g(these)h(p)q(opular)f(systems)g(use)g(the)
+h(same)e(format?)177 1429 y(The)j(solution)f(to)g(dealing)g(with)g(these)i
+(di\013eren)o(t)f(formats)e(is)h(to)h(classify)f(them)g(as)g(non-p)q(ortable)
+g(and)h(hide)177 1479 y(the)g(functions)f(that)g(manipulate)e(them)h(in)g
+(the)i(mac)o(hine-sp)q(eci\014c)f(mo)q(dule)e(of)i(F)m(unnelW)m(eb.)20
+b(Luc)o(kily)14 b(there)177 1528 y(are)g(not)g(man)o(y)e(suc)o(h)j
+(functions.)177 1612 y(The)g(main)c(problem)i(is)h(coping)f(with)h(\014le)g
+(systems)g(that)g(do)g(not)g(explicitly)e(supp)q(ort)j(\014le)f(extensions.)
+19 b(With)177 1661 y(so)14 b(man)o(y)e(p)q(ossible)i(input)f(and)g(output)h
+(\014les,)g(F)m(unnelW)m(eb)f(all)f(but)i(needs)h(suc)o(h)g(extensions.)k
+(Mac)o(hines)14 b(that)177 1711 y(do)h(not)g(supp)q(ort)h(them)e(p)q(ose)h
+(di\016cult)g(design)g(decisions.)22 b(If)14 b(the)i(user)g(sp)q(eci\014es)h
+(\\)p Fi(sloth)p Fn(")c(as)i(an)g(input)g(\014le)177 1761 y(on)d(suc)o(h)g(a)
+g(non-extension-supp)q(orting)g(system,)g(should)g(F)m(unnelW)m(eb)f(lo)q(ok)
+g(for)g Fi(sloth)g Fn(or)h Fi(sloth.fw)p Fn(?)k(If)11 b(the)177
+1811 y(user)k(sp)q(eci\014es)h Fi(walrus)c Fn(as)i(a)g(listing)f(\014le,)g
+(should)h(it)f(generate)j Fi(walrus)c Fn(or)i Fi(walrus.lis)p
+Fn(?)177 1894 y(Some)f(p)q(ossible)h(solutions)f(are:)228 2032
+y(1.)20 b(Regard)14 b(the)g(\014lename)f Fi(sloth)g Fn(as)h(ha)o(ving)e(an)i
+(empt)o(y)f(extension.)19 b(It)14 b(will)e(then)j(default)e(to)h
+Fi(sloth.fw)p Fn(.)228 2132 y(2.)20 b(Regard)g(the)h(\014lename)d
+Fi(sloth)h Fn(as)i(ha)o(ving)e(a)g(blank)h(but)g(full)f(extension.)37
+b(That)20 b(is,)h(it)f(cannot)g(b)q(e)281 2181 y(o)o(v)o(erwritten)14
+b(b)o(y)g(inheritance,)g(but)g(it)g(remains)f(blank.)228 2282
+y(3.)20 b(Pro)o(vide)c(an)g(extra)h(syn)o(tactic)f(mec)o(hanism)e(to)i(allo)o
+(w)f(the)i(user)g(to)f(sp)q(ecify)h(one)f(or)g(other)h(of)e(the)i(t)o(w)o(o)
+281 2331 y(options)c(ab)q(o)o(v)o(e.)177 2469 y(My)i(solution)e(w)o(as)i(to)f
+(c)o(ho)q(ose)i(the)f(\014rst)g(option.)k(Use)d(of)e(F)m(unnelW)m(eb)g
+(results)h(in)f(lots)h(of)f(\014les)h(lying)e(around)177 2519
+y(\(e.g.)h Fi(sloth.lis)p Fn(\))f(and)h(it)g(is)g(hard)h(to)f(see)i(ho)o(w)e
+(the)h(user)h(will)c(cop)q(e)k(with)e(them)g(all)f(without)h(some)f(kind)h
+(of)177 2569 y(naming)e(discipline.)17 b(If)d(a)f(naming)f(discipline)h(has)h
+(to)g(b)q(e)h(used,)f(it)g(migh)o(t)d(as)j(w)o(ell)f(b)q(e)i(the)f(F)m
+(unnelW)m(eb)g(one.)177 2652 y(Th)o(us)h(the)g(names)e(of)h(all)f(\014les)i
+(read)f(and)h(written)f(b)o(y)h(F)m(unnelW)m(eb)e(will)g(ha)o(v)o(e)h(a)g
+(\014le)h(extension)g(of)e(from)g(zero)177 2702 y(to)h(three)h(letters)g
+(separated)g(from)e(the)h(rest)h(of)e(the)i(\014lename)e(b)o(y)g(a)h(\\)p
+Fi(.)p Fn(".)177 2785 y(The)d(only)f(exception)i(is)f(pro)q(duct)g(\014les)g
+(whose)h(extension)f(is)g(left)f(unde\014ned.)19 b(Pro)q(duct)12
+b(\014les)f(need)h(not)e(con)o(tain)177 2835 y(a)k(\\)p Fi(.)p
+Fn(")k(and)13 b(a)h(\014le)g(extension,)g(although)f(they)h(can)g(inherit)g
+(one)g(if)f(the)i(user)g(wishes.)1042 2940 y(21)p eop
+%%Page: 22 23
+22 22 bop 177 42 a Fe(1.9)70 b(Sp)r(ecifying)31 b(Constrain)n(ts)i(on)h(the)e
+(Num)n(b)r(er)g(of)i(Instan)n(tia-)334 116 y(tions)177 232
+y Fn(Exp)q(erience)17 b(with)d(F)m(unnelW)m(eb)g(V1)g(demonstrated)h(the)g
+(need)g(to)g(b)q(e)g(able)f(to)g(sp)q(ecify)h(in)g(macro)e(de\014nitions)177
+281 y(ho)o(w)f(man)o(y)f(times)h(it)g(w)o(as)h(exp)q(ected)h(that)f(the)g
+(macro)f(w)o(ould)g(b)q(e)h(used.)18 b(F)m(unnelW)m(eb)13 b(V1)f(generates)i
+(an)f(error)177 331 y(if)g(a)g(macro)f(is)h(not)g(used,)h(but)g(p)q(ermits)f
+(macros)f(to)i(b)q(e)g(called)f(more)f(than)h(once.)19 b(This)13
+b(caused)i(problems)d(for)177 381 y(macro)h(libraries,)g(whic)o(h)h(w)o(ould)
+f(b)q(e)h(included,)g(but)g(whose)g(macros)f(w)o(ere)i(often)f(not)g(called.)
+177 455 y(By)g(default,)e(F)m(unnelW)m(eb)h(V3)h(requires)g(that)g(eac)o(h)f
+(macro)g(\(except)i(for)e(the)h(ones)f(attac)o(hed)h(to)g(output)f(\014les\))
+177 505 y(b)q(e)19 b(called)e(exactly)h(once.)30 b(Ho)o(w)o(ev)o(er,)19
+b(it)f(also)f(pro)o(vides)h(syn)o(tax)g(that)f(allo)o(ws)g(the)h(user)h(to)f
+(sp)q(ecify)g(that)g(a)177 555 y(macro)13 b(b)q(e)h(allo)o(w)o(ed)e(to)i(b)q
+(e)g(called)f(zero)i(times)d(or)i(man)o(y)e(times.)17 b(This)c(allo)o(ws)g(a)
+g(macro)f(to)i(b)q(e)g(sp)q(eci\014ed)h(with)177 605 y(the)f(follo)o(wing)d
+(p)q(ermissible)i(ranges)h(of)f(n)o(um)o(b)q(ers)g(of)g(calls)g(dep)q(ending)
+h(on)f(the)h(presence)i(or)e(absence)h(of)e(\\)p Fi(@Z)p Fn(")177
+655 y(and)h(\\)p Fi(@M)p Fn(":)243 770 y Fi(0..1)217 b(@$@<Sloth@>@Z==.)o(..)
+308 819 y(1)h(@$@<Sloth@>==...)308 869 y(1..n)152 b(@$@<Sloth@>@M==.)o(..)243
+919 y(0.....n)f(@$@<Sloth@>@Z@M=)o(=...)177 1034 y Fn(The)14
+b(only)g(t)o(w)o(o)f(problems)g(with)g(this)h(sc)o(heme)g(are:)228
+1149 y(1.)20 b(It)11 b(is)g(incompatible)f(with)h(F)m(unnelW)m(eb)f(V1)i
+(\014les,)f(as)h(the)f(default)g(in)g(F)m(unnelW)m(eb)g(V1)g(is)g(1)c
+Fj(:)g(:)g(:)e(n)11 b Fn(whereas)281 1198 y(the)16 b(default)g(in)f(new)h(F)m
+(unnelW)m(eb)f(is)h(1.)23 b(This)16 b(is)f(not)h(a)g(big)f(problem)f(b)q
+(ecause)j(most)e(macros)g(in)g(the)281 1248 y(old)e(\014les)h(w)o(ere)h(used)
+g(exactly)f(once.)19 b(Only)13 b(a)h(few)g(macros)f(will)f(ha)o(v)o(e)i(to)g
+(b)q(e)g(c)o(hanged.)228 1331 y(2.)20 b(What)13 b(should)h(the)h(syn)o(tax)e
+(b)q(e?)19 b(\(ab)q(o)o(v)o(e)14 b(is)g(a)f(sneak)i(preview)f(only!\))177
+1446 y(The)g(initial)d(prop)q(osal)i(for)g(syn)o(tax)g(w)o(as)g(to)g(allo)o
+(w)f(the)i(user)g(to)f(insert)h(zero,)g(one,)f(or)g(b)q(oth)g(of)g
+Fi(@?)18 b Fn(and)13 b Fi(@M)g Fn(just)177 1496 y(after)h(the)h
+Fi(@$)e Fn(of)g(a)h(macro)f(de\014nition.)k(Ho)o(w)o(ev)o(er,)d(this)g(has)g
+(the)h(follo)o(wing)c(dra)o(wbac)o(ks:)228 1610 y(1.)20 b(It)14
+b(uses)h(t)o(w)o(o)e(sequences)k(that)d(are)g(desirable)g(to)g(reserv)o(e)i
+(\()p Fi(@?)i Fn(for)c(conditionals)f(and)g Fi(@M)h Fn(for)f(macro\).)228
+1693 y(2.)20 b(It)14 b(stops)g(the)h(user)g(from)d(searc)o(hing)i(for)g(the)g
+(string)g Fi(@$@<name)f Fn(to)g(\014nd)h(the)h(de\014nition)e(of)h(a)f
+(macro.)177 1808 y(These)h(are)e(signi\014can)o(t)g(problems.)17
+b(Here)c(are)g(some)e(alternativ)o(e)h(ideas)h(for)f(where)h(to)f(p)q
+(osition)g(the)h(mo)q(di\014ers)177 1858 y(in)h(the)g(macro)f(de\014nition:)
+177 1973 y Fi(@?@M@$@<Slothy)19 b(dogs@>@\(@5@\)==@{@-)177
+2022 y(This)i(is)h(a)f(short)g(macro.)177 2072 y(With)g(only)g(a)h(line)f(or)
+g(two@})177 2172 y(@$@<Slothy)f(dogs@>@?@M@\(@5@\)=)o(=@{@-)177
+2222 y(This)h(is)h(a)f(short)g(macro.)177 2271 y(With)g(only)g(a)h(line)f(or)
+g(two@})177 2371 y(@$@<Slothy)f(dogs@>@\(@5@\)@?@M=)o(=@{@-)177
+2421 y(This)h(is)h(a)f(short)g(macro.)177 2471 y(With)g(only)g(a)h(line)f(or)
+g(two@)177 2586 y Fn(The)14 b(\014rst)f(form)e(puts)j(me)e(o\013)h(b)q
+(ecause)h(I)f(think)g(that)g(it)f(is)h(a)g(go)q(o)q(d)f(visual)g(rule)h(to)g
+(start)h(all)e(the)h(macros)f(with)177 2635 y Fi(@$)p Fn(.)17
+b(The)12 b(second)h(form)d(puts)j(me)d(o\013)i(b)q(ecause)i(it)d(detac)o(hes)
+i(the)g(macro)d(name)h(from)f(the)j(parameter)e(list,)g(th)o(us)177
+2685 y(making)g(it)i(lo)q(ok)f(less)i(lik)o(e)f(a)g(call,)f(whic)o(h)h(is)h
+(desirable)f(syn)o(tactic)h(resonance.)20 b(The)13 b(third)h(form)d(is)j
+(messy)f(but)177 2735 y(probably)i(w)o(ork)n(able.)23 b(Because)17
+b(w)o(e)f(are)g(righ)o(t)g(next)g(to)f(the)h(tested)i(constan)o(t)e(string)g
+(\(either)g Fi(==)g Fn(or)f Fi(+=)p Fn(\))h(w)o(e)177 2785
+y(could)f(augmen)o(t)e(it)h(further.)21 b(F)m(or)15 b(example,)e
+Fi(01==)h Fn(could)g(allo)o(w)f(a)h(macro)g(to)g(b)q(e)i(called)e(from)f(0)h
+(to)h(1)f(times.)177 2835 y(The)g(main)e(problem)h(with)g(this)h(is)g(that)g
+(w)o(e)g(are)g(trying)g(to)g(phase)g(out)g Fi(==)f Fn(an)o(yw)o(a)o(y!)1042
+2940 y(22)p eop
+%%Page: 23 24
+23 23 bop 177 42 a Fn(Nev)o(ertheless,)17 b(all)c(the)j(logic)d(p)q(oin)o(ts)
+i(to)f(after)h(the)g(parameter)g(list)f(as)h(the)g(b)q(est)h(place)f(to)f(lo)
+q(cate)h(this)g(infor-)177 91 y(mation.)177 167 y(After)21
+b(some)d(though)o(t,)j(it)e(w)o(as)h(decided)h(that)f(the)g(\\)p
+Fi(@?)p Fn(")35 b(sequence)22 b(b)q(e)e(reserv)o(ed)i(for)e(a)f(p)q(ossible)h
+(future)177 217 y(conditional)13 b(facilit)o(y)m(,)e(and)j(so)g
+Fi(@Z)f Fn(w)o(as)h(used)h(instead.)177 292 y Fk(Decision:)h
+Fn(The)f(p)q(osition)e(is)h(after)g(the)g(parameter)g(list.)j(The)e(notation)
+e(is)g Fi(@Z)h Fn(for)f(zero,)i(and)e Fi(@M)h Fn(for)f(man)o(y)m(.)177
+368 y(Example)g(of)g(\014nal)g(syn)o(tax:)177 486 y Fi(@$@<Slothy)20
+b(dogs@>@\(@5@\)@Z@M+)o(=@{@-)177 536 y(This)h(is)h(a)f(short)g(macro.)177
+585 y(With)g(only)g(a)h(line)f(or)g(two@})177 750 y Fe(1.10)70
+b(The)25 b(Relationship)e(Bet)n(w)n(een)g(Do)r(cumen)n(t)h(Structure)h(and)
+368 825 y(Macro)f(Structure)177 942 y Fn(Ha)o(ving)15 b(already)h(decided)h
+(up)q(on)f(a)g(fully)e(hierarc)o(hical)i(do)q(cumen)o(t)g(structure,)i(I)e
+(determined)g(to)g(re\014ne)h(the)177 992 y(details.)h(The)c(issues)h(to)f(b)
+q(e)h(addressed)g(w)o(ere)g(as)f(follo)o(ws:)239 1110 y Fm(\017)21
+b Fn(Ho)o(w)13 b(should)h(the)h(hierarc)o(hical)e(structure)j(connect)g(to)d
+(the)i(macro)e(structure?)239 1194 y Fm(\017)21 b Fn(Ho)o(w)13
+b(can)i(bac)o(kw)o(ards)f(compatibilit)o(y)c(b)q(e)15 b(ac)o(hiev)o(ed?)j
+(Should)c(it?)239 1279 y Fm(\017)21 b Fn(Should)13 b(the)i(macros)e(b)q(e)h
+(cross)h(referenced)i(b)o(y)c(section)i(or)f(b)o(y)g(de\014nition?)239
+1363 y Fm(\017)21 b Fn(Should)13 b(nameless)h(sections)h(inherit)f(macro)e
+(names)h(as)h(headings?)239 1448 y Fm(\017)21 b Fn(Should)13
+b(w)o(e)h(simply)e(use)j(T)708 1457 y(E)731 1448 y(X)f(macros)f(to)h
+(structure)i(the)e(do)q(cumen)o(t?)177 1566 y(After)h(some)e(though)o(t,)g(I)
+h(arriv)o(ed)g(at)f(the)i(follo)o(wing)c(though)o(ts:)177 1642
+y Fk(Basically)i(a)h(T)439 1651 y(E)464 1642 y(X)h(\014le:)h
+Fn(One)d(option)f(is)g(simply)e(to)i(treat)h(eac)o(h)g Fi(.fw)e
+Fn(\014le)i(as)f(a)g(T)1481 1651 y(E)1504 1642 y(X)g(\014le)h(laced)f(with)g
+(macros.)177 1691 y(That)18 b(is,)g(a)g Fi(.fw)f Fn(\014le)h(could)f(b)q(e)i
+(structured)h(as)e(a)f(real)h(T)1117 1700 y(E)1140 1691 y(X)g(\014le)g(from)e
+(whic)o(h)i(F)m(unnelW)m(eb)f(could)h(extract)177 1741 y(macro)13
+b(de\014nitions.)18 b(This)13 b(approac)o(h)h(is)g(feasible)f(b)q(ecause)j(T)
+1157 1750 y(E)1180 1741 y(X)e(could)f(b)q(e)i(programmed)c(to)j(resp)q(ond)h
+(to)e(the)177 1791 y Fi(@)g Fn(sequences)i(in)d(the)i(same)e(w)o(a)o(y)g
+(that)h(F)m(unnelW)m(eb)f(resp)q(onds)i(to)f(them.)k(Th)o(us,)12
+b(there)i(w)o(ould)e(b)q(e)i(no)e(need)i(for)177 1841 y(W)m(ea)o(v)o(e.)177
+1916 y(I)h(rejected)i(this)e(approac)o(h,)g(\014rst)g(b)q(ecause)i(it)e(is)g
+(to)q(o)f(t)o(yp)q(esetter-dep)q(e)q(nden)o(t,)k(and)d(second)h(b)q(ecause)h
+(it)d(com-)177 1966 y(plicates)i(the)h(inclusion)e(of)h(an)o(y)f(sort)h(of)g
+(complicated)e(p)q(ost-pro)q(cessing)k(in)d(the)i(do)q(cumen)o(tation)e
+(\014le.)24 b(This)177 2016 y(w)o(ould)13 b(ha)o(v)o(e)h(to)g(b)q(e)g
+(implemen)o(ted)e(in)h(T)818 2025 y(E)841 2016 y(X.)177 2091
+y(A)h(b)q(etter)h(approac)o(h)f(is)f(to)h(use)g(an)g(in)o(v)o(en)o(ted)g
+(section)g(notation)f(\(e.g.)18 b Fi(@A)j(@B)g(@C)p Fn(\).)13
+b(This)h(main)o(tains)d(F)m(unnel-)177 2141 y(W)m(eb's)h(t)o(yp)q(esetter)k
+(indep)q(endence)f(and)d(can)h(easily)f(b)q(e)i(con)o(v)o(erted)g(in)o(to)e
+(T)1365 2150 y(E)1388 2141 y(X)h(sectioning)f(macros)g(b)o(y)h(W)m(ea)o(v)o
+(e.)177 2217 y(In)g(the)h(same)e(spirit,)g(it)h(migh)o(t)e(b)q(e)j(w)o(orth)f
+(in)o(tro)q(ducing)f(a)h(few)g Fi(@)g Fn(sequences)i(for)e(certain)h(general)
+f(t)o(yp)q(esetting)177 2267 y(op)q(erations)h(suc)o(h)h(as)f(italics)f(and)h
+(program)e(co)q(de.)177 2342 y Fk(Confusion)f(in)i(F)l(unnelW)l(eb)e(V1)j
+(Heading)e(Num)o(b)q(ering:)j Fn(F)m(unnelW)m(eb)d(V1)g(uses)h(t)o(w)o(o)f
+(lev)o(els)g(of)f(section)177 2392 y(headings,)16 b(but)g(n)o(um)o(b)q(ers)f
+(all)f(the)i(headings)g(sequen)o(tially)m(.)22 b(In)16 b(this,)f(it)h(is)f(a)
+g(little)g(confused.)24 b(Clearly)15 b(with)177 2442 y(a)20
+b(fully)e(hierarc)o(hical)h(do)q(cumen)o(t)h(structure,)i(the)f(headings)e
+(cannot)h(b)q(e)g(n)o(um)o(b)q(ered)g(sequen)o(tially)f(|)g(the)177
+2492 y(n)o(um)o(b)q(ering)13 b(m)o(ust)g(re\015ect)i(the)g(structure)h
+(\(e.g.)d(3.2.1\).)177 2567 y Fk(Hierarc)o(hical)d(n)o(um)o(b)q(erin)o(g)f
+(is)j(messy)f(for)h(macros:)k Fn(Unfortunately)m(,)11 b(hierarc)o(hical)f(n)o
+(um)o(b)q(ering)g(is)g(messy)177 2617 y(and)k(confusing)f(when)i(applied)e
+(to)h(macro)e(names.)18 b(In)c(F)m(unnelW)m(eb)f(V1's)h(t)o(yp)q(eset)h
+(output,)f(eac)o(h)g(macro)f(call)177 2667 y(has)i(app)q(ended)g(in)f(square)
+h(brac)o(k)o(ets)h(the)f(n)o(um)o(b)q(er)f(of)f(the)i(section)h(in)e(whic)o
+(h)g(the)h(macro)e(is)h(de\014ned.)21 b(Use)15 b(of)177 2716
+y(hierarc)o(hical)f(n)o(um)o(b)q(ering)e(w)o(ould)i(b)q(e)g(somewhat)f(messy)
+m(.)k(F)m(or)d(example,)e(a)h(macro)g(call)g(migh)o(t)f(lo)q(ok)h(lik)o(e.)
+243 2835 y Fi(Write)20 b(out)h(the)h(output[6.7.4.3])1042 2940
+y Fn(23)p eop
+%%Page: 24 25
+24 24 bop 177 42 a Fn(Similarly)l(,)11 b(cross)k(reference)h(lists)e(w)o
+(ould)f(b)q(e)i(messy:)243 180 y Fi(This)21 b(macro)f(is)i(used)f(in)g
+(3.4.5,)g(1.2,)g(7.8.9,)f(7.4,)h(2.2.1.1.)177 319 y Fk(Separate)12
+b(n)o(um)o(b)q(ering)e(for)j(macros)h(and)f(headings:)i Fn(One)e(idea)f(is)g
+(to)g(use)g(hierarc)o(hical)g(n)o(um)o(b)q(ering)f(for)177
+369 y(the)i(sections,)h(but)f(to)f(n)o(um)o(b)q(er)g(the)h(macros)f(sequen)o
+(tially)m(.)k(This)d(could)f(b)q(e)h(a)g(little)f(confusing)g(in)g(do)q
+(cumen)o(ts)177 419 y(without)j(m)o(uc)o(h)g(structure,)i(but)f(w)o(ould)f(b)
+q(e)h(v)o(ery)g(m)o(uc)o(h)f(less)h(messy)f(than)h(cross)g(referencing)h
+(using)f(hierar-)177 469 y(c)o(hical)f(n)o(um)o(b)q(ering.)22
+b(Also,)15 b(it)g(will)f(b)q(e)i(easier)g(to)g(\014nd)f(macros)g(indexed)h(b)
+o(y)f(a)g(sequen)o(tial)h(n)o(um)o(b)q(er)f(than)g(b)o(y)177
+519 y(section,)g(whic)o(h)g(has)g(a)g(less)g(direct)h(relationship)e(with)h
+(page)g(bulk)f(and)h(n)o(um)o(b)q(er.)20 b(By)15 b(macro)e(n)o(um)o(b)q
+(ering)h(is)177 568 y(mean)o(t)f(the)h(sequen)o(tial)g(n)o(um)o(b)q(ering)f
+(of)g(eac)o(h)h(macro)f(b)q(o)q(dy)h(part)g(through)g(the)h(whole)e(do)q
+(cumen)o(t.)177 652 y Fk(Input)h(format)g(matters)f(more)i(than)f(output)f
+(format:)k Fn(A)o(t)c(this)h(p)q(oin)o(t)e(w)o(e)i(realize)g(that)f(a)g
+(distinction)177 702 y(should)f(b)q(e)g(made)e(b)q(et)o(w)o(een)j(the)f
+Fh(input)i(format)d Fn(and)g(the)h Fh(typ)n(eset)h(output)p
+Fn(.)18 b(The)12 b(critical)f(issue)h(here)h(is)f(not)f(ho)o(w)177
+752 y(the)16 b(program)e(should)h(b)q(e)i(formatted)d(for)h(prin)o(ting,)g
+(but)g(rather)i(the)f(format)d(of)i(its)h Fi(.fw)f Fn(\014le.)22
+b(The)16 b(t)o(yp)q(eset)177 802 y(output)e(can)h(alw)o(a)o(ys)e(b)q(e)h(c)o
+(hanged)h(simply)d(b)o(y)i(\014ddling)f(with)g(W)m(ea)o(v)o(e.)18
+b(Ho)o(w)o(ev)o(er,)c(as)g(so)q(on)g(as)h(the)f(do)q(cumen)o(t)177
+851 y(structuring)g(features)f(of)f(F)m(unnelW)m(eb)g(are)h(\014xed,)f(they)h
+(will)e(b)q(e)i(used)h(in)e(dozens)h(or)f(h)o(undreds)i(of)e(do)q(cumen)o(ts)
+177 901 y(and)j(it)g(will)f(b)q(e)i(v)o(ery)g(di\016cult)f(indeed)h(to)f(c)o
+(hange)h(them.)21 b(Therefore,)c(the)f(imp)q(ortan)o(t)e(thing)g(is)i(to)f
+(pro)o(vide)177 951 y(as)f(sensible)h(and)f(expressiv)o(e)h(a)f
+Fi(.fw)f Fn(format)f(as)i(p)q(ossible.)177 1035 y(It)d(is)g(therefore)h(a)e
+(separate)i(decision)f(as)g(to)f(whether)i(w)o(e)f(should)g(n)o(um)o(b)q(er)f
+(macros)g(b)o(y)g(section)h(or)g(b)o(y)g(sequence)177 1085
+y(n)o(um)o(b)q(er.)17 b(The)e(imp)q(ortan)o(t)d(thing)h(is)h(to)g(address)h
+(the)f(format)f(and)g(rules)i(for)e(the)i(expression)g(of)e(structure.)177
+1168 y Fk(Naming)k(sections:)i Fn(The)d(naming)d(of)i(sections)h(requires)h
+(some)d(though)o(t.)22 b(In)16 b(man)o(y)d(cases)k(\(esp)q(ecially)e(in)177
+1218 y(the)k(case)g(of)e(high-lev)o(el)g(sections\))i(the)f(writer)h(will)d
+(pro)o(vide)i(an)g(explicit)f(name)g(for)h(a)f(section.)31
+b(In)18 b(other)177 1268 y(cases,)d(pro)o(vision)e(of)g(suc)o(h)h(a)g(name)e
+(will)h(merely)g(duplicate)g(the)i(name)d(of)h(the)i(macro)d(con)o(tained)i
+(within)f(the)177 1318 y(section.)23 b(It)15 b(therefore)i(mak)o(es)d(sense)j
+(to)e(allo)o(w)e(the)j(user)g(to)f(omit)f(the)h(name)f(from)g(a)h(section,)g
+(with)g(W)m(ea)o(v)o(e)177 1368 y(naming)10 b(the)k(section)f(after)g(the)g
+(\014rst)h(macro)d(de\014nition)h(in)g(the)i(section.)k(If)12
+b(a)h(macro)e(is)h(unnamed)g(and)g(there)177 1417 y(is)i(no)g(macro)e(in)i
+(the)g(section,)g(an)g(error)h(can)f(b)q(e)g(generated.)177
+1501 y(All)f(these)j(though)o(ts)e(lead)f(to)h(the)g(follo)o(wing)e(sc)o
+(heme:)239 1640 y Fm(\017)21 b Fn(Do)q(cumen)o(ts)13 b(will)g(b)q(e)h
+(hierarc)o(hically)g(structured)i(using)d Fi(@A)p Fn(,)g Fi(@B)h
+Fn(etc.)239 1741 y Fm(\017)21 b Fn(Eac)o(h)14 b(section)h(can)f(b)q(e)g(giv)o
+(en)g(a)f(name)g(delimited)f(b)o(y)i Fi(@<@>)p Fn(.)239 1842
+y Fm(\017)21 b Fn(Sections)15 b(that)f(do)f(not)h(ha)o(v)o(e)g(names)f
+(inherit)h(the)g(name)f(of)g(their)h(\014rst)h(macro.)239 1943
+y Fm(\017)21 b Fn(If)13 b(a)h(section)h(do)q(es)f(not)g(ha)o(v)o(e)g(a)f
+(name)g(or)h(a)g(macro,)e(it)h(is)h(erroneous.)239 2045 y Fm(\017)21
+b Fn(Sections)15 b(will)d(b)q(e)j(n)o(um)o(b)q(ered)e(hierarc)o(hically)g
+(either)i(b)o(y)f(F)m(unnelW)m(eb)f(or)h(b)o(y)g(T)1551 2054
+y(E)1574 2045 y(X.)239 2146 y Fm(\017)21 b Fn(Macro)12 b(b)q(o)q(dy)f(parts)h
+(will)e(b)q(e)i(n)o(um)o(b)q(ered)f(sequen)o(tially)g(b)o(y)g(F)m(unnelW)m
+(eb)g(and)h(cross)g(referenced)i(b)o(y)d(these)281 2196 y(n)o(um)o(b)q(ers.)
+177 2334 y(All)i(this)h(results)h(in)f(a)f(system)h(whic)o(h:)239
+2473 y Fm(\017)21 b Fn(Pro)o(vides)14 b(a)g(hierarc)o(hical)g(do)q(cumen)o(t)
+f(structuring)i(capabilit)o(y)m(.)239 2574 y Fm(\017)21 b Fn(Is)14
+b(t)o(yp)q(esetter)i(indep)q(enden)o(t.)239 2676 y Fm(\017)21
+b Fn(Do)q(es)14 b(not)g(require)h(duplication)e(b)q(et)o(w)o(een)i(heading)e
+(and)h(macro)f(names.)239 2777 y Fm(\017)21 b Fn(Separates)14
+b(the)f(heading)f(and)h(macro)e(systems)i(so)f(that)h(W)m(ea)o(v)o(e)f(can)h
+(b)q(e)g(con\014gured)h(at)e(a)g(later)h(date)g(to)281 2827
+y(cross)i(reference)h(in)e(di\013eren)o(t)h(w)o(a)o(ys)e(without)h(requiring)
+f(input)h(\014les)g(to)g(b)q(e)h(rew)o(ork)o(ed.)1042 2940
+y(24)p eop
+%%Page: 25 26
+25 25 bop 177 42 a Fe(1.11)70 b(Diagnostic)22 b(Messages)177
+157 y Fn(In)14 b(F)m(unnelW)m(eb,)f(all)g(error)i(messages)f(commence)f(with)
+h(an)g(indicator)f(indicating)g(the)i(sev)o(erit)o(y)g(of)e(the)i(error)177
+207 y(message.)j(Here)d(are)f(some)f(of)h(the)g(formats)e(that)i(I)g(in)o(v)o
+(estigated)g(b)q(efore)h(settling)e(on)h(the)h(\014nal)e(format:)177
+323 y Fi(W--Error)20 b(creating)g(sloth.)177 373 y(E--Error)g(opening)h
+(output)f(file.)177 423 y(S--I'm)h(a)g(teapot.)177 473 y(F--Can't)f(open)h
+(output)g(file.)177 572 y(W-Error)g(creating)f(sloth.)177 622
+y(E-Error)h(opening)f(output)g(file.)177 672 y(S-I'm)h(a)h(teapot.)177
+722 y(F-Can't)f(open)f(output)h(file.)177 822 y(W:Error)g(creating)f(sloth.)
+177 871 y(E:Error)h(opening)f(output)g(file.)177 921 y(S:I'm)h(a)h(teapot.)
+177 971 y(F:Can't)f(open)f(output)h(file.)177 1071 y(W:)h(Error)e(creating)g
+(sloth.)152 b(--)21 b(Format)g(chosen.)177 1120 y(E:)h(Error)e(opening)h
+(output)f(file.)177 1170 y(S:)i(I'm)f(a)g(teapot.)177 1220
+y(F:)h(Can't)e(open)h(output)g(file.)177 1320 y(War-Error)f(creating)g
+(sloth.)177 1369 y(Err-Error)g(opening)g(output)h(file.)177
+1419 y(Sev-I'm)g(a)g(teapot.)177 1469 y(Fat-Can't)f(open)h(output)g(file.)177
+1569 y(W-Old)g(fashioned)f(feature.)177 1668 y(W-Old)h(fashioned)f(feature.)
+177 1768 y(W--Old)h(fashioned)f(feature.)177 1868 y(W:)i(Old)f(fashioned)f
+(feature.)177 1967 y(W:Old)h(fashioned)f(feature.)177 2129
+y Fe(1.12)70 b(Summary)177 2245 y Fn(This)16 b(rather)i(unstructured)g(c)o
+(hapter)g(has)e(addressed)i(some)e(of)f(the)i(k)o(ey)g(design)f(decisions)h
+(of)f(F)m(unnelW)m(eb.)177 2295 y(In)e(man)o(y)e(cases,)j(the)g(alternativ)o
+(es)f(ha)o(v)o(e)g(b)q(een)h(unpleasan)o(t,)e(but)h(I)g(am)f(con\014den)o(t)h
+(that)g(in)g(all)f(cases,)h(a)g(fully)177 2345 y(w)o(ork)n(able)f(solution)g
+(has)h(b)q(een)h(found.)1042 2940 y(25)p eop
+%%Page: 26 27
+26 26 bop 1042 2940 a Fn(26)p eop
+%%Page: 27 28
+27 27 bop 177 375 a Ff(Chapter)34 b(2)177 606 y Fl(F)-10 b(unnelW)g(eb)41
+b(Implemen)m(tation)177 869 y Fe(2.1)70 b(In)n(tro)r(duction)177
+982 y Fn(This)13 b(c)o(hapter)g(con)o(tains)g(notes)g(on)g(the)g(actual)f(C)h
+(co)q(de)g(that)g(implemen)o(ts)d(F)m(unnelW)m(eb)i(V3.)18
+b(This)12 b(c)o(hapter)i(is)177 1032 y(rather)h(patc)o(h)o(y)m(.)20
+b(It)14 b(has)h(acted)g(mainly)d(as)i(a)h(dumping)d(ground)i(for)h(ideas)f
+(that)h(I)f(b)q(othered)i(to)e(write)h(ab)q(out)177 1082 y(during)f(dev)o
+(elopmen)o(t.)177 1241 y Fe(2.2)70 b(History)22 b(of)i(F)-6
+b(unnelW)g(eb)22 b(Implemen)n(tati)o(ons)177 1354 y Fn(The)16
+b(\014rst)h(implemen)o(tation)12 b(of)k(F)m(unnelW)m(eb)f(\(F)m(unnelW)m(eb)g
+(V1\))h(w)o(as)g(written)g(in)g(Ada)g(in)f(Decem)o(b)q(er)h(1986.)177
+1404 y(The)f(pro)r(ject)h(w)o(as)e(initially)e(canned)j(as)g(requiring)f(to)q
+(o)g(m)o(uc)o(h)g(time,)f(but)h(w)o(as)h(resurrected)i(when)e(I)g(decided)177
+1454 y(to)e(commit)d(to)k(Ada)p Fk([USDOD83])d Fn(and)i(realized)h(that)f(I)g
+(needed)i(a)e(program)f(to)h(write)g(to)g(help)g(me)g(to)g(learn)177
+1504 y(Ada.)18 b(F)m(unnelW)m(eb)13 b(V1)h(w)o(as,)g(in)f(fact,)g(m)o(y)g
+(\014rst)h(Ada)g(program.)i(It)e(to)q(ok)g(ab)q(out)g(one)g(mon)o(th)e(to)i
+(write.)177 1576 y(F)m(unnelW)m(eb)21 b(V1)g(w)o(as)g(used)h(in)o(tensiv)o
+(ely)f(b)o(y)g(m)o(yself)e(to)j(write)f(Ada)g(programs)f(from)g(Jan)o(uary)h
+(1986)f(to)177 1626 y(July)e(1989)f(at)h(whic)o(h)g(time)f(I)h(\014nished)h
+(m)o(y)e(Ph.D.)g(and)h(lost)g(access)i(to)e(the)h(V)-5 b(AX.)18
+b(During)g(this)g(time)f(at)177 1676 y(least)f(t)o(w)o(en)o(t)o(y)g(thousand)
+g(lines)f(of)g(co)q(de)h(w)o(ere)h(generated)g(using)e(F)m(unnelW)m(eb.)23
+b(Hardly)15 b(an)o(y)o(one)h(but)f(m)o(yself)177 1726 y(used)g(F)m(unnelW)m
+(eb.)177 1798 y(After)f(losing)f(access)i(to)e(Ada)h(and)f(the)h(V)m(ax)f
+(\(and)g(hence)i(to)e(F)m(unnelW)m(eb\),)g(I)g(w)o(as)h(forced)g(bac)o(k)f
+(to)h(program-)177 1848 y(ming)9 b(the)i(non-literate)g(w)o(a)o(y)m(.)16
+b(F)m(rom)9 b(time)g(to)i(time)e(I)i(found)g(that)f(I)h(needed)h(to)f(use)h
+(some)e(of)g(m)o(y)f(old)h(programs)177 1898 y(that)15 b(I)f(had)h(written)g
+(using)f(Ada)h(and)f(F)m(unnelW)m(eb.)19 b(I)c(knew)g(that)f(Ada)h(w)o(ould)f
+(b)q(ecome)g(a)o(v)n(ailable)e(on)j(more)177 1947 y(mac)o(hines,)e(but)h
+(certainly)g(F)m(unnelW)m(eb)g(w)o(ouldn't.)j(I)d(recognised)h(a)f(strong)g
+(need)h(for)e(a)h(p)q(ortable)g(v)o(ersion)g(of)177 1997 y(F)m(unnelW)m(eb)g
+(written)g(in)f(C)h(but)g(didn't)g(ha)o(v)o(e)f(the)i(time)d(or)i(energy)h
+(to)f(create)h(one.)177 2070 y(Ab)q(out)20 b(this)g(time)f(\(late)h(1989\),)g
+(Da)o(vid)f(Hulse,)i(at)f(the)g(time)f(a)g(studen)o(t)i(in)f(Computer)f
+(Science)i(at)f(the)177 2119 y(Univ)o(ersit)o(y)c(of)f(Adelaide,)h(v)o(olun)o
+(teered)h(to)e(translate)h(the)h(4000)e(line)g(Ada)h(v)o(ersion)g(of)f(F)m
+(unnelW)m(eb)g(in)o(to)g(C.)177 2169 y(T)m(o)e(m)o(y)e(kno)o(wledge)j(this)f
+(translation)g(pro)q(cess)i(to)q(ok)e(ab)q(out)g(three)i(w)o(eeks)f(\(in)f
+(Decem)o(b)q(er)h(1989\).)j(The)d(result)177 2219 y(w)o(as)g(called)g(F)m
+(unnelW)m(eb)f(V2)h(and)f(w)o(as)h(formally)d(signed)j(in)o(to)f(the)i
+(public)e(domain)f(on)i(5)f(Ma)o(y)h(1992.)177 2291 y(In)k(general,)h(Da)o
+(vid)d(Hulse)j(did)e(a)h(go)q(o)q(d)g(job.)29 b(Ho)o(w)o(ev)o(er,)19
+b(the)g(resultan)o(t)f(co)q(de)h(su\013ered)h(from)c(one)i(or)g(few)177
+2341 y(serious)d(defects,)g(the)f(most)f(serious)i(of)e(whic)o(h)h(w)o(as)f
+(a)h(lac)o(k)f(of)h(p)q(ortabilit)o(y)m(.)177 2414 y(Lac)o(k)c(of)g(p)q
+(ortabilit)o(y)f(of)g(the)i(C)f(co)q(de,)i(com)o(bined)c(with)i(the)h(need)g
+(for)f(a)g(rather)h(solid)f(design)g(review,)h(com)o(bined)177
+2463 y(with)17 b(the)g(need)h(to)e(strengthen)j(the)e(program)e(to)i(bring)f
+(it)g(up)h(to)g(pro)q(duction)g(standard,)g(resulted)h(in)e(m)o(y)177
+2513 y(p)q(erforming)10 b(a)i(complete)f(rew)o(orking)g(of)g(the)i(co)q(de.)
+18 b(The)12 b(C)g(co)q(de)g(w)o(as)g(en)o(tirely)m(,)f(but)h(incremen)o
+(tally)m(,)e(replaced)177 2563 y(or)20 b(reformatted.)36 b(The)21
+b(co)q(de)f(w)o(as)g(also)g(strengthened)i(and)e(new)g(features)h(w)o(ere)g
+(added.)37 b(This)20 b(pro)q(cess)177 2613 y(to)q(ok)d(ab)q(out)h(t)o(w)o(o)f
+(mon)o(ths)f(\(No)o(v)o(em)o(b)q(er)h(and)h(Decem)o(b)q(er)g(1991\).)28
+b(A)17 b(further)i(t)o(w)o(o)e(mon)o(ths)f(\(appro)o(x\))i(w)o(ere)177
+2663 y(sp)q(en)o(t)13 b(writing)f(do)q(cumen)o(tation,)f(constructing)i(a)f
+(regression)h(test)h(suite,)e(p)q(orting)g(the)h(program)e(to)h(di\013eren)o
+(t)177 2712 y(mac)o(hines,)h(and)g(sorting)h(out)g(the)g(legal)f(issues)i(in)
+o(v)o(olv)o(ed)e(in)g(its)h(release.)177 2785 y(I)g(w)o(ould)f(lik)o(e)h(to)g
+(tak)o(e)g(this)g(opp)q(ortunit)o(y)g(to)g(record)h(a)f(debt)g(of)g
+(gratitude)g(to)g(Da)o(vid)f(Hulse)h(who)g(translated)177 2835
+y(F)m(unnelW)m(eb)f(from)e(Ada)i(to)f(C.)h(Although)f(m)o(y)f(rew)o(orking)i
+(of)f(his)h(C)g(co)q(de)h(obliterated)f(most)e(of)i(his)f(co)q(de,)i(his)1042
+2940 y(27)p eop
+%%Page: 28 29
+28 28 bop 177 42 a Fn(translation)14 b(w)o(as)g(piv)o(otal)e(to)i(the)h(dev)o
+(elopmen)o(t)e(pro)q(cess.)21 b(Without)14 b(his)g(e\013ort)h(in)e(mo)o(ving)
+f(from)g(Ada)i(to)g(C,)177 91 y(I'm)f(not)j(sure)g(that)f(I)g(w)o(ould)g(ha)o
+(v)o(e)g(m)o(ustered)g(the)h(energy)g(and)f(time)f(to)h(complete)g(the)h(pro)
+q(cess)h(and)e(bring)177 141 y(F)m(unnelW)m(eb)f(up)f(to)h(its)g(curren)o(t)h
+(standard.)177 308 y Fe(2.3)70 b(Wh)n(y)23 b(F)-6 b(unnelW)g(eb)23
+b(W)-6 b(asn't)24 b(Used)e(to)h(W)-6 b(rite)22 b(Itself)177
+426 y Fn(After)d(Kn)o(uth)g(created)g(the)g(W)m(eb)f(literate)h(prepro)q
+(cessing)h(system,)e(he)h(re-wrote)g(it)f(using)g(W)m(eb)g(and)g(dis-)177
+476 y(tributed)13 b(the)g(source)g(co)q(de)g(in)f(W)m(eb)g(source)i(form.)h
+(T)m(o)d(allo)o(w)e(the)j(W)m(eb)f(source)h(co)q(de)h(to)e(b)q(e)g(tangled)g
+(b)o(y)g(users)177 526 y(not)i(y)o(et)g(ha)o(ving)f(a)g(cop)o(y)h(of)g(W)m
+(eb,)f(he)h(also)f(included)h(the)h(tangled)e(P)o(ascal)h(co)q(de)h(for)e
+(the)i(T)m(angler.)177 602 y(While)j(this)g(approac)o(h)h(is)f(heroic)h(and)g
+(serv)o(es)h(to)e(con)o(v)o(ey)h(a)f(commitm)o(en)o(t)e(and)i(a)g
+(con\014dence)i(in)f(literate)177 652 y(programming,)10 b(it)j(seemed)h(to)g
+(me)e(that)i(writing)f(F)m(unnelW)m(eb)g(in)g(F)m(unnelW)m(eb)g(w)o(ould)g
+(simply)f(b)q(e)i(asking)f(for)177 702 y(trouble.)18 b(F)m(or)11
+b(a)g(start,)i(it)e(w)o(ould)g(b)q(e)h(v)o(ery)g(hard)g(to)g(mo)q(dify)d(an)o
+(y)i(feature)i(of)e(F)m(unnelW)m(eb)g(that)h(had)f(b)q(een)i(used)177
+752 y(to)18 b(write)g(F)m(unnelW)m(eb,)f(and)h(the)g(though)o(t)g(of)f(what)g
+(w)o(ould)g(happ)q(en)h(if)f(the)h(w)o(orking)f(executable)i(b)q(ecame)177
+801 y(inop)q(erativ)o(e)14 b(for)f(some)g(reason)i(do)q(es)g(not)e(b)q(ear)i
+(thinking)e(up)q(on.)177 878 y(One)18 b(million)c(billion)h(computer)i
+(programs)f(w)o(ere)j(written)f(in)e(the)i(non-literate)g(st)o(yle)f(b)q
+(efore)h(F)m(unnelW)m(eb)177 928 y(w)o(as)c(created.)20 b(Wh)o(y)13
+b(not)h(one)g(more?)177 1095 y Fe(2.4)70 b(Co)r(ding)22 b(St)n(yle)177
+1213 y Fn(Although)15 b(F)m(unnelW)m(eb)g(w)o(asn't)g(co)q(ded)h(under)g(an)o
+(y)f(particular)g(co)q(ding)g(standard,)h(it)f(w)o(as)g(co)q(ded)h(in)f
+(accor-)177 1263 y(dance)c(with)e(a)g(fairly)g(strict)h(p)q(ersonal)g(st)o
+(yle)g(of)f(C)g(whic)o(h)h(dev)o(elop)q(ed)g(during)g(the)g(dev)o(elopmen)o
+(t)f(of)g(F)m(unnelW)m(eb.)177 1312 y(This)17 b(st)o(yle)f(w)o(as)h
+(subsequen)o(tly)h(em)o(b)q(o)q(died)d(in)h(a)g(real)h(C)f(co)q(ding)h
+(standard)g(prepared)g(for)g(the)g(South)f(Aus-)177 1362 y(tralian)10
+b(Go)o(v)o(ernmen)o(t)g(Departmen)o(t)h(of)f(Lands.)935 1347
+y Fd(1)971 1362 y Fn(Unfortunately)m(,)h(F)m(unnelW)m(eb)g(w)o(as)g(not)g
+(formally)d(dev)o(elop)q(ed)177 1412 y(under)16 b(the)g(standard)g(and)f(so)g
+(some)g(holes)g(remain)f(in)h(F)m(unnelW)m(eb's)g(co)q(ding)g(st)o(yle.)22
+b(This)15 b(section)h(aims)e(to)177 1462 y(describ)q(e)i(some)d(of)g(the)i
+(more)d(imp)q(ortan)o(t)h(asp)q(ects)i(of)e(the)i(co)q(ding)f(st)o(yle.)177
+1538 y Fk(P)o(ortabili)o(t)n(y:)27 b Fn(This)19 b(w)o(as)g(a)g(ma)r(jor)e
+(goal)h(of)h(the)g(F)m(unnelW)m(eb)g(implemen)o(tatio)o(n.)31
+b(Tw)o(o)19 b(excellen)o(t)h(b)q(o)q(oks)177 1588 y(guided)f(this)g(mo)o(v)o
+(e)e(to)i(p)q(ortabilit)o(y)m(.)31 b(They)19 b(w)o(ere)h Fk([Rabino)o
+(witz90])c Fn(\(whic)o(h)j(deals)g(with)f(C)h(co)q(de)h(itself)s(\))177
+1638 y(and)15 b Fk([Horton90])g Fn(\(whic)o(h)g(deals)h(with)f(the)h(p)q
+(ortabilit)o(y)e(of)g(v)n(arious)h(library)g(calls\).)22 b(Other)16
+b(w)o(orks)g(suc)o(h)g(as)177 1687 y Fk([Kernighan88])c Fn(and)i
+Fk([ANSI])g Fn(w)o(ere)h(also)e(helpful.)177 1764 y Fk(Iden)o(ti\014ers:)i
+([Rabino)o(witz90])p Fn(length)10 b(sp)q(eci\014es)k(that)f(for)f(wide)g(p)q
+(ortabilit)o(y)m(,)f(iden)o(ti\014ers)i(of)f(blo)q(c)o(k)g(and)h(\014le)177
+1814 y(scop)q(e)j(should)f(b)q(e)h(unique)f(to)g(eigh)o(t)f(c)o(haracters,)j
+(and)e(iden)o(ti\014ers)h(of)e(program)f(scop)q(e)j(should)f(b)q(e)h(unique)f
+(to)177 1863 y(six)d(c)o(haracters.)19 b(I)11 b(ha)o(v)o(e)h(gone)f(further)i
+(in)e(F)m(unnelW)m(eb)g(and)h(actually)e(made)h(these)i(restrictions)g
+(actual)e(limits)177 1913 y(on)j(iden)o(ti\014er)g(length.)177
+1989 y(Because)k(names)d(m)o(ust)g(b)q(e)i(so)f(short,)g(a)g(system)g(of)f
+(abbreviations)h(w)o(as)g(dev)o(elop)q(ed)g(to)g(organize)g(the)h(iden-)177
+2039 y(ti\014ers)f(used)h(within)d(F)m(unnelW)m(eb.)23 b(Eac)o(h)15
+b(abbreviation)g(consists)i(of)d(a)i(letter)g(pair.)22 b(Here)17
+b(are)f Fh(some)f Fn(of)g(the)177 2089 y(abbreviations)f(used:)177
+2209 y Fi(bp)22 b(-)f(Body)g(Part.)177 2259 y(cm)h(-)f(Compare.)f(Used)h(to)h
+(prefix)e(comparison)g(routines)g(that)h(return)g([-1,0,1].)177
+2309 y(dc)h(-)f(Document)f(component.)177 2359 y(dm)i(-)f(Dump)g(package.)177
+2408 y(el)h(-)f(Element.)177 2458 y(eq)h(-)f(Equal.)g(Used)g(to)g(prefix)g
+(comparison)e(routines)h(that)h(return)g(a)h(boolean.)177 2508
+y(ex)g(-)f(Expression.)177 2558 y(f)44 b(-)21 b(Global)g(files.)177
+2608 y(ll)h(-)f(List)g(of)g(lists.)177 2658 y(ln)h(-)f(Line)g(record.)177
+2707 y(ls)h(-)f(List)g(Package.)177 2757 y(lr)h(-)f(Lister)g(package.)p
+177 2796 709 2 v 223 2823 a Fc(1)241 2835 y Fb(The)11 b(standard)e(is)j
+(curren)o(tly)d(una)o(v)n(ailable)o(,)g(but)i(is)g(lik)o(ely)f(to)h(b)q(e)g
+(released)f(or)h(published)e(ev)o(en)o(tually)m(.)1042 2940
+y Fn(28)p eop
+%%Page: 29 30
+29 29 bop 177 42 a Fi(ma)22 b(-)f(Macro.)177 91 y(mc)h(-)f(Macro)g(Call.)177
+141 y(mn)h(-)f(Macro)g(Name.)177 191 y(op)h(-)f(Options)f(package.)177
+241 y(pr)i(-)f(Parser.)177 291 y(ps)h(-)f(Position)f(record.)177
+340 y(sc)i(-)f(Scrap)g(record.)177 390 y(sn)h(-)f(Section.)177
+440 y(tb)h(-)f(Table)g(package.)177 490 y(ty)h(-)f(Typesetter)f(directive.)
+177 540 y(wf)i(-)f(Write)g(file)g(package.)177 589 y(wl)h(-)f(Write)g(with)g
+(EOL)g(\(misc.c\).)177 639 y(wr)h(-)f(Write)217 b(\(misc.c\).)177
+756 y Fk(P)o(oin)o(ters:)15 b Fn(V)m(ariables)f(or)g(t)o(yp)q(es)g(denoting)g
+(p)q(oin)o(ters)g(start)h(with)e(\\)p Fi(p)p 1292 756 14 2
+v 16 w Fn(".)177 831 y Fk(T)o(yp)q(es:)18 b Fn(Names)13 b(denoting)g(t)o(yp)q
+(es)h(end)g(in)f(\\)p 898 831 V 15 w Fi(t)p Fn(".)18 b(Th)o(us,)13
+b(a)g(t)o(yp)q(e)h(for)f(a)g(p)q(oin)o(ter)g(to)g(a)g(table)g(w)o(ould)g(b)q
+(e)h(named)177 881 y Fi(p)p 202 881 V 16 w(tb)p 262 881 V 15
+w(t)p Fn(.)177 956 y Fk(File)j(names:)23 b Fn(All)16 b(\014les)h(used)g(in)f
+(F)m(unnelW)m(eb)g(ha)o(v)o(e)g(\014le)g(names)g(that)h(are)f(from)f(one)i
+(to)f(eigh)o(t)g(c)o(haracters)177 1005 y(long)d(and)g(\014le)g(extensions)i
+(that)e(are)h(from)e(one)h(to)h(three)g(c)o(haracters)i(long.)h(This)c
+(ensures)i(that)f(the)g(\014les)g(can)177 1055 y(b)q(e)h(p)q(ortably)e(mo)o
+(v)o(ed)f(to)i(all)f(kinds)h(of)f(mac)o(hines,)f(ev)o(en)j(MSDOS!)177
+1218 y Fe(2.5)70 b(Use)22 b(of)h(Memory)177 1334 y Fn(F)m(unnelW)m(eb)15
+b(is)h(not)g(a)g(memory-stressed)f(program.)23 b(Ho)o(w)o(ev)o(er,)16
+b(during)f(its)h(dev)o(elopmen)o(t,)f(problems)g(with)177 1384
+y(the)g(managemen)o(t)d(of)h(memory)f(seemed)j(to)f(crop)g(up)h(again)e(and)h
+(again.)k(This)c(section)h(do)q(cumen)o(ts)f(some)f(of)177
+1434 y(these)i(problems)e(and)h(the)h(solutions)e(adopted.)177
+1509 y(There)22 b(are)e(three)i(places)e(where)i(memory)17
+b(can)k(b)q(e)g(obtained:)30 b(the)21 b(heap,)g(the)g(stac)o(k,)h(and)e(from)
+e(static)177 1558 y(v)n(ariables.)f(The)e(follo)o(wing)c(three)k(sections)g
+(deal)f(with)f(eac)o(h)i(of)e(these)i(areas.)177 1721 y Fe(2.6)70
+b(The)22 b(Heap)177 1837 y Fn(One)17 b(of)f(the)h(great)g(frustrations)f(of)g
+(b)q(eing)h(a)f(user)h(is)f(to)h(\014nd)f(that)h(a)f(computer)g(program)e(is)
+j(complaining)177 1887 y(ab)q(out)d(lac)o(k)f(of)g(memory)f(when)i(one)g(kno)
+o(ws)g(full)e(w)o(ell)i(that)g(one)g(has)g(allo)q(cated)f(at)h(least)g(ten)g
+(times)f(as)h(m)o(uc)o(h)177 1937 y(memory)f(to)j(the)g(program)e(as)i(it)f
+(w)o(ould)g(ev)o(er)i(need)f(to)g(do)f(its)h(job.)23 b(The)16
+b(reason)g(for)g(suc)o(h)g(error)h(messages)177 1987 y(usually)h(has)h(to)g
+(do)f(with)g(the)i(programmer)c(setting)j(a)g(\014xed)g(\\reasonable")g
+(limit)d(to)i(a)h(particular)f(data)177 2037 y(structure)f(and)d(then)h(lo)q
+(c)o(king)e(it)i(up)f(in)o(to)g(an)g(arra)o(y)g(whose)h(b)q(ound)g(is)f(sp)q
+(eci\014ed)i(b)o(y)e(a)g(constan)o(t.)21 b(While)13 b(the)177
+2086 y(use)i(of)e(arra)o(ys)h(can)g(increase)h(the)f(sp)q(eed)h(of)e(a)h
+(program,)d(it)i(also)h(means)e(that)i(the)h(user)f(cannot)g(increase)h(the)
+177 2136 y(capacit)o(y)f(of)g(the)h(program)e(without)h(obtaining)f(the)i
+(source)h(co)q(de)f(and)g(recompiling)d(it,)i(whic)o(h)g(is)g(usually)g(a)177
+2186 y(daun)o(ting)f(option.)177 2261 y(The)g(alternativ)o(e)g(is)f(to)h(use)
+h(the)f(heap)g(for)f(all)g(data)g(structures)j(that)e(can)g(gro)o(w)f(in)h
+(prop)q(ortion)f(to)h(the)g(size)g(of)177 2311 y(the)f(user's)g(input.)17
+b(This)11 b(rule)h(has)f(b)q(een)h(follo)o(w)o(ed)e(rigorously)g(in)h(F)m
+(unnelW)m(eb.)16 b(This)11 b(means)g(that)g(as)g(memory)177
+2360 y(spaces)h(increase,)g(users)g(will)d(b)q(e)i(able)g(to)f(hand)h(their)f
+(v)o(ersion)h(of)f(F)m(unnelW)m(eb)g(more)g(memory)e(without)i(ha)o(ving)177
+2410 y(to)k(recompile)f(it.)998 2510 y(|)h Fm(x)g Fn(|)177
+2635 y(Some)i(problems)f(arose)j(early)e(on)h(the)g(Macin)o(tosh)g(in)f(the)h
+(use)h(of)e(the)h(heap.)27 b(It)17 b(seems)g(that)f(some)g(of)g(the)177
+2685 y(allo)q(cations)i(I)i(w)o(as)f(attempting)f(to)h(mak)o(e)f(w)o(ere)i
+(failing)d(for)i(some)g(obscure)i(reason,)f(p)q(ossibly)f(m)o(y)f(fault.)177
+2735 y(Whatev)o(er)c(it)f(w)o(as,)g(it)g(w)o(en)o(t)g(a)o(w)o(a)o(y)g(when)g
+(I)h(replaced)g(direct)g(calls)f(to)g Fi(malloc)f Fn(with)h(calls)g(to)g(a)g
+(mini)e(pac)o(k)n(age)177 2785 y(I)j(wrote)g(\(called)f Fi(memory)p
+Fn(\))f(that)i(allo)q(cated)f(large)g(c)o(h)o(unks)h(of)f(memory)e(and)j
+(then)g(doled)f(out)h(small)d(pieces)k(as)177 2835 y(required)g(b)o(y)f(the)g
+(rest)h(of)e(the)i(program.)1042 2940 y(29)p eop
+%%Page: 30 31
+30 30 bop 177 42 a Fn(Ha)o(ving)13 b(a)h(pac)o(k)n(age)f(to)h(manage)e(all)h
+(the)h(memory)e(allo)q(cation)g(had)i(t)o(w)o(o)f(other)h(b)q(ene\014ts.)177
+122 y(First,)k(only)f(one)h(c)o(hec)o(k)g(w)o(as)g(required)g(in)f(the)h(en)o
+(tire)g(program)e(to)h(see)i(if)e(memory)e(had)i(run)h(out)f(\(in)g(the)177
+172 y(memory)f(pac)o(k)n(age\),)i(and)g(if)g(that)g(failed,)f(the)i(program)e
+(could)h(b)q(e)g(brough)o(t)g(to)g(a)g(screaming)g(halt.)30
+b(This)177 222 y(organization)20 b(w)o(as)g(far)g(preferable)i(to)e(ha)o
+(ving)g(eac)o(h)h(piece)g(of)f(co)q(de)i(that)f(needed)h(to)e(allo)q(cate)g
+(memory)177 272 y(ha)o(ving)13 b(to)h(c)o(hec)o(k)h(to)e(see)i(if)e
+Fi(malloc)g Fn(had)h(failed.)177 352 y(Second,)21 b(the)f(decision)g(to)f
+(construct)i(a)f(mini-shell)c(within)j(F)m(unnelW)m(eb)g(to)g(supp)q(ort)i
+(regression)f(testing)177 402 y(mean)o(t)11 b(that)h(F)m(unnelW)m(eb)g(prop)q
+(er)h(could)f(b)q(e)g(run)h(man)o(y)d(times)h(in)h(an)o(y)f(giv)o(en)h(in)o
+(v)o(o)q(cation)f(of)g(F)m(unnelW)m(eb.)17 b(As)177 452 y(a)10
+b(consequence)j(it)d(w)o(as)h(necessary)h(to)f(mak)o(e)e(sure)i(that)g(there)
+g(w)o(as)g(no)f(memory)e(leak)n(age)i(b)q(et)o(w)o(een)i(in)o(v)o(o)q
+(cations)177 502 y(of)18 b(F)m(unnelW)m(eb)h(prop)q(er.)33
+b(This)19 b(w)o(as)g(accomplished)e(b)o(y)i(rew)o(orking)g(the)g(memory)d
+(pac)o(k)n(age)j(to)f(op)q(erate)i(a)177 551 y(w)o(atermark)12
+b(system.)17 b(The)d(user)g(of)e(the)i(pac)o(k)n(age,)e(when)h(requesting)h
+(memory)m(,)c(could)i(request)j(\\temp)q(orary")177 601 y(or)g(\\p)q(ermanen)
+o(t".)22 b(If)15 b(p)q(ermanen)o(t,)g(the)h(memory)d(pac)o(k)n(age)i(forgot)f
+(that)i(it)f(had)g(allo)q(cated)g(the)h(memory)m(.)j(If)177
+651 y(temp)q(orary)m(,)12 b(the)i(memory)c(pac)o(k)n(age)j(places)h(the)g
+(allo)q(cated)f(blo)q(c)o(k)g(on)g(a)g(list.)k(There)d(w)o(as)f(then)h(a)f
+(function)g(in)177 701 y(the)f(memory)d(pac)o(k)n(age)j(that)f(could)h(b)q(e)
+g(called)f(to)g(deallo)q(cate)h(all)e(the)i(temp)q(orary)f(memory)m(.)k(Th)o
+(us,)c(so)h(long)f(as)177 751 y(all)i(requests)j(for)e(memory)d(within)i(F)m
+(unnelW)m(eb)h(prop)q(er)h(w)o(ere)g(for)e(temp)q(orary)h(memory)m(,)c(and)k
+(that)g(memory)177 800 y(w)o(as)g(freed)h(at)e(the)i(end)f(of)g(ev)o(ery)g
+(run,)g(one)g(could)g(b)q(e)g(sure)h(that)f(there)h(w)o(as)f(no)g(memory)d
+(leak)n(age.)177 981 y Fe(2.7)70 b(The)22 b(Stac)n(k)177 1105
+y Fn(F)m(or)13 b(a)f(while)g(during)h(the)g(dev)o(elopmen)o(t)f(of)g(F)m
+(unnelW)m(eb)g(a)h(particularly)f(nast)o(y)h(bug)f(pro)o(v)o(ed)h(extremely)g
+(hard)177 1155 y(to)j(\014nd.)26 b(The)17 b(symptom)c(w)o(as)j(that)h(F)m
+(unnelW)m(eb)f(w)o(ould)f(crash,)i(sometimes)e(at)h(random,)f(but)h(more)g
+(often)177 1205 y(up)q(on)h(en)o(tering)g(a)g(particular)f(function.)27
+b(In)16 b(the)i(end)f(ab)q(out)g(a)f(da)o(y)h(of)f(sp)q(eci\014c)i(debugging)
+e(w)o(as)h(required)177 1255 y(b)q(efore)e(the)f(problem)e(w)o(as)i(trac)o(k)
+o(ed)h(do)o(wn)e(to)h(a)f(stac)o(k)h(problem.)j(It)d(turned)g(out)g(that)g
+(someho)o(w)e(\(either)j(the)177 1305 y(fault)f(of)g(the)i(Macin)o(tosh)e(or)
+h(the)g(THINK)h(C)e(language)g(system\),)h(only)f(6K)g(w)o(as)h(b)q(eing)g
+(allo)q(cated)f(for)g(stac)o(k)177 1354 y(space!!!!!!!)177
+1435 y(This)f(exp)q(erience)h(led)f(me)e(immediately)e(to)k(go)f(through)g
+(the)i(en)o(tire)f(program)e(and)h(eliminate)f(\(or)h(remo)o(v)o(e)g(to)177
+1485 y(the)j(heap\))f(an)o(y)f(automatic)f(v)n(ariable)h(declarations)h(that)
+g(used)h(more)e(than)h(one)g(h)o(undred)g(or)g(so)g(b)o(ytes.)177
+1565 y(The)g(lesson)g(is)g(clearly)f(that)h(C)f(programs)g(that)g(use)i(more)
+d(than)i(a)f(few)h(thousand)f(b)o(ytes)i(of)e(stac)o(k)h(space)g(are)177
+1615 y(risking)f(their)i(p)q(ortabilit)o(y)m(.)h(All)d(large)h(data)f
+(structures)j(should)e(b)q(e)h(placed)f(in)f(the)i(heap.)177
+1796 y Fe(2.8)70 b(Static)21 b(V)-6 b(ariables)177 1920 y Fn(Static)11
+b(v)n(ariables)e(also)h(pro)o(v)o(ed)g(a)g(problem)f(on)i(the)g(Macin)o
+(tosh.)16 b(It)11 b(turns)g(out)f(that)h(the)g(Macin)o(tosh)f(THINK)h(C)177
+1970 y(compiler)g(do)q(es)h(not)g(allo)o(w)e(more)h(than)h(32K)f(of)g
+(statics)i Fh(in)g(the)g(entir)n(e)f(pr)n(o)n(gr)n(am)p Fn(.)17
+b(F)m(or)11 b(a)h(while)f(this)h(restriction)177 2020 y(w)o(as)17
+b(a)f(serious)i(threat)g(to)e(the)i(program)d(as)i(it)f(w)o(as)h(disco)o(v)o
+(ered)h(that)f(constan)o(t)g(strings)g(w)o(ere)h(included)f(in)177
+2070 y(this)d(total!)k(Ho)o(w)o(ev)o(er,)c(some)f(searc)o(hing)h(rev)o(ealed)
+h(a)e(compiler)g(option)g(that)h(remo)o(v)o(ed)f(the)i(strings)f(from)e(the)
+177 2119 y(static)i(category)m(.)177 2200 y(Nev)o(ertheless,)k(the)e(32K)g
+(limit)c(is)k(rather)g(sev)o(ere.)25 b(Again,)15 b(it)g(seems)h(that)f(for)h
+(p)q(ortabilit)o(y)e(reasons,)i(C)g(pro-)177 2250 y(grams)f(that)h(use)g(a)g
+(lot)f(of)h(static)g(v)n(ariables)f(are)h(risking)g(their)g(p)q(ortabilit)o
+(y)m(.)22 b(As)16 b(a)g(result,)h(the)f(F)m(unnelW)m(eb)177
+2300 y(co)q(de)f(a)o(v)o(oids)e(static)h(v)n(ariables)f(where)i(p)q(ossible)f
+(in)g(fa)o(v)o(our)f(of)g(the)h(heap.)177 2480 y Fe(2.9)70
+b(Implemen)n(ti)o(ng)20 b(T)-6 b(ext)23 b(Inden)n(tation)177
+2605 y Fn(A)o(t)e(one)g(p)q(oin)o(t)f(during)g(the)h(dev)o(elopmen)o(t)f(of)g
+(F)m(unnelW)m(eb,)h(text)h(inden)o(tation)e(w)o(as)g(fully)g(implem)o(en)o
+(ted.)177 2654 y(Ho)o(w)o(ev)o(er,)12 b(it)g(w)o(as)g(subsequen)o(tly)h(remo)
+o(v)o(ed)e(b)q(ecause)i(it)f(w)o(as)g(considered)h(a)f(dangerous)g(feature.)
+18 b(This)12 b(section)177 2704 y(records)17 b(the)f(w)o(a)o(y)f(in)g(whic)o
+(h)h(text)g(inden)o(tation)f(w)o(as)g(implemen)o(ted)e(so)j(that)g(if)e(the)i
+(feature)h(ev)o(er)f(has)g(to)f(b)q(e)177 2754 y(put)f(bac)o(k,)g(this)g(tec)
+o(hnique)g(can)h(b)q(e)f(used)h(again.)177 2835 y(1.)j(Create)d(a)e(new)i
+(\014eld)f(in)f(the)i Fi(sc)p 739 2835 14 2 v 15 w(t)e Fn(record)j(call)d
+Fi(sc)p 1037 2835 V 15 w(postn)p Fn(.)1042 2940 y(30)p eop
+%%Page: 31 32
+31 31 bop 308 42 a Fi(char)21 b(*sc_postn;)f(/*)h(Pointer)f(in)i(the)f(range)
+g([sc_first,sc_las)o(t+1].)236 b(*/)657 91 y(/*)21 b(It)g(is)h(the)f(minimum)
+f(possible)g(value)h(of)h(sc_postn)e(for)108 b(*/)657 141 y(/*)21
+b(which)g(EOL)g(does)g(not)g(appear)g(in)g(*sc_postn..*sc_la)o(st.)84
+b(*/)657 191 y(/*)21 b(i.e.)g(Points)g(to)g(the)g(byte)g(following)f(the)h
+(first)g(EOL)g(in)65 b(*/)657 241 y(/*)21 b(the)g(scrap)g(or)g(sc_first)f(if)
+i(EOL)f(does)g(not)g(appear.)173 b(*/)177 342 y Fn(2.)17 b(Mo)q(dify)10
+b(the)i(scanner)h(so)e(that)g(it)g(generates)i(this)e(\014eld.)18
+b(Sendtext)12 b(should)f(b)q(e)h(mo)q(di\014ed)e(so)h(that)g(it)g(accepts)177
+391 y(an)j(argumen)o(t)f(for)g(the)i Fi(p)p 581 391 14 2 v
+15 w(postn)e Fn(v)n(alue.)177 492 y Fi(LOCAL)21 b(void)g(sendtext)f
+(P_\(\(p_ps_t,char)f(*,char)h(*,char)h(*,bool\)\);)177 542
+y(LOCAL)g(void)g(sendtext\(p_tkps,p)o(_firs)o(t,p_l)o(ast,)o(p_pos)o(tn,is)o
+(_whit)o(e\))177 592 y(/*)h(Appends)e(a)h(text)g(token)g(to)h(the)f(end)g(of)
+g(the)g(token)g(list.)544 b(*/)177 642 y(/*)22 b(IN:)f(p_ps)g(is)g(a)h
+(pointer)e(to)h(a)h(position)e(structure)g(giving)h(the)g(position)f(of)h
+(the)65 b(*/)177 691 y(/*)109 b(first)20 b(character)g(of)i(the)f(token.)914
+b(*/)177 741 y(/*)22 b(IN:)f(p_first)f(and)h(p_last)g(point)g(to)g(the)g
+(first)g(and)g(last)g(byte)g(of)g(the)h(text)e(scrap.)h(*/)177
+791 y(/*)h(IN:)f(p_postn)f(has)h(the)g(same)g(definition)f(as)h(sc_postn)g
+(\(see)g(fwdata.h\).)259 b(*/)177 841 y(/*)22 b(IN:)f(is_white)f(should)g(be)
+i(set)f(to)g(TRUE)g(iff)g(scrap)g(is)h(entirely)e(whitespace.)150
+b(*/)177 891 y(p_ps_t)21 b(p_tkps;)177 941 y(char)43 b(*p_first;)177
+990 y(char)g(*p_last;)177 1040 y(char)g(*p_postn;)177 1090
+y(bool)65 b(is_white;)177 1140 y({)199 1190 y(tk_t)21 b(token;)199
+1289 y(/*)g(Empty)g(text)g(scraps)g(should)f(never)h(be)g(generated.)f(*/)199
+1339 y(assert\(p_first<=p)o(_last)o(,"sen)o(dtext)o(:)f(Text)i(scrap)g
+(bounds)f(are)h(bad."\);)199 1439 y(/*)g(If)h(ch=EOL)e(then)h(we)h(should)e
+(be)i(scanning)e(more)h(text,)f(not)i(shipping)e(it!)h(*/)199
+1488 y(assert\(ch!=EOL,"s)o(entte)o(xt:)e(Shipping)h(text)h(while)f(still)h
+(more)g(to)h(scan."\);)199 1588 y(/*)f(Check)g(that)g(p_postn)f(is)i(in)f
+(range.)g(See)g(definition)f(in)h(fwdata.h.)f(*/)199 1638 y
+(assert\(p_first<=p)o(_post)o(n)f(&&)i(p_postn<=p_last+1,)352
+1688 y("sendtext:)e(p_postn)i(is)g(out)g(of)h(range."\);)199
+1787 y(/*)f(Debug:)g(Check)g(the)g(p_postn)f(field)h(using)g(a)g(brute)g
+(force)g(check.)f(*/)199 1837 y({)221 1887 y(char)h(*i,*j;)221
+1937 y(j=p_first;)221 1987 y(for)g(\(i=p_first;i<=p_l)o(ast;i)o(++\))286
+2036 y(if)h(\(*i==EOL\))352 2086 y(j=i+1;)221 2136 y(assert\(j==p_post)o
+(n,"se)o(ndtex)o(t:)d(sc_postn)h(field)h(is)g(incorrect."\);)199
+2186 y(})199 2286 y(/*)g(Load)g(the)g(text)g(token.)g(*/)199
+2335 y(token.tk_kind)172 b(=)21 b(TK_TEXT;)199 2385 y(ASSIGN\(token.tk_p)o
+(s,*p_)o(tkps\))o(;)199 2435 y(token.tk_sc.sc_fi)o(rst)e(=)i(p_first;)199
+2485 y(token.tk_sc.sc_la)o(st)41 b(=)21 b(p_last;)199 2535
+y(token.tk_sc.sc_po)o(stn)e(=)i(p_postn;)199 2584 y(token.tk_white)150
+b(=)21 b(is_white;)199 2634 y(token.tk_parno)150 b(=)21 b(0;)199
+2684 y(ls_add\(token_list)o(,PV)e(&token\);)177 2734 y(})177
+2835 y Fn(Then)c(all)d(the)j(calls)e(to)h(sendtext)h(ha)o(v)o(e)f(to)g(b)q(e)
+g(c)o(hanged:)1042 2940 y(31)p eop
+%%Page: 32 33
+32 32 bop 177 42 a Fi(/*)22 b(@)f(instructs)f(FunnelWeb)g(to)h(replace)g(the)
+g(special)f(construct)g(with)h(the)g(*/)177 91 y(/*)h(special)e(character.)g
+(Luckily)g(one)h(appears)f(just)h(before)g(the)g(@)h(!!)108
+b(*/)177 141 y(/*)22 b(Note:)e(FALSE)h(is)g(OK)h(because)e(space)h(is)g(not)g
+(a)h(legal)f(specialch.)150 b(*/)177 191 y(/*)22 b(Note:)e(Setting)h
+(parameter)f(p_postn)g(to)h(p_ch-1)g(is)g(OK)h(as)f(EOL)g(is)h(not)f(a)g(*/)
+177 241 y(/*)152 b(legal)21 b(specialch.)913 b(*/)177 291 y
+(sendtext\(&ps_spec,)o(p_ch-)o(1,p_c)o(h-1,p)o(_ch-1)o(,FAL)o(SE\);)177
+340 y(break;)177 440 y(/*)22 b(+)f(instructs)f(FunnelWeb)g(to)h(insert)g(an)g
+(EOL.)g(We)h(can't)e(look)h(to)h(the)f(end)g(of)g(*/)177 490
+y(/*)h(the)f(previous)f(line)h(to)g(find)g(an)h(EOL)f(as)g(this)g(might)g(be)
+g(the)g(first)g(line.)64 b(*/)177 540 y(/*)22 b(Running)e(ahead)h(to)g(the)g
+(end)g(of)h(the)f(line)g(is)g(expensive,)f(and)h(having)g(the)64
+b(*/)177 589 y(/*)22 b(liner)e(mini-package)g(maintain)g(a)h(variable)f(for)i
+(it)f(would)g(be)g(extra)173 b(*/)177 639 y(/*)22 b(housekeeping.)d(Instead)h
+(of)h(all)h(this,)e(we)i(just)f(point)f(to)i(a)f(static.)151
+b(*/)177 689 y({CONST)21 b(static)f(char)h(stateol)g(=)g(EOL;)199
+739 y(sendtext\(&ps_spec)o(,&sta)o(teol,)o(&stat)o(eol,\()o(&sta)o(teol\))o
+(+1,TR)o(UE\);})177 789 y(break;)177 888 y(/*)h(If)f(we)g(hit)g(something)f
+(that)h(ends)g(a)h(text)f(token)g(*/)177 938 y(/*)h(then)f(we)g(can)g
+(transmit)f(a)i(white)f(text)g(token.)64 b(*/)177 988 y(if)22
+b(\(ch==specialch)c(||)k(ch==EOFCH\))243 1038 y({sendtext\(&ps_s)o(tart,)o
+(p_fir)o(st,p_)o(ch-1,)o(MAX\()o(p_sol)o(,p_fi)o(rst\),)o(TRUE\))o(;)d
+(return;})177 1137 y(/*)j(Otherwise)d(we)j(have)f(some)g(more)g
+(\(non-white\))e(text)i(to)h(scan.)e(*/)177 1187 y(/*)i(We)f(can)g(then)g
+(send)g(a)h(non-white)e(text)h(token.)303 b(*/)177 1237 y(while)21
+b(\(ch!=specialch)e(&&)i(ch!=EOFCH\))243 1287 y(NEXTCH;)177
+1337 y(sendtext\(&ps_start)o(,p_fi)o(rst,p)o(_ch-1)o(,MAX\()o(p_so)o(l,p_f)o
+(irst\))o(,FALS)o(E\);)177 1442 y Fn(The)14 b(dump)f(co)q(de)i(needs)g(to)f
+(b)q(e)g(c)o(hanged)h(to)q(o!)352 1548 y Fi(wf_str\(p_wf,"\\")o("\);)177
+1597 y(assert\(token->tk_s)o(c.sc_)o(first)j(!=NULL,"dm_tkls:)h(NULL)i
+(ptr1."\);)177 1647 y(assert\(token->tk_s)o(c.sc_)o(last)40
+b(!=NULL,"dm_tkls:)19 b(NULL)i(ptr2."\);)177 1697 y(for)g
+(\(i=token->tk_sc.sc_)o(first)o(;)e(i<=token->tk_sc.s)o(c_las)o(t;)g(i++\))
+221 1747 y({)243 1797 y(if)i(\(i==token->tk_sc.)o(sc_po)o(stn\))308
+1846 y(wf_str\(p_wf,"<pos)o(tn>"\))o(;)243 1896 y(if)g(\(*i=='\\n'\))308
+1946 y(wf_wl\(p_wf,""\);)243 1996 y(else)308 2046 y(dm_byte\(p_wf,*\(\(u)o
+(byte_)d(*\))k(i\)\);)221 2095 y(})177 2145 y(if)g(\(i==token->tk_s)o(c.sc_)o
+(postn)o(\))243 2195 y(wf_str\(p_wf,"<p)o(ostn>)o("\);)177
+2245 y(wf_str\(p_wf,"\\""\);)177 2295 y(})177 2400 y Fn(3.)37
+b(Ov)o(er)22 b(in)e(the)h(T)m(angle)e(mo)q(dule,)h(create)i(a)e(massiv)o(e)f
+(arra)o(y)h(of)g(p)q(oin)o(ters)h(to)f(scraps)i(to)e(b)q(e)h(used)h(as)e(a)
+177 2450 y(stac)o(k.)f(Main)o(tain)13 b(p)q(oin)o(ters)h(in)o(to)g(the)g
+(stac)o(k)h(called)e Fi(current)g Fn(and)h Fh(b)n(ase)g Fn(\(similar)e(to)i
+(the)g(blank)f(inden)o(tation)177 2500 y(v)n(ariables\).)18
+b(Implemen)o(t)11 b(the)k(follo)o(wing:)239 2605 y Fm(\017)21
+b Fn(T)m(o)14 b(write)i(out)f(a)g(scrap,)h(scan)f(it)g(b)o(yte)h(b)o(y)f(b)o
+(yte.)22 b(Output)16 b(eac)o(h)g(b)o(yte.)22 b(When)15 b(y)o(ou)g(hit)g(an)g
+(EOL,)g(p)q(op)281 2655 y(the)g(stac)o(k)g(bac)o(k)g(to)f Fi(base)p
+Fn(.)20 b(Then)15 b(write)g(out)g(an)f(EOL)h(follo)o(w)o(ed)e(b)o(y)i(the)g
+(stac)o(k)g(con)o(ten)o(ts)h(but)f(writing)281 2705 y(eac)o(h)d(scrap)h(only)
+f(from)e Fi(postn)h Fn(to)h(end)g(end)h(of)e(eac)o(h)i(scrap.)18
+b(When)12 b(y)o(ou)g(ha)o(v)o(e)g(\014nished)g(the)h(new)f(scrap,)281
+2755 y(push)i(it)g(on)g(the)g(stac)o(k.)239 2835 y Fm(\017)21
+b Fn(When)14 b(y)o(ou)f(hit)h(a)g(new)g(macro)f(to)g(expand,)h(sa)o(v)o(e)g
+Fi(base)p Fn(.)j(Restore)e(it)e(later.)1042 2940 y(32)p eop
+%%Page: 33 34
+33 33 bop 177 42 a Fn(The)14 b Fi(postn)f Fn(\014eld)h(solv)o(es)g(the)h(big)
+e(problem)g(of)g(ho)o(w)g(to)h(cop)q(e)h(with)e(something)g(lik)o(e)g(this:)
+177 158 y Fi(The)21 b(rain)g(in)h(Spain)177 208 y(falls)f(mainly)f(@<on)h
+(the)h(plain@>)177 324 y Fn(The)f(trouble)g(is)f(that)h(w)o(e)g(w)o(an)o(t)f
+(to)g(text)h(inden)o(t)g(the)g(lines)g(in)f Fi(@<on)h(the)g(plain@>)e
+Fn(with)h(just)h(\\)p Fi(falls)177 374 y(mainly)g Fn(".)31
+b(Ho)o(w)o(ev)o(er,)20 b(this)f(string)f(is)g(only)g(part)h(of)f(a)g(scrap.)
+33 b(The)19 b(solution)e(is)i(to)f(get)h(the)g(scanner)h(to)177
+423 y(record,)c(in)e(the)i Fi(postn)e Fn(\014eld)h(of)f(eac)o(h)h(scrap,)h
+(the)f(p)q(osition)f(of)h(the)g(\014rst)h(b)o(yte)f(with)g(a)f(EOL-free)i
+(run)f(to)g(the)177 473 y(end)g(of)e(the)h(scrap.)177 548 y(This)i(sc)o(heme)
+g(is)g(v)o(ery)h(e\016cien)o(t)f(b)q(ecause)i(all)d(w)o(e)h(are)h(doing)e(is)
+h(pushing)g(and)g(p)q(opping)f(p)q(oin)o(ters)i(to)f(scraps)177
+598 y(on)g(a)g(stac)o(k)h(arra)o(y)m(.)25 b(The)16 b(main)e(disadv)n(an)o
+(tage)i(is)g(that)g(the)h(arra)o(y)f(m)o(ust)g(necessarily)h(b)q(e)g
+(\014nite)f(and)h(w)o(ould)177 648 y(imp)q(ose)c(a)h(limit)d(on)i(the)i
+(depth)f(of)g(inden)o(tation)f(nesting)h(\(not)g(a)g(big)f(problem\).)1042
+2940 y(33)p eop
+%%Page: 34 35
+34 34 bop 1042 2940 a Fn(34)p eop
+%%Page: 35 36
+35 35 bop 177 377 a Ff(Chapter)34 b(3)177 609 y Fl(F)-10 b(unnelW)g(eb)41
+b(Mo)s(di\014cation)177 875 y Fe(3.1)70 b(In)n(tro)r(duction)177
+990 y Fn(This)19 b(c)o(hapter)h(deals)f(with)g(mo)q(di\014cations)e(to)i(F)m
+(unnelW)m(eb.)33 b(Although)19 b(the)g(GNU)g(license)h(under)g(whic)o(h)177
+1040 y(F)m(unnelW)m(eb)10 b(is)h(distributed)h(allo)o(ws)d(an)o(y)o(one)i(to)
+f(mo)q(dify)f(F)m(unnelW)m(eb)h(and)h(distribute)g(the)g(mo)q(di\014ed)f(v)o
+(ersions,)177 1090 y(there)15 b(are)f(a)f(n)o(um)o(b)q(er)f(of)h(dangers)h
+(in)f(doing)g(this.)k(This)d(c)o(hapter)g(explains)f(the)h(dangers)g(and)f
+(presen)o(ts)j(some)177 1140 y(issues)f(that)f(y)o(ou)g(should)f(think)h(ab)q
+(out)g(if)f(y)o(ou)g(in)o(tend)h(to)g(distribute)g(mo)q(di\014ed)f(v)o
+(ersions)h(of)f(F)m(unnelW)m(eb.)177 1301 y Fe(3.2)70 b(The)22
+b(Danger)i(of)f(Mo)r(difying)g(Languages)177 1417 y Fn(Whenev)o(er)15
+b(someone)e(mo)q(di\014es)g(a)h(computer)f(program)f(they)j(should)e(alw)o(a)
+o(ys)g(ask)h(themselv)o(es)g(\\what)f(is)h(the)177 1467 y(impact)c(of)h
+(these)h(c)o(hanges)g(going)f(to)g(b)q(e)h(on)f(users".)18
+b(F)m(or)11 b(mature)g(pro)q(ducts,)h(the)g(degree)h(of)e(impact)e(is)j
+(largely)177 1516 y(determined)17 b(b)o(y)g(the)h(in)o(v)o(estmen)o(t)e(that)
+i(users)g(ha)o(v)o(e)f(made)f(in)h(particular)g(\014le)g(formats)f(supp)q
+(orted)i(b)o(y)f(the)177 1566 y(pro)q(duct.)177 1641 y(A)o(t)c(the)g(t)o(w)o
+(o)g(extremes,)g(there)h(are)f(the)g(video)g(game)e(and)i(the)g(compiler.)j
+(If)d(one)g(c)o(hanges)g(a)g(video)f(game,)f(the)177 1690 y(c)o(hange)h
+(a\013ects)g(only)e(the)i(future)g(games)e(pla)o(y)o(ed.)16
+b(Ho)o(w)o(ev)o(er,)c(if)e(one)i(c)o(hanges)f(a)g(compiler)f(in)h(particular)
+g(w)o(a)o(ys,)177 1740 y(it)i(is)f(lik)o(ely)g(that)h(thousands)g(of)g(users)
+h(will)e(b)q(e)h(forced)h(to)e(c)o(hange)i(milli)o(ons)c(of)j(source)h
+(\014les)f(to)g(accommo)q(date)177 1790 y(the)f(new)g(v)o(ersion.)17
+b(Th)o(us)11 b(the)h(impact)e(of)g(c)o(hanges)i(to)f(a)g(program)f(dep)q
+(ends)j(largely)d(on)h(the)h(in)o(v)o(estmen)o(t)e(made)177
+1840 y(b)o(y)k(users,)h(in)e(source)i(\014les,)f(training,)f(and)g(ev)o(en)i
+(m)o(uscle)e(memory!)177 1914 y(F)m(unnelW)m(eb)h(lies)h(v)o(ery)g(m)o(uc)o
+(h)f(at)h(the)g(compiler)f(end)h(of)f(this)h(sp)q(ectrum.)22
+b(In)14 b(fact)h(it)g(lies)f(ev)o(en)i(further.)22 b(Not)177
+1964 y(only)15 b(do)q(es)h(it)e(implemen)o(t)f(a)i(language,)f(but)h(it)g(is)
+g(curren)o(tly)h(the)g Fh(only)g Fn(implem)o(en)o(tation)c(of)j(that)g
+(language!)177 2014 y(This)c(means)g(that,)g(although)g(they)h(shouldn't,)f
+(p)q(eople)g(will)f(b)q(e)i(tempted)f(to)h(treat)g(the)g(F)m(unnelW)m(eb)e
+(program)177 2064 y(as)16 b(the)h(de\014nition)e(of)g(its)h(input)g(language)
+f(instead)h(of)f(the)i(de\014nition)e(c)o(hapter)i(in)e(the)i
+Fh(F)m(unnelWeb)h(User's)177 2113 y(Manual)p Fn(,)c(whic)o(h)g(tak)o(es)g
+(precedence)q(.)177 2188 y(Because)f(F)m(unnelW)m(eb)d(de\014nes)i(an)e
+(input)h(language,)f(and)g(p)q(eople)h(will)f(write)h(programs)e(using)h
+(that)h(language,)177 2238 y(particular)j(kinds)f(of)h(c)o(hanges)g(in)f(the)
+i(language)e(will)f(impact)g(sev)o(erely)j(on)f(users.)19 b(Three)c
+(di\013eren)o(t)g(kinds)e(of)177 2287 y(c)o(hange)h(are)h(discussed)g(b)q
+(elo)o(w.)295 2362 y Fk(Remo)o(ving)e(features:)k Fn(Remo)o(v)n(al)10
+b(of)i(features)i(\(featurectom)o(y\))f(is)g(extremely)g(di\016cult)f(once)
+295 2412 y(the)k(user)h(base)f(has)g(started)g(using)g(them.)22
+b(If)15 b(a)g(feature)h(is)g(remo)o(v)o(ed,)e(users)j(of)e(the)h(program)295
+2461 y(will)11 b(ha)o(v)o(e)h(to)h(go)e(through)i(all)e(their)i(programs)e
+(and)h(\014nd)h(a)f(w)o(a)o(y)f(to)i(sim)o(ulate)d(the)j(e\013ect)h(of)e(the)
+295 2511 y(remo)o(v)o(ed)h(feature)i(with)e(other)h(features.)19
+b(Often)c(this)e(is)h(so)g(un)o(think)n(able,)e(that)i(bad)g(language)295
+2561 y(constructs)i(are)e(tolerated)h(far)e(b)q(ey)o(ond)i(their)f(useful)g
+(lifetime.)295 2635 y Fk(Mo)q(difying)k(features:)23 b Fn(Mo)q(di\014cation)
+17 b(of)f(features)i(has)g(less)g(direct)g(impact)d(than)i(the)h(re-)295
+2685 y(mo)o(v)n(al)12 b(of)i(features,)h(but)g(can)f(cause)i(more)d(subtle)i
+(errors.)21 b(F)m(or)15 b(example,)d(consider)k(the)f(sorts)295
+2735 y(of)d(subtle)i(errors)g(that)f(migh)o(t)d(arise)j(if)f(the)i(seman)o
+(tics)e(of)g(the)h(F)m(unnelW)m(eb)f(commen)o(t)f Fi(@!)18
+b Fn(w)o(ere)295 2785 y(c)o(hanged)i(so)g(that)g(it)f(no)h(longer)f(includes)
+h(the)h(end)f(of)f(line)g(mark)o(er.)35 b(An)o(y)o(one)20 b(mo)q(difying)295
+2835 y(features)15 b(should)f(b)q(e)g(sure)h(that)f(they)h(are)f(not)g(inadv)
+o(erten)o(tly)g(la)o(ying)e(traps.)1042 2940 y(35)p eop
+%%Page: 36 37
+36 36 bop 295 42 a Fk(Adding)15 b(features:)20 b Fn(Although)14
+b(the)i(addition)e(of)h(features)h(is)f(generally)g(the)h(most)e(painless)295
+91 y(for)e(the)h(user)g(comm)o(unit)o(y)m(,)c(as)j(Hoare)h(p)q(oin)o(ts)f
+(out,)g(it)g(is)g(also)f(the)i(most)e(dangerous)i(in)f(the)h(long)295
+141 y(run.)343 246 y(\\When)d(an)o(y)f(new)h(language)f(design)h(pro)r(ject)h
+(is)f(nearing)f(completion,)g(there)i(is)e(alw)o(a)o(ys)g(a)h(mad)281
+295 y(rush)h(to)f(get)h(new)g(features)g(added)g(b)q(efore)g
+(standardization.)16 b(The)11 b(rush)g(is)f(mad)f(indeed,)i(b)q(ecause)281
+345 y(it)f(leads)h(in)o(to)f(a)g(trap)h(from)e(whic)o(h)h(there)i(is)e(no)h
+(escap)q(e.)18 b(A)11 b(feature)g(whic)o(h)g(is)f(omitted)f(can)i(alw)o(a)o
+(ys)281 395 y(b)q(e)18 b(added)g(later,)g(when)g(its)f(design)h(and)f(its)g
+(implications)e(are)j(w)o(ell)f(understo)q(o)q(d.)30 b(A)17
+b(feature)281 445 y(whic)o(h)c(is)g(included)h(b)q(efore)g(it)f(is)g(fully)f
+(understo)q(o)q(d)j(can)f(nev)o(er)g(b)q(e)g(remo)o(v)o(ed)e(later.")p
+Fk([Hoare80])177 549 y Fn(These)17 b(problems)d(exist)h(ev)o(en)h(when)f
+(there)i(is)e(a)f(cen)o(tral)i(authorit)o(y)m(.)21 b(If)14
+b(w)o(e)i(consider)g(the)f(case)h(where)g(there)177 599 y(is)g(no)g(cen)o
+(tral)h(authorit)o(y)m(,)e(and)h(users)i(mo)q(dify)c(a)i(language)f(and)h
+(its)g(implemen)o(tations)d(and)j(distribute)h(the)177 649
+y(mo)q(di\014ed)h(v)o(ersions,)i(the)g(result)g(is)f(ev)o(en)g(w)o(orse.)34
+b(F)m(or)19 b(a)g(start,)h(the)g(structure)h(of)e(the)g(genealogy)g(of)f(the)
+177 699 y(program)e(c)o(hanges)j(from)d(a)h(list)h(to)f(a)h(tree.)31
+b(This)18 b(mak)o(es)e(it)i(imp)q(ossible)e(to)h(imp)q(ose)g(an)h(ordering)g
+(on)f(the)177 749 y(di\013eren)o(t)f(v)o(ersions)g(and)g(mak)o(es)e(it)h
+(di\016cult)f(to)i(merge)f(them)f(once)i(they)g(div)o(erge.)23
+b(Second,)16 b(it)f(reduces)i(the)177 798 y(p)q(ortabilit)o(y)f(of)h(\014les)
+h(created)h(under)g(di\013eren)o(t)f(v)o(ersions.)30 b(Third,)18
+b(it)f(mak)o(es)f(adding)h(features)i(hazardous.)177 848 y(If)c(a)g(feature)h
+(is)f(added)h(in)e(one)i(v)o(ersion,)f(\014les)h(will)e(b)q(e)h(created)i
+(that)f(use)g(it.)21 b(These)c(\014les)f(will)d(immediately)177
+898 y(b)q(ecome)d(non-p)q(ortable.)17 b(F)m(urthermore,)11
+b(t)o(w)o(o)f(programmers)e(ma)o(y)g(in)o(tro)q(duce)k(di\013eren)o(t)f
+(features)g(that)g(use)g(the)177 948 y(same)h(syn)o(tactical)h(constructs,)h
+(th)o(us)f(prev)o(en)o(ting)g(the)h(t)o(w)o(o)e(v)o(ersions)h(from)e(ev)o(er)
+j(b)q(eing)f(merged.)k(W)m(orse,)12 b(t)o(w)o(o)177 998 y(programmers)f
+(could)i(in)o(tro)q(duce)h Fh(similar)e Fn(features)i(that)g(use)g(the)f
+(same)g(syn)o(tactical)g(constructs,)i(pro)q(ducing)177 1048
+y(ev)o(en)g(more)e(subtle)h(problems.)177 1119 y(The)c(only)f(w)o(a)o(y)f(to)
+i(a)o(v)o(oid)e(all)g(these)j(problems)e(is)g(to)g(create)i(some)e(sort)h(of)
+e(cen)o(tral)i(design)g(authorit)o(y)m(,)f(\(or,)h(at)f(the)177
+1169 y(v)o(ery)j(least,)g(some)f(sort)h(of)g(design)g(sync)o(hronization\))f
+(that)h(con)o(trols)g(the)h(language)d(and)i(its)g(implemen)o(tati)o(on.)177
+1240 y(The)i(b)q(ene\014ts)i(of)d(tigh)o(t)h(con)o(trol)f(o)o(v)o(er)h(the)h
+(language)e(are)h(enormous.)295 1311 y Fk(Univ)o(ersal)g(p)q(ortabilit)n(y:)k
+Fn(Source)e(\014les)f(can)g(b)q(e)g(treated)h(as)f(p)q(ortable.)21
+b(If)15 b(all)e(the)j(language)295 1361 y(implemen)o(tations)g(in)i(the)h(w)o
+(orld)e(are)i(singing)f(the)h(same)e(tune,)j(then)f(someone)f(in)g(Sydney)295
+1411 y(could)g(send)h(a)f(\014le)h(to)f(someone)f(in)h(New)h(Y)m(ork)f(and)g
+(b)q(e)g(sure)i(that)e(it)g(will)f(b)q(e)h(successfully)295
+1461 y(pro)q(cessed.)295 1532 y Fk(Clear)e(seman)o(tics:)i
+Fn(Doubt)c(ab)q(out)g(the)h(seman)o(tics)f(of)g(the)h(language)e(will)g(b)q
+(e)i(greatly)f(mini-)295 1582 y(mized.)k(So)13 b(long)g(as)h(more)f(than)h
+(one)h(sligh)o(tly)d(di\013ering)i(v)o(ersion)g(of)f(a)h(language)f(exists,)h
+(there)295 1632 y(will)9 b(b)q(e)j(confusion)e(o)o(v)o(er)g(the)i(seman)o
+(tics)e(of)g(its)g(constructs.)19 b(A)11 b(go)q(o)q(d)f(example)f(is)i(the)g
+(confusion)295 1682 y(b)q(et)o(w)o(een)16 b(the)e(A)m(T&T)g(Unix)f(and)h
+(Berk)o(eley)h(Unix)f(shell)f(languages.)177 1753 y(While)20
+b(c)o(hanges)h(to)g(the)g(language)f(supp)q(orted)i(b)o(y)e(a)g(piece)i(of)e
+(soft)o(w)o(are)h(is)f(the)h(most)f(serious)h(problem)177 1803
+y(asso)q(ciated)16 b(with)e(m)o(ultiple)f(v)o(ersions)i(of)f(soft)o(w)o(are,)
+h(the)g(lesser)h(problem)e(of)g(k)o(eeping)h(trac)o(k)g(of)f(c)o(hanges)i
+(that)177 1853 y(don't)f(a\013ect)h(the)g(language)e(that)h(the)h(soft)o(w)o
+(are)g(implem)o(en)o(ts)d(can)j(also)e(cause)j(trouble.)22
+b(Merging)15 b(di\013eren)o(t)177 1902 y(v)o(ersions)g(of)f(soft)o(w)o(are)g
+(is)h(extremely)f(tedious)h(as)f(an)o(y)o(one)g(who)g(has)h(tried)g(it)f
+(will)f(v)o(erify)m(.)19 b(Ho)o(w)o(ev)o(er,)14 b(c)o(hanges)177
+1952 y(not)g(a\013ecting)g(the)g(language)f(are)h(far)f(less)h(serious)h(b)q
+(ecause)g(they)f(impact)e(only)h(on)h(the)g(program)e(itself,)h(not)177
+2002 y(on)h(the)g(far)g(more)f(n)o(umerous)g(source)i(\014les)f(that)g(dep)q
+(end)i(on)d(it.)177 2159 y Fe(3.3)70 b(Authorit)n(y)23 b(vs)g(User)g(Securit)
+n(y)177 2272 y Fn(There)16 b(are)f(a)g(n)o(um)o(b)q(er)f(of)g(w)o(a)o(ys)h
+(of)f(pro)o(viding)f(the)j(strong)f(cen)o(tral)g(design)g(authorit)o(y)f
+(required)i(to)f(pro)q(duce)177 2322 y(the)g(p)q(ortabilit)o(y)d(and)i(seman)
+o(tic)f(securit)o(y)i(desired)g(b)o(y)e(users,)239 2426 y Fm(\017)21
+b Fn(T)m(rade)d(mark)e(the)i(name)f(of)g(the)i(language.)28
+b(Publish)18 b(a)g(sp)q(eci\014cation)g(of)f(the)i(language)e(under)h(the)281
+2476 y(trade)c(name.)i(W)m(arn)d(all)f(users)j(not)e(to)g(trust)h(an)o(y)f
+(implemen)o(tatio)o(n)e(that)i(do)q(es)h(not)f(guaran)o(tee)h(that)f(it)281
+2526 y(implemen)o(ts)d(the)j(language.)k(Then)c(con)o(trol)f(implemen)o
+(tations)d(b)o(y)k(only)e(licensing)i(the)g(trade)g(mark)e(to)281
+2576 y(conforming)h(implem)o(en)o(tations.)239 2655 y Fm(\017)21
+b Fn(Create)g(a)f(single)g(implemen)o(tation)d(of)j(the)h(language.)36
+b(Do)20 b(not)g(release)h(the)g(source)h(co)q(de)f(to)f(the)281
+2705 y(implemen)o(tatio)o(n.)15 b(Release)g(only)e(binary)g(executables.)239
+2785 y Fm(\017)21 b Fn(Release)14 b(the)f(source)i(co)q(de)f(to)f(the)g
+(implemen)o(tation,)c(but)14 b(under)g(a)f(license)g(that)h(prohibits)e(the)i
+(distri-)281 2835 y(bution)f(of)h(mo)q(di\014ed)e(v)o(ersions.)1042
+2940 y(36)p eop
+%%Page: 37 38
+37 37 bop 177 42 a Fn(Man)o(y)11 b(other)h(v)n(ariations)e(on)h(these)i
+(themes)e(are)h(p)q(ossible,)f(but)h(they)f(are)h(all)e(based)i(on)f(the)h
+(idea)f(of)g(regulating)177 91 y(either)k(the)f(\\o\016cial")e(de\014nition)i
+(of)f(the)i(language)e(or)g(all)g(of)g(its)h(existing)g(implemen)o(tatio)o
+(ns.)177 168 y(A)o(t)h(ab)q(out)f(this)h(stage,)g(a)f(con\015ict)h(arises.)21
+b(While)14 b(users)i(w)o(an)o(t)f(the)g(language)f(they)h(are)g(using)f(to)h
+(b)q(e)g(tigh)o(tly)177 217 y(con)o(trolled,)e(they)h(also)f(w)o(an)o(t)g(to)
+h(feel)f(secure)j(ab)q(out)d(the)h(a)o(v)n(ailabilit)o(y)c(of)j(its)h(implem)
+o(en)o(tations.)h(If)f(h)o(undreds)177 267 y(of)19 b(source)i(\014les)e(are)h
+(to)g(b)q(e)g(created)h(in)e(the)h(language,)f(there)i(had)e(b)q(etter)i(b)q
+(e)f(one)g(or)f(more)f(translators)177 317 y(a)o(v)n(ailable)12
+b(when)i(the)h(time)d(comes)i(to)f(use)i(them.)177 393 y(In)g(the)g(case)h
+(of)e(widely-used)h(programmi)o(ng)d(languages)i(suc)o(h)h(as)g(C,)f(the)i
+(problem)d(of)h(securing)i(implem)o(en-)177 443 y(tations)c(do)q(es)i(not)e
+(arise.)18 b(If)12 b(y)o(ou)g(don't)g(get)h(y)o(our)f(compiler)f(from)g
+(Borland,)h(y)o(ou)g(can)h(get)f(it)h(from)d(Microsoft.)177
+493 y(Ho)o(w)o(ev)o(er,)16 b(in)f(the)h(case)g(of)f(a)g(newly)h(in)o(tro)q
+(duced)g(language)e(suc)o(h)i(as)g(F)m(unnelW)m(eb,)f(there)h(ma)o(y)e(b)q(e)
+i(v)o(ery)g(few)177 543 y(implemen)o(tations,)g(or)i(ev)o(en)h(just)f(one)h
+(implemen)o(tatio)o(n,)d(and)i(this)h(p)q(oses)g(a)f(danger)h(to)f(the)h
+(user)g(who)f(is)177 593 y(committing)10 b(to)j(that)g(format.)j(Despite)d
+(the)h(b)q(est)g(in)o(ten)o(tions)f(of)f(the)i(cop)o(yrigh)o(t)f(o)o(wner,)g
+(there)h(are)g(a)e(v)n(ariet)o(y)177 642 y(of)h(w)o(a)o(ys)g(in)f(whic)o(h)h
+(a)g(computer)g(program)f(can)h(suddenly)h(b)q(ecome)f(una)o(v)n(ailable.)j
+(Here)e(are)g(some)e(examples:)239 762 y Fm(\017)21 b Fn(If)12
+b(the)h(program)e(is)i(o)o(wned)g(b)o(y)f(a)g(compan)o(y)f(and)i(the)g
+(compan)o(y)e(go)q(es)i(brok)o(e,)g(the)g(liquidators)e(ma)o(y)g(not)281
+812 y(b)q(other)k(to)e(place)h(the)h(soft)o(w)o(are)f(in)f(the)i(public)e
+(domain.)239 898 y Fm(\017)21 b Fn(If)13 b(the)g(program)f(is)h(o)o(wned)g(b)
+o(y)g(a)g(kindly)f(individual)f(who)i(issues)h(licenses)h(for)e(free,)g(and)g
+(that)g(individ-)281 948 y(ual)h(suddenly)h(dies,)g(users)i(migh)o(t)12
+b(suddenly)k(\014nd)f(themselv)o(es)g(negotiating)f(with)g(hard-nosed)i
+(estate)281 998 y(executors)g(for)d(the)i(righ)o(ts)e(to)h(con)o(tin)o(ue)g
+(using)g(the)g(program.)239 1084 y Fm(\017)21 b Fn(If)c(who)q(ev)o(er)h(o)o
+(wns)g(the)g(program)e(do)q(es)i(not)f(upgrade)h(the)g(program)e(ev)o(ery)i
+(so)f(often,)h(it)f(is)h(actually)281 1134 y(p)q(ossible)10
+b(for)g(the)h(released)g(executables)h(to)e(\\expire")h(when)f(new)h(op)q
+(erating)f(system)g(upgrades)h(app)q(ear.)177 1254 y(These)16
+b(p)q(ossibilities)d(mean)g(that)i(users)g(ab)q(out)g(to)f(in)o(v)o(est)g(in)
+g(a)g(newly)g(in)o(tro)q(duced)h(programmi)o(ng)c(to)q(ol)j(suc)o(h)177
+1304 y(as)j(F)m(unnelW)m(eb)f(ha)o(v)o(e)h(legitimate)d(concerns)19
+b(when)e(they)h(w)o(orry)e(ab)q(out)h(the)g(to)q(ol's)f(a)o(v)n(ailabilit)o
+(y)l(.)24 b(F)m(or)16 b(non-)177 1354 y(commercially)8 b(distributed)k(to)q
+(ols)f(suc)o(h)g(as)h(F)m(unnelW)m(eb,)e(the)i(simplest)e(solution)g(to)h
+(this)h(problem)d(is)i(to)g(mak)o(e)177 1404 y(the)i(source)g(co)q(de)g(a)o
+(v)n(ailable,)c(either)k(b)o(y)f(placing)f(it)g(in)o(to)g(the)i(public)e
+(domain,)f(or)i(b)o(y)f(releasing)h(it)g(under)h(some)177 1453
+y(kind)i(of)f(public)h(license,)g(suc)o(h)h(as)f(a)g(GNU)g(license.)22
+b(The)15 b(trouble)g(with)g(releasing)g(the)h(source)g(co)q(de)g(is)f(that)
+177 1503 y(it)f(remo)o(v)o(es)g(con)o(trol)g(from)f(the)i(design)g(authorit)o
+(y)m(.)j(Once)e(the)f(co)q(de)g(is)g(\\out")f(there)h(is)g(no)f(stopping)g
+(an)o(y)o(one)177 1553 y(from)e(mo)q(difying)f(the)k(program)d(and)i
+(distributing)f(mo)q(di\014ed)g(v)o(ersions.)18 b(All)13 b(c)o(haos)h(can)g
+(ensue.)177 1629 y(One)j(solution)d(to)i(this)g(con\015ict)g(is)f(to)h(tak)o
+(e)f(the)h(trade)h(mark)d(approac)o(h.)23 b(This)16 b(separates)h(the)f(righ)
+o(t)f(of)g(the)177 1679 y(design)e(authorit)o(y)f(to)h(con)o(trol)f(the)h
+(language)f(and)g(its)h(implemen)o(tatio)o(ns,)d(and)j(the)g(righ)o(t)f(of)g
+(the)h(users)h(to)f(use)177 1729 y(the)g(source)i(co)q(de)e(in)f(an)o(y)h(w)o
+(a)o(y)f(they)h(lik)o(e)f(\(but)h(they)g(ma)o(y)e(ha)o(v)o(e)h(to)h(c)o
+(hange)g(its)g(name!\).)j(Ho)o(w)o(ev)o(er,)d(the)g(trade)177
+1779 y(mark)g(approac)o(h)g(is)h(exp)q(ensiv)o(e.)177 1855
+y(The)e(solution)g(that)f(I)h(\(Ross)g(William)o(s)e(\()p Fi
+(ross@spam.adelaid)o(e.ed)o(u.au)p Fn(\)\))f(ha)o(v)o(e)i(adopted)i(is)e(to)h
+(release)h(the)177 1905 y(F)m(unnelW)m(eb)k(source)i(co)q(de)f(under)h(a)e
+(GNU)g(license)i(and)e(then)h(to)f(write)h(this)g(c)o(hapter)g(in)f(the)i
+Fh(F)m(unnelWeb)177 1955 y(Hacker's)c(Manual)h Fn(to)e(dissuade)h(p)q
+(ossible)g(hac)o(k)o(ers)h(from)d(releasing)h(mo)q(di\014ed)f(v)o(ersions)j
+(under)f(the)g(F)m(unnel-)177 2004 y(W)m(eb)e(name.)k(This)d(is)f(ab)q(out)h
+(as)g(close)g(to)f(the)i(GNU/trademark)d(approac)o(h)i(I)f(can)h(get)g
+(without)f(forking)g(out)177 2054 y(ab)q(out)e($1200)g(for)g(a)g(US)g
+(trademark)g(or)g(pa)o(ying)f(ev)o(en)i(more)f(to)g(get)h(a)f(la)o(wy)o(er)g
+(to)g(attempt)f(to)i(draft)f(a)g(con)o(tract)177 2104 y(stating)j(\\thou)f
+(shalt)h(not)g(mo)q(dify)d(the)k(F)m(unnelW)m(eb)e(language".)177
+2271 y Fe(3.4)70 b(What)23 b(I)g(W)-6 b(an)n(t)24 b(to)f(Protect)177
+2389 y Fn(The)13 b(concerns)i(expressed)g(in)d(the)h(previous)g(section)h(ab)
+q(out)e(mo)q(di\014cations)f(to)i(the)g(F)m(unnelW)m(eb)f(program)f(do)177
+2439 y(not)j(preclude)i(mo)q(di\014cations.)i(They)c(merely)g(imply)e(that)i
+(some)f(conditions)h(b)q(e)h(observ)o(ed)h(when)f(mo)q(di\014ca-)177
+2489 y(tions)g(are)g(made.)k(In)c(fact,)g(ha)o(ving)e(formally)f(released)k
+(the)f(sources)i(under)e(GNU,)f(there)i(is)f(nothing)f(that)h(I)177
+2539 y(can)h(do)f(to)h(stop)g(p)q(eople)g(distributing)f(mo)q(di\014ed)f(v)o
+(ersions)i(and)g(the)g(conditions)f(to)h(b)q(e)g(describ)q(ed)i(m)o(ust)c(b)q
+(e)177 2588 y(imp)q(osed)f(v)o(olun)o(tarily)m(.)177 2665 y(In)h(the)h(end)f
+(there)h(are)f(t)o(w)o(o)g(things)g(that)g(I)f(w)o(an)o(t)h(to)g
+(protect/main)o(tain:)228 2785 y(1.)20 b(Restriction)d(of)g(the)g(name)f(\\F)
+m(unnelW)m(eb")g(only)g(to)h(computer)g(programs)e(that)i(exactly)h(implem)o
+(en)o(t)281 2835 y(m)o(y)12 b(\\o\016cial")g(de\014nition)i(of)f(the)h
+(language.)1042 2940 y(37)p eop
+%%Page: 38 39
+38 38 bop 228 42 a Fn(2.)20 b(Restriction)15 b(of)f(the)h(F)m(unnelW)m(eb)f
+(source)i(\014le)f(extensions)h(\\)p Fi(.fw)p Fn(")d(\(input)i(\014les\))g
+(and)f(\\)p Fi(.fwi)p Fn(")g(\(include)281 91 y(\014les\))g(only)f(to)h
+(source)h(\014les)g(that)f(conform)e(to)i(m)o(y)e(\\o\016cial")g
+(de\014nition)h(of)h(the)g(language.)177 214 y(So)f(long)e(as)i(these)h
+(conditions)e(hold,)g(source)i(\014les)f(created)h(under)g(\\F)m(unnelW)m
+(eb")e(will)f(b)q(e)i(p)q(ortable,)g(and)f(the)177 264 y(language)g(will)g
+(ha)o(v)o(e)g(the)i(p)q(oten)o(tial)e(to)h(b)q(e)h(stable)f(and)g(w)o
+(ell-de\014ned.)18 b(Here)c(are)f(m)o(y)e(suggestions)j(for)e(ho)o(w)h(to)177
+314 y(ob)q(ey)i(these)i(rules.)22 b(These)16 b(suggestions)g(are)f(in)g
+(addition)e(to)i(the)h(GNU)f(license)g(rules)h(ab)q(out)f(do)q(cumen)o(ting)
+177 363 y(an)o(y)f(c)o(hanges)g(that)g(y)o(ou)g(mak)o(e)e(in)h(the)i(source)g
+(\014les.)295 441 y Fk(Mo)q(di\014cations)h(that)i(do)g(not)f(a\013ect)i
+(functional)o(i)o(t)o(y:)h Fn(If)c(y)o(ou)g(c)o(hange)g(the)h(F)m(unnelW)m
+(eb)295 491 y(program)f(in)i(a)f(manner)g(that)h(do)q(es)g(not)g(a\013ect)h
+(the)f(functionalit)o(y)e(of)h(the)i(program)d(in)h(an)o(y)295
+540 y(w)o(a)o(y)d(\(e.g.)f(p)q(ort)h(it)g(to)g(a)g(new)g(mac)o(hine,)f(or)h
+(just)g(sp)q(eed)i(it)d(up\),)h(then)h(y)o(ou)e(should)h(mo)q(dify)e(the)295
+590 y(program)g(to)h(write)g(out)g(a)g(message)g(when)g(it)g(starts)h(up)f
+(sa)o(ying)f(that)h(it)g(is)g(a)g(mo)q(di\014ed)f(v)o(ersion)295
+640 y(of)i(F)m(unnelW)m(eb.)j(No)d(other)g(actions)g(need)h(b)q(e)g(tak)o
+(en.)295 717 y Fk(Mo)q(di\014cations)d(that)h(a\013ect)h(functional)o(i)o(t)o
+(y:)h Fn(If)d(y)o(ou)g(mak)o(e)e(c)o(hanges)k(to)e(F)m(unnelW)m(eb)g(that)295
+767 y(a\013ect)g(its)f(functionalit)o(y)f(\(e.g.)g(c)o(hanges)i(to)f(command)
+e(line)h(options,)h(the)h(command)c(language,)295 817 y(or)13
+b(the)h(input)f(language\))g(y)o(ou)f(should)h(c)o(hange)h(the)g(name)e(of)g
+(the)i(program)e(so)h(that)g(the)h(name)295 867 y(no)h(longer)g(con)o(tains)h
+(the)g(w)o(ord)f(\\F)m(unnelW)m(eb",)f(and)h(should)g(c)o(ho)q(ose)i
+(alternativ)o(e)e(input)g(and)295 917 y(include-\014le)d(\014le)g(extensions)
+g(\(the)h(curren)o(t)g(ones)f(are)g(\\)p Fi(.fw)p Fn(")f(and)g(\\)p
+Fi(.fwi)p Fn("\).)16 b(F)m(or)c(example,)e(y)o(ou)295 966 y(migh)o(t)g(call)h
+(y)o(our)g(program)f(\\BananaW)m(eb")h(and)g(use)i(the)f(\014le)g(extensions)
+g(\\)p Fi(.bw)p Fn(")f(and)g(\\)p Fi(.bwi)p Fn(".)177 1044
+y(These)k(rules)f(are)g(not)g(v)o(ery)g(restrictiv)o(e.)19
+b(Basically)13 b(y)o(ou)g(can)h(do)f(what)h(y)o(ou)f(lik)o(e)g(so)h(long)e
+(as)i(y)o(ou)f(c)o(hange)h(the)177 1094 y(name)d(of)g(the)h(resulting)g
+(program.)k(I)c(do)f(not)h(wish)g(to)g(restrict)h(an)o(y)o(one)e(who)h(migh)o
+(t)e(w)o(an)o(t)h(to)h(use)g(F)m(unnelW)m(eb)177 1143 y(as)18
+b(a)g(foundation)f(for)g(a)h(more)f(sophisticated)h(literate)g(programming)d
+(system.)30 b(My)17 b(sole)h(aim)e(here)j(is)f(to)177 1193
+y(protect)d(the)g(in)o(tegrit)o(y)e(of)g(what)h(already)g(exists.)177
+1364 y Fe(3.5)70 b(Mo)r(difying)22 b(the)h(Man)n(uals)177 1483
+y Fn(While)15 b(it)h(is)f(p)q(ermitted)h(to)f(mo)q(dify)f(the)i(F)m(unnelW)m
+(eb)f(program,)g(no)g(license)i(has)f(b)q(een)g(gran)o(ted)h(to)e(mo)q(dify)
+177 1533 y(its)h(do)q(cumen)o(tation)f(\()p Fh(The)i(F)m(unnelWeb)h(User's)e
+(Manual)g Fn(and)g Fh(The)h(F)m(unnelWeb)h(Hacker's)e(Manual)p
+Fn(\).)25 b(The)177 1583 y(only)12 b(op)q(eration)h(that)f(can)h(b)q(e)h(p)q
+(erformed)e(on)g(the)i(F)m(unnelW)m(eb)e(do)q(cumen)o(tation)f(is)i(a)f(v)o
+(erbatim)f(cop)o(y)i(in)f(an)o(y)177 1633 y(medium.)177 1710
+y(If)j(y)o(ou)g(ha)o(v)o(e)g(created)i(a)f(mo)q(di\014ed)e(v)o(ersion)h(of)g
+(F)m(unnelW)m(eb)g(and)g(wish)h(to)f(do)q(cumen)o(t)g(it,)g(either)h(write)g
+(y)o(our)177 1760 y(o)o(wn)h(man)o(ual)e(from)g(scratc)o(h,)k(or)e(write)g(a)
+g(man)o(ual)e(that)i(can)g(b)q(e)h(used)g(in)e(conjunction)i(with)e(the)i
+(existing)177 1809 y(man)o(uals.)177 1980 y Fe(3.6)70 b(Ho)n(w)23
+b(Cop)n(yrigh)n(t)g(La)n(w)g(W)-6 b(orks)177 2099 y Fn(In)17
+b(order)h(to)f(understand)i(the)f(next)f(section,)i(some)d(understanding)i
+(of)e(cop)o(yrigh)o(t)h(la)o(w)f(is)h(required.)29 b(The)177
+2149 y(assertions)15 b(made)e(in)h(this)h(section)f(are)h(not)f(legal)f
+(opinions;)g(they)i(are)g(merely)e(appro)o(ximations)f(of)h(the)i(la)o(w,)177
+2199 y(based)g(on)e(m)o(y)g(understanding)h(of)f(it.)177 2276
+y(By)k(default,)g(who)q(ev)o(er)g(creates)h(a)f Fk(w)o(ork)f
+Fn(o)o(wns)h Fk(cop)o(yrigh)o(t)c Fn(o)o(v)o(er)k(it.)26 b(This)16
+b(means)g(that)h(b)o(y)f(default,)h(that)177 2326 y(p)q(erson)e(is)f(the)g
+(only)f(p)q(erson)i(in)f(the)g(w)o(orld)g(who)f(has)h(the)h(legal)e(righ)o(t)
+g(to)h(mak)o(e)e(copies)j(of)e(the)h(w)o(ork.)177 2403 y(Cop)o(yrigh)o(t)g(o)
+o(v)o(er)h(a)f(w)o(ork)g(usually)g(co)o(v)o(ers)i(all)d(direct)j(deriv)n
+(ations)e(of)g(this)h(w)o(ork.)20 b(F)m(or)14 b(example,)g(if)f(someone)177
+2453 y(o)o(wns)f(the)h(source)h(co)q(de)f(to)f(a)f(computer)h(program)f(then)
+i(they)f(also)g(o)o(wn)g(an)o(y)f(direct)i(deriv)n(ations)f(suc)o(h)h(as)f
+(the)177 2503 y(binary)i(executable.)177 2580 y(More)i(than)g(one)f(p)q
+(erson)i(ma)o(y)c(o)o(wn)i(cop)o(yrigh)o(t)g(o)o(v)o(er)h(a)f(w)o(ork.)23
+b(If)15 b(this)g(is)h(the)g(case,)g(then)g(the)g(w)o(ork)g(cannot)177
+2630 y(b)q(e)f(copied)f(without)f(the)i(p)q(ermission)e(of)g(all)g(of)g(the)h
+(p)q(eople)h(o)o(wning)e(the)h(cop)o(yrigh)o(t.)177 2708 y(A)k(p)q(erson)g
+(\(or)f(group\))g(o)o(wning)g(cop)o(yrigh)o(t)f(o)o(v)o(er)i(a)f(w)o(ork)g
+(can)g Fk(license)e Fn(the)j(righ)o(t)f(to)g(mak)o(e)f(copies)i(of)e(the)177
+2757 y(w)o(ork)e(to)f(an)o(y)o(one)h(he)g(lik)o(es)g(under)h(an)o(y)e
+(conditions)h(he)g(lik)o(es.)177 2835 y(If)g(a)f(w)o(ork)h(is)g(mo)q
+(di\014ed,)e(the)i(result)h(is)f(called)f(a)h Fk(deriv)o(ed)f(w)o(ork)p
+Fn(.)1042 2940 y(38)p eop
+%%Page: 39 40
+39 39 bop 177 42 a Fn(If)13 b(cop)o(yrigh)o(t)g(on)h(a)f(w)o(ork)g(is)g(o)o
+(wned)h(b)o(y)f Fj(A)h Fn(is)f(the)h(w)o(ork)f(is)h(mo)q(di\014ed)e(b)o(y)h
+Fj(B)r Fn(,)h(cop)o(yrigh)o(t)f(on)g(the)h(deriv)o(ed)g(w)o(ork)177
+91 y(is)g(o)o(wned)g(b)o(y)g(b)q(oth)g Fj(A)g Fn(and)f Fj(B)r
+Fn(.)177 159 y(Cop)o(yrigh)o(t)j(is)g(not)g(o)o(wnership)h(o)o(v)o(er)f
+(particular)g(con\014gurations)h(of)f(information,)d(but)k(rather)g(is)f(the)
+h(righ)o(t)177 209 y(to)d(restrict)i(the)f(cop)o(ying)e(of)h(information)d
+(deriv)o(ed)k(from)d(particular)i(sources.)21 b(F)m(or)14 b(example,)e(if)i
+(t)o(w)o(o)f(p)q(eople)177 259 y(p)q(oin)o(t)k(their)g(cameras)g(out)g(a)g
+(windo)o(w)f(and)h(tak)o(e)g(iden)o(tical)f(photographs,)i(eac)o(h)f(p)q
+(erson)h(has)g(the)f(righ)o(t)g(to)177 309 y(restrict)e(the)g(cop)o(ying)e
+(of)g Fh(their)g Fn(photograph)h(regardless)h(of)e(the)h(fact)g(that)g(the)g
+(other)g(p)q(erson)h(has)f(cop)o(yrigh)o(t)177 359 y(o)o(v)o(er)h(an)f(iden)o
+(tical)g(photograph.)20 b(In)14 b(the)h(unlik)o(ely)f(ev)o(en)o(t)h(that)f(t)
+o(w)o(o)g(p)q(eople)h(wrote)g(no)o(v)o(els)g(that)f(w)o(ere)i(letter)177
+408 y(for)d(letter)h(iden)o(tical)f(and)g(it)g(could)g(b)q(e)h(pro)o(v)o(en)g
+(that)f(there)i(w)o(as)e(no)g(con)o(tact)h(b)q(et)o(w)o(een)h(the)f(t)o(w)o
+(o)f(p)q(eople)g(when)177 458 y(they)e(wrote)h(the)f(no)o(v)o(els,)g(then)g
+(cop)o(yrigh)o(t)g(la)o(w)f(w)o(ould)g(eac)o(h)h(protect)h(the)f(righ)o(t)g
+(of)f(eac)o(h)h(p)q(erson)h(to)f(restrict)h(the)177 508 y(cop)o(ying)g(of)h
+(the)g(no)o(v)o(el)f(originating)f(from)g Fh(them)p Fn(.)18
+b(In)13 b(practice,)g(the)h(probabilit)o(y)d(of)h(suc)o(h)i(an)f(ev)o(en)o(t)
+g(o)q(ccurring)177 558 y(is)i(so)h(lo)o(w)e(that)h(the)h(la)o(w)f(assumes)g
+(that)g(if)g(t)o(w)o(o)f(w)o(orks)i(are)f(close)h(or)f(iden)o(tical,)g(that)g
+(there)i(has)e(b)q(een)i(some)177 608 y(information)11 b(in)o(terc)o(hange)k
+(at)e(some)g(p)q(oin)o(t.)177 676 y(Th)o(us,)f(if)f(I)h(o)o(wn)g(cop)o(yrigh)
+o(t)f(on)h(computer)f(program)g Fj(X)s Fn(,)h(and)g(I)f(create)j(an)d(iden)o
+(tical)h(cop)o(y)f(of)h Fj(X)j Fn(called)d Fj(Y)21 b Fn(and)177
+726 y(distribute)c(it)f(under)h(the)f(terms)g(of)g(a)g(license)h(agreemen)o
+(t,)f(then)g(that)h(license)g(agreemen)o(t)e(do)q(es)i(not)f(co)o(v)o(er)177
+775 y(the)e(cop)o(y)e Fj(X)s Fn(.)19 b(Once)14 b(the)f(license)h(agreemen)o
+(t)e(is)h(signed,)g(there)h(is)f(nothing)f(I)h(can)g(do)f(to)h(undo)g(the)g
+(license;)g Fj(Y)177 825 y Fn(has)h(gone.)k(Ho)o(w)o(ev)o(er,)c(I)g(still)f
+(ha)o(v)o(e)h(total)f(con)o(trol)g(o)o(v)o(er)h Fj(X)s Fn(.)177
+893 y(V)m(ersion)g(2)g(of)f(the)h(GNU)g(General)g(Public)g(License)h(\(under)
+g(whic)o(h)e(F)m(unnelW)m(eb)h(is)f(released\))j(sp)q(eci\014es)g(\(in)d(a)
+177 943 y(n)o(utshell\))e(that)h(soft)o(w)o(are)f(can)g(b)q(e)h(copied)f
+(freely)g(so)h(long)e(as)h(it)g(is)g(not)g(sold,)f(and)h(that)g(it)g(can)h(b)
+q(e)f(mo)q(di\014ed)f(and)177 993 y(copied)15 b(freely)h(so)f(long)f(as)h
+(the)h(mo)q(di\014cations)d(are)i(logged)g(and)g(it)f(is)h(not)g(sold.)21
+b(In)15 b(b)q(oth)h(cases,)g(it)f(requires)177 1043 y(that)h(the)h(result)g
+(of)e(the)i(cop)o(y)f(or)g(mo)q(di\014cation)e(op)q(eration)h(b)q(e)i(copied)
+f(only)g(under)g(the)h(conditions)f(of)f(the)177 1092 y(license.)177
+1160 y(Once)g(a)e(declaration)g(is)g(issued)h(licensing)f(a)g(cop)o(y)g(of)g
+(a)g(program)e(under)j(GNU)f(license,)h(that)g(license)g(cannot)177
+1210 y(b)q(e)h(retracted.)177 1363 y Fe(3.7)70 b(Managemen)n(t)23
+b(of)g(the)f(O\016cial)f(F)-6 b(unnelW)g(eb)177 1472 y Fn(I)14
+b(in)o(tend)f(to)h(main)o(tain)d(an)i(o\016cial)f(cop)o(y)i(of)f(F)m(unnelW)m
+(eb)g(and)g(release)i(it)f(under)g(GNU)f(license)i(from)d(time)g(to)177
+1522 y(time)h(so)h(that)g(ev)o(ery)o(one)g(can)h(use)f(it.)k(Unfortunately)c
+(its)g(going)e(to)i(b)q(e)g(a)g(little)f(messy)m(.)177 1590
+y(F)m(or)j(a)h(v)n(ariet)o(y)f(of)f(reasons,)j(I)f(w)o(an)o(t)f(to)g(main)o
+(tain)e(total)i(con)o(trol)g(o)o(v)o(er)g Fh(my)h Fn(cop)o(y)g(of)e(the)j
+(o\016cial)d(v)o(ersion)h(of)177 1640 y(F)m(unnelW)m(eb.)i(Some)12
+b(of)i(the)g(reasons)h(are:)239 1732 y Fm(\017)21 b Fn(If)15
+b(it)h(turns)h(out)f(that)g(there)h(is)e(an)h(enormous)f(demand)g(for)h(F)m
+(unnelW)m(eb)f(\(unlik)o(ely\))g(then)i(I)e(w)o(an)o(t)h(to)281
+1782 y(b)q(e)e(able)e(to)h(create)i(a)d(business)j(based)e(on)g(it,)f(or)h
+(at)g(least)h(b)q(e)f(able)g(to)g(bundle)g(it)g(with)f(other)i(pro)q(ducts.)
+281 1832 y(This)g(w)o(ould)g(b)q(e)i(di\016cult)e(if)f(the)j(only)d
+(up-to-date)i(cop)o(y)g(a)o(v)n(ailable)d(w)o(as)j(a)f(GNU)h(cop)o(y)m(.)k
+(Note:)h(If)15 b(this)281 1882 y(happ)q(ens,)f(all)f(the)h(GNU)g(releases)i
+(of)d(F)m(unnelW)m(eb)g(will)g(remain)f(v)n(alid.)239 1958
+y Fm(\017)21 b Fn(I)d(w)o(an)o(t)g(to)g(b)q(e)h(able)f(to)g(cop)o(y)g(co)q
+(de)h(from)d(m)o(y)h(v)o(ersion)h(of)g(F)m(unnelW)m(eb)f(in)o(to)h
+(commercial)d(pro)q(ducts)281 2008 y(without)e(ha)o(ving)g(to)h(w)o(orry)g
+(ab)q(out)g(the)g(GNU)g(license.)177 2101 y(The)i(trouble)f(is)h(that)f(\(in)
+g(m)o(y)f(understanding)h(of)g(cop)o(yrigh)o(t)g(la)o(w\),)f(once)i(a)f(cop)o
+(y)h(of)e(F)m(unnelW)m(eb)h(has)h(b)q(een)177 2151 y(released)i(under)g(GNU)f
+(license,)g(then)h(it)e(and)h(an)o(y)f(w)o(orks)h(deriv)o(ed)h(from)d(it)h
+(fall)g(under)h(GNU)g(license)g(to)q(o.)177 2200 y(This)c(means)g(that)g(if)g
+(y)o(ou)g(mo)q(dify)e(a)i(GNU)g(release)h(of)f(F)m(unnelW)m(eb)g(and)g(send)h
+(me)f(y)o(our)g(mo)q(di\014cations,)e(and)177 2250 y(I)18 b(incorp)q(orate)h
+(them)e(in)o(to)h(m)o(y)e(v)o(ersion,)j(then)g(I)f(no)g(longer)f(o)o(wn)h
+(cop)o(yrigh)o(t)g(on)g(the)g(v)o(ersion)h(I)f(mo)q(di\014ed.)177
+2300 y(Basically)m(,)12 b(if)h(GNU)h(touc)o(hes)h(a)f(w)o(ork,)f(then)h(that)
+g(cop)o(y)g(is)g(gone)g(forev)o(er.)177 2368 y(My)k(solution)e(to)i(the)g
+(problem)e(is)h(to)g(k)o(eep)i(a)e(cop)o(y)g(of)g(F)m(unnelW)m(eb)g(that)h
+(is)f(GNU-clean)g(and)h(only)e(mak)o(e)177 2418 y(mo)q(di\014cations)9
+b(to)h(it)h(that)f(are)h(GNU-clean.)17 b(So)11 b(long)e(as)i(m)o(y)e
+(o\016cial)g(cop)o(y)i(is)f(GNU)g(clean,)h(an)o(y)g(mo)q(di\014cations)177
+2468 y(that)j(I)g(mak)o(e)e(m)o(yself)g(will)h(b)q(e)h(GNU)g(clean.)k(The)c
+(problem)e(comes)i(when)g(someone)f(else)i(mo)q(di\014es)e(the)h(GNU)177
+2518 y(v)o(ersion)c(and)f(then)h(w)o(an)o(ts)g(me)e(to)i(incorp)q(orate)g
+(the)g(mo)q(di\014cations)e(in)o(to)g(m)o(y)g(o\016cial)g(v)o(ersion.)17
+b(As)10 b(I)g(understand)177 2567 y(the)h(la)o(w,)f(b)o(y)g(default,)g(the)h
+(programmer)d(o)o(wns)j(the)g(mo)q(di\014cations)d(\(b)q(ecause)k(he)f(made)e
+(them\),)h(but)h(the)g(result)177 2617 y(of)h(making)e(the)j(mo)q
+(di\014cations)d(falls)i(under)h(GNU)f(license.)18 b(What)12
+b(I)g(prop)q(ose)i(is)e(that)g(those)h(who)f(w)o(an)o(t)g(their)177
+2667 y(mo)q(di\014cations)g(included)i(in)g(the)g(o\016cial)f(cop)o(y)g(of)h
+(F)m(unnelW)m(eb)f(sign)h(an)f(agreemen)o(t)h(transferring)g(cop)o(yrigh)o(t)
+177 2717 y(of)f(the)g(mo)q(di\014cations)f(o)o(v)o(er)h(to)g(me)f(on)h
+(condition)f(that)h(the)h(result)g(b)q(e)f(released)i(under)f(GNU)f(license)h
+(within)177 2767 y(a)g(certain)g(time)f(p)q(erio)q(d.)18 b
+Fk(Figure)c(1)g Fn(demonstrates)g(the)h(pro)q(cess.)177 2835
+y(There)g(are)g(t)o(w)o(o)e(main)f(disadv)n(an)o(tages)h(to)h(this)g(sc)o
+(heme:)1042 2940 y(39)p eop
+%%Page: 40 41
+40 40 bop 221 91 a Fi(+---------->----)o(-----)o(-+---)o(-----)o(-----)o
+(-<--)o(-----)o(-----)o(-+)221 141 y(|\(modifications)18 b(by)87
+b(|)610 b(|)221 191 y(|)21 b(me\))370 b(V)610 b(|)221 241 y(|)109
+b(+--------------)o(-----)o(-----)o(-----)o(----)o(-+)193 b(|)221
+291 y(+--<--|)42 b(My)21 b(Official)f(Copy)h(of)h(FunnelWeb)63
+b(|)196 b(|)352 340 y(|)65 b(Copyright)20 b(\(C\))h(Ross)g(Williams)85
+b(|)196 b(|)352 390 y(+--------------)o(-----)o(-----)o(-----)o(----)o(-+)d
+(|)700 440 y(|)22 b(\(Periodic)e(releases\))150 b(/)22 b(\\)700
+490 y(V)567 b(/)65 b(\\)43 b(Programmers)482 540 y(+------------------)o(+)
+346 b(/Legal\\)20 b(sign)h(away)482 589 y(|)h(GNU)f(Release)f(Copy)h(|)349
+b(\\Filte/)20 b(copyright)g(on)482 639 y(+------------------)o(+)368
+b(\\)21 b(r)h(/)43 b(modifications)700 689 y(|)588 b(\\)22
+b(/)700 739 y(|)g(\(Modifications)d(made)i(by)108 b(|)700 789
+y(V)44 b(random)20 b(programmers\))f(--->--+)460 839 y(+-------------------)o
+(----+)460 888 y(|)j(Modified)e(GNU)h(Version)43 b(|)460 938
+y(+-------------------)o(----+)343 1079 y Fb(Once)13 b(a)f(w)o(ork)h(is)g
+(released)e(under)g(GNU)i(license,)f(all)g(deriv)o(ed)f(w)o(orks)h(fall)g
+(under)g(GNU)h(license.)18 b(Ho)o(w)o(ev)o(er,)281 1129 y(this)9
+b(diagram)f(sho)o(ws)i(ho)o(w)g(cop)o(yrigh)o(t)d(can)i(b)q(e)h(main)o
+(tained)d(o)o(v)o(er)i(a)h(w)o(ork,)g(while)f(still)g(making)f(it)i(a)o(v)n
+(ailable)e(under)281 1179 y(GNU)14 b(license.)19 b(Unfortunately)m(,)11
+b(this)i(sc)o(heme)e(requires)h(that)g(cop)o(yrigh)o(t)f(on)i(mo)q
+(di\014cati)o(ons)d(to)j(F)m(unnelW)m(eb)f(b)q(e)281 1229 y(signed)e(o\013)h
+(b)o(y)g(the)g(p)q(eople)e(who)j(mak)o(e)e(the)h(mo)q(di\014catio)o(ns.)453
+1320 y Fk(Figure)j(1)p Fn(:)k(Ho)o(w)13 b(I)h(am)e(going)h(to)h(main)o(tain)d
+(cop)o(yrigh)o(t)i(o)o(v)o(er)h(F)m(unnelW)m(eb.)228 1453 y(1.)20
+b(Getting)15 b(eac)o(h)i(p)q(erson)g(who)e(con)o(tributes)i(mo)q
+(di\014cations)d(to)i(F)m(unnelW)m(eb)g(to)f(sign)h(and)g(send)g(a)g(piece)
+281 1503 y(of)d(pap)q(er)i(signing)e(a)o(w)o(a)o(y)f(cop)o(yrigh)o(t)i(will)e
+(b)q(e)j(tedious.)228 1580 y(2.)20 b(Programmers)14 b(ma)o(y)g(b)q(e)j
+(reluctan)o(t)f(to)g(sign)g(a)o(w)o(a)o(y)e(cop)o(yrigh)o(t)i(on)g(mo)q
+(di\014cations)e(b)q(ecause)j(the)g(result)281 1630 y(could)e(b)q(e)h(used)g
+(b)o(y)f(me)f(for)h(commercial)d(purp)q(oses)17 b(b)o(y)e(me)f(at)h(a)g
+(later)h(date)f(\(Note:)21 b(But)16 b(it)f(m)o(ust)f(b)q(e)281
+1679 y(released)h(under)g(GNU)f(as)f(w)o(ell\).)177 1774 y(These)18
+b(disadv)n(an)o(tages)d(are)i(regrettable)g(consequences)i(of)c(m)o(y)g
+(decision)h(to)g(retain)g(total)f(con)o(trol)h(o)o(v)o(er)g(the)177
+1824 y(\\o\016cial")c(v)o(ersion)i(of)f(F)m(unnelW)m(eb.)177
+1893 y(The)h(upshot)h(of)e(all)g(this)h(is)f(that:)239 1988
+y Fm(\017)21 b Fn(I)12 b(will)e(nev)o(er)i(allo)o(w)f(an)o(y)g(co)q(de)h
+(from)e(a)i(GNU)f(release)i(of)e(F)m(unnelW)m(eb)g(to)h(touc)o(h)g(m)o(y)e
+(o\016cial)g(cop)o(y)m(.)17 b(Only)281 2038 y(mo)q(di\014cations)12
+b(will)g(b)q(e)j(acceptable.)239 2115 y Fm(\017)21 b Fn(If)e(y)o(ou)g(mak)o
+(e)f(a)h(mo)q(di\014cation)e(to)j(F)m(unnelW)m(eb)f(and)g(send)h(it)f(to)h
+(me)e(for)h(inclusion)g(in)g(the)h(o\016cial)281 2165 y(v)o(ersion,)d(I)f
+(will)g(not)g(incorp)q(orate)h(y)o(our)g(mo)q(di\014cation)d(un)o(til)i(I)h
+(ha)o(v)o(e)f(receiv)o(ed)i(a)e(signed)h(declaration)281 2214
+y(transferring)11 b(cop)o(yrigh)o(t.)17 b(I)11 b(will)e(prepare)k(suc)o(h)e
+(a)g(con)o(tract)h(when)f(the)h(\014rst)f(p)q(erson)h(sends)g(me)e(a)h(w)o
+(orth)o(y)281 2264 y(mo)q(di\014cation!)239 2341 y Fm(\017)21
+b Fn(If)12 b(y)o(ou)g(in)o(tend)h(to)f(mak)o(e)f(c)o(hanges)i(to)g(F)m
+(unnelW)m(eb)f(that)g(are)h(so)g(massiv)o(e)e(that)i(they)g(will)e(in)o(v)o
+(olv)o(e)g(wide-)281 2391 y(scale)i(mo)q(di\014cation)e(of)h(the)i(source)g
+(\014les,)f(and)g(y)o(ou)f(w)o(an)o(t)h(the)g(mo)q(di\014cation)e(to)i(b)q(e)
+g(part)g(of)g(the)g(o\016cial)281 2441 y(v)o(ersion,)j(it)g(migh)o(t)e(b)q(e)
+j(a)f(go)q(o)q(d)f(idea)h(to)g(con)o(tact)h(me)e(b)q(efore)i(doing)e(so.)25
+b(There)17 b(are)f(t)o(w)o(o)g(reasons)h(for)281 2491 y(doing)11
+b(this.)18 b(First,)12 b(it)g(allo)o(ws)f(me)h(a)g(c)o(hance)h(to)f(commen)o
+(t)e(on)i(y)o(our)h(prop)q(osed)g(mo)q(di\014cations)d(and)i(giv)o(e)281
+2540 y(m)o(y)i(opinion)g(on)i(whether)h(they)f(are)g(lik)o(ely)e(to)i(b)q(e)g
+(incorp)q(orated)g(in)o(to)f(the)i(o\016cial)d(v)o(ersion.)23
+b(Second,)281 2590 y(I)16 b(can)f(send)i(y)o(ou)e(a)g(cop)o(y)h(\(under)h(sp)
+q(ecial)e(license\))i(of)e(the)h(GNU-clean)g(o\016cial)e(v)o(ersion)i(to)f(w)
+o(ork)g(on.)281 2640 y(This)f(will)e(allo)o(w)g(y)o(ou)i(to)g(ship)f(bac)o(k)
+h(y)o(our)g(c)o(hanges)h(as)e(\014les)i(rather)f(than)g(as)g(c)o(hange)h
+(sections.)177 2735 y(As)h(a)g(separate)h(p)q(oin)o(t)e(from)f(the)i(legal)f
+(issues,)h(I)g(am)e(lik)o(ely)g(to)i(turn)g(out)g(to)f(b)q(e)i(prett)o(y)f
+(pic)o(ky)f(ab)q(out)h(what)177 2785 y(mo)q(di\014cations)10
+b(I)j(will)d(incorp)q(orate)j(in)o(to)e(the)i(o\016cial)e(cop)o(y)m(.)17
+b(Whether)c(a)f(mo)q(di\014cation)e(will)h(b)q(e)h(accepted)i(will)177
+2835 y(dep)q(end,)h(amongst)d(other)j(things,)e(on)h(the)g(follo)o(wing)d
+(criteria.)1042 2940 y(40)p eop
+%%Page: 41 42
+41 41 bop 239 42 a Fm(\017)21 b Fn(Do)q(es)11 b(the)g(mo)q(di\014cation)e
+(\014t)i(in)f(with)h(the)g(design)g(goals)f(of)g(F)m(unnelW)m(eb,)h(or)f(is)h
+(it)f(just)h(a)g(case)h(of)e(creeping)281 91 y(featurism?)239
+174 y Fm(\017)21 b Fn(Ho)o(w)13 b(w)o(ell)h(co)q(ded)g(is)g(the)h(mo)q
+(di\014cation?)h(W)m(ould)c(it)i(reduce)h(the)g(qualit)o(y)d(of)h(the)i(co)q
+(de?)239 257 y Fm(\017)21 b Fn(If)14 b(the)i(mo)q(di\014cation)d(c)o(hanges)i
+(F)m(unnelW)m(eb's)g(functionalit)o(y)m(,)d(is)j(this)g(a)g(desirable)g(c)o
+(hange?)22 b(Ho)o(w)14 b(will)281 307 y(it)f(impact)g(on)g(existing)h(users?)
+239 390 y Fm(\017)21 b Fn(W)m(ould)13 b(it)g(b)q(e)i(quic)o(k)o(er)f(for)g
+(me)f(to)h(mak)o(e)f(the)h(mo)q(di\014cation)e(m)o(yself)h(than)h(to)g(w)o
+(ork)f(out)h(ho)o(w)g(to)g(incor-)281 440 y(p)q(orate)g(the)h(submitted)e(mo)
+q(di\014cation?)177 556 y(It)g(is)f(m)o(y)f(goal)h(to)g(guard)h(the)g(in)o
+(tegrit)o(y)f(of)g(the)h(design)g(and)f(co)q(de)i(of)e(the)h(o\016cial)e(v)o
+(ersion)i(of)f(F)m(unnelW)m(eb)g(and)177 606 y(so)h(I)g(will)e(probably)h(b)q
+(e)h(rather)h(fussy)f(ab)q(out)f(what)h(I)f(regard)i(as)e(a)h(w)o(orth)o
+(while)f(mo)q(di\014cation.)j(I)e(do)f(not)h(wish)177 656 y(to)h(lose)g(con)o
+(trol)f(of)h(the)g(co)q(de,)g(either)h(tec)o(hnically)f(or)g(legally)m(.)177
+818 y Fe(3.8)70 b(A)23 b(GNU)f(V)-6 b(ersion?)177 934 y Fn(The)18
+b(con)o(trols)f(on)f(the)i(o\016cial)d(v)o(ersion)i(of)g(F)m(unnelW)m(eb)f
+(describ)q(ed)j(in)d(the)i(previous)f(section)h(will)d(ha)o(v)o(e)i(at)177
+984 y(most)d(a)h(minor)e(impact)h(on)h(F)m(unnelW)m(eb)g(dev)o(elopmen)o(t)f
+(if)h(F)m(unnelW)m(eb)f(already)h(serv)o(es)i(the)f(needs)g(of)f(most)177
+1034 y(of)k(its)h(users.)36 b(Ho)o(w)o(ev)o(er,)21 b(if)e(it)g(turns)h(out)g
+(that)f(F)m(unnelW)m(eb)g(is)h(b)q(oth)g(p)q(opular,)g Fh(and)g
+Fn(needs)h(widespread)177 1083 y(mo)q(di\014cations)13 b(and)h(enhancemen)o
+(ts,)h(then)g(the)g(o\016cial)e(feedbac)o(k)i(lo)q(op)e(describ)q(ed)j(in)e
+(the)h(previous)g(section)177 1133 y(will)e(b)q(ecome)g(un)o(w)o(ork)n(able,)
+g(and)h(there)h(will)d(b)q(e)j(a)e(GNU)h(break)o(out.)177 1208
+y(A)g Fk(GNU)i(break)o(out)c Fn(will)g(o)q(ccur)j(if)e(F)m(unnelW)m(eb)g
+(users)j(b)q(ecome)d(organized)h(enough)g(and)g(anno)o(y)o(ed)g(enough)177
+1258 y(\(at)20 b(the)h(o\016cial)d(dev)o(elopmen)o(t)h(cycle\))i(to)f(start)g
+(main)o(taining)d(a)j(coheren)o(t)h(v)o(ersion)f(of)f(F)m(unnelW)m(eb)h(that)
+177 1307 y(div)o(erges)f(from)d(the)j(o\016cial)e(v)o(ersion.)31
+b(If)18 b(a)g(GNU)g(break)o(out)g(o)q(ccurs,)i(I)e(w)o(ould)g(appreciate,)h
+(as)g(requested)177 1357 y(earlier,)14 b(that)g(a)f(di\013eren)o(t)i(name)e
+(and)h(\014le)f(extensions)i(b)q(e)g(c)o(hosen)g(for)e(the)i(div)o(erging)e
+(v)o(ersion.)177 1519 y Fe(3.9)70 b(Summary)177 1635 y Fn(Decen)o(tralized)21
+b(mo)q(di\014cations)d(to)i(a)f(programming)d(language)j(and)h(its)g
+(implemen)o(tatio)o(ns)e(can)i(seriously)177 1685 y(damage)12
+b(the)i(language's)f(p)q(ortabilit)o(y)f(and)i(seman)o(tic)e(clarit)o(y)m(.)
+17 b(Unfortunately)m(,)c(there)i(is)e(a)g(tension)h(b)q(et)o(w)o(een)177
+1735 y(cen)o(tralizing)c(con)o(trol)g(of)f(a)h(programmi)o(ng)d(language)i
+(and)h(pro)o(viding)f(source)i(co)q(de)g(securit)o(y)g(to)f(nerv)o(ous)h
+(users.)177 1785 y(In)k(F)m(unnelW)m(eb,)e(this)i(trade-o\013)g(has)g(b)q
+(een)g(resolv)o(ed)g(to)g(some)e(exten)o(t)j(b)o(y)e(releasing)h(the)g
+(source)h(co)q(de)f(along)177 1835 y(with)h(a)g(request)i(that)e(if)g(the)g
+(functionalit)o(y)f(of)h(the)h(program)d(is)i(mo)q(di\014ed,)f(that)i(the)g
+(program's)d(name)h(b)q(e)177 1884 y(c)o(hanged)d(and)g(a)f(di\013eren)o(t)i
+(\014le)e(extension)i(b)q(e)f(c)o(hosen)h(for)e(input)h(\014les)g(created)h
+(under)f(the)h(mo)q(di\014ed)d(program.)177 1934 y(The)k(author)g(of)f(F)m
+(unnelW)m(eb)g(has)g(decided)i(to)e(main)o(tain)e(an)i(o\016cial)g(v)o
+(ersion)g(of)g(F)m(unnelW)m(eb)g(o)o(v)o(er)h(whic)o(h)f(he)177
+1984 y(will)h(o)o(wn)h(cop)o(yrigh)o(t,)g(but)h(whic)o(h)f(he)h(will)e
+(release)j(under)f(GNU)f(license)i(from)c(time)h(to)i(time.)21
+b(This)16 b(means)177 2034 y(that)g(cop)o(yrigh)o(t)f(on)h(all)e(c)o(hanges)j
+(to)e(F)m(unnelW)m(eb)h(m)o(ust)e(b)q(e)j(signed)f(o)o(v)o(er)f(to)h(the)g
+(author)g(b)q(efore)h(they)f(ha)o(v)o(e)177 2084 y(a)g(c)o(hance)i(of)e(b)q
+(eing)h(incorp)q(orated)g(in)f(the)h(o\016cial)e(v)o(ersion.)27
+b(Finally)m(,)14 b(it)j(is)f(p)q(ossible)h(that)g(this)f(reluctance)177
+2133 y(of)e(the)h(author)f(to)g(remo)o(v)o(e)f(his)h(cop)o(yrigh)o(ted)h(v)o
+(ersion)f(from)e(the)j(dev)o(elopmen)o(t)e(cycle)i(of)f(the)h(o\016cial)e(v)o
+(ersion)177 2183 y(will)e(result)j(in)e(a)g(GNU)h(break)o(out)g(in)f(whic)o
+(h)g(a)h(div)o(erging)e(GNU)i(v)o(ersion)f(of)h(F)m(unnelW)m(eb)f(will)f(b)q
+(e)i(main)o(tained)177 2233 y(b)o(y)h(the)g(GNU)g(comm)o(unit)o(y)m(.)h(The)f
+(author)g(hop)q(es)h(this)f(w)o(on't)f(b)q(e)i(necessary)h(and)e(requests,)h
+(if)e(this)h(happ)q(ens,)177 2283 y(that)g(the)h(div)o(erging)e(GNU)g(v)o
+(ersion)h(b)q(e)h(renamed.)1042 2940 y(41)p eop
+%%Page: 42 43
+42 42 bop 1042 2940 a Fn(42)p eop
+%%Page: 43 44
+43 43 bop 177 376 a Ff(Chapter)34 b(4)177 607 y Fl(F)-10 b(unnelW)g(eb)41
+b(F)-10 b(uture)177 847 y Fn(Previous)13 b(c)o(hapters)h(ha)o(v)o(e)f
+(explained)f(the)h(design)g(of)f(F)m(unnelW)m(eb)g(and)h(giv)o(en)f(reasons)i
+(for)e(wh)o(y)g(it)h(is)f(the)h(w)o(a)o(y)177 897 y(it)i(is.)24
+b(This)15 b(c)o(hapter)i(go)q(es)f(through)g(eac)o(h)g(of)f(the)i(asp)q(ects)
+g(of)e(F)m(unnelW)m(eb,)g(and)h(explores)g(their)g(problems,)177
+946 y(ho)o(w)e(they)g(can)g(b)q(e)h(solv)o(ed,)e(and)h(lists)f(opp)q
+(ortunities)i(for)e(impro)o(v)o(emen)o(t.)177 1107 y Fe(4.1)70
+b(Do)r(cumen)n(tation)177 1221 y Fk(An)12 b(o\016cial)f(example:)16
+b Fn(A)11 b(o\016cial)e(example)h(program)f(written)j(using)e(F)m(unnelW)m
+(eb)h(should)f(b)q(e)i(constructed)177 1271 y(and)i(made)f(a)o(v)n(ailable.)
+177 1344 y Fk(Index)20 b(program:)26 b Fn(In)19 b(order)f(to)h(t)o(yp)q(eset)
+g(the)g(do)q(cumen)o(tation,)f(a)g(p)q(ortable)g(index)g(sorting)g(program)f
+(is)177 1394 y(required.)31 b(One)19 b(should)e(b)q(e)i(written)f(and)g
+(added)g(to)g(the)g(distribution)g(kit.)29 b(P)o(erhaps)19
+b(this)f(could)g(b)q(e)g(the)177 1444 y(o\016cial)13 b(example!)177
+1604 y Fe(4.2)70 b(Command)22 b(Line)g(In)n(terface)177 1719
+y Fk(Bu\013er)14 b(length:)i Fn(Curren)o(tly)d(the)h(F)m(unnelW)m(eb)e(shell)
+h(uses)i(the)e Fi(COMLINE)p 1368 1719 14 2 v 15 w(MAX)f Fn(constan)o(t)h(to)g
+(size)h(its)f(in)o(ternal)177 1768 y(command)h(line)h(bu\013ers.)27
+b(This)16 b(is)g(un)o(tenable.)25 b(The)17 b(maxim)n(um)12
+b(length)k(of)g(a)g(shell)g(command)d(line)j(should)177 1818
+y(not)e(b)q(e)g(mac)o(hine)f(dep)q(enden)o(t.)177 1892 y Fk(An)o(tiquated)h
+(F)l(eatures:)k Fn(As)d(the)g(F)m(unnelW)m(eb)e(language)h(dev)o(elops,)g(it)
+g(is)g(lik)o(ely)f(that)i(some)e(c)o(hanges)i(will)177 1941
+y(ha)o(v)o(e)g(to)g(b)q(e)h(made)d(that)i(will)f(render)j(one)e(or)g(more)f
+(language)g(constructs)j(obsolete.)22 b(When)15 b(this)g(happ)q(ens,)177
+1991 y(it)e(ma)o(y)d(b)q(e)k(necessary)h(to)d(add)h(a)g(command)d(line)i
+(option)g(that)h(has)g(the)g(p)q(o)o(w)o(er)g(to)g(turn)g(on)g(and)f(o\013)h
+(w)o(arnings)177 2041 y(or)h(errors)h(\015agging)e(an)o(tiquated)g(features.)
+177 2201 y Fe(4.3)70 b(Shell)21 b(In)n(terpreter)177 2316 y
+Fk(SET)l(ALL)f(command:)25 b Fn(When)17 b(writing)g(F)m(unnelW)m(eb)g
+(scripts,)i(it)e(is)h(sometimes)e(desirable)i(to)f(set)h Fh(al)r(l)f
+Fn(of)177 2366 y(F)m(unnelW)m(eb's)f(options)h(to)f(some)g(particular)h(v)n
+(alue)f(so)h(that)f(the)i(script)f(is)g(not)f(vulnerable)h(to)g(c)o(hanges)g
+(in)177 2415 y(F)m(unnelW)m(eb's)e(default)h(v)n(alues)f(whic)o(h)h(migh)o(t)
+e(o)q(ccur)i(from)e(time)h(to)h(time.)22 b(T)m(o)15 b(this)h(end,)g(it)g(ma)o
+(y)d(b)q(e)k(w)o(orth)177 2465 y(creating)c(a)f(\\)p Fi(SETALL)p
+Fn(")f(command)f(that)i(is)h(iden)o(tical)e(to)i(the)g(\\)p
+Fi(SET)p Fn(")e(command)f(except)k(that)e(it)g(will)f(generate)177
+2515 y(an)j(error)h(if)e(the)h(v)n(alue)f(of)h(an)f(option)g(is)h(not)g(sp)q
+(eci\014ed)h(explicitly)m(.)177 2588 y Fk(Recursion)f(test:)j
+Fn(A)d(test)h(should)f(b)q(e)g(added)h(to)e(test)i(for)f(recursiv)o(e)h(in)o
+(v)o(o)q(cation)e(in)g(a)h(shellscript.)177 2662 y Fk(Diagnostic)e(coun)o
+(ting:)j Fn(The)e(co)q(de)g(for)f(coun)o(ting)g(diagnostics)h(in)f(the)h
+(script)g(in)o(terpreter)h(is)f(rather)g(messy)177 2711 y(and)h(p)q(erhaps)h
+(ev)o(en)f(buggy)m(.)k(It)13 b(should)h(b)q(e)h(cleaned)f(up)g(and)g(commen)o
+(ted.)177 2785 y Fk(Argumen)o(t)i(coun)o(ting:)j Fn(In)c(the)h
+Fi(command.c)e Fn(mo)q(dule,)g(there)j(is)e(a)g(v)n(ariable)g(that)g(coun)o
+(ts)h(the)h(argumen)o(ts)177 2835 y(to)d(a)g(command.)j(Curren)o(tly)d(it)g
+(tak)o(es)h(the)g(v)n(alue)e(of)h(the)h(n)o(um)o(b)q(er)e(of)h(parameters)g
+(including)g(the)h(command)1042 2940 y(43)p eop
+%%Page: 44 45
+44 44 bop 177 42 a Fn(v)o(erb.)19 b(This)13 b(has)g(turned)i(out)e(to)g(mak)o
+(e)f(the)i(co)q(de)g(less)h(readable.)j(It)13 b(should)g(b)q(e)h(c)o(hanged)g
+(to)f(b)q(e)h(the)g(n)o(um)o(b)q(er)177 91 y(of)f(argumen)o(ts)h(to)f(the)i
+(command)c(v)o(erb.)177 168 y Fk(Mak)o(e)k(facilit)o(y:)h Fn(It)d(ma)o(y)e(b)
+q(e)i(w)o(orth)g(building)f(some)g(sort)h(of)f(mak)o(e)g(facilit)o(y)f(in)o
+(to)h(the)i(script)g(language)e(so)h(as)177 218 y(to)h(supp)q(ort)h(mac)o
+(hines)e(suc)o(h)h(as)g(the)h(Macin)o(tosh)f(that)f(do)h(not)g(already)f(ha)o
+(v)o(e)h(this)g(facilit)o(y)m(.)177 295 y Fk(Signature)d(\014le:)17
+b Fn(One)c(problem)f(with)g(using)g(F)m(unnelW)m(eb)g(in)g(conjunction)g
+(with)h(an)f(external)h Fi(Make)e Fn(facilit)o(y)177 345 y(is)k(that)h(a)f
+(user)h(migh)o(t)d(c)o(hange)j(a)f(F)m(unnelW)m(eb)g(source)h(\014le)g
+(without)f(making)e(c)o(hanges)j(that)f(will)f(a\013ect)i(the)177
+395 y(\014les)g(that)f(it)f(generates.)24 b(If)14 b(F)m(unnelW)m(eb)h(is)g
+(then)h(run)f(and)g(the)h(\\)p Fi(+D)p Fn(")e(option)g(is)h(on,)g(then)g(the)
+h(output)f(\014les)177 445 y(will)g(b)q(e)i(deleted)h(\(to)f(a)o(v)o(oid)e
+(further)i Fi(Make)f Fn(propagations\).)25 b(If)17 b Fi(Make)e
+Fn(then)i(has)g(a)f(pro)q(duction)h(linking)e(the)177 495 y
+Fi(.fw)d Fn(\014le)h(to)g(its)g(output)g(\014les,)g(then)g(it)g(ma)o(y)e
+(conclude)i(that)g(the)g(output)g(\014les)h(are)f(still)f(out)h(of)f(date.)18
+b(T)m(o)12 b(solv)o(e)177 544 y(the)17 b(problem,)e(F)m(unnelW)m(eb)h(could)h
+(b)q(e)g(c)o(hanged)f(to)h(write)f(a)g Fi(.sig)g Fn(\014le)g(whenev)o(er)i
+(it)e(pro)q(cesses)j(a)e Fi(.fw)e Fn(\014le.)177 594 y(The)g
+Fi(Make)e Fn(pro)q(duction)h(could)f(then)i(b)q(e)f(wired)h(up)f(to)f(link)g
+(the)i Fi(.fw)e Fn(\014le)h(to)g(the)g Fi(.sig)f Fn(\014le)h(instead)g(of)f
+(to)h(the)177 644 y(output)g(\014les.)177 814 y Fe(4.4)70 b(Language)24
+b(Design)177 933 y Fn(Some)13 b(prop)q(osed)i(c)o(hanges)g(to)f(F)m(unnelW)m
+(eb)f(do)h(not)g(corresp)q(ond)i(to)e(an)o(y)f(particular)h(comp)q(onen)o(t)g
+(of)f(F)m(unnel-)177 983 y(W)m(eb)h(and)f(are)i(really)e(to)h(do)f(with)h
+(the)g(design)h(of)e(the)h(input)g(language.)177 1060 y Fk(Output)c(or)h
+(\014le?:)16 b Fn(The)11 b(\\)p Fi(@O)p Fn(")e(sp)q(ecial)i(sequence)i(for)d
+(de\014ning)h(an)f(output)h(\014le)g(is)f(somewhat)g(non-mnemoni)o(c)177
+1110 y(and)k(can)g(b)q(e)g(confused)h(with)f(zero)h(\(\\)p
+Fi(0)p Fn("\).)i(P)o(erhaps)e(it)e(should)h(b)q(e)h(replaced)g(b)o(y)e(the)i
+(\\)p Fi(@F)p Fn(")e(sequence.)177 1187 y Fk(Syn)o(tax)j(of)h(section)f
+(names:)k Fn(Curren)o(tly)15 b(section)h(names)e(use)i(the)g(same)e(syn)o
+(tax)h(as)g(macro)f(names.)21 b(F)m(or)177 1236 y(example)16
+b(\\)p Fi(@<Sloth@>)p Fn(".)25 b(It)17 b(can)h(b)q(e)f(argued)h(that)f(angle)
+f(brac)o(k)o(ets)i(should)f(b)q(e)h(reserv)o(ed)h(only)d(for)h(macro)177
+1286 y(names)f(and)h(that)f(some)g(other)i(syn)o(tax)e(should)h(b)q(e)g
+(found)g(for)f(delimiting)e(section)j(names.)26 b(This)17 b(is)f(not)h(a)177
+1336 y(clear)12 b(issue.)18 b(It)11 b(could)h(also)e(b)q(e)j(argued)e(that)h
+(they)g(are)g(b)q(oth)f(names,)g(and)g(that)g(b)q(ecause)j(sections)e(can)g
+(inherit)177 1386 y(their)i(names)g(from)e(the)i(macros)f(they)i(con)o(tain,)
+e(that)g(the)i(names)e(are)h(of)g(the)g(same)f(\\t)o(yp)q(e".)177
+1463 y Fk(One)i(macro)f(p)q(er)h(section:)i Fn(One)d(particular)f(st)o(yle)g
+(of)g(using)g(F)m(unnelW)m(eb)f(is)h(to)g(ha)o(v)o(e)g(at)h(most)e(one)h
+(macro)177 1513 y(de\014nition)f(p)q(er)h(section.)19 b(It)12
+b(ma)o(y)f(b)q(e)i(w)o(orth)f(adding)g(a)g(pragma)e(that)j(instructs)h(F)m
+(unnelW)m(eb)d(to)i(enforce)g(this.)177 1590 y Fk(Should)i(@)p
+Fm(f)i Fk(suppress)e(EOL?:)20 b Fn(When)15 b(de\014ning)g(a)g(macro)f(in)h(F)
+m(unnelW)m(eb,)f(it)h(seems)g(to)g(b)q(e)h(rule)f(rather)177
+1640 y(than)f(the)h(exception)f(that)g(the)h(\\)p Fi(@)p Fm(f)p
+Fn(")e(b)q(e)h(follo)o(w)o(ed)f(b)o(y)g(\\)p Fi(@-)p Fn(".)18
+b(This)13 b(suppresses)k(the)e(EOL)f(on)g(the)g(de\014nition)177
+1690 y(line,)e(allo)o(wing)f(the)i(\014rst)h(line)e(of)h(the)g(macro)f(to)g
+(b)q(e)i(placed)f(immedia)o(tely)d(ab)q(o)o(v)o(e)j(and)f(in)h(line)f(with)h
+(the)g(other)177 1739 y(lines)k(without)g(in)o(tro)q(ducing)g(an)f(EOL)i(at)f
+(the)g(start)h(of)f(the)g(macro)f(text.)28 b(One)18 b(option)e(is)h(to)g(in)o
+(tro)q(duce)h(a)177 1789 y(pragma)12 b(to)i(determine)g(whether)h(to)f
+(suppress)i(EOLs)e(follo)o(wing)e(\\)p Fi(@)p Fm(f)p Fn(".)177
+1866 y Fk(Pragma)20 b(syn)o(tax:)26 b Fn(It)18 b(is)g(not)g(clear)g(ho)o(w)g
+(\\lo)q(ose")f(the)i(syn)o(tax)f(of)f(pragmas)g(should)g(b)q(e.)31
+b(P)o(erhaps)19 b(they)177 1916 y(should)14 b(b)q(e)g(case)h(insensitiv)o(e.)
+177 1993 y Fk(Conditional)o(s:)23 b Fn(Dep)q(ending)17 b(on)g(demand,)g(it)g
+(ma)o(y)e(b)q(e)j(w)o(orth)g(rein)o(tro)q(ducing)f(some)g(sort)g(of)g
+(conditional)177 2043 y(feature)g(in)o(to)f(F)m(unnelW)m(eb.)24
+b(Ho)o(w)o(ev)o(er,)17 b(it)e(w)o(ould)h(ha)o(v)o(e)g(to)g(b)q(e)h(v)o(ery)f
+(simple)f(to)h(comp)q(ete)g(with)g(the)g(v)n(arious)177 2093
+y(w)o(a)o(ys)e(in)f(whic)o(h)h(conditionals)f(can)h(already)f(b)q(e)i(fudged)
+f(within)f(F)m(unnelW)m(eb)g(as)h(it)g(stands.)177 2170 y Fk(File)h(mark)o
+(ers:)20 b Fn(It)14 b(migh)o(t)f(b)q(e)i(w)o(orth)g(mo)q(difying)d(the)j
+(language)f(so)h(that)f(a)h(sp)q(ecial)g(syn)o(tactical)f(mark)o(er)g(is)177
+2220 y(required)d(at)f(the)h(start)g(and)f(end)g(of)g(\014les.)17
+b(This)10 b(will)f(assist)h(in)g(detecting)h(truncations)g(and)f(other)h
+(corruptions.)177 2297 y Fk(F)l(ormal)i(parameter)g(lists:)j
+Fn(It)d(migh)o(t)d(b)q(e)j(w)o(orth)g(c)o(hanging)f(o)o(v)o(er)g(to)h(a)f
+(syn)o(tax)g(for)h(formal)d(parameter)i(lists)177 2347 y(that)k(do)q(es)h
+(not)g(require)g(the)f Fi(@\()g Fn(and)g Fi(@\))p Fn(.)25 b(Ho)o(w)o(ev)o
+(er,)17 b(they)f(could)g(b)q(e)h(retained)g(as)f(optional)f(for)h(bac)o(kw)o
+(ard)177 2396 y(compatibilit)o(y)m(.)177 2566 y Fe(4.5)70 b(Scanner/Mapp)r
+(er)177 2685 y Fk(All)17 b(non-con)o(tiguo)o(us)e(mappings:)21
+b Fn(Curren)o(tly)c(F)m(unnelW)m(eb)e(requires)i(that)g(all)e(input)g
+(\014les)i(b)q(e)g(mapp)q(ed)177 2735 y(in)o(to)e(a)g(con)o(tiguous)g(lump)f
+(of)h(memory)m(.)20 b(This)15 b(caused)i(problems)e(for)g(t)o(w)o(o)g
+(reasons.)24 b(First,)15 b(to)h(do)f(this,)h(one)177 2785 y(has)c(to)g(allo)q
+(cate)f(the)h(memory)d(\014rst,)k(and)e(to)h(do)f(that,)h(y)o(ou)f(ha)o(v)o
+(e)h(to)f(kno)o(w)g(ho)o(w)h(long)f(the)h(\014le)g(is,)f(and)h(it)f(turns)177
+2835 y(out)j(that)g(\014nding)g(out)g(the)g(length)g(of)f(a)h(\014le)g(in)g
+(a)f(p)q(ortable)i(manner)e(is)h(v)o(ery)g(ine\016cien)o(t.)k(Second,)d
+(although)1042 2940 y(44)p eop
+%%Page: 45 46
+45 45 bop 177 42 a Fn(IBM)14 b(PC)f(compatibles)f(ma)o(y)f(ha)o(v)o(e)i
+(megab)o(ytes)g(of)g(memory)m(,)d(it)i(is)i(segmen)o(ted)f(in)o(to)f(blo)q(c)
+o(ks)i(of)e(at)h(most)f(64K.)177 91 y(This)i(means)f(that)h(F)m(unnelW)m(eb)f
+(curren)o(tly)i(cannot)f(read)h(a)e(\014le)h(longer)g(than)g(64K)f(on)h(a)f
+(PC.)177 168 y(These)j(problems)d(could)i(b)q(e)g(a)o(v)o(oided)e(if)h(the)h
+(mapp)q(er)f(and)g(scanner)i(w)o(ere)f(reorganized)g(to)f(allo)o(w)f(input)h
+(\014les)177 218 y(to)g(b)q(e)g(read)h(in)e(and)h(stored)h(as)f(a)f(link)o
+(ed)h(list)f(of)g(c)o(h)o(unks)i(of)e(text)h(rather)h(than)f(a)g(con)o
+(tiguous)f(blo)q(c)o(k.)177 295 y Fk(EOL)h(is)g(unsp)q(eci\014abl)o(e:)h
+Fn(F)m(unnelW)m(eb)d(uses)h(ASCI)q(I)g(c)o(haracter)h(decimal)d(ten)i(\(10\))
+f(in)o(ternally)f(to)h(represen)o(t)177 345 y(logical)g(end-of-line)g(and)h
+(is)g(curren)o(tly)h(organized)f(so)g(that)g(if)g(one)g(of)g(these)h(is)f
+(inserted)h(in)o(to)f(the)h(text)f(b)o(y)g(the)177 395 y(user)g(using)e(a)h
+(\\)p Fi(@^D\(10\))p Fn(",)d(it)j(will)e(b)q(e)i(written)h(out)e(as)h(a)f
+(logical)f(end)i(of)g(line,)f(rather)h(than)g(as)g(a)f(single)h(ASCI)q(I)177
+445 y(c)o(haracter)j(10.)j(This)c(should)f(b)q(e)i(\014xed.)177
+522 y Fk(Allo)o(w)g(mnemonics)f(for)i(unprin)n(tabl)o(es:)g
+Fn(F)m(unnelW)m(eb)e(allo)o(ws)f(users)j(to)e(insert)h(unprin)o(table)f(c)o
+(haracters)177 572 y(in)o(to)i(the)h(output)f(using)g(the)h(\\)p
+Fi(@^D\(ddd\))p Fn(")d(sp)q(ecial)i(sequence.)28 b(P)o(erhaps)17
+b(it)f(w)o(ould)f(b)q(e)i(c)o(hanged)g(so)f(that)g(it)177 622
+y(understands)g(ASCI)q(I)e(standard)g(mnemonics)e(suc)o(h)i(as)g(\\)p
+Fi(LF)p Fn(")f(as)h(w)o(ell)f(as)h(ASCI)q(I)h(n)o(um)o(b)q(ers.)177
+699 y Fk(V)l(ersion)h(pragma:)22 b Fn(A)16 b(\\)p Fi(version)p
+Fn(")e(pragma)g(should)h(b)q(e)i(added)f(that)g(allo)o(ws)e(the)j(user)g(to)e
+(sp)q(ecify)i(in)e(the)177 749 y(input)g(\014le)h(the)g(v)o(ersion)g(of)e(F)m
+(unnelW)m(eb)h(that)h(w)o(as)f(around)h(when)g(the)g(input)f(\014le)g(w)o(as)
+h(created.)24 b(A)o(t)16 b(a)f(later)177 799 y(date,)g(suc)o(h)h(a)e
+(construct)j(w)o(ould)d(b)q(e)i(v)o(ery)f(useful)g(for)f(determining)g(ho)o
+(w)h(an)f(input)h(\014le)g(should)g(b)q(e)g(up)q(dated)177
+848 y(if)e(the)i(F)m(unnelW)m(eb)e(language)g(has)h(c)o(hanged)g(b)q(et)o(w)o
+(een)i(v)o(ersions.)177 1018 y Fe(4.6)70 b(P)n(arser)177 1138
+y Fn(There)15 b(are)g(no)e(prop)q(osals)h(to)g(c)o(hange)g(the)h(parser)g
+(except)g(as)f(a)f(consequence)k(of)c(other)h(prop)q(osals.)177
+1308 y Fe(4.7)70 b(Analyser)177 1427 y Fk(Recursion)11 b(detection:)k
+Fn(Curren)o(tly)d(the)h(F)m(unnelW)m(eb)e(analyser)h(\015ags,)f(with)h(an)f
+(error,)i(all)e(macros)g(with)g(an)177 1477 y(in\014nite)g(expansion.)17
+b(This)12 b(w)o(ould)e(b)q(e)i(b)q(est)g(c)o(hanged)g(to)f(\015agging)f(all)g
+(macros)h(that)g(are)h(directly)g(or)f(indirectly)177 1526
+y(recursiv)o(e.)19 b(T)m(o)11 b(do)g(this,)g(T)m(arjan's)g(algorithm)p
+Fk([T)l(arjan72])d Fn(for)k(the)g(detection)g(of)f(strong)h(comp)q(onen)o(ts)
+f(should)177 1576 y(b)q(e)k(installed.)177 1653 y Fk(Once)h(only)g(macros:)k
+Fn(By)15 b(default)f(F)m(unnelW)m(eb)g(prev)o(en)o(ts)i(a)f(macro)e(from)g(b)
+q(eing)h(called)h(more)e(than)i(once)177 1703 y(unless)g(it)e(has)h(a)f(\\)p
+Fi(@M)p Fn(")g(asso)q(ciated)h(with)g(it.)j(Ho)o(w)o(ev)o(er,)d(F)m(unnelW)m
+(eb)f(do)q(es)i(allo)o(w)d(a)h(macro)g(that)g(calls)h(suc)o(h)g(a)177
+1753 y(macro)f(to)h(b)q(e)g(called)g(more)f(than)g(once.)19
+b(P)o(erhaps)c(this)f(\\lo)q(ophole")e(should)i(b)q(e)h(plugged)e(someho)o
+(w.)177 1923 y Fe(4.8)70 b(T)-6 b(angle)177 2042 y Fn(The)12
+b(T)m(angler)f(is)h(one)g(of)f(the)i(cleanest)g(comp)q(onen)o(ts)e(of)g(F)m
+(unnelW)m(eb,)g(as)h(basically)f(all)f(it)i(has)g(to)f(do)h(is)g(expand)177
+2092 y(some)h(v)o(ery)h(w)o(ell-de\014ned)h(macros.)177 2169
+y Fk(T)l(ext)23 b(inden)o(tati)o(on)o(:)28 b Fn(Curren)o(tly)21
+b(F)m(unnelW)m(eb)e(supp)q(orts)j Fh(no)f(indentation)g Fn(and)f
+Fh(blank)g(indentation)p Fn(.)38 b(A)177 2219 y(third)17 b(form)d(could)j(b)q
+(e)g(added)g(if)e(it)h(w)o(as)h(considered)g(necessary)m(.)28
+b Fh(T)m(ext)17 b(indentation)g Fn(is)f(the)h(same)f(as)g Fh(blank)177
+2269 y(indentation)g Fn(except)h(that)e(instead)g(of)g(inden)o(ting)f(with)h
+(blanks,)g(F)m(unnelW)m(eb)f(w)o(ould)g(inden)o(t)i(with)e(the)i(text)177
+2319 y(to)g(the)h(left)f(of)g(the)h(called)f(macro.)24 b(This)16
+b(facilit)o(y)f(could)h(b)q(e)h(useful)f(for)g(commen)o(ting)d(out)k(large)f
+(b)q(o)q(dies)g(of)177 2369 y(text)f(in)f(languages)h(that)f(do)h(not)f(ha)o
+(v)o(e)g(m)o(ulti-line)e(commen)o(ts)h(\(e.g.)20 b(Ada\).)g(A)15
+b(discussion)g(of)f(the)h(pros)g(and)177 2418 y(cons)g(of)e(this)h(form)e(of)
+h(inden)o(tation)h(app)q(ears)g(earlier.)177 2588 y Fe(4.9)70
+b(W)-6 b(ea)n(v)n(e)177 2708 y Fn(P)o(erhaps)15 b(F)m(unnelW)m(eb's)e(w)o
+(eak)o(est)i(asp)q(ect)g(is)f(its)g(t)o(yp)q(esetting)h(facilit)o(y)m(.)177
+2785 y Fk(Align)g(table)h(of)h(con)o(ten)o(ts:)i Fn(When)c(F)m(unnelW)m(eb)f
+(generates)j(a)e(table)g(of)g(con)o(ten)o(ts,)h(the)f(section)h(n)o(um)o(b)q
+(ers)177 2835 y(are)e(not)g(quite)g(aligned)f(with)h(the)g(start)h(of)e(the)h
+(con)o(trolling)f(heading)h(ab)q(o)o(v)o(e)f(them.)1042 2940
+y(45)p eop
+%%Page: 46 47
+46 46 bop 177 42 a Fk(T)o(yp)q(esetting)20 b(strength:)27 b
+Fn(It)20 b(should)g(b)q(e)g(p)q(ossible)g(to)f(sp)q(ecify)h(the)g(lev)o(el)g
+(of)f(t)o(yp)q(esetting)h(strength)h(for)177 91 y(headings)16
+b(so)g(that)h(short)f(do)q(cumen)o(ts)g(do)g(not)g(lo)q(ok)f(o)o(v)o(erdone)h
+(when)h(t)o(yp)q(eset.)26 b(A)16 b(new)h(pragma)d(w)o(ould)h(b)q(e)177
+141 y(go)q(o)q(d)f(for)f(this.)177 222 y Fk(T)o(yp)q(eset)f(a)h(p)q(ortion:)i
+Fn(Sometimes)9 b(it)i(is)g(desirable)g(to)g(t)o(yp)q(eset)i(just)e(a)g(p)q
+(ortion)g(of)f(a)h(program.)k(A)d(command)177 272 y(line)g(option)f(could)h
+(b)q(e)g(added)g(to)g(do)g(this.)17 b(The)c(option)e(could)g(accept)j(as)e
+(its)g(argumen)o(t,)e(a)i(string)g(con)o(taining)177 322 y(a)i(list)f(of)g
+(section)i(n)o(um)o(b)q(ers)f(or)f(heading)h(names.)177 403
+y Fk(Generic)g(t)o(yp)q(esetter)f(option:)j Fn(In)e(addition)e(to)i(building)
+e(in)h(a)g(n)o(um)o(b)q(er)g(of)g(di\013eren)o(t)i(v)o(ersions)f(of)f(W)m(ea)
+o(v)o(e,)177 453 y(one)k(for)g(eac)o(h)g(p)q(opular)g(t)o(yp)q(esetter,)i(it)
+e(w)o(ould)f(b)q(e)h(p)q(ossible)g(to)g(add)g(a)f(sp)q(ecial)h(generic)h
+(format)d(where)j(the)177 503 y(t)o(yp)q(eset)h(output)e(is)g(expressed)i(in)
+e(terms)g(of)f Fh(F)m(unnelWeb)j(macr)n(os)p Fn(.)27 b(The)18
+b(user)g(could)f(then)g(sp)q(ecify)h(macro)177 552 y(de\014nitions)13
+b(for)g(a)f(non-supp)q(orted)i(t)o(yp)q(esetter)i(and)d(run)g(the)g(output)h
+(through)f(F)m(unnelW)m(eb)f(T)m(angle)g(to)h(get)g(a)177 602
+y(t)o(yp)q(eset)j(\014le)d(in)h(a)f(format)f(suitable)i(for)g(the)g(unsupp)q
+(orted)i(t)o(yp)q(esetter.)177 683 y Fk(Suppression)e(of)k(include)d
+(\014les:)21 b Fn(It)16 b(should)g(b)q(e)g(p)q(ossible)h(to)e(sp)q(ecify)i
+(in)e(the)i(input)e(\014le)h(that)g(particular)177 733 y(included)e(\014les)g
+(not)f(app)q(ear)h(in)f(the)h(t)o(yp)q(eset)h(output.)j(Curren)o(tly)m(,)13
+b(the)h(fact)f(that)g(an)h(inclusion)e(has)i(o)q(ccurred)177
+783 y(is)h(not)h(ev)o(en)g(represen)o(ted)i(in)d(the)h(t)o(yp)q(eset)g
+(output.)23 b(Suppression)16 b(of)f(inclusions)g(is)g(particularly)g
+(necessary)177 833 y(where)g(a)f(library)f(of)g(macros)g(has)h(b)q(een)h
+(included)f(at)g(the)h(top)e(of)h(eac)o(h)g(of)f(a)h(group)g(of)f(source)i
+(\014les.)177 914 y Fk(Cross)f(reference)e(of)i(iden)o(ti)o(\014ers)o(:)h
+Fn(WEB)e(pro)o(vides)f(a)g(list)g(of)g(iden)o(ti\014ers)h(and)f(a)g(list)g
+(of)g(all)f(the)i(de\014nitions)177 964 y(in)h(whic)o(h)f(they)i(are)f(used.)
+19 b(A)14 b(similar)d(feature)k(could)f(b)q(e)g(added)g(to)g(F)m(unnelW)m
+(eb.)177 1045 y Fk(Supp)q(ort)k(for)h(non-prin)n(tab)o(les)o(:)k
+Fn(Curren)o(tly)18 b(F)m(unnelW)m(eb)f(do)q(es)h(not)f(pro)o(vide)h(supp)q
+(ort)g(for)f(t)o(yp)q(esetting)177 1095 y(the)e(sp)q(ecial)f(\\)p
+Fi(@^\(num\))p Fn(")e(sequences.)20 b(This)14 b(should)g(b)q(e)g(added.)177
+1176 y Fk(Supp)q(ort)g(for)i(@+)h(sequences:)i Fn(Curren)o(tly)c(W)m(ea)o(v)o
+(e)f(do)q(es)h(not)f(see)i(\\)p Fi(@+)p Fn(")e(sequences)j(as)d(suc)o(h.)21
+b(Instead)15 b(it)177 1225 y(p)q(erceiv)o(es)h(them)d(as)h(ordinary)f(EOLs.)
+19 b(Ho)o(w)o(ev)o(er,)14 b(there)h(are)g(argumen)o(ts)e(for)g(t)o(yp)q
+(esetting)i(them)e(sp)q(ecially)m(.)177 1306 y Fk(T)o(yp)q(eset)e(text)h(in)f
+(macro)h(b)q(o)q(dies:)j Fn(One)d(of)e(the)h(m)o(uc)o(h-lo)o(v)o(ed)e
+(features)i(of)f(WEB)h(is)g(the)g(w)o(a)o(y)f(that)h(it)f(allo)o(ws)177
+1356 y(the)j(user)h(to)e(switc)o(h)h(recursiv)o(ely)g(b)q(et)o(w)o(een)h(do)q
+(cumen)o(t)e(and)g(program)f(formats.)16 b(F)m(unnelW)m(eb)c(do)q(es)h(not)f
+(allo)o(w)177 1406 y(this,)18 b(but)g(should.)29 b(In)17 b(F)m(unnelW)m(eb,)h
+(the)g(delimiters)f(\\)p Fi(@)p Fm(f)p Fn(")f(and)i(\\)p Fi(@)p
+Fm(g)p Fn(")e(are)i(already)f(used)i(consisten)o(tly)f(to)177
+1456 y(delimit)g(macro)g(text.)37 b(The)20 b(\\)p Fi(@[)p Fn(")f(and)g(\\)p
+Fi(@])p Fn(")g(sequences)j(ha)o(v)o(e)e(b)q(een)h(reserv)o(ed)h(for)d(the)i
+(delimitation)16 b(of)177 1506 y(do)q(cumen)o(tation)d(text.)177
+1587 y Fk(Non-tt)h(t)o(yp)q(esetting:)i Fn(The)d(curren)o(t)i(v)o(ersion)f
+(of)f(F)m(unnelW)m(eb)g(sets)i(all)d(its)h(macro)f(text)i(in)f
+Fi(tt)22 b(font)p Fn(.)17 b(This)177 1637 y(is)d(b)q(oth)g(a)f(blessing)h
+(and)g(a)g(curse.)19 b(It)14 b(is)g(a)f(blessing)h(b)q(ecause)i(it)d
+(connects)j(the)e(reader)h(directly)f(to)g(the)g(co)q(de,)177
+1686 y(with)g(no)g(complicated)f(in)o(termediary)m(.)k(It)d(is)g(a)g(curse)i
+(b)q(ecause)g(it)e(lo)q(oks)f(ugly)h(compared)f(to)h(the)h(b)q(eautifully)177
+1736 y(t)o(yp)q(eset)h(programs)c(pro)q(duced)j(b)o(y)f(other)g(literate)h
+(programmi)o(ng)c(to)q(ols.)177 1817 y(The)20 b(di\016cult)o(y)e(with)g
+(adding)g(suc)o(h)i(b)q(eautiful)e(t)o(yp)q(esetting)i(is)f(that)g(it)g(is)g
+(necessarily)h(language-sp)q(eci\014c.)177 1867 y(Keyw)o(ords)15
+b(and)f(syn)o(tax)g(di\013er)g(from)e(language)i(to)f(language)g(and)h(it)g
+(w)o(ould)f(not)h(b)q(e)h(easy)f(to)g(come)f(up)h(with)177
+1917 y(a)g(set)h(of)e(language)g(indep)q(enden)o(t)i(rules.)177
+1998 y(One)k(approac)o(h)g(is)f(to)g(write)g(a)h(set)g(of)e(W)m(ea)o(v)o(e)h
+(bac)o(k-ends,)i(one)e(for)g(eac)o(h)h(language.)31 b(Another)19
+b(approac)o(h)177 2048 y(is)e(to)g Fh(gener)n(ate)f Fn(bac)o(k)h(ends.)28
+b(This)17 b(is)g(the)g(approac)o(h)g(tak)o(en)g(in)f(the)i
+Fh(Spider)f Fn(system)p Fk([Ramsey89])p Fn(.)26 b(In)17 b(the)177
+2098 y Fh(Spider)f Fn(system,)g(the)h(programmer)d(writes)i(pro)q(duction)h
+(rules)f(for)g(con)o(v)o(erting)g(lexical)f(comp)q(onen)o(ts)h(of)f(the)177
+2148 y(program)f(text)h(in)o(to)g(t)o(yp)q(esetter)i(instructions.)22
+b(The)16 b Fh(Spider)f Fn(program)e(reads)j(these)h(rules)e(and)g(generates)i
+(a)177 2197 y(new)d(v)o(ersion)h(of)e(WEB)h(suited)g(for)g(the)g(target)h
+(language.)177 2278 y(F)m(or)j(F)m(unnelW)m(eb)g(a)g(sligh)o(tly)f
+(di\013eren)o(t)j(system)e(is)g(prop)q(osed)i(in)e(whic)o(h)g(Spider-lik)o(e)
+g(rules)h(app)q(ear)g(in)f(the)177 2328 y(input)e(\014le)h(and)f(are)h(used)h
+(directly)e(b)o(y)h(W)m(ea)o(v)o(e)f(to)g(p)q(erform)g(the)h(t)o(yp)q
+(esetting.)27 b(An)16 b(in)o(termediate)g(abstract)177 2378
+y(t)o(yp)q(esetting)d(language)e(could)h(b)q(e)h(used)g(so)f(that)g(the)h
+(pro)q(ductions)f(can)h(b)q(e)f(made)f(language)g(sp)q(eci\014c,)j(but)e(not)
+177 2428 y(t)o(yp)q(esetter)k(sp)q(eci\014c.)177 2610 y Fe(4.10)70
+b(Lister)177 2735 y Fk(Glue)17 b(factor:)23 b Fn(A)16 b(glue)g(factor)g
+(could)g(b)q(e)h(added)g(that)f(determines)h(ho)o(w)f(man)o(y)e(lines)i(can)h
+(b)q(e)g(in)e(b)q(et)o(w)o(een)177 2785 y(t)o(w)o(o)f(diagnostics)g(in)f(the)
+i(listing)e(b)q(efore)i(the)f(t)o(w)o(o)g(groups)g(of)g(lines)g(are)g(joined)
+g(together)h(in)e(the)i(listing)e(with)177 2835 y(no)h(in)o(terv)o(ening)g
+(ellipsis.)1042 2940 y(46)p eop
+%%Page: 47 48
+47 47 bop 177 42 a Fe(4.11)70 b(Diagnostics)177 157 y Fk(Advisory)16
+b(information)o(:)j Fn(Some)13 b(of)i(F)m(unnelW)m(eb's)g(diagnostics)f(pro)o
+(vide)h(a)g(detailed)g(explanatory)g(para-)177 207 y(graph.)i(While)11
+b(this)h(information)c(migh)o(t)i(b)q(e)i(useful)g(the)g(\014rst)g(time,)f
+(it)g(has)h(the)g(capacit)o(y)f(to)h(clog)f(up)h(a)f(listing)177
+257 y(\014le)k(if)f(the)h(user)h(has)f(made)f(the)h(same)f(error)i(man)o(y)d
+(times.)20 b(T)m(o)14 b(solv)o(e)g(this)h(problem,)e(F)m(unnelW)m(eb)i(could)
+f(b)q(e)177 307 y(mo)q(di\014ed)f(so)h(that)g(suc)o(h)g(explanations)f(are)i
+(only)e(displa)o(y)o(ed)g(the)i(\014rst)f(time)f(the)h(error)h(o)q(ccurs.)177
+382 y Fk(Ab)q(ort)g(after)f(n)h(errors:)i Fn(A)d(facilit)o(y)e(could)h(b)q(e)
+h(added)g(to)f(prev)o(en)o(t)i(F)m(unnelW)m(eb's)e(scanning,)g(parsing,)g
+(and)177 431 y(analysing)g(phases)i(from)d(con)o(tin)o(uing)h(if)g(a)g
+(certain)i(n)o(um)o(b)q(er)e(of)g(errors)i(ha)o(v)o(e)f(already)g(b)q(een)h
+(issued.)177 594 y Fe(4.12)70 b(Sp)r(eed)177 709 y Fk(Measuremen)o(t)11
+b(of)i(sp)q(eed:)k Fn(Although)11 b(F)m(unnelW)m(eb)g(can)h(generate)h(a)e
+(breakdo)o(wn)h(of)f(where)i(it)e(is)g(sp)q(ending)177 759
+y(its)j(time,)e(it)i(do)q(es)g(not)g(giv)o(e)f(a)h(\014nal)f(rating)h(in)f
+(lines)h(p)q(er)h(min)o(ute.)h(This)e(should)g(b)q(e)g(added.)177
+834 y Fk(Find)19 b(the)h(hot)f(sp)q(ots:)26 b Fn(Although)17
+b(F)m(unnelW)m(eb)h(has)g(b)q(een)h(designed)g(to)e(allo)o(w)g(high)g(sp)q
+(eed,)j(not)e(m)o(uc)o(h)177 884 y(e\013ort)d(has)f(so)g(far)f(b)q(een)i
+(made)e(to)h(mak)o(e)e(it)i(fast.)k(This)13 b(should)h(b)q(e)h(done.)177
+958 y Fk(Change)i(some)f(declarations:)i Fn(F)m(unnelW)m(eb)c(is)g(full)g(of)
+g(v)n(ariable)g(declarations)h(where)h(the)f(v)n(ariables)f(are)177
+1008 y(wider)g(than)g(they)h(need)f(b)q(e.)19 b(Replacing)13
+b(these)i(migh)o(t)d(sp)q(eed)k(it)d(up.)177 1170 y Fe(4.13)70
+b(Correctness)177 1286 y Fk(Bounds)17 b(analysis:)23 b Fn(Not)16
+b(m)o(uc)o(h)f(e\013ort)j(has)e(gone)h(in)o(to)f(the)h(design)g(of)f(F)m
+(unnelW)m(eb's)f(input)i(b)q(oundaries.)177 1336 y(An)12 b(analysis)f(should)
+g(b)q(e)h(made)f(of)g(F)m(unnelW)m(eb's)g(b)q(eha)o(viour)g(when)h(the)h
+(follo)o(wing)c(quan)o(tities)i(are)h(stretc)o(hed:)239 1452
+y Fm(\017)21 b Fn(Input)14 b(line)g(length.)239 1535 y Fm(\017)21
+b Fn(Input)14 b(\014le)g(size.)239 1618 y Fm(\017)21 b Fn(Num)o(b)q(er)13
+b(of)h(macros.)239 1701 y Fm(\017)21 b Fn(Length)14 b(of)f(macro.)177
+1818 y(In)h(particular,)f(F)m(unnelW)m(eb's)g(b)q(eha)o(viour)h(at)g(32K)g
+(and)f(64K)h(b)q(oundaries)g(should)g(b)q(e)g(observ)o(ed.)177
+1892 y Fk(Stac)o(k)k(detection:)i Fn(Macin)o(tosh)c(THINK-C)g(pro)o(vides)g
+(just)h(6K)f(of)f(memory)e(for)j(the)h(stac)o(k.)24 b(It)16
+b(migh)o(t)e(b)q(e)177 1942 y(w)o(orth)g(adding)f(c)o(hec)o(ks)i(to)f(mak)o
+(e)e(sure)j(that)f(the)h(stac)o(k)f(is)g(not)g(b)q(eing)g(blo)o(wn.)177
+2104 y Fe(4.14)70 b(T)-6 b(est)22 b(Suite)177 2220 y Fn(The)14
+b(follo)o(wing)e(tests)j(should)f(b)q(e)g(added)g(to)g(the)h(test)g(suite:)
+177 2337 y Fi(Lister)177 2386 y(------)243 2436 y(LR01:)20
+b(Test)h(with)g(a)h(full)f(listing)f(with)h(no)g(diagnostics.)243
+2486 y(LR02:)f(Test)h(with)g(a)h(full)f(listing)f(with)h(diagnostics.)243
+2536 y(LR03:)f(Test)h(with)g(an)h(abbreviated)d(listing)h(with)h(no)h
+(diagnostics.)243 2586 y(LR04:)e(Test)h(with)g(an)h(abbreviated)d(listing)h
+(with)h(diagnostics.)243 2635 y(LR05:)f(Test)h(error)g(context)f(system)h
+(with)g(nearby)f(diagnostics.)177 2735 y(Boundary)g(Cases)177
+2785 y(--------------)177 2835 y(Static)h(analysis)f(might)h(preclude)f(the)h
+(need)g(for)g(most)g(of)g(these)g(tests.)1042 2940 y Fn(47)p
+eop
+%%Page: 48 49
+48 48 bop 243 42 a Fi(BC01:)20 b(Test)h(what)g(happens)g(when)g(memory)f
+(runs)h(out.)243 91 y(BC02:)f(Test)h(on)h(a)f(file)g(with)g(a)h(single)e
+(line)h(of)h(a)f(megabyte.)243 141 y(BC03:)f(Test)h(on)h(a)f(file)g(of)h(a)f
+(megabyte)f(of)i(EOLs.)243 191 y(BC04:)e(Generate)g(an)i(output)e(file)h
+(with)g(an)h(extremely)e(long)h(line.)243 241 y(BC05:)f(Generate)g(an)i
+(output)e(file)h(with)g(one)g(million)g(lines.)243 291 y(BC06:)f(Test)h(on)h
+(a)f(file)g(with)g(very)g(many)g(macros.)177 390 y(General)177
+440 y(-------)243 490 y(GN01:)f(A)i(large)f(legal)f(input)h(file)g
+(exercising)f(as)h(many)g(features)f(as)i(possible.)373 540
+y(1.)g(Test)f(listing)f(file.)373 589 y(2.)i(Test)f(output)f(files.)373
+639 y(3.)i(Test)f(typeset)f(file.)243 689 y(GN...)g(A)i(selection)e(of)h(ten)
+g(real-life)f(FunnelWeb)g(files.)177 851 y Fe(4.15)70 b(Mac)n(hine-Sp)r
+(eci\014c)20 b(Changes)177 967 y Fk(Icon)14 b(for)g(the)f(Macin)o(tosh:)j
+Fn(Curren)o(tly)d(no)g(icon)f(is)g(supplied)h(for)f(the)i(Macin)o(tosh)e(v)o
+(ersion)h(of)f(F)m(unnelW)m(eb.)177 1017 y(An)i(icon)g(depicting)g(a)f
+(spider)i(or)f(a)f(funnelled)h(w)o(eb)g(of)g(some)f(kind)g(w)o(ould)g(seem)h
+(appropriate.)177 1179 y Fe(4.16)70 b(Summary)177 1295 y Fn(This)15
+b(c)o(hapter)i(has)e(describ)q(es)i(some)e(of)f(the)i(problems)f(with)g(F)m
+(unnelW)m(eb)f(and)i(some)e(of)h(the)g(opp)q(ortunities)177
+1345 y(that)e(exist)h(for)f(impro)o(ving)e(it.)17 b(The)d(direction)f(and)g
+(sp)q(eed)i(in)e(whic)o(h)g(F)m(unnelW)m(eb)g(will)e(dev)o(elop)j(will)e(dep)
+q(end)177 1395 y(largely)j(on)h(user)h(feedbac)o(k.)25 b(If)15
+b(y)o(ou)h(ha)o(v)o(e)f(an)o(y)h(strong)g(feelings)g(on)g(where)h(F)m(unnelW)
+m(eb)e(should)h(go,)f(please)177 1444 y(email)d(them)h(to)h(Ross)g(William)o
+(s)d(\()p Fi(ross@spam.adelaide)o(.edu.)o(au)p Fn(\).)1042
+2940 y(48)p eop
+%%Page: 49 50
+49 49 bop 177 380 a Ff(App)s(endix)34 b(A)177 615 y Fl(GNU)40
+b(General)i(Public)f(License)177 739 y(V)-10 b(ersion)41 b(2)177
+983 y Fn(This)16 b(app)q(endix)h(con)o(tains)f(a)g(v)o(erbatim)e(cop)o(y)j
+(of)e(V)m(ersion)i(2)f(of)f(the)i(GNU)f(General)g(Public)g(License)i(under)
+177 1032 y(whic)o(h)g(the)g(F)m(unnelW)m(eb)g(computer)f(program)f(is)i
+(released.)31 b(Note)18 b(that)g(the)h Fh(F)m(unnelWeb)g(User's)f(Manual)177
+1082 y Fn(and)e Fh(F)m(unnelWeb)j(Hacker's)e(Manual)g Fn(are)g(released)g
+(under)h(a)e(m)o(uc)o(h)f(simpler)g(license)i(that)g(do)q(es)g(not)f(allo)o
+(w)177 1132 y(mo)q(di\014cations.)p 177 1188 1772 2 v 264 1340
+a Fi(GNU)22 b(GENERAL)e(PUBLIC)g(LICENSE)330 1390 y(Version)g(2,)h(June)g
+(1991)199 1490 y(Copyright)f(\(C\))h(1989,)g(1991)g(Free)g(Software)f
+(Foundation,)f(Inc.)744 1540 y(675)i(Mass)g(Ave,)g(Cambridge,)f(MA)h(02139,)g
+(USA)199 1589 y(Everyone)f(is)h(permitted)f(to)i(copy)f(and)g(distribute)f
+(verbatim)g(copies)199 1639 y(of)h(this)g(license)g(document,)f(but)h
+(changing)f(it)h(is)h(not)f(allowed.)264 1739 y(Preamble)221
+1838 y(The)g(licenses)f(for)h(most)g(software)f(are)i(designed)e(to)h(take)g
+(away)g(your)177 1888 y(freedom)g(to)g(share)g(and)g(change)f(it.)43
+b(By)22 b(contrast,)e(the)h(GNU)g(General)f(Public)177 1938
+y(License)h(is)g(intended)f(to)h(guarantee)f(your)h(freedom)g(to)g(share)g
+(and)g(change)g(free)177 1988 y(software--to)e(make)i(sure)g(the)h(software)e
+(is)h(free)g(for)g(all)g(its)h(users.)42 b(This)177 2038 y(General)21
+b(Public)f(License)g(applies)h(to)g(most)g(of)g(the)h(Free)f(Software)177
+2087 y(Foundation's)e(software)i(and)g(to)g(any)g(other)g(program)f(whose)h
+(authors)g(commit)f(to)177 2137 y(using)h(it.)43 b(\(Some)21
+b(other)f(Free)h(Software)g(Foundation)e(software)h(is)i(covered)e(by)177
+2187 y(the)h(GNU)h(Library)e(General)g(Public)h(License)f(instead.\))42
+b(You)21 b(can)g(apply)g(it)g(to)177 2237 y(your)g(programs,)f(too.)221
+2337 y(When)h(we)g(speak)g(of)g(free)g(software,)f(we)i(are)f(referring)f(to)
+h(freedom,)f(not)177 2386 y(price.)43 b(Our)21 b(General)f(Public)h(Licenses)
+f(are)h(designed)f(to)h(make)g(sure)g(that)g(you)177 2436 y(have)g(the)g
+(freedom)g(to)g(distribute)f(copies)g(of)i(free)f(software)f(\(and)h(charge)f
+(for)177 2486 y(this)h(service)f(if)i(you)f(wish\),)g(that)g(you)g(receive)f
+(source)h(code)g(or)g(can)g(get)g(it)177 2536 y(if)h(you)f(want)g(it,)g(that)
+g(you)g(can)g(change)g(the)g(software)f(or)h(use)h(pieces)e(of)i(it)177
+2586 y(in)g(new)f(free)g(programs;)f(and)h(that)g(you)g(know)g(you)g(can)g
+(do)h(these)e(things.)221 2685 y(To)h(protect)f(your)h(rights,)g(we)g(need)g
+(to)h(make)e(restrictions)g(that)h(forbid)177 2735 y(anyone)g(to)g(deny)g
+(you)g(these)g(rights)g(or)g(to)g(ask)g(you)h(to)f(surrender)f(the)h(rights.)
+177 2785 y(These)g(restrictions)e(translate)h(to)i(certain)e
+(responsibilities)e(for)k(you)f(if)g(you)177 2835 y(distribute)f(copies)g(of)
+i(the)f(software,)f(or)h(if)h(you)f(modify)f(it.)1042 2940
+y Fn(49)p eop
+%%Page: 50 51
+50 50 bop 221 91 a Fi(For)21 b(example,)f(if)h(you)h(distribute)d(copies)i
+(of)g(such)g(a)h(program,)e(whether)177 141 y(gratis)h(or)g(for)g(a)h(fee,)f
+(you)g(must)g(give)g(the)g(recipients)f(all)h(the)g(rights)g(that)177
+191 y(you)g(have.)43 b(You)21 b(must)g(make)g(sure)g(that)g(they,)g(too,)g
+(receive)f(or)h(can)h(get)f(the)177 241 y(source)g(code.)42
+b(And)21 b(you)h(must)f(show)g(them)g(these)f(terms)h(so)g(they)g(know)g
+(their)177 291 y(rights.)221 390 y(We)g(protect)f(your)h(rights)g(with)g(two)
+g(steps:)g(\(1\))g(copyright)f(the)h(software,)f(and)177 440
+y(\(2\))h(offer)g(you)g(this)g(license)g(which)f(gives)h(you)g(legal)g
+(permission)f(to)h(copy,)177 490 y(distribute)f(and/or)g(modify)h(the)g
+(software.)221 589 y(Also,)g(for)g(each)g(author's)f(protection)g(and)h
+(ours,)f(we)i(want)f(to)g(make)g(certain)177 639 y(that)g(everyone)f
+(understands)g(that)h(there)g(is)g(no)g(warranty)f(for)i(this)f(free)177
+689 y(software.)42 b(If)21 b(the)g(software)g(is)g(modified)f(by)h(someone)g
+(else)g(and)g(passed)g(on,)g(we)177 739 y(want)g(its)g(recipients)f(to)h
+(know)g(that)g(what)g(they)g(have)g(is)h(not)f(the)g(original,)f(so)177
+789 y(that)h(any)g(problems)f(introduced)g(by)i(others)e(will)h(not)g
+(reflect)g(on)g(the)g(original)177 839 y(authors')f(reputations.)221
+938 y(Finally,)g(any)h(free)g(program)f(is)i(threatened)d(constantly)h(by)i
+(software)177 988 y(patents.)42 b(We)21 b(wish)g(to)h(avoid)f(the)g(danger)f
+(that)h(redistributors)e(of)j(a)f(free)177 1038 y(program)g(will)f
+(individually)g(obtain)g(patent)h(licenses,)f(in)h(effect)g(making)f(the)177
+1088 y(program)h(proprietary.)41 b(To)21 b(prevent)f(this,)h(we)g(have)g
+(made)g(it)h(clear)f(that)g(any)177 1137 y(patent)g(must)g(be)g(licensed)f
+(for)h(everyone's)f(free)h(use)g(or)h(not)f(licensed)f(at)h(all.)221
+1237 y(The)g(precise)f(terms)h(and)g(conditions)f(for)h(copying,)f
+(distribution)g(and)177 1287 y(modification)f(follow.)264 1386
+y(GNU)j(GENERAL)e(PUBLIC)g(LICENSE)243 1436 y(TERMS)g(AND)h(CONDITIONS)f(FOR)
+h(COPYING,)g(DISTRIBUTION)e(AND)i(MODIFICATION)221 1536 y(0.)g(This)g
+(License)f(applies)h(to)g(any)g(program)g(or)g(other)g(work)g(which)g
+(contains)177 1586 y(a)h(notice)e(placed)h(by)g(the)g(copyright)f(holder)h
+(saying)f(it)i(may)f(be)g(distributed)177 1636 y(under)g(the)g(terms)g(of)g
+(this)g(General)g(Public)f(License.)42 b(The)21 b("Program",)f(below,)177
+1685 y(refers)h(to)g(any)g(such)g(program)g(or)g(work,)g(and)g(a)g("work)g
+(based)g(on)g(the)h(Program")177 1735 y(means)f(either)f(the)i(Program)e(or)h
+(any)h(derivative)d(work)i(under)g(copyright)f(law:)177 1785
+y(that)h(is)h(to)f(say,)g(a)g(work)g(containing)f(the)h(Program)g(or)g(a)h
+(portion)e(of)h(it,)177 1835 y(either)g(verbatim)f(or)h(with)g(modifications)
+e(and/or)i(translated)f(into)h(another)177 1885 y(language.)42
+b(\(Hereinafter,)19 b(translation)h(is)h(included)f(without)g(limitation)g
+(in)177 1934 y(the)h(term)g("modification".\))41 b(Each)21
+b(licensee)f(is)h(addressed)f(as)h("you".)177 2034 y(Activities)f(other)h
+(than)g(copying,)f(distribution)f(and)i(modification)f(are)h(not)177
+2084 y(covered)g(by)g(this)g(License;)f(they)h(are)g(outside)f(its)i(scope.)
+42 b(The)21 b(act)g(of)177 2134 y(running)g(the)g(Program)f(is)h(not)h
+(restricted,)d(and)i(the)g(output)g(from)g(the)g(Program)177
+2183 y(is)h(covered)e(only)h(if)g(its)g(contents)g(constitute)e(a)j(work)f
+(based)g(on)g(the)177 2233 y(Program)g(\(independent)e(of)i(having)g(been)g
+(made)g(by)g(running)f(the)i(Program\).)177 2283 y(Whether)f(that)f(is)i
+(true)f(depends)f(on)i(what)f(the)g(Program)f(does.)221 2383
+y(1.)h(You)g(may)g(copy)g(and)h(distribute)d(verbatim)h(copies)h(of)g(the)h
+(Program's)177 2433 y(source)f(code)g(as)g(you)g(receive)g(it,)g(in)g(any)g
+(medium,)g(provided)f(that)h(you)177 2482 y(conspicuously)e(and)i
+(appropriately)f(publish)g(on)h(each)g(copy)g(an)h(appropriate)177
+2532 y(copyright)e(notice)h(and)g(disclaimer)f(of)h(warranty;)f(keep)h
+(intact)f(all)i(the)177 2582 y(notices)f(that)f(refer)h(to)h(this)f(License)f
+(and)h(to)g(the)h(absence)e(of)h(any)h(warranty;)177 2632 y(and)f(give)g(any)
+g(other)g(recipients)f(of)h(the)h(Program)e(a)h(copy)g(of)h(this)f(License)
+177 2682 y(along)g(with)g(the)g(Program.)177 2781 y(You)g(may)h(charge)e(a)i
+(fee)f(for)g(the)g(physical)f(act)h(of)h(transferring)d(a)j(copy,)f(and)177
+2831 y(you)g(may)h(at)f(your)g(option)f(offer)h(warranty)f(protection)g(in)h
+(exchange)g(for)g(a)g(fee.)1042 2940 y Fn(50)p eop
+%%Page: 51 52
+51 51 bop 221 91 a Fi(2.)21 b(You)g(may)g(modify)g(your)g(copy)g(or)g(copies)
+g(of)g(the)g(Program)g(or)g(any)g(portion)177 141 y(of)h(it,)f(thus)g
+(forming)f(a)i(work)f(based)f(on)i(the)f(Program,)f(and)h(copy)g(and)177
+191 y(distribute)f(such)h(modifications)e(or)i(work)g(under)g(the)g(terms)g
+(of)g(Section)g(1)177 241 y(above,)g(provided)f(that)h(you)g(also)g(meet)g
+(all)g(of)g(these)g(conditions:)264 340 y(a\))h(You)f(must)g(cause)g(the)g
+(modified)f(files)h(to)g(carry)g(prominent)f(notices)264 390
+y(stating)h(that)g(you)g(changed)f(the)h(files)g(and)g(the)g(date)g(of)h(any)
+f(change.)264 490 y(b\))h(You)f(must)g(cause)g(any)g(work)g(that)g(you)g
+(distribute)f(or)h(publish,)f(that)h(in)264 540 y(whole)g(or)g(in)h(part)f
+(contains)f(or)h(is)h(derived)e(from)h(the)g(Program)g(or)g(any)264
+589 y(part)g(thereof,)f(to)i(be)f(licensed)f(as)i(a)f(whole)g(at)g(no)h
+(charge)e(to)i(all)f(third)264 639 y(parties)g(under)f(the)i(terms)e(of)i
+(this)f(License.)264 739 y(c\))h(If)f(the)g(modified)f(program)h(normally)f
+(reads)h(commands)f(interactively)264 789 y(when)h(run,)g(you)g(must)g(cause)
+g(it,)g(when)g(started)g(running)f(for)h(such)264 839 y(interactive)f(use)h
+(in)g(the)h(most)f(ordinary)f(way,)h(to)g(print)g(or)g(display)g(an)264
+888 y(announcement)f(including)g(an)h(appropriate)e(copyright)h(notice)h(and)
+g(a)264 938 y(notice)g(that)g(there)g(is)g(no)g(warranty)g(\(or)g(else,)f
+(saying)h(that)g(you)g(provide)264 988 y(a)h(warranty\))e(and)h(that)g(users)
+g(may)g(redistribute)e(the)i(program)g(under)264 1038 y(these)g(conditions,)f
+(and)h(telling)f(the)h(user)g(how)g(to)h(view)f(a)g(copy)g(of)h(this)264
+1088 y(License.)42 b(\(Exception:)20 b(if)h(the)g(Program)g(itself)f(is)i
+(interactive)d(but)264 1137 y(does)i(not)g(normally)g(print)f(such)h(an)h
+(announcement,)d(your)i(work)g(based)g(on)264 1187 y(the)h(Program)e(is)h
+(not)g(required)g(to)g(print)g(an)g(announcement.\))177 1287
+y(These)g(requirements)e(apply)i(to)g(the)h(modified)e(work)h(as)g(a)h
+(whole.)42 b(If)177 1337 y(identifiable)19 b(sections)i(of)g(that)g(work)g
+(are)g(not)g(derived)g(from)g(the)g(Program,)177 1386 y(and)g(can)h(be)f
+(reasonably)f(considered)f(independent)h(and)h(separate)f(works)h(in)177
+1436 y(themselves,)f(then)h(this)g(License,)f(and)h(its)g(terms,)g(do)g(not)g
+(apply)g(to)g(those)177 1486 y(sections)f(when)h(you)g(distribute)f(them)h
+(as)h(separate)e(works.)42 b(But)21 b(when)g(you)177 1536 y(distribute)f(the)
+h(same)g(sections)f(as)i(part)f(of)g(a)g(whole)g(which)g(is)g(a)h(work)f
+(based)177 1586 y(on)h(the)f(Program,)f(the)h(distribution)e(of)j(the)f
+(whole)g(must)g(be)g(on)g(the)h(terms)e(of)177 1636 y(this)h(License,)f
+(whose)h(permissions)f(for)h(other)f(licensees)g(extend)h(to)g(the)177
+1685 y(entire)g(whole,)f(and)h(thus)g(to)h(each)f(and)g(every)g(part)g
+(regardless)e(of)j(who)f(wrote)g(it.)177 1785 y(Thus,)g(it)g(is)h(not)f(the)g
+(intent)g(of)g(this)g(section)f(to)i(claim)e(rights)h(or)g(contest)177
+1835 y(your)g(rights)g(to)g(work)g(written)f(entirely)h(by)g(you;)g(rather,)f
+(the)h(intent)g(is)g(to)177 1885 y(exercise)f(the)h(right)g(to)h(control)e
+(the)h(distribution)e(of)j(derivative)e(or)177 1934 y(collective)g(works)h
+(based)f(on)i(the)f(Program.)177 2034 y(In)h(addition,)d(mere)i(aggregation)f
+(of)h(another)g(work)g(not)g(based)g(on)g(the)g(Program)177
+2084 y(with)g(the)g(Program)g(\(or)g(with)g(a)g(work)g(based)g(on)g(the)h
+(Program\))e(on)h(a)h(volume)e(of)177 2134 y(a)i(storage)e(or)h(distribution)
+f(medium)g(does)h(not)g(bring)g(the)g(other)g(work)g(under)177
+2183 y(the)g(scope)g(of)g(this)g(License.)221 2283 y(3.)g(You)g(may)g(copy)g
+(and)h(distribute)d(the)j(Program)e(\(or)h(a)h(work)f(based)f(on)i(it,)177
+2333 y(under)f(Section)f(2\))i(in)f(object)g(code)g(or)g(executable)f(form)h
+(under)f(the)i(terms)e(of)177 2383 y(Sections)g(1)i(and)f(2)h(above)e
+(provided)h(that)g(you)g(also)g(do)g(one)g(of)h(the)f(following:)264
+2482 y(a\))h(Accompany)e(it)h(with)g(the)g(complete)f(corresponding)f
+(machine-readable)264 2532 y(source)i(code,)g(which)f(must)h(be)h
+(distributed)d(under)i(the)g(terms)g(of)g(Sections)264 2582
+y(1)h(and)f(2)h(above)e(on)i(a)f(medium)g(customarily)e(used)i(for)h
+(software)e(interchange;)f(or,)264 2682 y(b\))j(Accompany)e(it)h(with)g(a)h
+(written)e(offer,)g(valid)h(for)g(at)h(least)f(three)264 2731
+y(years,)g(to)g(give)g(any)g(third)g(party,)g(for)g(a)g(charge)g(no)g(more)g
+(than)g(your)264 2781 y(cost)g(of)h(physically)d(performing)h(source)h
+(distribution,)e(a)i(complete)264 2831 y(machine-readable)e(copy)i(of)g(the)g
+(corresponding)e(source)i(code,)g(to)g(be)1042 2940 y Fn(51)p
+eop
+%%Page: 52 53
+52 52 bop 264 42 a Fi(distributed)20 b(under)h(the)g(terms)g(of)g(Sections)f
+(1)i(and)f(2)g(above)g(on)h(a)f(medium)264 91 y(customarily)f(used)h(for)g
+(software)f(interchange;)f(or,)264 191 y(c\))j(Accompany)e(it)h(with)g(the)g
+(information)f(you)h(received)f(as)h(to)h(the)f(offer)264 241
+y(to)h(distribute)d(corresponding)h(source)g(code.)43 b(\(This)20
+b(alternative)g(is)264 291 y(allowed)h(only)g(for)g(noncommercial)e
+(distribution)g(and)i(only)g(if)h(you)264 340 y(received)e(the)i(program)e
+(in)h(object)g(code)g(or)g(executable)f(form)h(with)g(such)264
+390 y(an)h(offer,)e(in)i(accord)e(with)h(Subsection)f(b)h(above.\))177
+490 y(The)g(source)g(code)g(for)g(a)h(work)f(means)f(the)i(preferred)d(form)i
+(of)h(the)f(work)g(for)177 540 y(making)g(modifications)e(to)i(it.)43
+b(For)21 b(an)h(executable)d(work,)i(complete)f(source)177
+589 y(code)h(means)g(all)g(the)g(source)g(code)g(for)g(all)g(modules)f(it)i
+(contains,)e(plus)h(any)177 639 y(associated)f(interface)g(definition)g
+(files,)g(plus)h(the)g(scripts)g(used)g(to)177 689 y(control)g(compilation)e
+(and)i(installation)f(of)h(the)g(executable.)41 b(However,)21
+b(as)g(a)177 739 y(special)g(exception,)e(the)i(source)g(code)g(distributed)e
+(need)i(not)h(include)177 789 y(anything)e(that)h(is)h(normally)e
+(distributed)f(\(in)i(either)g(source)g(or)g(binary)177 839
+y(form\))g(with)g(the)g(major)g(components)f(\(compiler,)f(kernel,)i(and)g
+(so)g(on\))g(of)h(the)177 888 y(operating)e(system)h(on)g(which)g(the)g
+(executable)f(runs,)g(unless)h(that)g(component)177 938 y(itself)g
+(accompanies)e(the)i(executable.)177 1038 y(If)h(distribution)d(of)i
+(executable)f(or)h(object)g(code)g(is)g(made)g(by)h(offering)177
+1088 y(access)f(to)g(copy)g(from)g(a)h(designated)d(place,)i(then)g(offering)
+f(equivalent)177 1137 y(access)h(to)g(copy)g(the)g(source)g(code)g(from)g
+(the)g(same)g(place)g(counts)f(as)177 1187 y(distribution)f(of)j(the)f
+(source)g(code,)f(even)h(though)g(third)g(parties)f(are)h(not)177
+1237 y(compelled)f(to)h(copy)g(the)h(source)e(along)h(with)g(the)g(object)g
+(code.)221 1337 y(4.)g(You)g(may)g(not)h(copy,)e(modify,)h(sublicense,)e(or)j
+(distribute)d(the)j(Program)177 1386 y(except)f(as)g(expressly)f(provided)g
+(under)h(this)g(License.)42 b(Any)21 b(attempt)177 1436 y(otherwise)f(to)h
+(copy,)g(modify,)g(sublicense)e(or)j(distribute)d(the)j(Program)e(is)177
+1486 y(void,)h(and)g(will)g(automatically)e(terminate)h(your)h(rights)g
+(under)f(this)h(License.)177 1536 y(However,)f(parties)h(who)g(have)g
+(received)f(copies,)g(or)i(rights,)e(from)h(you)g(under)177
+1586 y(this)g(License)f(will)h(not)h(have)f(their)f(licenses)g(terminated)g
+(so)i(long)f(as)g(such)177 1636 y(parties)g(remain)f(in)h(full)g(compliance.)
+221 1735 y(5.)g(You)g(are)g(not)h(required)e(to)h(accept)g(this)g(License,)f
+(since)h(you)g(have)g(not)177 1785 y(signed)g(it.)43 b(However,)20
+b(nothing)g(else)h(grants)g(you)g(permission)f(to)h(modify)g(or)177
+1835 y(distribute)f(the)h(Program)f(or)i(its)f(derivative)f(works.)42
+b(These)21 b(actions)f(are)177 1885 y(prohibited)g(by)h(law)g(if)h(you)f(do)g
+(not)h(accept)e(this)h(License.)42 b(Therefore,)20 b(by)177
+1934 y(modifying)g(or)h(distributing)f(the)h(Program)f(\(or)h(any)h(work)f
+(based)f(on)i(the)177 1984 y(Program\),)e(you)h(indicate)f(your)h(acceptance)
+f(of)h(this)g(License)g(to)g(do)h(so,)f(and)177 2034 y(all)g(its)h(terms)e
+(and)h(conditions)f(for)h(copying,)f(distributing)g(or)h(modifying)177
+2084 y(the)g(Program)g(or)g(works)g(based)g(on)g(it.)221 2183
+y(6.)g(Each)g(time)g(you)g(redistribute)f(the)h(Program)f(\(or)h(any)g(work)g
+(based)g(on)h(the)177 2233 y(Program\),)e(the)h(recipient)f(automatically)f
+(receives)h(a)i(license)e(from)h(the)177 2283 y(original)f(licensor)g(to)i
+(copy,)f(distribute)e(or)j(modify)e(the)h(Program)g(subject)f(to)177
+2333 y(these)h(terms)g(and)g(conditions.)41 b(You)21 b(may)h(not)f(impose)f
+(any)h(further)177 2383 y(restrictions)e(on)j(the)f(recipients')f(exercise)g
+(of)h(the)g(rights)g(granted)f(herein.)177 2433 y(You)h(are)h(not)f
+(responsible)e(for)i(enforcing)f(compliance)g(by)h(third)g(parties)g(to)177
+2482 y(this)g(License.)221 2582 y(7.)g(If,)g(as)h(a)f(consequence)f(of)h(a)h
+(court)f(judgment)f(or)h(allegation)f(of)h(patent)177 2632
+y(infringement)e(or)j(for)f(any)g(other)g(reason)g(\(not)f(limited)h(to)g
+(patent)g(issues\),)177 2682 y(conditions)f(are)h(imposed)f(on)i(you)f
+(\(whether)f(by)h(court)g(order,)g(agreement)f(or)177 2731
+y(otherwise\))g(that)h(contradict)f(the)h(conditions)e(of)j(this)f(License,)f
+(they)h(do)g(not)177 2781 y(excuse)g(you)g(from)g(the)g(conditions)f(of)h
+(this)g(License.)42 b(If)21 b(you)h(cannot)177 2831 y(distribute)e(so)h(as)h
+(to)f(satisfy)f(simultaneously)f(your)i(obligations)f(under)h(this)1042
+2940 y Fn(52)p eop
+%%Page: 53 54
+53 53 bop 177 42 a Fi(License)21 b(and)g(any)g(other)g(pertinent)f
+(obligations,)f(then)i(as)g(a)h(consequence)d(you)177 91 y(may)i(not)h
+(distribute)d(the)i(Program)g(at)g(all.)43 b(For)21 b(example,)f(if)i(a)f
+(patent)177 141 y(license)g(would)f(not)h(permit)g(royalty-free)e
+(redistribution)g(of)j(the)f(Program)f(by)177 191 y(all)h(those)g(who)g
+(receive)g(copies)f(directly)g(or)i(indirectly)d(through)i(you,)g(then)177
+241 y(the)g(only)g(way)g(you)h(could)e(satisfy)h(both)g(it)g(and)g(this)g
+(License)g(would)f(be)i(to)177 291 y(refrain)f(entirely)f(from)h
+(distribution)e(of)i(the)g(Program.)177 390 y(If)h(any)f(portion)f(of)h(this)
+g(section)g(is)g(held)g(invalid)f(or)i(unenforceable)d(under)177
+440 y(any)i(particular)f(circumstance,)f(the)i(balance)g(of)g(the)g(section)g
+(is)g(intended)f(to)177 490 y(apply)h(and)g(the)g(section)g(as)g(a)h(whole)e
+(is)i(intended)e(to)h(apply)g(in)g(other)177 540 y(circumstances.)177
+639 y(It)h(is)f(not)g(the)g(purpose)g(of)g(this)g(section)f(to)i(induce)e
+(you)h(to)h(infringe)e(any)177 689 y(patents)h(or)g(other)g(property)f(right)
+h(claims)f(or)h(to)h(contest)e(validity)g(of)i(any)177 739
+y(such)f(claims;)f(this)h(section)g(has)g(the)g(sole)g(purpose)f(of)i
+(protecting)e(the)177 789 y(integrity)g(of)h(the)h(free)f(software)f
+(distribution)f(system,)h(which)h(is)177 839 y(implemented)f(by)h(public)g
+(license)f(practices.)41 b(Many)21 b(people)g(have)g(made)177
+888 y(generous)f(contributions)f(to)j(the)f(wide)g(range)g(of)g(software)f
+(distributed)177 938 y(through)h(that)f(system)h(in)g(reliance)g(on)g
+(consistent)f(application)f(of)j(that)177 988 y(system;)f(it)g(is)g(up)h(to)f
+(the)g(author/donor)f(to)h(decide)f(if)i(he)f(or)h(she)f(is)g(willing)177
+1038 y(to)h(distribute)d(software)h(through)h(any)g(other)g(system)f(and)h(a)
+h(licensee)e(cannot)177 1088 y(impose)h(that)g(choice.)177
+1187 y(This)g(section)f(is)i(intended)e(to)h(make)g(thoroughly)f(clear)h
+(what)g(is)g(believed)f(to)177 1237 y(be)i(a)f(consequence)f(of)h(the)g(rest)
+g(of)h(this)f(License.)221 1337 y(8.)g(If)h(the)f(distribution)e(and/or)i
+(use)g(of)g(the)g(Program)g(is)g(restricted)f(in)177 1386 y(certain)h
+(countries)e(either)i(by)g(patents)g(or)g(by)g(copyrighted)f(interfaces,)g
+(the)177 1436 y(original)g(copyright)g(holder)h(who)g(places)g(the)g(Program)
+f(under)h(this)g(License)177 1486 y(may)g(add)h(an)f(explicit)f(geographical)
+f(distribution)h(limitation)f(excluding)177 1536 y(those)i(countries,)f(so)h
+(that)g(distribution)e(is)j(permitted)e(only)h(in)g(or)g(among)177
+1586 y(countries)f(not)h(thus)g(excluded.)42 b(In)21 b(such)g(case,)g(this)g
+(License)f(incorporates)177 1636 y(the)h(limitation)f(as)h(if)h(written)e(in)
+i(the)f(body)g(of)g(this)g(License.)221 1735 y(9.)g(The)g(Free)g(Software)f
+(Foundation)g(may)h(publish)g(revised)f(and/or)h(new)g(versions)177
+1785 y(of)h(the)f(General)f(Public)h(License)f(from)h(time)g(to)g(time.)43
+b(Such)21 b(new)g(versions)f(will)177 1835 y(be)i(similar)e(in)h(spirit)g(to)
+g(the)g(present)g(version,)f(but)h(may)g(differ)g(in)g(detail)g(to)177
+1885 y(address)g(new)g(problems)f(or)h(concerns.)177 1984 y(Each)g(version)f
+(is)i(given)f(a)g(distinguishing)e(version)h(number.)43 b(If)21
+b(the)g(Program)177 2034 y(specifies)f(a)i(version)e(number)h(of)g(this)g
+(License)f(which)h(applies)f(to)i(it)f(and)g("any)177 2084
+y(later)g(version",)f(you)h(have)g(the)g(option)g(of)g(following)f(the)h
+(terms)g(and)g(conditions)177 2134 y(either)g(of)g(that)g(version)f(or)i(of)f
+(any)g(later)g(version)f(published)g(by)i(the)f(Free)177 2183
+y(Software)f(Foundation.)42 b(If)21 b(the)g(Program)g(does)f(not)i(specify)e
+(a)i(version)e(number)g(of)177 2233 y(this)h(License,)f(you)h(may)h(choose)e
+(any)h(version)g(ever)g(published)f(by)h(the)g(Free)g(Software)177
+2283 y(Foundation.)221 2383 y(10.)g(If)g(you)g(wish)g(to)h(incorporate)d
+(parts)i(of)g(the)h(Program)e(into)h(other)g(free)177 2433
+y(programs)f(whose)h(distribution)e(conditions)h(are)h(different,)f(write)h
+(to)g(the)g(author)177 2482 y(to)h(ask)f(for)g(permission.)41
+b(For)21 b(software)g(which)f(is)i(copyrighted)d(by)j(the)f(Free)177
+2532 y(Software)f(Foundation,)g(write)h(to)g(the)g(Free)g(Software)f
+(Foundation;)g(we)h(sometimes)177 2582 y(make)g(exceptions)f(for)h(this.)43
+b(Our)21 b(decision)f(will)h(be)g(guided)g(by)g(the)g(two)h(goals)177
+2632 y(of)g(preserving)d(the)i(free)g(status)g(of)g(all)h(derivatives)d(of)i
+(our)h(free)f(software)f(and)177 2682 y(of)i(promoting)d(the)j(sharing)e(and)
+h(reuse)g(of)g(software)f(generally.)264 2781 y(NO)i(WARRANTY)1042
+2940 y Fn(53)p eop
+%%Page: 54 55
+54 54 bop 221 42 a Fi(11.)21 b(BECAUSE)f(THE)h(PROGRAM)g(IS)g(LICENSED)f
+(FREE)h(OF)h(CHARGE,)e(THERE)h(IS)g(NO)h(WARRANTY)177 91 y(FOR)f(THE)h
+(PROGRAM,)e(TO)h(THE)g(EXTENT)g(PERMITTED)f(BY)h(APPLICABLE)f(LAW.)43
+b(EXCEPT)20 b(WHEN)177 141 y(OTHERWISE)g(STATED)h(IN)g(WRITING)f(THE)i
+(COPYRIGHT)d(HOLDERS)i(AND/OR)f(OTHER)h(PARTIES)177 191 y(PROVIDE)g(THE)g
+(PROGRAM)f("AS)h(IS")g(WITHOUT)g(WARRANTY)f(OF)h(ANY)g(KIND,)g(EITHER)g
+(EXPRESSED)177 241 y(OR)h(IMPLIED,)e(INCLUDING,)f(BUT)j(NOT)f(LIMITED)f(TO,)h
+(THE)g(IMPLIED)g(WARRANTIES)f(OF)177 291 y(MERCHANTABILITY)f(AND)i(FITNESS)f
+(FOR)i(A)f(PARTICULAR)f(PURPOSE.)42 b(THE)21 b(ENTIRE)g(RISK)f(AS)177
+340 y(TO)i(THE)f(QUALITY)f(AND)h(PERFORMANCE)f(OF)h(THE)g(PROGRAM)g(IS)g
+(WITH)g(YOU.)43 b(SHOULD)20 b(THE)177 390 y(PROGRAM)h(PROVE)f(DEFECTIVE,)g
+(YOU)h(ASSUME)g(THE)g(COST)g(OF)g(ALL)g(NECESSARY)f(SERVICING,)177
+440 y(REPAIR)h(OR)g(CORRECTION.)221 540 y(12.)g(IN)g(NO)h(EVENT)e(UNLESS)h
+(REQUIRED)f(BY)i(APPLICABLE)d(LAW)i(OR)h(AGREED)e(TO)i(IN)f(WRITING)177
+589 y(WILL)g(ANY)g(COPYRIGHT)f(HOLDER,)h(OR)g(ANY)g(OTHER)g(PARTY)g(WHO)g
+(MAY)g(MODIFY)g(AND/OR)177 639 y(REDISTRIBUTE)e(THE)j(PROGRAM)e(AS)h
+(PERMITTED)f(ABOVE,)h(BE)g(LIABLE)g(TO)g(YOU)g(FOR)h(DAMAGES,)177
+689 y(INCLUDING)e(ANY)h(GENERAL,)f(SPECIAL,)h(INCIDENTAL)e(OR)j
+(CONSEQUENTIAL)d(DAMAGES)h(ARISING)177 739 y(OUT)h(OF)h(THE)f(USE)g(OR)g
+(INABILITY)f(TO)i(USE)f(THE)g(PROGRAM)f(\(INCLUDING)g(BUT)h(NOT)h(LIMITED)177
+789 y(TO)g(LOSS)f(OF)g(DATA)g(OR)g(DATA)g(BEING)g(RENDERED)f(INACCURATE)g(OR)
+h(LOSSES)g(SUSTAINED)f(BY)177 839 y(YOU)h(OR)h(THIRD)e(PARTIES)h(OR)g(A)h
+(FAILURE)e(OF)i(THE)f(PROGRAM)f(TO)h(OPERATE)g(WITH)g(ANY)g(OTHER)177
+888 y(PROGRAMS\),)f(EVEN)h(IF)g(SUCH)g(HOLDER)g(OR)g(OTHER)g(PARTY)g(HAS)g
+(BEEN)g(ADVISED)f(OF)i(THE)177 938 y(POSSIBILITY)e(OF)h(SUCH)g(DAMAGES.)286
+1038 y(END)g(OF)h(TERMS)e(AND)i(CONDITIONS)177 1137 y(Appendix:)e(How)h(to)h
+(Apply)e(These)h(Terms)g(to)g(Your)g(New)g(Programs)221 1237
+y(If)g(you)g(develop)g(a)g(new)g(program,)g(and)g(you)g(want)g(it)g(to)h(be)f
+(of)g(the)h(greatest)177 1287 y(possible)e(use)h(to)h(the)f(public,)f(the)i
+(best)f(way)g(to)g(achieve)f(this)h(is)h(to)f(make)g(it)177
+1337 y(free)g(software)f(which)h(everyone)f(can)h(redistribute)f(and)h
+(change)f(under)h(these)g(terms.)221 1436 y(To)g(do)h(so,)f(attach)f(the)h
+(following)f(notices)h(to)g(the)g(program.)42 b(It)22 b(is)f(safest)177
+1486 y(to)h(attach)e(them)h(to)g(the)h(start)e(of)i(each)f(source)f(file)h
+(to)h(most)f(effectively)177 1536 y(convey)g(the)g(exclusion)f(of)h
+(warranty;)f(and)h(each)g(file)g(should)g(have)g(at)g(least)177
+1586 y(the)g("copyright")f(line)h(and)g(a)h(pointer)e(to)h(where)g(the)g
+(full)g(notice)g(is)g(found.)264 1685 y(<one)g(line)g(to)h(give)f(the)g
+(program's)f(name)h(and)g(a)g(brief)g(idea)g(of)h(what)f(it)g(does.>)264
+1735 y(Copyright)f(\(C\))h(19yy)43 b(<name)21 b(of)g(author>)264
+1835 y(This)g(program)g(is)g(free)g(software;)f(you)h(can)g(redistribute)f
+(it)h(and/or)g(modify)264 1885 y(it)h(under)e(the)i(terms)e(of)i(the)f(GNU)g
+(General)f(Public)h(License)f(as)i(published)e(by)264 1934
+y(the)i(Free)e(Software)h(Foundation;)e(either)i(version)f(2)i(of)f(the)g
+(License,)f(or)264 1984 y(\(at)i(your)e(option\))h(any)g(later)g(version.)264
+2084 y(This)g(program)g(is)g(distributed)f(in)h(the)g(hope)g(that)g(it)g
+(will)g(be)h(useful,)264 2134 y(but)g(WITHOUT)e(ANY)h(WARRANTY;)f(without)g
+(even)h(the)g(implied)g(warranty)f(of)264 2183 y(MERCHANTABILITY)f(or)i
+(FITNESS)g(FOR)g(A)h(PARTICULAR)d(PURPOSE.)42 b(See)21 b(the)264
+2233 y(GNU)h(General)e(Public)g(License)h(for)g(more)g(details.)264
+2333 y(You)h(should)e(have)h(received)f(a)i(copy)f(of)g(the)g(GNU)g(General)g
+(Public)f(License)264 2383 y(along)h(with)g(this)g(program;)f(if)i(not,)f
+(write)f(to)i(the)f(Free)g(Software)264 2433 y(Foundation,)f(Inc.,)h(675)g
+(Mass)g(Ave,)g(Cambridge,)e(MA)j(02139,)e(USA.)177 2532 y(Also)h(add)g
+(information)f(on)h(how)g(to)h(contact)e(you)h(by)h(electronic)d(and)j(paper)
+e(mail.)177 2632 y(If)i(the)f(program)f(is)h(interactive,)f(make)h(it)g
+(output)g(a)g(short)g(notice)g(like)g(this)177 2682 y(when)g(it)h(starts)e
+(in)h(an)h(interactive)d(mode:)264 2781 y(Gnomovision)h(version)g(69,)h
+(Copyright)f(\(C\))h(19yy)g(name)g(of)h(author)264 2831 y(Gnomovision)e
+(comes)h(with)g(ABSOLUTELY)e(NO)j(WARRANTY;)e(for)h(details)1042
+2940 y Fn(54)p eop
+%%Page: 55 56
+55 55 bop 264 42 a Fi(type)21 b(`show)g(w'.)264 91 y(This)g(is)h(free)f
+(software,)f(and)h(you)g(are)g(welcome)f(to)i(redistribute)d(it)264
+141 y(under)i(certain)f(conditions;)g(type)h(`show)g(c')g(for)g(details.)177
+241 y(The)g(hypothetical)f(commands)g(`show)h(w')g(and)g(`show)g(c')g(should)
+g(show)g(the)g(appropriate)177 291 y(parts)g(of)g(the)g(General)g(Public)f
+(License.)42 b(Of)22 b(course,)e(the)h(commands)f(you)i(use)f(may)177
+340 y(be)h(called)e(something)g(other)h(than)g(`show)g(w')g(and)g(`show)g
+(c';)g(they)g(could)g(even)g(be)177 390 y(mouse-clicks)e(or)j(menu)f
+(items--whatever)e(suits)h(your)h(program.)177 490 y(You)g(should)g(also)g
+(get)g(your)g(employer)f(\(if)h(you)g(work)g(as)h(a)f(programmer\))f(or)h
+(your)177 540 y(school,)g(if)g(any,)g(to)g(sign)g(a)h("copyright)e
+(disclaimer")f(for)i(the)g(program,)g(if)177 589 y(necessary.)42
+b(Here)21 b(is)g(a)h(sample;)e(alter)h(the)g(names:)221 689
+y(Yoyodyne,)f(Inc.,)g(hereby)h(disclaims)f(all)h(copyright)f(interest)g(in)i
+(the)f(program)221 739 y(`Gnomovision')e(\(which)h(makes)h(passes)g(at)g
+(compilers\))f(written)g(by)i(James)e(Hacker.)221 839 y(<signature)f(of)j(Ty)
+f(Coon>,)g(1)g(April)g(1989)221 888 y(Ty)g(Coon,)g(President)f(of)h(Vice)177
+988 y(This)g(General)f(Public)h(License)f(does)h(not)h(permit)e
+(incorporating)f(your)i(program)f(into)177 1038 y(proprietary)g(programs.)41
+b(If)22 b(your)f(program)f(is)h(a)h(subroutine)e(library,)g(you)h(may)177
+1088 y(consider)f(it)i(more)f(useful)f(to)i(permit)e(linking)g(proprietary)g
+(applications)f(with)i(the)177 1137 y(library.)42 b(If)21 b(this)g(is)h(what)
+f(you)g(want)g(to)g(do,)g(use)h(the)f(GNU)g(Library)f(General)177
+1187 y(Public)h(License)f(instead)g(of)i(this)f(License.)p
+177 1280 1772 2 v 1042 2940 a Fn(55)p eop
+%%Page: 56 57
+56 56 bop 1042 2940 a Fn(56)p eop
+%%Page: 57 58
+57 57 bop 177 378 a Ff(App)s(endix)34 b(B)177 610 y Fl(References)177
+851 y Fk([ANSI])21 b Fn(Australian)f(Standard)h(AS)f(3955-1991,)f
+(\\Programming)e(Languages)j(|)g(C",)g(\(ISBN:)g(0-7262-)177
+901 y(6970-0\),)c(12)h(July)g(1991.)27 b(Iden)o(tical)17 b(to:)24
+b(In)o(ternational)17 b(Standard)g(ISO/IEC)h(9899:)23 b(1990)16
+b(Programming)177 951 y(Languages)e(|)f(C.)177 1025 y Fk([Ben)o(tley86])h
+Fn(Ben)o(tley)i(J.,)g(\\Programmi)o(ng)d(P)o(earls:)22 b(Literate)16
+b(Programming",)c Fh(Communic)n(ations)17 b(of)g(the)177 1075
+y(A)o(CM)p Fn(,)c(V)m(ol.)g(29,)f(No.)i(5,)f(pp.)g(364{369,)f(1986.)177
+1150 y Fk([Hoare80])f Fn(Hoare)f(C.A.R.,)f(\\The)h(Emp)q(eror's)g(Old)g
+(Clothes",)g(T)m(uring)g(Aw)o(ard)g(Lecture,)i(1980,)e(from)e(\\A)o(CM)177
+1200 y(T)m(uring)15 b(Aw)o(ard)g(Lectures:)24 b(The)16 b(First)f(Tw)o(en)o(t)
+o(y)h(Y)m(ears)g(1966{1985",)d(A)o(CM)i(Press,)i(New)g(Y)m(ork,)e(\(ISBN:)g
+(0-)177 1249 y(201-07794-9\),)c(1987)i(\(see)i(p.)f(155\).)177
+1324 y Fk([Horton90])f Fn(Horton)h(M.R.,)e(\\P)o(ortable)i(C)g(Soft)o(w)o
+(are",)e(Pren)o(tice)k(Hall,)c(\(ISBN:)i(0-13-868050-7\),)d(1990.)177
+1399 y Fk([Kernighan88])k Fn(Kernighan)i(B.W.,)g(Ritc)o(hie)f(D.M.,)g(\\The)h
+(C)g(Programming)c(Language",)k(\(second)h(edi-)177 1449 y(tion,\\ANSI)13
+b(C"\),)g(Pren)o(tice)j(Hall,)c(\(ISBN:)i(0-13-110362-8\),)d(1988.)177
+1523 y Fk([Kn)o(uth83])j Fn(Kn)o(uth)h(D.E.,)f(\\The)h(WEB)g(System)f(of)h
+(Structured)h(Do)q(cumen)o(tation",)d(\(W)m(eb)i(User)h(Man)o(ual,)177
+1573 y(V)m(ersion)e(2.5,)f(No)o(v)o(em)o(b)q(er,)f(1983\),)h(Stanford)g(Univ)
+o(ersit)o(y)m(,)g(1983.)177 1648 y Fk([Kn)o(uth84])f Fn(Kn)o(uth)j(D.E.,)d
+(\\The)i(T)767 1657 y(E)790 1648 y(Xb)q(o)q(ok",)f(Addison-W)m(esley)m(,)g
+(\(ISBN:)h(0-201-13448-9\),)d(1984.)177 1723 y Fk([Lamp)q(ort86])k
+Fn(Lamp)q(ort)h(L.,)g(\\L)723 1718 y Fg(a)742 1723 y Fn(T)765
+1735 y(E)788 1723 y(X:)g(A)g(Do)q(cumen)o(t)g(Preparation)h(System",)f
+(Addison-W)m(esley)m(,)g(\(ISBN:)177 1773 y(0-201-15790-X\),)11
+b(1986.)177 1847 y Fk([Rabino)o(witz90])k Fn(Rabino)o(witz)h(H.,)h(Sc)o(haap)
+g(C.,)h(\\P)o(ortable)f(C",)f(Pren)o(tice)j(Hall,)d(\(ISBN:0-13-685967-4\))
+177 1897 y(1990.)177 1972 y Fk([Ramsey89])22 b Fn(Ramsey)f(N.,)j(\\W)m(ea)o
+(ving)d(a)h(Language-Indep)q(enden)o(t)h(WEB",)f Fh(Communic)n(ations)h(of)g
+(the)177 2022 y(A)o(CM)p Fn(,)13 b(V)m(ol.)g(32,)f(No.)i(9,)f(pp.)g
+(1051{1055,)e(1989.)177 2096 y Fk([T)l(arjan72])16 b Fn(T)m(arjan)f(R.E.,)h
+(\\Depth-First)g(Searc)o(h)i(and)e(Linear)g(Graph)g(Algorithms",)e
+Fh(SIAM)k(Journal)f(of)177 2146 y(Computing)p Fn(,)d(V)m(ol.)e(1,)h(No.)h(2,)
+f(pp.)g(146{160,)f(June)j(1972.)177 2221 y Fk([USDOD83])i Fn(\\The)i
+(Programming)c(Language)j(Ada)g(Reference)i(Man)o(ual",)e(American)g
+(National)f(Stan-)177 2271 y(dards)e(Institute)f(Inc,)g
+(ANSI/MIL-STD-1815A-1983,)d(1983.)1042 2940 y(57)p eop
+%%Page: 58 59
+58 58 bop 177 279 a Fl(Index)177 487 y Fn(.cld)14 b(\014le)f(18)177
+537 y(==)i(14)177 587 y(@M)f(23)177 637 y(@Z)h(23)177 687 y(abbreviations)f
+(iden)o(ti\014er)g(28)177 737 y(ac)o(kno)o(wledgemen)o(ts)f(7)177
+787 y(Ada)h(18)177 837 y(Ada)g(27)177 886 y(Ada)g(7)177 936
+y(adding)f(features)i(36)177 986 y(Adelaide)f(Univ)o(ersit)o(y)g(27)177
+1036 y(analyser)g(45)177 1086 y(Andrew)h(T)m(rev)o(orro)o(w)f(9)177
+1136 y(ANSI)g(28)177 1186 y(ANSI)g(57)177 1236 y(an)o(tiquated)g(features)h
+(43)177 1286 y(ASCI)q(I)f(mnemonics)e(45)177 1336 y(asking)h(for)h(trouble)g
+(28)177 1386 y(authorit)o(y)f(design)i(36)177 1436 y(authorit)o(y)e(securit)o
+(y)i(36)177 1486 y(a)o(v)n(ailabilit)o(y)10 b(program)j(37)177
+1536 y(bac)o(kw)o(ards)h(compatibilit)o(y)d(11)177 1586 y(Barry)k(Dwy)o(er)f
+(7)177 1636 y(Begg)g(Jerem)o(y)g(7)177 1686 y(Ben)o(tley)h(Jon)f(11)177
+1736 y(Ben)o(tley86)g(11)177 1786 y(Ben)o(tley86)g(57)177 1836
+y(blank)f(inden)o(tation)h(12)177 1886 y(blank)f(inden)o(tation)h(12)177
+1935 y(break)o(out,)g(GNU)f(41)177 1985 y(Brissenden)j(Roger)e(7)177
+2035 y(c)o(hanges)h(dangers)f(35)177 2085 y(co)q(ding)g(st)o(yle)g(28)177
+2135 y(command)d(in)o(terface)k(43)177 2185 y(command)c(in)o(terpreter)16
+b(43)177 2235 y(command)11 b(line)j(in)o(terface)g(design)g(goals)f(19)177
+2285 y(command)e(line)j(in)o(terface)g(18)177 2335 y(command)d(setall)j(43)
+177 2385 y(commen)o(t)e(duplication)h(18)177 2435 y(Comm)o(unicati)o(ons)e
+(of)j(the)g(A)o(CM)g(11)177 2485 y(compatibilit)o(y)d(bac)o(kw)o(ards)j(11)
+177 2535 y(compiler)f(ThinkC)g(30)177 2585 y(compiler)g(35)177
+2635 y(conditionals)g(44)177 2685 y(con)o(tiguous)h(memory)d(45)177
+2735 y(cop)o(yrigh)o(t)j(la)o(w)f(38)177 2785 y(cop)o(yrigh)o(t)h(notice)g(1)
+177 2835 y(cop)o(yrigh)o(t)g(38)1136 487 y(correctness)i(47)1136
+537 y(coun)o(ting)d(diagnostic)g(43)1136 587 y(cross)i(references)h(46)1136
+637 y(dangers)e(c)o(hanges)h(35)1136 687 y(dangers)f(inden)o(tation)f(13)1136
+737 y(dangers)h(languages)g(35)1136 787 y(Da)o(vid)e(Hulse)j(27)1136
+837 y(Da)o(vid)d(Hulse)j(7)1136 886 y(DCL)e(13)1136 936 y(deriv)o(ed)h(w)o
+(ork)g(38)1136 986 y(design)g(authorit)o(y)f(36)1136 1036 y(design)h(F)m
+(unnelW)m(eb)f(11)1136 1086 y(design)h(goals)f(command)e(line)i(in)o(terface)
+i(19)1136 1136 y(design)f(language)f(44)1136 1186 y(detection)i(recursion)g
+(45)1136 1236 y(diagnostic)e(coun)o(ting)g(43)1136 1286 y(diagnostic)g
+(messages)h(25)1136 1336 y(diagnostics)f(47)1136 1386 y(do)q(cumen)o(t)g
+(structure)j(macro)d(structure)j(23)1136 1436 y(do)q(cumen)o(t)d(structure)j
+(16)1136 1486 y(do)q(cumen)o(t)d(structure)j(23)1136 1536 y(do)q(cumen)o
+(tation)c(out)i(of)f(date)i(18)1136 1586 y(do)q(cumen)o(tation)d(43)1136
+1636 y(Donald)g(Kn)o(uth)j(11)1136 1686 y(Donald)d(Kn)o(uth)j(7)1136
+1736 y(duplication)d(commen)o(t)g(18)1136 1786 y(Dwy)o(er)i(Barry)g(7)1136
+1836 y(e\016ciency)g(47)1136 1886 y(EOL)g(represen)o(tation)h(45)1136
+1935 y(example)d(o\016cial)h(43)1136 1985 y(extensions)i(\014lename)d(20)1136
+2035 y(factor)i(glue)f(46)1136 2085 y(features)i(adding)e(36)1136
+2135 y(features)i(an)o(tiquated)e(43)1136 2185 y(features)i(mo)q
+(di\014cation)c(35)1136 2235 y(features)k(remo)o(ving)d(35)1136
+2285 y(\014le)i(.cld)f(18)1136 2335 y(\014le)h(extension)g(protection)h(37)
+1136 2385 y(\014le)f(mark)o(ers)f(44)1136 2435 y(\014le)h(names)f(19)1136
+2485 y(\014le)h(names)f(21)1136 2535 y(\014le)h(signature)g(44)1136
+2585 y(\014lename)e(extensions)j(20)1136 2635 y(\014lename)d(inheritance)j
+(20)1136 2685 y(\014lenames)e(length)h(29)1136 2735 y(\014lenames)f(p)q
+(ortable)h(21)1136 2785 y(formal)d(parameter)j(list)f(44)1136
+2835 y(F)m(unnelW)m(eb)g(design)h(11)1042 2940 y(58)p eop
+%%Page: 59 60
+59 59 bop 177 42 a Fn(F)m(unnelW)m(eb)14 b(future)g(43)177
+91 y(F)m(unnelW)m(eb)g(history)f(27)177 141 y(F)m(unnelW)m(eb)h(implem)o(en)o
+(tation)d(27)177 191 y(F)m(unnelW)m(eb)j(managem)o(en)o(t)e(39)177
+241 y(F)m(unnelW)m(eb)i(mo)q(di\014cation)d(35)177 291 y(F)m(unnelW)m(eb)j
+(motiv)n(atio)o(n)d(11)177 341 y(F)m(unnelW)m(eb)j(o\016cial)e(39)177
+391 y(F)m(unnelW)m(eb)i(past)g(use)g(27)177 441 y(F)m(unnelW)m(eb)g
+(protection)g(37)177 490 y(F)m(unnelW)m(eb)g(syn)o(tax)f(14)177
+540 y(F)m(unnelW)m(eb)h(V1)f(11)177 590 y(F)m(unnelW)m(eb)h(v)o(ersion)g(1)f
+(27)177 640 y(F)m(unnelW)m(eb)h(v)o(ersion)g(2)f(27)177 690
+y(F)m(unnelW)m(eb)h(v)o(ersion)g(3)f(27)177 740 y(F)m(unnelW)m(eb)h(writing)f
+(itself)g(28)177 790 y(future)i(F)m(unnelW)m(eb)e(43)177 840
+y(genealogy)g(program)g(36)177 889 y(generic)i(t)o(yp)q(esetter)h(46)177
+939 y(glue)e(factor)g(46)177 989 y(GNU)g(break)o(out)g(41)177
+1039 y(GNU)g(license)h(35)177 1089 y(GNU)f(license)h(39)177
+1139 y(GNU)f(License)h(49)177 1189 y(GNU)f(v)o(ersion)g(41)177
+1239 y(Hac)o(k)o(ett)h(Simon)d(7)177 1288 y(headings)i(16)177
+1338 y(heap)g(memory)e(29)177 1388 y(hierarc)o(hical)i(structure)i(23)177
+1438 y(history)e(F)m(unnelW)m(eb)f(27)177 1488 y(Hoare80)h(36)177
+1538 y(Hoare80)g(57)177 1588 y(Horton90)g(28)177 1638 y(Horton90)g(57)177
+1687 y(Hulse)h(Da)o(vid)d(27)177 1737 y(Hulse)j(Da)o(vid)d(7)177
+1787 y(iden)o(ti\014er)i(abbreviations)g(28)177 1837 y(iden)o(ti\014er)g(28)
+177 1887 y(implemen)o(tation)d(F)m(unnelW)m(eb)i(27)177 1937
+y(include)h(\014le)g(suppression)h(46)177 1987 y(inden)o(tation)e(blank)h(12)
+177 2037 y(inden)o(tation)f(dangers)i(13)177 2086 y(inden)o(tation)e(no)h(12)
+177 2136 y(inden)o(tation)f(text)i(12)177 2186 y(inden)o(tation)e(text)i(30)
+177 2236 y(inden)o(tation)e(text)i(45)177 2286 y(inden)o(tation)e(12)177
+2336 y(inden)o(tation)g(12)177 2386 y(inden)o(ted)i(macro)d(call)h(12)177
+2436 y(index)h(program)e(43)177 2486 y(inheritance)j(\014lename)d(20)177
+2535 y(in)o(terface)j(command)c(line)i(18)177 2585 y(in)o(terface)i(command)c
+(43)177 2635 y(in)o(terpreter)16 b(command)11 b(43)177 2685
+y(in)o(terpreter)16 b(shell)e(43)177 2735 y(in)o(v)o(o)q(cations)f(n)o(um)o
+(b)q(er)g(22)177 2785 y(issues)i(miscellaneous)e(18)177 2835
+y(Jerem)o(y)h(Begg)g(7)1136 42 y(Jon)g(Ben)o(tley)g(11)1136
+91 y(Kernighan88)f(28)1136 141 y(Kernighan88)g(57)1136 191
+y(Kn)o(uth)h(Donald)f(11)1136 241 y(Kn)o(uth)h(Donald)f(7)1136
+291 y(Kn)o(uth83)g(11)1136 341 y(Kn)o(uth83)g(57)1136 391 y(Kn)o(uth84)g(57)
+1136 441 y(Kn)o(uth84)g(9)1136 490 y(Lamp)q(ort86)f(57)1136
+540 y(Lamp)q(ort86)g(9)1136 590 y(language)h(design)h(44)1136
+640 y(languages)f(dangers)i(35)1136 690 y(LaT)m(eX)e(9)1136
+740 y(LaT)m(eX)g(9)1136 790 y(la)o(w)g(cop)o(yrigh)o(t)g(38)1136
+840 y(leak)n(age)g(memory)e(30)1136 889 y(length)i(\014lenames)h(29)1136
+939 y(license)g(GNU)g(35)1136 989 y(license)g(GNU)g(39)1136
+1039 y(License)h(GNU)e(49)1136 1089 y(license)h(38)1136 1139
+y(lister)g(46)1136 1189 y(Macin)o(tosh)g(29)1136 1239 y(Macin)o(tosh)g(30)
+1136 1288 y(Macin)o(tosh)g(9)1136 1338 y(macro)e(call)h(syn)o(tax)h(16)1136
+1388 y(macro)e(de\014nition)i(syn)o(tax)g(14)1136 1438 y(macro)e(structure)k
+(do)q(cumen)o(t)e(structure)i(23)1136 1488 y(macro)c(structure)k(23)1136
+1538 y(mak)o(e)c(44)1136 1588 y(mallo)q(c)f(29)1136 1638 y(managemen)o(t)g(F)
+m(unnelW)m(eb)i(39)1136 1687 y(man)o(uals)e(mo)q(difying)g(38)1136
+1737 y(mapp)q(er)i(44)1136 1787 y(mark)o(ers)g(\014le)h(44)1136
+1837 y(memory)d(con)o(tiguous)j(45)1136 1887 y(memory)d(heap)j(29)1136
+1937 y(memory)d(leak)n(age)i(30)1136 1987 y(memory)e(pac)o(k)n(age)j(29)1136
+2037 y(memory)d(stac)o(k)j(30)1136 2086 y(memory)d(static)j(30)1136
+2136 y(memory)d(use)k(of)e(29)1136 2186 y(messages)h(diagnostic)f(25)1136
+2236 y(miscellaneous)f(issues)j(18)1136 2286 y(mnemonics)c(ASCI)q(I)j(45)1136
+2336 y(mo)q(di\014cation)d(features)k(35)1136 2386 y(mo)q(di\014cation)c(F)m
+(unnelW)m(eb)j(35)1136 2436 y(mo)q(difying)d(man)o(uals)g(38)1136
+2486 y(motiv)n(atio)o(n)g(F)m(unnelW)m(eb)j(11)1136 2535 y(MSDOS)g(29)1136
+2585 y(names)f(\014le)h(19)1136 2635 y(names)f(\014le)h(21)1136
+2685 y(naming)d(p)q(oin)o(ters)k(29)1136 2735 y(naming)c(t)o(yp)q(es)k(29)
+1136 2785 y(no)e(inden)o(tation)h(12)1136 2835 y(no)f(inden)o(tation)h(12)
+1042 2940 y(59)p eop
+%%Page: 60 61
+60 60 bop 177 42 a Fn(notice)14 b(cop)o(yrigh)o(t)g(1)177 91
+y(n)o(um)o(b)q(er)f(in)o(v)o(o)q(cations)g(22)177 141 y(n)o(um)o(b)q(er)g
+(output)h(\014les)h(12)177 191 y(n)o(um)o(b)q(ering)e(section)h(23)177
+241 y(Occam's)f(razor)i(12)177 291 y(o\016cial)e(example)f(43)177
+341 y(o\016cial)h(F)m(unnelW)m(eb)g(39)177 391 y(options)h(43)177
+441 y(out)g(of)f(date)h(do)q(cumen)o(tation)f(18)177 490 y(output)h(\014les)g
+(n)o(um)o(b)q(er)g(12)177 540 y(OzT)m(eX)h(9)177 590 y(pac)o(k)n(age)f
+(memory)d(29)177 640 y(parameter)j(list)f(formal)f(44)177 690
+y(parameterized)i(macro)f(call)g(syn)o(tax)h(16)177 740 y(parameterized)g
+(macro)f(de\014nitions)h(syn)o(tax)g(15)177 790 y(parser)h(45)177
+840 y(P)o(ascal)f(12)177 889 y(past)g(use)h(F)m(unnelW)m(eb)e(27)177
+939 y(Ph.D.)g(27)177 989 y(p)q(oin)o(ters)i(naming)c(29)177
+1039 y(p)q(ortabilit)o(y)i(28)177 1089 y(p)q(ortable)h(\014lenames)f(21)177
+1139 y(pragma)f(syn)o(tax)i(44)177 1189 y(pragma)e(v)o(ersion)i(45)177
+1239 y(preface)h(5)177 1288 y(presen)o(tation)g(notes)g(9)177
+1338 y(program)d(a)o(v)n(ailabilit)o(y)f(37)177 1388 y(program)h(genealogy)i
+(36)177 1438 y(program)e(index)i(43)177 1488 y(programming)c(p)q(earls)15
+b(11)177 1538 y(protection)g(\014le)e(extension)i(37)177 1588
+y(protection)g(F)m(unnelW)m(eb)e(37)177 1638 y(Rabino)o(witz90)f(28)177
+1687 y(Rabino)o(witz90)g(28)177 1737 y(Rabino)o(witz90)g(57)177
+1787 y(Ramsey89)g(46)177 1837 y(Ramsey89)g(57)177 1887 y(recursion)j
+(detection)g(45)177 1937 y(recursion)g(test)g(43)177 1987 y(references)i
+(cross)e(46)177 2037 y(references)i(57)177 2086 y(regression)e(testing)g(18)
+177 2136 y(remo)o(ving)d(features)j(35)177 2186 y(represen)o(tation)h(EOL)e
+(45)177 2236 y(Rob)q(ert)g(Endre)h(T)m(arjan)e(45)177 2286
+y(Roger)h(Brissenden)i(7)177 2336 y(Ross)e(William)o(s)d(1)177
+2386 y(scanner)k(44)177 2436 y(section)g(n)o(um)o(b)q(ering)d(23)177
+2486 y(section)j(syn)o(tax)f(44)177 2535 y(sections)h(16)177
+2585 y(securit)o(y)g(authorit)o(y)e(36)177 2635 y(setall)h(command)d(43)177
+2685 y(shell)j(in)o(terpreter)i(43)177 2735 y(signature)e(\014le)g(44)177
+2785 y(Simon)e(Hac)o(k)o(ett)j(7)177 2835 y(size)g(stac)o(k)f(30)1136
+42 y(South)d(Australian)f(Go)o(v)o(ernmen)o(t)g(Departmen)o(t)g(of)1302
+91 y(Lands)k(28)1136 141 y(sp)q(eed)h(47)1136 191 y(spider)f(46)1136
+241 y(stac)o(k)g(memory)d(30)1136 291 y(stac)o(k)j(size)h(30)1136
+341 y(static)f(memory)d(30)1136 391 y(static)j(v)n(ariables)f(30)1136
+440 y(strength)i(t)o(yp)q(esetting)g(46)1136 490 y(structure)h(do)q(cumen)o
+(t)d(16)1136 540 y(structure)j(do)q(cumen)o(t)d(23)1136 590
+y(structure)j(hierarc)o(hical)d(23)1136 640 y(structure)j(macro)c(23)1136
+690 y(st)o(yle)i(co)q(ding)f(28)1136 740 y(suite)h(test)h(47)1136
+790 y(suppression)g(include)f(\014le)g(46)1136 840 y(syn)o(tax)f(F)m(unnelW)m
+(eb)h(14)1136 889 y(syn)o(tax)f(macro)g(call)g(16)1136 939
+y(syn)o(tax)g(macro)g(de\014nition)h(14)1136 989 y(syn)o(tax)f(parameterized)
+i(macro)d(call)h(16)1136 1039 y(syn)o(tax)g(parameterized)i(macro)d
+(de\014nitions)i(15)1136 1089 y(syn)o(tax)f(pragma)f(44)1136
+1139 y(syn)o(tax)h(section)i(44)1136 1189 y(table)e(of)h(con)o(ten)o(ts)h(45)
+1136 1239 y(tangle)e(45)1136 1288 y(T)m(arjan)g(Rob)q(ert)h(Endre)h(45)1136
+1338 y(T)m(arjan72)d(45)1136 1388 y(T)m(arjan72)g(57)1136 1438
+y(test)j(recursion)g(43)1136 1488 y(test)g(suite)f(47)1136
+1538 y(testing)g(regression)h(18)1136 1588 y(text)f(inden)o(tation)f(12)1136
+1638 y(text)h(inden)o(tation)f(12)1136 1687 y(text)h(inden)o(tation)f(30)1136
+1737 y(text)h(inden)o(tation)f(45)1136 1787 y(T)m(eX)h(23)1136
+1837 y(T)m(eX)g(9)1136 1887 y(ThinkC)f(compiler)f(30)1136 1937
+y(trademark)h(36)1136 1987 y(T)m(rev)o(orro)o(w)g(Andrew)i(9)1136
+2037 y(trouble)f(asking)f(for)g(28)1136 2086 y(t)o(yp)q(es)h(naming)e(29)1136
+2136 y(t)o(yp)q(esetter)k(generic)f(46)1136 2186 y(t)o(yp)q(esetting)f
+(strength)i(46)1136 2236 y(t)o(yp)q(esetting)e(9)1136 2286
+y(Univ)o(ersit)o(y)f(Adelaide)h(27)1136 2336 y(Unix)f(36)1136
+2386 y(USDOD83)g(27)1136 2436 y(USDOD83)g(57)1136 2485 y(use)h(of)g(memory)d
+(29)1136 2535 y(v)n(ariables)i(static)h(30)1136 2585 y(v)n(ax)f(vms)f(18)1136
+2635 y(v)o(ersion)i(GNU)f(41)1136 2685 y(v)o(ersion)h(pragma)e(45)1136
+2735 y(video)h(game)g(35)1136 2785 y(vms)f(v)n(ax)h(18)1136
+2835 y(w)o(ea)o(v)o(e)h(45)1042 2940 y(60)p eop
+%%Page: 61 62
+61 61 bop 177 42 a Fn(William)o(s)12 b(Ross)h(1)177 91 y(w)o(ork)h(38)177
+141 y(writing)f(itself)h(F)m(unnelW)m(eb)f(28)1042 2940 y(61)p
+eop
+%%Trailer
+end
+userdict /end-hook known{end-hook}if
+%%EOF
diff --git a/web/funnelAC/hackman/h_manual.sin b/web/funnelAC/hackman/h_manual.sin
new file mode 100644
index 0000000000..72e1b4fa20
--- /dev/null
+++ b/web/funnelAC/hackman/h_manual.sin
@@ -0,0 +1,326 @@
+\indexentry{.cld file}{18}
+\indexentry{==}{14}
+\indexentry{@M}{23}
+\indexentry{@Z}{23}
+\indexentry{abbreviations identifier}{28}
+\indexentry{acknowledgements}{7}
+\indexentry{Ada}{18}
+\indexentry{Ada}{27}
+\indexentry{Ada}{7}
+\indexentry{adding features}{36}
+\indexentry{Adelaide University}{27}
+\indexentry{analyser}{45}
+\indexentry{Andrew Trevorrow}{9}
+\indexentry{ANSI}{28}
+\indexentry{ANSI}{57}
+\indexentry{antiquated features}{43}
+\indexentry{ASCII mnemonics}{45}
+\indexentry{asking for trouble}{28}
+\indexentry{authority design}{36}
+\indexentry{authority security}{36}
+\indexentry{availability program}{37}
+\indexentry{backwards compatibility}{11}
+\indexentry{Barry Dwyer}{7}
+\indexentry{Begg Jeremy}{7}
+\indexentry{Bentley Jon}{11}
+\indexentry{Bentley86}{11}
+\indexentry{Bentley86}{57}
+\indexentry{blank indentation}{12}
+\indexentry{blank indentation}{12}
+\indexentry{breakout, GNU}{41}
+\indexentry{Brissenden Roger}{7}
+\indexentry{changes dangers}{35}
+\indexentry{coding style}{28}
+\indexentry{command interface}{43}
+\indexentry{command interpreter}{43}
+\indexentry{command line interface design goals}{19}
+\indexentry{command line interface}{18}
+\indexentry{command setall}{43}
+\indexentry{comment duplication}{18}
+\indexentry{Communications of the ACM}{11}
+\indexentry{compatibility backwards}{11}
+\indexentry{compiler ThinkC}{30}
+\indexentry{compiler}{35}
+\indexentry{conditionals}{44}
+\indexentry{contiguous memory}{45}
+\indexentry{copyright law}{38}
+\indexentry{copyright notice}{1}
+\indexentry{copyright}{38}
+\indexentry{correctness}{47}
+\indexentry{counting diagnostic}{43}
+\indexentry{cross references}{46}
+\indexentry{dangers changes}{35}
+\indexentry{dangers indentation}{13}
+\indexentry{dangers languages}{35}
+\indexentry{David Hulse}{27}
+\indexentry{David Hulse}{7}
+\indexentry{DCL}{13}
+\indexentry{derived work}{38}
+\indexentry{design authority}{36}
+\indexentry{design FunnelWeb}{11}
+\indexentry{design goals command line interface}{19}
+\indexentry{design language}{44}
+\indexentry{detection recursion}{45}
+\indexentry{diagnostic counting}{43}
+\indexentry{diagnostic messages}{25}
+\indexentry{diagnostics}{47}
+\indexentry{document structure macro structure}{23}
+\indexentry{document structure}{16}
+\indexentry{document structure}{23}
+\indexentry{documentation out of date}{18}
+\indexentry{documentation}{43}
+\indexentry{Donald Knuth}{11}
+\indexentry{Donald Knuth}{7}
+\indexentry{duplication comment}{18}
+\indexentry{Dwyer Barry}{7}
+\indexentry{efficiency}{47}
+\indexentry{EOL representation}{45}
+\indexentry{example official}{43}
+\indexentry{extensions filename}{20}
+\indexentry{factor glue}{46}
+\indexentry{features adding}{36}
+\indexentry{features antiquated}{43}
+\indexentry{features modification}{35}
+\indexentry{features removing}{35}
+\indexentry{file .cld}{18}
+\indexentry{file extension protection}{37}
+\indexentry{file markers}{44}
+\indexentry{file names}{19}
+\indexentry{file names}{21}
+\indexentry{file signature}{44}
+\indexentry{filename extensions}{20}
+\indexentry{filename inheritance}{20}
+\indexentry{filenames length}{29}
+\indexentry{filenames portable}{21}
+\indexentry{formal parameter list}{44}
+\indexentry{FunnelWeb design}{11}
+\indexentry{FunnelWeb future}{43}
+\indexentry{FunnelWeb history}{27}
+\indexentry{FunnelWeb implementation}{27}
+\indexentry{FunnelWeb management}{39}
+\indexentry{FunnelWeb modification}{35}
+\indexentry{FunnelWeb motivation}{11}
+\indexentry{FunnelWeb official}{39}
+\indexentry{FunnelWeb past use}{27}
+\indexentry{FunnelWeb protection}{37}
+\indexentry{FunnelWeb syntax}{14}
+\indexentry{FunnelWeb V1}{11}
+\indexentry{FunnelWeb version 1}{27}
+\indexentry{FunnelWeb version 2}{27}
+\indexentry{FunnelWeb version 3}{27}
+\indexentry{FunnelWeb writing itself}{28}
+\indexentry{future FunnelWeb}{43}
+\indexentry{genealogy program}{36}
+\indexentry{generic typesetter}{46}
+\indexentry{glue factor}{46}
+\indexentry{GNU breakout}{41}
+\indexentry{GNU license}{35}
+\indexentry{GNU license}{39}
+\indexentry{GNU License}{49}
+\indexentry{GNU version}{41}
+\indexentry{Hackett Simon}{7}
+\indexentry{headings}{16}
+\indexentry{heap memory}{29}
+\indexentry{hierarchical structure}{23}
+\indexentry{history FunnelWeb}{27}
+\indexentry{Hoare80}{36}
+\indexentry{Hoare80}{57}
+\indexentry{Horton90}{28}
+\indexentry{Horton90}{57}
+\indexentry{Hulse David}{27}
+\indexentry{Hulse David}{7}
+\indexentry{identifier abbreviations}{28}
+\indexentry{identifier}{28}
+\indexentry{implementation FunnelWeb}{27}
+\indexentry{include file suppression}{46}
+\indexentry{indentation blank}{12}
+\indexentry{indentation dangers}{13}
+\indexentry{indentation no}{12}
+\indexentry{indentation text}{12}
+\indexentry{indentation text}{30}
+\indexentry{indentation text}{45}
+\indexentry{indentation}{12}
+\indexentry{indentation}{12}
+\indexentry{indented macro call}{12}
+\indexentry{index program}{43}
+\indexentry{inheritance filename}{20}
+\indexentry{interface command line}{18}
+\indexentry{interface command}{43}
+\indexentry{interpreter command}{43}
+\indexentry{interpreter shell}{43}
+\indexentry{invocations number}{22}
+\indexentry{issues miscellaneous}{18}
+\indexentry{Jeremy Begg}{7}
+\indexentry{Jon Bentley}{11}
+\indexentry{Kernighan88}{28}
+\indexentry{Kernighan88}{57}
+\indexentry{Knuth Donald}{11}
+\indexentry{Knuth Donald}{7}
+\indexentry{Knuth83}{11}
+\indexentry{Knuth83}{57}
+\indexentry{Knuth84}{57}
+\indexentry{Knuth84}{9}
+\indexentry{Lamport86}{57}
+\indexentry{Lamport86}{9}
+\indexentry{language design}{44}
+\indexentry{languages dangers}{35}
+\indexentry{LaTeX}{9}
+\indexentry{LaTeX}{9}
+\indexentry{law copyright}{38}
+\indexentry{leakage memory}{30}
+\indexentry{length filenames}{29}
+\indexentry{license GNU}{35}
+\indexentry{license GNU}{39}
+\indexentry{License GNU}{49}
+\indexentry{license}{38}
+\indexentry{lister}{46}
+\indexentry{Macintosh}{29}
+\indexentry{Macintosh}{30}
+\indexentry{Macintosh}{9}
+\indexentry{macro call syntax}{16}
+\indexentry{macro definition syntax}{14}
+\indexentry{macro structure document structure}{23}
+\indexentry{macro structure}{23}
+\indexentry{make}{44}
+\indexentry{malloc}{29}
+\indexentry{management FunnelWeb}{39}
+\indexentry{manuals modifying}{38}
+\indexentry{mapper}{44}
+\indexentry{markers file}{44}
+\indexentry{memory contiguous}{45}
+\indexentry{memory heap}{29}
+\indexentry{memory leakage}{30}
+\indexentry{memory package}{29}
+\indexentry{memory stack}{30}
+\indexentry{memory static}{30}
+\indexentry{memory use of}{29}
+\indexentry{messages diagnostic}{25}
+\indexentry{miscellaneous issues}{18}
+\indexentry{mnemonics ASCII}{45}
+\indexentry{modification features}{35}
+\indexentry{modification FunnelWeb}{35}
+\indexentry{modifying manuals}{38}
+\indexentry{motivation FunnelWeb}{11}
+\indexentry{MSDOS}{29}
+\indexentry{names file}{19}
+\indexentry{names file}{21}
+\indexentry{naming pointers}{29}
+\indexentry{naming types}{29}
+\indexentry{no indentation}{12}
+\indexentry{no indentation}{12}
+\indexentry{notice copyright}{1}
+\indexentry{number invocations}{22}
+\indexentry{number output files}{12}
+\indexentry{numbering section}{23}
+\indexentry{Occam's razor}{12}
+\indexentry{official example}{43}
+\indexentry{official FunnelWeb}{39}
+\indexentry{options}{43}
+\indexentry{out of date documentation}{18}
+\indexentry{output files number}{12}
+\indexentry{OzTeX}{9}
+\indexentry{package memory}{29}
+\indexentry{parameter list formal}{44}
+\indexentry{parameterized macro call syntax}{16}
+\indexentry{parameterized macro definitions syntax}{15}
+\indexentry{parser}{45}
+\indexentry{Pascal}{12}
+\indexentry{past use FunnelWeb}{27}
+\indexentry{Ph.D.}{27}
+\indexentry{pointers naming}{29}
+\indexentry{portability}{28}
+\indexentry{portable filenames}{21}
+\indexentry{pragma syntax}{44}
+\indexentry{pragma version}{45}
+\indexentry{preface}{5}
+\indexentry{presentation notes}{9}
+\indexentry{program availability}{37}
+\indexentry{program genealogy}{36}
+\indexentry{program index}{43}
+\indexentry{programming pearls}{11}
+\indexentry{protection file extension}{37}
+\indexentry{protection FunnelWeb}{37}
+\indexentry{Rabinowitz90}{28}
+\indexentry{Rabinowitz90}{28}
+\indexentry{Rabinowitz90}{57}
+\indexentry{Ramsey89}{46}
+\indexentry{Ramsey89}{57}
+\indexentry{recursion detection}{45}
+\indexentry{recursion test}{43}
+\indexentry{references cross}{46}
+\indexentry{references}{57}
+\indexentry{regression testing}{18}
+\indexentry{removing features}{35}
+\indexentry{representation EOL}{45}
+\indexentry{Robert Endre Tarjan}{45}
+\indexentry{Roger Brissenden}{7}
+\indexentry{Ross Williams}{1}
+\indexentry{scanner}{44}
+\indexentry{section numbering}{23}
+\indexentry{section syntax}{44}
+\indexentry{sections}{16}
+\indexentry{security authority}{36}
+\indexentry{setall command}{43}
+\indexentry{shell interpreter}{43}
+\indexentry{signature file}{44}
+\indexentry{Simon Hackett}{7}
+\indexentry{size stack}{30}
+\indexentry{South Australian Government Department of Lands}{28}
+\indexentry{speed}{47}
+\indexentry{spider}{46}
+\indexentry{stack memory}{30}
+\indexentry{stack size}{30}
+\indexentry{static memory}{30}
+\indexentry{static variables}{30}
+\indexentry{strength typesetting}{46}
+\indexentry{structure document}{16}
+\indexentry{structure document}{23}
+\indexentry{structure hierarchical}{23}
+\indexentry{structure macro}{23}
+\indexentry{style coding}{28}
+\indexentry{suite test}{47}
+\indexentry{suppression include file}{46}
+\indexentry{syntax FunnelWeb}{14}
+\indexentry{syntax macro call}{16}
+\indexentry{syntax macro definition}{14}
+\indexentry{syntax parameterized macro call}{16}
+\indexentry{syntax parameterized macro definitions}{15}
+\indexentry{syntax pragma}{44}
+\indexentry{syntax section}{44}
+\indexentry{table of contents}{45}
+\indexentry{tangle}{45}
+\indexentry{Tarjan Robert Endre}{45}
+\indexentry{Tarjan72}{45}
+\indexentry{Tarjan72}{57}
+\indexentry{test recursion}{43}
+\indexentry{test suite}{47}
+\indexentry{testing regression}{18}
+\indexentry{text indentation}{12}
+\indexentry{text indentation}{12}
+\indexentry{text indentation}{30}
+\indexentry{text indentation}{45}
+\indexentry{TeX}{23}
+\indexentry{TeX}{9}
+\indexentry{ThinkC compiler}{30}
+\indexentry{trademark}{36}
+\indexentry{Trevorrow Andrew}{9}
+\indexentry{trouble asking for}{28}
+\indexentry{types naming}{29}
+\indexentry{typesetter generic}{46}
+\indexentry{typesetting strength}{46}
+\indexentry{typesetting}{9}
+\indexentry{University Adelaide}{27}
+\indexentry{Unix}{36}
+\indexentry{USDOD83}{27}
+\indexentry{USDOD83}{57}
+\indexentry{use of memory}{29}
+\indexentry{variables static}{30}
+\indexentry{vax vms}{18}
+\indexentry{version GNU}{41}
+\indexentry{version pragma}{45}
+\indexentry{video game}{35}
+\indexentry{vms vax}{18}
+\indexentry{weave}{45}
+\indexentry{Williams Ross}{1}
+\indexentry{work}{38}
+\indexentry{writing itself FunnelWeb}{28}
diff --git a/web/funnelAC/hackman/h_manual.tex b/web/funnelAC/hackman/h_manual.tex
new file mode 100644
index 0000000000..716a28277c
--- /dev/null
+++ b/web/funnelAC/hackman/h_manual.tex
@@ -0,0 +1,283 @@
+%==============================================================================%
+% FUNNELWEB USER'S MANUAL %
+%==============================================================================%
+%
+% Summary
+% -------
+% This is the main .tex file of the FunnelWeb Hacker's Manual.
+%
+% For a list of the other files that contribute to this document,
+% see the list of files given in \input lines at the end of this file.
+%
+% See the TeX comments below to find out how to typeset this document.
+%
+%
+% Copyright
+% ---------
+% Copyright (C) 1992 Ross N. Williams.
+%
+% Permission is granted to make and distribute verbatim copies of this manual
+% provided that the copyright notice and this permission notice are preserved
+% on all copies.
+%
+%
+% Version
+% -------
+% Date : May 1992.
+% Version : 1.0.
+%
+%
+% Author
+% ------
+% Name : Ross Williams.
+% Email : ross@spam.adelaide.edu.au
+% Snail : 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+%
+%
+% How to Typeset This Document
+% ----------------------------
+% This document is written in a format suitable for processing by the LaTeX
+% typesetting system which can be found on many machines around the world.
+% The document is an entirely self contained LaTeX document. To assist in
+% the electronic distribution of this document, all diagrams have been
+% constructing using ASCII text from within LaTeX. This means that all you
+% need to print this document is a LaTeX typesetting system.
+%
+% To print this document using LaTeX, give a command sequence that looks
+% something like this:
+%
+% latex manual
+% latex manual
+% sort -f <manual.idx >manual.sin
+% % Start here if manual.aux, manual.toc, and manual.sin already exist.
+% latex manual
+% print manual
+%
+% The commands must be given three times so as to allow the cross
+% referencing information to be correctly assembled.
+% The "sort" command should perform a case insensitive sort of the lines of
+% its input, but should not alter the lines it is sorting. In the example
+% about, the "-f" option specifies that the sort should be case insensitive.
+% The "print" command should print the .dvi file generated by LaTeX.
+% The details of the typesetting sequence above may vary on your computer
+% system.
+%
+%=============================================================================%
+
+
+% Basic Document Style
+% --------------------
+% The default font size is 10pt which is what I want.
+% titlepage - Instructs LaTeX to produce a title page at the front.
+% book - Use the "book" built in format.
+\documentstyle[titlepage]{book}
+
+% The following pagestyle command instructs LaTeX to set each page with just
+% a page number at the middle of the bottom of each page.
+\pagestyle{plain}
+
+% By default, the "book" style sets even and odd pages differently on the
+% assumption that the result is to be used in a two-sided printing process.
+% However, most people printing this will print it single sided.
+% To suppress double sided mode, we need to give the \onecolumn command.
+\onecolumn
+
+
+% Page Size and Position
+% ----------------------
+% The following sets the size of the text box and its position on the page.
+% It works OK on A4 paper. I suppose I should test it on American paper too.
+\textwidth 15cm
+\textheight 24cm
+\topmargin 0cm
+\oddsidemargin 1.5cm
+\evensidemargin 1.5cm
+\headheight 0cm
+\headsep 0cm
+
+
+% Table of Contents
+% -----------------
+% Specify that all headings be numbered and appear in the Table of Contents.
+\setcounter{secnumdepth}{100}
+\setcounter{tocdepth}{100}
+
+% LaTeX lets you create an unnumbered chapter, but it doesn't put it in
+% the table of contents. So we have to do it manually.
+\def\pseudochapter#1{%
+\chapter*{#1}
+\addcontentsline{toc}{chapter}{#1}
+}
+
+% Paragraph Separation and Indentation
+% ------------------------------------
+% The default LaTeX format is to have paragraphs jammed up against each other
+% with indentation of text on the first line of each paragraph used to
+% highlight the start of each paragraph. I prefer to identify paragraphs
+% by separating them with space and eliminating the indentation.
+\parskip \medskipamount
+\parindent 0pt
+
+
+% Quick Style Macros
+% ------------------
+% Use of the following macros is much neater and safer than opening a group
+% and setting a mode (e.g. {\bf sloth}) as these macros will cause TeX to
+% scream if they span more than one paragraph whereas the group method
+% can cause half the document to be set in a funny mode.
+% Other little macros here serve the same neatening normalizing purposes.
+\def\i#1{{\it #1}} % Italics.
+\def\b#1{{\bf #1}} % Bold.
+\def\p#1{{\tt #1}} % Program text.
+\def\sq#1{`#1'} % Single quotes.
+\def\dq#1{``#1''} % Double quotes.
+\def\dqp#1{\dq{\p{#1}}} % Double quoted program text.
+\def\fix#1{\footnote{$\bullet$ #1}} % Fix it up footnote.
+\def\softfix#1{} % Marks opportunity for improvement.
+\def\eg{e.g.~} % Spacing regulated "e.g.".
+\def\ie{i.e.~} % Spacing regulated "i.e.".
+\def\til{\char`\~} % For tilde ("~") character.
+\def\circumflex{\char`\^} % Circumflex.
+\def\bs{{\tt\char`\\}} % Backslash.
+
+% Point Making
+% ------------
+% LaTeX provides some useful environment for listing points. However, it does
+% not seem to provide what I want which is a paragraph of text led in by
+% a label set in bold.
+\def\thing#1{{\bf #1}}
+\def\firstthing#1{\thing{#1}}
+\def\narrowthing#1#2{{%From defintion of \narrower
+\advance\leftskip1cm%
+\advance\rightskip1cm%
+{\bf #1} #2\vskip0pt}}
+\def\narrowtext#1{{%From defintion of \narrower
+\advance\leftskip1cm%
+\advance\rightskip1cm%
+#1\vskip0pt}}
+\def\summary{\b{Summary:}\ }
+
+% Invisible Annotations
+% ---------------------
+% Sometimes it is convenient to be able to annotate the LaTeX code without
+% causing text to appear in the document.
+% Here, the \checked{} macro can be placed next to any quotation or
+% fact, or other externally dependent material that has to be checked
+% before publication. The \note{} macro can be used to add a note.
+% Both macros are safer than "%" in a paragraph where the text may be
+% continually being rearranged across lines.
+\def\checked#1{}
+\def\note#1{}
+
+
+% Wide Verbatim Text
+% ------------------
+% This document was originally set in 12pt and the result was that many of
+% the verbatim examples wouldn't fit. To solve this, I created two macros
+% to reduce and increase the size of the text, and wrapped the longer
+% verbatim texts in calls to the macros. Later, the document was reset in
+% 10pt eliminating the original problem, so I redefined the macros to empty.
+%\def\beginsmall{\scriptsize}
+%\def\endsmall{\normalsize}
+\def\beginsmall{}
+\def\endsmall{}
+
+
+% The Index
+% ---------
+% LaTeX provides a single command (\index) for adding index entries to the
+% index. We shorten it and refine it a little with a few definitions.
+\def\newterm#1{{\bf #1}\x{#1}} % Special terminology.
+\def\x#1{\index{#1}} % Normal index entry.
+\def\xx#1#2{\index{#1 #2}\index{#2 #1}} % Symmetric index entry.
+\def\xn#1#2{\xx{#1}{#2}} % For a person's name.
+\def\xs#1#2{\index{#1, #2}} % For an entry with a subclause.
+
+
+% References
+% ----------
+\def\paper#1{{\bf [#1]}\x{#1}\linebreak[1]{}}
+
+
+% Figures and Tables
+% ------------------
+% LaTeX numbers figures by chapter and doesn't position captions where I
+% want them and so I have decided to do it all manually. I haven't got
+% time for fancy stuff so I am using manual macros.
+\def\mylabel#1#2{%
+\begin{quotation}
+\footnotesize\baselineskip=12pt #2
+\end{quotation}
+\centerline{#1}
+\smallskip}
+
+\def\figfor#1{{\bf Figure~#1}}
+\def\tabfor#1{{\bf Table~#1}}
+
+\def\figlicense{\figfor{1}}
+%\def\figtwo{\figfor{2}}
+
+%\def\tabone{\tabfor{1}}
+%\def\tabtwo{\tabfor{2}}
+
+
+% Glossary
+% --------
+\def\gloss#1{\thing{#1:}\x{#1}}
+
+
+% Random Leftover Stuff
+% ---------------------
+\def\topicbreak{\bigskip\centerline{--- $\S$ ---}\bigskip}
+
+
+
+%------------------------------------------------------------------------------
+
+% Title Page
+% ----------
+% Although the title should really be in the ch0.tex file, LaTeX forces us to
+% put it here.
+\begin{titlepage}
+\vspace*{3cm}
+\begin{center}
+\Huge
+\vspace{2cm}
+FunnelWeb Hacker's Manual\\
+\vspace{2cm}
+\LARGE
+Ross~N.~Williams\\
+\vspace{1cm}
+\Large
+V1.0 for FunnelWeb V3.0\\
+\vspace{1cm}
+May 1992\\
+\normalsize
+\end{center}
+\end{titlepage}
+
+% Note: LaTeX sometimes puts a blank page before chapters so as to
+% start each chapter on an odd-numbered page. There is nothing that I
+% can do about this. This is part of the cost of using LaTeX instead
+% of TeX.
+
+\makeindex
+
+%-------------------------------------------------------------------------------
+
+\begin{document}
+\sloppy
+\nonstopmode
+
+\input h_ch0 % Table of contents etc.
+\input h_ch1 % FunnelWeb Design
+\input h_ch2 % FunnelWeb Implementation
+\input h_ch3 % FunnelWeb Modification
+\input h_ch4 % FunnelWeb Future
+\input h_cha % Appendices
+
+\end{document}
+
+%==============================================================================%
+% End of Main .TeX File of FunnelWeb Hacker's Manual %
+%==============================================================================%
diff --git a/web/funnelAC/hackman/h_manual.toc b/web/funnelAC/hackman/h_manual.toc
new file mode 100644
index 0000000000..41e1e43e82
--- /dev/null
+++ b/web/funnelAC/hackman/h_manual.toc
@@ -0,0 +1,62 @@
+\contentsline {chapter}{Preface}{5}
+\contentsline {chapter}{Acknowledgements}{7}
+\contentsline {chapter}{Presentation Notes}{9}
+\contentsline {chapter}{\numberline {1}FunnelWeb Design}{11}
+\contentsline {section}{\numberline {1.1}Motivation for FunnelWeb}{11}
+\contentsline {section}{\numberline {1.2}Indentation}{12}
+\contentsline {section}{\numberline {1.3}Review of FunnelWeb Syntax}{14}
+\contentsline {subsection}{\numberline {1.3.1}Review of Macro Definition Syntax}{14}
+\contentsline {subsection}{\numberline {1.3.2}Review of Macro Call Syntax}{16}
+\contentsline {subsection}{\numberline {1.3.3}Review of Parameterized Macro Call Syntax}{16}
+\contentsline {section}{\numberline {1.4}Document Structuring}{16}
+\contentsline {section}{\numberline {1.5}Discussion of Some Miscellaneous Issues}{18}
+\contentsline {section}{\numberline {1.6}Automated Regression Testing}{18}
+\contentsline {section}{\numberline {1.7}Command Line Interface}{18}
+\contentsline {section}{\numberline {1.8}File Name Management}{19}
+\contentsline {subsection}{\numberline {1.8.1}Filename Extensions}{20}
+\contentsline {subsection}{\numberline {1.8.2}Filename Inheritance}{20}
+\contentsline {subsection}{\numberline {1.8.3}Portable Structure of File Names}{21}
+\contentsline {section}{\numberline {1.9}Specifying Constraints on the Number of Instantiations}{22}
+\contentsline {section}{\numberline {1.10}The Relationship Between Document Structure and Macro Structure}{23}
+\contentsline {section}{\numberline {1.11}Diagnostic Messages}{25}
+\contentsline {section}{\numberline {1.12}Summary}{25}
+\contentsline {chapter}{\numberline {2}FunnelWeb Implementation}{27}
+\contentsline {section}{\numberline {2.1}Introduction}{27}
+\contentsline {section}{\numberline {2.2}History of FunnelWeb Implementations}{27}
+\contentsline {section}{\numberline {2.3}Why FunnelWeb Wasn't Used to Write Itself}{28}
+\contentsline {section}{\numberline {2.4}Coding Style}{28}
+\contentsline {section}{\numberline {2.5}Use of Memory}{29}
+\contentsline {section}{\numberline {2.6}The Heap}{29}
+\contentsline {section}{\numberline {2.7}The Stack}{30}
+\contentsline {section}{\numberline {2.8}Static Variables}{30}
+\contentsline {section}{\numberline {2.9}Implementing Text Indentation}{30}
+\contentsline {chapter}{\numberline {3}FunnelWeb Modification}{35}
+\contentsline {section}{\numberline {3.1}Introduction}{35}
+\contentsline {section}{\numberline {3.2}The Danger of Modifying Languages}{35}
+\contentsline {section}{\numberline {3.3}Authority vs User Security}{36}
+\contentsline {section}{\numberline {3.4}What I Want to Protect}{37}
+\contentsline {section}{\numberline {3.5}Modifying the Manuals}{38}
+\contentsline {section}{\numberline {3.6}How Copyright Law Works}{38}
+\contentsline {section}{\numberline {3.7}Management of the Official FunnelWeb}{39}
+\contentsline {section}{\numberline {3.8}A GNU Version?}{41}
+\contentsline {section}{\numberline {3.9}Summary}{41}
+\contentsline {chapter}{\numberline {4}FunnelWeb Future}{43}
+\contentsline {section}{\numberline {4.1}Documentation}{43}
+\contentsline {section}{\numberline {4.2}Command Line Interface}{43}
+\contentsline {section}{\numberline {4.3}Shell Interpreter}{43}
+\contentsline {section}{\numberline {4.4}Language Design}{44}
+\contentsline {section}{\numberline {4.5}Scanner/Mapper}{44}
+\contentsline {section}{\numberline {4.6}Parser}{45}
+\contentsline {section}{\numberline {4.7}Analyser}{45}
+\contentsline {section}{\numberline {4.8}Tangle}{45}
+\contentsline {section}{\numberline {4.9}Weave}{45}
+\contentsline {section}{\numberline {4.10}Lister}{46}
+\contentsline {section}{\numberline {4.11}Diagnostics}{47}
+\contentsline {section}{\numberline {4.12}Speed}{47}
+\contentsline {section}{\numberline {4.13}Correctness}{47}
+\contentsline {section}{\numberline {4.14}Test Suite}{47}
+\contentsline {section}{\numberline {4.15}Machine-Specific Changes}{48}
+\contentsline {section}{\numberline {4.16}Summary}{48}
+\contentsline {chapter}{\numberline {A}GNU General Public License Version 2}{49}
+\contentsline {chapter}{\numberline {B}References}{57}
+\contentsline {chapter}{Index}{57}
diff --git a/web/funnelAC/regform.txt b/web/funnelAC/regform.txt
new file mode 100644
index 0000000000..c4c00d3189
--- /dev/null
+++ b/web/funnelAC/regform.txt
@@ -0,0 +1,30 @@
+ +----------------------FunnelWeb Registration Form----------------------+
+ | 1. Date: |
+ | |
+ | 2. Title and name: |
+ | |
+ | 3. Internet email address: |
+ | |
+ | 4. Snail mail address: |
+ | |
+ | 5. Work phone number (country,area,number): |
+ | |
+ | 6. Which category of FunnelWeb user best describes you? |
+ | Latent - Installed FunnelWeb, but don't intend to use it. |
+ | Beginner - Haven't used FunnelWeb much yet; have an open mind. |
+ | Casual - Use FunnelWeb occasionally. |
+ | Convert - Use FunnelWeb to do most programming. |
+ | Fanatic - FunnelWeb has become a way of life. |
+ | |
+ | 7. What changes or new features would you like to see in FunnelWeb? |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | 8. Do you want to be kept informed of new FunnelWeb developments? |
+ | |
+ +-----------------------------------------------------------------------+
+
+Email to `coates@physics.uq.edu.au'.
diff --git a/web/funnelAC/results/0testres.dif b/web/funnelAC/results/0testres.dif
new file mode 100644
index 0000000000..734f06a09d
--- /dev/null
+++ b/web/funnelAC/results/0testres.dif
@@ -0,0 +1,8167 @@
+
+
+Comparing "/usr/var/tmp/funnelweb/results/generate.lis"
+ with "/usr/var/tmp/funnelweb/answers/generate.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc01.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc01.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc02.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc02.lis".
+
+ +-----
+00040|------------------- Start of Macro Dump --------------------
+00041|Macro Name : "#file"
+00042|Defined? : Yes.
+00043|Parameters : 0
+00044|Additive? : No.
+00045|Zero Calls? : Yes.
+00046|Many Calls? : Yes.
+00047|Output File?: No.
+00048|Automatic Line Directive Macro?: No.
+00049|Call list :
+00050|Macro body :
+00051|
+00052|--Start of List of Body Parts--
+00053|This macro has 1 body part.
+00054|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00055|
+00056|---- Start of Expression ----
+00057|
+00058|--- Start Special Function ---
+00059|---- End Special Function ----
+00060|
+00061|----- End of Expression -----
+00062|
+00063|---End of List of Body Parts---
+00064|
+00065|-------------------- End of Macro Dump ---------------------
+00066|
+00067|
+00068|
+00069|------------------- Start of Macro Dump --------------------
+00070|Macro Name : "#line"
+00071|Defined? : Yes.
+00072|Parameters : 0
+00073|Additive? : No.
+00074|Zero Calls? : Yes.
+00075|Many Calls? : Yes.
+00076|Output File?: No.
+00077|Automatic Line Directive Macro?: No.
+00078|Call list :
+00079|Macro body :
+00080|
+00081|--Start of List of Body Parts--
+00082|This macro has 1 body part.
+00083|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00084|
+00085|---- Start of Expression ----
+00086|
+00087|--- Start Special Function ---
+00088|---- End Special Function ----
+00089|
+00090|----- End of Expression -----
+00091|
+00092|---End of List of Body Parts---
+00093|
+00094|-------------------- End of Macro Dump ---------------------
+00095|
+00096|
+00097|
+00098|------------------- Start of Macro Dump --------------------
+00099|Macro Name : "#timestamp"
+00100|Defined? : Yes.
+00101|Parameters : 0
+00102|Additive? : No.
+00103|Zero Calls? : Yes.
+ +-----
+00040|=========================== End of MACRO TABLE DUMP ============================
+00041|
+00042|
+00043|========================= Start of DOCUMENT LIST DUMP ==========================
+00044|
+00045|
+00046|========================== End of DOCUMENT LIST DUMP ===========================
+00047|
+00048|E: No macros defined.
+00049|E: No output files specified.
+00050|
+00051|Global Local| Input File
+00052|------------+-------------------------------------------------------------------
+00053| | <End-Of-File>
+00054| Warning|.^Input file is empty (not a byte in syte)!
+00055|------------+-------------------------------------------------------------------
+00056|
+00057|There were 2 Errors and 1 Warning.
+ +-----
+
+ +-----
+00104|Many Calls? : Yes.
+00105|Output File?: No.
+00106|Automatic Line Directive Macro?: No.
+00107|Call list :
+00108|Macro body :
+00109|
+00110|--Start of List of Body Parts--
+00111|This macro has 1 body part.
+00112|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00113|
+00114|---- Start of Expression ----
+00115|
+00116|--- Start Special Function ---
+00117|---- End Special Function ----
+00118|
+00119|----- End of Expression -----
+00120|
+00121|---End of List of Body Parts---
+00122|
+00123|-------------------- End of Macro Dump ---------------------
+00124|
+00125|
+00126|
+00127|=========================== End of MACRO TABLE DUMP ============================
+00128|
+00129|
+00130|========================= Start of DOCUMENT LIST DUMP ==========================
+00131|
+00132|
+00133|========================== End of DOCUMENT LIST DUMP ===========================
+00134|
+00135|E: No output files specified.
+00136|
+00137|Global Local| Input File
+00138|------------+-------------------------------------------------------------------
+00139| | <End-Of-File>
+00140| Warning|.^Input file is empty (not a byte in syte)!
+00141|------------+-------------------------------------------------------------------
+00142|
+00143|There was 1 Error and 1 Warning.
+ +-----
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc03.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc03.lis".
+
+ +-----
+00044|------------------- Start of Macro Dump --------------------
+00045|Macro Name : "#file"
+00046|Defined? : Yes.
+00047|Parameters : 0
+00048|Additive? : No.
+00049|Zero Calls? : Yes.
+00050|Many Calls? : Yes.
+00051|Output File?: No.
+00052|Automatic Line Directive Macro?: No.
+00053|Call list :
+00054|Macro body :
+00055|
+00056|--Start of List of Body Parts--
+00057|This macro has 1 body part.
+00058|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00059|
+00060|---- Start of Expression ----
+00061|
+00062|--- Start Special Function ---
+00063|---- End Special Function ----
+00064|
+00065|----- End of Expression -----
+00066|
+00067|---End of List of Body Parts---
+00068|
+00069|-------------------- End of Macro Dump ---------------------
+00070|
+00071|
+00072|
+00073|------------------- Start of Macro Dump --------------------
+00074|Macro Name : "#line"
+00075|Defined? : Yes.
+00076|Parameters : 0
+00077|Additive? : No.
+00078|Zero Calls? : Yes.
+00079|Many Calls? : Yes.
+00080|Output File?: No.
+00081|Automatic Line Directive Macro?: No.
+00082|Call list :
+00083|Macro body :
+00084|
+00085|--Start of List of Body Parts--
+00086|This macro has 1 body part.
+00087|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00088|
+00089|---- Start of Expression ----
+00090|
+00091|--- Start Special Function ---
+00092|---- End Special Function ----
+00093|
+00094|----- End of Expression -----
+00095|
+00096|---End of List of Body Parts---
+00097|
+00098|-------------------- End of Macro Dump ---------------------
+00099|
+00100|
+00101|
+00102|------------------- Start of Macro Dump --------------------
+00103|Macro Name : "#timestamp"
+00104|Defined? : Yes.
+00105|Parameters : 0
+00106|Additive? : No.
+00107|Zero Calls? : Yes.
+ +-----
+00044|=========================== End of MACRO TABLE DUMP ============================
+00045|
+00046|
+00047|========================= Start of DOCUMENT LIST DUMP ==========================
+00048|
+00049|
+00050|TEXT COMPONENT: Pos(L,C)=(1,1).
+00051|
+00052|-- Start of Text Scrap List --
+00053|Text scrap[White]="<010>
+00054|"
+00055|--- End of Text Scrap List ---
+00056|
+00057|
+00058|========================== End of DOCUMENT LIST DUMP ===========================
+00059|
+00060|E: No macros defined.
+00061|E: No output files specified.
+00062|
+00063|Global Local| Input File
+00064|------------+-------------------------------------------------------------------
+00065|.................
+00066|------------+-------------------------------------------------------------------
+00067|
+00068|There were 2 Errors.
+ +-----
+
+ +-----
+00108|Many Calls? : Yes.
+00109|Output File?: No.
+00110|Automatic Line Directive Macro?: No.
+00111|Call list :
+00112|Macro body :
+00113|
+00114|--Start of List of Body Parts--
+00115|This macro has 1 body part.
+00116|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00117|
+00118|---- Start of Expression ----
+00119|
+00120|--- Start Special Function ---
+00121|---- End Special Function ----
+00122|
+00123|----- End of Expression -----
+00124|
+00125|---End of List of Body Parts---
+00126|
+00127|-------------------- End of Macro Dump ---------------------
+00128|
+00129|
+00130|
+00131|=========================== End of MACRO TABLE DUMP ============================
+00132|
+00133|
+00134|========================= Start of DOCUMENT LIST DUMP ==========================
+00135|
+00136|
+00137|TEXT COMPONENT: Pos(L,C)=(1,1).
+00138|
+00139|-- Start of Text Scrap List --
+00140|Text scrap[White]="<010>
+00141|"
+00142|--- End of Text Scrap List ---
+00143|
+00144|
+00145|========================== End of DOCUMENT LIST DUMP ===========================
+00146|
+00147|E: No output files specified.
+00148|
+00149|Global Local| Input File
+00150|------------+-------------------------------------------------------------------
+00151|.................
+00152|------------+-------------------------------------------------------------------
+00153|
+00154|There was 1 Error.
+ +-----
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc04.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc04.lis".
+
+ +-----
+00046|------------------- Start of Macro Dump --------------------
+00047|Macro Name : "#file"
+00048|Defined? : Yes.
+00049|Parameters : 0
+00050|Additive? : No.
+00051|Zero Calls? : Yes.
+00052|Many Calls? : Yes.
+00053|Output File?: No.
+00054|Automatic Line Directive Macro?: No.
+00055|Call list :
+00056|Macro body :
+00057|
+00058|--Start of List of Body Parts--
+00059|This macro has 1 body part.
+00060|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00061|
+00062|---- Start of Expression ----
+00063|
+00064|--- Start Special Function ---
+00065|---- End Special Function ----
+00066|
+00067|----- End of Expression -----
+00068|
+00069|---End of List of Body Parts---
+00070|
+00071|-------------------- End of Macro Dump ---------------------
+00072|
+00073|
+00074|
+00075|------------------- Start of Macro Dump --------------------
+00076|Macro Name : "#line"
+00077|Defined? : Yes.
+00078|Parameters : 0
+00079|Additive? : No.
+00080|Zero Calls? : Yes.
+00081|Many Calls? : Yes.
+00082|Output File?: No.
+00083|Automatic Line Directive Macro?: No.
+00084|Call list :
+00085|Macro body :
+00086|
+00087|--Start of List of Body Parts--
+00088|This macro has 1 body part.
+00089|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00090|
+00091|---- Start of Expression ----
+00092|
+00093|--- Start Special Function ---
+00094|---- End Special Function ----
+00095|
+00096|----- End of Expression -----
+00097|
+00098|---End of List of Body Parts---
+00099|
+00100|-------------------- End of Macro Dump ---------------------
+00101|
+00102|
+00103|
+00104|------------------- Start of Macro Dump --------------------
+00105|Macro Name : "#timestamp"
+00106|Defined? : Yes.
+00107|Parameters : 0
+00108|Additive? : No.
+00109|Zero Calls? : Yes.
+ +-----
+00046|=========================== End of MACRO TABLE DUMP ============================
+00047|
+00048|
+00049|========================= Start of DOCUMENT LIST DUMP ==========================
+00050|
+00051|
+00052|TEXT COMPONENT: Pos(L,C)=(1,1).
+00053|
+00054|-- Start of Text Scrap List --
+00055|Text scrap[White]="<010>
+00056|<010>
+00057|"
+00058|--- End of Text Scrap List ---
+00059|
+00060|
+00061|========================== End of DOCUMENT LIST DUMP ===========================
+00062|
+00063|E: No macros defined.
+00064|E: No output files specified.
+00065|
+00066|Global Local| Input File
+00067|------------+-------------------------------------------------------------------
+00068|.................
+00069|------------+-------------------------------------------------------------------
+00070|
+00071|There were 2 Errors.
+ +-----
+
+ +-----
+00110|Many Calls? : Yes.
+00111|Output File?: No.
+00112|Automatic Line Directive Macro?: No.
+00113|Call list :
+00114|Macro body :
+00115|
+00116|--Start of List of Body Parts--
+00117|This macro has 1 body part.
+00118|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00119|
+00120|---- Start of Expression ----
+00121|
+00122|--- Start Special Function ---
+00123|---- End Special Function ----
+00124|
+00125|----- End of Expression -----
+00126|
+00127|---End of List of Body Parts---
+00128|
+00129|-------------------- End of Macro Dump ---------------------
+00130|
+00131|
+00132|
+00133|=========================== End of MACRO TABLE DUMP ============================
+00134|
+00135|
+00136|========================= Start of DOCUMENT LIST DUMP ==========================
+00137|
+00138|
+00139|TEXT COMPONENT: Pos(L,C)=(1,1).
+00140|
+00141|-- Start of Text Scrap List --
+00142|Text scrap[White]="<010>
+00143|<010>
+00144|"
+00145|--- End of Text Scrap List ---
+00146|
+00147|
+00148|========================== End of DOCUMENT LIST DUMP ===========================
+00149|
+00150|E: No output files specified.
+00151|
+00152|Global Local| Input File
+00153|------------+-------------------------------------------------------------------
+00154|.................
+00155|------------+-------------------------------------------------------------------
+00156|
+00157|There was 1 Error.
+ +-----
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc05.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc05.lis".
+
+ +-----
+00048|------------------- Start of Macro Dump --------------------
+00049|Macro Name : "#file"
+00050|Defined? : Yes.
+00051|Parameters : 0
+00052|Additive? : No.
+00053|Zero Calls? : Yes.
+00054|Many Calls? : Yes.
+00055|Output File?: No.
+00056|Automatic Line Directive Macro?: No.
+00057|Call list :
+00058|Macro body :
+00059|
+00060|--Start of List of Body Parts--
+00061|This macro has 1 body part.
+00062|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00063|
+00064|---- Start of Expression ----
+00065|
+00066|--- Start Special Function ---
+00067|---- End Special Function ----
+00068|
+00069|----- End of Expression -----
+00070|
+00071|---End of List of Body Parts---
+00072|
+00073|-------------------- End of Macro Dump ---------------------
+00074|
+00075|
+00076|
+00077|------------------- Start of Macro Dump --------------------
+00078|Macro Name : "#line"
+00079|Defined? : Yes.
+00080|Parameters : 0
+00081|Additive? : No.
+00082|Zero Calls? : Yes.
+00083|Many Calls? : Yes.
+00084|Output File?: No.
+00085|Automatic Line Directive Macro?: No.
+00086|Call list :
+00087|Macro body :
+00088|
+00089|--Start of List of Body Parts--
+00090|This macro has 1 body part.
+00091|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00092|
+00093|---- Start of Expression ----
+00094|
+00095|--- Start Special Function ---
+00096|---- End Special Function ----
+00097|
+00098|----- End of Expression -----
+00099|
+00100|---End of List of Body Parts---
+00101|
+00102|-------------------- End of Macro Dump ---------------------
+00103|
+00104|
+00105|
+00106|------------------- Start of Macro Dump --------------------
+00107|Macro Name : "#timestamp"
+00108|Defined? : Yes.
+00109|Parameters : 0
+00110|Additive? : No.
+00111|Zero Calls? : Yes.
+ +-----
+00048|=========================== End of MACRO TABLE DUMP ============================
+00049|
+00050|
+00051|========================= Start of DOCUMENT LIST DUMP ==========================
+00052|
+00053|
+00054|TEXT COMPONENT: Pos(L,C)=(1,1).
+00055|
+00056|-- Start of Text Scrap List --
+00057|Text scrap[Grey]="SC05: This input file contains a single line containing this text!<010>
+00058|"
+00059|--- End of Text Scrap List ---
+00060|
+00061|
+00062|========================== End of DOCUMENT LIST DUMP ===========================
+00063|
+00064|E: No macros defined.
+00065|E: No output files specified.
+00066|
+00067|Global Local| Input File
+00068|------------+-------------------------------------------------------------------
+00069|.................
+00070|------------+-------------------------------------------------------------------
+00071|
+00072|There were 2 Errors.
+ +-----
+
+ +-----
+00112|Many Calls? : Yes.
+00113|Output File?: No.
+00114|Automatic Line Directive Macro?: No.
+00115|Call list :
+00116|Macro body :
+00117|
+00118|--Start of List of Body Parts--
+00119|This macro has 1 body part.
+00120|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00121|
+00122|---- Start of Expression ----
+00123|
+00124|--- Start Special Function ---
+00125|---- End Special Function ----
+00126|
+00127|----- End of Expression -----
+00128|
+00129|---End of List of Body Parts---
+00130|
+00131|-------------------- End of Macro Dump ---------------------
+00132|
+00133|
+00134|
+00135|=========================== End of MACRO TABLE DUMP ============================
+00136|
+00137|
+00138|========================= Start of DOCUMENT LIST DUMP ==========================
+00139|
+00140|
+00141|TEXT COMPONENT: Pos(L,C)=(1,1).
+00142|
+00143|-- Start of Text Scrap List --
+00144|Text scrap[Grey]="SC05: This input file contains a single line containing this text!<010>
+00145|"
+00146|--- End of Text Scrap List ---
+00147|
+00148|
+00149|========================== End of DOCUMENT LIST DUMP ===========================
+00150|
+00151|E: No output files specified.
+00152|
+00153|Global Local| Input File
+00154|------------+-------------------------------------------------------------------
+00155|.................
+00156|------------+-------------------------------------------------------------------
+00157|
+00158|There was 1 Error.
+ +-----
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc06.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc06.lis".
+
+ +-----
+00018|| 72 6B 65 72 2E 0A 0A | rker... |
+ +-----
+00018|| 72 6B 65 72 2E 0A 0A 48 65 72 65 20 69 73 20 74 | rker...Here is t |
+00019|| 68 65 20 69 6D 70 72 6F 70 65 72 20 74 65 72 6D | he improper term |
+00020|| 69 6E 61 74 69 6F 6E 21 2D 2D 2D 2D 3E | ination!----> |
+ +-----
+
+ +-----
+00029|00004 00004| <End-Of-File><010>
+ +-----
+00031|00004 00004| Here is the improper termination!----><010>
+00032|00005 00005| <End-Of-File><010>
+ +-----
+
+ +-----
+00046|"
+00047|0004[01]: End Of File.
+ +-----
+00049|Here is the improper termination!----><010>
+00050|"
+00051|0005[01]: End Of File.
+ +-----
+
+ +-----
+00054|------------------- Start of Macro Dump --------------------
+00055|Macro Name : "#file"
+00056|Defined? : Yes.
+00057|Parameters : 0
+00058|Additive? : No.
+00059|Zero Calls? : Yes.
+00060|Many Calls? : Yes.
+00061|Output File?: No.
+00062|Automatic Line Directive Macro?: No.
+00063|Call list :
+00064|Macro body :
+00065|
+00066|--Start of List of Body Parts--
+00067|This macro has 1 body part.
+00068|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00069|
+00070|---- Start of Expression ----
+00071|
+00072|--- Start Special Function ---
+00073|---- End Special Function ----
+00074|
+00075|----- End of Expression -----
+00076|
+00077|---End of List of Body Parts---
+00078|
+00079|-------------------- End of Macro Dump ---------------------
+00080|
+00081|
+00082|
+00083|------------------- Start of Macro Dump --------------------
+00084|Macro Name : "#line"
+00085|Defined? : Yes.
+00086|Parameters : 0
+00087|Additive? : No.
+00088|Zero Calls? : Yes.
+00089|Many Calls? : Yes.
+00090|Output File?: No.
+00091|Automatic Line Directive Macro?: No.
+00092|Call list :
+00093|Macro body :
+00094|
+00095|--Start of List of Body Parts--
+00096|This macro has 1 body part.
+00097|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00098|
+00099|---- Start of Expression ----
+00100|
+00101|--- Start Special Function ---
+00102|---- End Special Function ----
+00103|
+00104|----- End of Expression -----
+00105|
+00106|---End of List of Body Parts---
+00107|
+00108|-------------------- End of Macro Dump ---------------------
+00109|
+00110|
+00111|
+00112|------------------- Start of Macro Dump --------------------
+00113|Macro Name : "#timestamp"
+00114|Defined? : Yes.
+00115|Parameters : 0
+00116|Additive? : No.
+00117|Zero Calls? : Yes.
+ +-----
+00058|=========================== End of MACRO TABLE DUMP ============================
+00059|
+00060|
+00061|========================= Start of DOCUMENT LIST DUMP ==========================
+00062|
+00063|
+00064|TEXT COMPONENT: Pos(L,C)=(1,1).
+00065|
+00066|-- Start of Text Scrap List --
+00067|Text scrap[Grey]="SC06: Test FunnelWeb on a file whose last line is not terminated properly<010>
+00068|with an end of line marker.<010>
+00069|<010>
+00070|Here is the improper termination!----><010>
+00071|"
+00072|--- End of Text Scrap List ---
+00073|
+00074|
+00075|========================== End of DOCUMENT LIST DUMP ===========================
+00076|
+00077|E: No macros defined.
+00078|E: No output files specified.
+00079|
+00080|Global Local| Input File
+00081|------------+-------------------------------------------------------------------
+00082| 1 1| SC06: Test FunnelWeb on a file whose last line is not terminated properly
+00083| 2 2| with an end of line marker.
+00084| 3 3|
+00085| 4 4| Here is the improper termination!---->
+00086| | <End-Of-File>
+00087| Warning|.^The last line of the input file was terminated by EOF.
+00088| |.^An EOL was inserted at the end of the last line.
+00089|------------+-------------------------------------------------------------------
+00090|
+00091|There were 2 Errors and 1 Warning.
+ +-----
+
+ +-----
+00118|Many Calls? : Yes.
+00119|Output File?: No.
+00120|Automatic Line Directive Macro?: No.
+00121|Call list :
+00122|Macro body :
+00123|
+00124|--Start of List of Body Parts--
+00125|This macro has 1 body part.
+00126|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00127|
+00128|---- Start of Expression ----
+00129|
+00130|--- Start Special Function ---
+00131|---- End Special Function ----
+00132|
+00133|----- End of Expression -----
+00134|
+00135|---End of List of Body Parts---
+00136|
+00137|-------------------- End of Macro Dump ---------------------
+00138|
+00139|
+00140|
+00141|=========================== End of MACRO TABLE DUMP ============================
+00142|
+00143|
+00144|========================= Start of DOCUMENT LIST DUMP ==========================
+00145|
+00146|
+00147|TEXT COMPONENT: Pos(L,C)=(1,1).
+00148|
+00149|-- Start of Text Scrap List --
+00150|Text scrap[Grey]="SC06: Test FunnelWeb on a file whose last line is not terminated properly<010>
+00151|with an end of line marker.<010>
+00152|<010>
+00153|"
+00154|--- End of Text Scrap List ---
+00155|
+00156|
+00157|========================== End of DOCUMENT LIST DUMP ===========================
+00158|
+00159|E: No output files specified.
+00160|
+00161|Global Local| Input File
+00162|------------+-------------------------------------------------------------------
+00163|.................
+00164|------------+-------------------------------------------------------------------
+00165|
+00166|There was 1 Error.
+ +-----
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc07.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc07.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc08.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc08.lis".
+
+ +-----
+00066|------------------- Start of Macro Dump --------------------
+00067|Macro Name : "#file"
+00068|Defined? : Yes.
+00069|Parameters : 0
+00070|Additive? : No.
+00071|Zero Calls? : Yes.
+00072|Many Calls? : Yes.
+00073|Output File?: No.
+00074|Automatic Line Directive Macro?: No.
+00075|Call list :
+00076|Macro body :
+00077|
+00078|--Start of List of Body Parts--
+00079|This macro has 1 body part.
+00080|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00081|
+00082|---- Start of Expression ----
+00083|
+00084|--- Start Special Function ---
+00085|---- End Special Function ----
+00086|
+00087|----- End of Expression -----
+00088|
+00089|---End of List of Body Parts---
+00090|
+00091|-------------------- End of Macro Dump ---------------------
+00092|
+00093|
+00094|
+00095|------------------- Start of Macro Dump --------------------
+00096|Macro Name : "#line"
+00097|Defined? : Yes.
+00098|Parameters : 0
+00099|Additive? : No.
+00100|Zero Calls? : Yes.
+00101|Many Calls? : Yes.
+00102|Output File?: No.
+00103|Automatic Line Directive Macro?: No.
+00104|Call list :
+00105|Macro body :
+00106|
+00107|--Start of List of Body Parts--
+00108|This macro has 1 body part.
+00109|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00110|
+00111|---- Start of Expression ----
+00112|
+00113|--- Start Special Function ---
+00114|---- End Special Function ----
+00115|
+00116|----- End of Expression -----
+00117|
+00118|---End of List of Body Parts---
+00119|
+00120|-------------------- End of Macro Dump ---------------------
+00121|
+00122|
+00123|
+00124|------------------- Start of Macro Dump --------------------
+00125|Macro Name : "#timestamp"
+00126|Defined? : Yes.
+00127|Parameters : 0
+00128|Additive? : No.
+00129|Zero Calls? : Yes.
+ +-----
+00066|=========================== End of MACRO TABLE DUMP ============================
+00067|
+00068|
+00069|========================= Start of DOCUMENT LIST DUMP ==========================
+00070|
+00071|
+00072|TEXT COMPONENT: Pos(L,C)=(1,1).
+00073|
+00074|-- Start of Text Scrap List --
+00075|Text scrap[Grey]="SC08: Detection of trailing spaces.<010>
+00076|<010>
+00077|This line has zero trailing spaces |<010>
+00078|This line has one trailing space | <010>
+00079|This line has two trailing spaces | <010>
+00080|This line has three trailing spaces | <010>
+00081|"
+00082|--- End of Text Scrap List ---
+00083|
+00084|
+00085|========================== End of DOCUMENT LIST DUMP ===========================
+00086|
+00087|E: No macros defined.
+00088|E: No output files specified.
+00089|
+00090|Global Local| Input File
+00091|------------+-------------------------------------------------------------------
+00092| 1 1| SC08: Detection of trailing spaces.
+00093| 2 2|
+00094| 3 3| This line has zero trailing spaces |
+00095| 4 4| This line has one trailing space |
+00096| Warning|......................................^Line has trailing spaces up to and including this space.
+00097| 5 5| This line has two trailing spaces |
+00098| Warning|.......................................^Line has trailing spaces up to and including this space.
+00099| 6 6| This line has three trailing spaces |
+00100| Warning|........................................^Line has trailing spaces up to and including this space.
+00101| | <End-Of-File>
+00102|------------+-------------------------------------------------------------------
+00103|
+00104|There were 2 Errors and 3 Warnings.
+ +-----
+
+ +-----
+00130|Many Calls? : Yes.
+00131|Output File?: No.
+00132|Automatic Line Directive Macro?: No.
+00133|Call list :
+00134|Macro body :
+00135|
+00136|--Start of List of Body Parts--
+00137|This macro has 1 body part.
+00138|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00139|
+00140|---- Start of Expression ----
+00141|
+00142|--- Start Special Function ---
+00143|---- End Special Function ----
+00144|
+00145|----- End of Expression -----
+00146|
+00147|---End of List of Body Parts---
+00148|
+00149|-------------------- End of Macro Dump ---------------------
+00150|
+00151|
+00152|
+00153|=========================== End of MACRO TABLE DUMP ============================
+00154|
+00155|
+00156|========================= Start of DOCUMENT LIST DUMP ==========================
+00157|
+00158|
+00159|TEXT COMPONENT: Pos(L,C)=(1,1).
+00160|
+00161|-- Start of Text Scrap List --
+00162|Text scrap[Grey]="SC08: Detection of trailing spaces.<010>
+00163|<010>
+00164|This line has zero trailing spaces |<010>
+00165|This line has one trailing space | <010>
+00166|This line has two trailing spaces | <010>
+00167|This line has three trailing spaces | <010>
+00168|"
+00169|--- End of Text Scrap List ---
+00170|
+00171|
+00172|========================== End of DOCUMENT LIST DUMP ===========================
+00173|
+00174|E: No output files specified.
+00175|
+00176|Global Local| Input File
+00177|------------+-------------------------------------------------------------------
+00178| 1 1| SC08: Detection of trailing spaces.
+00179| 2 2|
+00180| 3 3| This line has zero trailing spaces |
+00181| 4 4| This line has one trailing space |
+00182| Warning|......................................^Line has trailing spaces up to and including this space.
+00183| 5 5| This line has two trailing spaces |
+00184| Warning|.......................................^Line has trailing spaces up to and including this space.
+00185| 6 6| This line has three trailing spaces |
+00186| Warning|........................................^Line has trailing spaces up to and including this space.
+00187| | <End-Of-File>
+00188|------------+-------------------------------------------------------------------
+00189|
+00190|There was 1 Error and 3 Warnings.
+ +-----
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc09.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc09.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc10.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc10.lis".
+
+ +-----
+00752| |......^ @p typesetter = none | tex | hypertext | html
+00753| |......^ @p no_doc_header
+00754| |......^ @p raw_macro_and_section_names
+00755| |......^ @p ignore_text_after_special_minus
+00756| |......^ @p no_paragraph_markups
+00757| |......^ @p declare_source_code_type "<name>"
+00758| |......^ @p automatic_line_directive_macro = "<name>"
+00759| |......^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+00760| |......^ @p #line_offset = <num>
+00761| |......^ @p #line_depth = <num>
+ +-----
+00752| |......^ @p typesetter = none | tex
+ +-----
+
+ +-----
+00833| |......^ @p typesetter = none | tex | hypertext | html
+00834| |......^ @p no_doc_header
+00835| |......^ @p raw_macro_and_section_names
+00836| |......^ @p ignore_text_after_special_minus
+00837| |......^ @p no_paragraph_markups
+00838| |......^ @p declare_source_code_type "<name>"
+00839| |......^ @p automatic_line_directive_macro = "<name>"
+00840| |......^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+00841| |......^ @p #line_offset = <num>
+00842| |......^ @p #line_depth = <num>
+ +-----
+00824| |......^ @p typesetter = none | tex
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc11.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc11.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc12.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc12.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc13.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc13.lis".
+
+ +-----
+00118|| 2E 0A 0A | ... |
+ +-----
+00118|| 2E 0A 0A 48 65 72 65 20 69 73 20 74 68 65 20 69 | ...Here is the i |
+00119|| 6D 70 72 6F 70 65 72 20 74 65 72 6D 69 6E 61 74 | mproper terminat |
+00120|| 69 6F 6E 21 2D 2D 2D 2D 3E | ion!----> |
+ +-----
+
+ +-----
+00192|00033 00026| After include<010>
+00193|00034 00027| <010>
+00194|00035 00028| 6. Include file is ordinary.<010>
+00195|00036 00029| Before include<010>
+00196|00037 00030| @i sc13f<010>
+00197|00038 00001| This is the include file for tests SC13.6 and SC13.7.<010>
+00198|00039 00002| There are only two lines, and this is the second one.<010>
+00199|00040 00031| After include<010>
+00200|00041 00032| <010>
+00201|00042 00033| 7. Test upper case I and file extension inheritance.<010>
+00202|00043 00034| Before include<010>
+00203|00044 00035| @I sc13f<010>
+00204|00045 00001| This is the include file for tests SC13.6 and SC13.7.<010>
+00205|00046 00002| There are only two lines, and this is the second one.<010>
+00206|00047 00036| After include<010>
+00207|00048 00037| <010>
+00208|00049 00038| End of test File.<010>
+00209|00050 00039| <End-Of-File><010>
+ +-----
+00194|00033 00004| Here is the improper termination!----><010>
+00195|00034 00026| After include<010>
+00196|00035 00027| <010>
+00197|00036 00028| 6. Include file is ordinary.<010>
+00198|00037 00029| Before include<010>
+00199|00038 00030| @i sc13f<010>
+00200|00039 00001| This is the include file for tests SC13.6 and SC13.7.<010>
+00201|00040 00002| There are only two lines, and this is the second one.<010>
+00202|00041 00031| After include<010>
+00203|00042 00032| <010>
+00204|00043 00033| 7. Test upper case I and file extension inheritance.<010>
+00205|00044 00034| Before include<010>
+00206|00045 00035| @I sc13f<010>
+00207|00046 00001| This is the include file for tests SC13.6 and SC13.7.<010>
+00208|00047 00002| There are only two lines, and this is the second one.<010>
+00209|00048 00036| After include<010>
+00210|00049 00037| <010>
+00211|00050 00038| End of test File.<010>
+00212|00051 00039| <End-Of-File><010>
+ +-----
+
+ +-----
+00258|"
+00259|0033[01]: Text. Text scrap[Grey]="After include<010>
+ +-----
+00261|Here is the improper termination!----><010>
+00262|"
+00263|0034[01]: Text. Text scrap[Grey]="After include<010>
+ +-----
+
+ +-----
+00264|0038[01]: Text. Text scrap[Grey]="This is the include file for tests SC13.6 and SC13.7.<010>
+00265|There are only two lines, and this is the second one.<010>
+00266|"
+00267|0040[01]: Text. Text scrap[Grey]="After include<010>
+ +-----
+00268|0039[01]: Text. Text scrap[Grey]="This is the include file for tests SC13.6 and SC13.7.<010>
+00269|There are only two lines, and this is the second one.<010>
+00270|"
+00271|0041[01]: Text. Text scrap[Grey]="After include<010>
+ +-----
+
+ +-----
+00272|0045[01]: Text. Text scrap[Grey]="This is the include file for tests SC13.6 and SC13.7.<010>
+00273|There are only two lines, and this is the second one.<010>
+00274|"
+00275|0047[01]: Text. Text scrap[Grey]="After include<010>
+ +-----
+00276|0046[01]: Text. Text scrap[Grey]="This is the include file for tests SC13.6 and SC13.7.<010>
+00277|There are only two lines, and this is the second one.<010>
+00278|"
+00279|0048[01]: Text. Text scrap[Grey]="After include<010>
+ +-----
+
+ +-----
+00279|0050[01]: End Of File.
+ +-----
+00283|0051[01]: End Of File.
+ +-----
+
+ +-----
+00286|------------------- Start of Macro Dump --------------------
+00287|Macro Name : "#file"
+00288|Defined? : Yes.
+00289|Parameters : 0
+00290|Additive? : No.
+00291|Zero Calls? : Yes.
+00292|Many Calls? : Yes.
+00293|Output File?: No.
+00294|Automatic Line Directive Macro?: No.
+00295|Call list :
+00296|Macro body :
+00297|
+00298|--Start of List of Body Parts--
+00299|This macro has 1 body part.
+00300|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00301|
+00302|---- Start of Expression ----
+00303|
+00304|--- Start Special Function ---
+00305|---- End Special Function ----
+00306|
+00307|----- End of Expression -----
+00308|
+00309|---End of List of Body Parts---
+00310|
+00311|-------------------- End of Macro Dump ---------------------
+00312|
+00313|
+00314|
+00315|------------------- Start of Macro Dump --------------------
+00316|Macro Name : "#line"
+00317|Defined? : Yes.
+00318|Parameters : 0
+00319|Additive? : No.
+00320|Zero Calls? : Yes.
+00321|Many Calls? : Yes.
+00322|Output File?: No.
+00323|Automatic Line Directive Macro?: No.
+00324|Call list :
+00325|Macro body :
+00326|
+00327|--Start of List of Body Parts--
+00328|This macro has 1 body part.
+00329|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00330|
+00331|---- Start of Expression ----
+00332|
+00333|--- Start Special Function ---
+00334|---- End Special Function ----
+00335|
+00336|----- End of Expression -----
+00337|
+00338|---End of List of Body Parts---
+00339|
+00340|-------------------- End of Macro Dump ---------------------
+00341|
+00342|
+00343|
+00344|------------------- Start of Macro Dump --------------------
+00345|Macro Name : "#timestamp"
+00346|Defined? : Yes.
+00347|Parameters : 0
+00348|Additive? : No.
+00349|Zero Calls? : Yes.
+ +-----
+00290|=========================== End of MACRO TABLE DUMP ============================
+00291|
+00292|
+00293|========================= Start of DOCUMENT LIST DUMP ==========================
+00294|
+00295|
+00296|TEXT COMPONENT: Pos(L,C)=(1,1).
+00297|
+00298|-- Start of Text Scrap List --
+00299|Text scrap[Grey]="SC13: Various kinds of include file.<010>
+00300|<010>
+00301|1. Include file is empty.<010>
+00302|Before include<010>
+00303|"
+00304|Text scrap[Grey]="After include<010>
+00305|<010>
+00306|2. Include file contains a single blank line.<010>
+00307|Before include<010>
+00308|"
+00309|Text scrap[White]="<010>
+00310|"
+00311|Text scrap[Grey]="After include<010>
+00312|<010>
+00313|3. Include file contains two blank lines.<010>
+00314|Before include<010>
+00315|"
+00316|Text scrap[White]="<010>
+00317|<010>
+00318|"
+00319|Text scrap[Grey]="After include<010>
+00320|<010>
+00321|4. Include file contains a single line with text on it.<010>
+00322|Before include<010>
+00323|"
+00324|Text scrap[Grey]="This is the include file for test SC13d. Just a file containing one line.<010>
+00325|"
+00326|Text scrap[Grey]="After include<010>
+00327|<010>
+00328|5. Include file's last line is not properly terminated.<010>
+00329|Before include<010>
+00330|"
+00331|Text scrap[Grey]="This is the include file for test SC13e. The test is to see how FunnelWeb<010>
+00332|copes with an include file that has an improperly terminated last line.<010>
+00333|<010>
+00334|Here is the improper termination!----><010>
+00335|"
+00336|Text scrap[Grey]="After include<010>
+00337|<010>
+00338|6. Include file is ordinary.<010>
+00339|Before include<010>
+00340|"
+00341|Text scrap[Grey]="This is the include file for tests SC13.6 and SC13.7.<010>
+00342|There are only two lines, and this is the second one.<010>
+00343|"
+00344|Text scrap[Grey]="After include<010>
+00345|<010>
+00346|7. Test upper case I and file extension inheritance.<010>
+00347|Before include<010>
+00348|"
+00349|Text scrap[Grey]="This is the include file for tests SC13.6 and SC13.7.<010>
+00350|There are only two lines, and this is the second one.<010>
+00351|"
+00352|Text scrap[Grey]="After include<010>
+00353|<010>
+ +-----
+
+ +-----
+00350|Many Calls? : Yes.
+00351|Output File?: No.
+00352|Automatic Line Directive Macro?: No.
+00353|Call list :
+00354|Macro body :
+00355|
+00356|--Start of List of Body Parts--
+00357|This macro has 1 body part.
+00358|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00359|
+00360|---- Start of Expression ----
+00361|
+00362|--- Start Special Function ---
+00363|---- End Special Function ----
+00364|
+00365|----- End of Expression -----
+00366|
+00367|---End of List of Body Parts---
+00368|
+00369|-------------------- End of Macro Dump ---------------------
+00370|
+00371|
+00372|
+00373|=========================== End of MACRO TABLE DUMP ============================
+00374|
+00375|
+00376|========================= Start of DOCUMENT LIST DUMP ==========================
+00377|
+00378|
+00379|TEXT COMPONENT: Pos(L,C)=(1,1).
+00380|
+00381|-- Start of Text Scrap List --
+00382|Text scrap[Grey]="SC13: Various kinds of include file.<010>
+00383|<010>
+00384|1. Include file is empty.<010>
+00385|Before include<010>
+00386|"
+00387|Text scrap[Grey]="After include<010>
+00388|<010>
+00389|2. Include file contains a single blank line.<010>
+00390|Before include<010>
+00391|"
+00392|Text scrap[White]="<010>
+00393|"
+00394|Text scrap[Grey]="After include<010>
+00395|<010>
+00396|3. Include file contains two blank lines.<010>
+00397|Before include<010>
+00398|"
+00399|Text scrap[White]="<010>
+00400|<010>
+00401|"
+00402|Text scrap[Grey]="After include<010>
+00403|<010>
+00404|4. Include file contains a single line with text on it.<010>
+00405|Before include<010>
+00406|"
+00407|Text scrap[Grey]="This is the include file for test SC13d. Just a file containing one line.<010>
+00408|"
+00409|Text scrap[Grey]="After include<010>
+00410|<010>
+00411|5. Include file's last line is not properly terminated.<010>
+00412|Before include<010>
+00413|"
+ +-----
+00354|End of test File.<010>
+00355|"
+00356|--- End of Text Scrap List ---
+00357|
+00358|
+00359|========================== End of DOCUMENT LIST DUMP ===========================
+00360|
+00361|E: No macros defined.
+00362|E: No output files specified.
+00363|
+00364|Global Local| Input File
+00365|------------+-------------------------------------------------------------------
+00366| 1 1| SC13: Various kinds of include file.
+00367| 2 2|
+00368| 3 3| 1. Include file is empty.
+00369| 4 4| Before include
+00370| 5 5| @i sc13a
+00371| Warning|.^Include file is empty (not a byte in syte)!
+00372| 6 6| After include
+00373| 7 7|
+00374| 8 8| 2. Include file contains a single blank line.
+00375| 9 9| Before include
+00376| 10 10| @i sc13b
+00377| 11 1|
+00378| 12 11| After include
+00379| 13 12|
+00380| 14 13| 3. Include file contains two blank lines.
+00381| 15 14| Before include
+00382| 16 15| @i sc13c
+00383| 17 1|
+00384| 18 2|
+00385| 19 16| After include
+00386| 20 17|
+00387| 21 18| 4. Include file contains a single line with text on it.
+00388| 22 19| Before include
+00389| 23 20| @i sc13d
+00390| 24 1| This is the include file for test SC13d. Just a file containing one line.
+00391| 25 21| After include
+00392| 26 22|
+00393| 27 23| 5. Include file's last line is not properly terminated.
+00394| 28 24| Before include
+00395| 29 25| @i sc13e
+00396| 30 1| This is the include file for test SC13e. The test is to see how FunnelWeb
+00397| 31 2| copes with an include file that has an improperly terminated last line.
+00398| 32 3|
+00399| 33 4| Here is the improper termination!---->
+00400| 34 26| After include
+00401| Warning|.^The last line of the include file was terminated by EOF.
+00402| |.^An EOL was inserted at the end of the last line.
+00403| 35 27|
+00404| 36 28| 6. Include file is ordinary.
+00405| 37 29| Before include
+00406| 38 30| @i sc13f
+00407| 39 1| This is the include file for tests SC13.6 and SC13.7.
+00408| 40 2| There are only two lines, and this is the second one.
+00409| 41 31| After include
+00410| 42 32|
+00411| 43 33| 7. Test upper case I and file extension inheritance.
+00412| 44 34| Before include
+00413| 45 35| @I sc13f
+00414| 46 1| This is the include file for tests SC13.6 and SC13.7.
+00415| 47 2| There are only two lines, and this is the second one.
+00416| 48 36| After include
+00417| 49 37|
+ +-----
+
+ +-----
+00414|Text scrap[Grey]="This is the include file for test SC13e. The test is to see how FunnelWeb<010>
+00415|copes with an include file that has an improperly terminated last line.<010>
+00416|<010>
+00417|"
+00418|Text scrap[Grey]="After include<010>
+00419|<010>
+00420|6. Include file is ordinary.<010>
+00421|Before include<010>
+00422|"
+00423|Text scrap[Grey]="This is the include file for tests SC13.6 and SC13.7.<010>
+00424|There are only two lines, and this is the second one.<010>
+00425|"
+00426|Text scrap[Grey]="After include<010>
+00427|<010>
+00428|7. Test upper case I and file extension inheritance.<010>
+00429|Before include<010>
+00430|"
+00431|Text scrap[Grey]="This is the include file for tests SC13.6 and SC13.7.<010>
+00432|There are only two lines, and this is the second one.<010>
+00433|"
+00434|Text scrap[Grey]="After include<010>
+00435|<010>
+00436|End of test File.<010>
+00437|"
+00438|--- End of Text Scrap List ---
+00439|
+00440|
+00441|========================== End of DOCUMENT LIST DUMP ===========================
+00442|
+00443|E: No output files specified.
+00444|
+00445|Global Local| Input File
+00446|------------+-------------------------------------------------------------------
+00447| 1 1| SC13: Various kinds of include file.
+00448| 2 2|
+00449| 3 3| 1. Include file is empty.
+00450| 4 4| Before include
+00451| 5 5| @i sc13a
+00452| Warning|.^Include file is empty (not a byte in syte)!
+00453| 6 6| After include
+00454| 7 7|
+00455| 8 8| 2. Include file contains a single blank line.
+00456| 9 9| Before include
+00457| 10 10| @i sc13b
+00458| 11 1|
+00459| 12 11| After include
+00460| 13 12|
+00461| 14 13| 3. Include file contains two blank lines.
+00462| 15 14| Before include
+00463| 16 15| @i sc13c
+00464| 17 1|
+00465| 18 2|
+00466| 19 16| After include
+00467| 20 17|
+00468| 21 18| 4. Include file contains a single line with text on it.
+00469| 22 19| Before include
+00470| 23 20| @i sc13d
+00471| 24 1| This is the include file for test SC13d. Just a file containing one line.
+00472| 25 21| After include
+00473| 26 22|
+00474| 27 23| 5. Include file's last line is not properly terminated.
+00475| 28 24| Before include
+00476| 29 25| @i sc13e
+00477| 30 1| This is the include file for test SC13e. The test is to see how FunnelWeb
+ +-----
+00418| 50 38| End of test File.
+00419| | <End-Of-File>
+00420|------------+-------------------------------------------------------------------
+00421|
+00422|There were 2 Errors and 2 Warnings.
+ +-----
+
+ +-----
+00478| 31 2| copes with an include file that has an improperly terminated last line.
+00479| 32 3|
+00480| 33 26| After include
+00481| 34 27|
+00482| 35 28| 6. Include file is ordinary.
+00483| 36 29| Before include
+00484| 37 30| @i sc13f
+00485| 38 1| This is the include file for tests SC13.6 and SC13.7.
+00486| 39 2| There are only two lines, and this is the second one.
+00487| 40 31| After include
+00488| 41 32|
+00489| 42 33| 7. Test upper case I and file extension inheritance.
+00490| 43 34| Before include
+00491| 44 35| @I sc13f
+00492| 45 1| This is the include file for tests SC13.6 and SC13.7.
+00493| 46 2| There are only two lines, and this is the second one.
+00494| 47 36| After include
+00495| 48 37|
+00496| 49 38| End of test File.
+00497| | <End-Of-File>
+00498|------------+-------------------------------------------------------------------
+00499|
+00500|There was 1 Error and 1 Warning.
+ +-----
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc14.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc14.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc15.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc15.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc16.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc16.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc17.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc17.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc18.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc18.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc19.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc19.lis".
+
+ +-----
+00083| Error|...........................^Suppress EOL sequence is legal only at the end of a line
+00084| |...........................^unless `@p ignore_text_after_special_minus' is used.
+ +-----
+00083| Error|...........................^Suppress EOL sequence is legal only at the end of a line.
+ +-----
+
+ +-----
+00089| Error|......^Suppress EOL sequence is legal only at the end of a line
+00090| |......^unless `@p ignore_text_after_special_minus' is used.
+ +-----
+00088| Error|......^Suppress EOL sequence is legal only at the end of a line.
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc20.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc20.lis".
+
+ +-----
+00079|------------------- Start of Macro Dump --------------------
+00080|Macro Name : "#file"
+00081|Defined? : Yes.
+00082|Parameters : 0
+00083|Additive? : No.
+00084|Zero Calls? : Yes.
+00085|Many Calls? : Yes.
+00086|Output File?: No.
+00087|Automatic Line Directive Macro?: No.
+00088|Call list :
+00089|Macro body :
+00090|
+00091|--Start of List of Body Parts--
+00092|This macro has 1 body part.
+00093|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00094|
+00095|---- Start of Expression ----
+00096|
+00097|--- Start Special Function ---
+00098|---- End Special Function ----
+00099|
+00100|----- End of Expression -----
+00101|
+00102|---End of List of Body Parts---
+00103|
+00104|-------------------- End of Macro Dump ---------------------
+00105|
+00106|
+00107|
+00108|------------------- Start of Macro Dump --------------------
+00109|Macro Name : "#line"
+00110|Defined? : Yes.
+00111|Parameters : 0
+00112|Additive? : No.
+00113|Zero Calls? : Yes.
+00114|Many Calls? : Yes.
+00115|Output File?: No.
+00116|Automatic Line Directive Macro?: No.
+00117|Call list :
+00118|Macro body :
+00119|
+00120|--Start of List of Body Parts--
+00121|This macro has 1 body part.
+00122|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00123|
+00124|---- Start of Expression ----
+00125|
+00126|--- Start Special Function ---
+00127|---- End Special Function ----
+00128|
+00129|----- End of Expression -----
+00130|
+00131|---End of List of Body Parts---
+00132|
+00133|-------------------- End of Macro Dump ---------------------
+00134|
+00135|
+00136|
+00137|------------------- Start of Macro Dump --------------------
+00138|Macro Name : "#timestamp"
+00139|Defined? : Yes.
+00140|Parameters : 0
+00141|Additive? : No.
+00142|Zero Calls? : Yes.
+ +-----
+00079|=========================== End of MACRO TABLE DUMP ============================
+00080|
+00081|
+00082|========================= Start of DOCUMENT LIST DUMP ==========================
+00083|
+00084|
+00085|TEXT COMPONENT: Pos(L,C)=(1,1).
+00086|
+00087|-- Start of Text Scrap List --
+00088|Text scrap[Grey]="SC20: Test "
+00089|Text scrap[Grey]="<010>
+00090|1. Test at the start of a line.<010>
+00091|<010>
+00092|"
+00093|Text scrap[Grey]="<010>
+00094|2. Test halfway through a line.<010>
+00095|<010>
+00096|This is a line "
+00097|Text scrap[White]="<010>
+00098|"
+00099|--- End of Text Scrap List ---
+00100|
+00101|
+00102|========================== End of DOCUMENT LIST DUMP ===========================
+00103|
+00104|E: No macros defined.
+00105|E: No output files specified.
+00106|
+00107|Global Local| Input File
+00108|------------+-------------------------------------------------------------------
+00109|.................
+00110|------------+-------------------------------------------------------------------
+00111|
+00112|There were 2 Errors.
+ +-----
+
+ +-----
+00143|Many Calls? : Yes.
+00144|Output File?: No.
+00145|Automatic Line Directive Macro?: No.
+00146|Call list :
+00147|Macro body :
+00148|
+00149|--Start of List of Body Parts--
+00150|This macro has 1 body part.
+00151|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00152|
+00153|---- Start of Expression ----
+00154|
+00155|--- Start Special Function ---
+00156|---- End Special Function ----
+00157|
+00158|----- End of Expression -----
+00159|
+00160|---End of List of Body Parts---
+00161|
+00162|-------------------- End of Macro Dump ---------------------
+00163|
+00164|
+00165|
+00166|=========================== End of MACRO TABLE DUMP ============================
+00167|
+00168|
+00169|========================= Start of DOCUMENT LIST DUMP ==========================
+00170|
+00171|
+00172|TEXT COMPONENT: Pos(L,C)=(1,1).
+00173|
+00174|-- Start of Text Scrap List --
+00175|Text scrap[Grey]="SC20: Test "
+00176|Text scrap[Grey]="<010>
+00177|1. Test at the start of a line.<010>
+00178|<010>
+00179|"
+00180|Text scrap[Grey]="<010>
+00181|2. Test halfway through a line.<010>
+00182|<010>
+00183|This is a line "
+00184|Text scrap[White]="<010>
+00185|"
+00186|--- End of Text Scrap List ---
+00187|
+00188|
+00189|========================== End of DOCUMENT LIST DUMP ===========================
+00190|
+00191|E: No output files specified.
+00192|
+00193|Global Local| Input File
+00194|------------+-------------------------------------------------------------------
+00195|.................
+00196|------------+-------------------------------------------------------------------
+00197|
+00198|There was 1 Error.
+ +-----
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc21.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc21.lis".
+
+ +-----
+00172| |....^ @p typesetter = none | tex | hypertext | html
+00173| |....^ @p no_doc_header
+00174| |....^ @p raw_macro_and_section_names
+00175| |....^ @p ignore_text_after_special_minus
+00176| |....^ @p no_paragraph_markups
+00177| |....^ @p declare_source_code_type "<name>"
+00178| |....^ @p automatic_line_directive_macro = "<name>"
+00179| |....^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+00180| |....^ @p #line_offset = <num>
+00181| |....^ @p #line_depth = <num>
+ +-----
+00172| |....^ @p typesetter = none | tex
+ +-----
+
+ +-----
+00202| |.^ @p typesetter = none | tex | hypertext | html
+00203| |.^ @p no_doc_header
+00204| |.^ @p raw_macro_and_section_names
+00205| |.^ @p ignore_text_after_special_minus
+00206| |.^ @p no_paragraph_markups
+00207| |.^ @p declare_source_code_type "<name>"
+00208| |.^ @p automatic_line_directive_macro = "<name>"
+00209| |.^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+00210| |.^ @p #line_offset = <num>
+00211| |.^ @p #line_depth = <num>
+ +-----
+00193| |.^ @p typesetter = none | tex
+ +-----
+
+ +-----
+00229| |.^ @p typesetter = none | tex | hypertext | html
+00230| |.^ @p no_doc_header
+00231| |.^ @p raw_macro_and_section_names
+00232| |.^ @p ignore_text_after_special_minus
+00233| |.^ @p no_paragraph_markups
+00234| |.^ @p declare_source_code_type "<name>"
+00235| |.^ @p automatic_line_directive_macro = "<name>"
+00236| |.^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+00237| |.^ @p #line_offset = <num>
+00238| |.^ @p #line_depth = <num>
+ +-----
+00211| |.^ @p typesetter = none | tex
+ +-----
+
+ +-----
+00261| |.^ @p typesetter = none | tex | hypertext | html
+00262| |.^ @p no_doc_header
+00263| |.^ @p raw_macro_and_section_names
+00264| |.^ @p ignore_text_after_special_minus
+00265| |.^ @p no_paragraph_markups
+00266| |.^ @p declare_source_code_type "<name>"
+00267| |.^ @p automatic_line_directive_macro = "<name>"
+00268| |.^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+00269| |.^ @p #line_offset = <num>
+00270| |.^ @p #line_depth = <num>
+ +-----
+00234| |.^ @p typesetter = none | tex
+ +-----
+
+ +-----
+00283| |.^ @p typesetter = none | tex | hypertext | html
+00284| |.^ @p no_doc_header
+00285| |.^ @p raw_macro_and_section_names
+00286| |.^ @p ignore_text_after_special_minus
+00287| |.^ @p no_paragraph_markups
+00288| |.^ @p declare_source_code_type "<name>"
+00289| |.^ @p automatic_line_directive_macro = "<name>"
+00290| |.^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+00291| |.^ @p #line_offset = <num>
+00292| |.^ @p #line_depth = <num>
+ +-----
+00247| |.^ @p typesetter = none | tex
+ +-----
+
+ +-----
+00329| |.^ @p typesetter = none | tex | hypertext | html
+00330| |.^ @p no_doc_header
+00331| |.^ @p raw_macro_and_section_names
+00332| |.^ @p ignore_text_after_special_minus
+00333| |.^ @p no_paragraph_markups
+00334| |.^ @p declare_source_code_type "<name>"
+00335| |.^ @p automatic_line_directive_macro = "<name>"
+00336| |.^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+00337| |.^ @p #line_offset = <num>
+00338| |.^ @p #line_depth = <num>
+ +-----
+00284| |.^ @p typesetter = none | tex
+ +-----
+
+ +-----
+00357| |.^ @p typesetter = none | tex | hypertext | html
+00358| |.^ @p no_doc_header
+00359| |.^ @p raw_macro_and_section_names
+00360| |.^ @p ignore_text_after_special_minus
+00361| |.^ @p no_paragraph_markups
+00362| |.^ @p declare_source_code_type "<name>"
+00363| |.^ @p automatic_line_directive_macro = "<name>"
+00364| |.^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+00365| |.^ @p #line_offset = <num>
+00366| |.^ @p #line_depth = <num>
+ +-----
+00303| |.^ @p typesetter = none | tex
+ +-----
+
+ +-----
+00387| |.^ @p typesetter = none | tex | hypertext | html
+00388| |.^ @p no_doc_header
+00389| |.^ @p raw_macro_and_section_names
+00390| |.^ @p ignore_text_after_special_minus
+00391| |.^ @p no_paragraph_markups
+00392| |.^ @p declare_source_code_type "<name>"
+00393| |.^ @p automatic_line_directive_macro = "<name>"
+00394| |.^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+00395| |.^ @p #line_offset = <num>
+00396| |.^ @p #line_depth = <num>
+ +-----
+00324| |.^ @p typesetter = none | tex
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc22.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc22.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc23.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc23.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc24.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc24.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc25.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc25.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc26.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc26.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc27.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc27.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc28.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc28.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/sc29.lis"
+ with "/usr/var/tmp/funnelweb/answers/sc29.lis".
+
+ +-----
+00120| |.^The correct format is: "@p typesetter = none|tex"
+00121| |.^ or for hypertext "@p typesetter = hypertext|html".
+ +-----
+00120| |.^The correct format is: "@p typesetter = none|tex".
+ +-----
+
+ +-----
+00125| |.^The correct format is: "@p typesetter = none|tex"
+00126| |.^ or for hypertext "@p typesetter = hypertext|html".
+ +-----
+00124| |.^The correct format is: "@p typesetter = none|tex".
+ +-----
+
+ +-----
+00130| |.^The correct format is: "@p typesetter = none|tex"
+00131| |.^ or for hypertext "@p typesetter = hypertext|html".
+ +-----
+00128| |.^The correct format is: "@p typesetter = none|tex".
+ +-----
+
+ +-----
+00136| |.^The correct format is: "@p typesetter = none|tex"
+00137| |.^ or for hypertext "@p typesetter = hypertext|html".
+ +-----
+00133| |.^The correct format is: "@p typesetter = none|tex".
+ +-----
+
+ +-----
+00143| |.^The correct format is: "@p typesetter = none|tex"
+00144| |.^ or for hypertext "@p typesetter = hypertext|html".
+00145| |.^Pragma ignored.
+00146| Error|.................^Expecting one of:
+00147| Error|.................^ (i) "none"
+00148| Error|.................^ (ii) "tex"
+00149| Error|.................^ (iii) "hypertext"
+00150| Error|.................^ (iv) "html".
+ +-----
+00139| |.^The correct format is: "@p typesetter = none|tex".
+00140| |.^Pragma ignored.
+00141| Error|.................^Expecting either "none" or "tex".
+ +-----
+
+ +-----
+00170|There were 10 Errors.
+ +-----
+00161|There were 6 Errors.
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/pr01.lis"
+ with "/usr/var/tmp/funnelweb/answers/pr01.lis".
+
+ +-----
+00215|------------------- Start of Macro Dump --------------------
+00216|Macro Name : "#file"
+00217|Defined? : Yes.
+00218|Parameters : 0
+00219|Additive? : No.
+00220|Zero Calls? : Yes.
+00221|Many Calls? : Yes.
+00222|Output File?: No.
+00223|Automatic Line Directive Macro?: No.
+00224|Call list :
+00225|Macro body :
+00226|
+00227|--Start of List of Body Parts--
+00228|This macro has 1 body part.
+00229|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00230|
+00231|---- Start of Expression ----
+00232|
+00233|--- Start Special Function ---
+00234|---- End Special Function ----
+00235|
+00236|----- End of Expression -----
+00237|
+00238|---End of List of Body Parts---
+00239|
+00240|-------------------- End of Macro Dump ---------------------
+00241|
+00242|
+00243|
+00244|------------------- Start of Macro Dump --------------------
+00245|Macro Name : "#line"
+00246|Defined? : Yes.
+00247|Parameters : 0
+00248|Additive? : No.
+00249|Zero Calls? : Yes.
+00250|Many Calls? : Yes.
+00251|Output File?: No.
+00252|Automatic Line Directive Macro?: No.
+00253|Call list :
+00254|Macro body :
+00255|
+00256|--Start of List of Body Parts--
+00257|This macro has 1 body part.
+00258|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00259|
+00260|---- Start of Expression ----
+00261|
+00262|--- Start Special Function ---
+00263|---- End Special Function ----
+00264|
+00265|----- End of Expression -----
+00266|
+00267|---End of List of Body Parts---
+00268|
+00269|-------------------- End of Macro Dump ---------------------
+00270|
+00271|
+00272|
+00273|------------------- Start of Macro Dump --------------------
+00274|Macro Name : "#timestamp"
+00275|Defined? : Yes.
+00276|Parameters : 0
+00277|Additive? : No.
+00278|Zero Calls? : Yes.
+ +-----
+00215|=========================== End of MACRO TABLE DUMP ============================
+00216|
+00217|
+00218|========================= Start of DOCUMENT LIST DUMP ==========================
+00219|
+00220|
+00221|TEXT COMPONENT: Pos(L,C)=(1,1).
+00222|
+00223|-- Start of Text Scrap List --
+00224|Text scrap[Grey]="PR01: Test the inline typesetting features.<010>
+00225|<010>
+00226|1. First we test the legal use of the "
+00227|--- End of Text Scrap List ---
+00228|
+00229|
+00230|TYPESETTER DIRECTIVE COMPONENT: Open literal.
+00231|
+00232|TEXT COMPONENT: Pos(L,C)=(3,41).
+00233|
+00234|-- Start of Text Scrap List --
+00235|Text scrap[Grey]="literal"
+00236|--- End of Text Scrap List ---
+00237|
+00238|
+00239|TYPESETTER DIRECTIVE COMPONENT: Close literal.
+00240|
+00241|TEXT COMPONENT: Pos(L,C)=(3,50).
+00242|
+00243|-- Start of Text Scrap List --
+00244|Text scrap[Grey]=" construct.<010>
+00245|<010>
+00246|2.Test "
+00247|--- End of Text Scrap List ---
+00248|
+00249|
+00250|TYPESETTER DIRECTIVE COMPONENT: Open literal.
+00251|
+00252|TYPESETTER DIRECTIVE COMPONENT:
+00253| Section "1", Section name="Error Recovery Point".
+00254|
+00255|TEXT COMPONENT: Pos(L,C)=(6,27).
+00256|
+00257|-- Start of Text Scrap List --
+00258|Text scrap[Grey]="<010>
+00259|<010>
+00260|3. Test the construct "
+00261|--- End of Text Scrap List ---
+00262|
+00263|
+00264|TYPESETTER DIRECTIVE COMPONENT: Open literal.
+00265|
+00266|TEXT COMPONENT: Pos(L,C)=(8,25).
+00267|
+00268|-- Start of Text Scrap List --
+00269|Text scrap[Grey]="across<010>
+00270| more than one line"
+00271|--- End of Text Scrap List ---
+00272|
+00273|
+00274|TYPESETTER DIRECTIVE COMPONENT: Close literal.
+00275|
+00276|TEXT COMPONENT: Pos(L,C)=(9,24).
+00277|
+00278|-- Start of Text Scrap List --
+ +-----
+
+ +-----
+00279|Many Calls? : Yes.
+00280|Output File?: No.
+00281|Automatic Line Directive Macro?: No.
+00282|Call list :
+00283|Macro body :
+00284|
+00285|--Start of List of Body Parts--
+00286|This macro has 1 body part.
+00287|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00288|
+00289|---- Start of Expression ----
+00290|
+00291|--- Start Special Function ---
+00292|---- End Special Function ----
+00293|
+00294|----- End of Expression -----
+00295|
+00296|---End of List of Body Parts---
+00297|
+00298|-------------------- End of Macro Dump ---------------------
+00299|
+00300|
+00301|
+00302|=========================== End of MACRO TABLE DUMP ============================
+00303|
+00304|
+00305|========================= Start of DOCUMENT LIST DUMP ==========================
+00306|
+00307|
+00308|TEXT COMPONENT: Pos(L,C)=(1,1).
+00309|
+00310|-- Start of Text Scrap List --
+00311|Text scrap[Grey]="PR01: Test the inline typesetting features.<010>
+00312|<010>
+00313|1. First we test the legal use of the "
+ +-----
+00279|Text scrap[Grey]=".<010>
+00280|<010>
+00281|4. Now we test the construct with non-text following it.<010>
+00282| "
+ +-----
+
+ +-----
+00319|TEXT COMPONENT: Pos(L,C)=(3,41).
+00320|
+00321|-- Start of Text Scrap List --
+00322|Text scrap[Grey]="literal"
+ +-----
+00288|TYPESETTER DIRECTIVE COMPONENT:
+00289| Section "2", Section name="Error Recovery Point".
+00290|
+00291|TEXT COMPONENT: Pos(L,C)=(13,27).
+00292|
+00293|-- Start of Text Scrap List --
+00294|Text scrap[White]="<010>
+00295| "
+ +-----
+
+ +-----
+00326|TYPESETTER DIRECTIVE COMPONENT: Close literal.
+00327|
+00328|TEXT COMPONENT: Pos(L,C)=(3,50).
+00329|
+00330|-- Start of Text Scrap List --
+00331|Text scrap[Grey]=" construct.<010>
+00332|<010>
+00333|2.Test "
+ +-----
+00299|TYPESETTER DIRECTIVE COMPONENT: Open literal.
+00300|
+00301|TEXT COMPONENT: Pos(L,C)=(14,6).
+00302|
+00303|-- Start of Text Scrap List --
+00304|Text scrap[White]=" "
+ +-----
+
+ +-----
+00337|TYPESETTER DIRECTIVE COMPONENT: Open literal.
+00338|
+00339|TYPESETTER DIRECTIVE COMPONENT:
+00340| Section "1", Section name="Error Recovery Point".
+00341|
+00342|TEXT COMPONENT: Pos(L,C)=(6,27).
+ +-----
+00308|TYPESETTER DIRECTIVE COMPONENT:
+00309| Section "3", Section name="Error Recovery Point".
+00310|
+00311|TEXT COMPONENT: Pos(L,C)=(15,27).
+ +-----
+
+ +-----
+00347|3. Test the construct "
+ +-----
+00316|5. Test the legal use of the "
+ +-----
+
+ +-----
+00351|TYPESETTER DIRECTIVE COMPONENT: Open literal.
+00352|
+00353|TEXT COMPONENT: Pos(L,C)=(8,25).
+00354|
+00355|-- Start of Text Scrap List --
+00356|Text scrap[Grey]="across<010>
+00357| more than one line"
+ +-----
+00320|TYPESETTER DIRECTIVE COMPONENT: Open emphasise.
+00321|
+00322|TEXT COMPONENT: Pos(L,C)=(17,32).
+00323|
+00324|-- Start of Text Scrap List --
+00325|Text scrap[Grey]="emphasis"
+ +-----
+
+ +-----
+00361|TYPESETTER DIRECTIVE COMPONENT: Close literal.
+00362|
+00363|TEXT COMPONENT: Pos(L,C)=(9,24).
+00364|
+00365|-- Start of Text Scrap List --
+00366|Text scrap[Grey]=".<010>
+00367|<010>
+00368|4. Now we test the construct with non-text following it.<010>
+00369| "
+ +-----
+00329|TYPESETTER DIRECTIVE COMPONENT: Close emphasise.
+00330|
+00331|TEXT COMPONENT: Pos(L,C)=(17,42).
+00332|
+00333|-- Start of Text Scrap List --
+00334|Text scrap[Grey]=" construct.<010>
+00335|<010>
+00336|6.Test "
+ +-----
+
+ +-----
+00373|TYPESETTER DIRECTIVE COMPONENT: Open literal.
+00374|
+00375|TYPESETTER DIRECTIVE COMPONENT:
+00376| Section "2", Section name="Error Recovery Point".
+00377|
+00378|TEXT COMPONENT: Pos(L,C)=(13,27).
+00379|
+00380|-- Start of Text Scrap List --
+00381|Text scrap[White]="<010>
+00382| "
+ +-----
+00340|TYPESETTER DIRECTIVE COMPONENT: Open emphasise.
+00341|
+00342|TYPESETTER DIRECTIVE COMPONENT:
+00343| Section "4", Section name="Error Recovery Point".
+00344|
+00345|TEXT COMPONENT: Pos(L,C)=(20,27).
+00346|
+00347|-- Start of Text Scrap List --
+00348|Text scrap[Grey]="<010>
+00349|<010>
+00350|7. Test the construct "
+ +-----
+
+ +-----
+00386|TYPESETTER DIRECTIVE COMPONENT: Open literal.
+00387|
+00388|TEXT COMPONENT: Pos(L,C)=(14,6).
+00389|
+00390|-- Start of Text Scrap List --
+00391|Text scrap[White]=" "
+ +-----
+00354|TYPESETTER DIRECTIVE COMPONENT: Open emphasise.
+00355|
+00356|TEXT COMPONENT: Pos(L,C)=(22,25).
+00357|
+00358|-- Start of Text Scrap List --
+00359|Text scrap[Grey]="across<010>
+00360| more than one line"
+ +-----
+
+ +-----
+00395|TYPESETTER DIRECTIVE COMPONENT:
+00396| Section "3", Section name="Error Recovery Point".
+00397|
+00398|TEXT COMPONENT: Pos(L,C)=(15,27).
+00399|
+00400|-- Start of Text Scrap List --
+00401|Text scrap[Grey]="<010>
+00402|<010>
+00403|5. Test the legal use of the "
+ +-----
+00364|TYPESETTER DIRECTIVE COMPONENT: Close emphasise.
+00365|
+00366|TEXT COMPONENT: Pos(L,C)=(23,24).
+00367|
+00368|-- Start of Text Scrap List --
+00369|Text scrap[Grey]=".<010>
+00370|<010>
+00371|8. Now we test the construct with non-text following it.<010>
+00372| "
+ +-----
+
+ +-----
+00409|TEXT COMPONENT: Pos(L,C)=(17,32).
+00410|
+00411|-- Start of Text Scrap List --
+00412|Text scrap[Grey]="emphasis"
+ +-----
+00378|TYPESETTER DIRECTIVE COMPONENT:
+00379| Section "5", Section name="Error Recovery Point".
+00380|
+00381|TEXT COMPONENT: Pos(L,C)=(27,27).
+00382|
+00383|-- Start of Text Scrap List --
+00384|Text scrap[White]="<010>
+00385| "
+ +-----
+
+ +-----
+00416|TYPESETTER DIRECTIVE COMPONENT: Close emphasise.
+00417|
+00418|TEXT COMPONENT: Pos(L,C)=(17,42).
+00419|
+00420|-- Start of Text Scrap List --
+00421|Text scrap[Grey]=" construct.<010>
+00422|<010>
+00423|6.Test "
+ +-----
+00389|TYPESETTER DIRECTIVE COMPONENT: Open emphasise.
+00390|
+00391|TEXT COMPONENT: Pos(L,C)=(28,6).
+00392|
+00393|-- Start of Text Scrap List --
+00394|Text scrap[White]=" "
+ +-----
+
+ +-----
+00427|TYPESETTER DIRECTIVE COMPONENT: Open emphasise.
+00428|
+00429|TYPESETTER DIRECTIVE COMPONENT:
+00430| Section "4", Section name="Error Recovery Point".
+00431|
+00432|TEXT COMPONENT: Pos(L,C)=(20,27).
+00433|
+00434|-- Start of Text Scrap List --
+00435|Text scrap[Grey]="<010>
+00436|<010>
+00437|7. Test the construct "
+00438|--- End of Text Scrap List ---
+00439|
+00440|
+00441|TYPESETTER DIRECTIVE COMPONENT: Open emphasise.
+00442|
+00443|TEXT COMPONENT: Pos(L,C)=(22,25).
+00444|
+00445|-- Start of Text Scrap List --
+00446|Text scrap[Grey]="across<010>
+00447| more than one line"
+00448|--- End of Text Scrap List ---
+00449|
+00450|
+00451|TYPESETTER DIRECTIVE COMPONENT: Close emphasise.
+00452|
+00453|TEXT COMPONENT: Pos(L,C)=(23,24).
+00454|
+00455|-- Start of Text Scrap List --
+00456|Text scrap[Grey]=".<010>
+00457|<010>
+00458|8. Now we test the construct with non-text following it.<010>
+00459| "
+00460|--- End of Text Scrap List ---
+00461|
+00462|
+00463|TYPESETTER DIRECTIVE COMPONENT: Open emphasise.
+00464|
+00465|TYPESETTER DIRECTIVE COMPONENT:
+00466| Section "5", Section name="Error Recovery Point".
+00467|
+00468|TEXT COMPONENT: Pos(L,C)=(27,27).
+00469|
+00470|-- Start of Text Scrap List --
+00471|Text scrap[White]="<010>
+00472| "
+00473|--- End of Text Scrap List ---
+00474|
+00475|
+00476|TYPESETTER DIRECTIVE COMPONENT: Open emphasise.
+00477|
+00478|TEXT COMPONENT: Pos(L,C)=(28,6).
+00479|
+00480|-- Start of Text Scrap List --
+00481|Text scrap[White]=" "
+00482|--- End of Text Scrap List ---
+00483|
+00484|
+ +-----
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/pr02.lis"
+ with "/usr/var/tmp/funnelweb/answers/pr02.lis".
+
+ +-----
+00093|------------------- Start of Macro Dump --------------------
+00094|Macro Name : "#file"
+00095|Defined? : Yes.
+00096|Parameters : 0
+00097|Additive? : No.
+00098|Zero Calls? : Yes.
+00099|Many Calls? : Yes.
+00100|Output File?: No.
+00101|Automatic Line Directive Macro?: No.
+00102|Call list :
+00103|Macro body :
+00104|
+00105|--Start of List of Body Parts--
+00106|This macro has 1 body part.
+00107|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00108|
+00109|---- Start of Expression ----
+00110|
+00111|--- Start Special Function ---
+00112|---- End Special Function ----
+00113|
+00114|----- End of Expression -----
+00115|
+00116|---End of List of Body Parts---
+00117|
+00118|-------------------- End of Macro Dump ---------------------
+00119|
+00120|
+00121|
+00122|------------------- Start of Macro Dump --------------------
+00123|Macro Name : "#line"
+00124|Defined? : Yes.
+00125|Parameters : 0
+00126|Additive? : No.
+00127|Zero Calls? : Yes.
+00128|Many Calls? : Yes.
+00129|Output File?: No.
+00130|Automatic Line Directive Macro?: No.
+00131|Call list :
+00132|Macro body :
+00133|
+00134|--Start of List of Body Parts--
+00135|This macro has 1 body part.
+00136|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00137|
+00138|---- Start of Expression ----
+00139|
+00140|--- Start Special Function ---
+00141|---- End Special Function ----
+00142|
+00143|----- End of Expression -----
+00144|
+00145|---End of List of Body Parts---
+00146|
+00147|-------------------- End of Macro Dump ---------------------
+00148|
+00149|
+00150|
+00151|------------------- Start of Macro Dump --------------------
+00152|Macro Name : "#timestamp"
+00153|Defined? : Yes.
+00154|Parameters : 0
+00155|Additive? : No.
+00156|Zero Calls? : Yes.
+ +-----
+00093|=========================== End of MACRO TABLE DUMP ============================
+00094|
+00095|
+00096|========================= Start of DOCUMENT LIST DUMP ==========================
+00097|
+00098|
+00099|TEXT COMPONENT: Pos(L,C)=(1,1).
+00100|
+00101|-- Start of Text Scrap List --
+00102|Text scrap[Grey]="PR02: Test the parsing of typesetter directives.<010>
+00103|<010>
+00104|1. Test parsing of new page directive.<010>
+00105|"
+00106|--- End of Text Scrap List ---
+00107|
+00108|
+00109|TYPESETTER DIRECTIVE COMPONENT: New page.
+00110|
+00111|TEXT COMPONENT: Pos(L,C)=(5,1).
+00112|
+00113|-- Start of Text Scrap List --
+00114|Text scrap[Grey]="<010>
+00115|2. Test parsing of table of contents directive.<010>
+00116|"
+00117|--- End of Text Scrap List ---
+00118|
+00119|
+00120|TYPESETTER DIRECTIVE COMPONENT: Table of contents.
+00121|
+00122|TEXT COMPONENT: Pos(L,C)=(8,1).
+00123|
+00124|-- Start of Text Scrap List --
+00125|Text scrap[Grey]="<010>
+00126|3. Test parsing of vskip directive.<010>
+00127|"
+00128|--- End of Text Scrap List ---
+00129|
+00130|
+00131|TYPESETTER DIRECTIVE COMPONENT: Vertical skip by 32 mm.
+00132|
+00133|TEXT COMPONENT: Pos(L,C)=(11,1).
+00134|
+00135|-- Start of Text Scrap List --
+00136|Text scrap[Grey]="<010>
+00137|4. Test parsing of title directive.<010>
+00138|"
+00139|--- End of Text Scrap List ---
+00140|
+00141|
+00142|TYPESETTER DIRECTIVE COMPONENT: Font=Title, Alignment=Left. Title text follows:
+00143|Text scrap[Grey]="Sloth"
+00144|
+00145|TEXT COMPONENT: Pos(L,C)=(14,1).
+00146|
+00147|-- Start of Text Scrap List --
+00148|Text scrap[White]="<010>
+00149|"
+00150|--- End of Text Scrap List ---
+00151|
+00152|
+00153|========================== End of DOCUMENT LIST DUMP ===========================
+00154|
+00155|E: No macros defined.
+00156|E: No output files specified.
+ +-----
+
+ +-----
+00157|Many Calls? : Yes.
+00158|Output File?: No.
+00159|Automatic Line Directive Macro?: No.
+00160|Call list :
+00161|Macro body :
+00162|
+00163|--Start of List of Body Parts--
+00164|This macro has 1 body part.
+00165|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00166|
+00167|---- Start of Expression ----
+00168|
+00169|--- Start Special Function ---
+00170|---- End Special Function ----
+00171|
+00172|----- End of Expression -----
+00173|
+00174|---End of List of Body Parts---
+00175|
+00176|-------------------- End of Macro Dump ---------------------
+00177|
+00178|
+00179|
+00180|=========================== End of MACRO TABLE DUMP ============================
+00181|
+00182|
+00183|========================= Start of DOCUMENT LIST DUMP ==========================
+00184|
+00185|
+00186|TEXT COMPONENT: Pos(L,C)=(1,1).
+00187|
+00188|-- Start of Text Scrap List --
+00189|Text scrap[Grey]="PR02: Test the parsing of typesetter directives.<010>
+00190|<010>
+00191|1. Test parsing of new page directive.<010>
+00192|"
+00193|--- End of Text Scrap List ---
+00194|
+00195|
+00196|TYPESETTER DIRECTIVE COMPONENT: New page.
+00197|
+00198|TEXT COMPONENT: Pos(L,C)=(5,1).
+00199|
+00200|-- Start of Text Scrap List --
+00201|Text scrap[Grey]="<010>
+00202|2. Test parsing of table of contents directive.<010>
+00203|"
+00204|--- End of Text Scrap List ---
+00205|
+00206|
+00207|TYPESETTER DIRECTIVE COMPONENT: Table of contents.
+00208|
+00209|TEXT COMPONENT: Pos(L,C)=(8,1).
+00210|
+00211|-- Start of Text Scrap List --
+00212|Text scrap[Grey]="<010>
+00213|3. Test parsing of vskip directive.<010>
+00214|"
+00215|--- End of Text Scrap List ---
+00216|
+00217|
+00218|TYPESETTER DIRECTIVE COMPONENT: Vertical skip by 32 mm.
+00219|
+00220|TEXT COMPONENT: Pos(L,C)=(11,1).
+ +-----
+00157|
+00158|Global Local| Input File
+00159|------------+-------------------------------------------------------------------
+00160|.................
+00161|------------+-------------------------------------------------------------------
+00162|
+00163|There were 2 Errors.
+ +-----
+
+ +-----
+00221|
+00222|-- Start of Text Scrap List --
+00223|Text scrap[Grey]="<010>
+00224|4. Test parsing of title directive.<010>
+00225|"
+00226|--- End of Text Scrap List ---
+00227|
+00228|
+00229|TYPESETTER DIRECTIVE COMPONENT: Font=Title, Alignment=Left. Title text follows:
+00230|Text scrap[Grey]="Sloth"
+00231|
+00232|TEXT COMPONENT: Pos(L,C)=(14,1).
+00233|
+00234|-- Start of Text Scrap List --
+00235|Text scrap[White]="<010>
+00236|"
+00237|--- End of Text Scrap List ---
+00238|
+00239|
+00240|========================== End of DOCUMENT LIST DUMP ===========================
+00241|
+00242|E: No output files specified.
+00243|
+00244|Global Local| Input File
+00245|------------+-------------------------------------------------------------------
+00246|.................
+00247|------------+-------------------------------------------------------------------
+00248|
+00249|There was 1 Error.
+ +-----
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/pr03.lis"
+ with "/usr/var/tmp/funnelweb/answers/pr03.lis".
+
+ +-----
+00206|Macro Name : "#file"
+ +-----
+00206|Macro Name : "The section name inherits the name of this macro"
+ +-----
+
+ +-----
+00210|Zero Calls? : Yes.
+00211|Many Calls? : Yes.
+00212|Output File?: No.
+00213|Automatic Line Directive Macro?: No.
+ +-----
+00210|Zero Calls? : No.
+00211|Many Calls? : No.
+00212|Output File?: No.
+ +-----
+
+ +-----
+00219|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+ +-----
+00218|Body part 1: Seqnum=1, Pos(L,C)=(8,3), Expression follows:
+ +-----
+
+ +-----
+00223|--- Start Special Function ---
+00224|---- End Special Function ----
+ +-----
+00222|----- Start Text Element -----
+00223|Text scrap[Grey]="Walrus"
+00224|------ End Text Element ------
+ +-----
+
+ +-----
+00234|------------------- Start of Macro Dump --------------------
+00235|Macro Name : "#line"
+00236|Defined? : Yes.
+00237|Parameters : 0
+00238|Additive? : No.
+00239|Zero Calls? : Yes.
+00240|Many Calls? : Yes.
+00241|Output File?: No.
+00242|Automatic Line Directive Macro?: No.
+00243|Call list :
+00244|Macro body :
+00245|
+00246|--Start of List of Body Parts--
+00247|This macro has 1 body part.
+00248|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00249|
+00250|---- Start of Expression ----
+00251|
+00252|--- Start Special Function ---
+00253|---- End Special Function ----
+00254|
+00255|----- End of Expression -----
+00256|
+00257|---End of List of Body Parts---
+00258|
+00259|-------------------- End of Macro Dump ---------------------
+00260|
+00261|
+00262|
+00263|------------------- Start of Macro Dump --------------------
+00264|Macro Name : "#timestamp"
+00265|Defined? : Yes.
+00266|Parameters : 0
+00267|Additive? : No.
+00268|Zero Calls? : Yes.
+00269|Many Calls? : Yes.
+00270|Output File?: No.
+00271|Automatic Line Directive Macro?: No.
+00272|Call list :
+00273|Macro body :
+00274|
+00275|--Start of List of Body Parts--
+00276|This macro has 1 body part.
+00277|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00278|
+00279|---- Start of Expression ----
+00280|
+00281|--- Start Special Function ---
+00282|---- End Special Function ----
+00283|
+00284|----- End of Expression -----
+00285|
+00286|---End of List of Body Parts---
+00287|
+00288|-------------------- End of Macro Dump ---------------------
+00289|
+00290|
+00291|
+00292|------------------- Start of Macro Dump --------------------
+00293|Macro Name : "The section name inherits the name of this macro"
+00294|Defined? : Yes.
+00295|Parameters : 0
+00296|Additive? : No.
+00297|Zero Calls? : No.
+ +-----
+00234|=========================== End of MACRO TABLE DUMP ============================
+00235|
+00236|
+00237|========================= Start of DOCUMENT LIST DUMP ==========================
+00238|
+00239|
+00240|TEXT COMPONENT: Pos(L,C)=(1,1).
+00241|
+00242|-- Start of Text Scrap List --
+00243|Text scrap[Grey]="PR03: Test the parsing and semantics of sections.<010>
+00244|<010>
+00245|4. Test first section of document is not <special>A.<010>
+00246|"
+00247|--- End of Text Scrap List ---
+00248|
+00249|
+00250|TYPESETTER DIRECTIVE COMPONENT:
+00251| Section "1.2", Section name="This section is out of order (and so is this test!)".
+00252|
+00253|TEXT COMPONENT: Pos(L,C)=(4,58).
+00254|
+00255|-- Start of Text Scrap List --
+00256|Text scrap[Grey]="<010>
+00257|<010>
+00258|1. Test section with no name.<010>
+00259|"
+00260|--- End of Text Scrap List ---
+00261|
+00262|
+00263|TYPESETTER DIRECTIVE COMPONENT:
+00264| Section "2", Section name="The section name inherits the name of this macro".
+00265|
+00266|TEXT COMPONENT: Pos(L,C)=(7,3).
+00267|
+00268|-- Start of Text Scrap List --
+00269|Text scrap[Grey]=" This section has no name.<010>
+00270|"
+00271|--- End of Text Scrap List ---
+00272|
+00273|
+00274|MACRO DEFINITION COMPONENT: Pos(L,C)=(8,1).
+00275|Part 1 of macro @<The section name inherits the name of this macro@>.
+00276|
+00277|TEXT COMPONENT: Pos(L,C)=(8,65).
+00278|
+00279|-- Start of Text Scrap List --
+00280|Text scrap[Grey]="<010>
+00281|<010>
+00282|2. Test section with a name<010>
+00283|"
+00284|--- End of Text Scrap List ---
+00285|
+00286|
+00287|TYPESETTER DIRECTIVE COMPONENT:
+00288| Section "3", Section name="This section has no name.".
+00289|
+00290|TEXT COMPONENT: Pos(L,C)=(11,32).
+00291|
+00292|-- Start of Text Scrap List --
+00293|Text scrap[Grey]="<010>
+00294|<010>
+00295|3. Test the entire hierarchy.<010>
+00296|"
+00297|--- End of Text Scrap List ---
+ +-----
+
+ +-----
+00298|Many Calls? : No.
+00299|Output File?: No.
+00300|Automatic Line Directive Macro?: No.
+00301|Call list :
+00302|Macro body :
+00303|
+00304|--Start of List of Body Parts--
+00305|This macro has 1 body part.
+00306|Body part 1: Seqnum=1, Pos(L,C)=(8,3), Expression follows:
+00307|
+00308|---- Start of Expression ----
+00309|
+00310|----- Start Text Element -----
+00311|Text scrap[Grey]="Walrus"
+00312|------ End Text Element ------
+00313|
+00314|----- End of Expression -----
+00315|
+00316|---End of List of Body Parts---
+00317|
+00318|-------------------- End of Macro Dump ---------------------
+00319|
+00320|
+00321|
+00322|=========================== End of MACRO TABLE DUMP ============================
+00323|
+00324|
+00325|========================= Start of DOCUMENT LIST DUMP ==========================
+00326|
+00327|
+00328|TEXT COMPONENT: Pos(L,C)=(1,1).
+00329|
+00330|-- Start of Text Scrap List --
+00331|Text scrap[Grey]="PR03: Test the parsing and semantics of sections.<010>
+00332|<010>
+00333|4. Test first section of document is not <special>A.<010>
+00334|"
+00335|--- End of Text Scrap List ---
+ +-----
+ +-----
+
+ +-----
+00339| Section "1.2", Section name="This section is out of order (and so is this test!)".
+00340|
+00341|TEXT COMPONENT: Pos(L,C)=(4,58).
+00342|
+00343|-- Start of Text Scrap List --
+00344|Text scrap[Grey]="<010>
+00345|<010>
+00346|1. Test section with no name.<010>
+ +-----
+00301| Section "4", Section name="One".
+00302|
+00303|TEXT COMPONENT: Pos(L,C)=(14,10).
+00304|
+00305|-- Start of Text Scrap List --
+00306|Text scrap[White]="<010>
+ +-----
+
+ +-----
+00352| Section "2", Section name="The section name inherits the name of this macro".
+00353|
+00354|TEXT COMPONENT: Pos(L,C)=(7,3).
+00355|
+00356|-- Start of Text Scrap List --
+00357|Text scrap[Grey]=" This section has no name.<010>
+ +-----
+00312| Section "4.1", Section name="Two".
+00313|
+00314|TEXT COMPONENT: Pos(L,C)=(15,10).
+00315|
+00316|-- Start of Text Scrap List --
+00317|Text scrap[White]="<010>
+ +-----
+
+ +-----
+00362|MACRO DEFINITION COMPONENT: Pos(L,C)=(8,1).
+00363|Part 1 of macro @<The section name inherits the name of this macro@>.
+00364|
+00365|TEXT COMPONENT: Pos(L,C)=(8,65).
+00366|
+00367|-- Start of Text Scrap List --
+00368|Text scrap[Grey]="<010>
+00369|<010>
+00370|2. Test section with a name<010>
+ +-----
+00322|TYPESETTER DIRECTIVE COMPONENT:
+00323| Section "4.1.1", Section name="Three".
+00324|
+00325|TEXT COMPONENT: Pos(L,C)=(16,12).
+00326|
+00327|-- Start of Text Scrap List --
+00328|Text scrap[White]="<010>
+ +-----
+
+ +-----
+00376| Section "3", Section name="This section has no name.".
+00377|
+00378|TEXT COMPONENT: Pos(L,C)=(11,32).
+00379|
+00380|-- Start of Text Scrap List --
+00381|Text scrap[Grey]="<010>
+00382|<010>
+00383|3. Test the entire hierarchy.<010>
+ +-----
+00334| Section "4.1.1.1", Section name="Four".
+00335|
+00336|TEXT COMPONENT: Pos(L,C)=(17,11).
+00337|
+00338|-- Start of Text Scrap List --
+00339|Text scrap[White]="<010>
+ +-----
+
+ +-----
+00389| Section "4", Section name="One".
+00390|
+00391|TEXT COMPONENT: Pos(L,C)=(14,10).
+00392|
+00393|-- Start of Text Scrap List --
+00394|Text scrap[White]="<010>
+ +-----
+00345| Section "4.1.1.1.1", Section name="Five".
+00346|
+00347|TEXT COMPONENT: Pos(L,C)=(18,11).
+00348|
+00349|-- Start of Text Scrap List --
+00350|Text scrap[Grey]="<010>
+00351|<010>
+00352|5. Test detection of discontinuity in levels.<010>
+ +-----
+
+ +-----
+00400| Section "4.1", Section name="Two".
+00401|
+00402|TEXT COMPONENT: Pos(L,C)=(15,10).
+ +-----
+00358| Section "5", Section name="One".
+00359|
+00360|TEXT COMPONENT: Pos(L,C)=(21,10).
+ +-----
+
+ +-----
+00411| Section "4.1.1", Section name="Three".
+00412|
+00413|TEXT COMPONENT: Pos(L,C)=(16,12).
+ +-----
+00369| Section "1.1.2", Section name="Three".
+00370|
+00371|TEXT COMPONENT: Pos(L,C)=(22,12).
+ +-----
+
+ +-----
+00422| Section "4.1.1.1", Section name="Four".
+00423|
+00424|TEXT COMPONENT: Pos(L,C)=(17,11).
+ +-----
+00380| Section "1.1.1.1.2", Section name="Five".
+00381|
+00382|TEXT COMPONENT: Pos(L,C)=(23,11).
+ +-----
+
+ +-----
+ +-----
+00386|<010>
+ +-----
+
+ +-----
+00433| Section "4.1.1.1.1", Section name="Five".
+00434|
+00435|TEXT COMPONENT: Pos(L,C)=(18,11).
+00436|
+00437|-- Start of Text Scrap List --
+00438|Text scrap[Grey]="<010>
+00439|<010>
+00440|5. Test detection of discontinuity in levels.<010>
+ +-----
+00392| Section "2", Section name="One".
+00393|
+00394|TEXT COMPONENT: Pos(L,C)=(25,10).
+00395|
+00396|-- Start of Text Scrap List --
+00397|Text scrap[White]="<010>
+ +-----
+
+ +-----
+00446| Section "5", Section name="One".
+00447|
+00448|TEXT COMPONENT: Pos(L,C)=(21,10).
+ +-----
+00403| Section "2.1", Section name="Three".
+00404|
+00405|TEXT COMPONENT: Pos(L,C)=(26,12).
+ +-----
+
+ +-----
+00457| Section "1.1.2", Section name="Three".
+00458|
+00459|TEXT COMPONENT: Pos(L,C)=(22,12).
+ +-----
+00414| Section "1.1.1.2", Section name="Five".
+00415|
+00416|TEXT COMPONENT: Pos(L,C)=(27,11).
+ +-----
+
+ +-----
+00467|TYPESETTER DIRECTIVE COMPONENT:
+00468| Section "1.1.1.1.2", Section name="Five".
+00469|
+00470|TEXT COMPONENT: Pos(L,C)=(23,11).
+00471|
+00472|-- Start of Text Scrap List --
+00473|Text scrap[White]="<010>
+00474|<010>
+00475|"
+00476|--- End of Text Scrap List ---
+00477|
+00478|
+00479|TYPESETTER DIRECTIVE COMPONENT:
+00480| Section "2", Section name="One".
+00481|
+00482|TEXT COMPONENT: Pos(L,C)=(25,10).
+00483|
+00484|-- Start of Text Scrap List --
+00485|Text scrap[White]="<010>
+00486|"
+00487|--- End of Text Scrap List ---
+00488|
+00489|
+00490|TYPESETTER DIRECTIVE COMPONENT:
+00491| Section "2.1", Section name="Three".
+00492|
+00493|TEXT COMPONENT: Pos(L,C)=(26,12).
+00494|
+00495|-- Start of Text Scrap List --
+00496|Text scrap[White]="<010>
+00497|"
+00498|--- End of Text Scrap List ---
+00499|
+00500|
+00501|TYPESETTER DIRECTIVE COMPONENT:
+00502| Section "1.1.1.2", Section name="Five".
+00503|
+00504|TEXT COMPONENT: Pos(L,C)=(27,11).
+00505|
+00506|-- Start of Text Scrap List --
+00507|Text scrap[White]="<010>
+00508|"
+00509|--- End of Text Scrap List ---
+00510|
+00511|
+ +-----
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/pr04.lis"
+ with "/usr/var/tmp/funnelweb/answers/pr04.lis".
+
+ +-----
+00267|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00297|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00315|Macro Name : "#file"
+ +-----
+00313|Macro Name : "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
+ +-----
+
+ +-----
+00319|Zero Calls? : Yes.
+00320|Many Calls? : Yes.
+00321|Output File?: No.
+00322|Automatic Line Directive Macro?: No.
+ +-----
+00317|Zero Calls? : No.
+00318|Many Calls? : No.
+00319|Output File?: No.
+ +-----
+
+ +-----
+00328|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00329|
+00330|---- Start of Expression ----
+00331|
+00332|--- Start Special Function ---
+00333|---- End Special Function ----
+00334|
+ +-----
+00325|Body part 1: Seqnum=4, Pos(L,C)=(20,3), Expression follows:
+00326|
+00327|---- Start of Expression ----
+ +-----
+
+ +-----
+00344|Macro Name : "#line"
+ +-----
+00337|Macro Name : "A@"
+ +-----
+
+ +-----
+00348|Zero Calls? : Yes.
+00349|Many Calls? : Yes.
+00350|Output File?: No.
+00351|Automatic Line Directive Macro?: No.
+ +-----
+00341|Zero Calls? : No.
+00342|Many Calls? : No.
+00343|Output File?: No.
+ +-----
+
+ +-----
+00357|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00358|
+00359|---- Start of Expression ----
+00360|
+00361|--- Start Special Function ---
+00362|---- End Special Function ----
+00363|
+ +-----
+00349|Body part 1: Seqnum=8, Pos(L,C)=(31,3), Expression follows:
+00350|
+00351|---- Start of Expression ----
+ +-----
+
+ +-----
+00373|Macro Name : "#timestamp"
+ +-----
+00361|Macro Name : "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`"
+ +-----
+
+ +-----
+00377|Zero Calls? : Yes.
+00378|Many Calls? : Yes.
+00379|Output File?: No.
+00380|Automatic Line Directive Macro?: No.
+ +-----
+00365|Zero Calls? : No.
+00366|Many Calls? : No.
+00367|Output File?: No.
+ +-----
+
+ +-----
+00386|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00387|
+00388|---- Start of Expression ----
+00389|
+00390|--- Start Special Function ---
+00391|---- End Special Function ----
+00392|
+ +-----
+00373|Body part 1: Seqnum=6, Pos(L,C)=(26,3), Expression follows:
+00374|
+00375|---- Start of Expression ----
+ +-----
+
+ +-----
+00402|Macro Name : "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
+ +-----
+00385|Macro Name : "Ordinary"
+ +-----
+
+ +-----
+00409|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00415|Body part 1: Seqnum=4, Pos(L,C)=(20,3), Expression follows:
+00416|
+00417|---- Start of Expression ----
+ +-----
+00397|Body part 1: Seqnum=1, Pos(L,C)=(4,3), Expression follows:
+00398|
+00399|---- Start of Expression ----
+00400|
+00401|----- Start Text Element -----
+00402|Text scrap[Grey]="The text of ordinary"
+00403|------ End Text Element ------
+00404|
+ +-----
+
+ +-----
+00427|Macro Name : "A@"
+ +-----
+00414|Macro Name : "abcdefghijklmnopqrstuvwxyz{|}~"
+ +-----
+
+ +-----
+00434|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00440|Body part 1: Seqnum=8, Pos(L,C)=(31,3), Expression follows:
+ +-----
+00426|Body part 1: Seqnum=7, Pos(L,C)=(27,3), Expression follows:
+ +-----
+
+ +-----
+00452|Macro Name : "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`"
+ +-----
+00438|Macro Name : "|"
+ +-----
+
+ +-----
+00459|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00465|Body part 1: Seqnum=6, Pos(L,C)=(26,3), Expression follows:
+00466|
+00467|---- Start of Expression ----
+ +-----
+00450|Body part 1: Seqnum=2, Pos(L,C)=(7,3), Expression follows:
+00451|
+00452|---- Start of Expression ----
+00453|
+00454|----- Start Text Element -----
+00455|Text scrap[Grey]="The text of ordinary"
+00456|------ End Text Element ------
+00457|
+ +-----
+
+ +-----
+00476|------------------- Start of Macro Dump --------------------
+00477|Macro Name : "Ordinary"
+00478|Defined? : Yes.
+00479|Parameters : 0
+00480|Additive? : No.
+00481|Zero Calls? : No.
+00482|Many Calls? : No.
+00483|Output File?: No.
+00484|Automatic Line Directive Macro?: No.
+00485|Call list :
+00486|Macro body :
+00487|
+00488|--Start of List of Body Parts--
+00489|This macro has 1 body part.
+00490|Body part 1: Seqnum=1, Pos(L,C)=(4,3), Expression follows:
+00491|
+00492|---- Start of Expression ----
+00493|
+00494|----- Start Text Element -----
+00495|Text scrap[Grey]="The text of ordinary"
+00496|------ End Text Element ------
+00497|
+00498|----- End of Expression -----
+00499|
+00500|---End of List of Body Parts---
+00501|
+00502|-------------------- End of Macro Dump ---------------------
+00503|
+00504|
+00505|
+00506|------------------- Start of Macro Dump --------------------
+00507|Macro Name : "abcdefghijklmnopqrstuvwxyz{|}~"
+00508|Defined? : Yes.
+00509|Parameters : 0
+00510|Additive? : No.
+00511|Zero Calls? : No.
+00512|Many Calls? : No.
+00513|Output File?: No.
+00514|Automatic Line Directive Macro?: No.
+00515|Call list :
+00516|Macro body :
+00517|
+00518|--Start of List of Body Parts--
+00519|This macro has 1 body part.
+00520|Body part 1: Seqnum=7, Pos(L,C)=(27,3), Expression follows:
+00521|
+00522|---- Start of Expression ----
+00523|----- End of Expression -----
+00524|
+00525|---End of List of Body Parts---
+00526|
+00527|-------------------- End of Macro Dump ---------------------
+00528|
+00529|
+00530|
+00531|------------------- Start of Macro Dump --------------------
+00532|Macro Name : "|"
+00533|Defined? : Yes.
+00534|Parameters : 0
+00535|Additive? : No.
+00536|Zero Calls? : No.
+00537|Many Calls? : No.
+00538|Output File?: No.
+00539|Automatic Line Directive Macro?: No.
+ +-----
+00466|=========================== End of MACRO TABLE DUMP ============================
+00467|
+00468|
+00469|========================= Start of DOCUMENT LIST DUMP ==========================
+00470|
+00471|
+00472|TEXT COMPONENT: Pos(L,C)=(1,1).
+00473|
+00474|-- Start of Text Scrap List --
+00475|Text scrap[Grey]="PR04: Test the definition of ordinary macros.<010>
+00476|<010>
+00477|1. Test an ordinary macro definition.<010>
+00478|"
+00479|--- End of Text Scrap List ---
+00480|
+00481|
+00482|MACRO DEFINITION COMPONENT: Pos(L,C)=(4,1).
+00483|Part 1 of macro @<Ordinary@>.
+00484|
+00485|TEXT COMPONENT: Pos(L,C)=(4,39).
+00486|
+00487|-- Start of Text Scrap List --
+00488|Text scrap[Grey]="<010>
+00489|<010>
+00490|2. Test an ordinary definition using a quickname.<010>
+00491|"
+00492|--- End of Text Scrap List ---
+00493|
+00494|
+00495|MACRO DEFINITION COMPONENT: Pos(L,C)=(7,1).
+00496|Part 1 of macro @<|@>.
+00497|
+00498|TEXT COMPONENT: Pos(L,C)=(7,30).
+00499|
+00500|-- Start of Text Scrap List --
+00501|Text scrap[Grey]="<010>
+00502|<010>
+00503|3. Test a name that includes EOL.<010>
+00504|"
+00505|--- End of Text Scrap List ---
+00506|
+00507|
+00508|TYPESETTER DIRECTIVE COMPONENT:
+00509| Section "1", Section name="Error Recovery Point".
+00510|
+00511|TEXT COMPONENT: Pos(L,C)=(12,27).
+00512|
+00513|-- Start of Text Scrap List --
+00514|Text scrap[Grey]="<010>
+00515|<010>
+00516|4. Test the minimum length name (the empty name).<010>
+00517|"
+00518|--- End of Text Scrap List ---
+00519|
+00520|
+00521|MACRO DEFINITION COMPONENT: Pos(L,C)=(15,1).
+00522|Part 1 of macro @<@>.
+00523|
+00524|TEXT COMPONENT: Pos(L,C)=(15,60).
+00525|
+00526|-- Start of Text Scrap List --
+00527|Text scrap[Grey]="<010>
+00528|<010>
+00529|5. Test a name at the maximum name length limit (80).<010>
+ +-----
+
+ +-----
+00540|Call list :
+00541|Macro body :
+00542|
+00543|--Start of List of Body Parts--
+00544|This macro has 1 body part.
+00545|Body part 1: Seqnum=2, Pos(L,C)=(7,3), Expression follows:
+00546|
+00547|---- Start of Expression ----
+00548|
+00549|----- Start Text Element -----
+00550|Text scrap[Grey]="The text of ordinary"
+00551|------ End Text Element ------
+00552|
+00553|----- End of Expression -----
+00554|
+00555|---End of List of Body Parts---
+00556|
+00557|-------------------- End of Macro Dump ---------------------
+00558|
+00559|
+00560|
+00561|=========================== End of MACRO TABLE DUMP ============================
+00562|
+00563|
+00564|========================= Start of DOCUMENT LIST DUMP ==========================
+00565|
+00566|
+00567|TEXT COMPONENT: Pos(L,C)=(1,1).
+00568|
+00569|-- Start of Text Scrap List --
+00570|Text scrap[Grey]="PR04: Test the definition of ordinary macros.<010>
+00571|<010>
+00572|1. Test an ordinary macro definition.<010>
+ +-----
+00530|ONly the second of the two macros should generate an error.<010>
+ +-----
+
+ +-----
+00577|MACRO DEFINITION COMPONENT: Pos(L,C)=(4,1).
+00578|Part 1 of macro @<Ordinary@>.
+00579|
+00580|TEXT COMPONENT: Pos(L,C)=(4,39).
+00581|
+00582|-- Start of Text Scrap List --
+00583|Text scrap[Grey]="<010>
+00584|<010>
+00585|2. Test an ordinary definition using a quickname.<010>
+ +-----
+00535|MACRO DEFINITION COMPONENT: Pos(L,C)=(20,1).
+00536|Part 1 of macro @<12345678901234567890123456789012345678901234567890123456789012345678901234567890@>.
+00537|
+00538|TEXT COMPONENT: Pos(L,C)=(20,91).
+00539|
+00540|-- Start of Text Scrap List --
+00541|Text scrap[White]="<010>
+ +-----
+
+ +-----
+00590|MACRO DEFINITION COMPONENT: Pos(L,C)=(7,1).
+00591|Part 1 of macro @<|@>.
+00592|
+00593|TEXT COMPONENT: Pos(L,C)=(7,30).
+ +-----
+00546|TYPESETTER DIRECTIVE COMPONENT:
+00547| Section "2", Section name="Error Recovery Point".
+00548|
+00549|TEXT COMPONENT: Pos(L,C)=(22,27).
+ +-----
+
+ +-----
+00598|3. Test a name that includes EOL.<010>
+ +-----
+00554|6. Test names with all legal characters. There should be no errors.<010>
+ +-----
+
+ +-----
+00603|TYPESETTER DIRECTIVE COMPONENT:
+00604| Section "1", Section name="Error Recovery Point".
+00605|
+00606|TEXT COMPONENT: Pos(L,C)=(12,27).
+00607|
+00608|-- Start of Text Scrap List --
+00609|Text scrap[Grey]="<010>
+00610|<010>
+00611|4. Test the minimum length name (the empty name).<010>
+ +-----
+00559|MACRO DEFINITION COMPONENT: Pos(L,C)=(25,1).
+00560|Part 1 of macro @< !"#$%'()*+,-./0123456789:;<=>?@>.
+00561|
+00562|TEXT COMPONENT: Pos(L,C)=(25,42).
+00563|
+00564|-- Start of Text Scrap List --
+00565|Text scrap[White]="<010>
+ +-----
+
+ +-----
+00616|MACRO DEFINITION COMPONENT: Pos(L,C)=(15,1).
+00617|Part 1 of macro @<@>.
+00618|
+00619|TEXT COMPONENT: Pos(L,C)=(15,60).
+00620|
+00621|-- Start of Text Scrap List --
+00622|Text scrap[Grey]="<010>
+00623|<010>
+00624|5. Test a name at the maximum name length limit (80).<010>
+00625|ONly the second of the two macros should generate an error.<010>
+ +-----
+00570|MACRO DEFINITION COMPONENT: Pos(L,C)=(26,1).
+00571|Part 1 of macro @<ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`@>.
+00572|
+00573|TEXT COMPONENT: Pos(L,C)=(26,43).
+00574|
+00575|-- Start of Text Scrap List --
+00576|Text scrap[White]="<010>
+ +-----
+
+ +-----
+00630|MACRO DEFINITION COMPONENT: Pos(L,C)=(20,1).
+00631|Part 1 of macro @<12345678901234567890123456789012345678901234567890123456789012345678901234567890@>.
+00632|
+00633|TEXT COMPONENT: Pos(L,C)=(20,91).
+00634|
+00635|-- Start of Text Scrap List --
+00636|Text scrap[White]="<010>
+ +-----
+00581|MACRO DEFINITION COMPONENT: Pos(L,C)=(27,1).
+00582|Part 1 of macro @<abcdefghijklmnopqrstuvwxyz{|}~@>.
+00583|
+00584|TEXT COMPONENT: Pos(L,C)=(27,41).
+00585|
+00586|-- Start of Text Scrap List --
+00587|Text scrap[Grey]="<010>
+00588|<010>
+00589|7. Test a name that has inserted text sequences.<010>
+00590|<010>
+ +-----
+
+ +-----
+00641|TYPESETTER DIRECTIVE COMPONENT:
+00642| Section "2", Section name="Error Recovery Point".
+00643|
+00644|TEXT COMPONENT: Pos(L,C)=(22,27).
+00645|
+00646|-- Start of Text Scrap List --
+00647|Text scrap[Grey]="<010>
+00648|<010>
+00649|6. Test names with all legal characters. There should be no errors.<010>
+ +-----
+00595|MACRO DEFINITION COMPONENT: Pos(L,C)=(31,1).
+00596|Part 1 of macro @<A@@>.
+00597|
+00598|TEXT COMPONENT: Pos(L,C)=(31,23).
+00599|
+00600|-- Start of Text Scrap List --
+00601|Text scrap[White]="<010>
+00602|<010>
+00603|<010>
+ +-----
+
+ +-----
+00654|MACRO DEFINITION COMPONENT: Pos(L,C)=(25,1).
+00655|Part 1 of macro @< !"#$%'()*+,-./0123456789:;<=>?@>.
+00656|
+00657|TEXT COMPONENT: Pos(L,C)=(25,42).
+00658|
+00659|-- Start of Text Scrap List --
+00660|Text scrap[White]="<010>
+00661|"
+00662|--- End of Text Scrap List ---
+00663|
+00664|
+00665|MACRO DEFINITION COMPONENT: Pos(L,C)=(26,1).
+00666|Part 1 of macro @<ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`@>.
+00667|
+00668|TEXT COMPONENT: Pos(L,C)=(26,43).
+00669|
+00670|-- Start of Text Scrap List --
+00671|Text scrap[White]="<010>
+00672|"
+00673|--- End of Text Scrap List ---
+00674|
+00675|
+00676|MACRO DEFINITION COMPONENT: Pos(L,C)=(27,1).
+00677|Part 1 of macro @<abcdefghijklmnopqrstuvwxyz{|}~@>.
+00678|
+00679|TEXT COMPONENT: Pos(L,C)=(27,41).
+00680|
+00681|-- Start of Text Scrap List --
+00682|Text scrap[Grey]="<010>
+00683|<010>
+00684|7. Test a name that has inserted text sequences.<010>
+00685|<010>
+00686|"
+00687|--- End of Text Scrap List ---
+00688|
+00689|
+00690|MACRO DEFINITION COMPONENT: Pos(L,C)=(31,1).
+00691|Part 1 of macro @<A@@>.
+00692|
+00693|TEXT COMPONENT: Pos(L,C)=(31,23).
+00694|
+00695|-- Start of Text Scrap List --
+00696|Text scrap[White]="<010>
+00697|<010>
+00698|<010>
+00699|"
+00700|--- End of Text Scrap List ---
+00701|
+00702|
+ +-----
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/pr05.lis"
+ with "/usr/var/tmp/funnelweb/answers/pr05.lis".
+
+ +-----
+00375|Macro Name : "#file"
+ +-----
+00375|Macro Name : "Sloth"
+ +-----
+
+ +-----
+00379|Zero Calls? : Yes.
+00380|Many Calls? : Yes.
+00381|Output File?: No.
+00382|Automatic Line Directive Macro?: No.
+ +-----
+00379|Zero Calls? : No.
+00380|Many Calls? : No.
+00381|Output File?: No.
+ +-----
+
+ +-----
+00388|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+ +-----
+00387|Body part 1: Seqnum=1, Pos(L,C)=(7,3), Expression follows:
+ +-----
+
+ +-----
+00392|--- Start Special Function ---
+00393|---- End Special Function ----
+ +-----
+00391|----- Start Text Element -----
+00392|Text scrap[Grey]="Slothtext"
+00393|------ End Text Element ------
+ +-----
+
+ +-----
+00404|Macro Name : "#line"
+ +-----
+00404|Macro Name : "Sloth a"
+00405|Defined? : No.
+00406|-------------------- End of Macro Dump ---------------------
+00407|
+00408|
+00409|
+00410|------------------- Start of Macro Dump --------------------
+00411|Macro Name : "Sloth b"
+ +-----
+
+ +-----
+00408|Zero Calls? : Yes.
+00409|Many Calls? : Yes.
+00410|Output File?: No.
+00411|Automatic Line Directive Macro?: No.
+ +-----
+00415|Zero Calls? : No.
+00416|Many Calls? : No.
+00417|Output File?: No.
+ +-----
+
+ +-----
+00416|This macro has 1 body part.
+00417|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00418|
+00419|---- Start of Expression ----
+00420|
+00421|--- Start Special Function ---
+00422|---- End Special Function ----
+00423|
+00424|----- End of Expression -----
+00425|
+ +-----
+00422|This macro has 0 body parts.
+ +-----
+
+ +-----
+00433|Macro Name : "#timestamp"
+ +-----
+00430|Macro Name : "Sloth c"
+00431|Defined? : No.
+00432|-------------------- End of Macro Dump ---------------------
+00433|
+00434|
+00435|
+00436|------------------- Start of Macro Dump --------------------
+00437|Macro Name : "Sloth d"
+ +-----
+
+ +-----
+00437|Zero Calls? : Yes.
+00438|Many Calls? : Yes.
+00439|Output File?: No.
+00440|Automatic Line Directive Macro?: No.
+ +-----
+00441|Zero Calls? : No.
+00442|Many Calls? : No.
+00443|Output File?: No.
+ +-----
+
+ +-----
+00445|This macro has 1 body part.
+00446|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00447|
+00448|---- Start of Expression ----
+00449|
+00450|--- Start Special Function ---
+00451|---- End Special Function ----
+00452|
+00453|----- End of Expression -----
+00454|
+ +-----
+00448|This macro has 0 body parts.
+ +-----
+
+ +-----
+00462|Macro Name : "Sloth"
+00463|Defined? : Yes.
+00464|Parameters : 0
+ +-----
+00456|Macro Name : "Sloth e"
+00457|Defined? : Yes.
+00458|Parameters : 9
+ +-----
+
+ +-----
+00469|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00474|This macro has 1 body part.
+00475|Body part 1: Seqnum=1, Pos(L,C)=(7,3), Expression follows:
+00476|
+00477|---- Start of Expression ----
+00478|
+00479|----- Start Text Element -----
+00480|Text scrap[Grey]="Slothtext"
+00481|------ End Text Element ------
+00482|
+00483|----- End of Expression -----
+00484|
+ +-----
+00467|This macro has 0 body parts.
+ +-----
+
+ +-----
+00492|Macro Name : "Sloth a"
+00493|Defined? : No.
+00494|-------------------- End of Macro Dump ---------------------
+00495|
+00496|
+00497|
+00498|------------------- Start of Macro Dump --------------------
+00499|Macro Name : "Sloth b"
+00500|Defined? : Yes.
+00501|Parameters : 0
+ +-----
+00475|Macro Name : "Sloth with 2"
+00476|Defined? : Yes.
+00477|Parameters : 2
+ +-----
+
+ +-----
+00506|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00511|This macro has 0 body parts.
+ +-----
+00486|This macro has 1 body part.
+00487|Body part 1: Seqnum=3, Pos(L,C)=(13,3), Expression follows:
+00488|
+00489|---- Start of Expression ----
+00490|
+00491|----- Start Text Element -----
+00492|Text scrap[Grey]="Slothtext"
+00493|------ End Text Element ------
+00494|
+00495|----- End of Expression -----
+00496|
+ +-----
+
+ +-----
+00519|Macro Name : "Sloth c"
+00520|Defined? : No.
+00521|-------------------- End of Macro Dump ---------------------
+00522|
+00523|
+00524|
+00525|------------------- Start of Macro Dump --------------------
+00526|Macro Name : "Sloth d"
+00527|Defined? : Yes.
+00528|Parameters : 0
+ +-----
+00504|Macro Name : "Sloth with 3"
+00505|Defined? : Yes.
+00506|Parameters : 3
+ +-----
+
+ +-----
+00533|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00538|This macro has 0 body parts.
+ +-----
+00515|This macro has 1 body part.
+00516|Body part 1: Seqnum=4, Pos(L,C)=(14,3), Expression follows:
+00517|
+00518|---- Start of Expression ----
+00519|
+00520|----- Start Text Element -----
+00521|Text scrap[Grey]="Slothtext"
+00522|------ End Text Element ------
+00523|
+00524|----- End of Expression -----
+00525|
+ +-----
+
+ +-----
+00546|Macro Name : "Sloth e"
+00547|Defined? : Yes.
+00548|Parameters : 9
+ +-----
+00533|Macro Name : "Sloth with 4"
+00534|Defined? : Yes.
+00535|Parameters : 4
+ +-----
+
+ +-----
+00553|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00558|This macro has 0 body parts.
+ +-----
+00544|This macro has 1 body part.
+00545|Body part 1: Seqnum=5, Pos(L,C)=(15,3), Expression follows:
+00546|
+00547|---- Start of Expression ----
+00548|
+00549|----- Start Text Element -----
+00550|Text scrap[Grey]="Slothtext"
+00551|------ End Text Element ------
+00552|
+00553|----- End of Expression -----
+00554|
+ +-----
+
+ +-----
+00566|Macro Name : "Sloth with 2"
+00567|Defined? : Yes.
+00568|Parameters : 2
+ +-----
+00562|Macro Name : "Sloth with 5"
+00563|Defined? : Yes.
+00564|Parameters : 5
+ +-----
+
+ +-----
+00573|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00579|Body part 1: Seqnum=3, Pos(L,C)=(13,3), Expression follows:
+ +-----
+00574|Body part 1: Seqnum=6, Pos(L,C)=(16,3), Expression follows:
+ +-----
+
+ +-----
+00596|Macro Name : "Sloth with 3"
+00597|Defined? : Yes.
+00598|Parameters : 3
+ +-----
+00591|Macro Name : "Sloth with 6"
+00592|Defined? : Yes.
+00593|Parameters : 6
+ +-----
+
+ +-----
+00603|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00609|Body part 1: Seqnum=4, Pos(L,C)=(14,3), Expression follows:
+ +-----
+00603|Body part 1: Seqnum=7, Pos(L,C)=(17,3), Expression follows:
+ +-----
+
+ +-----
+00626|Macro Name : "Sloth with 4"
+00627|Defined? : Yes.
+00628|Parameters : 4
+ +-----
+00620|Macro Name : "Sloth with 7"
+00621|Defined? : Yes.
+00622|Parameters : 7
+ +-----
+
+ +-----
+00633|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00639|Body part 1: Seqnum=5, Pos(L,C)=(15,3), Expression follows:
+ +-----
+00632|Body part 1: Seqnum=8, Pos(L,C)=(18,3), Expression follows:
+ +-----
+
+ +-----
+00656|Macro Name : "Sloth with 5"
+00657|Defined? : Yes.
+00658|Parameters : 5
+ +-----
+00649|Macro Name : "Sloth with 8"
+00650|Defined? : Yes.
+00651|Parameters : 8
+ +-----
+
+ +-----
+00663|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00669|Body part 1: Seqnum=6, Pos(L,C)=(16,3), Expression follows:
+ +-----
+00661|Body part 1: Seqnum=9, Pos(L,C)=(19,3), Expression follows:
+ +-----
+
+ +-----
+00686|Macro Name : "Sloth with 6"
+00687|Defined? : Yes.
+00688|Parameters : 6
+ +-----
+00678|Macro Name : "Sloth with 9"
+00679|Defined? : Yes.
+00680|Parameters : 9
+ +-----
+
+ +-----
+00693|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00699|Body part 1: Seqnum=7, Pos(L,C)=(17,3), Expression follows:
+ +-----
+00690|Body part 1: Seqnum=10, Pos(L,C)=(20,3), Expression follows:
+ +-----
+
+ +-----
+00716|Macro Name : "Sloth with 7"
+00717|Defined? : Yes.
+00718|Parameters : 7
+ +-----
+00707|Macro Name : "Sloth with one"
+00708|Defined? : Yes.
+00709|Parameters : 1
+ +-----
+
+ +-----
+00723|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00729|Body part 1: Seqnum=8, Pos(L,C)=(18,3), Expression follows:
+ +-----
+00719|Body part 1: Seqnum=2, Pos(L,C)=(10,3), Expression follows:
+ +-----
+
+ +-----
+00745|------------------- Start of Macro Dump --------------------
+00746|Macro Name : "Sloth with 8"
+00747|Defined? : Yes.
+00748|Parameters : 8
+00749|Additive? : No.
+00750|Zero Calls? : No.
+00751|Many Calls? : No.
+00752|Output File?: No.
+00753|Automatic Line Directive Macro?: No.
+00754|Call list :
+00755|Macro body :
+00756|
+00757|--Start of List of Body Parts--
+00758|This macro has 1 body part.
+00759|Body part 1: Seqnum=9, Pos(L,C)=(19,3), Expression follows:
+00760|
+00761|---- Start of Expression ----
+00762|
+00763|----- Start Text Element -----
+00764|Text scrap[Grey]="Slothtext"
+00765|------ End Text Element ------
+00766|
+00767|----- End of Expression -----
+00768|
+00769|---End of List of Body Parts---
+00770|
+00771|-------------------- End of Macro Dump ---------------------
+00772|
+00773|
+00774|
+00775|------------------- Start of Macro Dump --------------------
+00776|Macro Name : "Sloth with 9"
+00777|Defined? : Yes.
+00778|Parameters : 9
+00779|Additive? : No.
+00780|Zero Calls? : No.
+00781|Many Calls? : No.
+00782|Output File?: No.
+00783|Automatic Line Directive Macro?: No.
+00784|Call list :
+00785|Macro body :
+00786|
+00787|--Start of List of Body Parts--
+00788|This macro has 1 body part.
+00789|Body part 1: Seqnum=10, Pos(L,C)=(20,3), Expression follows:
+00790|
+00791|---- Start of Expression ----
+00792|
+00793|----- Start Text Element -----
+00794|Text scrap[Grey]="Slothtext"
+00795|------ End Text Element ------
+00796|
+00797|----- End of Expression -----
+00798|
+00799|---End of List of Body Parts---
+00800|
+00801|-------------------- End of Macro Dump ---------------------
+00802|
+00803|
+00804|
+00805|------------------- Start of Macro Dump --------------------
+00806|Macro Name : "Sloth with one"
+00807|Defined? : Yes.
+00808|Parameters : 1
+ +-----
+00735|=========================== End of MACRO TABLE DUMP ============================
+00736|
+00737|
+00738|========================= Start of DOCUMENT LIST DUMP ==========================
+00739|
+00740|
+00741|TEXT COMPONENT: Pos(L,C)=(1,1).
+00742|
+00743|-- Start of Text Scrap List --
+00744|Text scrap[Grey]="PR05: Test the parsing of formal parameter lists.<010>
+00745|<010>
+00746|First trip the parser so we don't get past the parser.<010>
+00747|"
+00748|--- End of Text Scrap List ---
+00749|
+00750|
+00751|TEXT COMPONENT: Pos(L,C)=(4,3).
+00752|
+00753|-- Start of Text Scrap List --
+00754|Text scrap[Grey]="<010>
+00755|<010>
+00756|1. Test macro definition with no formal parameters.<010>
+00757|"
+00758|--- End of Text Scrap List ---
+00759|
+00760|
+00761|MACRO DEFINITION COMPONENT: Pos(L,C)=(7,1).
+00762|Part 1 of macro @<Sloth@>.
+00763|
+00764|TEXT COMPONENT: Pos(L,C)=(7,25).
+00765|
+00766|-- Start of Text Scrap List --
+00767|Text scrap[Grey]="<010>
+00768|<010>
+00769|2. Test macro definition with one formal parameter.<010>
+00770|"
+00771|--- End of Text Scrap List ---
+00772|
+00773|
+00774|MACRO DEFINITION COMPONENT: Pos(L,C)=(10,1).
+00775|Part 1 of macro @<Sloth with one@>.
+00776|
+00777|TEXT COMPONENT: Pos(L,C)=(10,40).
+00778|
+00779|-- Start of Text Scrap List --
+00780|Text scrap[Grey]="<010>
+00781|<010>
+00782|3. Test macro definition with many formal parameters.<010>
+00783|"
+00784|--- End of Text Scrap List ---
+00785|
+00786|
+00787|MACRO DEFINITION COMPONENT: Pos(L,C)=(13,1).
+00788|Part 1 of macro @<Sloth with 2@>.
+00789|
+00790|TEXT COMPONENT: Pos(L,C)=(13,38).
+00791|
+00792|-- Start of Text Scrap List --
+00793|Text scrap[White]="<010>
+00794|"
+00795|--- End of Text Scrap List ---
+00796|
+00797|
+00798|MACRO DEFINITION COMPONENT: Pos(L,C)=(14,1).
+ +-----
+
+ +-----
+00809|Additive? : No.
+00810|Zero Calls? : No.
+00811|Many Calls? : No.
+00812|Output File?: No.
+00813|Automatic Line Directive Macro?: No.
+00814|Call list :
+00815|Macro body :
+00816|
+00817|--Start of List of Body Parts--
+00818|This macro has 1 body part.
+00819|Body part 1: Seqnum=2, Pos(L,C)=(10,3), Expression follows:
+00820|
+00821|---- Start of Expression ----
+00822|
+00823|----- Start Text Element -----
+00824|Text scrap[Grey]="Slothtext"
+00825|------ End Text Element ------
+00826|
+00827|----- End of Expression -----
+00828|
+00829|---End of List of Body Parts---
+00830|
+00831|-------------------- End of Macro Dump ---------------------
+00832|
+00833|
+00834|
+00835|=========================== End of MACRO TABLE DUMP ============================
+00836|
+00837|
+00838|========================= Start of DOCUMENT LIST DUMP ==========================
+00839|
+00840|
+00841|TEXT COMPONENT: Pos(L,C)=(1,1).
+00842|
+00843|-- Start of Text Scrap List --
+00844|Text scrap[Grey]="PR05: Test the parsing of formal parameter lists.<010>
+00845|<010>
+00846|First trip the parser so we don't get past the parser.<010>
+ +-----
+00799|Part 1 of macro @<Sloth with 3@>.
+00800|
+00801|TEXT COMPONENT: Pos(L,C)=(14,38).
+00802|
+00803|-- Start of Text Scrap List --
+00804|Text scrap[White]="<010>
+ +-----
+
+ +-----
+00851|TEXT COMPONENT: Pos(L,C)=(4,3).
+00852|
+00853|-- Start of Text Scrap List --
+00854|Text scrap[Grey]="<010>
+00855|<010>
+00856|1. Test macro definition with no formal parameters.<010>
+ +-----
+00809|MACRO DEFINITION COMPONENT: Pos(L,C)=(15,1).
+00810|Part 1 of macro @<Sloth with 4@>.
+00811|
+00812|TEXT COMPONENT: Pos(L,C)=(15,38).
+00813|
+00814|-- Start of Text Scrap List --
+00815|Text scrap[White]="<010>
+ +-----
+
+ +-----
+00861|MACRO DEFINITION COMPONENT: Pos(L,C)=(7,1).
+00862|Part 1 of macro @<Sloth@>.
+00863|
+00864|TEXT COMPONENT: Pos(L,C)=(7,25).
+00865|
+00866|-- Start of Text Scrap List --
+00867|Text scrap[Grey]="<010>
+00868|<010>
+00869|2. Test macro definition with one formal parameter.<010>
+ +-----
+00820|MACRO DEFINITION COMPONENT: Pos(L,C)=(16,1).
+00821|Part 1 of macro @<Sloth with 5@>.
+00822|
+00823|TEXT COMPONENT: Pos(L,C)=(16,38).
+00824|
+00825|-- Start of Text Scrap List --
+00826|Text scrap[White]="<010>
+ +-----
+
+ +-----
+00874|MACRO DEFINITION COMPONENT: Pos(L,C)=(10,1).
+00875|Part 1 of macro @<Sloth with one@>.
+00876|
+00877|TEXT COMPONENT: Pos(L,C)=(10,40).
+00878|
+00879|-- Start of Text Scrap List --
+00880|Text scrap[Grey]="<010>
+00881|<010>
+00882|3. Test macro definition with many formal parameters.<010>
+ +-----
+00831|MACRO DEFINITION COMPONENT: Pos(L,C)=(17,1).
+00832|Part 1 of macro @<Sloth with 6@>.
+00833|
+00834|TEXT COMPONENT: Pos(L,C)=(17,38).
+00835|
+00836|-- Start of Text Scrap List --
+00837|Text scrap[White]="<010>
+ +-----
+
+ +-----
+00887|MACRO DEFINITION COMPONENT: Pos(L,C)=(13,1).
+00888|Part 1 of macro @<Sloth with 2@>.
+00889|
+00890|TEXT COMPONENT: Pos(L,C)=(13,38).
+ +-----
+00842|MACRO DEFINITION COMPONENT: Pos(L,C)=(18,1).
+00843|Part 1 of macro @<Sloth with 7@>.
+00844|
+00845|TEXT COMPONENT: Pos(L,C)=(18,38).
+ +-----
+
+ +-----
+00898|MACRO DEFINITION COMPONENT: Pos(L,C)=(14,1).
+00899|Part 1 of macro @<Sloth with 3@>.
+00900|
+00901|TEXT COMPONENT: Pos(L,C)=(14,38).
+ +-----
+00853|MACRO DEFINITION COMPONENT: Pos(L,C)=(19,1).
+00854|Part 1 of macro @<Sloth with 8@>.
+00855|
+00856|TEXT COMPONENT: Pos(L,C)=(19,38).
+ +-----
+
+ +-----
+00909|MACRO DEFINITION COMPONENT: Pos(L,C)=(15,1).
+00910|Part 1 of macro @<Sloth with 4@>.
+00911|
+00912|TEXT COMPONENT: Pos(L,C)=(15,38).
+00913|
+00914|-- Start of Text Scrap List --
+00915|Text scrap[White]="<010>
+ +-----
+00864|MACRO DEFINITION COMPONENT: Pos(L,C)=(20,1).
+00865|Part 1 of macro @<Sloth with 9@>.
+00866|
+00867|TEXT COMPONENT: Pos(L,C)=(20,38).
+00868|
+00869|-- Start of Text Scrap List --
+00870|Text scrap[Grey]="<010>
+00871|<010>
+00872|4. Test with syntax errors in the parameter list.<010>
+00873|<010>
+ +-----
+
+ +-----
+00920|MACRO DEFINITION COMPONENT: Pos(L,C)=(16,1).
+00921|Part 1 of macro @<Sloth with 5@>.
+00922|
+00923|TEXT COMPONENT: Pos(L,C)=(16,38).
+ +-----
+00878|TYPESETTER DIRECTIVE COMPONENT:
+00879| Section "1", Section name="Error recovery point".
+00880|
+00881|TEXT COMPONENT: Pos(L,C)=(25,27).
+ +-----
+
+ +-----
+ +-----
+00885|<010>
+ +-----
+
+ +-----
+00931|MACRO DEFINITION COMPONENT: Pos(L,C)=(17,1).
+00932|Part 1 of macro @<Sloth with 6@>.
+00933|
+00934|TEXT COMPONENT: Pos(L,C)=(17,38).
+ +-----
+00890|TYPESETTER DIRECTIVE COMPONENT:
+00891| Section "2", Section name="Error recovery point".
+00892|
+00893|TEXT COMPONENT: Pos(L,C)=(28,27).
+ +-----
+
+ +-----
+ +-----
+00897|<010>
+ +-----
+
+ +-----
+00942|MACRO DEFINITION COMPONENT: Pos(L,C)=(18,1).
+00943|Part 1 of macro @<Sloth with 7@>.
+00944|
+00945|TEXT COMPONENT: Pos(L,C)=(18,38).
+ +-----
+00902|TYPESETTER DIRECTIVE COMPONENT:
+00903| Section "3", Section name="Error recovery point".
+00904|
+00905|TEXT COMPONENT: Pos(L,C)=(31,27).
+ +-----
+
+ +-----
+ +-----
+00909|<010>
+ +-----
+
+ +-----
+00953|MACRO DEFINITION COMPONENT: Pos(L,C)=(19,1).
+00954|Part 1 of macro @<Sloth with 8@>.
+00955|
+00956|TEXT COMPONENT: Pos(L,C)=(19,38).
+ +-----
+00914|TYPESETTER DIRECTIVE COMPONENT:
+00915| Section "4", Section name="Error recovery point".
+00916|
+00917|TEXT COMPONENT: Pos(L,C)=(34,27).
+ +-----
+
+ +-----
+ +-----
+00921|<010>
+ +-----
+
+ +-----
+00964|MACRO DEFINITION COMPONENT: Pos(L,C)=(20,1).
+00965|Part 1 of macro @<Sloth with 9@>.
+00966|
+00967|TEXT COMPONENT: Pos(L,C)=(20,38).
+00968|
+00969|-- Start of Text Scrap List --
+00970|Text scrap[Grey]="<010>
+00971|<010>
+00972|4. Test with syntax errors in the parameter list.<010>
+ +-----
+00926|TYPESETTER DIRECTIVE COMPONENT:
+00927| Section "5", Section name="Error recovery point".
+00928|
+00929|TEXT COMPONENT: Pos(L,C)=(37,27).
+00930|
+00931|-- Start of Text Scrap List --
+00932|Text scrap[White]="<010>
+00933|<010>
+00934|<010>
+ +-----
+
+ +-----
+00978|TYPESETTER DIRECTIVE COMPONENT:
+00979| Section "1", Section name="Error recovery point".
+00980|
+00981|TEXT COMPONENT: Pos(L,C)=(25,27).
+00982|
+00983|-- Start of Text Scrap List --
+00984|Text scrap[White]="<010>
+00985|<010>
+00986|"
+00987|--- End of Text Scrap List ---
+00988|
+00989|
+00990|TYPESETTER DIRECTIVE COMPONENT:
+00991| Section "2", Section name="Error recovery point".
+00992|
+00993|TEXT COMPONENT: Pos(L,C)=(28,27).
+00994|
+00995|-- Start of Text Scrap List --
+00996|Text scrap[White]="<010>
+00997|<010>
+00998|"
+00999|--- End of Text Scrap List ---
+01000|
+01001|
+01002|TYPESETTER DIRECTIVE COMPONENT:
+01003| Section "3", Section name="Error recovery point".
+01004|
+01005|TEXT COMPONENT: Pos(L,C)=(31,27).
+01006|
+01007|-- Start of Text Scrap List --
+01008|Text scrap[White]="<010>
+01009|<010>
+01010|"
+01011|--- End of Text Scrap List ---
+01012|
+01013|
+01014|TYPESETTER DIRECTIVE COMPONENT:
+01015| Section "4", Section name="Error recovery point".
+01016|
+01017|TEXT COMPONENT: Pos(L,C)=(34,27).
+01018|
+01019|-- Start of Text Scrap List --
+01020|Text scrap[White]="<010>
+01021|<010>
+01022|"
+01023|--- End of Text Scrap List ---
+01024|
+01025|
+01026|TYPESETTER DIRECTIVE COMPONENT:
+01027| Section "5", Section name="Error recovery point".
+01028|
+01029|TEXT COMPONENT: Pos(L,C)=(37,27).
+01030|
+01031|-- Start of Text Scrap List --
+01032|Text scrap[White]="<010>
+01033|<010>
+01034|<010>
+01035|<010>
+01036|"
+01037|--- End of Text Scrap List ---
+01038|
+01039|
+01040|========================== End of DOCUMENT LIST DUMP ===========================
+01041|
+ +-----
+00940|========================== End of DOCUMENT LIST DUMP ===========================
+00941|
+00942|
+00943|Global Local| Input File
+00944|------------+-------------------------------------------------------------------
+00945| 1 1| PR05: Test the parsing of formal parameter lists.
+00946| 2 2|
+00947| 3 3| First trip the parser so we don't get past the parser.
+00948| 4 4| @>
+00949| Error|.^The parser was at the top level and was expecting
+00950| |.^one of: {Directive, Text, Macro definition, EOF}.
+00951| 5 5|
+00952| 6 6| 1. Test macro definition with no formal parameters.
+00953| 7 7| @$@<Sloth@>@{Slothtext@}
+00954| 8 8|
+00955| 9 9| 2. Test macro definition with one formal parameter.
+00956| 10 10| @$@<Sloth with one@>@(@1@)@{Slothtext@}
+00957| 11 11|
+00958| 12 12| 3. Test macro definition with many formal parameters.
+00959| 13 13| @$@<Sloth with 2@>@(@2@)@{Slothtext@}
+00960| 14 14| @$@<Sloth with 3@>@(@3@)@{Slothtext@}
+00961| 15 15| @$@<Sloth with 4@>@(@4@)@{Slothtext@}
+00962| 16 16| @$@<Sloth with 5@>@(@5@)@{Slothtext@}
+00963| 17 17| @$@<Sloth with 6@>@(@6@)@{Slothtext@}
+00964| 18 18| @$@<Sloth with 7@>@(@7@)@{Slothtext@}
+00965| 19 19| @$@<Sloth with 8@>@(@8@)@{Slothtext@}
+00966| 20 20| @$@<Sloth with 9@>@(@9@)@{Slothtext@}
+00967| 21 21|
+00968| 22 22| 4. Test with syntax errors in the parameter list.
+00969| 23 23|
+00970| 24 24| @$@<Sloth a@>@(@+@9@)@{Slothtext@}
+00971| Error|................^Expecting one of [@1..@9].
+00972| |................^Skipping after error to the next major construct...
+00973| 25 25| @A@<Error recovery point@>
+00974| |.^...skipped to here after the error.
+00975| 26 26|
+00976| 27 27| @$@<Sloth b@>@9@)@{Slothtext@}
+00977| Error|..............^Expecting '@{'.
+00978| |..............^Skipping after error to the next major construct...
+00979| 28 28| @A@<Error recovery point@>
+00980| |.^...skipped to here after the error.
+00981| 29 29|
+00982| 30 30| @$@<Sloth c@>@(9@)@{Slothtext@}
+00983| Error|................^Expecting one of [@1..@9].
+00984| |................^Skipping after error to the next major construct...
+00985| 31 31| @A@<Error recovery point@>
+00986| |.^...skipped to here after the error.
+00987| 32 32|
+00988| 33 33| @$@<Sloth d@>@9@)@{Slothtext@}
+00989| Error|..............^Expecting '@{'.
+00990| |..............^Skipping after error to the next major construct...
+00991| 34 34| @A@<Error recovery point@>
+00992| |.^...skipped to here after the error.
+00993| 35 35|
+00994| 36 36| @$@<Sloth e@>@(@9@)@)@{Slothtext@}
+00995| Error|....................^Expecting '@{'.
+00996| |....................^Skipping after error to the next major construct...
+00997| 37 37| @A@<Error recovery point@>
+00998| |.^...skipped to here after the error.
+00999| 38 38|
+01000| 39 39|
+01001| 40 40|
+01002| | <End-Of-File>
+01003|------------+-------------------------------------------------------------------
+ +-----
+
+ +-----
+01043|Global Local| Input File
+01044|------------+-------------------------------------------------------------------
+01045| 1 1| PR05: Test the parsing of formal parameter lists.
+01046| 2 2|
+01047| 3 3| First trip the parser so we don't get past the parser.
+01048| 4 4| @>
+01049| Error|.^The parser was at the top level and was expecting
+01050| |.^one of: {Directive, Text, Macro definition, EOF}.
+01051| 5 5|
+01052| 6 6| 1. Test macro definition with no formal parameters.
+01053| 7 7| @$@<Sloth@>@{Slothtext@}
+01054| 8 8|
+01055| 9 9| 2. Test macro definition with one formal parameter.
+01056| 10 10| @$@<Sloth with one@>@(@1@)@{Slothtext@}
+01057| 11 11|
+01058| 12 12| 3. Test macro definition with many formal parameters.
+01059| 13 13| @$@<Sloth with 2@>@(@2@)@{Slothtext@}
+01060| 14 14| @$@<Sloth with 3@>@(@3@)@{Slothtext@}
+01061| 15 15| @$@<Sloth with 4@>@(@4@)@{Slothtext@}
+01062| 16 16| @$@<Sloth with 5@>@(@5@)@{Slothtext@}
+01063| 17 17| @$@<Sloth with 6@>@(@6@)@{Slothtext@}
+01064| 18 18| @$@<Sloth with 7@>@(@7@)@{Slothtext@}
+01065| 19 19| @$@<Sloth with 8@>@(@8@)@{Slothtext@}
+01066| 20 20| @$@<Sloth with 9@>@(@9@)@{Slothtext@}
+01067| 21 21|
+01068| 22 22| 4. Test with syntax errors in the parameter list.
+01069| 23 23|
+01070| 24 24| @$@<Sloth a@>@(@+@9@)@{Slothtext@}
+01071| Error|................^Expecting one of [@1..@9].
+01072| |................^Skipping after error to the next major construct...
+01073| 25 25| @A@<Error recovery point@>
+01074| |.^...skipped to here after the error.
+01075| 26 26|
+01076| 27 27| @$@<Sloth b@>@9@)@{Slothtext@}
+01077| Error|..............^Expecting '@{'.
+01078| |..............^Skipping after error to the next major construct...
+01079| 28 28| @A@<Error recovery point@>
+01080| |.^...skipped to here after the error.
+01081| 29 29|
+01082| 30 30| @$@<Sloth c@>@(9@)@{Slothtext@}
+01083| Error|................^Expecting one of [@1..@9].
+01084| |................^Skipping after error to the next major construct...
+01085| 31 31| @A@<Error recovery point@>
+01086| |.^...skipped to here after the error.
+01087| 32 32|
+01088| 33 33| @$@<Sloth d@>@9@)@{Slothtext@}
+01089| Error|..............^Expecting '@{'.
+01090| |..............^Skipping after error to the next major construct...
+01091| 34 34| @A@<Error recovery point@>
+01092| |.^...skipped to here after the error.
+01093| 35 35|
+01094| 36 36| @$@<Sloth e@>@(@9@)@)@{Slothtext@}
+01095| Error|....................^Expecting '@{'.
+01096| |....................^Skipping after error to the next major construct...
+01097| 37 37| @A@<Error recovery point@>
+01098| |.^...skipped to here after the error.
+01099| 38 38|
+01100| 39 39|
+01101| 40 40|
+01102| | <End-Of-File>
+01103|------------+-------------------------------------------------------------------
+01104|
+01105|There were 6 Errors.
+ +-----
+01005|There were 6 Errors.
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/pr06.lis"
+ with "/usr/var/tmp/funnelweb/answers/pr06.lis".
+
+ +-----
+00305|Macro Name : "#file"
+ +-----
+00305|Macro Name : "Sloth"
+ +-----
+
+ +-----
+00309|Zero Calls? : Yes.
+00310|Many Calls? : Yes.
+00311|Output File?: No.
+00312|Automatic Line Directive Macro?: No.
+ +-----
+00309|Zero Calls? : No.
+00310|Many Calls? : No.
+00311|Output File?: No.
+ +-----
+
+ +-----
+00318|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+ +-----
+00317|Body part 1: Seqnum=1, Pos(L,C)=(7,3), Expression follows:
+ +-----
+
+ +-----
+00322|--- Start Special Function ---
+00323|---- End Special Function ----
+ +-----
+00321|----- Start Text Element -----
+00322|Text scrap[Grey]="No zero and no many in this macro"
+00323|------ End Text Element ------
+ +-----
+
+ +-----
+00334|Macro Name : "#line"
+ +-----
+00334|Macro Name : "Sloth a"
+00335|Defined? : No.
+00336|-------------------- End of Macro Dump ---------------------
+00337|
+00338|
+00339|
+00340|------------------- Start of Macro Dump --------------------
+00341|Macro Name : "Sloth b"
+ +-----
+
+ +-----
+00339|Many Calls? : Yes.
+00340|Output File?: No.
+00341|Automatic Line Directive Macro?: No.
+ +-----
+00346|Many Calls? : No.
+00347|Output File?: No.
+ +-----
+
+ +-----
+00346|This macro has 1 body part.
+00347|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00348|
+00349|---- Start of Expression ----
+00350|
+00351|--- Start Special Function ---
+00352|---- End Special Function ----
+00353|
+00354|----- End of Expression -----
+00355|
+ +-----
+00352|This macro has 0 body parts.
+ +-----
+
+ +-----
+00363|Macro Name : "#timestamp"
+ +-----
+00360|Macro Name : "Sloth d"
+00361|Defined? : No.
+00362|-------------------- End of Macro Dump ---------------------
+00363|
+00364|
+00365|
+00366|------------------- Start of Macro Dump --------------------
+00367|Macro Name : "Sloth many"
+ +-----
+
+ +-----
+00367|Zero Calls? : Yes.
+00368|Many Calls? : Yes.
+00369|Output File?: No.
+00370|Automatic Line Directive Macro?: No.
+ +-----
+00371|Zero Calls? : No.
+00372|Many Calls? : Yes.
+00373|Output File?: No.
+ +-----
+
+ +-----
+00376|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+ +-----
+00379|Body part 1: Seqnum=3, Pos(L,C)=(13,3), Expression follows:
+ +-----
+
+ +-----
+00380|--- Start Special Function ---
+00381|---- End Special Function ----
+ +-----
+00383|----- Start Text Element -----
+00384|Text scrap[Grey]="Can be called from 1 to infinity times."
+00385|------ End Text Element ------
+ +-----
+
+ +-----
+00392|Macro Name : "Sloth"
+ +-----
+00396|Macro Name : "Sloth manyzero"
+ +-----
+
+ +-----
+00397|Many Calls? : No.
+00398|Output File?: No.
+00399|Automatic Line Directive Macro?: No.
+ +-----
+00401|Many Calls? : Yes.
+00402|Output File?: No.
+ +-----
+
+ +-----
+00404|This macro has 1 body part.
+00405|Body part 1: Seqnum=1, Pos(L,C)=(7,3), Expression follows:
+00406|
+00407|---- Start of Expression ----
+00408|
+00409|----- Start Text Element -----
+00410|Text scrap[Grey]="No zero and no many in this macro"
+00411|------ End Text Element ------
+00412|
+00413|----- End of Expression -----
+00414|
+ +-----
+00407|This macro has 0 body parts.
+ +-----
+
+ +-----
+00422|Macro Name : "Sloth a"
+00423|Defined? : No.
+00424|-------------------- End of Macro Dump ---------------------
+00425|
+00426|
+00427|
+00428|------------------- Start of Macro Dump --------------------
+00429|Macro Name : "Sloth b"
+ +-----
+00415|Macro Name : "Sloth zero"
+ +-----
+
+ +-----
+00436|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00441|This macro has 0 body parts.
+ +-----
+00426|This macro has 1 body part.
+00427|Body part 1: Seqnum=2, Pos(L,C)=(10,3), Expression follows:
+00428|
+00429|---- Start of Expression ----
+00430|
+00431|----- Start Text Element -----
+00432|Text scrap[Grey]="Can be called from 0 to 1 times."
+00433|------ End Text Element ------
+00434|
+00435|----- End of Expression -----
+00436|
+ +-----
+
+ +-----
+00449|Macro Name : "Sloth d"
+00450|Defined? : No.
+00451|-------------------- End of Macro Dump ---------------------
+00452|
+00453|
+00454|
+00455|------------------- Start of Macro Dump --------------------
+00456|Macro Name : "Sloth many"
+ +-----
+00444|Macro Name : "Sloth zeromany"
+ +-----
+
+ +-----
+00460|Zero Calls? : No.
+00461|Many Calls? : Yes.
+00462|Output File?: No.
+00463|Automatic Line Directive Macro?: No.
+ +-----
+00448|Zero Calls? : Yes.
+00449|Many Calls? : Yes.
+00450|Output File?: No.
+ +-----
+
+ +-----
+00469|Body part 1: Seqnum=3, Pos(L,C)=(13,3), Expression follows:
+ +-----
+00456|Body part 1: Seqnum=4, Pos(L,C)=(16,3), Expression follows:
+ +-----
+
+ +-----
+00474|Text scrap[Grey]="Can be called from 1 to infinity times."
+ +-----
+00461|Text scrap[Grey]="Can be called from 0 to infinity times."
+ +-----
+
+ +-----
+00485|------------------- Start of Macro Dump --------------------
+00486|Macro Name : "Sloth manyzero"
+00487|Defined? : Yes.
+00488|Parameters : 0
+00489|Additive? : No.
+00490|Zero Calls? : No.
+00491|Many Calls? : Yes.
+00492|Output File?: No.
+00493|Automatic Line Directive Macro?: No.
+00494|Call list :
+00495|Macro body :
+00496|
+00497|--Start of List of Body Parts--
+00498|This macro has 0 body parts.
+00499|---End of List of Body Parts---
+00500|
+00501|-------------------- End of Macro Dump ---------------------
+00502|
+00503|
+00504|
+00505|------------------- Start of Macro Dump --------------------
+00506|Macro Name : "Sloth zero"
+00507|Defined? : Yes.
+00508|Parameters : 0
+00509|Additive? : No.
+00510|Zero Calls? : Yes.
+00511|Many Calls? : No.
+00512|Output File?: No.
+00513|Automatic Line Directive Macro?: No.
+00514|Call list :
+00515|Macro body :
+00516|
+00517|--Start of List of Body Parts--
+00518|This macro has 1 body part.
+00519|Body part 1: Seqnum=2, Pos(L,C)=(10,3), Expression follows:
+00520|
+00521|---- Start of Expression ----
+00522|
+00523|----- Start Text Element -----
+00524|Text scrap[Grey]="Can be called from 0 to 1 times."
+00525|------ End Text Element ------
+00526|
+00527|----- End of Expression -----
+00528|
+00529|---End of List of Body Parts---
+00530|
+00531|-------------------- End of Macro Dump ---------------------
+00532|
+00533|
+00534|
+00535|------------------- Start of Macro Dump --------------------
+00536|Macro Name : "Sloth zeromany"
+00537|Defined? : Yes.
+00538|Parameters : 0
+00539|Additive? : No.
+00540|Zero Calls? : Yes.
+00541|Many Calls? : Yes.
+00542|Output File?: No.
+00543|Automatic Line Directive Macro?: No.
+00544|Call list :
+00545|Macro body :
+00546|
+00547|--Start of List of Body Parts--
+00548|This macro has 1 body part.
+ +-----
+00472|=========================== End of MACRO TABLE DUMP ============================
+00473|
+00474|
+00475|========================= Start of DOCUMENT LIST DUMP ==========================
+00476|
+00477|
+00478|TEXT COMPONENT: Pos(L,C)=(1,1).
+00479|
+00480|-- Start of Text Scrap List --
+00481|Text scrap[Grey]="PR06: Test the parsing on invocation number constraints.<010>
+00482|<010>
+00483|Trip the parser so we don't get past it.<010>
+00484|"
+00485|--- End of Text Scrap List ---
+00486|
+00487|
+00488|TEXT COMPONENT: Pos(L,C)=(4,3).
+00489|
+00490|-- Start of Text Scrap List --
+00491|Text scrap[Grey]="<010>
+00492|<010>
+00493|1. Test with no zero and no many.<010>
+00494|"
+00495|--- End of Text Scrap List ---
+00496|
+00497|
+00498|MACRO DEFINITION COMPONENT: Pos(L,C)=(7,1).
+00499|Part 1 of macro @<Sloth@>.
+00500|
+00501|TEXT COMPONENT: Pos(L,C)=(7,49).
+00502|
+00503|-- Start of Text Scrap List --
+00504|Text scrap[Grey]="<010>
+00505|<010>
+00506|2. Test with a zero.<010>
+00507|"
+00508|--- End of Text Scrap List ---
+00509|
+00510|
+00511|MACRO DEFINITION COMPONENT: Pos(L,C)=(10,1).
+00512|Part 1 of macro @<Sloth zero@>.
+00513|
+00514|TEXT COMPONENT: Pos(L,C)=(10,55).
+00515|
+00516|-- Start of Text Scrap List --
+00517|Text scrap[Grey]="<010>
+00518|<010>
+00519|3. Test with a many.<010>
+00520|"
+00521|--- End of Text Scrap List ---
+00522|
+00523|
+00524|MACRO DEFINITION COMPONENT: Pos(L,C)=(13,1).
+00525|Part 1 of macro @<Sloth many@>.
+00526|
+00527|TEXT COMPONENT: Pos(L,C)=(13,62).
+00528|
+00529|-- Start of Text Scrap List --
+00530|Text scrap[Grey]="<010>
+00531|<010>
+00532|4. Test with a zero and a many.<010>
+00533|"
+00534|--- End of Text Scrap List ---
+00535|
+ +-----
+
+ +-----
+00549|Body part 1: Seqnum=4, Pos(L,C)=(16,3), Expression follows:
+00550|
+00551|---- Start of Expression ----
+00552|
+00553|----- Start Text Element -----
+00554|Text scrap[Grey]="Can be called from 0 to infinity times."
+00555|------ End Text Element ------
+00556|
+00557|----- End of Expression -----
+00558|
+00559|---End of List of Body Parts---
+00560|
+00561|-------------------- End of Macro Dump ---------------------
+00562|
+00563|
+00564|
+00565|=========================== End of MACRO TABLE DUMP ============================
+00566|
+00567|
+00568|========================= Start of DOCUMENT LIST DUMP ==========================
+00569|
+00570|
+00571|TEXT COMPONENT: Pos(L,C)=(1,1).
+00572|
+00573|-- Start of Text Scrap List --
+00574|Text scrap[Grey]="PR06: Test the parsing on invocation number constraints.<010>
+00575|<010>
+00576|Trip the parser so we don't get past it.<010>
+ +-----
+00536|
+00537|MACRO DEFINITION COMPONENT: Pos(L,C)=(16,1).
+00538|Part 1 of macro @<Sloth zeromany@>.
+00539|
+00540|TEXT COMPONENT: Pos(L,C)=(16,68).
+00541|
+00542|-- Start of Text Scrap List --
+00543|Text scrap[Grey]="<010>
+00544|<010>
+00545|5. Test with a zero and a many but out of order (should give error).<010>
+ +-----
+
+ +-----
+00581|TEXT COMPONENT: Pos(L,C)=(4,3).
+ +-----
+00550|TYPESETTER DIRECTIVE COMPONENT:
+00551| Section "1", Section name="Error recovery point".
+00552|
+00553|TEXT COMPONENT: Pos(L,C)=(20,27).
+ +-----
+
+ +-----
+00586|1. Test with no zero and no many.<010>
+ +-----
+00558|6. Test with syntactic errors.<010>
+00559|<010>
+ +-----
+
+ +-----
+00591|MACRO DEFINITION COMPONENT: Pos(L,C)=(7,1).
+00592|Part 1 of macro @<Sloth@>.
+00593|
+00594|TEXT COMPONENT: Pos(L,C)=(7,49).
+00595|
+00596|-- Start of Text Scrap List --
+00597|Text scrap[Grey]="<010>
+00598|<010>
+00599|2. Test with a zero.<010>
+ +-----
+00564|TYPESETTER DIRECTIVE COMPONENT:
+00565| Section "2", Section name="Error recovery point".
+00566|
+00567|TEXT COMPONENT: Pos(L,C)=(25,27).
+00568|
+00569|-- Start of Text Scrap List --
+00570|Text scrap[White]="<010>
+00571|<010>
+ +-----
+
+ +-----
+00604|MACRO DEFINITION COMPONENT: Pos(L,C)=(10,1).
+00605|Part 1 of macro @<Sloth zero@>.
+00606|
+00607|TEXT COMPONENT: Pos(L,C)=(10,55).
+00608|
+00609|-- Start of Text Scrap List --
+00610|Text scrap[Grey]="<010>
+00611|<010>
+00612|3. Test with a many.<010>
+ +-----
+00576|TYPESETTER DIRECTIVE COMPONENT:
+00577| Section "3", Section name="Error recovery point".
+00578|
+00579|TEXT COMPONENT: Pos(L,C)=(28,27).
+00580|
+00581|-- Start of Text Scrap List --
+00582|Text scrap[White]="<010>
+00583|<010>
+ +-----
+
+ +-----
+00617|MACRO DEFINITION COMPONENT: Pos(L,C)=(13,1).
+00618|Part 1 of macro @<Sloth many@>.
+00619|
+00620|TEXT COMPONENT: Pos(L,C)=(13,62).
+00621|
+00622|-- Start of Text Scrap List --
+00623|Text scrap[Grey]="<010>
+00624|<010>
+00625|4. Test with a zero and a many.<010>
+ +-----
+00588|TYPESETTER DIRECTIVE COMPONENT:
+00589| Section "4", Section name="Error recovery point".
+00590|
+00591|TEXT COMPONENT: Pos(L,C)=(31,27).
+00592|
+00593|-- Start of Text Scrap List --
+00594|Text scrap[White]="<010>
+00595|<010>
+ +-----
+
+ +-----
+00630|MACRO DEFINITION COMPONENT: Pos(L,C)=(16,1).
+00631|Part 1 of macro @<Sloth zeromany@>.
+00632|
+00633|TEXT COMPONENT: Pos(L,C)=(16,68).
+00634|
+00635|-- Start of Text Scrap List --
+00636|Text scrap[Grey]="<010>
+00637|<010>
+00638|5. Test with a zero and a many but out of order (should give error).<010>
+ +-----
+00600|TYPESETTER DIRECTIVE COMPONENT:
+00601| Section "5", Section name="Error recovery point".
+00602|
+00603|TEXT COMPONENT: Pos(L,C)=(34,27).
+00604|
+00605|-- Start of Text Scrap List --
+00606|Text scrap[White]="<010>
+00607|<010>
+ +-----
+
+ +-----
+00644| Section "1", Section name="Error recovery point".
+00645|
+00646|TEXT COMPONENT: Pos(L,C)=(20,27).
+00647|
+00648|-- Start of Text Scrap List --
+00649|Text scrap[Grey]="<010>
+00650|<010>
+00651|6. Test with syntactic errors.<010>
+ +-----
+00613| Section "6", Section name="Error recovery point".
+00614|
+00615|TEXT COMPONENT: Pos(L,C)=(37,27).
+00616|
+00617|-- Start of Text Scrap List --
+00618|Text scrap[White]="<010>
+00619|<010>
+ +-----
+
+ +-----
+00657|TYPESETTER DIRECTIVE COMPONENT:
+00658| Section "2", Section name="Error recovery point".
+00659|
+00660|TEXT COMPONENT: Pos(L,C)=(25,27).
+00661|
+00662|-- Start of Text Scrap List --
+00663|Text scrap[White]="<010>
+00664|<010>
+00665|"
+00666|--- End of Text Scrap List ---
+00667|
+00668|
+00669|TYPESETTER DIRECTIVE COMPONENT:
+00670| Section "3", Section name="Error recovery point".
+00671|
+00672|TEXT COMPONENT: Pos(L,C)=(28,27).
+00673|
+00674|-- Start of Text Scrap List --
+00675|Text scrap[White]="<010>
+00676|<010>
+00677|"
+00678|--- End of Text Scrap List ---
+00679|
+00680|
+00681|TYPESETTER DIRECTIVE COMPONENT:
+00682| Section "4", Section name="Error recovery point".
+00683|
+00684|TEXT COMPONENT: Pos(L,C)=(31,27).
+00685|
+00686|-- Start of Text Scrap List --
+00687|Text scrap[White]="<010>
+00688|<010>
+00689|"
+00690|--- End of Text Scrap List ---
+00691|
+00692|
+00693|TYPESETTER DIRECTIVE COMPONENT:
+00694| Section "5", Section name="Error recovery point".
+00695|
+00696|TEXT COMPONENT: Pos(L,C)=(34,27).
+00697|
+00698|-- Start of Text Scrap List --
+00699|Text scrap[White]="<010>
+00700|<010>
+00701|"
+00702|--- End of Text Scrap List ---
+00703|
+00704|
+00705|TYPESETTER DIRECTIVE COMPONENT:
+00706| Section "6", Section name="Error recovery point".
+00707|
+00708|TEXT COMPONENT: Pos(L,C)=(37,27).
+00709|
+00710|-- Start of Text Scrap List --
+00711|Text scrap[White]="<010>
+00712|<010>
+00713|<010>
+00714|"
+00715|--- End of Text Scrap List ---
+00716|
+00717|
+ +-----
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/pr07.lis"
+ with "/usr/var/tmp/funnelweb/answers/pr07.lis".
+
+ +-----
+00283|Macro Name : "#file"
+00284|Defined? : Yes.
+00285|Parameters : 0
+00286|Additive? : No.
+00287|Zero Calls? : Yes.
+00288|Many Calls? : Yes.
+00289|Output File?: No.
+00290|Automatic Line Directive Macro?: No.
+00291|Call list :
+00292|Macro body :
+00293|
+00294|--Start of List of Body Parts--
+00295|This macro has 1 body part.
+00296|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00297|
+00298|---- Start of Expression ----
+00299|
+00300|--- Start Special Function ---
+00301|---- End Special Function ----
+00302|
+00303|----- End of Expression -----
+00304|
+00305|---End of List of Body Parts---
+00306|
+ +-----
+00283|Macro Name : "Error1"
+00284|Defined? : No.
+ +-----
+
+ +-----
+00312|Macro Name : "#line"
+ +-----
+00290|Macro Name : "Error2"
+00291|Defined? : No.
+00292|-------------------- End of Macro Dump ---------------------
+00293|
+00294|
+00295|
+00296|------------------- Start of Macro Dump --------------------
+00297|Macro Name : "Error3"
+00298|Defined? : No.
+00299|-------------------- End of Macro Dump ---------------------
+00300|
+00301|
+00302|
+00303|------------------- Start of Macro Dump --------------------
+00304|Macro Name : "Error4"
+00305|Defined? : No.
+00306|-------------------- End of Macro Dump ---------------------
+00307|
+00308|
+00309|
+00310|------------------- Start of Macro Dump --------------------
+00311|Macro Name : "Sloth"
+ +-----
+
+ +-----
+00316|Zero Calls? : Yes.
+00317|Many Calls? : Yes.
+00318|Output File?: No.
+00319|Automatic Line Directive Macro?: No.
+ +-----
+00315|Zero Calls? : No.
+00316|Many Calls? : No.
+00317|Output File?: No.
+ +-----
+
+ +-----
+00325|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+ +-----
+00323|Body part 1: Seqnum=1, Pos(L,C)=(7,3), Expression follows:
+ +-----
+
+ +-----
+00329|--- Start Special Function ---
+00330|---- End Special Function ----
+ +-----
+00327|----- Start Text Element -----
+00328|Text scrap[Grey]="No equals in this macro definition."
+00329|------ End Text Element ------
+ +-----
+
+ +-----
+00341|Macro Name : "#timestamp"
+ +-----
+00340|Macro Name : "Sloth with equals"
+ +-----
+
+ +-----
+00345|Zero Calls? : Yes.
+00346|Many Calls? : Yes.
+00347|Output File?: No.
+00348|Automatic Line Directive Macro?: No.
+ +-----
+00344|Zero Calls? : No.
+00345|Many Calls? : No.
+00346|Output File?: No.
+ +-----
+
+ +-----
+00354|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+ +-----
+00352|Body part 1: Seqnum=2, Pos(L,C)=(10,3), Expression follows:
+ +-----
+
+ +-----
+00358|--- Start Special Function ---
+00359|---- End Special Function ----
+ +-----
+00356|----- Start Text Element -----
+00357|Text scrap[Grey]="No equals in this macro definition."
+00358|------ End Text Element ------
+ +-----
+
+ +-----
+00370|Macro Name : "Error1"
+00371|Defined? : No.
+ +-----
+00369|Macro Name : "Sloth with plus"
+00370|Defined? : Yes.
+00371|Parameters : 0
+00372|Additive? : Yes.
+00373|Zero Calls? : No.
+00374|Many Calls? : No.
+00375|Output File?: No.
+00376|Call list :
+00377|Macro body :
+00378|
+00379|--Start of List of Body Parts--
+00380|This macro has 1 body part.
+00381|Body part 1: Seqnum=3, Pos(L,C)=(13,3), Expression follows:
+00382|
+00383|---- Start of Expression ----
+00384|
+00385|----- Start Text Element -----
+00386|Text scrap[Grey]="No equals in this macro definition."
+00387|------ End Text Element ------
+00388|
+00389|----- End of Expression -----
+00390|
+00391|---End of List of Body Parts---
+00392|
+ +-----
+
+ +-----
+00376|------------------- Start of Macro Dump --------------------
+00377|Macro Name : "Error2"
+00378|Defined? : No.
+00379|-------------------- End of Macro Dump ---------------------
+00380|
+00381|
+00382|
+00383|------------------- Start of Macro Dump --------------------
+00384|Macro Name : "Error3"
+00385|Defined? : No.
+00386|-------------------- End of Macro Dump ---------------------
+00387|
+00388|
+00389|
+00390|------------------- Start of Macro Dump --------------------
+00391|Macro Name : "Error4"
+00392|Defined? : No.
+00393|-------------------- End of Macro Dump ---------------------
+00394|
+00395|
+00396|
+00397|------------------- Start of Macro Dump --------------------
+00398|Macro Name : "Sloth"
+00399|Defined? : Yes.
+00400|Parameters : 0
+00401|Additive? : No.
+00402|Zero Calls? : No.
+00403|Many Calls? : No.
+00404|Output File?: No.
+00405|Automatic Line Directive Macro?: No.
+00406|Call list :
+00407|Macro body :
+00408|
+00409|--Start of List of Body Parts--
+00410|This macro has 1 body part.
+00411|Body part 1: Seqnum=1, Pos(L,C)=(7,3), Expression follows:
+00412|
+00413|---- Start of Expression ----
+00414|
+00415|----- Start Text Element -----
+00416|Text scrap[Grey]="No equals in this macro definition."
+00417|------ End Text Element ------
+00418|
+00419|----- End of Expression -----
+00420|
+00421|---End of List of Body Parts---
+00422|
+00423|-------------------- End of Macro Dump ---------------------
+00424|
+00425|
+00426|
+00427|------------------- Start of Macro Dump --------------------
+00428|Macro Name : "Sloth with equals"
+00429|Defined? : Yes.
+00430|Parameters : 0
+00431|Additive? : No.
+00432|Zero Calls? : No.
+00433|Many Calls? : No.
+00434|Output File?: No.
+00435|Automatic Line Directive Macro?: No.
+00436|Call list :
+00437|Macro body :
+00438|
+00439|--Start of List of Body Parts--
+ +-----
+00397|=========================== End of MACRO TABLE DUMP ============================
+00398|
+00399|
+00400|========================= Start of DOCUMENT LIST DUMP ==========================
+00401|
+00402|
+00403|TEXT COMPONENT: Pos(L,C)=(1,1).
+00404|
+00405|-- Start of Text Scrap List --
+00406|Text scrap[Grey]="PR07: Test the parsing of == and += in macro definitions.<010>
+00407|<010>
+00408|Trip the parser so we don't get any further.<010>
+00409|"
+00410|--- End of Text Scrap List ---
+00411|
+00412|
+00413|TEXT COMPONENT: Pos(L,C)=(4,3).
+00414|
+00415|-- Start of Text Scrap List --
+00416|Text scrap[Grey]="<010>
+00417|<010>
+00418|1. Test with no equals.<010>
+00419|"
+00420|--- End of Text Scrap List ---
+00421|
+00422|
+00423|MACRO DEFINITION COMPONENT: Pos(L,C)=(7,1).
+00424|Part 1 of macro @<Sloth@>.
+00425|
+00426|TEXT COMPONENT: Pos(L,C)=(7,51).
+00427|
+00428|-- Start of Text Scrap List --
+00429|Text scrap[Grey]="<010>
+00430|<010>
+00431|2. Test with ==.<010>
+00432|"
+00433|--- End of Text Scrap List ---
+00434|
+00435|
+00436|MACRO DEFINITION COMPONENT: Pos(L,C)=(10,1).
+00437|Part 1 of macro @<Sloth with equals@>.
+00438|
+00439|TEXT COMPONENT: Pos(L,C)=(10,65).
+00440|
+00441|-- Start of Text Scrap List --
+00442|Text scrap[Grey]="<010>
+00443|<010>
+00444|3. Test with +=.<010>
+00445|"
+00446|--- End of Text Scrap List ---
+00447|
+00448|
+00449|MACRO DEFINITION COMPONENT: Pos(L,C)=(13,1).
+00450|Part 1 of macro @<Sloth with plus@>.
+00451|
+00452|TEXT COMPONENT: Pos(L,C)=(13,63).
+00453|
+00454|-- Start of Text Scrap List --
+00455|Text scrap[Grey]="<010>
+00456|<010>
+00457|4. Test with syntax errors.<010>
+00458|<010>
+00459|"
+00460|--- End of Text Scrap List ---
+ +-----
+
+ +-----
+00440|This macro has 1 body part.
+00441|Body part 1: Seqnum=2, Pos(L,C)=(10,3), Expression follows:
+00442|
+00443|---- Start of Expression ----
+00444|
+00445|----- Start Text Element -----
+00446|Text scrap[Grey]="No equals in this macro definition."
+00447|------ End Text Element ------
+00448|
+00449|----- End of Expression -----
+00450|
+00451|---End of List of Body Parts---
+00452|
+00453|-------------------- End of Macro Dump ---------------------
+00454|
+00455|
+00456|
+00457|------------------- Start of Macro Dump --------------------
+00458|Macro Name : "Sloth with plus"
+00459|Defined? : Yes.
+00460|Parameters : 0
+00461|Additive? : Yes.
+00462|Zero Calls? : No.
+00463|Many Calls? : No.
+00464|Output File?: No.
+00465|Automatic Line Directive Macro?: No.
+00466|Call list :
+00467|Macro body :
+00468|
+00469|--Start of List of Body Parts--
+00470|This macro has 1 body part.
+00471|Body part 1: Seqnum=3, Pos(L,C)=(13,3), Expression follows:
+00472|
+00473|---- Start of Expression ----
+00474|
+00475|----- Start Text Element -----
+00476|Text scrap[Grey]="No equals in this macro definition."
+00477|------ End Text Element ------
+00478|
+00479|----- End of Expression -----
+00480|
+00481|---End of List of Body Parts---
+00482|
+00483|-------------------- End of Macro Dump ---------------------
+00484|
+00485|
+00486|
+00487|=========================== End of MACRO TABLE DUMP ============================
+00488|
+00489|
+00490|========================= Start of DOCUMENT LIST DUMP ==========================
+00491|
+00492|
+00493|TEXT COMPONENT: Pos(L,C)=(1,1).
+00494|
+00495|-- Start of Text Scrap List --
+00496|Text scrap[Grey]="PR07: Test the parsing of == and += in macro definitions.<010>
+00497|<010>
+00498|Trip the parser so we don't get any further.<010>
+00499|"
+00500|--- End of Text Scrap List ---
+00501|
+00502|
+00503|TEXT COMPONENT: Pos(L,C)=(4,3).
+ +-----
+00461|
+00462|
+00463|TYPESETTER DIRECTIVE COMPONENT:
+00464| Section "1", Section name="Error recovery point".
+00465|
+00466|TEXT COMPONENT: Pos(L,C)=(18,27).
+00467|
+00468|-- Start of Text Scrap List --
+00469|Text scrap[White]="<010>
+00470|<010>
+00471|"
+00472|--- End of Text Scrap List ---
+00473|
+00474|
+00475|TYPESETTER DIRECTIVE COMPONENT:
+00476| Section "2", Section name="Error recovery point".
+00477|
+00478|TEXT COMPONENT: Pos(L,C)=(21,27).
+00479|
+00480|-- Start of Text Scrap List --
+00481|Text scrap[White]="<010>
+00482|<010>
+00483|"
+00484|--- End of Text Scrap List ---
+00485|
+00486|
+00487|TYPESETTER DIRECTIVE COMPONENT:
+00488| Section "3", Section name="Error recovery point".
+00489|
+00490|TEXT COMPONENT: Pos(L,C)=(24,27).
+00491|
+00492|-- Start of Text Scrap List --
+00493|Text scrap[White]="<010>
+00494|<010>
+00495|"
+00496|--- End of Text Scrap List ---
+00497|
+00498|
+00499|TYPESETTER DIRECTIVE COMPONENT:
+00500| Section "4", Section name="Error recovery point".
+00501|
+00502|TEXT COMPONENT: Pos(L,C)=(27,27).
+00503|
+00504|-- Start of Text Scrap List --
+00505|Text scrap[White]="<010>
+00506|<010>
+00507|"
+00508|--- End of Text Scrap List ---
+00509|
+00510|
+00511|TYPESETTER DIRECTIVE COMPONENT:
+00512| Section "5", Section name="Error recovery point".
+00513|
+00514|TEXT COMPONENT: Pos(L,C)=(30,27).
+00515|
+00516|-- Start of Text Scrap List --
+00517|Text scrap[White]="<010>
+00518|<010>
+00519|"
+00520|--- End of Text Scrap List ---
+00521|
+00522|
+00523|TYPESETTER DIRECTIVE COMPONENT:
+00524| Section "6", Section name="Error recovery point".
+ +-----
+
+ +-----
+00505|-- Start of Text Scrap List --
+00506|Text scrap[Grey]="<010>
+00507|<010>
+00508|1. Test with no equals.<010>
+ +-----
+00526|TEXT COMPONENT: Pos(L,C)=(33,27).
+00527|
+00528|-- Start of Text Scrap List --
+00529|Text scrap[White]="<010>
+00530|<010>
+00531|<010>
+00532|<010>
+ +-----
+
+ +-----
+00513|MACRO DEFINITION COMPONENT: Pos(L,C)=(7,1).
+00514|Part 1 of macro @<Sloth@>.
+00515|
+00516|TEXT COMPONENT: Pos(L,C)=(7,51).
+00517|
+00518|-- Start of Text Scrap List --
+00519|Text scrap[Grey]="<010>
+00520|<010>
+00521|2. Test with ==.<010>
+00522|"
+00523|--- End of Text Scrap List ---
+00524|
+00525|
+00526|MACRO DEFINITION COMPONENT: Pos(L,C)=(10,1).
+00527|Part 1 of macro @<Sloth with equals@>.
+00528|
+00529|TEXT COMPONENT: Pos(L,C)=(10,65).
+00530|
+00531|-- Start of Text Scrap List --
+00532|Text scrap[Grey]="<010>
+00533|<010>
+00534|3. Test with +=.<010>
+00535|"
+00536|--- End of Text Scrap List ---
+00537|
+00538|
+00539|MACRO DEFINITION COMPONENT: Pos(L,C)=(13,1).
+00540|Part 1 of macro @<Sloth with plus@>.
+00541|
+00542|TEXT COMPONENT: Pos(L,C)=(13,63).
+00543|
+00544|-- Start of Text Scrap List --
+00545|Text scrap[Grey]="<010>
+00546|<010>
+00547|4. Test with syntax errors.<010>
+00548|<010>
+00549|"
+00550|--- End of Text Scrap List ---
+00551|
+00552|
+00553|TYPESETTER DIRECTIVE COMPONENT:
+00554| Section "1", Section name="Error recovery point".
+00555|
+00556|TEXT COMPONENT: Pos(L,C)=(18,27).
+00557|
+00558|-- Start of Text Scrap List --
+00559|Text scrap[White]="<010>
+00560|<010>
+00561|"
+00562|--- End of Text Scrap List ---
+00563|
+00564|
+00565|TYPESETTER DIRECTIVE COMPONENT:
+00566| Section "2", Section name="Error recovery point".
+00567|
+00568|TEXT COMPONENT: Pos(L,C)=(21,27).
+00569|
+00570|-- Start of Text Scrap List --
+00571|Text scrap[White]="<010>
+00572|<010>
+00573|"
+00574|--- End of Text Scrap List ---
+00575|
+00576|
+ +-----
+00537|========================== End of DOCUMENT LIST DUMP ===========================
+00538|
+00539|
+00540|Global Local| Input File
+00541|------------+-------------------------------------------------------------------
+00542| 1 1| PR07: Test the parsing of == and += in macro definitions.
+00543| 2 2|
+00544| 3 3| Trip the parser so we don't get any further.
+00545| 4 4| @>
+00546| Error|.^The parser was at the top level and was expecting
+00547| |.^one of: {Directive, Text, Macro definition, EOF}.
+00548| 5 5|
+00549| 6 6| 1. Test with no equals.
+00550| 7 7| @$@<Sloth@>@{No equals in this macro definition.@}
+00551| 8 8|
+00552| 9 9| 2. Test with ==.
+00553| 10 10| @$@<Sloth with equals@>==@{No equals in this macro definition.@}
+00554| 11 11|
+00555| 12 12| 3. Test with +=.
+00556| 13 13| @$@<Sloth with plus@>+=@{No equals in this macro definition.@}
+00557| 14 14|
+00558| 15 15| 4. Test with syntax errors.
+00559| 16 16|
+00560| 17 17| @$@<Error1@>++@{No equals in this macro definition.@}
+00561| Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+00562| |.............^(or @Z or @M if they have not already appeared).
+00563| |.............^Note: FunnelWeb is intolerant of spaces at this point.
+00564| |...............^Skipping after error to the next major construct...
+00565| 18 18| @A@<Error recovery point@>
+00566| |.^...skipped to here after the error.
+00567| 19 19|
+00568| 20 20| @$@<Error2@>@+=@{No equals in this macro definition.@}
+00569| Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+00570| |.............^(or @Z or @M if they have not already appeared).
+00571| |.............^Note: FunnelWeb is intolerant of spaces at this point.
+00572| |................^Skipping after error to the next major construct...
+00573| 21 21| @A@<Error recovery point@>
+00574| |.^...skipped to here after the error.
+00575| 22 22|
+00576| 23 23| @$@<Error3@>+==+@{No equals in this macro definition.@}
+00577| Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+00578| |.............^(or @Z or @M if they have not already appeared).
+00579| |.............^Note: FunnelWeb is intolerant of spaces at this point.
+00580| |.................^Skipping after error to the next major construct...
+00581| 24 24| @A@<Error recovery point@>
+00582| |.^...skipped to here after the error.
+00583| 25 25|
+00584| 26 26| @$@<Error4@>=+@{No equals in this macro definition.@}
+00585| Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+00586| |.............^(or @Z or @M if they have not already appeared).
+00587| |.............^Note: FunnelWeb is intolerant of spaces at this point.
+00588| |...............^Skipping after error to the next major construct...
+00589| 27 27| @A@<Error recovery point@>
+00590| |.^...skipped to here after the error.
+00591| 28 28|
+00592| 29 29| @$@<Error4@>@=@=@{No equals in this macro definition.@}
+00593| Error|................^Expecting "==@{" or "+=@{" or just "@{".
+00594| |................^(or @Z or @M if they have not already appeared).
+00595| |................^Note: FunnelWeb is intolerant of spaces at this point.
+00596| |.................^Skipping after error to the next major construct...
+00597| 30 30| @A@<Error recovery point@>
+00598| |.^...skipped to here after the error.
+00599| 31 31|
+00600| 32 32| @$@<Error4@>@+@=@{No equals in this macro definition.@}
+ +-----
+
+ +-----
+00577|TYPESETTER DIRECTIVE COMPONENT:
+00578| Section "3", Section name="Error recovery point".
+00579|
+00580|TEXT COMPONENT: Pos(L,C)=(24,27).
+00581|
+00582|-- Start of Text Scrap List --
+00583|Text scrap[White]="<010>
+00584|<010>
+00585|"
+00586|--- End of Text Scrap List ---
+00587|
+00588|
+00589|TYPESETTER DIRECTIVE COMPONENT:
+00590| Section "4", Section name="Error recovery point".
+00591|
+00592|TEXT COMPONENT: Pos(L,C)=(27,27).
+00593|
+00594|-- Start of Text Scrap List --
+00595|Text scrap[White]="<010>
+00596|<010>
+00597|"
+00598|--- End of Text Scrap List ---
+00599|
+00600|
+00601|TYPESETTER DIRECTIVE COMPONENT:
+00602| Section "5", Section name="Error recovery point".
+00603|
+00604|TEXT COMPONENT: Pos(L,C)=(30,27).
+00605|
+00606|-- Start of Text Scrap List --
+00607|Text scrap[White]="<010>
+00608|<010>
+00609|"
+00610|--- End of Text Scrap List ---
+00611|
+00612|
+00613|TYPESETTER DIRECTIVE COMPONENT:
+00614| Section "6", Section name="Error recovery point".
+00615|
+00616|TEXT COMPONENT: Pos(L,C)=(33,27).
+00617|
+00618|-- Start of Text Scrap List --
+00619|Text scrap[White]="<010>
+00620|<010>
+00621|<010>
+00622|<010>
+00623|"
+00624|--- End of Text Scrap List ---
+00625|
+00626|
+00627|========================== End of DOCUMENT LIST DUMP ===========================
+00628|
+00629|
+00630|Global Local| Input File
+00631|------------+-------------------------------------------------------------------
+00632| 1 1| PR07: Test the parsing of == and += in macro definitions.
+00633| 2 2|
+00634| 3 3| Trip the parser so we don't get any further.
+00635| 4 4| @>
+00636| Error|.^The parser was at the top level and was expecting
+00637| |.^one of: {Directive, Text, Macro definition, EOF}.
+00638| 5 5|
+00639| 6 6| 1. Test with no equals.
+00640| 7 7| @$@<Sloth@>@{No equals in this macro definition.@}
+ +-----
+00601| Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+00602| |.............^(or @Z or @M if they have not already appeared).
+00603| |.............^Note: FunnelWeb is intolerant of spaces at this point.
+00604| |......................................................^Skipping after error to the next major construct...
+00605| 33 33| @A@<Error recovery point@>
+00606| |.^...skipped to here after the error.
+00607| 34 34|
+00608| 35 35|
+00609| 36 36|
+00610| | <End-Of-File>
+00611|------------+-------------------------------------------------------------------
+00612|
+00613|There were 7 Errors.
+ +-----
+
+ +-----
+00641| 8 8|
+00642| 9 9| 2. Test with ==.
+00643| 10 10| @$@<Sloth with equals@>==@{No equals in this macro definition.@}
+00644| 11 11|
+00645| 12 12| 3. Test with +=.
+00646| 13 13| @$@<Sloth with plus@>+=@{No equals in this macro definition.@}
+00647| 14 14|
+00648| 15 15| 4. Test with syntax errors.
+00649| 16 16|
+00650| 17 17| @$@<Error1@>++@{No equals in this macro definition.@}
+00651| Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+00652| |.............^(or @Z or @M if they have not already appeared).
+00653| |.............^Note: FunnelWeb is intolerant of spaces at this point.
+00654| |...............^Skipping after error to the next major construct...
+00655| 18 18| @A@<Error recovery point@>
+00656| |.^...skipped to here after the error.
+00657| 19 19|
+00658| 20 20| @$@<Error2@>@+=@{No equals in this macro definition.@}
+00659| Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+00660| |.............^(or @Z or @M if they have not already appeared).
+00661| |.............^Note: FunnelWeb is intolerant of spaces at this point.
+00662| |................^Skipping after error to the next major construct...
+00663| 21 21| @A@<Error recovery point@>
+00664| |.^...skipped to here after the error.
+00665| 22 22|
+00666| 23 23| @$@<Error3@>+==+@{No equals in this macro definition.@}
+00667| Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+00668| |.............^(or @Z or @M if they have not already appeared).
+00669| |.............^Note: FunnelWeb is intolerant of spaces at this point.
+00670| |.................^Skipping after error to the next major construct...
+00671| 24 24| @A@<Error recovery point@>
+00672| |.^...skipped to here after the error.
+00673| 25 25|
+00674| 26 26| @$@<Error4@>=+@{No equals in this macro definition.@}
+00675| Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+00676| |.............^(or @Z or @M if they have not already appeared).
+00677| |.............^Note: FunnelWeb is intolerant of spaces at this point.
+00678| |...............^Skipping after error to the next major construct...
+00679| 27 27| @A@<Error recovery point@>
+00680| |.^...skipped to here after the error.
+00681| 28 28|
+00682| 29 29| @$@<Error4@>@=@=@{No equals in this macro definition.@}
+00683| Error|................^Expecting "==@{" or "+=@{" or just "@{".
+00684| |................^(or @Z or @M if they have not already appeared).
+00685| |................^Note: FunnelWeb is intolerant of spaces at this point.
+00686| |.................^Skipping after error to the next major construct...
+00687| 30 30| @A@<Error recovery point@>
+00688| |.^...skipped to here after the error.
+00689| 31 31|
+00690| 32 32| @$@<Error4@>@+@=@{No equals in this macro definition.@}
+00691| Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+00692| |.............^(or @Z or @M if they have not already appeared).
+00693| |.............^Note: FunnelWeb is intolerant of spaces at this point.
+00694| |......................................................^Skipping after error to the next major construct...
+00695| 33 33| @A@<Error recovery point@>
+00696| |.^...skipped to here after the error.
+00697| 34 34|
+00698| 35 35|
+00699| 36 36|
+00700| | <End-Of-File>
+00701|------------+-------------------------------------------------------------------
+00702|
+00703|There were 7 Errors.
+ +-----
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/pr08.lis"
+ with "/usr/var/tmp/funnelweb/answers/pr08.lis".
+
+ +-----
+00584|Macro Name : "#file"
+00585|Defined? : Yes.
+00586|Parameters : 0
+00587|Additive? : No.
+ +-----
+00584|Macro Name : "Elephant"
+00585|Defined? : Yes.
+00586|Parameters : 0
+00587|Additive? : Yes.
+ +-----
+
+ +-----
+00591|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00597|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+ +-----
+00596|Body part 1: Seqnum=4, Pos(L,C)=(48,3), Expression follows:
+ +-----
+
+ +-----
+00601|--- Start Special Function ---
+00602|---- End Special Function ----
+ +-----
+00600|----- Start Text Element -----
+00601|Text scrap[Grey]="Turkey"
+00602|------ End Text Element ------
+ +-----
+
+ +-----
+00613|Macro Name : "#line"
+00614|Defined? : Yes.
+00615|Parameters : 0
+00616|Additive? : No.
+00617|Zero Calls? : Yes.
+00618|Many Calls? : Yes.
+00619|Output File?: No.
+00620|Automatic Line Directive Macro?: No.
+ +-----
+00613|Macro Name : "Many"
+00614|Defined? : Yes.
+00615|Parameters : 7
+00616|Additive? : No.
+00617|Zero Calls? : Yes.
+00618|Many Calls? : No.
+00619|Output File?: No.
+ +-----
+
+ +-----
+00626|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+ +-----
+00625|Body part 1: Seqnum=7, Pos(L,C)=(60,3), Expression follows:
+ +-----
+
+ +-----
+00630|--- Start Special Function ---
+00631|---- End Special Function ----
+ +-----
+00629|----- Start Text Element -----
+00630|Text scrap[Grey]="Sloth"
+00631|------ End Text Element ------
+00632|
+00633|
+00634|-- Start Parameter Element --
+00635|Parameter number=8.
+00636|Parameter is of macro "Many".
+00637|--- End Parameter Element ---
+00638|
+00639|
+00640|----- Start Text Element -----
+00641|Text scrap[Grey]="Walrus"
+00642|------ End Text Element ------
+ +-----
+
+ +-----
+00642|Macro Name : "#timestamp"
+00643|Defined? : Yes.
+00644|Parameters : 0
+00645|Additive? : No.
+00646|Zero Calls? : Yes.
+00647|Many Calls? : Yes.
+00648|Output File?: No.
+00649|Automatic Line Directive Macro?: No.
+ +-----
+00653|Macro Name : "One"
+00654|Defined? : Yes.
+00655|Parameters : 1
+00656|Additive? : No.
+00657|Zero Calls? : Yes.
+00658|Many Calls? : No.
+00659|Output File?: No.
+ +-----
+
+ +-----
+00655|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+ +-----
+00665|Body part 1: Seqnum=6, Pos(L,C)=(57,3), Expression follows:
+ +-----
+
+ +-----
+00659|--- Start Special Function ---
+00660|---- End Special Function ----
+ +-----
+00669|----- Start Text Element -----
+00670|Text scrap[Grey]="Sloth"
+00671|------ End Text Element ------
+00672|
+00673|
+00674|-- Start Parameter Element --
+00675|Parameter number=2.
+00676|Parameter is of macro "One".
+00677|--- End Parameter Element ---
+00678|
+00679|
+00680|----- Start Text Element -----
+00681|Text scrap[Grey]="Walrus"
+00682|------ End Text Element ------
+ +-----
+
+ +-----
+00671|Macro Name : "Elephant"
+00672|Defined? : Yes.
+00673|Parameters : 0
+00674|Additive? : Yes.
+00675|Zero Calls? : Yes.
+00676|Many Calls? : Yes.
+00677|Output File?: No.
+00678|Automatic Line Directive Macro?: No.
+00679|Call list :
+00680|Macro body :
+00681|
+00682|--Start of List of Body Parts--
+00683|This macro has 1 body part.
+00684|Body part 1: Seqnum=4, Pos(L,C)=(48,3), Expression follows:
+00685|
+00686|---- Start of Expression ----
+00687|
+00688|----- Start Text Element -----
+00689|Text scrap[Grey]="Turkey"
+00690|------ End Text Element ------
+00691|
+00692|----- End of Expression -----
+00693|
+00694|---End of List of Body Parts---
+00695|
+ +-----
+00693|Macro Name : "Sloth 1"
+00694|Defined? : No.
+ +-----
+
+ +-----
+00701|Macro Name : "Many"
+00702|Defined? : Yes.
+00703|Parameters : 7
+00704|Additive? : No.
+00705|Zero Calls? : Yes.
+00706|Many Calls? : No.
+00707|Output File?: No.
+00708|Automatic Line Directive Macro?: No.
+00709|Call list :
+00710|Macro body :
+00711|
+00712|--Start of List of Body Parts--
+00713|This macro has 1 body part.
+00714|Body part 1: Seqnum=7, Pos(L,C)=(60,3), Expression follows:
+00715|
+00716|---- Start of Expression ----
+00717|
+00718|----- Start Text Element -----
+00719|Text scrap[Grey]="Sloth"
+00720|------ End Text Element ------
+00721|
+00722|
+00723|-- Start Parameter Element --
+00724|Parameter number=8.
+00725|Parameter is of macro "Many".
+00726|--- End Parameter Element ---
+00727|
+00728|
+00729|----- Start Text Element -----
+00730|Text scrap[Grey]="Walrus"
+00731|------ End Text Element ------
+00732|
+00733|----- End of Expression -----
+00734|
+00735|---End of List of Body Parts---
+00736|
+ +-----
+00700|Macro Name : "Sloth 2"
+00701|Defined? : No.
+ +-----
+
+ +-----
+00742|Macro Name : "One"
+00743|Defined? : Yes.
+00744|Parameters : 1
+00745|Additive? : No.
+00746|Zero Calls? : Yes.
+00747|Many Calls? : No.
+00748|Output File?: No.
+00749|Automatic Line Directive Macro?: No.
+ +-----
+00707|Macro Name : "Sloth 3"
+00708|Defined? : No.
+00709|-------------------- End of Macro Dump ---------------------
+00710|
+00711|
+00712|
+00713|------------------- Start of Macro Dump --------------------
+00714|Macro Name : "Sloth 4"
+00715|Defined? : No.
+00716|-------------------- End of Macro Dump ---------------------
+00717|
+00718|
+00719|
+00720|------------------- Start of Macro Dump --------------------
+00721|Macro Name : "Sloth 5"
+00722|Defined? : No.
+00723|-------------------- End of Macro Dump ---------------------
+00724|
+00725|
+00726|
+00727|------------------- Start of Macro Dump --------------------
+00728|Macro Name : "Unicorn"
+00729|Defined? : Yes.
+00730|Parameters : 3
+00731|Additive? : Yes.
+00732|Zero Calls? : No.
+00733|Many Calls? : No.
+00734|Output File?: No.
+ +-----
+
+ +-----
+00755|Body part 1: Seqnum=6, Pos(L,C)=(57,3), Expression follows:
+ +-----
+00740|Body part 1: Seqnum=3, Pos(L,C)=(43,3), Expression follows:
+ +-----
+
+ +-----
+00760|Text scrap[Grey]="Sloth"
+00761|------ End Text Element ------
+00762|
+00763|
+00764|-- Start Parameter Element --
+00765|Parameter number=2.
+00766|Parameter is of macro "One".
+00767|--- End Parameter Element ---
+00768|
+00769|
+00770|----- Start Text Element -----
+00771|Text scrap[Grey]="Walrus"
+ +-----
+00745|Text scrap[Grey]="Turkey"
+ +-----
+
+ +-----
+00783|Macro Name : "Sloth 1"
+00784|Defined? : No.
+ +-----
+00757|Macro Name : "Walrus 1"
+00758|Defined? : Yes.
+00759|Parameters : 0
+00760|Additive? : No.
+00761|Zero Calls? : No.
+00762|Many Calls? : No.
+00763|Output File?: No.
+00764|Call list :
+00765|Macro body :
+00766|
+00767|--Start of List of Body Parts--
+00768|This macro has 1 body part.
+00769|Body part 1: Seqnum=1, Pos(L,C)=(33,3), Expression follows:
+00770|
+00771|---- Start of Expression ----
+00772|
+00773|----- Start Text Element -----
+00774|Text scrap[Grey]="Sloth"
+00775|------ End Text Element ------
+00776|
+00777|----- End of Expression -----
+00778|
+00779|---End of List of Body Parts---
+00780|
+ +-----
+
+ +-----
+00790|Macro Name : "Sloth 2"
+00791|Defined? : No.
+ +-----
+00786|Macro Name : "Walrus 2"
+00787|Defined? : Yes.
+00788|Parameters : 0
+00789|Additive? : Yes.
+00790|Zero Calls? : No.
+00791|Many Calls? : No.
+00792|Output File?: No.
+00793|Call list :
+00794|Macro body :
+00795|
+00796|--Start of List of Body Parts--
+00797|This macro has 1 body part.
+00798|Body part 1: Seqnum=2, Pos(L,C)=(38,3), Expression follows:
+00799|
+00800|---- Start of Expression ----
+00801|
+00802|----- Start Text Element -----
+00803|Text scrap[Grey]="Sloth"
+00804|------ End Text Element ------
+00805|
+00806|----- End of Expression -----
+00807|
+00808|---End of List of Body Parts---
+00809|
+ +-----
+
+ +-----
+00797|Macro Name : "Sloth 3"
+00798|Defined? : No.
+00799|-------------------- End of Macro Dump ---------------------
+00800|
+00801|
+00802|
+00803|------------------- Start of Macro Dump --------------------
+00804|Macro Name : "Sloth 4"
+00805|Defined? : No.
+00806|-------------------- End of Macro Dump ---------------------
+00807|
+00808|
+00809|
+00810|------------------- Start of Macro Dump --------------------
+00811|Macro Name : "Sloth 5"
+00812|Defined? : No.
+00813|-------------------- End of Macro Dump ---------------------
+00814|
+00815|
+00816|
+00817|------------------- Start of Macro Dump --------------------
+00818|Macro Name : "Unicorn"
+00819|Defined? : Yes.
+00820|Parameters : 3
+00821|Additive? : Yes.
+00822|Zero Calls? : No.
+00823|Many Calls? : No.
+00824|Output File?: No.
+00825|Automatic Line Directive Macro?: No.
+ +-----
+00815|Macro Name : "Zero"
+00816|Defined? : Yes.
+00817|Parameters : 0
+00818|Additive? : No.
+00819|Zero Calls? : Yes.
+00820|Many Calls? : No.
+00821|Output File?: No.
+ +-----
+
+ +-----
+00831|Body part 1: Seqnum=3, Pos(L,C)=(43,3), Expression follows:
+ +-----
+00827|Body part 1: Seqnum=5, Pos(L,C)=(54,3), Expression follows:
+ +-----
+
+ +-----
+00836|Text scrap[Grey]="Turkey"
+ +-----
+00832|Text scrap[Grey]="Sloth"
+00833|------ End Text Element ------
+00834|
+00835|
+00836|-- Start Parameter Element --
+00837|Parameter number=1.
+00838|Parameter is of macro "Zero".
+00839|--- End Parameter Element ---
+00840|
+00841|
+00842|----- Start Text Element -----
+00843|Text scrap[Grey]="Walrus"
+ +-----
+
+ +-----
+00847|------------------- Start of Macro Dump --------------------
+00848|Macro Name : "Walrus 1"
+00849|Defined? : Yes.
+00850|Parameters : 0
+00851|Additive? : No.
+00852|Zero Calls? : No.
+00853|Many Calls? : No.
+00854|Output File?: No.
+00855|Automatic Line Directive Macro?: No.
+00856|Call list :
+00857|Macro body :
+00858|
+00859|--Start of List of Body Parts--
+00860|This macro has 1 body part.
+00861|Body part 1: Seqnum=1, Pos(L,C)=(33,3), Expression follows:
+00862|
+00863|---- Start of Expression ----
+00864|
+00865|----- Start Text Element -----
+00866|Text scrap[Grey]="Sloth"
+00867|------ End Text Element ------
+00868|
+00869|----- End of Expression -----
+00870|
+00871|---End of List of Body Parts---
+00872|
+00873|-------------------- End of Macro Dump ---------------------
+00874|
+00875|
+00876|
+00877|------------------- Start of Macro Dump --------------------
+00878|Macro Name : "Walrus 2"
+00879|Defined? : Yes.
+00880|Parameters : 0
+00881|Additive? : Yes.
+00882|Zero Calls? : No.
+00883|Many Calls? : No.
+00884|Output File?: No.
+00885|Automatic Line Directive Macro?: No.
+00886|Call list :
+00887|Macro body :
+00888|
+00889|--Start of List of Body Parts--
+00890|This macro has 1 body part.
+00891|Body part 1: Seqnum=2, Pos(L,C)=(38,3), Expression follows:
+00892|
+00893|---- Start of Expression ----
+00894|
+00895|----- Start Text Element -----
+00896|Text scrap[Grey]="Sloth"
+00897|------ End Text Element ------
+00898|
+00899|----- End of Expression -----
+00900|
+00901|---End of List of Body Parts---
+00902|
+00903|-------------------- End of Macro Dump ---------------------
+00904|
+00905|
+00906|
+00907|------------------- Start of Macro Dump --------------------
+00908|Macro Name : "Zero"
+00909|Defined? : Yes.
+00910|Parameters : 0
+ +-----
+00854|=========================== End of MACRO TABLE DUMP ============================
+00855|
+00856|
+00857|========================= Start of DOCUMENT LIST DUMP ==========================
+00858|
+00859|
+00860|TEXT COMPONENT: Pos(L,C)=(1,1).
+00861|
+00862|-- Start of Text Scrap List --
+00863|Text scrap[Grey]="PR08: Test semantic checking of macro definitions.<010>
+00864|<010>
+00865|Trip parser to be sure that we won't get any output files!<010>
+00866|"
+00867|--- End of Text Scrap List ---
+00868|
+00869|
+00870|TEXT COMPONENT: Pos(L,C)=(4,3).
+00871|
+00872|-- Start of Text Scrap List --
+00873|Text scrap[Grey]="<010>
+00874|<010>
+00875|1. File macro has parameters. Error.<010>
+00876|"
+00877|--- End of Text Scrap List ---
+00878|
+00879|
+00880|TYPESETTER DIRECTIVE COMPONENT:
+00881| Section "1", Section name="Error recovery point".
+00882|
+00883|TEXT COMPONENT: Pos(L,C)=(8,27).
+00884|
+00885|-- Start of Text Scrap List --
+00886|Text scrap[Grey]="<010>
+00887|<010>
+00888|2. File macro is additive. Error.<010>
+00889|"
+00890|--- End of Text Scrap List ---
+00891|
+00892|
+00893|TYPESETTER DIRECTIVE COMPONENT:
+00894| Section "2", Section name="Error recovery point".
+00895|
+00896|TEXT COMPONENT: Pos(L,C)=(12,27).
+00897|
+00898|-- Start of Text Scrap List --
+00899|Text scrap[Grey]="<010>
+00900|<010>
+00901|3. File macro has too long a name. The test name has 1200 characters. Err.<010>
+00902|Note: This test can't test the error message if the maximum length of a<010>
+00903|macro name is less than the maximum length of a file name as the name<010>
+00904|error is caught first.<010>
+00905|"
+00906|--- End of Text Scrap List ---
+00907|
+00908|
+00909|TYPESETTER DIRECTIVE COMPONENT:
+00910| Section "3", Section name="Error recovery point".
+00911|
+00912|TEXT COMPONENT: Pos(L,C)=(20,27).
+00913|
+00914|-- Start of Text Scrap List --
+00915|Text scrap[Grey]="<010>
+00916|<010>
+00917|4. File macro has zero or many attributes. Error.<010>
+ +-----
+
+ +-----
+00911|Additive? : No.
+00912|Zero Calls? : Yes.
+00913|Many Calls? : No.
+00914|Output File?: No.
+00915|Automatic Line Directive Macro?: No.
+00916|Call list :
+00917|Macro body :
+00918|
+00919|--Start of List of Body Parts--
+00920|This macro has 1 body part.
+00921|Body part 1: Seqnum=5, Pos(L,C)=(54,3), Expression follows:
+00922|
+00923|---- Start of Expression ----
+00924|
+00925|----- Start Text Element -----
+00926|Text scrap[Grey]="Sloth"
+00927|------ End Text Element ------
+00928|
+00929|
+00930|-- Start Parameter Element --
+00931|Parameter number=1.
+00932|Parameter is of macro "Zero".
+00933|--- End Parameter Element ---
+00934|
+00935|
+00936|----- Start Text Element -----
+00937|Text scrap[Grey]="Walrus"
+00938|------ End Text Element ------
+00939|
+00940|----- End of Expression -----
+00941|
+00942|---End of List of Body Parts---
+00943|
+00944|-------------------- End of Macro Dump ---------------------
+00945|
+00946|
+00947|
+00948|=========================== End of MACRO TABLE DUMP ============================
+00949|
+00950|
+00951|========================= Start of DOCUMENT LIST DUMP ==========================
+00952|
+00953|
+00954|TEXT COMPONENT: Pos(L,C)=(1,1).
+00955|
+00956|-- Start of Text Scrap List --
+00957|Text scrap[Grey]="PR08: Test semantic checking of macro definitions.<010>
+00958|<010>
+00959|Trip parser to be sure that we won't get any output files!<010>
+ +-----
+ +-----
+
+ +-----
+00964|TEXT COMPONENT: Pos(L,C)=(4,3).
+00965|
+00966|-- Start of Text Scrap List --
+00967|Text scrap[Grey]="<010>
+00968|<010>
+00969|1. File macro has parameters. Error.<010>
+ +-----
+00922|TYPESETTER DIRECTIVE COMPONENT:
+00923| Section "4", Section name="Error recovery point".
+00924|
+00925|TEXT COMPONENT: Pos(L,C)=(24,27).
+00926|
+00927|-- Start of Text Scrap List --
+00928|Text scrap[White]="<010>
+00929|<010>
+ +-----
+
+ +-----
+00975| Section "1", Section name="Error recovery point".
+00976|
+00977|TEXT COMPONENT: Pos(L,C)=(8,27).
+00978|
+00979|-- Start of Text Scrap List --
+00980|Text scrap[Grey]="<010>
+00981|<010>
+00982|2. File macro is additive. Error.<010>
+ +-----
+00935| Section "5", Section name="Error recovery point".
+00936|
+00937|TEXT COMPONENT: Pos(L,C)=(27,27).
+00938|
+00939|-- Start of Text Scrap List --
+00940|Text scrap[White]="<010>
+00941|<010>
+ +-----
+
+ +-----
+00988| Section "2", Section name="Error recovery point".
+00989|
+00990|TEXT COMPONENT: Pos(L,C)=(12,27).
+ +-----
+00947| Section "6", Section name="Error recovery point".
+00948|
+00949|TEXT COMPONENT: Pos(L,C)=(30,27).
+ +-----
+
+ +-----
+00995|3. File macro has too long a name. The test name has 1200 characters. Err.<010>
+00996|Note: This test can't test the error message if the maximum length of a<010>
+00997|macro name is less than the maximum length of a file name as the name<010>
+00998|error is caught first.<010>
+ +-----
+00954|5. Previous definition is full, current is additive.<010>
+ +-----
+
+ +-----
+01003|TYPESETTER DIRECTIVE COMPONENT:
+01004| Section "3", Section name="Error recovery point".
+01005|
+01006|TEXT COMPONENT: Pos(L,C)=(20,27).
+01007|
+01008|-- Start of Text Scrap List --
+01009|Text scrap[Grey]="<010>
+01010|<010>
+01011|4. File macro has zero or many attributes. Error.<010>
+ +-----
+00959|MACRO DEFINITION COMPONENT: Pos(L,C)=(33,1).
+00960|Part 1 of macro @<Walrus 1@>.
+00961|
+00962|TEXT COMPONENT: Pos(L,C)=(33,26).
+00963|
+00964|-- Start of Text Scrap List --
+00965|Text scrap[White]="<010>
+ +-----
+
+ +-----
+01017| Section "4", Section name="Error recovery point".
+01018|
+01019|TEXT COMPONENT: Pos(L,C)=(24,27).
+01020|
+01021|-- Start of Text Scrap List --
+01022|Text scrap[White]="<010>
+01023|<010>
+ +-----
+00971| Section "7", Section name="Error recovery point".
+00972|
+00973|TEXT COMPONENT: Pos(L,C)=(35,27).
+00974|
+00975|-- Start of Text Scrap List --
+00976|Text scrap[Grey]="<010>
+00977|<010>
+00978|6. Previous definition is additive, current is full.<010>
+ +-----
+
+ +-----
+01028|TYPESETTER DIRECTIVE COMPONENT:
+01029| Section "5", Section name="Error recovery point".
+01030|
+01031|TEXT COMPONENT: Pos(L,C)=(27,27).
+ +-----
+00983|MACRO DEFINITION COMPONENT: Pos(L,C)=(38,1).
+00984|Part 1 of macro @<Walrus 2@>.
+00985|
+00986|TEXT COMPONENT: Pos(L,C)=(38,26).
+ +-----
+
+ +-----
+01035|<010>
+ +-----
+ +-----
+
+ +-----
+01041| Section "6", Section name="Error recovery point".
+01042|
+01043|TEXT COMPONENT: Pos(L,C)=(30,27).
+ +-----
+00995| Section "8", Section name="Error recovery point".
+00996|
+00997|TEXT COMPONENT: Pos(L,C)=(40,27).
+ +-----
+
+ +-----
+01048|5. Previous definition is full, current is additive.<010>
+ +-----
+01002|7. Non-first body part of partial has parameter.<010>
+ +-----
+
+ +-----
+01053|MACRO DEFINITION COMPONENT: Pos(L,C)=(33,1).
+01054|Part 1 of macro @<Walrus 1@>.
+01055|
+01056|TEXT COMPONENT: Pos(L,C)=(33,26).
+ +-----
+01007|MACRO DEFINITION COMPONENT: Pos(L,C)=(43,1).
+01008|Part 1 of macro @<Unicorn@>.
+01009|
+01010|TEXT COMPONENT: Pos(L,C)=(43,32).
+ +-----
+
+ +-----
+01065| Section "7", Section name="Error recovery point".
+01066|
+01067|TEXT COMPONENT: Pos(L,C)=(35,27).
+ +-----
+01019| Section "9", Section name="Error recovery point".
+01020|
+01021|TEXT COMPONENT: Pos(L,C)=(45,27).
+ +-----
+
+ +-----
+01072|6. Previous definition is additive, current is full.<010>
+ +-----
+01026|8. Zero or many attributes on non-first body part of additive.<010>
+ +-----
+
+ +-----
+01077|MACRO DEFINITION COMPONENT: Pos(L,C)=(38,1).
+01078|Part 1 of macro @<Walrus 2@>.
+01079|
+01080|TEXT COMPONENT: Pos(L,C)=(38,26).
+ +-----
+01031|MACRO DEFINITION COMPONENT: Pos(L,C)=(48,1).
+01032|Part 1 of macro @<Elephant@>.
+01033|
+01034|TEXT COMPONENT: Pos(L,C)=(48,31).
+ +-----
+
+ +-----
+01089| Section "8", Section name="Error recovery point".
+01090|
+01091|TEXT COMPONENT: Pos(L,C)=(40,27).
+ +-----
+01043| Section "10", Section name="Error recovery point".
+01044|
+01045|TEXT COMPONENT: Pos(L,C)=(50,27).
+ +-----
+
+ +-----
+01096|7. Non-first body part of partial has parameter.<010>
+ +-----
+01050|9. Check that non-existent formal parameters are caught.<010>
+01051|<010>
+ +-----
+
+ +-----
+01101|MACRO DEFINITION COMPONENT: Pos(L,C)=(43,1).
+01102|Part 1 of macro @<Unicorn@>.
+01103|
+01104|TEXT COMPONENT: Pos(L,C)=(43,32).
+ +-----
+01056|MACRO DEFINITION COMPONENT: Pos(L,C)=(54,1).
+01057|Part 1 of macro @<Zero@>.
+01058|
+01059|TEXT COMPONENT: Pos(L,C)=(54,30).
+ +-----
+
+ +-----
+01113| Section "9", Section name="Error recovery point".
+01114|
+01115|TEXT COMPONENT: Pos(L,C)=(45,27).
+01116|
+01117|-- Start of Text Scrap List --
+01118|Text scrap[Grey]="<010>
+01119|<010>
+01120|8. Zero or many attributes on non-first body part of additive.<010>
+ +-----
+01068| Section "11", Section name="Error recovery point".
+01069|
+01070|TEXT COMPONENT: Pos(L,C)=(55,27).
+01071|
+01072|-- Start of Text Scrap List --
+01073|Text scrap[White]="<010>
+01074|<010>
+ +-----
+
+ +-----
+01125|MACRO DEFINITION COMPONENT: Pos(L,C)=(48,1).
+01126|Part 1 of macro @<Elephant@>.
+01127|
+01128|TEXT COMPONENT: Pos(L,C)=(48,31).
+ +-----
+01079|MACRO DEFINITION COMPONENT: Pos(L,C)=(57,1).
+01080|Part 1 of macro @<One@>.
+01081|
+01082|TEXT COMPONENT: Pos(L,C)=(57,35).
+ +-----
+
+ +-----
+01137| Section "10", Section name="Error recovery point".
+01138|
+01139|TEXT COMPONENT: Pos(L,C)=(50,27).
+01140|
+01141|-- Start of Text Scrap List --
+01142|Text scrap[Grey]="<010>
+01143|<010>
+01144|9. Check that non-existent formal parameters are caught.<010>
+ +-----
+01091| Section "12", Section name="Error recovery point".
+01092|
+01093|TEXT COMPONENT: Pos(L,C)=(58,27).
+01094|
+01095|-- Start of Text Scrap List --
+01096|Text scrap[White]="<010>
+ +-----
+
+ +-----
+01150|MACRO DEFINITION COMPONENT: Pos(L,C)=(54,1).
+01151|Part 1 of macro @<Zero@>.
+01152|
+01153|TEXT COMPONENT: Pos(L,C)=(54,30).
+ +-----
+01102|MACRO DEFINITION COMPONENT: Pos(L,C)=(60,1).
+01103|Part 1 of macro @<Many@>.
+01104|
+01105|TEXT COMPONENT: Pos(L,C)=(60,36).
+ +-----
+
+ +-----
+01162| Section "11", Section name="Error recovery point".
+01163|
+01164|TEXT COMPONENT: Pos(L,C)=(55,27).
+ +-----
+01114| Section "13", Section name="Error recovery point".
+01115|
+01116|TEXT COMPONENT: Pos(L,C)=(61,27).
+ +-----
+
+ +-----
+01168|<010>
+ +-----
+ +-----
+
+ +-----
+01173|MACRO DEFINITION COMPONENT: Pos(L,C)=(57,1).
+01174|Part 1 of macro @<One@>.
+01175|
+01176|TEXT COMPONENT: Pos(L,C)=(57,35).
+01177|
+01178|-- Start of Text Scrap List --
+01179|Text scrap[White]="<010>
+01180|"
+01181|--- End of Text Scrap List ---
+01182|
+01183|
+01184|TYPESETTER DIRECTIVE COMPONENT:
+01185| Section "12", Section name="Error recovery point".
+01186|
+01187|TEXT COMPONENT: Pos(L,C)=(58,27).
+01188|
+01189|-- Start of Text Scrap List --
+01190|Text scrap[White]="<010>
+01191|<010>
+01192|"
+01193|--- End of Text Scrap List ---
+01194|
+01195|
+01196|MACRO DEFINITION COMPONENT: Pos(L,C)=(60,1).
+01197|Part 1 of macro @<Many@>.
+01198|
+01199|TEXT COMPONENT: Pos(L,C)=(60,36).
+01200|
+01201|-- Start of Text Scrap List --
+01202|Text scrap[White]="<010>
+01203|"
+01204|--- End of Text Scrap List ---
+01205|
+01206|
+01207|TYPESETTER DIRECTIVE COMPONENT:
+01208| Section "13", Section name="Error recovery point".
+01209|
+01210|TEXT COMPONENT: Pos(L,C)=(61,27).
+01211|
+01212|-- Start of Text Scrap List --
+01213|Text scrap[White]="<010>
+01214|"
+01215|--- End of Text Scrap List ---
+01216|
+01217|
+ +-----
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/pr09.lis"
+ with "/usr/var/tmp/funnelweb/answers/pr09.lis".
+
+ +-----
+00825|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00844|Macro Name : "#file"
+ +-----
+00843|Macro Name : "Error1"
+ +-----
+
+ +-----
+00848|Zero Calls? : Yes.
+00849|Many Calls? : Yes.
+00850|Output File?: No.
+00851|Automatic Line Directive Macro?: No.
+ +-----
+00847|Zero Calls? : No.
+00848|Many Calls? : No.
+00849|Output File?: No.
+ +-----
+
+ +-----
+00856|This macro has 1 body part.
+00857|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00858|
+00859|---- Start of Expression ----
+00860|
+00861|--- Start Special Function ---
+00862|---- End Special Function ----
+00863|
+00864|----- End of Expression -----
+00865|
+ +-----
+00854|This macro has 0 body parts.
+ +-----
+
+ +-----
+00873|Macro Name : "#line"
+ +-----
+00862|Macro Name : "Error2"
+ +-----
+
+ +-----
+00877|Zero Calls? : Yes.
+00878|Many Calls? : Yes.
+00879|Output File?: No.
+00880|Automatic Line Directive Macro?: No.
+ +-----
+00866|Zero Calls? : No.
+00867|Many Calls? : No.
+00868|Output File?: No.
+ +-----
+
+ +-----
+00885|This macro has 1 body part.
+00886|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00887|
+00888|---- Start of Expression ----
+00889|
+00890|--- Start Special Function ---
+00891|---- End Special Function ----
+00892|
+00893|----- End of Expression -----
+00894|
+ +-----
+00873|This macro has 0 body parts.
+ +-----
+
+ +-----
+00902|Macro Name : "#timestamp"
+ +-----
+00881|Macro Name : "Error3"
+ +-----
+
+ +-----
+00906|Zero Calls? : Yes.
+00907|Many Calls? : Yes.
+00908|Output File?: No.
+00909|Automatic Line Directive Macro?: No.
+ +-----
+00885|Zero Calls? : No.
+00886|Many Calls? : No.
+00887|Output File?: No.
+ +-----
+
+ +-----
+00914|This macro has 1 body part.
+00915|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00916|
+00917|---- Start of Expression ----
+00918|
+00919|--- Start Special Function ---
+00920|---- End Special Function ----
+00921|
+00922|----- End of Expression -----
+00923|
+ +-----
+00892|This macro has 0 body parts.
+ +-----
+
+ +-----
+00931|Macro Name : "Error1"
+ +-----
+00900|Macro Name : "Error4"
+ +-----
+
+ +-----
+00938|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00951|Macro Name : "Error2"
+ +-----
+00919|Macro Name : "Error5"
+ +-----
+
+ +-----
+00958|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00963|This macro has 0 body parts.
+ +-----
+00930|This macro has 1 body part.
+00931|Body part 1: Seqnum=8, Pos(L,C)=(75,3), Expression follows:
+00932|
+00933|---- Start of Expression ----
+00934|
+00935|----- Start Text Element -----
+00936|Text scrap[White]="<010>
+00937|"
+00938|------ End Text Element ------
+00939|
+00940|
+00941|-- Begin Invocation Element --
+00942|Invocation of macro @<Two@>
+00943|This invocation has 1 actual parameters.
+00944|Actual parameter list follows as a sequence of expressions:
+00945|(Text crud before and after parameter has been omitted).
+00946|Expression for parameter number 1:
+00947|
+00948|---- Start of Expression ----
+00949|
+00950|----- Start Text Element -----
+00951|Text scrap[Grey]="Toucan"
+00952|------ End Text Element ------
+00953|
+00954|----- End of Expression -----
+00955|
+00956|--- End Invocation Element ---
+00957|
+00958|
+00959|----- Start Text Element -----
+00960|Text scrap[White]="<010>
+00961|"
+00962|------ End Text Element ------
+00963|
+00964|----- End of Expression -----
+00965|
+ +-----
+
+ +-----
+00971|Macro Name : "Error3"
+ +-----
+00973|Macro Name : "Error6"
+ +-----
+
+ +-----
+00978|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00991|Macro Name : "Error4"
+ +-----
+00992|Macro Name : "Error7"
+ +-----
+
+ +-----
+00998|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+01011|Macro Name : "Error5"
+ +-----
+01011|Macro Name : "Macro containing the test macro calls."
+ +-----
+
+ +-----
+01018|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+01024|Body part 1: Seqnum=8, Pos(L,C)=(75,3), Expression follows:
+ +-----
+01023|Body part 1: Seqnum=7, Pos(L,C)=(17,3), Expression follows:
+ +-----
+
+ +-----
+01029|Text scrap[White]="<010>
+ +-----
+01028|Text scrap[Grey]="<010>
+01029|1. Test macro call with no parameter list.<010>
+ +-----
+
+ +-----
+01035|Invocation of macro @<Two@>
+01036|This invocation has 1 actual parameters.
+01037|Actual parameter list follows as a sequence of expressions:
+01038|(Text crud before and after parameter has been omitted).
+01039|Expression for parameter number 1:
+01040|
+01041|---- Start of Expression ----
+01042|
+01043|----- Start Text Element -----
+01044|Text scrap[Grey]="Toucan"
+01045|------ End Text Element ------
+01046|
+01047|----- End of Expression -----
+01048|
+ +-----
+01035|Invocation of macro @<Zero@>
+01036|No actual parameters.
+ +-----
+
+ +-----
+01053|Text scrap[White]="<010>
+ +-----
+01041|Text scrap[Grey]="<010>
+01042|<010>
+01043|2. Test macro call with quick name.<010>
+ +-----
+
+ +-----
+01057|----- End of Expression -----
+01058|
+01059|---End of List of Body Parts---
+01060|
+01061|-------------------- End of Macro Dump ---------------------
+01062|
+01063|
+01064|
+01065|------------------- Start of Macro Dump --------------------
+01066|Macro Name : "Error6"
+01067|Defined? : Yes.
+01068|Parameters : 0
+01069|Additive? : No.
+01070|Zero Calls? : No.
+01071|Many Calls? : No.
+01072|Output File?: No.
+01073|Automatic Line Directive Macro?: No.
+01074|Call list :
+01075|Macro body :
+01076|
+01077|--Start of List of Body Parts--
+01078|This macro has 0 body parts.
+01079|---End of List of Body Parts---
+01080|
+01081|-------------------- End of Macro Dump ---------------------
+01082|
+01083|
+01084|
+01085|------------------- Start of Macro Dump --------------------
+01086|Macro Name : "Error7"
+01087|Defined? : Yes.
+01088|Parameters : 0
+01089|Additive? : No.
+01090|Zero Calls? : No.
+01091|Many Calls? : No.
+01092|Output File?: No.
+01093|Automatic Line Directive Macro?: No.
+01094|Call list :
+01095|Macro body :
+01096|
+01097|--Start of List of Body Parts--
+01098|This macro has 0 body parts.
+01099|---End of List of Body Parts---
+01100|
+01101|-------------------- End of Macro Dump ---------------------
+01102|
+01103|
+01104|
+01105|------------------- Start of Macro Dump --------------------
+01106|Macro Name : "Macro containing the test macro calls."
+01107|Defined? : Yes.
+01108|Parameters : 0
+01109|Additive? : No.
+01110|Zero Calls? : No.
+01111|Many Calls? : No.
+01112|Output File?: No.
+01113|Automatic Line Directive Macro?: No.
+01114|Call list :
+01115|Macro body :
+01116|
+01117|--Start of List of Body Parts--
+01118|This macro has 1 body part.
+01119|Body part 1: Seqnum=7, Pos(L,C)=(17,3), Expression follows:
+01120|
+ +-----
+01047|
+01048|-- Begin Invocation Element --
+01049|Invocation of macro @<"@>
+01050|No actual parameters.
+01051|--- End Invocation Element ---
+01052|
+01053|
+01054|----- Start Text Element -----
+01055|Text scrap[Grey]="<010>
+01056|<010>
+01057|3. Test macro call with one parameter.<010>
+01058|"
+01059|------ End Text Element ------
+01060|
+01061|
+01062|-- Begin Invocation Element --
+01063|Invocation of macro @<One@>
+01064|This invocation has 1 actual parameters.
+01065|Actual parameter list follows as a sequence of expressions:
+01066|(Text crud before and after parameter has been omitted).
+01067|Expression for parameter number 1:
+01068|
+01069|---- Start of Expression ----
+01070|
+01071|----- Start Text Element -----
+01072|Text scrap[Grey]="Toucan"
+01073|------ End Text Element ------
+01074|
+01075|----- End of Expression -----
+01076|
+01077|--- End Invocation Element ---
+01078|
+01079|
+01080|----- Start Text Element -----
+01081|Text scrap[Grey]="<010>
+01082|<010>
+01083|4. Test macro call with many parameters.<010>
+01084|"
+01085|------ End Text Element ------
+01086|
+01087|
+01088|-- Begin Invocation Element --
+01089|Invocation of macro @<Two@>
+01090|This invocation has 2 actual parameters.
+01091|Actual parameter list follows as a sequence of expressions:
+01092|(Text crud before and after parameter has been omitted).
+01093|Expression for parameter number 1:
+01094|
+01095|---- Start of Expression ----
+01096|
+01097|----- Start Text Element -----
+01098|Text scrap[Grey]="Toucan"
+01099|------ End Text Element ------
+01100|
+01101|----- End of Expression -----
+01102|
+01103|Expression for parameter number 2:
+01104|
+01105|---- Start of Expression ----
+01106|
+01107|----- Start Text Element -----
+01108|Text scrap[Grey]="Teapot"
+01109|------ End Text Element ------
+01110|
+ +-----
+
+ +-----
+01121|---- Start of Expression ----
+01122|
+01123|----- Start Text Element -----
+01124|Text scrap[Grey]="<010>
+01125|1. Test macro call with no parameter list.<010>
+ +-----
+01111|----- End of Expression -----
+01112|
+01113|--- End Invocation Element ---
+01114|
+01115|
+01116|----- Start Text Element -----
+01117|Text scrap[White]="<010>
+ +-----
+
+ +-----
+01131|Invocation of macro @<Zero@>
+01132|No actual parameters.
+01133|--- End Invocation Element ---
+01134|
+01135|
+01136|----- Start Text Element -----
+01137|Text scrap[Grey]="<010>
+01138|<010>
+01139|2. Test macro call with quick name.<010>
+01140|"
+01141|------ End Text Element ------
+01142|
+01143|
+01144|-- Begin Invocation Element --
+01145|Invocation of macro @<"@>
+01146|No actual parameters.
+01147|--- End Invocation Element ---
+01148|
+01149|
+01150|----- Start Text Element -----
+01151|Text scrap[Grey]="<010>
+01152|<010>
+01153|3. Test macro call with one parameter.<010>
+01154|"
+01155|------ End Text Element ------
+01156|
+01157|
+01158|-- Begin Invocation Element --
+01159|Invocation of macro @<One@>
+01160|This invocation has 1 actual parameters.
+ +-----
+01123|Invocation of macro @<Three@>
+01124|This invocation has 3 actual parameters.
+ +-----
+
+ +-----
+01173|--- End Invocation Element ---
+01174|
+01175|
+01176|----- Start Text Element -----
+01177|Text scrap[Grey]="<010>
+01178|<010>
+01179|4. Test macro call with many parameters.<010>
+01180|"
+01181|------ End Text Element ------
+01182|
+01183|
+01184|-- Begin Invocation Element --
+01185|Invocation of macro @<Two@>
+01186|This invocation has 2 actual parameters.
+01187|Actual parameter list follows as a sequence of expressions:
+01188|(Text crud before and after parameter has been omitted).
+01189|Expression for parameter number 1:
+ +-----
+01137|Expression for parameter number 2:
+ +-----
+
+ +-----
+01194|Text scrap[Grey]="Toucan"
+ +-----
+01142|Text scrap[Grey]="Teapot"
+ +-----
+
+ +-----
+01199|Expression for parameter number 2:
+ +-----
+01147|Expression for parameter number 3:
+ +-----
+
+ +-----
+01204|Text scrap[Grey]="Teapot"
+ +-----
+01152|Text scrap[Grey]="Walrus"
+ +-----
+
+ +-----
+01219|Invocation of macro @<Three@>
+01220|This invocation has 3 actual parameters.
+ +-----
+01167|Invocation of macro @<Nine@>
+01168|This invocation has 9 actual parameters.
+ +-----
+
+ +-----
+01253|--- End Invocation Element ---
+01254|
+01255|
+01256|----- Start Text Element -----
+01257|Text scrap[White]="<010>
+01258|"
+01259|------ End Text Element ------
+01260|
+01261|
+01262|-- Begin Invocation Element --
+01263|Invocation of macro @<Nine@>
+01264|This invocation has 9 actual parameters.
+01265|Actual parameter list follows as a sequence of expressions:
+01266|(Text crud before and after parameter has been omitted).
+01267|Expression for parameter number 1:
+ +-----
+01201|Expression for parameter number 4:
+ +-----
+
+ +-----
+01272|Text scrap[Grey]="Toucan"
+ +-----
+01206|Text scrap[Grey]="<010>
+01207| Toucan"
+ +-----
+
+ +-----
+01277|Expression for parameter number 2:
+ +-----
+01212|Expression for parameter number 5:
+ +-----
+
+ +-----
+01287|Expression for parameter number 3:
+ +-----
+01222|Expression for parameter number 6:
+ +-----
+
+ +-----
+01297|Expression for parameter number 4:
+ +-----
+01232|Expression for parameter number 7:
+ +-----
+
+ +-----
+01308|Expression for parameter number 5:
+ +-----
+01243|Expression for parameter number 8:
+ +-----
+
+ +-----
+01318|Expression for parameter number 6:
+ +-----
+01253|Expression for parameter number 9:
+ +-----
+
+ +-----
+01328|Expression for parameter number 7:
+01329|
+01330|---- Start of Expression ----
+ +-----
+01263|--- End Invocation Element ---
+01264|
+ +-----
+
+ +-----
+01334| Toucan"
+01335|------ End Text Element ------
+01336|
+01337|----- End of Expression -----
+01338|
+01339|Expression for parameter number 8:
+ +-----
+01268|<010>
+01269|5. Test macro calls with double quotes on parameters.<010>
+01270|"
+01271|------ End Text Element ------
+01272|
+01273|
+01274|-- Begin Invocation Element --
+01275|Invocation of macro @<One@>
+01276|This invocation has 1 actual parameters.
+01277|Actual parameter list follows as a sequence of expressions:
+01278|(Text crud before and after parameter has been omitted).
+01279|Expression for parameter number 1:
+ +-----
+
+ +-----
+01344|Text scrap[Grey]="Teapot"
+ +-----
+01284|Text scrap[Grey]="Toucan"
+ +-----
+
+ +-----
+01349|Expression for parameter number 9:
+01350|
+01351|---- Start of Expression ----
+01352|
+01353|----- Start Text Element -----
+01354|Text scrap[Grey]="Walrus"
+01355|------ End Text Element ------
+01356|
+01357|----- End of Expression -----
+01358|
+ +-----
+ +-----
+
+ +-----
+01363|Text scrap[Grey]="<010>
+01364|<010>
+01365|5. Test macro calls with double quotes on parameters.<010>
+ +-----
+01293|Text scrap[White]="<010>
+ +-----
+
+ +-----
+01371|Invocation of macro @<One@>
+01372|This invocation has 1 actual parameters.
+ +-----
+01299|Invocation of macro @<Two@>
+01300|This invocation has 2 actual parameters.
+ +-----
+
+ +-----
+ +-----
+01313|Expression for parameter number 2:
+01314|
+01315|---- Start of Expression ----
+01316|
+01317|----- Start Text Element -----
+01318|Text scrap[Grey]="Teapot"
+01319|------ End Text Element ------
+01320|
+01321|----- End of Expression -----
+01322|
+ +-----
+
+ +-----
+01395|Invocation of macro @<Two@>
+01396|This invocation has 2 actual parameters.
+ +-----
+01333|Invocation of macro @<Three@>
+01334|This invocation has 3 actual parameters.
+ +-----
+
+ +-----
+ +-----
+01357|Expression for parameter number 3:
+01358|
+01359|---- Start of Expression ----
+01360|
+01361|----- Start Text Element -----
+01362|Text scrap[Grey]="Walrus"
+01363|------ End Text Element ------
+01364|
+01365|----- End of Expression -----
+01366|
+ +-----
+
+ +-----
+01429|Invocation of macro @<Three@>
+01430|This invocation has 3 actual parameters.
+ +-----
+01377|Invocation of macro @<Nine@>
+01378|This invocation has 9 actual parameters.
+ +-----
+
+ +-----
+01463|--- End Invocation Element ---
+01464|
+01465|
+01466|----- Start Text Element -----
+01467|Text scrap[White]="<010>
+01468|"
+01469|------ End Text Element ------
+01470|
+01471|
+01472|-- Begin Invocation Element --
+01473|Invocation of macro @<Nine@>
+01474|This invocation has 9 actual parameters.
+01475|Actual parameter list follows as a sequence of expressions:
+01476|(Text crud before and after parameter has been omitted).
+01477|Expression for parameter number 1:
+ +-----
+01411|Expression for parameter number 4:
+ +-----
+
+ +-----
+01487|Expression for parameter number 2:
+ +-----
+01421|Expression for parameter number 5:
+ +-----
+
+ +-----
+01497|Expression for parameter number 3:
+ +-----
+01431|Expression for parameter number 6:
+ +-----
+
+ +-----
+01507|Expression for parameter number 4:
+ +-----
+01441|Expression for parameter number 7:
+ +-----
+
+ +-----
+01517|Expression for parameter number 5:
+ +-----
+01451|Expression for parameter number 8:
+ +-----
+
+ +-----
+01527|Expression for parameter number 6:
+ +-----
+01461|Expression for parameter number 9:
+ +-----
+
+ +-----
+01537|Expression for parameter number 7:
+ +-----
+01471|--- End Invocation Element ---
+01472|
+01473|
+01474|----- Start Text Element -----
+01475|Text scrap[Grey]="<010>
+01476|<010>
+01477|7. Test macro calls with mixed double quotes on parameters.<010>
+01478|"
+01479|------ End Text Element ------
+01480|
+01481|
+01482|-- Begin Invocation Element --
+01483|Invocation of macro @<Two@>
+01484|This invocation has 2 actual parameters.
+01485|Actual parameter list follows as a sequence of expressions:
+01486|(Text crud before and after parameter has been omitted).
+01487|Expression for parameter number 1:
+ +-----
+
+ +-----
+01547|Expression for parameter number 8:
+ +-----
+01497|Expression for parameter number 2:
+ +-----
+
+ +-----
+01557|Expression for parameter number 9:
+01558|
+01559|---- Start of Expression ----
+01560|
+01561|----- Start Text Element -----
+01562|Text scrap[Grey]="Walrus"
+01563|------ End Text Element ------
+01564|
+01565|----- End of Expression -----
+01566|
+ +-----
+ +-----
+
+ +-----
+01571|Text scrap[Grey]="<010>
+01572|<010>
+01573|7. Test macro calls with mixed double quotes on parameters.<010>
+ +-----
+01511|Text scrap[White]="<010>
+ +-----
+
+ +-----
+01579|Invocation of macro @<Two@>
+01580|This invocation has 2 actual parameters.
+ +-----
+01517|Invocation of macro @<Three@>
+01518|This invocation has 3 actual parameters.
+ +-----
+
+ +-----
+ +-----
+01541|Expression for parameter number 3:
+01542|
+01543|---- Start of Expression ----
+01544|
+01545|----- Start Text Element -----
+01546|Text scrap[Grey]="Walrus"
+01547|------ End Text Element ------
+01548|
+01549|----- End of Expression -----
+01550|
+ +-----
+
+ +-----
+01613|Invocation of macro @<Three@>
+01614|This invocation has 3 actual parameters.
+ +-----
+01561|Invocation of macro @<Nine@>
+01562|This invocation has 9 actual parameters.
+ +-----
+
+ +-----
+01642|Text scrap[Grey]="Walrus"
+ +-----
+01590|Text scrap[Grey]=" Walrus "
+ +-----
+
+ +-----
+01647|--- End Invocation Element ---
+01648|
+01649|
+01650|----- Start Text Element -----
+01651|Text scrap[White]="<010>
+01652|"
+01653|------ End Text Element ------
+01654|
+01655|
+01656|-- Begin Invocation Element --
+01657|Invocation of macro @<Nine@>
+01658|This invocation has 9 actual parameters.
+01659|Actual parameter list follows as a sequence of expressions:
+01660|(Text crud before and after parameter has been omitted).
+01661|Expression for parameter number 1:
+ +-----
+01595|Expression for parameter number 4:
+ +-----
+
+ +-----
+01671|Expression for parameter number 2:
+ +-----
+01605|Expression for parameter number 5:
+ +-----
+
+ +-----
+01676|Text scrap[Grey]="Teapot"
+ +-----
+01610|Text scrap[Grey]=" Teapot "
+ +-----
+
+ +-----
+01681|Expression for parameter number 3:
+ +-----
+01615|Expression for parameter number 6:
+ +-----
+
+ +-----
+01686|Text scrap[Grey]=" Walrus "
+ +-----
+01620|Text scrap[Grey]="Walrus"
+ +-----
+
+ +-----
+01691|Expression for parameter number 4:
+ +-----
+01625|Expression for parameter number 7:
+ +-----
+
+ +-----
+01701|Expression for parameter number 5:
+ +-----
+01635|Expression for parameter number 8:
+ +-----
+
+ +-----
+01706|Text scrap[Grey]=" Teapot "
+ +-----
+01640|Text scrap[Grey]="Teapot"
+ +-----
+
+ +-----
+01711|Expression for parameter number 6:
+ +-----
+01645|Expression for parameter number 9:
+ +-----
+
+ +-----
+01721|Expression for parameter number 7:
+01722|
+01723|---- Start of Expression ----
+01724|
+01725|----- Start Text Element -----
+01726|Text scrap[Grey]="Toucan"
+ +-----
+01655|--- End Invocation Element ---
+01656|
+01657|
+01658|----- Start Text Element -----
+01659|Text scrap[White]="<010>
+01660|<010>
+01661|"
+ +-----
+
+ +-----
+01731|Expression for parameter number 8:
+01732|
+01733|---- Start of Expression ----
+01734|
+01735|----- Start Text Element -----
+01736|Text scrap[Grey]="Teapot"
+01737|------ End Text Element ------
+01738|
+01739|----- End of Expression -----
+01740|
+01741|Expression for parameter number 9:
+01742|
+01743|---- Start of Expression ----
+01744|
+01745|----- Start Text Element -----
+01746|Text scrap[Grey]="Walrus"
+01747|------ End Text Element ------
+01748|
+01749|----- End of Expression -----
+01750|
+01751|--- End Invocation Element ---
+01752|
+01753|
+01754|----- Start Text Element -----
+01755|Text scrap[White]="<010>
+01756|<010>
+01757|"
+01758|------ End Text Element ------
+01759|
+01760|----- End of Expression -----
+01761|
+ +-----
+ +-----
+
+ +-----
+01776|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+01804|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+01831|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+01859|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+01888|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/pr10.lis"
+ with "/usr/var/tmp/funnelweb/answers/pr10.lis".
+
+ +-----
+00204|Macro Name : "#file"
+ +-----
+00204|Macro Name : "Sloth1"
+ +-----
+
+ +-----
+00208|Zero Calls? : Yes.
+00209|Many Calls? : Yes.
+00210|Output File?: No.
+00211|Automatic Line Directive Macro?: No.
+ +-----
+00208|Zero Calls? : No.
+00209|Many Calls? : No.
+00210|Output File?: No.
+ +-----
+
+ +-----
+00216|This macro has 1 body part.
+00217|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00218|
+00219|---- Start of Expression ----
+00220|
+00221|--- Start Special Function ---
+00222|---- End Special Function ----
+00223|
+00224|----- End of Expression -----
+00225|
+ +-----
+00215|This macro has 0 body parts.
+ +-----
+
+ +-----
+00233|Macro Name : "#line"
+ +-----
+00223|Macro Name : "Sloth2"
+ +-----
+
+ +-----
+00237|Zero Calls? : Yes.
+00238|Many Calls? : Yes.
+00239|Output File?: No.
+00240|Automatic Line Directive Macro?: No.
+ +-----
+00227|Zero Calls? : No.
+00228|Many Calls? : No.
+00229|Output File?: No.
+ +-----
+
+ +-----
+00245|This macro has 1 body part.
+00246|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00247|
+00248|---- Start of Expression ----
+00249|
+00250|--- Start Special Function ---
+00251|---- End Special Function ----
+00252|
+00253|----- End of Expression -----
+00254|
+ +-----
+00234|This macro has 0 body parts.
+ +-----
+
+ +-----
+00262|Macro Name : "#timestamp"
+ +-----
+00242|Macro Name : "Sloth3"
+ +-----
+
+ +-----
+00266|Zero Calls? : Yes.
+00267|Many Calls? : Yes.
+00268|Output File?: No.
+00269|Automatic Line Directive Macro?: No.
+ +-----
+00246|Zero Calls? : No.
+00247|Many Calls? : No.
+00248|Output File?: No.
+ +-----
+
+ +-----
+00274|This macro has 1 body part.
+00275|Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+00276|
+00277|---- Start of Expression ----
+00278|
+00279|--- Start Special Function ---
+00280|---- End Special Function ----
+00281|
+00282|----- End of Expression -----
+00283|
+ +-----
+00253|This macro has 0 body parts.
+ +-----
+
+ +-----
+00291|Macro Name : "Sloth1"
+ +-----
+00261|Macro Name : "Sloth4"
+ +-----
+
+ +-----
+00298|Automatic Line Directive Macro?: No.
+ +-----
+ +-----
+
+ +-----
+00310|------------------- Start of Macro Dump --------------------
+00311|Macro Name : "Sloth2"
+00312|Defined? : Yes.
+00313|Parameters : 0
+00314|Additive? : No.
+00315|Zero Calls? : No.
+00316|Many Calls? : No.
+00317|Output File?: No.
+00318|Automatic Line Directive Macro?: No.
+00319|Call list :
+00320|Macro body :
+00321|
+00322|--Start of List of Body Parts--
+00323|This macro has 0 body parts.
+00324|---End of List of Body Parts---
+00325|
+00326|-------------------- End of Macro Dump ---------------------
+00327|
+00328|
+00329|
+00330|------------------- Start of Macro Dump --------------------
+00331|Macro Name : "Sloth3"
+00332|Defined? : Yes.
+00333|Parameters : 0
+00334|Additive? : No.
+00335|Zero Calls? : No.
+00336|Many Calls? : No.
+00337|Output File?: No.
+00338|Automatic Line Directive Macro?: No.
+00339|Call list :
+00340|Macro body :
+00341|
+00342|--Start of List of Body Parts--
+00343|This macro has 0 body parts.
+00344|---End of List of Body Parts---
+00345|
+00346|-------------------- End of Macro Dump ---------------------
+00347|
+00348|
+00349|
+00350|------------------- Start of Macro Dump --------------------
+00351|Macro Name : "Sloth4"
+00352|Defined? : Yes.
+00353|Parameters : 0
+00354|Additive? : No.
+00355|Zero Calls? : No.
+00356|Many Calls? : No.
+00357|Output File?: No.
+00358|Automatic Line Directive Macro?: No.
+00359|Call list :
+00360|Macro body :
+00361|
+00362|--Start of List of Body Parts--
+00363|This macro has 0 body parts.
+00364|---End of List of Body Parts---
+00365|
+00366|-------------------- End of Macro Dump ---------------------
+00367|
+00368|
+00369|
+ +-----
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/an01.lis"
+ with "/usr/var/tmp/funnelweb/answers/an01.lis".
+
+ +-----
+ +-----
+00004|E: No macros defined.
+ +-----
+
+ +-----
+00011|There was 1 Error.
+ +-----
+00012|There were 2 Errors.
+ +-----
+
+
+Comparing "/usr/var/tmp/funnelweb/results/an02.lis"
+ with "/usr/var/tmp/funnelweb/answers/an02.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/an03.lis"
+ with "/usr/var/tmp/funnelweb/answers/an03.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/an04.lis"
+ with "/usr/var/tmp/funnelweb/answers/an04.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/tg01.lis"
+ with "/usr/var/tmp/funnelweb/answers/tg01.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/tg01.out"
+ with "/usr/var/tmp/funnelweb/answers/tg01.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/tg02.lis"
+ with "/usr/var/tmp/funnelweb/answers/tg02.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/tg02.out"
+ with "/usr/var/tmp/funnelweb/answers/tg02.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/tg03.lis"
+ with "/usr/var/tmp/funnelweb/answers/tg03.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/tg03.out"
+ with "/usr/var/tmp/funnelweb/answers/tg03.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/tg04.lis"
+ with "/usr/var/tmp/funnelweb/answers/tg04.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/tg04.out"
+ with "/usr/var/tmp/funnelweb/answers/tg04.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/tg05.lis"
+ with "/usr/var/tmp/funnelweb/answers/tg05.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/tg05.out"
+ with "/usr/var/tmp/funnelweb/answers/tg05.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/tg06.lis"
+ with "/usr/var/tmp/funnelweb/answers/tg06.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/tg06.out"
+ with "/usr/var/tmp/funnelweb/answers/tg06.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/tg07.lis"
+ with "/usr/var/tmp/funnelweb/answers/tg07.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/tg07.out"
+ with "/usr/var/tmp/funnelweb/answers/tg07.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/tg08.lis"
+ with "/usr/var/tmp/funnelweb/answers/tg08.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/tg08.out"
+ with "/usr/var/tmp/funnelweb/answers/tg08.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/tg09.lis"
+ with "/usr/var/tmp/funnelweb/answers/tg09.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/tg09.out"
+ with "/usr/var/tmp/funnelweb/answers/tg09.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/wv01.lis"
+ with "/usr/var/tmp/funnelweb/answers/wv01.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/wv01.tex"
+ with "/usr/var/tmp/funnelweb/answers/wv01.tex".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/wv02.lis"
+ with "/usr/var/tmp/funnelweb/answers/wv02.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/wv02.tex"
+ with "/usr/var/tmp/funnelweb/answers/wv02.tex".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/wv03.lis"
+ with "/usr/var/tmp/funnelweb/answers/wv03.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/wv03.tex"
+ with "/usr/var/tmp/funnelweb/answers/wv03.tex".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/wv04.lis"
+ with "/usr/var/tmp/funnelweb/answers/wv04.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/wv04.tex"
+ with "/usr/var/tmp/funnelweb/answers/wv04.tex".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/wv05.lis"
+ with "/usr/var/tmp/funnelweb/answers/wv05.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/wv05.tex"
+ with "/usr/var/tmp/funnelweb/answers/wv05.tex".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/wv06.lis"
+ with "/usr/var/tmp/funnelweb/answers/wv06.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/wv06.tex"
+ with "/usr/var/tmp/funnelweb/answers/wv06.tex".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex01.lis"
+ with "/usr/var/tmp/funnelweb/answers/ex01.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex01.out"
+ with "/usr/var/tmp/funnelweb/answers/ex01.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex02.lis"
+ with "/usr/var/tmp/funnelweb/answers/ex02.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex02.out"
+ with "/usr/var/tmp/funnelweb/answers/ex02.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex03.lis"
+ with "/usr/var/tmp/funnelweb/answers/ex03.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex04.lis"
+ with "/usr/var/tmp/funnelweb/answers/ex04.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex04.out"
+ with "/usr/var/tmp/funnelweb/answers/ex04.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex05.lis"
+ with "/usr/var/tmp/funnelweb/answers/ex05.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex05.out"
+ with "/usr/var/tmp/funnelweb/answers/ex05.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex06.lis"
+ with "/usr/var/tmp/funnelweb/answers/ex06.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex06.out"
+ with "/usr/var/tmp/funnelweb/answers/ex06.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex07.lis"
+ with "/usr/var/tmp/funnelweb/answers/ex07.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex07.out"
+ with "/usr/var/tmp/funnelweb/answers/ex07.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex08.lis"
+ with "/usr/var/tmp/funnelweb/answers/ex08.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex08.out"
+ with "/usr/var/tmp/funnelweb/answers/ex08.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex09.lis"
+ with "/usr/var/tmp/funnelweb/answers/ex09.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex09.out"
+ with "/usr/var/tmp/funnelweb/answers/ex09.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex10.lis"
+ with "/usr/var/tmp/funnelweb/answers/ex10.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex10.out"
+ with "/usr/var/tmp/funnelweb/answers/ex10.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex11.lis"
+ with "/usr/var/tmp/funnelweb/answers/ex11.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex11.tex"
+ with "/usr/var/tmp/funnelweb/answers/ex11.tex".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex12.lis"
+ with "/usr/var/tmp/funnelweb/answers/ex12.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex12.tex"
+ with "/usr/var/tmp/funnelweb/answers/ex12.tex".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex13.lis"
+ with "/usr/var/tmp/funnelweb/answers/ex13.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex13.tex"
+ with "/usr/var/tmp/funnelweb/answers/ex13.tex".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex14.lis"
+ with "/usr/var/tmp/funnelweb/answers/ex14.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex14.tex"
+ with "/usr/var/tmp/funnelweb/answers/ex14.tex".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex15.lis"
+ with "/usr/var/tmp/funnelweb/answers/ex15.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex15.tex"
+ with "/usr/var/tmp/funnelweb/answers/ex15.tex".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex16.lis"
+ with "/usr/var/tmp/funnelweb/answers/ex16.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex16.out"
+ with "/usr/var/tmp/funnelweb/answers/ex16.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/ex16.tex"
+ with "/usr/var/tmp/funnelweb/answers/ex16.tex".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi01.lis"
+ with "/usr/var/tmp/funnelweb/answers/hi01.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi01.out"
+ with "/usr/var/tmp/funnelweb/answers/hi01.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi02.lis"
+ with "/usr/var/tmp/funnelweb/answers/hi02.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi02.out"
+ with "/usr/var/tmp/funnelweb/answers/hi02.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi03.lis"
+ with "/usr/var/tmp/funnelweb/answers/hi03.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi03.out"
+ with "/usr/var/tmp/funnelweb/answers/hi03.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi04.lis"
+ with "/usr/var/tmp/funnelweb/answers/hi04.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi04.out"
+ with "/usr/var/tmp/funnelweb/answers/hi04.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi05.lis"
+ with "/usr/var/tmp/funnelweb/answers/hi05.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi05.out"
+ with "/usr/var/tmp/funnelweb/answers/hi05.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi06.lis"
+ with "/usr/var/tmp/funnelweb/answers/hi06.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi06a.out"
+ with "/usr/var/tmp/funnelweb/answers/hi06a.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi06b.out"
+ with "/usr/var/tmp/funnelweb/answers/hi06b.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi07.lis"
+ with "/usr/var/tmp/funnelweb/answers/hi07.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi07a.out"
+ with "/usr/var/tmp/funnelweb/answers/hi07a.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi07b.out"
+ with "/usr/var/tmp/funnelweb/answers/hi07b.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi08.lis"
+ with "/usr/var/tmp/funnelweb/answers/hi08.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi08.out"
+ with "/usr/var/tmp/funnelweb/answers/hi08.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi09.lis"
+ with "/usr/var/tmp/funnelweb/answers/hi09.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi09.out"
+ with "/usr/var/tmp/funnelweb/answers/hi09.out".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi10.lis"
+ with "/usr/var/tmp/funnelweb/answers/hi10.lis".
+The two files are IDENTICAL.
+
+
+Comparing "/usr/var/tmp/funnelweb/results/hi10.out"
+ with "/usr/var/tmp/funnelweb/answers/hi10.out".
+The two files are IDENTICAL.
diff --git a/web/funnelAC/results/an01.lis b/web/funnelAC/results/an01.lis
new file mode 100644
index 0000000000..cb554e6d28
--- /dev/null
+++ b/web/funnelAC/results/an01.lis
@@ -0,0 +1,11 @@
+FUNNELWEB LISTING FILE
+======================
+
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+There was 1 Error.
diff --git a/web/funnelAC/results/an02.lis b/web/funnelAC/results/an02.lis
new file mode 100644
index 0000000000..cb554e6d28
--- /dev/null
+++ b/web/funnelAC/results/an02.lis
@@ -0,0 +1,11 @@
+FUNNELWEB LISTING FILE
+======================
+
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+There was 1 Error.
diff --git a/web/funnelAC/results/an03.lis b/web/funnelAC/results/an03.lis
new file mode 100644
index 0000000000..8cda130586
--- /dev/null
+++ b/web/funnelAC/results/an03.lis
@@ -0,0 +1,86 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| AN03: Test semantics checking of macros.
+ 2 2|
+ 3 3| First define some macros to call.
+ 4 4| @$@<Zero@>@Z@M@{@}
+ 5 5| @$@<One@>@(@1@)@Z@M@{@}
+ 6 6| @$@<Two@>@(@2@)@Z@M@{@}
+ 7 7|
+ 8 8| 1. Test call to undefined macro.
+ 9 9| @$@<Sloth1@>@Z==@{@<Walrus@>@}
+ Error|...................^Call to undefined macro.
+ 10 10|
+ 11 11| 2. Test calls with wrong number of parameters.
+ 12 12| @$@<Sloth2@>@Z==@{
+ 13 13| @<Zero@>
+ 14 14| @<Zero@>@(@)
+ Error|.^Call has 1 parameter, but the macro
+ |.^definition at line 4 specifies 0 parameters.
+ |.^Note: If your call looks like this: @<Macro@>@(@) then you
+ |.^should be aware that FunnelWeb treats this as a call with
+ |.^a single parameter consisting of the empty string. This
+ |.^is a consequence of parameter delimiters @"@" being optional.
+ 15 15| @<Zero@>@(@,@)
+ Error|.^Call has 2 parameters, but the macro
+ |.^definition at line 4 specifies 0 parameters.
+ 16 16| @<One@>
+ Error|.^Call has 0 parameters, but the macro
+ |.^definition at line 5 specifies 1 parameter.
+ 17 17| @<One@>@(@)
+ 18 18| @<One@>@(Walrus@,@)
+ Error|.^Call has 2 parameters, but the macro
+ |.^definition at line 5 specifies 1 parameter.
+ 19 19| @<Two@>@(Sloth@)
+ Error|.^Call has 1 parameter, but the macro
+ |.^definition at line 6 specifies 2 parameters.
+ 20 20| @}
+ 21 21|
+ 22 22| 3. Test call to file macro.
+ 23 23| @O@<deleteme.txt@>@{@}
+ |.^This file macro is called one or more times.
+ |.^Each call has been flagged with an error message.
+ 24 24| @$@<Teapot@>@Z@{@<deleteme.txt@>@}
+ Error|.................^Calls to file macros are not allowed.
+ |.................^Reason: It should be possible to comment out a
+ |.................^file macro without a big fuss. Calling a file macro
+ |.................^just tangles it up in the macro structure,
+ |.................^making it more difficult to comment out later.
+ 25 25|
+ 26 26| 4. Test macro never used and has <special>Z.
+ 27 27| @$@<Elephant@>@Z@{@}
+ 28 28|
+ 29 29| 5. Test macro often used and has <special>M.
+ 30 30| @$@<Giraffe@>@M@{@}
+ 31 31| @$@<Use Giraffe@>@Z@{@<Giraffe@>@<Giraffe@>@}
+ 32 32|
+ 33 33| 6. Test macro never used and no <special>Z
+ 34 34| @$@<Zebra@>@{@}
+ Error|.^This macro is never used (and has no @Z).
+ 35 35|
+ 36 36| 7. Test multiply used and no <special>M.
+ 37 37| @$@<Monkey@>@{@}
+ Error|.^This macro is used more than once (and has no @M).
+ 38 38| @$@<Use Monkey@>@Z@{@<Monkey@>@<Monkey@>@}
+ 39 39|
+ 40 40| 8. Test directly recursive macro.
+ 41 41| @$@<Who do ya call?@>@{@<Who do ya call?@>@}
+ Error|.^This macro has an infinite expansion.
+ 42 42|
+ 43 43| 9. Test indirectly recursive macro.
+ 44 44| @$@<X@>@M@{@<Y@>@}
+ Error|.^This macro has an infinite expansion.
+ 45 45| @$@<Y@>@{@<X@>@}
+ Error|.^This macro has an infinite expansion.
+ 46 46|
+ 47 47| 10. Test callers of recursive macros.
+ 48 48| @$@<Z@>@Z@{@<X@>@}
+ Error|.^This macro has an infinite expansion.
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 13 Errors.
diff --git a/web/funnelAC/results/an04.lis b/web/funnelAC/results/an04.lis
new file mode 100644
index 0000000000..46c3409a8e
--- /dev/null
+++ b/web/funnelAC/results/an04.lis
@@ -0,0 +1,28 @@
+FUNNELWEB LISTING FILE
+======================
+
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| AN04: Test document list checks.
+ 2 2|
+ 3 3| 1. Test for sections with no names.
+ 4 4|
+ 5 5| @A@<This section has both a name and a macro@>
+ 6 6| @$@<Sloth@>@Z@{@}
+ 7 7|
+ 8 8| @A@<This section has an explicit name but no macro@>
+ 9 9|
+ 10 10| @A
+ 11 11| @$@<This section has no explicit name but does have a macro@>@Z@{@}
+ 12 12|
+ 13 13| @A This section has no name and no macro to inherit one from.
+ Error|.^This section has no name.
+ |.^You can give it one explicitly (As in @A@<Sloth@>) or implicitly by
+ |.^defining a macro (whose name will be inherited) within the section.
+ 14 14|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 2 Errors.
diff --git a/web/funnelAC/results/ex01.lis b/web/funnelAC/results/ex01.lis
new file mode 100644
index 0000000000..9cb0a6b7c9
--- /dev/null
+++ b/web/funnelAC/results/ex01.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex01.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/ex01.out b/web/funnelAC/results/ex01.out
new file mode 100644
index 0000000000..557db03de9
--- /dev/null
+++ b/web/funnelAC/results/ex01.out
@@ -0,0 +1 @@
+Hello World
diff --git a/web/funnelAC/results/ex02.lis b/web/funnelAC/results/ex02.lis
new file mode 100644
index 0000000000..1f31a5ff30
--- /dev/null
+++ b/web/funnelAC/results/ex02.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex02.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/ex02.out b/web/funnelAC/results/ex02.out
new file mode 100644
index 0000000000..557db03de9
--- /dev/null
+++ b/web/funnelAC/results/ex02.out
@@ -0,0 +1 @@
+Hello World
diff --git a/web/funnelAC/results/ex03.lis b/web/funnelAC/results/ex03.lis
new file mode 100644
index 0000000000..beb06214aa
--- /dev/null
+++ b/web/funnelAC/results/ex03.lis
@@ -0,0 +1,50 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| EX03: An example containing errors to do with the number of times
+ 2 2| that macros are called.
+ 3 3|
+ 4 4| @O@<ex03.out@>==@{@-
+ 5 5| @<Include Files@>
+ 6 6| @<Include Files@>
+ 7 7| @<Main Program@>
+ 8 8| @}
+ 9 9|
+ 10 10| @$@<Main Program@>==@{@-
+ 11 11| main()
+ 12 12| {
+ 13 13| doit();
+ 14 14| }
+ 15 15| @}
+ 16 16|
+ 17 17| @$@<Subroutine@>==@{@-
+ Error|.^This macro is never used (and has no @Z).
+ 18 18| void doit()
+ 19 19| {
+ 20 20| int i;
+ 21 21| for (i=0;i<10;i++)
+ 22 22| {
+ 23 23| @<Print@>
+ 24 24| @<Print@>
+ 25 25| }
+ 26 26| }@}
+ 27 27|
+ 28 28| @$@<Print@>==@{@-
+ Error|.^This macro is used more than once (and has no @M).
+ 29 29| printf("Hello World!");
+ 30 30| printf("\n");@}
+ 31 31|
+ 32 32| @$@<Scan@>==@{scanf@}
+ Error|.^This macro is never used (and has no @Z).
+ 33 33|
+ 34 34| @$@<Include Files@>==@{@-
+ Error|.^This macro is used more than once (and has no @M).
+ 35 35| #include <stdio.h>
+ 36 36| #include <stdlib.h>@}
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 4 Errors.
diff --git a/web/funnelAC/results/ex04.lis b/web/funnelAC/results/ex04.lis
new file mode 100644
index 0000000000..780c9c7f77
--- /dev/null
+++ b/web/funnelAC/results/ex04.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex04.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/ex04.out b/web/funnelAC/results/ex04.out
new file mode 100644
index 0000000000..939a0cdf82
--- /dev/null
+++ b/web/funnelAC/results/ex04.out
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <stdlib.h>
+void doit()
+{
+ int i;
+ for (i=0;i<10;i++)
+ {
+ printf("Hello World!");
+ printf("\n");
+ printf("Hello World!");
+ printf("\n");
+ }
+}
+main()
+{
+ doit();
+}
+
diff --git a/web/funnelAC/results/ex05.lis b/web/funnelAC/results/ex05.lis
new file mode 100644
index 0000000000..a7e84fcdaa
--- /dev/null
+++ b/web/funnelAC/results/ex05.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex05.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/ex05.out b/web/funnelAC/results/ex05.out
new file mode 100644
index 0000000000..4a12476ca9
--- /dev/null
+++ b/web/funnelAC/results/ex05.out
@@ -0,0 +1,18 @@
+program adt(input,output);
+type buffer_type =
+ record
+ length : integer;
+ buf : array[1..100] of char;
+ end;
+type complex_type = record r,i : real; end;
+
+bigbuf : buffer_type;
+
+procedure buf_init (var b : buffer_type ) {Body of buf_init}
+procedure buf_add (var b : buffer_type; ch : char) {Body of buf_add}
+procedure buf_get (var b : buffer_type; var ch : char) {Body of buf_get}
+procedure cm_set (var c: complex_type; a,b: real) {Body of cm_set}
+procedure cm_add (a,b: complex_type; var c: complex_type) {Body of cm_add}
+{Other procedures and functions}
+
+begin startproc; end.
diff --git a/web/funnelAC/results/ex06.lis b/web/funnelAC/results/ex06.lis
new file mode 100644
index 0000000000..5a2782517d
--- /dev/null
+++ b/web/funnelAC/results/ex06.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex06.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/ex06.out b/web/funnelAC/results/ex06.out
new file mode 100644
index 0000000000..03ac7feb13
--- /dev/null
+++ b/web/funnelAC/results/ex06.out
@@ -0,0 +1,22 @@
+program adt(input,output);
+type buffer_type = record
+ length : integer;
+ buf : array[1..100] of char;
+ end;
+
+type complex_type = record r,i : real; end;
+
+
+bigbuf : buffer_type;
+
+
+procedure buf_init(var b : buffer_type) {Body of buf_init}
+procedure buf_add(var b : buffer_type; ch : char) {Body of buf_add}
+procedure buf_get(var b : buffer_type; var ch : char) {Body of buf_get}
+
+procedure cm_set(var c: complex_type; a,b : real) {Body of cm_set}
+procedure cm_add(a,b : complex_type; var c: complex_type) {Body of cm_add}
+{Other procedures and functions}
+
+
+begin startproc; end.
diff --git a/web/funnelAC/results/ex07.lis b/web/funnelAC/results/ex07.lis
new file mode 100644
index 0000000000..b354e7c18e
--- /dev/null
+++ b/web/funnelAC/results/ex07.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex07.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/ex07.out b/web/funnelAC/results/ex07.out
new file mode 100644
index 0000000000..b6e41eea63
--- /dev/null
+++ b/web/funnelAC/results/ex07.out
@@ -0,0 +1,24 @@
+
+
+x=1;
+while (x<=10)
+ {
+ printf("X=%u\n",x);
+ }
+
+
+x:=1;
+while (x<=10)
+ {
+ printf("X=%u\n",x);
+ }
+
+
+x=1;
+while (x<=10)
+ {
+ printf("X=%u\n",x);
+ }
+
+
+
diff --git a/web/funnelAC/results/ex08.lis b/web/funnelAC/results/ex08.lis
new file mode 100644
index 0000000000..17d93d8838
--- /dev/null
+++ b/web/funnelAC/results/ex08.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex08.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/ex08.out b/web/funnelAC/results/ex08.out
new file mode 100644
index 0000000000..5820d58ba2
--- /dev/null
+++ b/web/funnelAC/results/ex08.out
@@ -0,0 +1,107 @@
+The Twelve Bugs of Christmas
+----------------------------
+For the first bug of Christmas, my manager said to me
+ See if they can do it again.
+
+For the second bug of Christmas, my manager said to me
+ Ask them how they did it and
+ See if they can do it again.
+
+For the third bug of Christmas, my manager said to me
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+For the fourth bug of Christmas, my manager said to me
+ Run with the debugger
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+For the fifth bug of Christmas, my manager said to me
+ Ask for a dump
+ Run with the debugger
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+For the sixth bug of Christmas, my manager said to me
+ Reinstall the software
+ Ask for a dump
+ Run with the debugger
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+For the seventh bug of Christmas, my manager said to me
+ Say they need an upgrade
+ Reinstall the software
+ Ask for a dump
+ Run with the debugger
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+For the eighth bug of Christmas, my manager said to me
+ Find a way around it
+ Say they need an upgrade
+ Reinstall the software
+ Ask for a dump
+ Run with the debugger
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+For the ninth bug of Christmas, my manager said to me
+ Blame it on the hardware
+ Find a way around it
+ Say they need an upgrade
+ Reinstall the software
+ Ask for a dump
+ Run with the debugger
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+For the tenth bug of Christmas, my manager said to me
+ Change the documentation
+ Blame it on the hardware
+ Find a way around it
+ Say they need an upgrade
+ Reinstall the software
+ Ask for a dump
+ Run with the debugger
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+For the eleventh bug of Christmas, my manager said to me
+ Say it's not supported
+ Change the documentation
+ Blame it on the hardware
+ Find a way around it
+ Say they need an upgrade
+ Reinstall the software
+ Ask for a dump
+ Run with the debugger
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+For the twelfth bug of Christmas, my manager said to me
+ Tell them it's a feature
+ Say it's not supported
+ Change the documentation
+ Blame it on the hardware
+ Find a way around it
+ Say they need an upgrade
+ Reinstall the software
+ Ask for a dump
+ Run with the debugger
+ Try to reproduce it
+ Ask them how they did it and
+ See if they can do it again.
+
+
+This song appeared in the internet newsgroup rec.humor.funny on 24-Dec-1991.
+It was contributed by Pat Scannell (scannell@darkstar.ma30.bull.com).
diff --git a/web/funnelAC/results/ex09.lis b/web/funnelAC/results/ex09.lis
new file mode 100644
index 0000000000..1fdc31299c
--- /dev/null
+++ b/web/funnelAC/results/ex09.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex09.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/ex09.out b/web/funnelAC/results/ex09.out
new file mode 100644
index 0000000000..80fbfc9f1f
--- /dev/null
+++ b/web/funnelAC/results/ex09.out
@@ -0,0 +1,6 @@
+
+I like to go shooting, it's a whole lot of fun,
+'Cos I shoot with a camera instead of a gun.
+The animals flock to be petted and fed,
+Cos they know my camera isn't loaded with lead.
+- RNW, 04-Jan-1991.
diff --git a/web/funnelAC/results/ex10.lis b/web/funnelAC/results/ex10.lis
new file mode 100644
index 0000000000..613224af3d
--- /dev/null
+++ b/web/funnelAC/results/ex10.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex10.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/ex10.out b/web/funnelAC/results/ex10.out
new file mode 100644
index 0000000000..9672b09b88
--- /dev/null
+++ b/web/funnelAC/results/ex10.out
@@ -0,0 +1,2 @@
+This is the text of the sloth macro.
+
diff --git a/web/funnelAC/results/ex11.lis b/web/funnelAC/results/ex11.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/results/ex11.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/ex11.tex b/web/funnelAC/results/ex11.tex
new file mode 100644
index 0000000000..b5e6714dd2
--- /dev/null
+++ b/web/funnelAC/results/ex11.tex
@@ -0,0 +1,384 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+EX11: This example shows how FunnelWeb typesets macros, typesetter commands
+ and free text.
+
+You are reading some free text before the macro. Free text can consist
+of any text (not containing the FunnelWeb special character) including
+typesetter commands
+such as \$, \%, \#, and $\backslash$TeX$\{$$\}$ which
+will be typeset to appear exactly as they do in the input file!
+Look out! Here comes a macro!
+
+\fwbeginmacro
+\fwfilename{ex11.out}{1}\fwequals \fwodef \fwbtx[This text is part of
+a macro definition.
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+
+This is free text following the macro. This sentence contains
+two \fwlit{inline} typesetter \fwemp{directives}.
+Now here is a non-inline typesetting directive.
+
+
+\fwnewpage
+
+
+This sentence will appear on the next page.
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/results/ex12.lis b/web/funnelAC/results/ex12.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/results/ex12.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/ex12.tex b/web/funnelAC/results/ex12.tex
new file mode 100644
index 0000000000..145d1d111f
--- /dev/null
+++ b/web/funnelAC/results/ex12.tex
@@ -0,0 +1,385 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+EX12: This example gives some simple headings and demonstrates heading name
+ inheritance.
+
+\fwbeginmacro
+\fwfilename{ex12.out}{1}\fwequals \fwodef \fwbtx[dummy text]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwseca{1}{Feed the Penguins and Save the World}
+\fwsecb{1.1}{Feed the Penguins}
+\fwsecc{1.1.1}{Feed the little penguins}
+\fwsecc{1.1.2}{Feed the big penguins}
+\fwsecb{1.2}{Save the World}
+\fwsecc{1.2.1}{Save Europe}
+\fwsecc{1.2.2}{Save Africa}
+
+\fwsecc{1.2.3}{Save the rest of the world} This heading hasn't been given an explicit name, but will inherit the
+name $\backslash$p$\{$Save the rest of the world$\}$ from the macro definition below.
+
+\fwbeginmacro
+\fwmacroname{Save the rest of the world}{2}\fwzero{}\fwequals \fwodef \fwbtx[...]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/results/ex13.lis b/web/funnelAC/results/ex13.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/results/ex13.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/ex13.tex b/web/funnelAC/results/ex13.tex
new file mode 100644
index 0000000000..835ae999e6
--- /dev/null
+++ b/web/funnelAC/results/ex13.tex
@@ -0,0 +1,499 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+EX13: This example is used to generate typeset documentation which is
+ discussed in the tutorial in the FunnelWeb user's manual.
+
+
+\fwseca{1}{Table of Contents}
+
+
+\fwtocstart{}
+\fwtoca{1}{Table of Contents}
+\fwtoca{2}{Macros for Moral Support}
+\fwtoca{3}{An Extremely Imperative Stack Abstraction}
+\fwtocb{3.1}{Define the Stack}
+\fwtocb{3.2}{Push the Stack}
+\fwtocb{3.3}{Pop the Stack}
+\fwtocb{3.4}{Rough the Stack Up a Bit}
+\fwtocfinish{}
+
+
+\fwseca{2}{Macros for Moral Support}
+
+The following macro contain comments that provide moral support in the
+output code.
+
+\fwbeginmacro
+\fwmacroname{Programmer's Cheer}{1}\fwmany{}\fwequals \fwodef \fwbtx[
+-- Shift to the left!
+-- Shift to the right!
+-- Pop up, push down!
+-- Byte! Byte! Byte!
+-- (From "The New Hacker's Dictionary").
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is invoked in definitions 6 and 8.}
+\fwendmacronotes
+\fwendmacro
+
+
+The next macro is similar but is distributed throughout the program.
+\fwbeginmacro
+\fwmacroname{Hacker's Cheer}{2}\fwplusequals \fwodef \fwbtx[
+-- Pointer to the left
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 2, 3, 5, 7, and 9.}
+\fwusedin{This macro is invoked in definition 10.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwseca{3}{An Extremely Imperative Stack Abstraction}
+
+\fwsecb{3.1}{Define the Stack}
+\fwbeginmacro
+\fwmacroname{Hacker's Cheer}{3}\fwplusequals \fwodef \fwbtx[-- Pointer to the right
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 2, 3, 5, 7, and 9.}
+\fwusedin{This macro is invoked in definition 10.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Stack Type}{4}\fwzero{}\fwequals \fwodef \fwbtx[type stack = record ... end;]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsecb{3.2}{Push the Stack}
+\fwbeginmacro
+\fwmacroname{Hacker's Cheer}{5}\fwplusequals \fwodef \fwbtx[-- Hack that code
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 2, 3, 5, 7, and 9.}
+\fwusedin{This macro is invoked in definition 10.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Push Procedure}{6}\fwzero{}\fwequals \fwodef \fwbtx[procedure push(var b:stack; v:value); ]fwetx=%
+\fwmacroname{Programmer's Cheer}{1}\fwbtx[ {...}]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsecb{3.3}{Pop the Stack}
+\fwbeginmacro
+\fwmacroname{Hacker's Cheer}{7}\fwplusequals \fwodef \fwbtx[-- Tight! Tight! Tight!
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 2, 3, 5, 7, and 9.}
+\fwusedin{This macro is invoked in definition 10.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Pop Procedure}{8}\fwzero{}\fwequals \fwodef \fwbtx[procedure pop(var b:stack); ]fwetx=%
+\fwmacroname{Programmer's Cheer}{1}\fwbtx[ {...}]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsecb{3.4}{Rough the Stack Up a Bit}
+\fwbeginmacro
+\fwmacroname{Hacker's Cheer}{9}\fwplusequals \fwodef \fwbtx[-- (RNW, 04-Jan-1991).
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 2, 3, 5, 7, and 9.}
+\fwusedin{This macro is invoked in definition 10.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Rough Procedure}{10}\fwzero{}\fwequals \fwodef \fwbtx[procedure rough(var b:stack); ]fwetx=%
+\fwmacroname{Hacker's Cheer}{2}\fwbtx[ {...}]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwbeginmacro
+\fwfilename{dummy.txt}{11}\fwequals \fwodef \fwbtx[dummy
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/results/ex14.lis b/web/funnelAC/results/ex14.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/results/ex14.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/ex14.tex b/web/funnelAC/results/ex14.tex
new file mode 100644
index 0000000000..1de1e8756b
--- /dev/null
+++ b/web/funnelAC/results/ex14.tex
@@ -0,0 +1,369 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+EX14: This example demonstrates the literal and emphasis typesetting constructs.
+
+The following procedure \fwlit{put\_sloth} writes the \fwlit{sloth} variable to
+the output file. Note: \fwemp{The output file must be opened for writing
+at this point or the program will crash!}
+
+\fwbeginmacro
+\fwfilename{ex14.out}{1}\fwequals \fwodef \fwbtx[dummy
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/results/ex15.lis b/web/funnelAC/results/ex15.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/results/ex15.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/ex15.tex b/web/funnelAC/results/ex15.tex
new file mode 100644
index 0000000000..a82b33d2f2
--- /dev/null
+++ b/web/funnelAC/results/ex15.tex
@@ -0,0 +1,390 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+EX15: This example demonstrates some of FunnelWeb's generic typesetting
+ constructs.
+
+\fwvskip{40}
+\fwcenterline{\fwfonttitle{Hairy Wombat}}
+\fwcenterline{\fwfonttitle{Simulation}}
+\fwvskip{10}
+\fwcenterline{\fwfontsmalltitle{A Program in Six Parts}}
+\fwcenterline{\fwfontsmalltitle{Simulating the Life of Some Hairy Wombats}}
+\fwvskip{20}
+\fwleftline{\fwfontnormal{By Zqitzypbuswapzra Ypongtatoslrtzz}}
+
+\fwnewpage
+
+
+\fwtocstart{}
+\fwtoca{1}{Section One}
+\fwtoca{2}{Section Two}
+\fwtocfinish{}
+
+
+\fwnewpage
+
+
+\fwseca{1}{Section One}
+\fwseca{2}{Section Two}
+
+\fwbeginmacro
+\fwfilename{ex15.out}{1}\fwequals \fwodef \fwbtx[Dummy
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/results/ex16.lis b/web/funnelAC/results/ex16.lis
new file mode 100644
index 0000000000..46682a4458
--- /dev/null
+++ b/web/funnelAC/results/ex16.lis
@@ -0,0 +1,13 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed ex16.out.
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/ex16.out b/web/funnelAC/results/ex16.out
new file mode 100644
index 0000000000..a3b510afd9
--- /dev/null
+++ b/web/funnelAC/results/ex16.out
@@ -0,0 +1,18 @@
+with text_io; use text_io;
+
+procedure example is
+ n : constant natural := 10; -- How many numbers? (Ans: [1,n]).
+ p : constant natural := 5; -- How many powers? (Ans: [1,p]).
+begin -- example
+ for i in 1..n loop
+ declare
+ ip : natural := 1;
+ begin
+ for power in 1..p loop
+ ip:=ip*i;
+ put(natural'image(ip) & " ");
+ end loop;
+ new_line;
+ end;
+ end loop;
+end example;
diff --git a/web/funnelAC/results/ex16.tex b/web/funnelAC/results/ex16.tex
new file mode 100644
index 0000000000..c29b4ce43e
--- /dev/null
+++ b/web/funnelAC/results/ex16.tex
@@ -0,0 +1,448 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+
+\fwvskip{40}
+\fwcenterline{\fwfonttitle{Powers:}}
+\fwcenterline{\fwfonttitle{An Example of}}
+\fwcenterline{\fwfonttitle{A Short}}
+\fwcenterline{\fwfonttitle{FunnelWeb .fw File}}
+\fwvskip{10}
+\fwcenterline{\fwfontsmalltitle{by Ross Williams}}
+\fwcenterline{\fwfontsmalltitle{26 January 1992}}
+\fwvskip{20}
+
+\fwtocstart{}
+\fwtoca{1}{FunnelWeb Example Program}
+\fwtocb{1.1}{ex16.out}
+\fwtocb{1.2}{Pull in packages}
+\fwtocb{1.3}{Write out the first p powers of i on a single line}
+\fwtocfinish{}
+
+
+\fwseca{1}{FunnelWeb Example Program}
+
+This program writes out each of the first \fwlit{p} powers of the first \fwlit{n}
+integers. These constant parameters are located here so that they are easy to
+change.
+
+\fwbeginmacro
+\fwmacroname{Constants}{1}\fwequals \fwodef \fwbtx[n : constant natural := 10; -- How many numbers? (Ans: [1,n]).
+p : constant natural := 5; -- How many powers? (Ans: [1,p]).]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is invoked in definition 2.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsecb{1.1}{ex16.out} Here is the outline of the program. This FunnelWeb file generates a single
+Ada output file called \fwlit{Power.ada}. The main program consists of a loop that
+iterates once for each number to be written out.
+
+\fwbeginmacro
+\fwfilename{ex16.out}{2}\fwequals \fwodef \fwmacroname{Pull in packages}{3}\fwbtx[
+
+procedure example is
+ ]fwetx=%
+\fwmacroname{Constants}{1}\fwbtx[
+begin -- example
+ for i in 1..n loop
+ ]fwetx=%
+\fwmacroname{Write out the first p powers of i on a single line}{4}\fwbtx[
+ end loop;
+end example;
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsecb{1.2}{Pull in packages} In this section, we pull in the packages that this program needs to run. In
+fact, all we need is the IO package so that we can write out the results. To use
+the IO package, we first of all need to haul it in (\fwlit{with text\_io}) and then
+we need to make all its identifiers visible at the top level (\fwlit{use text\_io}).
+
+\fwbeginmacro
+\fwmacroname{Pull in packages}{3}\fwequals \fwodef \fwbtx[with text_io; use text_io;]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is invoked in definition 2.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsecb{1.3}{Write out the first p powers of i on a single line} Here is the bit that writes out the first \fwlit{p} powers of \fwlit{i}. The power
+values are calculated incrementally in \fwlit{ip} to avoid the use of the
+exponentiation operator.
+
+\fwbeginmacro
+\fwmacroname{Write out the first p powers of i on a single line}{4}\fwequals \fwodef \fwbtx[declare
+ ip : natural := 1;
+begin
+ for power in 1..p loop
+ ip:=ip*i;
+ put(natural'image(ip) & " ");
+ end loop;
+ new_line;
+end;]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is invoked in definition 2.}
+\fwendmacronotes
+\fwendmacro
+
+
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/results/generate.lis b/web/funnelAC/results/generate.lis
new file mode 100644
index 0000000000..8588c0fca9
--- /dev/null
+++ b/web/funnelAC/results/generate.lis
@@ -0,0 +1,15 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed sc06.fw.
+Tangle: Completed sc08.fw.
+Tangle: Completed sc09.fw.
+Tangle: Completed sc13e.fwi.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/hi01.lis b/web/funnelAC/results/hi01.lis
new file mode 100644
index 0000000000..58682d7c0d
--- /dev/null
+++ b/web/funnelAC/results/hi01.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi01.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/hi01.out b/web/funnelAC/results/hi01.out
new file mode 100644
index 0000000000..9ab646f4ff
--- /dev/null
+++ b/web/funnelAC/results/hi01.out
@@ -0,0 +1,9 @@
+
+while the_walrus_is_sleepy do
+ begin
+ writeln('zzzzzzz');
+
+ wake_up_the_walrus(the_walrus);
+
+ writeln('Umpharumpha...');
+ end;
diff --git a/web/funnelAC/results/hi02.lis b/web/funnelAC/results/hi02.lis
new file mode 100644
index 0000000000..2c342e0954
--- /dev/null
+++ b/web/funnelAC/results/hi02.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi02.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/hi02.out b/web/funnelAC/results/hi02.out
new file mode 100644
index 0000000000..d1a9b3e8cf
--- /dev/null
+++ b/web/funnelAC/results/hi02.out
@@ -0,0 +1,6 @@
+
+while sloth<walrus loop
+ assert(sloth<walrus,"AWK! sloth>=walrus!!!!!!!");
+ assert(timer<timermax,"AWK! timer>=timermax!!!");
+ inc(sloth);
+end loop
diff --git a/web/funnelAC/results/hi03.lis b/web/funnelAC/results/hi03.lis
new file mode 100644
index 0000000000..80014f814d
--- /dev/null
+++ b/web/funnelAC/results/hi03.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi03.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/hi03.out b/web/funnelAC/results/hi03.out
new file mode 100644
index 0000000000..5b1b66b552
--- /dev/null
+++ b/web/funnelAC/results/hi03.out
@@ -0,0 +1,6 @@
+
+while sloth<walrus loop
+ assert(sloth<walrus,"AWK! sloth>=walrus!!!!!!!");
+ assert(timer<timermax,"AWK! timer>=timermax!!!");
+ inc(sloth);
+end loop
diff --git a/web/funnelAC/results/hi04.lis b/web/funnelAC/results/hi04.lis
new file mode 100644
index 0000000000..c215c0f14b
--- /dev/null
+++ b/web/funnelAC/results/hi04.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi04.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/hi04.out b/web/funnelAC/results/hi04.out
new file mode 100644
index 0000000000..7069503f68
--- /dev/null
+++ b/web/funnelAC/results/hi04.out
@@ -0,0 +1,3 @@
+-------
+get_command_line(comline)
+-------
diff --git a/web/funnelAC/results/hi05.lis b/web/funnelAC/results/hi05.lis
new file mode 100644
index 0000000000..422de4e7eb
--- /dev/null
+++ b/web/funnelAC/results/hi05.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi05.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/hi05.out b/web/funnelAC/results/hi05.out
new file mode 100644
index 0000000000..d2143079f1
--- /dev/null
+++ b/web/funnelAC/results/hi05.out
@@ -0,0 +1,7 @@
+Unreadable Postscript code
+/print { push pop pop push turn around and jump up and down and print it} def
+
+Unreadable Postscript code
+/zap { push pop pop push turn around and jump up and down and print it} def
+
+Unreadable Postscript code
diff --git a/web/funnelAC/results/hi06.lis b/web/funnelAC/results/hi06.lis
new file mode 100644
index 0000000000..e053ffc8bf
--- /dev/null
+++ b/web/funnelAC/results/hi06.lis
@@ -0,0 +1,13 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi06a.out.
+Tangle: Completed hi06b.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/hi06a.out b/web/funnelAC/results/hi06a.out
new file mode 100644
index 0000000000..b6645c6f7d
--- /dev/null
+++ b/web/funnelAC/results/hi06a.out
@@ -0,0 +1,3 @@
+DCL commands
+copy printme.txt unixnode::
+DCL commands
diff --git a/web/funnelAC/results/hi06b.out b/web/funnelAC/results/hi06b.out
new file mode 100644
index 0000000000..d26ba0f49c
--- /dev/null
+++ b/web/funnelAC/results/hi06b.out
@@ -0,0 +1,3 @@
+unix commands
+print printme.txt
+unix commands
diff --git a/web/funnelAC/results/hi07.lis b/web/funnelAC/results/hi07.lis
new file mode 100644
index 0000000000..5a23a3ee91
--- /dev/null
+++ b/web/funnelAC/results/hi07.lis
@@ -0,0 +1,13 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi07a.out.
+Tangle: Completed hi07b.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/hi07a.out b/web/funnelAC/results/hi07a.out
new file mode 100644
index 0000000000..052b1c079a
--- /dev/null
+++ b/web/funnelAC/results/hi07a.out
@@ -0,0 +1,4 @@
+First lump of text shared by both documents.
+Text for first document
+Second lump of text shared by both documents.
+
diff --git a/web/funnelAC/results/hi07b.out b/web/funnelAC/results/hi07b.out
new file mode 100644
index 0000000000..8c94004628
--- /dev/null
+++ b/web/funnelAC/results/hi07b.out
@@ -0,0 +1,4 @@
+First lump of text shared by both documents.
+Text for second document
+Second lump of text shared by both documents.
+
diff --git a/web/funnelAC/results/hi08.lis b/web/funnelAC/results/hi08.lis
new file mode 100644
index 0000000000..e0fa58dddb
--- /dev/null
+++ b/web/funnelAC/results/hi08.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi08.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/hi08.out b/web/funnelAC/results/hi08.out
new file mode 100644
index 0000000000..87b344c98f
--- /dev/null
+++ b/web/funnelAC/results/hi08.out
@@ -0,0 +1,8 @@
+1992 ANNUAL REPORT TO Shareholders
+==================================
+This has been a very good year for The Very Big Corporation of America.
+With your help, we have been able to successfully
+screw the customers for every cent they have.
+With gross earnings approaching six trillion dollars, we have been able to
+increase dividends.
+We expect to have an even better year next year.
diff --git a/web/funnelAC/results/hi09.lis b/web/funnelAC/results/hi09.lis
new file mode 100644
index 0000000000..fb069219c0
--- /dev/null
+++ b/web/funnelAC/results/hi09.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi09.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/hi09.out b/web/funnelAC/results/hi09.out
new file mode 100644
index 0000000000..0f7aeebe64
--- /dev/null
+++ b/web/funnelAC/results/hi09.out
@@ -0,0 +1,98 @@
+
+[inherit ('NaryTree'), environment ('NaryTreeSet')]
+
+module NaryTreeSet;
+
+type NaryTreeSet = ^NaryTreeSetRecord;
+ NaryTreeSetRecord = record
+ Member: NaryTree;
+ Next: NaryTreeSet;
+ end;
+
+procedure NullNaryTreeSet (var Result: NaryTreeSet);
+begin new (Result);
+Result^.Member := (- MaxInt)::NaryTree;
+Result^.Next := nil end;
+
+function IsNullNaryTreeSet (S: NaryTreeSet): boolean;
+begin IsNullNaryTreeSet := S^.Member::integer = - MaxInt end;
+
+procedure ForEachNaryTree (S: NaryTreeSet; procedure DoIt (i: NaryTree));
+var ThisS, NextS: NaryTreeSet;
+begin ThisS := S;
+while ThisS^.Member::integer <> - MaxInt do
+ begin NextS := ThisS^.Next;
+ DoIt (ThisS^.Member);
+ ThisS := NextS end;
+end;
+
+function FirstNaryTree (S: NaryTreeSet): NaryTree;
+begin FirstNaryTree := S^.Member end;
+
+function IsNaryTreeInSet (i: NaryTree; S: NaryTreeSet): boolean;
+ procedure TestEquals (j: NaryTree);
+ begin if EqualNaryTree (i, j) then IsNaryTreeInSet := true; end;
+begin IsNaryTreeInSet := false; ForEachNaryTree (S, TestEquals); end;
+
+function IncludesNaryTreeSet (S1, S2: NaryTreeSet): boolean;
+var Result: boolean;
+ procedure TestIfInS1 (i: NaryTree);
+ begin if Result then if not IsNaryTreeInSet (i, S1) then Result := false; end;
+begin Result := true;
+ForEachNaryTree (S2, TestIfInS1);
+IncludesNaryTreeSet := Result end;
+
+function DisjointNaryTreeSets (S1, S2: NaryTreeSet): boolean;
+var Result: boolean;
+ procedure TestIfInS1 (i: NaryTree);
+ begin if Result then if IsNaryTreeInSet (i, S1) then Result := false; end;
+begin Result := true;
+ForEachNaryTree (S2, TestIfInS1);
+DisjointNaryTreeSets := Result end;
+
+function EqualNaryTreeSet (S1, S2: NaryTreeSet): boolean;
+begin
+EqualNaryTreeSet := IncludesNaryTreeSet (S1, S2) and IncludesNaryTreeSet (S2, S1);
+end;
+
+procedure InsertNaryTree (i: NaryTree; var S: NaryTreeSet);
+var This, Pred, Succ: NaryTreeSet;
+begin
+if not IsNaryTreeInSet (i, S) then
+ begin
+ Pred := nil; Succ := S;
+ while Succ^.Member::integer > i::integer do begin
+ Pred := Succ; Succ := Succ^.Next end;
+ if Succ^.Member::integer < i::integer then begin
+ new (This); This^.Next := Succ; This^.Member := i;
+ if Pred <> nil then Pred^.Next := This else S := This;
+ end;
+ end;
+end;
+
+procedure InsertNaryTrees (S1: NaryTreeSet; var S2: NaryTreeSet);
+var This, Pred, Succ: NaryTreeSet;
+ procedure AddNaryTree (i: NaryTree);
+ begin InsertNaryTree (i, S2) end;
+begin
+ForEachNaryTree (S1, AddNaryTree);
+end;
+
+procedure RemoveNaryTree (i: NaryTree; var S: NaryTreeSet);
+var Pred, This: NaryTreeSet;
+begin
+Pred := nil; This := S;
+while not EqualNaryTree (This^.Member, i) do begin
+ Pred := This; This := This^.Next end;
+if Pred <> nil then Pred^.Next := This^.Next else S := This^.Next;
+Dispose (This);
+end;
+
+procedure DisposeNaryTreeSet (var S: NaryTreeSet);
+var Old: NaryTreeSet;
+begin
+while S <> nil do begin Old := S; S := S^.Next; Dispose (Old) end;
+end;
+
+end.
+
diff --git a/web/funnelAC/results/hi10.lis b/web/funnelAC/results/hi10.lis
new file mode 100644
index 0000000000..fbe12da983
--- /dev/null
+++ b/web/funnelAC/results/hi10.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed hi10.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/hi10.out b/web/funnelAC/results/hi10.out
new file mode 100644
index 0000000000..a7ec61c0f6
--- /dev/null
+++ b/web/funnelAC/results/hi10.out
@@ -0,0 +1,23 @@
+
+/* Pre: sorted(b). */
+i=1; p=1;
+while (i != N)
+ {
+ /* Invariant: sorted(b) and 1<=i<=N and */
+ /* p is len of longest run in b[1..i]. */
+ i++; if (b[i] != b[i-p]) p++;
+ }
+/* Post: sorted(b) and p is the length of the longest run in b[1..N]. */
+
+
+bool comp(p,q)
+char *p,*q;
+{
+ while (TRUE)
+ {
+ if (*p != *q ) return FALSE;
+ if (*p == '\0') return TRUE;
+ p++; q++;
+ }
+}
+
diff --git a/web/funnelAC/results/pr01.lis b/web/funnelAC/results/pr01.lis
new file mode 100644
index 0000000000..116c1daef6
--- /dev/null
+++ b/web/funnelAC/results/pr01.lis
@@ -0,0 +1,544 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 30 31 3A 20 54 65 73 74 20 74 68 65 20 69 | PR01: Test the i |
+| 6E 6C 69 6E 65 20 74 79 70 65 73 65 74 74 69 6E | nline typesettin |
+| 67 20 66 65 61 74 75 72 65 73 2E 0A 0A 31 2E 20 | g features...1. |
+| 46 69 72 73 74 20 77 65 20 74 65 73 74 20 74 68 | First we test th |
+| 65 20 6C 65 67 61 6C 20 75 73 65 20 6F 66 20 74 | e legal use of t |
+| 68 65 20 40 7B 6C 69 74 65 72 61 6C 40 7D 20 63 | he @{literal@} c |
+| 6F 6E 73 74 72 75 63 74 2E 0A 0A 32 2E 54 65 73 | onstruct...2.Tes |
+| 74 20 40 7B 40 7D 20 28 69 6C 6C 65 67 61 6C 29 | t @{@} (illegal) |
+| 2E 0A 40 41 40 3C 45 72 72 6F 72 20 52 65 63 6F | ..@A@<Error Reco |
+| 76 65 72 79 20 50 6F 69 6E 74 40 3E 0A 0A 33 2E | very Point@>..3. |
+| 20 54 65 73 74 20 74 68 65 20 63 6F 6E 73 74 72 | Test the constr |
+| 75 63 74 20 40 7B 61 63 72 6F 73 73 0A 20 20 20 | uct @{across. |
+| 6D 6F 72 65 20 74 68 61 6E 20 6F 6E 65 20 6C 69 | more than one li |
+| 6E 65 40 7D 2E 0A 0A 34 2E 20 4E 6F 77 20 77 65 | ne@}...4. Now we |
+| 20 74 65 73 74 20 74 68 65 20 63 6F 6E 73 74 72 | test the constr |
+| 75 63 74 20 77 69 74 68 20 6E 6F 6E 2D 74 65 78 | uct with non-tex |
+| 74 20 66 6F 6C 6C 6F 77 69 6E 67 20 69 74 2E 0A | t following it.. |
+| 20 20 20 40 7B 40 3C 73 6C 6F 74 68 40 3E 40 7D | @{@<sloth@>@} |
+| 0A 40 41 40 3C 45 72 72 6F 72 20 52 65 63 6F 76 | .@A@<Error Recov |
+| 65 72 79 20 50 6F 69 6E 74 40 3E 0A 20 20 20 40 | ery Point@>. @ |
+| 7B 20 20 20 20 20 40 3E 20 20 20 40 7D 0A 40 41 | { @> @}.@A |
+| 40 3C 45 72 72 6F 72 20 52 65 63 6F 76 65 72 79 | @<Error Recovery |
+| 20 50 6F 69 6E 74 40 3E 0A 0A 35 2E 20 54 65 73 | Point@>..5. Tes |
+| 74 20 74 68 65 20 6C 65 67 61 6C 20 75 73 65 20 | t the legal use |
+| 6F 66 20 74 68 65 20 40 2F 65 6D 70 68 61 73 69 | of the @/emphasi |
+| 73 40 2F 20 63 6F 6E 73 74 72 75 63 74 2E 0A 0A | s@/ construct... |
+| 36 2E 54 65 73 74 20 40 2F 40 2F 20 28 69 6C 6C | 6.Test @/@/ (ill |
+| 65 67 61 6C 29 2E 0A 40 41 40 3C 45 72 72 6F 72 | egal)..@A@<Error |
+| 20 52 65 63 6F 76 65 72 79 20 50 6F 69 6E 74 40 | Recovery Point@ |
+| 3E 0A 0A 37 2E 20 54 65 73 74 20 74 68 65 20 63 | >..7. Test the c |
+| 6F 6E 73 74 72 75 63 74 20 40 2F 61 63 72 6F 73 | onstruct @/acros |
+| 73 0A 20 20 20 6D 6F 72 65 20 74 68 61 6E 20 6F | s. more than o |
+| 6E 65 20 6C 69 6E 65 40 2F 2E 0A 0A 38 2E 20 4E | ne line@/...8. N |
+| 6F 77 20 77 65 20 74 65 73 74 20 74 68 65 20 63 | ow we test the c |
+| 6F 6E 73 74 72 75 63 74 20 77 69 74 68 20 6E 6F | onstruct with no |
+| 6E 2D 74 65 78 74 20 66 6F 6C 6C 6F 77 69 6E 67 | n-text following |
+| 20 69 74 2E 0A 20 20 20 40 2F 40 3C 73 6C 6F 74 | it.. @/@<slot |
+| 68 40 3E 40 2F 0A 40 41 40 3C 45 72 72 6F 72 20 | h@>@/.@A@<Error |
+| 52 65 63 6F 76 65 72 79 20 50 6F 69 6E 74 40 3E | Recovery Point@> |
+| 0A 20 20 20 40 2F 20 20 20 20 20 40 3C 20 20 20 | . @/ @< |
+| 40 2F 0A 0A 0A 0A | @/.... |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR01: Test the inline typesetting features.<010>
+00002 00002| <010>
+00003 00003| 1. First we test the legal use of the @{literal@} construct.<010>
+00004 00004| <010>
+00005 00005| 2.Test @{@} (illegal).<010>
+00006 00006| @A@<Error Recovery Point@><010>
+00007 00007| <010>
+00008 00008| 3. Test the construct @{across<010>
+00009 00009| more than one line@}.<010>
+00010 00010| <010>
+00011 00011| 4. Now we test the construct with non-text following it.<010>
+00012 00012| @{@<sloth@>@}<010>
+00013 00013| @A@<Error Recovery Point@><010>
+00014 00014| @{ @> @}<010>
+00015 00015| @A@<Error Recovery Point@><010>
+00016 00016| <010>
+00017 00017| 5. Test the legal use of the @/emphasis@/ construct.<010>
+00018 00018| <010>
+00019 00019| 6.Test @/@/ (illegal).<010>
+00020 00020| @A@<Error Recovery Point@><010>
+00021 00021| <010>
+00022 00022| 7. Test the construct @/across<010>
+00023 00023| more than one line@/.<010>
+00024 00024| <010>
+00025 00025| 8. Now we test the construct with non-text following it.<010>
+00026 00026| @/@<sloth@>@/<010>
+00027 00027| @A@<Error Recovery Point@><010>
+00028 00028| @/ @< @/<010>
+00029 00029| <010>
+00030 00030| <010>
+00031 00031| <010>
+00032 00032| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 73 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR01: Test the inline typesetting features.<010>
+<010>
+1. First we test the legal use of the "
+0003[39]: @{ Open defn.
+0003[41]: Text. Text scrap[Grey]="literal"
+0003[48]: @} Close defn.
+0003[50]: Text. Text scrap[Grey]=" construct.<010>
+<010>
+2.Test "
+0005[08]: @{ Open defn.
+0005[10]: @} Close defn.
+0005[12]: Text. Text scrap[Grey]=" (illegal).<010>
+"
+0006[01]: @A New section (Level 1).
+0006[03]: @< Open name.
+0006[05]: Text. Text scrap[Grey]="Error Recovery Point"
+0006[25]: @> Close name.
+0006[27]: Text. Text scrap[Grey]="<010>
+<010>
+3. Test the construct "
+0008[23]: @{ Open defn.
+0008[25]: Text. Text scrap[Grey]="across<010>
+ more than one line"
+0009[22]: @} Close defn.
+0009[24]: Text. Text scrap[Grey]=".<010>
+<010>
+4. Now we test the construct with non-text following it.<010>
+ "
+0012[04]: @{ Open defn.
+0012[06]: @< Open name.
+0012[08]: Text. Text scrap[Grey]="sloth"
+0012[13]: @> Close name.
+0012[15]: @} Close defn.
+0012[17]: Text. Text scrap[White]="<010>
+"
+0013[01]: @A New section (Level 1).
+0013[03]: @< Open name.
+0013[05]: Text. Text scrap[Grey]="Error Recovery Point"
+0013[25]: @> Close name.
+0013[27]: Text. Text scrap[White]="<010>
+ "
+0014[04]: @{ Open defn.
+0014[06]: Text. Text scrap[White]=" "
+0014[11]: @> Close name.
+0014[13]: Text. Text scrap[White]=" "
+0014[16]: @} Close defn.
+0014[18]: Text. Text scrap[White]="<010>
+"
+0015[01]: @A New section (Level 1).
+0015[03]: @< Open name.
+0015[05]: Text. Text scrap[Grey]="Error Recovery Point"
+0015[25]: @> Close name.
+0015[27]: Text. Text scrap[Grey]="<010>
+<010>
+5. Test the legal use of the "
+0017[30]: @/ Emphasise.
+0017[32]: Text. Text scrap[Grey]="emphasis"
+0017[40]: @/ Emphasise.
+0017[42]: Text. Text scrap[Grey]=" construct.<010>
+<010>
+6.Test "
+0019[08]: @/ Emphasise.
+0019[10]: @/ Emphasise.
+0019[12]: Text. Text scrap[Grey]=" (illegal).<010>
+"
+0020[01]: @A New section (Level 1).
+0020[03]: @< Open name.
+0020[05]: Text. Text scrap[Grey]="Error Recovery Point"
+0020[25]: @> Close name.
+0020[27]: Text. Text scrap[Grey]="<010>
+<010>
+7. Test the construct "
+0022[23]: @/ Emphasise.
+0022[25]: Text. Text scrap[Grey]="across<010>
+ more than one line"
+0023[22]: @/ Emphasise.
+0023[24]: Text. Text scrap[Grey]=".<010>
+<010>
+8. Now we test the construct with non-text following it.<010>
+ "
+0026[04]: @/ Emphasise.
+0026[06]: @< Open name.
+0026[08]: Text. Text scrap[Grey]="sloth"
+0026[13]: @> Close name.
+0026[15]: @/ Emphasise.
+0026[17]: Text. Text scrap[White]="<010>
+"
+0027[01]: @A New section (Level 1).
+0027[03]: @< Open name.
+0027[05]: Text. Text scrap[Grey]="Error Recovery Point"
+0027[25]: @> Close name.
+0027[27]: Text. Text scrap[White]="<010>
+ "
+0028[04]: @/ Emphasise.
+0028[06]: Text. Text scrap[White]=" "
+0028[11]: @< Open name.
+0028[13]: Text. Text scrap[White]=" "
+0028[16]: @/ Emphasise.
+0028[18]: Text. Text scrap[White]="<010>
+<010>
+<010>
+<010>
+"
+0032[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#file"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#line"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#timestamp"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR01: Test the inline typesetting features.<010>
+<010>
+1. First we test the legal use of the "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open literal.
+
+TEXT COMPONENT: Pos(L,C)=(3,41).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="literal"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Close literal.
+
+TEXT COMPONENT: Pos(L,C)=(3,50).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]=" construct.<010>
+<010>
+2.Test "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open literal.
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1", Section name="Error Recovery Point".
+
+TEXT COMPONENT: Pos(L,C)=(6,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+3. Test the construct "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open literal.
+
+TEXT COMPONENT: Pos(L,C)=(8,25).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="across<010>
+ more than one line"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Close literal.
+
+TEXT COMPONENT: Pos(L,C)=(9,24).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]=".<010>
+<010>
+4. Now we test the construct with non-text following it.<010>
+ "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open literal.
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="Error Recovery Point".
+
+TEXT COMPONENT: Pos(L,C)=(13,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+ "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open literal.
+
+TEXT COMPONENT: Pos(L,C)=(14,6).
+
+-- Start of Text Scrap List --
+Text scrap[White]=" "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "3", Section name="Error Recovery Point".
+
+TEXT COMPONENT: Pos(L,C)=(15,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+5. Test the legal use of the "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open emphasise.
+
+TEXT COMPONENT: Pos(L,C)=(17,32).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="emphasis"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Close emphasise.
+
+TEXT COMPONENT: Pos(L,C)=(17,42).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]=" construct.<010>
+<010>
+6.Test "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open emphasise.
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4", Section name="Error Recovery Point".
+
+TEXT COMPONENT: Pos(L,C)=(20,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+7. Test the construct "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open emphasise.
+
+TEXT COMPONENT: Pos(L,C)=(22,25).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="across<010>
+ more than one line"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Close emphasise.
+
+TEXT COMPONENT: Pos(L,C)=(23,24).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]=".<010>
+<010>
+8. Now we test the construct with non-text following it.<010>
+ "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open emphasise.
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "5", Section name="Error Recovery Point".
+
+TEXT COMPONENT: Pos(L,C)=(27,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+ "
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Open emphasise.
+
+TEXT COMPONENT: Pos(L,C)=(28,6).
+
+-- Start of Text Scrap List --
+Text scrap[White]=" "
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| PR01: Test the inline typesetting features.
+ 2 2|
+ 3 3| 1. First we test the legal use of the @{literal@} construct.
+ 4 4|
+ 5 5| 2.Test @{@} (illegal).
+ Error|..........^Text expected after open literal token "@{".
+ |..........^Sorry, empty literal strings are not allowed.
+ |..........^Skipping after error to the next major construct...
+ 6 6| @A@<Error Recovery Point@>
+ |.^...skipped to here after the error.
+ 7 7|
+ 8 8| 3. Test the construct @{across
+ 9 9| more than one line@}.
+ 10 10|
+ 11 11| 4. Now we test the construct with non-text following it.
+ 12 12| @{@<sloth@>@}
+ Error|......^Text expected after open literal token "@{".
+ |......^Skipping after error to the next major construct...
+ 13 13| @A@<Error Recovery Point@>
+ |.^...skipped to here after the error.
+ 14 14| @{ @> @}
+ Error|...........^Expecting '@}'.
+ |...........^Skipping after error to the next major construct...
+ 15 15| @A@<Error Recovery Point@>
+ |.^...skipped to here after the error.
+ 16 16|
+ 17 17| 5. Test the legal use of the @/emphasis@/ construct.
+ 18 18|
+ 19 19| 6.Test @/@/ (illegal).
+ Error|..........^Text expected after open emphasise token "@/".
+ |..........^Sorry, empty emphasised strings are not allowed.
+ |..........^Skipping after error to the next major construct...
+ 20 20| @A@<Error Recovery Point@>
+ |.^...skipped to here after the error.
+ 21 21|
+ 22 22| 7. Test the construct @/across
+ 23 23| more than one line@/.
+ 24 24|
+ 25 25| 8. Now we test the construct with non-text following it.
+ 26 26| @/@<sloth@>@/
+ Error|......^Text expected after open emphasise token "@/".
+ |......^Skipping after error to the next major construct...
+ 27 27| @A@<Error Recovery Point@>
+ |.^...skipped to here after the error.
+ 28 28| @/ @< @/
+ Error|...........^Expecting '@/'.
+ |...........^Skipping after error to the next major construct...
+ 29 29|
+ 30 30|
+ 31 31|
+ | <End-Of-File>
+ |.^...skipped to here after the error.
+------------+-------------------------------------------------------------------
+
+There were 6 Errors.
diff --git a/web/funnelAC/results/pr02.lis b/web/funnelAC/results/pr02.lis
new file mode 100644
index 0000000000..5051dfb106
--- /dev/null
+++ b/web/funnelAC/results/pr02.lis
@@ -0,0 +1,249 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 30 32 3A 20 54 65 73 74 20 74 68 65 20 70 | PR02: Test the p |
+| 61 72 73 69 6E 67 20 6F 66 20 74 79 70 65 73 65 | arsing of typese |
+| 74 74 65 72 20 64 69 72 65 63 74 69 76 65 73 2E | tter directives. |
+| 0A 0A 31 2E 20 54 65 73 74 20 70 61 72 73 69 6E | ..1. Test parsin |
+| 67 20 6F 66 20 6E 65 77 20 70 61 67 65 20 64 69 | g of new page di |
+| 72 65 63 74 69 76 65 2E 0A 40 74 20 6E 65 77 5F | rective..@t new_ |
+| 70 61 67 65 0A 0A 32 2E 20 54 65 73 74 20 70 61 | page..2. Test pa |
+| 72 73 69 6E 67 20 6F 66 20 74 61 62 6C 65 20 6F | rsing of table o |
+| 66 20 63 6F 6E 74 65 6E 74 73 20 64 69 72 65 63 | f contents direc |
+| 74 69 76 65 2E 0A 40 74 20 74 61 62 6C 65 5F 6F | tive..@t table_o |
+| 66 5F 63 6F 6E 74 65 6E 74 73 0A 0A 33 2E 20 54 | f_contents..3. T |
+| 65 73 74 20 70 61 72 73 69 6E 67 20 6F 66 20 76 | est parsing of v |
+| 73 6B 69 70 20 64 69 72 65 63 74 69 76 65 2E 0A | skip directive.. |
+| 40 74 20 76 73 6B 69 70 20 33 32 20 6D 6D 0A 0A | @t vskip 32 mm.. |
+| 34 2E 20 54 65 73 74 20 70 61 72 73 69 6E 67 20 | 4. Test parsing |
+| 6F 66 20 74 69 74 6C 65 20 64 69 72 65 63 74 69 | of title directi |
+| 76 65 2E 0A 40 74 20 74 69 74 6C 65 20 74 69 74 | ve..@t title tit |
+| 6C 65 66 6F 6E 74 20 6C 65 66 74 20 22 53 6C 6F | lefont left "Slo |
+| 74 68 22 0A 0A | th".. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR02: Test the parsing of typesetter directives.<010>
+00002 00002| <010>
+00003 00003| 1. Test parsing of new page directive.<010>
+00004 00004| @t new_page<010>
+00005 00005| <010>
+00006 00006| 2. Test parsing of table of contents directive.<010>
+00007 00007| @t table_of_contents<010>
+00008 00008| <010>
+00009 00009| 3. Test parsing of vskip directive.<010>
+00010 00010| @t vskip 32 mm<010>
+00011 00011| <010>
+00012 00012| 4. Test parsing of title directive.<010>
+00013 00013| @t title titlefont left "Sloth"<010>
+00014 00014| <010>
+00015 00015| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 10 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR02: Test the parsing of typesetter directives.<010>
+<010>
+1. Test parsing of new page directive.<010>
+"
+0004[01]: @t.. Newpage.
+0005[01]: Text. Text scrap[Grey]="<010>
+2. Test parsing of table of contents directive.<010>
+"
+0007[01]: @t.. TOC.
+0008[01]: Text. Text scrap[Grey]="<010>
+3. Test parsing of vskip directive.<010>
+"
+0010[01]: @t.. Vertical skip. Vertical space skipped=32mm.
+0011[01]: Text. Text scrap[Grey]="<010>
+4. Test parsing of title directive.<010>
+"
+0013[01]: @t.. Title. Font=Title, Alignment=Left. Title text follows:
+Text scrap[Grey]="Sloth"
+0014[01]: Text. Text scrap[White]="<010>
+"
+0015[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#file"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#line"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#timestamp"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR02: Test the parsing of typesetter directives.<010>
+<010>
+1. Test parsing of new page directive.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: New page.
+
+TEXT COMPONENT: Pos(L,C)=(5,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+2. Test parsing of table of contents directive.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Table of contents.
+
+TEXT COMPONENT: Pos(L,C)=(8,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+3. Test parsing of vskip directive.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Vertical skip by 32 mm.
+
+TEXT COMPONENT: Pos(L,C)=(11,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+4. Test parsing of title directive.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT: Font=Title, Alignment=Left. Title text follows:
+Text scrap[Grey]="Sloth"
+
+TEXT COMPONENT: Pos(L,C)=(14,1).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+There was 1 Error.
diff --git a/web/funnelAC/results/pr03.lis b/web/funnelAC/results/pr03.lis
new file mode 100644
index 0000000000..76b9388f30
--- /dev/null
+++ b/web/funnelAC/results/pr03.lis
@@ -0,0 +1,557 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 30 33 3A 20 54 65 73 74 20 74 68 65 20 70 | PR03: Test the p |
+| 61 72 73 69 6E 67 20 61 6E 64 20 73 65 6D 61 6E | arsing and seman |
+| 74 69 63 73 20 6F 66 20 73 65 63 74 69 6F 6E 73 | tics of sections |
+| 2E 0A 0A 34 2E 20 54 65 73 74 20 66 69 72 73 74 | ...4. Test first |
+| 20 73 65 63 74 69 6F 6E 20 6F 66 20 64 6F 63 75 | section of docu |
+| 6D 65 6E 74 20 69 73 20 6E 6F 74 20 3C 73 70 65 | ment is not <spe |
+| 63 69 61 6C 3E 41 2E 0A 40 42 40 3C 54 68 69 73 | cial>A..@B@<This |
+| 20 73 65 63 74 69 6F 6E 20 69 73 20 6F 75 74 20 | section is out |
+| 6F 66 20 6F 72 64 65 72 20 28 61 6E 64 20 73 6F | of order (and so |
+| 20 69 73 20 74 68 69 73 20 74 65 73 74 21 29 40 | is this test!)@ |
+| 3E 0A 0A 31 2E 20 54 65 73 74 20 73 65 63 74 69 | >..1. Test secti |
+| 6F 6E 20 77 69 74 68 20 6E 6F 20 6E 61 6D 65 2E | on with no name. |
+| 0A 40 41 20 54 68 69 73 20 73 65 63 74 69 6F 6E | .@A This section |
+| 20 68 61 73 20 6E 6F 20 6E 61 6D 65 2E 0A 40 24 | has no name..@$ |
+| 40 3C 54 68 65 20 73 65 63 74 69 6F 6E 20 6E 61 | @<The section na |
+| 6D 65 20 69 6E 68 65 72 69 74 73 20 74 68 65 20 | me inherits the |
+| 6E 61 6D 65 20 6F 66 20 74 68 69 73 20 6D 61 63 | name of this mac |
+| 72 6F 40 3E 40 7B 57 61 6C 72 75 73 40 7D 0A 0A | ro@>@{Walrus@}.. |
+| 32 2E 20 54 65 73 74 20 73 65 63 74 69 6F 6E 20 | 2. Test section |
+| 77 69 74 68 20 61 20 6E 61 6D 65 0A 40 41 40 3C | with a name.@A@< |
+| 54 68 69 73 20 73 65 63 74 69 6F 6E 20 68 61 73 | This section has |
+| 20 6E 6F 20 6E 61 6D 65 2E 40 3E 0A 0A 33 2E 20 | no name.@>..3. |
+| 54 65 73 74 20 74 68 65 20 65 6E 74 69 72 65 20 | Test the entire |
+| 68 69 65 72 61 72 63 68 79 2E 0A 40 41 40 3C 4F | hierarchy..@A@<O |
+| 6E 65 40 3E 0A 40 42 40 3C 54 77 6F 40 3E 0A 40 | ne@>.@B@<Two@>.@ |
+| 43 40 3C 54 68 72 65 65 40 3E 0A 40 44 40 3C 46 | C@<Three@>.@D@<F |
+| 6F 75 72 40 3E 0A 40 45 40 3C 46 69 76 65 40 3E | our@>.@E@<Five@> |
+| 0A 0A 35 2E 20 54 65 73 74 20 64 65 74 65 63 74 | ..5. Test detect |
+| 69 6F 6E 20 6F 66 20 64 69 73 63 6F 6E 74 69 6E | ion of discontin |
+| 75 69 74 79 20 69 6E 20 6C 65 76 65 6C 73 2E 0A | uity in levels.. |
+| 40 41 40 3C 4F 6E 65 40 3E 0A 40 43 40 3C 54 68 | @A@<One@>.@C@<Th |
+| 72 65 65 40 3E 0A 40 45 40 3C 46 69 76 65 40 3E | ree@>.@E@<Five@> |
+| 0A 0A 40 41 40 3C 4F 6E 65 40 3E 0A 40 42 40 3C | ..@A@<One@>.@B@< |
+| 54 68 72 65 65 40 3E 0A 40 44 40 3C 46 69 76 65 | Three@>.@D@<Five |
+| 40 3E 0A | @>. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR03: Test the parsing and semantics of sections.<010>
+00002 00002| <010>
+00003 00003| 4. Test first section of document is not <special>A.<010>
+00004 00004| @B@<This section is out of order (and so is this test!)@><010>
+00005 00005| <010>
+00006 00006| 1. Test section with no name.<010>
+00007 00007| @A This section has no name.<010>
+00008 00008| @$@<The section name inherits the name of this macro@>@{Walrus@}<010>
+00009 00009| <010>
+00010 00010| 2. Test section with a name<010>
+00011 00011| @A@<This section has no name.@><010>
+00012 00012| <010>
+00013 00013| 3. Test the entire hierarchy.<010>
+00014 00014| @A@<One@><010>
+00015 00015| @B@<Two@><010>
+00016 00016| @C@<Three@><010>
+00017 00017| @D@<Four@><010>
+00018 00018| @E@<Five@><010>
+00019 00019| <010>
+00020 00020| 5. Test detection of discontinuity in levels.<010>
+00021 00021| @A@<One@><010>
+00022 00022| @C@<Three@><010>
+00023 00023| @E@<Five@><010>
+00024 00024| <010>
+00025 00025| @A@<One@><010>
+00026 00026| @B@<Three@><010>
+00027 00027| @D@<Five@><010>
+00028 00028| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 77 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR03: Test the parsing and semantics of sections.<010>
+<010>
+4. Test first section of document is not <special>A.<010>
+"
+0004[01]: @B New section (Level 2).
+0004[03]: @< Open name.
+0004[05]: Text. Text scrap[Grey]="This section is out of order (and so is this test!)"
+0004[56]: @> Close name.
+0004[58]: Text. Text scrap[Grey]="<010>
+<010>
+1. Test section with no name.<010>
+"
+0007[01]: @A New section (Level 1).
+0007[03]: Text. Text scrap[Grey]=" This section has no name.<010>
+"
+0008[01]: @$ Macro defn.
+0008[03]: @< Open name.
+0008[05]: Text. Text scrap[Grey]="The section name inherits the name of this macro"
+0008[53]: @> Close name.
+0008[55]: @{ Open defn.
+0008[57]: Text. Text scrap[Grey]="Walrus"
+0008[63]: @} Close defn.
+0008[65]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test section with a name<010>
+"
+0011[01]: @A New section (Level 1).
+0011[03]: @< Open name.
+0011[05]: Text. Text scrap[Grey]="This section has no name."
+0011[30]: @> Close name.
+0011[32]: Text. Text scrap[Grey]="<010>
+<010>
+3. Test the entire hierarchy.<010>
+"
+0014[01]: @A New section (Level 1).
+0014[03]: @< Open name.
+0014[05]: Text. Text scrap[Grey]="One"
+0014[08]: @> Close name.
+0014[10]: Text. Text scrap[White]="<010>
+"
+0015[01]: @B New section (Level 2).
+0015[03]: @< Open name.
+0015[05]: Text. Text scrap[Grey]="Two"
+0015[08]: @> Close name.
+0015[10]: Text. Text scrap[White]="<010>
+"
+0016[01]: @C New section (Level 3).
+0016[03]: @< Open name.
+0016[05]: Text. Text scrap[Grey]="Three"
+0016[10]: @> Close name.
+0016[12]: Text. Text scrap[White]="<010>
+"
+0017[01]: @D New section (Level 4).
+0017[03]: @< Open name.
+0017[05]: Text. Text scrap[Grey]="Four"
+0017[09]: @> Close name.
+0017[11]: Text. Text scrap[White]="<010>
+"
+0018[01]: @E New section (Level 5).
+0018[03]: @< Open name.
+0018[05]: Text. Text scrap[Grey]="Five"
+0018[09]: @> Close name.
+0018[11]: Text. Text scrap[Grey]="<010>
+<010>
+5. Test detection of discontinuity in levels.<010>
+"
+0021[01]: @A New section (Level 1).
+0021[03]: @< Open name.
+0021[05]: Text. Text scrap[Grey]="One"
+0021[08]: @> Close name.
+0021[10]: Text. Text scrap[White]="<010>
+"
+0022[01]: @C New section (Level 3).
+0022[03]: @< Open name.
+0022[05]: Text. Text scrap[Grey]="Three"
+0022[10]: @> Close name.
+0022[12]: Text. Text scrap[White]="<010>
+"
+0023[01]: @E New section (Level 5).
+0023[03]: @< Open name.
+0023[05]: Text. Text scrap[Grey]="Five"
+0023[09]: @> Close name.
+0023[11]: Text. Text scrap[White]="<010>
+<010>
+"
+0025[01]: @A New section (Level 1).
+0025[03]: @< Open name.
+0025[05]: Text. Text scrap[Grey]="One"
+0025[08]: @> Close name.
+0025[10]: Text. Text scrap[White]="<010>
+"
+0026[01]: @B New section (Level 2).
+0026[03]: @< Open name.
+0026[05]: Text. Text scrap[Grey]="Three"
+0026[10]: @> Close name.
+0026[12]: Text. Text scrap[White]="<010>
+"
+0027[01]: @D New section (Level 4).
+0027[03]: @< Open name.
+0027[05]: Text. Text scrap[Grey]="Five"
+0027[09]: @> Close name.
+0027[11]: Text. Text scrap[White]="<010>
+"
+0028[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#file"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#line"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#timestamp"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "The section name inherits the name of this macro"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=1, Pos(L,C)=(8,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR03: Test the parsing and semantics of sections.<010>
+<010>
+4. Test first section of document is not <special>A.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1.2", Section name="This section is out of order (and so is this test!)".
+
+TEXT COMPONENT: Pos(L,C)=(4,58).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+1. Test section with no name.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="The section name inherits the name of this macro".
+
+TEXT COMPONENT: Pos(L,C)=(7,3).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]=" This section has no name.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(8,1).
+Part 1 of macro @<The section name inherits the name of this macro@>.
+
+TEXT COMPONENT: Pos(L,C)=(8,65).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+2. Test section with a name<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "3", Section name="This section has no name.".
+
+TEXT COMPONENT: Pos(L,C)=(11,32).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+3. Test the entire hierarchy.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4", Section name="One".
+
+TEXT COMPONENT: Pos(L,C)=(14,10).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4.1", Section name="Two".
+
+TEXT COMPONENT: Pos(L,C)=(15,10).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4.1.1", Section name="Three".
+
+TEXT COMPONENT: Pos(L,C)=(16,12).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4.1.1.1", Section name="Four".
+
+TEXT COMPONENT: Pos(L,C)=(17,11).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4.1.1.1.1", Section name="Five".
+
+TEXT COMPONENT: Pos(L,C)=(18,11).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+5. Test detection of discontinuity in levels.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "5", Section name="One".
+
+TEXT COMPONENT: Pos(L,C)=(21,10).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1.1.2", Section name="Three".
+
+TEXT COMPONENT: Pos(L,C)=(22,12).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1.1.1.1.2", Section name="Five".
+
+TEXT COMPONENT: Pos(L,C)=(23,11).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="One".
+
+TEXT COMPONENT: Pos(L,C)=(25,10).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2.1", Section name="Three".
+
+TEXT COMPONENT: Pos(L,C)=(26,12).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1.1.1.2", Section name="Five".
+
+TEXT COMPONENT: Pos(L,C)=(27,11).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| PR03: Test the parsing and semantics of sections.
+ 2 2|
+ 3 3| 4. Test first section of document is not <special>A.
+ 4 4| @B@<This section is out of order (and so is this test!)@>
+ Error|.^The first section in a document must be an @A section.
+ 5 5|
+ 6 6| 1. Test section with no name.
+ 7 7| @A This section has no name.
+ 8 8| @$@<The section name inherits the name of this macro@>@{Walrus@}
+ 9 9|
+ 10 10| 2. Test section with a name
+ 11 11| @A@<This section has no name.@>
+ 12 12|
+ 13 13| 3. Test the entire hierarchy.
+ 14 14| @A@<One@>
+ 15 15| @B@<Two@>
+ 16 16| @C@<Three@>
+ 17 17| @D@<Four@>
+ 18 18| @E@<Five@>
+ 19 19|
+ 20 20| 5. Test detection of discontinuity in levels.
+ 21 21| @A@<One@>
+ |.^The next section (at line 22) is too deep.
+ 22 22| @C@<Three@>
+ Error|.^This section is more than one level deeper than the last
+ |.^section (at line 21). Example: @B followed by @D is not allowed.
+ |.^The next section (at line 23) is too deep.
+ 23 23| @E@<Five@>
+ Error|.^This section is more than one level deeper than the last
+ |.^section (at line 22). Example: @B followed by @D is not allowed.
+ 24 24|
+ 25 25| @A@<One@>
+ 26 26| @B@<Three@>
+ |.^The next section (at line 27) is too deep.
+ 27 27| @D@<Five@>
+ Error|.^This section is more than one level deeper than the last
+ |.^section (at line 26). Example: @B followed by @D is not allowed.
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 4 Errors.
diff --git a/web/funnelAC/results/pr04.lis b/web/funnelAC/results/pr04.lis
new file mode 100644
index 0000000000..38d0680caf
--- /dev/null
+++ b/web/funnelAC/results/pr04.lis
@@ -0,0 +1,751 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 30 34 3A 20 54 65 73 74 20 74 68 65 20 64 | PR04: Test the d |
+| 65 66 69 6E 69 74 69 6F 6E 20 6F 66 20 6F 72 64 | efinition of ord |
+| 69 6E 61 72 79 20 6D 61 63 72 6F 73 2E 0A 0A 31 | inary macros...1 |
+| 2E 20 54 65 73 74 20 61 6E 20 6F 72 64 69 6E 61 | . Test an ordina |
+| 72 79 20 6D 61 63 72 6F 20 64 65 66 69 6E 69 74 | ry macro definit |
+| 69 6F 6E 2E 0A 40 24 40 3C 4F 72 64 69 6E 61 72 | ion..@$@<Ordinar |
+| 79 40 3E 40 7B 54 68 65 20 74 65 78 74 20 6F 66 | y@>@{The text of |
+| 20 6F 72 64 69 6E 61 72 79 40 7D 0A 0A 32 2E 20 | ordinary@}..2. |
+| 54 65 73 74 20 61 6E 20 6F 72 64 69 6E 61 72 79 | Test an ordinary |
+| 20 64 65 66 69 6E 69 74 69 6F 6E 20 75 73 69 6E | definition usin |
+| 67 20 61 20 71 75 69 63 6B 6E 61 6D 65 2E 0A 40 | g a quickname..@ |
+| 24 40 23 7C 40 7B 54 68 65 20 74 65 78 74 20 6F | $@#|@{The text o |
+| 66 20 6F 72 64 69 6E 61 72 79 40 7D 0A 0A 33 2E | f ordinary@}..3. |
+| 20 54 65 73 74 20 61 20 6E 61 6D 65 20 74 68 61 | Test a name tha |
+| 74 20 69 6E 63 6C 75 64 65 73 20 45 4F 4C 2E 0A | t includes EOL.. |
+| 40 24 40 3C 54 68 69 73 20 6E 61 6D 65 20 69 73 | @$@<This name is |
+| 20 69 6C 6C 65 67 61 6C 20 62 65 63 61 75 73 65 | illegal because |
+| 0A 69 74 20 63 72 6F 73 73 65 73 20 61 20 6C 69 | .it crosses a li |
+| 6F 6E 40 3E 40 7B 41 6E 64 20 70 65 6F 70 6C 65 | on@>@{And people |
+| 20 77 68 6F 20 63 72 6F 73 73 20 6C 69 6F 6E 73 | who cross lions |
+| 20 74 65 6E 64 20 74 6F 20 67 65 74 20 65 61 74 | tend to get eat |
+| 65 6E 2E 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 | en.@}.@A@<Error |
+| 52 65 63 6F 76 65 72 79 20 50 6F 69 6E 74 40 3E | Recovery Point@> |
+| 0A 0A 34 2E 20 54 65 73 74 20 74 68 65 20 6D 69 | ..4. Test the mi |
+| 6E 69 6D 75 6D 20 6C 65 6E 67 74 68 20 6E 61 6D | nimum length nam |
+| 65 20 28 74 68 65 20 65 6D 70 74 79 20 6E 61 6D | e (the empty nam |
+| 65 29 2E 0A 40 24 40 3C 40 3E 40 7B 54 68 65 20 | e)..@$@<@>@{The |
+| 65 6D 70 74 79 20 6D 61 63 72 6F 20 6E 61 6D 65 | empty macro name |
+| 20 69 73 20 71 75 69 74 65 20 6C 65 67 61 6C 20 | is quite legal |
+| 69 6E 20 46 75 6E 6E 65 6C 57 65 62 2E 40 7D 0A | in FunnelWeb.@}. |
+| 0A 35 2E 20 54 65 73 74 20 61 20 6E 61 6D 65 20 | .5. Test a name |
+| 61 74 20 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E | at the maximum n |
+| 61 6D 65 20 6C 65 6E 67 74 68 20 6C 69 6D 69 74 | ame length limit |
+| 20 28 38 30 29 2E 0A 4F 4E 6C 79 20 74 68 65 20 | (80)..ONly the |
+| 73 65 63 6F 6E 64 20 6F 66 20 74 68 65 20 74 77 | second of the tw |
+| 6F 20 6D 61 63 72 6F 73 20 73 68 6F 75 6C 64 20 | o macros should |
+| 67 65 6E 65 72 61 74 65 20 61 6E 20 65 72 72 6F | generate an erro |
+| 72 2E 0A 40 70 20 6D 61 78 69 6D 75 6D 5F 69 6E | r..@p maximum_in |
+| 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 74 68 20 | put_line_length |
+| 3D 20 31 30 30 0A 40 24 40 3C 31 32 33 34 35 36 | = 100.@$@<123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 40 3E 40 7B 40 7D | 1234567890@>@{@} |
+| 0A 40 24 40 3C 31 32 33 34 35 36 37 38 39 30 31 | .@$@<12345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 40 3E 40 7B 40 7D 0A 40 41 40 | 678901@>@{@}.@A@ |
+| 3C 45 72 72 6F 72 20 52 65 63 6F 76 65 72 79 20 | <Error Recovery |
+| 50 6F 69 6E 74 40 3E 0A 0A 36 2E 20 54 65 73 74 | Point@>..6. Test |
+| 20 6E 61 6D 65 73 20 77 69 74 68 20 61 6C 6C 20 | names with all |
+| 6C 65 67 61 6C 20 63 68 61 72 61 63 74 65 72 73 | legal characters |
+| 2E 20 54 68 65 72 65 20 73 68 6F 75 6C 64 20 62 | . There should b |
+| 65 20 6E 6F 20 65 72 72 6F 72 73 2E 0A 40 24 40 | e no errors..@$@ |
+| 3C 20 21 22 23 24 25 27 28 29 2A 2B 2C 2D 2E 2F | < !"#$%'()*+,-./ |
+| 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F | 0123456789:;<=>? |
+| 40 3E 40 7B 40 7D 0A 40 24 40 3C 41 42 43 44 45 | @>@{@}.@$@<ABCDE |
+| 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 | FGHIJKLMNOPQRSTU |
+| 56 57 58 59 5A 5B 5C 5D 5E 5F 60 40 3E 40 7B 40 | VWXYZ[\]^_`@>@{@ |
+| 7D 0A 40 24 40 3C 61 62 63 64 65 66 67 68 69 6A | }.@$@<abcdefghij |
+| 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A | klmnopqrstuvwxyz |
+| 7B 7C 7D 7E 40 3E 40 7B 40 7D 0A 0A 37 2E 20 54 | {|}~@>@{@}..7. T |
+| 65 73 74 20 61 20 6E 61 6D 65 20 74 68 61 74 20 | est a name that |
+| 68 61 73 20 69 6E 73 65 72 74 65 64 20 74 65 78 | has inserted tex |
+| 74 20 73 65 71 75 65 6E 63 65 73 2E 0A 0A 40 24 | t sequences...@$ |
+| 40 3C 40 5E 44 28 30 36 35 29 40 40 40 3E 3D 3D | @<@^D(065)@@@>== |
+| 40 7B 40 7D 0A 0A 0A | @{@}... |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR04: Test the definition of ordinary macros.<010>
+00002 00002| <010>
+00003 00003| 1. Test an ordinary macro definition.<010>
+00004 00004| @$@<Ordinary@>@{The text of ordinary@}<010>
+00005 00005| <010>
+00006 00006| 2. Test an ordinary definition using a quickname.<010>
+00007 00007| @$@#|@{The text of ordinary@}<010>
+00008 00008| <010>
+00009 00009| 3. Test a name that includes EOL.<010>
+00010 00010| @$@<This name is illegal because<010>
+00011 00011| it crosses a lion@>@{And people who cross lions tend to get eaten.@}<010>
+00012 00012| @A@<Error Recovery Point@><010>
+00013 00013| <010>
+00014 00014| 4. Test the minimum length name (the empty name).<010>
+00015 00015| @$@<@>@{The empty macro name is quite legal in FunnelWeb.@}<010>
+00016 00016| <010>
+00017 00017| 5. Test a name at the maximum name length limit (80).<010>
+00018 00018| ONly the second of the two macros should generate an error.<010>
+00019 00019| @p maximum_input_line_length = 100<010>
+00020 00020| @$@<12345678901234567890123456789012345678901234567890123456789012345678901234567890@>@{@}<010>
+00021 00021| @$@<123456789012345678901234567890123456789012345678901234567890123456789012345678901@>@{@}<010>
+00022 00022| @A@<Error Recovery Point@><010>
+00023 00023| <010>
+00024 00024| 6. Test names with all legal characters. There should be no errors.<010>
+00025 00025| @$@< !"#$%'()*+,-./0123456789:;<=>?@>@{@}<010>
+00026 00026| @$@<ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`@>@{@}<010>
+00027 00027| @$@<abcdefghijklmnopqrstuvwxyz{|}~@>@{@}<010>
+00028 00028| <010>
+00029 00029| 7. Test a name that has inserted text sequences.<010>
+00030 00030| <010>
+00031 00031| @$@<@^D(065)@@@>==@{@}<010>
+00032 00032| <010>
+00033 00033| <010>
+00034 00034| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 85 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR04: Test the definition of ordinary macros.<010>
+<010>
+1. Test an ordinary macro definition.<010>
+"
+0004[01]: @$ Macro defn.
+0004[03]: @< Open name.
+0004[05]: Text. Text scrap[Grey]="Ordinary"
+0004[13]: @> Close name.
+0004[15]: @{ Open defn.
+0004[17]: Text. Text scrap[Grey]="The text of ordinary"
+0004[37]: @} Close defn.
+0004[39]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test an ordinary definition using a quickname.<010>
+"
+0007[01]: @$ Macro defn.
+0007[03]: @# Name. Character='|'.
+0007[06]: @{ Open defn.
+0007[08]: Text. Text scrap[Grey]="The text of ordinary"
+0007[28]: @} Close defn.
+0007[30]: Text. Text scrap[Grey]="<010>
+<010>
+3. Test a name that includes EOL.<010>
+"
+0010[01]: @$ Macro defn.
+0010[03]: @< Open name.
+0010[05]: Text. Text scrap[Grey]="This name is illegal because<010>
+it crosses a lion"
+0011[18]: @> Close name.
+0011[20]: @{ Open defn.
+0011[22]: Text. Text scrap[Grey]="And people who cross lions tend to get eaten."
+0011[67]: @} Close defn.
+0011[69]: Text. Text scrap[White]="<010>
+"
+0012[01]: @A New section (Level 1).
+0012[03]: @< Open name.
+0012[05]: Text. Text scrap[Grey]="Error Recovery Point"
+0012[25]: @> Close name.
+0012[27]: Text. Text scrap[Grey]="<010>
+<010>
+4. Test the minimum length name (the empty name).<010>
+"
+0015[01]: @$ Macro defn.
+0015[03]: @< Open name.
+0015[05]: @> Close name.
+0015[07]: @{ Open defn.
+0015[09]: Text. Text scrap[Grey]="The empty macro name is quite legal in FunnelWeb."
+0015[58]: @} Close defn.
+0015[60]: Text. Text scrap[Grey]="<010>
+<010>
+5. Test a name at the maximum name length limit (80).<010>
+ONly the second of the two macros should generate an error.<010>
+"
+0020[01]: @$ Macro defn.
+0020[03]: @< Open name.
+0020[05]: Text. Text scrap[Grey]="12345678901234567890123456789012345678901234567890123456789012345678901234567890"
+0020[85]: @> Close name.
+0020[87]: @{ Open defn.
+0020[89]: @} Close defn.
+0020[91]: Text. Text scrap[White]="<010>
+"
+0021[01]: @$ Macro defn.
+0021[03]: @< Open name.
+0021[05]: Text. Text scrap[Grey]="123456789012345678901234567890123456789012345678901234567890123456789012345678901"
+0021[86]: @> Close name.
+0021[88]: @{ Open defn.
+0021[90]: @} Close defn.
+0021[92]: Text. Text scrap[White]="<010>
+"
+0022[01]: @A New section (Level 1).
+0022[03]: @< Open name.
+0022[05]: Text. Text scrap[Grey]="Error Recovery Point"
+0022[25]: @> Close name.
+0022[27]: Text. Text scrap[Grey]="<010>
+<010>
+6. Test names with all legal characters. There should be no errors.<010>
+"
+0025[01]: @$ Macro defn.
+0025[03]: @< Open name.
+0025[05]: Text. Text scrap[Grey]=" !"#$%'()*+,-./0123456789:;<=>?"
+0025[36]: @> Close name.
+0025[38]: @{ Open defn.
+0025[40]: @} Close defn.
+0025[42]: Text. Text scrap[White]="<010>
+"
+0026[01]: @$ Macro defn.
+0026[03]: @< Open name.
+0026[05]: Text. Text scrap[Grey]="ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`"
+0026[37]: @> Close name.
+0026[39]: @{ Open defn.
+0026[41]: @} Close defn.
+0026[43]: Text. Text scrap[White]="<010>
+"
+0027[01]: @$ Macro defn.
+0027[03]: @< Open name.
+0027[05]: Text. Text scrap[Grey]="abcdefghijklmnopqrstuvwxyz{|}~"
+0027[35]: @> Close name.
+0027[37]: @{ Open defn.
+0027[39]: @} Close defn.
+0027[41]: Text. Text scrap[Grey]="<010>
+<010>
+7. Test a name that has inserted text sequences.<010>
+<010>
+"
+0031[01]: @$ Macro defn.
+0031[03]: @< Open name.
+0031[05]: Text. Text scrap[Grey]="A"
+0031[13]: Text. Text scrap[Grey]="@"
+0031[15]: @> Close name.
+0031[17]: Text. Text scrap[Grey]="=="
+0031[19]: @{ Open defn.
+0031[21]: @} Close defn.
+0031[23]: Text. Text scrap[White]="<010>
+<010>
+<010>
+"
+0034[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : ""
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=3, Pos(L,C)=(15,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="The empty macro name is quite legal in FunnelWeb."
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : " !"#$%'()*+,-./0123456789:;<=>?"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=5, Pos(L,C)=(25,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#file"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#line"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#timestamp"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=4, Pos(L,C)=(20,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "A@"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=8, Pos(L,C)=(31,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=6, Pos(L,C)=(26,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Ordinary"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=1, Pos(L,C)=(4,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="The text of ordinary"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "abcdefghijklmnopqrstuvwxyz{|}~"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=7, Pos(L,C)=(27,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "|"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=2, Pos(L,C)=(7,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="The text of ordinary"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR04: Test the definition of ordinary macros.<010>
+<010>
+1. Test an ordinary macro definition.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(4,1).
+Part 1 of macro @<Ordinary@>.
+
+TEXT COMPONENT: Pos(L,C)=(4,39).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+2. Test an ordinary definition using a quickname.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(7,1).
+Part 1 of macro @<|@>.
+
+TEXT COMPONENT: Pos(L,C)=(7,30).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+3. Test a name that includes EOL.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1", Section name="Error Recovery Point".
+
+TEXT COMPONENT: Pos(L,C)=(12,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+4. Test the minimum length name (the empty name).<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(15,1).
+Part 1 of macro @<@>.
+
+TEXT COMPONENT: Pos(L,C)=(15,60).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+5. Test a name at the maximum name length limit (80).<010>
+ONly the second of the two macros should generate an error.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(20,1).
+Part 1 of macro @<12345678901234567890123456789012345678901234567890123456789012345678901234567890@>.
+
+TEXT COMPONENT: Pos(L,C)=(20,91).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="Error Recovery Point".
+
+TEXT COMPONENT: Pos(L,C)=(22,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+6. Test names with all legal characters. There should be no errors.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(25,1).
+Part 1 of macro @< !"#$%'()*+,-./0123456789:;<=>?@>.
+
+TEXT COMPONENT: Pos(L,C)=(25,42).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(26,1).
+Part 1 of macro @<ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`@>.
+
+TEXT COMPONENT: Pos(L,C)=(26,43).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(27,1).
+Part 1 of macro @<abcdefghijklmnopqrstuvwxyz{|}~@>.
+
+TEXT COMPONENT: Pos(L,C)=(27,41).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+7. Test a name that has inserted text sequences.<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(31,1).
+Part 1 of macro @<A@@>.
+
+TEXT COMPONENT: Pos(L,C)=(31,23).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| PR04: Test the definition of ordinary macros.
+ 2 2|
+ 3 3| 1. Test an ordinary macro definition.
+ 4 4| @$@<Ordinary@>@{The text of ordinary@}
+ 5 5|
+ 6 6| 2. Test an ordinary definition using a quickname.
+ 7 7| @$@#|@{The text of ordinary@}
+ 8 8|
+ 9 9| 3. Test a name that includes EOL.
+ 10 10| @$@<This name is illegal because
+ Error|.....^Names cannot cross lines.
+ |.....^Skipping after error to the next major construct...
+ 11 11| it crosses a lion@>@{And people who cross lions tend to get eaten.@}
+ 12 12| @A@<Error Recovery Point@>
+ |.^...skipped to here after the error.
+ 13 13|
+ 14 14| 4. Test the minimum length name (the empty name).
+ 15 15| @$@<@>@{The empty macro name is quite legal in FunnelWeb.@}
+ 16 16|
+ 17 17| 5. Test a name at the maximum name length limit (80).
+ 18 18| ONly the second of the two macros should generate an error.
+ 19 19| @p maximum_input_line_length = 100
+ 20 20| @$@<12345678901234567890123456789012345678901234567890123456789012345678901234567890@>@{@}
+ 21 21| @$@<123456789012345678901234567890123456789012345678901234567890123456789012345678901@>@{@}
+ Error|.....^Name is too long.
+ |.....^The maximum length of a legal name is 80 characters.
+ |.....^Skipping after error to the next major construct...
+ 22 22| @A@<Error Recovery Point@>
+ |.^...skipped to here after the error.
+ 23 23|
+ 24 24| 6. Test names with all legal characters. There should be no errors.
+ 25 25| @$@< !"#$%'()*+,-./0123456789:;<=>?@>@{@}
+ 26 26| @$@<ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`@>@{@}
+ 27 27| @$@<abcdefghijklmnopqrstuvwxyz{|}~@>@{@}
+ 28 28|
+ 29 29| 7. Test a name that has inserted text sequences.
+ 30 30|
+ 31 31| @$@<@^D(065)@@@>==@{@}
+ 32 32|
+ 33 33|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 2 Errors.
diff --git a/web/funnelAC/results/pr05.lis b/web/funnelAC/results/pr05.lis
new file mode 100644
index 0000000000..8253f2091c
--- /dev/null
+++ b/web/funnelAC/results/pr05.lis
@@ -0,0 +1,1105 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 30 35 3A 20 54 65 73 74 20 74 68 65 20 70 | PR05: Test the p |
+| 61 72 73 69 6E 67 20 6F 66 20 66 6F 72 6D 61 6C | arsing of formal |
+| 20 70 61 72 61 6D 65 74 65 72 20 6C 69 73 74 73 | parameter lists |
+| 2E 0A 0A 46 69 72 73 74 20 74 72 69 70 20 74 68 | ...First trip th |
+| 65 20 70 61 72 73 65 72 20 73 6F 20 77 65 20 64 | e parser so we d |
+| 6F 6E 27 74 20 67 65 74 20 70 61 73 74 20 74 68 | on't get past th |
+| 65 20 70 61 72 73 65 72 2E 0A 40 3E 0A 0A 31 2E | e parser..@>..1. |
+| 20 54 65 73 74 20 6D 61 63 72 6F 20 64 65 66 69 | Test macro defi |
+| 6E 69 74 69 6F 6E 20 77 69 74 68 20 6E 6F 20 66 | nition with no f |
+| 6F 72 6D 61 6C 20 70 61 72 61 6D 65 74 65 72 73 | ormal parameters |
+| 2E 0A 40 24 40 3C 53 6C 6F 74 68 40 3E 40 7B 53 | ..@$@<Sloth@>@{S |
+| 6C 6F 74 68 74 65 78 74 40 7D 0A 0A 32 2E 20 54 | lothtext@}..2. T |
+| 65 73 74 20 6D 61 63 72 6F 20 64 65 66 69 6E 69 | est macro defini |
+| 74 69 6F 6E 20 77 69 74 68 20 6F 6E 65 20 66 6F | tion with one fo |
+| 72 6D 61 6C 20 70 61 72 61 6D 65 74 65 72 2E 0A | rmal parameter.. |
+| 40 24 40 3C 53 6C 6F 74 68 20 77 69 74 68 20 6F | @$@<Sloth with o |
+| 6E 65 40 3E 40 28 40 31 40 29 40 7B 53 6C 6F 74 | ne@>@(@1@)@{Slot |
+| 68 74 65 78 74 40 7D 0A 0A 33 2E 20 54 65 73 74 | htext@}..3. Test |
+| 20 6D 61 63 72 6F 20 64 65 66 69 6E 69 74 69 6F | macro definitio |
+| 6E 20 77 69 74 68 20 6D 61 6E 79 20 66 6F 72 6D | n with many form |
+| 61 6C 20 70 61 72 61 6D 65 74 65 72 73 2E 0A 40 | al parameters..@ |
+| 24 40 3C 53 6C 6F 74 68 20 77 69 74 68 20 32 40 | $@<Sloth with 2@ |
+| 3E 40 28 40 32 40 29 40 7B 53 6C 6F 74 68 74 65 | >@(@2@)@{Slothte |
+| 78 74 40 7D 0A 40 24 40 3C 53 6C 6F 74 68 20 77 | xt@}.@$@<Sloth w |
+| 69 74 68 20 33 40 3E 40 28 40 33 40 29 40 7B 53 | ith 3@>@(@3@)@{S |
+| 6C 6F 74 68 74 65 78 74 40 7D 0A 40 24 40 3C 53 | lothtext@}.@$@<S |
+| 6C 6F 74 68 20 77 69 74 68 20 34 40 3E 40 28 40 | loth with 4@>@(@ |
+| 34 40 29 40 7B 53 6C 6F 74 68 74 65 78 74 40 7D | 4@)@{Slothtext@} |
+| 0A 40 24 40 3C 53 6C 6F 74 68 20 77 69 74 68 20 | .@$@<Sloth with |
+| 35 40 3E 40 28 40 35 40 29 40 7B 53 6C 6F 74 68 | 5@>@(@5@)@{Sloth |
+| 74 65 78 74 40 7D 0A 40 24 40 3C 53 6C 6F 74 68 | text@}.@$@<Sloth |
+| 20 77 69 74 68 20 36 40 3E 40 28 40 36 40 29 40 | with 6@>@(@6@)@ |
+| 7B 53 6C 6F 74 68 74 65 78 74 40 7D 0A 40 24 40 | {Slothtext@}.@$@ |
+| 3C 53 6C 6F 74 68 20 77 69 74 68 20 37 40 3E 40 | <Sloth with 7@>@ |
+| 28 40 37 40 29 40 7B 53 6C 6F 74 68 74 65 78 74 | (@7@)@{Slothtext |
+| 40 7D 0A 40 24 40 3C 53 6C 6F 74 68 20 77 69 74 | @}.@$@<Sloth wit |
+| 68 20 38 40 3E 40 28 40 38 40 29 40 7B 53 6C 6F | h 8@>@(@8@)@{Slo |
+| 74 68 74 65 78 74 40 7D 0A 40 24 40 3C 53 6C 6F | thtext@}.@$@<Slo |
+| 74 68 20 77 69 74 68 20 39 40 3E 40 28 40 39 40 | th with 9@>@(@9@ |
+| 29 40 7B 53 6C 6F 74 68 74 65 78 74 40 7D 0A 0A | )@{Slothtext@}.. |
+| 34 2E 20 54 65 73 74 20 77 69 74 68 20 73 79 6E | 4. Test with syn |
+| 74 61 78 20 65 72 72 6F 72 73 20 69 6E 20 74 68 | tax errors in th |
+| 65 20 70 61 72 61 6D 65 74 65 72 20 6C 69 73 74 | e parameter list |
+| 2E 0A 0A 40 24 40 3C 53 6C 6F 74 68 20 61 40 3E | ...@$@<Sloth a@> |
+| 40 28 40 2B 40 39 40 29 40 7B 53 6C 6F 74 68 74 | @(@+@9@)@{Slotht |
+| 65 78 74 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 | ext@}.@A@<Error |
+| 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 40 3E | recovery point@> |
+| 0A 0A 40 24 40 3C 53 6C 6F 74 68 20 62 40 3E 40 | ..@$@<Sloth b@>@ |
+| 39 40 29 40 7B 53 6C 6F 74 68 74 65 78 74 40 7D | 9@)@{Slothtext@} |
+| 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 | .@A@<Error recov |
+| 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 40 24 40 | ery point@>..@$@ |
+| 3C 53 6C 6F 74 68 20 63 40 3E 40 28 39 40 29 40 | <Sloth c@>@(9@)@ |
+| 7B 53 6C 6F 74 68 74 65 78 74 40 7D 0A 40 41 40 | {Slothtext@}.@A@ |
+| 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 | <Error recovery |
+| 70 6F 69 6E 74 40 3E 0A 0A 40 24 40 3C 53 6C 6F | point@>..@$@<Slo |
+| 74 68 20 64 40 3E 40 39 40 29 40 7B 53 6C 6F 74 | th d@>@9@)@{Slot |
+| 68 74 65 78 74 40 7D 0A 40 41 40 3C 45 72 72 6F | htext@}.@A@<Erro |
+| 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 | r recovery point |
+| 40 3E 0A 0A 40 24 40 3C 53 6C 6F 74 68 20 65 40 | @>..@$@<Sloth e@ |
+| 3E 40 28 40 39 40 29 40 29 40 7B 53 6C 6F 74 68 | >@(@9@)@)@{Sloth |
+| 74 65 78 74 40 7D 0A 40 41 40 3C 45 72 72 6F 72 | text@}.@A@<Error |
+| 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 40 | recovery point@ |
+| 3E 0A 0A 0A 0A | >.... |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR05: Test the parsing of formal parameter lists.<010>
+00002 00002| <010>
+00003 00003| First trip the parser so we don't get past the parser.<010>
+00004 00004| @><010>
+00005 00005| <010>
+00006 00006| 1. Test macro definition with no formal parameters.<010>
+00007 00007| @$@<Sloth@>@{Slothtext@}<010>
+00008 00008| <010>
+00009 00009| 2. Test macro definition with one formal parameter.<010>
+00010 00010| @$@<Sloth with one@>@(@1@)@{Slothtext@}<010>
+00011 00011| <010>
+00012 00012| 3. Test macro definition with many formal parameters.<010>
+00013 00013| @$@<Sloth with 2@>@(@2@)@{Slothtext@}<010>
+00014 00014| @$@<Sloth with 3@>@(@3@)@{Slothtext@}<010>
+00015 00015| @$@<Sloth with 4@>@(@4@)@{Slothtext@}<010>
+00016 00016| @$@<Sloth with 5@>@(@5@)@{Slothtext@}<010>
+00017 00017| @$@<Sloth with 6@>@(@6@)@{Slothtext@}<010>
+00018 00018| @$@<Sloth with 7@>@(@7@)@{Slothtext@}<010>
+00019 00019| @$@<Sloth with 8@>@(@8@)@{Slothtext@}<010>
+00020 00020| @$@<Sloth with 9@>@(@9@)@{Slothtext@}<010>
+00021 00021| <010>
+00022 00022| 4. Test with syntax errors in the parameter list.<010>
+00023 00023| <010>
+00024 00024| @$@<Sloth a@>@(@+@9@)@{Slothtext@}<010>
+00025 00025| @A@<Error recovery point@><010>
+00026 00026| <010>
+00027 00027| @$@<Sloth b@>@9@)@{Slothtext@}<010>
+00028 00028| @A@<Error recovery point@><010>
+00029 00029| <010>
+00030 00030| @$@<Sloth c@>@(9@)@{Slothtext@}<010>
+00031 00031| @A@<Error recovery point@><010>
+00032 00032| <010>
+00033 00033| @$@<Sloth d@>@9@)@{Slothtext@}<010>
+00034 00034| @A@<Error recovery point@><010>
+00035 00035| <010>
+00036 00036| @$@<Sloth e@>@(@9@)@)@{Slothtext@}<010>
+00037 00037| @A@<Error recovery point@><010>
+00038 00038| <010>
+00039 00039| <010>
+00040 00040| <010>
+00041 00041| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 191 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR05: Test the parsing of formal parameter lists.<010>
+<010>
+First trip the parser so we don't get past the parser.<010>
+"
+0004[01]: @> Close name.
+0004[03]: Text. Text scrap[Grey]="<010>
+<010>
+1. Test macro definition with no formal parameters.<010>
+"
+0007[01]: @$ Macro defn.
+0007[03]: @< Open name.
+0007[05]: Text. Text scrap[Grey]="Sloth"
+0007[10]: @> Close name.
+0007[12]: @{ Open defn.
+0007[14]: Text. Text scrap[Grey]="Slothtext"
+0007[23]: @} Close defn.
+0007[25]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test macro definition with one formal parameter.<010>
+"
+0010[01]: @$ Macro defn.
+0010[03]: @< Open name.
+0010[05]: Text. Text scrap[Grey]="Sloth with one"
+0010[19]: @> Close name.
+0010[21]: @( Open param.
+0010[23]: @n Parameter. Parameterno=1.
+0010[25]: @} Close param.
+0010[27]: @{ Open defn.
+0010[29]: Text. Text scrap[Grey]="Slothtext"
+0010[38]: @} Close defn.
+0010[40]: Text. Text scrap[Grey]="<010>
+<010>
+3. Test macro definition with many formal parameters.<010>
+"
+0013[01]: @$ Macro defn.
+0013[03]: @< Open name.
+0013[05]: Text. Text scrap[Grey]="Sloth with 2"
+0013[17]: @> Close name.
+0013[19]: @( Open param.
+0013[21]: @n Parameter. Parameterno=2.
+0013[23]: @} Close param.
+0013[25]: @{ Open defn.
+0013[27]: Text. Text scrap[Grey]="Slothtext"
+0013[36]: @} Close defn.
+0013[38]: Text. Text scrap[White]="<010>
+"
+0014[01]: @$ Macro defn.
+0014[03]: @< Open name.
+0014[05]: Text. Text scrap[Grey]="Sloth with 3"
+0014[17]: @> Close name.
+0014[19]: @( Open param.
+0014[21]: @n Parameter. Parameterno=3.
+0014[23]: @} Close param.
+0014[25]: @{ Open defn.
+0014[27]: Text. Text scrap[Grey]="Slothtext"
+0014[36]: @} Close defn.
+0014[38]: Text. Text scrap[White]="<010>
+"
+0015[01]: @$ Macro defn.
+0015[03]: @< Open name.
+0015[05]: Text. Text scrap[Grey]="Sloth with 4"
+0015[17]: @> Close name.
+0015[19]: @( Open param.
+0015[21]: @n Parameter. Parameterno=4.
+0015[23]: @} Close param.
+0015[25]: @{ Open defn.
+0015[27]: Text. Text scrap[Grey]="Slothtext"
+0015[36]: @} Close defn.
+0015[38]: Text. Text scrap[White]="<010>
+"
+0016[01]: @$ Macro defn.
+0016[03]: @< Open name.
+0016[05]: Text. Text scrap[Grey]="Sloth with 5"
+0016[17]: @> Close name.
+0016[19]: @( Open param.
+0016[21]: @n Parameter. Parameterno=5.
+0016[23]: @} Close param.
+0016[25]: @{ Open defn.
+0016[27]: Text. Text scrap[Grey]="Slothtext"
+0016[36]: @} Close defn.
+0016[38]: Text. Text scrap[White]="<010>
+"
+0017[01]: @$ Macro defn.
+0017[03]: @< Open name.
+0017[05]: Text. Text scrap[Grey]="Sloth with 6"
+0017[17]: @> Close name.
+0017[19]: @( Open param.
+0017[21]: @n Parameter. Parameterno=6.
+0017[23]: @} Close param.
+0017[25]: @{ Open defn.
+0017[27]: Text. Text scrap[Grey]="Slothtext"
+0017[36]: @} Close defn.
+0017[38]: Text. Text scrap[White]="<010>
+"
+0018[01]: @$ Macro defn.
+0018[03]: @< Open name.
+0018[05]: Text. Text scrap[Grey]="Sloth with 7"
+0018[17]: @> Close name.
+0018[19]: @( Open param.
+0018[21]: @n Parameter. Parameterno=7.
+0018[23]: @} Close param.
+0018[25]: @{ Open defn.
+0018[27]: Text. Text scrap[Grey]="Slothtext"
+0018[36]: @} Close defn.
+0018[38]: Text. Text scrap[White]="<010>
+"
+0019[01]: @$ Macro defn.
+0019[03]: @< Open name.
+0019[05]: Text. Text scrap[Grey]="Sloth with 8"
+0019[17]: @> Close name.
+0019[19]: @( Open param.
+0019[21]: @n Parameter. Parameterno=8.
+0019[23]: @} Close param.
+0019[25]: @{ Open defn.
+0019[27]: Text. Text scrap[Grey]="Slothtext"
+0019[36]: @} Close defn.
+0019[38]: Text. Text scrap[White]="<010>
+"
+0020[01]: @$ Macro defn.
+0020[03]: @< Open name.
+0020[05]: Text. Text scrap[Grey]="Sloth with 9"
+0020[17]: @> Close name.
+0020[19]: @( Open param.
+0020[21]: @n Parameter. Parameterno=9.
+0020[23]: @} Close param.
+0020[25]: @{ Open defn.
+0020[27]: Text. Text scrap[Grey]="Slothtext"
+0020[36]: @} Close defn.
+0020[38]: Text. Text scrap[Grey]="<010>
+<010>
+4. Test with syntax errors in the parameter list.<010>
+<010>
+"
+0024[01]: @$ Macro defn.
+0024[03]: @< Open name.
+0024[05]: Text. Text scrap[Grey]="Sloth a"
+0024[12]: @> Close name.
+0024[14]: @( Open param.
+0024[16]: Text. Text scrap[White]="<010>
+"
+0024[18]: @n Parameter. Parameterno=9.
+0024[20]: @} Close param.
+0024[22]: @{ Open defn.
+0024[24]: Text. Text scrap[Grey]="Slothtext"
+0024[33]: @} Close defn.
+0024[35]: Text. Text scrap[White]="<010>
+"
+0025[01]: @A New section (Level 1).
+0025[03]: @< Open name.
+0025[05]: Text. Text scrap[Grey]="Error recovery point"
+0025[25]: @> Close name.
+0025[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0027[01]: @$ Macro defn.
+0027[03]: @< Open name.
+0027[05]: Text. Text scrap[Grey]="Sloth b"
+0027[12]: @> Close name.
+0027[14]: @n Parameter. Parameterno=9.
+0027[16]: @} Close param.
+0027[18]: @{ Open defn.
+0027[20]: Text. Text scrap[Grey]="Slothtext"
+0027[29]: @} Close defn.
+0027[31]: Text. Text scrap[White]="<010>
+"
+0028[01]: @A New section (Level 1).
+0028[03]: @< Open name.
+0028[05]: Text. Text scrap[Grey]="Error recovery point"
+0028[25]: @> Close name.
+0028[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0030[01]: @$ Macro defn.
+0030[03]: @< Open name.
+0030[05]: Text. Text scrap[Grey]="Sloth c"
+0030[12]: @> Close name.
+0030[14]: @( Open param.
+0030[16]: Text. Text scrap[Grey]="9"
+0030[17]: @} Close param.
+0030[19]: @{ Open defn.
+0030[21]: Text. Text scrap[Grey]="Slothtext"
+0030[30]: @} Close defn.
+0030[32]: Text. Text scrap[White]="<010>
+"
+0031[01]: @A New section (Level 1).
+0031[03]: @< Open name.
+0031[05]: Text. Text scrap[Grey]="Error recovery point"
+0031[25]: @> Close name.
+0031[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0033[01]: @$ Macro defn.
+0033[03]: @< Open name.
+0033[05]: Text. Text scrap[Grey]="Sloth d"
+0033[12]: @> Close name.
+0033[14]: @n Parameter. Parameterno=9.
+0033[16]: @} Close param.
+0033[18]: @{ Open defn.
+0033[20]: Text. Text scrap[Grey]="Slothtext"
+0033[29]: @} Close defn.
+0033[31]: Text. Text scrap[White]="<010>
+"
+0034[01]: @A New section (Level 1).
+0034[03]: @< Open name.
+0034[05]: Text. Text scrap[Grey]="Error recovery point"
+0034[25]: @> Close name.
+0034[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0036[01]: @$ Macro defn.
+0036[03]: @< Open name.
+0036[05]: Text. Text scrap[Grey]="Sloth e"
+0036[12]: @> Close name.
+0036[14]: @( Open param.
+0036[16]: @n Parameter. Parameterno=9.
+0036[18]: @} Close param.
+0036[20]: @} Close param.
+0036[22]: @{ Open defn.
+0036[24]: Text. Text scrap[Grey]="Slothtext"
+0036[33]: @} Close defn.
+0036[35]: Text. Text scrap[White]="<010>
+"
+0037[01]: @A New section (Level 1).
+0037[03]: @< Open name.
+0037[05]: Text. Text scrap[Grey]="Error recovery point"
+0037[25]: @> Close name.
+0037[27]: Text. Text scrap[White]="<010>
+<010>
+<010>
+<010>
+"
+0041[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#file"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#line"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#timestamp"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=1, Pos(L,C)=(7,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth a"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth b"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth c"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth d"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth e"
+Defined? : Yes.
+Parameters : 9
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with 2"
+Defined? : Yes.
+Parameters : 2
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=3, Pos(L,C)=(13,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with 3"
+Defined? : Yes.
+Parameters : 3
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=4, Pos(L,C)=(14,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with 4"
+Defined? : Yes.
+Parameters : 4
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=5, Pos(L,C)=(15,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with 5"
+Defined? : Yes.
+Parameters : 5
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=6, Pos(L,C)=(16,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with 6"
+Defined? : Yes.
+Parameters : 6
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=7, Pos(L,C)=(17,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with 7"
+Defined? : Yes.
+Parameters : 7
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=8, Pos(L,C)=(18,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with 8"
+Defined? : Yes.
+Parameters : 8
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=9, Pos(L,C)=(19,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with 9"
+Defined? : Yes.
+Parameters : 9
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=10, Pos(L,C)=(20,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with one"
+Defined? : Yes.
+Parameters : 1
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=2, Pos(L,C)=(10,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Slothtext"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR05: Test the parsing of formal parameter lists.<010>
+<010>
+First trip the parser so we don't get past the parser.<010>
+"
+--- End of Text Scrap List ---
+
+
+TEXT COMPONENT: Pos(L,C)=(4,3).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+1. Test macro definition with no formal parameters.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(7,1).
+Part 1 of macro @<Sloth@>.
+
+TEXT COMPONENT: Pos(L,C)=(7,25).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+2. Test macro definition with one formal parameter.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(10,1).
+Part 1 of macro @<Sloth with one@>.
+
+TEXT COMPONENT: Pos(L,C)=(10,40).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+3. Test macro definition with many formal parameters.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(13,1).
+Part 1 of macro @<Sloth with 2@>.
+
+TEXT COMPONENT: Pos(L,C)=(13,38).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(14,1).
+Part 1 of macro @<Sloth with 3@>.
+
+TEXT COMPONENT: Pos(L,C)=(14,38).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(15,1).
+Part 1 of macro @<Sloth with 4@>.
+
+TEXT COMPONENT: Pos(L,C)=(15,38).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(16,1).
+Part 1 of macro @<Sloth with 5@>.
+
+TEXT COMPONENT: Pos(L,C)=(16,38).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(17,1).
+Part 1 of macro @<Sloth with 6@>.
+
+TEXT COMPONENT: Pos(L,C)=(17,38).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(18,1).
+Part 1 of macro @<Sloth with 7@>.
+
+TEXT COMPONENT: Pos(L,C)=(18,38).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(19,1).
+Part 1 of macro @<Sloth with 8@>.
+
+TEXT COMPONENT: Pos(L,C)=(19,38).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(20,1).
+Part 1 of macro @<Sloth with 9@>.
+
+TEXT COMPONENT: Pos(L,C)=(20,38).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+4. Test with syntax errors in the parameter list.<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(25,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(28,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "3", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(31,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(34,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "5", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(37,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| PR05: Test the parsing of formal parameter lists.
+ 2 2|
+ 3 3| First trip the parser so we don't get past the parser.
+ 4 4| @>
+ Error|.^The parser was at the top level and was expecting
+ |.^one of: {Directive, Text, Macro definition, EOF}.
+ 5 5|
+ 6 6| 1. Test macro definition with no formal parameters.
+ 7 7| @$@<Sloth@>@{Slothtext@}
+ 8 8|
+ 9 9| 2. Test macro definition with one formal parameter.
+ 10 10| @$@<Sloth with one@>@(@1@)@{Slothtext@}
+ 11 11|
+ 12 12| 3. Test macro definition with many formal parameters.
+ 13 13| @$@<Sloth with 2@>@(@2@)@{Slothtext@}
+ 14 14| @$@<Sloth with 3@>@(@3@)@{Slothtext@}
+ 15 15| @$@<Sloth with 4@>@(@4@)@{Slothtext@}
+ 16 16| @$@<Sloth with 5@>@(@5@)@{Slothtext@}
+ 17 17| @$@<Sloth with 6@>@(@6@)@{Slothtext@}
+ 18 18| @$@<Sloth with 7@>@(@7@)@{Slothtext@}
+ 19 19| @$@<Sloth with 8@>@(@8@)@{Slothtext@}
+ 20 20| @$@<Sloth with 9@>@(@9@)@{Slothtext@}
+ 21 21|
+ 22 22| 4. Test with syntax errors in the parameter list.
+ 23 23|
+ 24 24| @$@<Sloth a@>@(@+@9@)@{Slothtext@}
+ Error|................^Expecting one of [@1..@9].
+ |................^Skipping after error to the next major construct...
+ 25 25| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 26 26|
+ 27 27| @$@<Sloth b@>@9@)@{Slothtext@}
+ Error|..............^Expecting '@{'.
+ |..............^Skipping after error to the next major construct...
+ 28 28| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 29 29|
+ 30 30| @$@<Sloth c@>@(9@)@{Slothtext@}
+ Error|................^Expecting one of [@1..@9].
+ |................^Skipping after error to the next major construct...
+ 31 31| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 32 32|
+ 33 33| @$@<Sloth d@>@9@)@{Slothtext@}
+ Error|..............^Expecting '@{'.
+ |..............^Skipping after error to the next major construct...
+ 34 34| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 35 35|
+ 36 36| @$@<Sloth e@>@(@9@)@)@{Slothtext@}
+ Error|....................^Expecting '@{'.
+ |....................^Skipping after error to the next major construct...
+ 37 37| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 38 38|
+ 39 39|
+ 40 40|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 6 Errors.
diff --git a/web/funnelAC/results/pr06.lis b/web/funnelAC/results/pr06.lis
new file mode 100644
index 0000000000..9a01fd7d7f
--- /dev/null
+++ b/web/funnelAC/results/pr06.lis
@@ -0,0 +1,791 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 30 36 3A 20 54 65 73 74 20 74 68 65 20 70 | PR06: Test the p |
+| 61 72 73 69 6E 67 20 6F 6E 20 69 6E 76 6F 63 61 | arsing on invoca |
+| 74 69 6F 6E 20 6E 75 6D 62 65 72 20 63 6F 6E 73 | tion number cons |
+| 74 72 61 69 6E 74 73 2E 0A 0A 54 72 69 70 20 74 | traints...Trip t |
+| 68 65 20 70 61 72 73 65 72 20 73 6F 20 77 65 20 | he parser so we |
+| 64 6F 6E 27 74 20 67 65 74 20 70 61 73 74 20 69 | don't get past i |
+| 74 2E 0A 40 3E 0A 0A 31 2E 20 54 65 73 74 20 77 | t..@>..1. Test w |
+| 69 74 68 20 6E 6F 20 7A 65 72 6F 20 61 6E 64 20 | ith no zero and |
+| 6E 6F 20 6D 61 6E 79 2E 0A 40 24 40 3C 53 6C 6F | no many..@$@<Slo |
+| 74 68 40 3E 40 7B 4E 6F 20 7A 65 72 6F 20 61 6E | th@>@{No zero an |
+| 64 20 6E 6F 20 6D 61 6E 79 20 69 6E 20 74 68 69 | d no many in thi |
+| 73 20 6D 61 63 72 6F 40 7D 0A 0A 32 2E 20 54 65 | s macro@}..2. Te |
+| 73 74 20 77 69 74 68 20 61 20 7A 65 72 6F 2E 0A | st with a zero.. |
+| 40 24 40 3C 53 6C 6F 74 68 20 7A 65 72 6F 40 3E | @$@<Sloth zero@> |
+| 40 5A 40 7B 43 61 6E 20 62 65 20 63 61 6C 6C 65 | @Z@{Can be calle |
+| 64 20 66 72 6F 6D 20 30 20 74 6F 20 31 20 74 69 | d from 0 to 1 ti |
+| 6D 65 73 2E 40 7D 0A 0A 33 2E 20 54 65 73 74 20 | mes.@}..3. Test |
+| 77 69 74 68 20 61 20 6D 61 6E 79 2E 0A 40 24 40 | with a many..@$@ |
+| 3C 53 6C 6F 74 68 20 6D 61 6E 79 40 3E 40 4D 40 | <Sloth many@>@M@ |
+| 7B 43 61 6E 20 62 65 20 63 61 6C 6C 65 64 20 66 | {Can be called f |
+| 72 6F 6D 20 31 20 74 6F 20 69 6E 66 69 6E 69 74 | rom 1 to infinit |
+| 79 20 74 69 6D 65 73 2E 40 7D 0A 0A 34 2E 20 54 | y times.@}..4. T |
+| 65 73 74 20 77 69 74 68 20 61 20 7A 65 72 6F 20 | est with a zero |
+| 61 6E 64 20 61 20 6D 61 6E 79 2E 0A 40 24 40 3C | and a many..@$@< |
+| 53 6C 6F 74 68 20 7A 65 72 6F 6D 61 6E 79 40 3E | Sloth zeromany@> |
+| 40 5A 40 4D 40 7B 43 61 6E 20 62 65 20 63 61 6C | @Z@M@{Can be cal |
+| 6C 65 64 20 66 72 6F 6D 20 30 20 74 6F 20 69 6E | led from 0 to in |
+| 66 69 6E 69 74 79 20 74 69 6D 65 73 2E 40 7D 0A | finity times.@}. |
+| 0A 35 2E 20 54 65 73 74 20 77 69 74 68 20 61 20 | .5. Test with a |
+| 7A 65 72 6F 20 61 6E 64 20 61 20 6D 61 6E 79 20 | zero and a many |
+| 62 75 74 20 6F 75 74 20 6F 66 20 6F 72 64 65 72 | but out of order |
+| 20 28 73 68 6F 75 6C 64 20 67 69 76 65 20 65 72 | (should give er |
+| 72 6F 72 29 2E 0A 40 24 40 3C 53 6C 6F 74 68 20 | ror)..@$@<Sloth |
+| 6D 61 6E 79 7A 65 72 6F 40 3E 40 4D 40 5A 40 7B | manyzero@>@M@Z@{ |
+| 4F 6F 70 73 2E 40 7D 0A 40 41 40 3C 45 72 72 6F | Oops.@}.@A@<Erro |
+| 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 | r recovery point |
+| 40 3E 0A 0A 36 2E 20 54 65 73 74 20 77 69 74 68 | @>..6. Test with |
+| 20 73 79 6E 74 61 63 74 69 63 20 65 72 72 6F 72 | syntactic error |
+| 73 2E 0A 0A 40 24 40 3C 53 6C 6F 74 68 20 61 40 | s...@$@<Sloth a@ |
+| 3E 20 40 4D 20 40 5A 20 40 7B 4F 6F 70 73 2E 40 | > @M @Z @{Oops.@ |
+| 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F | }.@A@<Error reco |
+| 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 40 24 | very point@>..@$ |
+| 40 3C 53 6C 6F 74 68 20 62 40 3E 40 5A 40 5A 40 | @<Sloth b@>@Z@Z@ |
+| 7B 4F 6F 70 73 2E 40 7D 0A 40 41 40 3C 45 72 72 | {Oops.@}.@A@<Err |
+| 6F 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E | or recovery poin |
+| 74 40 3E 0A 0A 40 24 40 3C 53 6C 6F 74 68 20 63 | t@>..@$@<Sloth c |
+| 40 5A 40 3E 40 7B 4F 6F 70 73 2E 40 7D 0A 40 41 | @Z@>@{Oops.@}.@A |
+| 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 | @<Error recovery |
+| 20 70 6F 69 6E 74 40 3E 0A 0A 40 24 40 3C 53 6C | point@>..@$@<Sl |
+| 6F 74 68 20 64 40 3E 5A 40 7B 4F 6F 70 73 2E 40 | oth d@>Z@{Oops.@ |
+| 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F | }.@A@<Error reco |
+| 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 40 24 | very point@>..@$ |
+| 40 3C 53 6C 6F 74 68 20 64 40 3E 40 5A 4D 40 7B | @<Sloth d@>@ZM@{ |
+| 4F 6F 70 73 2E 40 7D 0A 40 41 40 3C 45 72 72 6F | Oops.@}.@A@<Erro |
+| 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 | r recovery point |
+| 40 3E 0A 0A 0A | @>... |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR06: Test the parsing on invocation number constraints.<010>
+00002 00002| <010>
+00003 00003| Trip the parser so we don't get past it.<010>
+00004 00004| @><010>
+00005 00005| <010>
+00006 00006| 1. Test with no zero and no many.<010>
+00007 00007| @$@<Sloth@>@{No zero and no many in this macro@}<010>
+00008 00008| <010>
+00009 00009| 2. Test with a zero.<010>
+00010 00010| @$@<Sloth zero@>@Z@{Can be called from 0 to 1 times.@}<010>
+00011 00011| <010>
+00012 00012| 3. Test with a many.<010>
+00013 00013| @$@<Sloth many@>@M@{Can be called from 1 to infinity times.@}<010>
+00014 00014| <010>
+00015 00015| 4. Test with a zero and a many.<010>
+00016 00016| @$@<Sloth zeromany@>@Z@M@{Can be called from 0 to infinity times.@}<010>
+00017 00017| <010>
+00018 00018| 5. Test with a zero and a many but out of order (should give error).<010>
+00019 00019| @$@<Sloth manyzero@>@M@Z@{Oops.@}<010>
+00020 00020| @A@<Error recovery point@><010>
+00021 00021| <010>
+00022 00022| 6. Test with syntactic errors.<010>
+00023 00023| <010>
+00024 00024| @$@<Sloth a@> @M @Z @{Oops.@}<010>
+00025 00025| @A@<Error recovery point@><010>
+00026 00026| <010>
+00027 00027| @$@<Sloth b@>@Z@Z@{Oops.@}<010>
+00028 00028| @A@<Error recovery point@><010>
+00029 00029| <010>
+00030 00030| @$@<Sloth c@Z@>@{Oops.@}<010>
+00031 00031| @A@<Error recovery point@><010>
+00032 00032| <010>
+00033 00033| @$@<Sloth d@>Z@{Oops.@}<010>
+00034 00034| @A@<Error recovery point@><010>
+00035 00035| <010>
+00036 00036| @$@<Sloth d@>@ZM@{Oops.@}<010>
+00037 00037| @A@<Error recovery point@><010>
+00038 00038| <010>
+00039 00039| <010>
+00040 00040| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 131 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR06: Test the parsing on invocation number constraints.<010>
+<010>
+Trip the parser so we don't get past it.<010>
+"
+0004[01]: @> Close name.
+0004[03]: Text. Text scrap[Grey]="<010>
+<010>
+1. Test with no zero and no many.<010>
+"
+0007[01]: @$ Macro defn.
+0007[03]: @< Open name.
+0007[05]: Text. Text scrap[Grey]="Sloth"
+0007[10]: @> Close name.
+0007[12]: @{ Open defn.
+0007[14]: Text. Text scrap[Grey]="No zero and no many in this macro"
+0007[47]: @} Close defn.
+0007[49]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test with a zero.<010>
+"
+0010[01]: @$ Macro defn.
+0010[03]: @< Open name.
+0010[05]: Text. Text scrap[Grey]="Sloth zero"
+0010[15]: @> Close name.
+0010[17]: @Z Zero calls.
+0010[19]: @{ Open defn.
+0010[21]: Text. Text scrap[Grey]="Can be called from 0 to 1 times."
+0010[53]: @} Close defn.
+0010[55]: Text. Text scrap[Grey]="<010>
+<010>
+3. Test with a many.<010>
+"
+0013[01]: @$ Macro defn.
+0013[03]: @< Open name.
+0013[05]: Text. Text scrap[Grey]="Sloth many"
+0013[15]: @> Close name.
+0013[17]: @M Many calls.
+0013[19]: @{ Open defn.
+0013[21]: Text. Text scrap[Grey]="Can be called from 1 to infinity times."
+0013[60]: @} Close defn.
+0013[62]: Text. Text scrap[Grey]="<010>
+<010>
+4. Test with a zero and a many.<010>
+"
+0016[01]: @$ Macro defn.
+0016[03]: @< Open name.
+0016[05]: Text. Text scrap[Grey]="Sloth zeromany"
+0016[19]: @> Close name.
+0016[21]: @Z Zero calls.
+0016[23]: @M Many calls.
+0016[25]: @{ Open defn.
+0016[27]: Text. Text scrap[Grey]="Can be called from 0 to infinity times."
+0016[66]: @} Close defn.
+0016[68]: Text. Text scrap[Grey]="<010>
+<010>
+5. Test with a zero and a many but out of order (should give error).<010>
+"
+0019[01]: @$ Macro defn.
+0019[03]: @< Open name.
+0019[05]: Text. Text scrap[Grey]="Sloth manyzero"
+0019[19]: @> Close name.
+0019[21]: @M Many calls.
+0019[23]: @Z Zero calls.
+0019[25]: @{ Open defn.
+0019[27]: Text. Text scrap[Grey]="Oops."
+0019[32]: @} Close defn.
+0019[34]: Text. Text scrap[White]="<010>
+"
+0020[01]: @A New section (Level 1).
+0020[03]: @< Open name.
+0020[05]: Text. Text scrap[Grey]="Error recovery point"
+0020[25]: @> Close name.
+0020[27]: Text. Text scrap[Grey]="<010>
+<010>
+6. Test with syntactic errors.<010>
+<010>
+"
+0024[01]: @$ Macro defn.
+0024[03]: @< Open name.
+0024[05]: Text. Text scrap[Grey]="Sloth a"
+0024[12]: @> Close name.
+0024[14]: Text. Text scrap[White]=" "
+0024[15]: @M Many calls.
+0024[17]: Text. Text scrap[White]=" "
+0024[18]: @Z Zero calls.
+0024[20]: Text. Text scrap[White]=" "
+0024[21]: @{ Open defn.
+0024[23]: Text. Text scrap[Grey]="Oops."
+0024[28]: @} Close defn.
+0024[30]: Text. Text scrap[White]="<010>
+"
+0025[01]: @A New section (Level 1).
+0025[03]: @< Open name.
+0025[05]: Text. Text scrap[Grey]="Error recovery point"
+0025[25]: @> Close name.
+0025[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0027[01]: @$ Macro defn.
+0027[03]: @< Open name.
+0027[05]: Text. Text scrap[Grey]="Sloth b"
+0027[12]: @> Close name.
+0027[14]: @Z Zero calls.
+0027[16]: @Z Zero calls.
+0027[18]: @{ Open defn.
+0027[20]: Text. Text scrap[Grey]="Oops."
+0027[25]: @} Close defn.
+0027[27]: Text. Text scrap[White]="<010>
+"
+0028[01]: @A New section (Level 1).
+0028[03]: @< Open name.
+0028[05]: Text. Text scrap[Grey]="Error recovery point"
+0028[25]: @> Close name.
+0028[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0030[01]: @$ Macro defn.
+0030[03]: @< Open name.
+0030[05]: Text. Text scrap[Grey]="Sloth c"
+0030[12]: @Z Zero calls.
+0030[14]: @> Close name.
+0030[16]: @{ Open defn.
+0030[18]: Text. Text scrap[Grey]="Oops."
+0030[23]: @} Close defn.
+0030[25]: Text. Text scrap[White]="<010>
+"
+0031[01]: @A New section (Level 1).
+0031[03]: @< Open name.
+0031[05]: Text. Text scrap[Grey]="Error recovery point"
+0031[25]: @> Close name.
+0031[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0033[01]: @$ Macro defn.
+0033[03]: @< Open name.
+0033[05]: Text. Text scrap[Grey]="Sloth d"
+0033[12]: @> Close name.
+0033[14]: Text. Text scrap[Grey]="Z"
+0033[15]: @{ Open defn.
+0033[17]: Text. Text scrap[Grey]="Oops."
+0033[22]: @} Close defn.
+0033[24]: Text. Text scrap[White]="<010>
+"
+0034[01]: @A New section (Level 1).
+0034[03]: @< Open name.
+0034[05]: Text. Text scrap[Grey]="Error recovery point"
+0034[25]: @> Close name.
+0034[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0036[01]: @$ Macro defn.
+0036[03]: @< Open name.
+0036[05]: Text. Text scrap[Grey]="Sloth d"
+0036[12]: @> Close name.
+0036[14]: @Z Zero calls.
+0036[16]: Text. Text scrap[Grey]="M"
+0036[17]: @{ Open defn.
+0036[19]: Text. Text scrap[Grey]="Oops."
+0036[24]: @} Close defn.
+0036[26]: Text. Text scrap[White]="<010>
+"
+0037[01]: @A New section (Level 1).
+0037[03]: @< Open name.
+0037[05]: Text. Text scrap[Grey]="Error recovery point"
+0037[25]: @> Close name.
+0037[27]: Text. Text scrap[White]="<010>
+<010>
+<010>
+"
+0040[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#file"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#line"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#timestamp"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=1, Pos(L,C)=(7,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="No zero and no many in this macro"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth a"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth b"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth d"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth many"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=3, Pos(L,C)=(13,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Can be called from 1 to infinity times."
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth manyzero"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth zero"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=2, Pos(L,C)=(10,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Can be called from 0 to 1 times."
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth zeromany"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=4, Pos(L,C)=(16,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Can be called from 0 to infinity times."
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR06: Test the parsing on invocation number constraints.<010>
+<010>
+Trip the parser so we don't get past it.<010>
+"
+--- End of Text Scrap List ---
+
+
+TEXT COMPONENT: Pos(L,C)=(4,3).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+1. Test with no zero and no many.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(7,1).
+Part 1 of macro @<Sloth@>.
+
+TEXT COMPONENT: Pos(L,C)=(7,49).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+2. Test with a zero.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(10,1).
+Part 1 of macro @<Sloth zero@>.
+
+TEXT COMPONENT: Pos(L,C)=(10,55).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+3. Test with a many.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(13,1).
+Part 1 of macro @<Sloth many@>.
+
+TEXT COMPONENT: Pos(L,C)=(13,62).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+4. Test with a zero and a many.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(16,1).
+Part 1 of macro @<Sloth zeromany@>.
+
+TEXT COMPONENT: Pos(L,C)=(16,68).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+5. Test with a zero and a many but out of order (should give error).<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(20,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+6. Test with syntactic errors.<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(25,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "3", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(28,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(31,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "5", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(34,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "6", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(37,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| PR06: Test the parsing on invocation number constraints.
+ 2 2|
+ 3 3| Trip the parser so we don't get past it.
+ 4 4| @>
+ Error|.^The parser was at the top level and was expecting
+ |.^one of: {Directive, Text, Macro definition, EOF}.
+ 5 5|
+ 6 6| 1. Test with no zero and no many.
+ 7 7| @$@<Sloth@>@{No zero and no many in this macro@}
+ 8 8|
+ 9 9| 2. Test with a zero.
+ 10 10| @$@<Sloth zero@>@Z@{Can be called from 0 to 1 times.@}
+ 11 11|
+ 12 12| 3. Test with a many.
+ 13 13| @$@<Sloth many@>@M@{Can be called from 1 to infinity times.@}
+ 14 14|
+ 15 15| 4. Test with a zero and a many.
+ 16 16| @$@<Sloth zeromany@>@Z@M@{Can be called from 0 to infinity times.@}
+ 17 17|
+ 18 18| 5. Test with a zero and a many but out of order (should give error).
+ 19 19| @$@<Sloth manyzero@>@M@Z@{Oops.@}
+ Error|.......................^Expecting '@{'.
+ |.......................^Skipping after error to the next major construct...
+ 20 20| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 21 21|
+ 22 22| 6. Test with syntactic errors.
+ 23 23|
+ 24 24| @$@<Sloth a@> @M @Z @{Oops.@}
+ Error|..............^Expecting "==@{" or "+=@{" or just "@{".
+ |..............^(or @Z or @M if they have not already appeared).
+ |..............^Note: FunnelWeb is intolerant of spaces at this point.
+ |...............^Skipping after error to the next major construct...
+ 25 25| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 26 26|
+ 27 27| @$@<Sloth b@>@Z@Z@{Oops.@}
+ Error|................^Expecting '@{'.
+ |................^Skipping after error to the next major construct...
+ 28 28| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 29 29|
+ 30 30| @$@<Sloth c@Z@>@{Oops.@}
+ Error|............^Illegal character or symbol in name.
+ |............^Skipping after error to the next major construct...
+ 31 31| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 32 32|
+ 33 33| @$@<Sloth d@>Z@{Oops.@}
+ Error|..............^Expecting "==@{" or "+=@{" or just "@{".
+ |..............^(or @Z or @M if they have not already appeared).
+ |..............^Note: FunnelWeb is intolerant of spaces at this point.
+ |...............^Skipping after error to the next major construct...
+ 34 34| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 35 35|
+ 36 36| @$@<Sloth d@>@ZM@{Oops.@}
+ Error|................^Expecting "==@{" or "+=@{" or just "@{".
+ |................^(or @Z or @M if they have not already appeared).
+ |................^Note: FunnelWeb is intolerant of spaces at this point.
+ |.................^Skipping after error to the next major construct...
+ 37 37| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 38 38|
+ 39 39|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 7 Errors.
diff --git a/web/funnelAC/results/pr07.lis b/web/funnelAC/results/pr07.lis
new file mode 100644
index 0000000000..be11d727e6
--- /dev/null
+++ b/web/funnelAC/results/pr07.lis
@@ -0,0 +1,703 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 30 37 3A 20 54 65 73 74 20 74 68 65 20 70 | PR07: Test the p |
+| 61 72 73 69 6E 67 20 6F 66 20 3D 3D 20 61 6E 64 | arsing of == and |
+| 20 2B 3D 20 69 6E 20 6D 61 63 72 6F 20 64 65 66 | += in macro def |
+| 69 6E 69 74 69 6F 6E 73 2E 0A 0A 54 72 69 70 20 | initions...Trip |
+| 74 68 65 20 70 61 72 73 65 72 20 73 6F 20 77 65 | the parser so we |
+| 20 64 6F 6E 27 74 20 67 65 74 20 61 6E 79 20 66 | don't get any f |
+| 75 72 74 68 65 72 2E 0A 40 3E 0A 0A 31 2E 20 54 | urther..@>..1. T |
+| 65 73 74 20 77 69 74 68 20 6E 6F 20 65 71 75 61 | est with no equa |
+| 6C 73 2E 0A 40 24 40 3C 53 6C 6F 74 68 40 3E 40 | ls..@$@<Sloth@>@ |
+| 7B 4E 6F 20 65 71 75 61 6C 73 20 69 6E 20 74 68 | {No equals in th |
+| 69 73 20 6D 61 63 72 6F 20 64 65 66 69 6E 69 74 | is macro definit |
+| 69 6F 6E 2E 40 7D 0A 0A 32 2E 20 54 65 73 74 20 | ion.@}..2. Test |
+| 77 69 74 68 20 3D 3D 2E 0A 40 24 40 3C 53 6C 6F | with ==..@$@<Slo |
+| 74 68 20 77 69 74 68 20 65 71 75 61 6C 73 40 3E | th with equals@> |
+| 3D 3D 40 7B 4E 6F 20 65 71 75 61 6C 73 20 69 6E | ==@{No equals in |
+| 20 74 68 69 73 20 6D 61 63 72 6F 20 64 65 66 69 | this macro defi |
+| 6E 69 74 69 6F 6E 2E 40 7D 0A 0A 33 2E 20 54 65 | nition.@}..3. Te |
+| 73 74 20 77 69 74 68 20 2B 3D 2E 0A 40 24 40 3C | st with +=..@$@< |
+| 53 6C 6F 74 68 20 77 69 74 68 20 70 6C 75 73 40 | Sloth with plus@ |
+| 3E 2B 3D 40 7B 4E 6F 20 65 71 75 61 6C 73 20 69 | >+=@{No equals i |
+| 6E 20 74 68 69 73 20 6D 61 63 72 6F 20 64 65 66 | n this macro def |
+| 69 6E 69 74 69 6F 6E 2E 40 7D 0A 0A 34 2E 20 54 | inition.@}..4. T |
+| 65 73 74 20 77 69 74 68 20 73 79 6E 74 61 78 20 | est with syntax |
+| 65 72 72 6F 72 73 2E 0A 0A 40 24 40 3C 45 72 72 | errors...@$@<Err |
+| 6F 72 31 40 3E 2B 2B 40 7B 4E 6F 20 65 71 75 61 | or1@>++@{No equa |
+| 6C 73 20 69 6E 20 74 68 69 73 20 6D 61 63 72 6F | ls in this macro |
+| 20 64 65 66 69 6E 69 74 69 6F 6E 2E 40 7D 0A 40 | definition.@}.@ |
+| 41 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 72 | A@<Error recover |
+| 79 20 70 6F 69 6E 74 40 3E 0A 0A 40 24 40 3C 45 | y point@>..@$@<E |
+| 72 72 6F 72 32 40 3E 40 2B 3D 40 7B 4E 6F 20 65 | rror2@>@+=@{No e |
+| 71 75 61 6C 73 20 69 6E 20 74 68 69 73 20 6D 61 | quals in this ma |
+| 63 72 6F 20 64 65 66 69 6E 69 74 69 6F 6E 2E 40 | cro definition.@ |
+| 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F | }.@A@<Error reco |
+| 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 40 24 | very point@>..@$ |
+| 40 3C 45 72 72 6F 72 33 40 3E 2B 3D 3D 2B 40 7B | @<Error3@>+==+@{ |
+| 4E 6F 20 65 71 75 61 6C 73 20 69 6E 20 74 68 69 | No equals in thi |
+| 73 20 6D 61 63 72 6F 20 64 65 66 69 6E 69 74 69 | s macro definiti |
+| 6F 6E 2E 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 | on.@}.@A@<Error |
+| 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 40 3E | recovery point@> |
+| 0A 0A 40 24 40 3C 45 72 72 6F 72 34 40 3E 3D 2B | ..@$@<Error4@>=+ |
+| 40 7B 4E 6F 20 65 71 75 61 6C 73 20 69 6E 20 74 | @{No equals in t |
+| 68 69 73 20 6D 61 63 72 6F 20 64 65 66 69 6E 69 | his macro defini |
+| 74 69 6F 6E 2E 40 7D 0A 40 41 40 3C 45 72 72 6F | tion.@}.@A@<Erro |
+| 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 | r recovery point |
+| 40 3E 0A 0A 40 24 40 3C 45 72 72 6F 72 34 40 3E | @>..@$@<Error4@> |
+| 40 3D 40 3D 40 7B 4E 6F 20 65 71 75 61 6C 73 20 | @=@=@{No equals |
+| 69 6E 20 74 68 69 73 20 6D 61 63 72 6F 20 64 65 | in this macro de |
+| 66 69 6E 69 74 69 6F 6E 2E 40 7D 0A 40 41 40 3C | finition.@}.@A@< |
+| 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 70 | Error recovery p |
+| 6F 69 6E 74 40 3E 0A 0A 40 24 40 3C 45 72 72 6F | oint@>..@$@<Erro |
+| 72 34 40 3E 40 2B 40 3D 40 7B 4E 6F 20 65 71 75 | r4@>@+@=@{No equ |
+| 61 6C 73 20 69 6E 20 74 68 69 73 20 6D 61 63 72 | als in this macr |
+| 6F 20 64 65 66 69 6E 69 74 69 6F 6E 2E 40 7D 0A | o definition.@}. |
+| 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 | @A@<Error recove |
+| 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 0A 0A | ry point@>.... |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR07: Test the parsing of == and += in macro definitions.<010>
+00002 00002| <010>
+00003 00003| Trip the parser so we don't get any further.<010>
+00004 00004| @><010>
+00005 00005| <010>
+00006 00006| 1. Test with no equals.<010>
+00007 00007| @$@<Sloth@>@{No equals in this macro definition.@}<010>
+00008 00008| <010>
+00009 00009| 2. Test with ==.<010>
+00010 00010| @$@<Sloth with equals@>==@{No equals in this macro definition.@}<010>
+00011 00011| <010>
+00012 00012| 3. Test with +=.<010>
+00013 00013| @$@<Sloth with plus@>+=@{No equals in this macro definition.@}<010>
+00014 00014| <010>
+00015 00015| 4. Test with syntax errors.<010>
+00016 00016| <010>
+00017 00017| @$@<Error1@>++@{No equals in this macro definition.@}<010>
+00018 00018| @A@<Error recovery point@><010>
+00019 00019| <010>
+00020 00020| @$@<Error2@>@+=@{No equals in this macro definition.@}<010>
+00021 00021| @A@<Error recovery point@><010>
+00022 00022| <010>
+00023 00023| @$@<Error3@>+==+@{No equals in this macro definition.@}<010>
+00024 00024| @A@<Error recovery point@><010>
+00025 00025| <010>
+00026 00026| @$@<Error4@>=+@{No equals in this macro definition.@}<010>
+00027 00027| @A@<Error recovery point@><010>
+00028 00028| <010>
+00029 00029| @$@<Error4@>@=@=@{No equals in this macro definition.@}<010>
+00030 00030| @A@<Error recovery point@><010>
+00031 00031| <010>
+00032 00032| @$@<Error4@>@+@=@{No equals in this macro definition.@}<010>
+00033 00033| @A@<Error recovery point@><010>
+00034 00034| <010>
+00035 00035| <010>
+00036 00036| <010>
+00037 00037| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 114 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR07: Test the parsing of == and += in macro definitions.<010>
+<010>
+Trip the parser so we don't get any further.<010>
+"
+0004[01]: @> Close name.
+0004[03]: Text. Text scrap[Grey]="<010>
+<010>
+1. Test with no equals.<010>
+"
+0007[01]: @$ Macro defn.
+0007[03]: @< Open name.
+0007[05]: Text. Text scrap[Grey]="Sloth"
+0007[10]: @> Close name.
+0007[12]: @{ Open defn.
+0007[14]: Text. Text scrap[Grey]="No equals in this macro definition."
+0007[49]: @} Close defn.
+0007[51]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test with ==.<010>
+"
+0010[01]: @$ Macro defn.
+0010[03]: @< Open name.
+0010[05]: Text. Text scrap[Grey]="Sloth with equals"
+0010[22]: @> Close name.
+0010[24]: Text. Text scrap[Grey]="=="
+0010[26]: @{ Open defn.
+0010[28]: Text. Text scrap[Grey]="No equals in this macro definition."
+0010[63]: @} Close defn.
+0010[65]: Text. Text scrap[Grey]="<010>
+<010>
+3. Test with +=.<010>
+"
+0013[01]: @$ Macro defn.
+0013[03]: @< Open name.
+0013[05]: Text. Text scrap[Grey]="Sloth with plus"
+0013[20]: @> Close name.
+0013[22]: Text. Text scrap[Grey]="+="
+0013[24]: @{ Open defn.
+0013[26]: Text. Text scrap[Grey]="No equals in this macro definition."
+0013[61]: @} Close defn.
+0013[63]: Text. Text scrap[Grey]="<010>
+<010>
+4. Test with syntax errors.<010>
+<010>
+"
+0017[01]: @$ Macro defn.
+0017[03]: @< Open name.
+0017[05]: Text. Text scrap[Grey]="Error1"
+0017[11]: @> Close name.
+0017[13]: Text. Text scrap[Grey]="++"
+0017[15]: @{ Open defn.
+0017[17]: Text. Text scrap[Grey]="No equals in this macro definition."
+0017[52]: @} Close defn.
+0017[54]: Text. Text scrap[White]="<010>
+"
+0018[01]: @A New section (Level 1).
+0018[03]: @< Open name.
+0018[05]: Text. Text scrap[Grey]="Error recovery point"
+0018[25]: @> Close name.
+0018[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0020[01]: @$ Macro defn.
+0020[03]: @< Open name.
+0020[05]: Text. Text scrap[Grey]="Error2"
+0020[11]: @> Close name.
+0020[13]: Text. Text scrap[White]="<010>
+"
+0020[15]: Text. Text scrap[Grey]="="
+0020[16]: @{ Open defn.
+0020[18]: Text. Text scrap[Grey]="No equals in this macro definition."
+0020[53]: @} Close defn.
+0020[55]: Text. Text scrap[White]="<010>
+"
+0021[01]: @A New section (Level 1).
+0021[03]: @< Open name.
+0021[05]: Text. Text scrap[Grey]="Error recovery point"
+0021[25]: @> Close name.
+0021[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0023[01]: @$ Macro defn.
+0023[03]: @< Open name.
+0023[05]: Text. Text scrap[Grey]="Error3"
+0023[11]: @> Close name.
+0023[13]: Text. Text scrap[Grey]="+==+"
+0023[17]: @{ Open defn.
+0023[19]: Text. Text scrap[Grey]="No equals in this macro definition."
+0023[54]: @} Close defn.
+0023[56]: Text. Text scrap[White]="<010>
+"
+0024[01]: @A New section (Level 1).
+0024[03]: @< Open name.
+0024[05]: Text. Text scrap[Grey]="Error recovery point"
+0024[25]: @> Close name.
+0024[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0026[01]: @$ Macro defn.
+0026[03]: @< Open name.
+0026[05]: Text. Text scrap[Grey]="Error4"
+0026[11]: @> Close name.
+0026[13]: Text. Text scrap[Grey]="=+"
+0026[15]: @{ Open defn.
+0026[17]: Text. Text scrap[Grey]="No equals in this macro definition."
+0026[52]: @} Close defn.
+0026[54]: Text. Text scrap[White]="<010>
+"
+0027[01]: @A New section (Level 1).
+0027[03]: @< Open name.
+0027[05]: Text. Text scrap[Grey]="Error recovery point"
+0027[25]: @> Close name.
+0027[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0029[01]: @$ Macro defn.
+0029[03]: @< Open name.
+0029[05]: Text. Text scrap[Grey]="Error4"
+0029[11]: @> Close name.
+0029[16]: Text. Text scrap[Grey]="="
+0029[17]: @{ Open defn.
+0029[19]: Text. Text scrap[Grey]="No equals in this macro definition."
+0029[54]: @} Close defn.
+0029[56]: Text. Text scrap[White]="<010>
+"
+0030[01]: @A New section (Level 1).
+0030[03]: @< Open name.
+0030[05]: Text. Text scrap[Grey]="Error recovery point"
+0030[25]: @> Close name.
+0030[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0032[01]: @$ Macro defn.
+0032[03]: @< Open name.
+0032[05]: Text. Text scrap[Grey]="Error4"
+0032[11]: @> Close name.
+0032[13]: Text. Text scrap[White]="<010>
+"
+0032[18]: Text. Text scrap[Grey]="{No equals in this macro definition."
+0032[54]: @} Close defn.
+0032[56]: Text. Text scrap[White]="<010>
+"
+0033[01]: @A New section (Level 1).
+0033[03]: @< Open name.
+0033[05]: Text. Text scrap[Grey]="Error recovery point"
+0033[25]: @> Close name.
+0033[27]: Text. Text scrap[White]="<010>
+<010>
+<010>
+<010>
+"
+0037[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#file"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#line"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#timestamp"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error1"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error2"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error3"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error4"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=1, Pos(L,C)=(7,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="No equals in this macro definition."
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with equals"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=2, Pos(L,C)=(10,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="No equals in this macro definition."
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth with plus"
+Defined? : Yes.
+Parameters : 0
+Additive? : Yes.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=3, Pos(L,C)=(13,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="No equals in this macro definition."
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR07: Test the parsing of == and += in macro definitions.<010>
+<010>
+Trip the parser so we don't get any further.<010>
+"
+--- End of Text Scrap List ---
+
+
+TEXT COMPONENT: Pos(L,C)=(4,3).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+1. Test with no equals.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(7,1).
+Part 1 of macro @<Sloth@>.
+
+TEXT COMPONENT: Pos(L,C)=(7,51).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+2. Test with ==.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(10,1).
+Part 1 of macro @<Sloth with equals@>.
+
+TEXT COMPONENT: Pos(L,C)=(10,65).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+3. Test with +=.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(13,1).
+Part 1 of macro @<Sloth with plus@>.
+
+TEXT COMPONENT: Pos(L,C)=(13,63).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+4. Test with syntax errors.<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(18,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(21,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "3", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(24,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(27,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "5", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(30,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "6", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(33,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| PR07: Test the parsing of == and += in macro definitions.
+ 2 2|
+ 3 3| Trip the parser so we don't get any further.
+ 4 4| @>
+ Error|.^The parser was at the top level and was expecting
+ |.^one of: {Directive, Text, Macro definition, EOF}.
+ 5 5|
+ 6 6| 1. Test with no equals.
+ 7 7| @$@<Sloth@>@{No equals in this macro definition.@}
+ 8 8|
+ 9 9| 2. Test with ==.
+ 10 10| @$@<Sloth with equals@>==@{No equals in this macro definition.@}
+ 11 11|
+ 12 12| 3. Test with +=.
+ 13 13| @$@<Sloth with plus@>+=@{No equals in this macro definition.@}
+ 14 14|
+ 15 15| 4. Test with syntax errors.
+ 16 16|
+ 17 17| @$@<Error1@>++@{No equals in this macro definition.@}
+ Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+ |.............^(or @Z or @M if they have not already appeared).
+ |.............^Note: FunnelWeb is intolerant of spaces at this point.
+ |...............^Skipping after error to the next major construct...
+ 18 18| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 19 19|
+ 20 20| @$@<Error2@>@+=@{No equals in this macro definition.@}
+ Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+ |.............^(or @Z or @M if they have not already appeared).
+ |.............^Note: FunnelWeb is intolerant of spaces at this point.
+ |................^Skipping after error to the next major construct...
+ 21 21| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 22 22|
+ 23 23| @$@<Error3@>+==+@{No equals in this macro definition.@}
+ Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+ |.............^(or @Z or @M if they have not already appeared).
+ |.............^Note: FunnelWeb is intolerant of spaces at this point.
+ |.................^Skipping after error to the next major construct...
+ 24 24| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 25 25|
+ 26 26| @$@<Error4@>=+@{No equals in this macro definition.@}
+ Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+ |.............^(or @Z or @M if they have not already appeared).
+ |.............^Note: FunnelWeb is intolerant of spaces at this point.
+ |...............^Skipping after error to the next major construct...
+ 27 27| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 28 28|
+ 29 29| @$@<Error4@>@=@=@{No equals in this macro definition.@}
+ Error|................^Expecting "==@{" or "+=@{" or just "@{".
+ |................^(or @Z or @M if they have not already appeared).
+ |................^Note: FunnelWeb is intolerant of spaces at this point.
+ |.................^Skipping after error to the next major construct...
+ 30 30| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 31 31|
+ 32 32| @$@<Error4@>@+@=@{No equals in this macro definition.@}
+ Error|.............^Expecting "==@{" or "+=@{" or just "@{".
+ |.............^(or @Z or @M if they have not already appeared).
+ |.............^Note: FunnelWeb is intolerant of spaces at this point.
+ |......................................................^Skipping after error to the next major construct...
+ 33 33| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 34 34|
+ 35 35|
+ 36 36|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 7 Errors.
diff --git a/web/funnelAC/results/pr08.lis b/web/funnelAC/results/pr08.lis
new file mode 100644
index 0000000000..daf44e8219
--- /dev/null
+++ b/web/funnelAC/results/pr08.lis
@@ -0,0 +1,1360 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 30 38 3A 20 54 65 73 74 20 73 65 6D 61 6E | PR08: Test seman |
+| 74 69 63 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 | tic checking of |
+| 6D 61 63 72 6F 20 64 65 66 69 6E 69 74 69 6F 6E | macro definition |
+| 73 2E 0A 0A 54 72 69 70 20 70 61 72 73 65 72 20 | s...Trip parser |
+| 74 6F 20 62 65 20 73 75 72 65 20 74 68 61 74 20 | to be sure that |
+| 77 65 20 77 6F 6E 27 74 20 67 65 74 20 61 6E 79 | we won't get any |
+| 20 6F 75 74 70 75 74 20 66 69 6C 65 73 21 0A 40 | output files!.@ |
+| 3E 0A 0A 31 2E 20 46 69 6C 65 20 6D 61 63 72 6F | >..1. File macro |
+| 20 68 61 73 20 70 61 72 61 6D 65 74 65 72 73 2E | has parameters. |
+| 20 45 72 72 6F 72 2E 0A 40 4F 40 3C 53 6C 6F 74 | Error..@O@<Slot |
+| 68 20 31 40 3E 40 28 40 33 40 29 40 7B 57 61 6C | h 1@>@(@3@)@{Wal |
+| 72 75 73 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 | rus@}.@A@<Error |
+| 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 40 3E | recovery point@> |
+| 0A 0A 32 2E 20 46 69 6C 65 20 6D 61 63 72 6F 20 | ..2. File macro |
+| 69 73 20 61 64 64 69 74 69 76 65 2E 20 45 72 72 | is additive. Err |
+| 6F 72 2E 0A 40 4F 40 3C 53 6C 6F 74 68 20 32 40 | or..@O@<Sloth 2@ |
+| 3E 2B 3D 40 7B 57 61 6C 72 75 73 40 7D 0A 40 41 | >+=@{Walrus@}.@A |
+| 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 | @<Error recovery |
+| 20 70 6F 69 6E 74 40 3E 0A 0A 33 2E 20 46 69 6C | point@>..3. Fil |
+| 65 20 6D 61 63 72 6F 20 68 61 73 20 74 6F 6F 20 | e macro has too |
+| 6C 6F 6E 67 20 61 20 6E 61 6D 65 2E 20 54 68 65 | long a name. The |
+| 20 74 65 73 74 20 6E 61 6D 65 20 68 61 73 20 31 | test name has 1 |
+| 32 30 30 20 63 68 61 72 61 63 74 65 72 73 2E 20 | 200 characters. |
+| 45 72 72 2E 0A 4E 6F 74 65 3A 20 54 68 69 73 20 | Err..Note: This |
+| 74 65 73 74 20 63 61 6E 27 74 20 74 65 73 74 20 | test can't test |
+| 74 68 65 20 65 72 72 6F 72 20 6D 65 73 73 61 67 | the error messag |
+| 65 20 69 66 20 74 68 65 20 6D 61 78 69 6D 75 6D | e if the maximum |
+| 20 6C 65 6E 67 74 68 20 6F 66 20 61 0A 6D 61 63 | length of a.mac |
+| 72 6F 20 6E 61 6D 65 20 69 73 20 6C 65 73 73 20 | ro name is less |
+| 74 68 61 6E 20 74 68 65 20 6D 61 78 69 6D 75 6D | than the maximum |
+| 20 6C 65 6E 67 74 68 20 6F 66 20 61 20 66 69 6C | length of a fil |
+| 65 20 6E 61 6D 65 20 61 73 20 74 68 65 20 6E 61 | e name as the na |
+| 6D 65 0A 65 72 72 6F 72 20 69 73 20 63 61 75 67 | me.error is caug |
+| 68 74 20 66 69 72 73 74 2E 0A 40 70 20 6D 61 78 | ht first..@p max |
+| 69 6D 75 6D 5F 69 6E 70 75 74 5F 6C 69 6E 65 5F | imum_input_line_ |
+| 6C 65 6E 67 74 68 20 3D 20 69 6E 66 69 6E 69 74 | length = infinit |
+| 79 0A 40 4F 40 3C 31 32 33 34 35 36 37 38 39 30 | y.@O@<1234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 40 3E 40 7B 40 7D 0A 40 41 40 | 567890@>@{@}.@A@ |
+| 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 | <Error recovery |
+| 70 6F 69 6E 74 40 3E 0A 0A 34 2E 20 46 69 6C 65 | point@>..4. File |
+| 20 6D 61 63 72 6F 20 68 61 73 20 7A 65 72 6F 20 | macro has zero |
+| 6F 72 20 6D 61 6E 79 20 61 74 74 72 69 62 75 74 | or many attribut |
+| 65 73 2E 20 45 72 72 6F 72 2E 0A 40 4F 40 3C 53 | es. Error..@O@<S |
+| 6C 6F 74 68 20 33 40 3E 40 5A 40 7B 57 61 6C 72 | loth 3@>@Z@{Walr |
+| 75 73 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 | us@}.@A@<Error r |
+| 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A | ecovery point@>. |
+| 0A 40 4F 40 3C 53 6C 6F 74 68 20 34 40 3E 40 4D | .@O@<Sloth 4@>@M |
+| 40 7B 57 61 6C 72 75 73 40 7D 0A 40 41 40 3C 45 | @{Walrus@}.@A@<E |
+| 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 70 6F | rror recovery po |
+| 69 6E 74 40 3E 0A 0A 40 4F 40 3C 53 6C 6F 74 68 | int@>..@O@<Sloth |
+| 20 35 40 3E 40 5A 40 4D 40 7B 57 61 6C 72 75 73 | 5@>@Z@M@{Walrus |
+| 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 | @}.@A@<Error rec |
+| 6F 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 35 | overy point@>..5 |
+| 2E 20 50 72 65 76 69 6F 75 73 20 64 65 66 69 6E | . Previous defin |
+| 69 74 69 6F 6E 20 69 73 20 66 75 6C 6C 2C 20 63 | ition is full, c |
+| 75 72 72 65 6E 74 20 69 73 20 61 64 64 69 74 69 | urrent is additi |
+| 76 65 2E 0A 40 24 40 3C 57 61 6C 72 75 73 20 31 | ve..@$@<Walrus 1 |
+| 40 3E 3D 3D 40 7B 53 6C 6F 74 68 40 7D 0A 40 24 | @>==@{Sloth@}.@$ |
+| 40 3C 57 61 6C 72 75 73 20 31 40 3E 2B 3D 40 7B | @<Walrus 1@>+=@{ |
+| 41 61 72 64 76 61 72 6B 40 7D 0A 40 41 40 3C 45 | Aardvark@}.@A@<E |
+| 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 70 6F | rror recovery po |
+| 69 6E 74 40 3E 0A 0A 36 2E 20 50 72 65 76 69 6F | int@>..6. Previo |
+| 75 73 20 64 65 66 69 6E 69 74 69 6F 6E 20 69 73 | us definition is |
+| 20 61 64 64 69 74 69 76 65 2C 20 63 75 72 72 65 | additive, curre |
+| 6E 74 20 69 73 20 66 75 6C 6C 2E 0A 40 24 40 3C | nt is full..@$@< |
+| 57 61 6C 72 75 73 20 32 40 3E 2B 3D 40 7B 53 6C | Walrus 2@>+=@{Sl |
+| 6F 74 68 40 7D 0A 40 24 40 3C 57 61 6C 72 75 73 | oth@}.@$@<Walrus |
+| 20 32 40 3E 3D 3D 40 7B 41 61 72 64 76 61 72 6B | 2@>==@{Aardvark |
+| 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 | @}.@A@<Error rec |
+| 6F 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 37 | overy point@>..7 |
+| 2E 20 4E 6F 6E 2D 66 69 72 73 74 20 62 6F 64 79 | . Non-first body |
+| 20 70 61 72 74 20 6F 66 20 70 61 72 74 69 61 6C | part of partial |
+| 20 68 61 73 20 70 61 72 61 6D 65 74 65 72 2E 0A | has parameter.. |
+| 40 24 40 3C 55 6E 69 63 6F 72 6E 40 3E 40 28 40 | @$@<Unicorn@>@(@ |
+| 33 40 29 2B 3D 40 7B 54 75 72 6B 65 79 40 7D 0A | 3@)+=@{Turkey@}. |
+| 40 24 40 3C 55 6E 69 63 6F 72 6E 40 3E 40 28 40 | @$@<Unicorn@>@(@ |
+| 33 40 29 2B 3D 40 7B 54 75 72 6B 65 79 40 7D 0A | 3@)+=@{Turkey@}. |
+| 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 | @A@<Error recove |
+| 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 38 2E 20 5A | ry point@>..8. Z |
+| 65 72 6F 20 6F 72 20 6D 61 6E 79 20 61 74 74 72 | ero or many attr |
+| 69 62 75 74 65 73 20 6F 6E 20 6E 6F 6E 2D 66 69 | ibutes on non-fi |
+| 72 73 74 20 62 6F 64 79 20 70 61 72 74 20 6F 66 | rst body part of |
+| 20 61 64 64 69 74 69 76 65 2E 0A 40 24 40 3C 45 | additive..@$@<E |
+| 6C 65 70 68 61 6E 74 40 3E 40 5A 40 4D 2B 3D 40 | lephant@>@Z@M+=@ |
+| 7B 54 75 72 6B 65 79 40 7D 0A 40 24 40 3C 45 6C | {Turkey@}.@$@<El |
+| 65 70 68 61 6E 74 40 3E 40 5A 40 4D 2B 3D 40 7B | ephant@>@Z@M+=@{ |
+| 54 75 72 6B 65 79 40 7D 0A 40 41 40 3C 45 72 72 | Turkey@}.@A@<Err |
+| 6F 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E | or recovery poin |
+| 74 40 3E 0A 0A 39 2E 20 43 68 65 63 6B 20 74 68 | t@>..9. Check th |
+| 61 74 20 6E 6F 6E 2D 65 78 69 73 74 65 6E 74 20 | at non-existent |
+| 66 6F 72 6D 61 6C 20 70 61 72 61 6D 65 74 65 72 | formal parameter |
+| 73 20 61 72 65 20 63 61 75 67 68 74 2E 0A 0A 40 | s are caught...@ |
+| 24 40 3C 5A 65 72 6F 40 3E 40 5A 40 7B 53 6C 6F | $@<Zero@>@Z@{Slo |
+| 74 68 40 31 57 61 6C 72 75 73 40 7D 0A 40 41 40 | th@1Walrus@}.@A@ |
+| 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 | <Error recovery |
+| 70 6F 69 6E 74 40 3E 0A 0A 40 24 40 3C 4F 6E 65 | point@>..@$@<One |
+| 40 3E 40 28 40 31 40 29 40 5A 40 7B 53 6C 6F 74 | @>@(@1@)@Z@{Slot |
+| 68 40 32 57 61 6C 72 75 73 40 7D 0A 40 41 40 3C | h@2Walrus@}.@A@< |
+| 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 70 | Error recovery p |
+| 6F 69 6E 74 40 3E 0A 0A 40 24 40 3C 4D 61 6E 79 | oint@>..@$@<Many |
+| 40 3E 40 28 40 37 40 29 40 5A 40 7B 53 6C 6F 74 | @>@(@7@)@Z@{Slot |
+| 68 40 38 57 61 6C 72 75 73 40 7D 0A 40 41 40 3C | h@8Walrus@}.@A@< |
+| 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 70 | Error recovery p |
+| 6F 69 6E 74 40 3E 0A | oint@>. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR08: Test semantic checking of macro definitions.<010>
+00002 00002| <010>
+00003 00003| Trip parser to be sure that we won't get any output files!<010>
+00004 00004| @><010>
+00005 00005| <010>
+00006 00006| 1. File macro has parameters. Error.<010>
+00007 00007| @O@<Sloth 1@>@(@3@)@{Walrus@}<010>
+00008 00008| @A@<Error recovery point@><010>
+00009 00009| <010>
+00010 00010| 2. File macro is additive. Error.<010>
+00011 00011| @O@<Sloth 2@>+=@{Walrus@}<010>
+00012 00012| @A@<Error recovery point@><010>
+00013 00013| <010>
+00014 00014| 3. File macro has too long a name. The test name has 1200 characters. Err.<010>
+00015 00015| Note: This test can't test the error message if the maximum length of a<010>
+00016 00016| macro name is less than the maximum length of a file name as the name<010>
+00017 00017| error is caught first.<010>
+00018 00018| @p maximum_input_line_length = infinity<010>
+00019 00019| @O@<123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890@>@{@}<010>
+00020 00020| @A@<Error recovery point@><010>
+00021 00021| <010>
+00022 00022| 4. File macro has zero or many attributes. Error.<010>
+00023 00023| @O@<Sloth 3@>@Z@{Walrus@}<010>
+00024 00024| @A@<Error recovery point@><010>
+00025 00025| <010>
+00026 00026| @O@<Sloth 4@>@M@{Walrus@}<010>
+00027 00027| @A@<Error recovery point@><010>
+00028 00028| <010>
+00029 00029| @O@<Sloth 5@>@Z@M@{Walrus@}<010>
+00030 00030| @A@<Error recovery point@><010>
+00031 00031| <010>
+00032 00032| 5. Previous definition is full, current is additive.<010>
+00033 00033| @$@<Walrus 1@>==@{Sloth@}<010>
+00034 00034| @$@<Walrus 1@>+=@{Aardvark@}<010>
+00035 00035| @A@<Error recovery point@><010>
+00036 00036| <010>
+00037 00037| 6. Previous definition is additive, current is full.<010>
+00038 00038| @$@<Walrus 2@>+=@{Sloth@}<010>
+00039 00039| @$@<Walrus 2@>==@{Aardvark@}<010>
+00040 00040| @A@<Error recovery point@><010>
+00041 00041| <010>
+00042 00042| 7. Non-first body part of partial has parameter.<010>
+00043 00043| @$@<Unicorn@>@(@3@)+=@{Turkey@}<010>
+00044 00044| @$@<Unicorn@>@(@3@)+=@{Turkey@}<010>
+00045 00045| @A@<Error recovery point@><010>
+00046 00046| <010>
+00047 00047| 8. Zero or many attributes on non-first body part of additive.<010>
+00048 00048| @$@<Elephant@>@Z@M+=@{Turkey@}<010>
+00049 00049| @$@<Elephant@>@Z@M+=@{Turkey@}<010>
+00050 00050| @A@<Error recovery point@><010>
+00051 00051| <010>
+00052 00052| 9. Check that non-existent formal parameters are caught.<010>
+00053 00053| <010>
+00054 00054| @$@<Zero@>@Z@{Sloth@1Walrus@}<010>
+00055 00055| @A@<Error recovery point@><010>
+00056 00056| <010>
+00057 00057| @$@<One@>@(@1@)@Z@{Sloth@2Walrus@}<010>
+00058 00058| @A@<Error recovery point@><010>
+00059 00059| <010>
+00060 00060| @$@<Many@>@(@7@)@Z@{Sloth@8Walrus@}<010>
+00061 00061| @A@<Error recovery point@><010>
+00062 00062| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 245 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR08: Test semantic checking of macro definitions.<010>
+<010>
+Trip parser to be sure that we won't get any output files!<010>
+"
+0004[01]: @> Close name.
+0004[03]: Text. Text scrap[Grey]="<010>
+<010>
+1. File macro has parameters. Error.<010>
+"
+0007[01]: @F File defn.
+0007[03]: @< Open name.
+0007[05]: Text. Text scrap[Grey]="Sloth 1"
+0007[12]: @> Close name.
+0007[14]: @( Open param.
+0007[16]: @n Parameter. Parameterno=3.
+0007[18]: @} Close param.
+0007[20]: @{ Open defn.
+0007[22]: Text. Text scrap[Grey]="Walrus"
+0007[28]: @} Close defn.
+0007[30]: Text. Text scrap[White]="<010>
+"
+0008[01]: @A New section (Level 1).
+0008[03]: @< Open name.
+0008[05]: Text. Text scrap[Grey]="Error recovery point"
+0008[25]: @> Close name.
+0008[27]: Text. Text scrap[Grey]="<010>
+<010>
+2. File macro is additive. Error.<010>
+"
+0011[01]: @F File defn.
+0011[03]: @< Open name.
+0011[05]: Text. Text scrap[Grey]="Sloth 2"
+0011[12]: @> Close name.
+0011[14]: Text. Text scrap[Grey]="+="
+0011[16]: @{ Open defn.
+0011[18]: Text. Text scrap[Grey]="Walrus"
+0011[24]: @} Close defn.
+0011[26]: Text. Text scrap[White]="<010>
+"
+0012[01]: @A New section (Level 1).
+0012[03]: @< Open name.
+0012[05]: Text. Text scrap[Grey]="Error recovery point"
+0012[25]: @> Close name.
+0012[27]: Text. Text scrap[Grey]="<010>
+<010>
+3. File macro has too long a name. The test name has 1200 characters. Err.<010>
+Note: This test can't test the error message if the maximum length of a<010>
+macro name is less than the maximum length of a file name as the name<010>
+error is caught first.<010>
+"
+0019[01]: @F File defn.
+0019[03]: @< Open name.
+0019[05]: Text. Text scrap[Grey]="123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
+0019[1205]: @> Close name.
+0019[1207]: @{ Open defn.
+0019[1209]: @} Close defn.
+0019[1211]: Text. Text scrap[White]="<010>
+"
+0020[01]: @A New section (Level 1).
+0020[03]: @< Open name.
+0020[05]: Text. Text scrap[Grey]="Error recovery point"
+0020[25]: @> Close name.
+0020[27]: Text. Text scrap[Grey]="<010>
+<010>
+4. File macro has zero or many attributes. Error.<010>
+"
+0023[01]: @F File defn.
+0023[03]: @< Open name.
+0023[05]: Text. Text scrap[Grey]="Sloth 3"
+0023[12]: @> Close name.
+0023[14]: @Z Zero calls.
+0023[16]: @{ Open defn.
+0023[18]: Text. Text scrap[Grey]="Walrus"
+0023[24]: @} Close defn.
+0023[26]: Text. Text scrap[White]="<010>
+"
+0024[01]: @A New section (Level 1).
+0024[03]: @< Open name.
+0024[05]: Text. Text scrap[Grey]="Error recovery point"
+0024[25]: @> Close name.
+0024[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0026[01]: @F File defn.
+0026[03]: @< Open name.
+0026[05]: Text. Text scrap[Grey]="Sloth 4"
+0026[12]: @> Close name.
+0026[14]: @M Many calls.
+0026[16]: @{ Open defn.
+0026[18]: Text. Text scrap[Grey]="Walrus"
+0026[24]: @} Close defn.
+0026[26]: Text. Text scrap[White]="<010>
+"
+0027[01]: @A New section (Level 1).
+0027[03]: @< Open name.
+0027[05]: Text. Text scrap[Grey]="Error recovery point"
+0027[25]: @> Close name.
+0027[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0029[01]: @F File defn.
+0029[03]: @< Open name.
+0029[05]: Text. Text scrap[Grey]="Sloth 5"
+0029[12]: @> Close name.
+0029[14]: @Z Zero calls.
+0029[16]: @M Many calls.
+0029[18]: @{ Open defn.
+0029[20]: Text. Text scrap[Grey]="Walrus"
+0029[26]: @} Close defn.
+0029[28]: Text. Text scrap[White]="<010>
+"
+0030[01]: @A New section (Level 1).
+0030[03]: @< Open name.
+0030[05]: Text. Text scrap[Grey]="Error recovery point"
+0030[25]: @> Close name.
+0030[27]: Text. Text scrap[Grey]="<010>
+<010>
+5. Previous definition is full, current is additive.<010>
+"
+0033[01]: @$ Macro defn.
+0033[03]: @< Open name.
+0033[05]: Text. Text scrap[Grey]="Walrus 1"
+0033[13]: @> Close name.
+0033[15]: Text. Text scrap[Grey]="=="
+0033[17]: @{ Open defn.
+0033[19]: Text. Text scrap[Grey]="Sloth"
+0033[24]: @} Close defn.
+0033[26]: Text. Text scrap[White]="<010>
+"
+0034[01]: @$ Macro defn.
+0034[03]: @< Open name.
+0034[05]: Text. Text scrap[Grey]="Walrus 1"
+0034[13]: @> Close name.
+0034[15]: Text. Text scrap[Grey]="+="
+0034[17]: @{ Open defn.
+0034[19]: Text. Text scrap[Grey]="Aardvark"
+0034[27]: @} Close defn.
+0034[29]: Text. Text scrap[White]="<010>
+"
+0035[01]: @A New section (Level 1).
+0035[03]: @< Open name.
+0035[05]: Text. Text scrap[Grey]="Error recovery point"
+0035[25]: @> Close name.
+0035[27]: Text. Text scrap[Grey]="<010>
+<010>
+6. Previous definition is additive, current is full.<010>
+"
+0038[01]: @$ Macro defn.
+0038[03]: @< Open name.
+0038[05]: Text. Text scrap[Grey]="Walrus 2"
+0038[13]: @> Close name.
+0038[15]: Text. Text scrap[Grey]="+="
+0038[17]: @{ Open defn.
+0038[19]: Text. Text scrap[Grey]="Sloth"
+0038[24]: @} Close defn.
+0038[26]: Text. Text scrap[White]="<010>
+"
+0039[01]: @$ Macro defn.
+0039[03]: @< Open name.
+0039[05]: Text. Text scrap[Grey]="Walrus 2"
+0039[13]: @> Close name.
+0039[15]: Text. Text scrap[Grey]="=="
+0039[17]: @{ Open defn.
+0039[19]: Text. Text scrap[Grey]="Aardvark"
+0039[27]: @} Close defn.
+0039[29]: Text. Text scrap[White]="<010>
+"
+0040[01]: @A New section (Level 1).
+0040[03]: @< Open name.
+0040[05]: Text. Text scrap[Grey]="Error recovery point"
+0040[25]: @> Close name.
+0040[27]: Text. Text scrap[Grey]="<010>
+<010>
+7. Non-first body part of partial has parameter.<010>
+"
+0043[01]: @$ Macro defn.
+0043[03]: @< Open name.
+0043[05]: Text. Text scrap[Grey]="Unicorn"
+0043[12]: @> Close name.
+0043[14]: @( Open param.
+0043[16]: @n Parameter. Parameterno=3.
+0043[18]: @} Close param.
+0043[20]: Text. Text scrap[Grey]="+="
+0043[22]: @{ Open defn.
+0043[24]: Text. Text scrap[Grey]="Turkey"
+0043[30]: @} Close defn.
+0043[32]: Text. Text scrap[White]="<010>
+"
+0044[01]: @$ Macro defn.
+0044[03]: @< Open name.
+0044[05]: Text. Text scrap[Grey]="Unicorn"
+0044[12]: @> Close name.
+0044[14]: @( Open param.
+0044[16]: @n Parameter. Parameterno=3.
+0044[18]: @} Close param.
+0044[20]: Text. Text scrap[Grey]="+="
+0044[22]: @{ Open defn.
+0044[24]: Text. Text scrap[Grey]="Turkey"
+0044[30]: @} Close defn.
+0044[32]: Text. Text scrap[White]="<010>
+"
+0045[01]: @A New section (Level 1).
+0045[03]: @< Open name.
+0045[05]: Text. Text scrap[Grey]="Error recovery point"
+0045[25]: @> Close name.
+0045[27]: Text. Text scrap[Grey]="<010>
+<010>
+8. Zero or many attributes on non-first body part of additive.<010>
+"
+0048[01]: @$ Macro defn.
+0048[03]: @< Open name.
+0048[05]: Text. Text scrap[Grey]="Elephant"
+0048[13]: @> Close name.
+0048[15]: @Z Zero calls.
+0048[17]: @M Many calls.
+0048[19]: Text. Text scrap[Grey]="+="
+0048[21]: @{ Open defn.
+0048[23]: Text. Text scrap[Grey]="Turkey"
+0048[29]: @} Close defn.
+0048[31]: Text. Text scrap[White]="<010>
+"
+0049[01]: @$ Macro defn.
+0049[03]: @< Open name.
+0049[05]: Text. Text scrap[Grey]="Elephant"
+0049[13]: @> Close name.
+0049[15]: @Z Zero calls.
+0049[17]: @M Many calls.
+0049[19]: Text. Text scrap[Grey]="+="
+0049[21]: @{ Open defn.
+0049[23]: Text. Text scrap[Grey]="Turkey"
+0049[29]: @} Close defn.
+0049[31]: Text. Text scrap[White]="<010>
+"
+0050[01]: @A New section (Level 1).
+0050[03]: @< Open name.
+0050[05]: Text. Text scrap[Grey]="Error recovery point"
+0050[25]: @> Close name.
+0050[27]: Text. Text scrap[Grey]="<010>
+<010>
+9. Check that non-existent formal parameters are caught.<010>
+<010>
+"
+0054[01]: @$ Macro defn.
+0054[03]: @< Open name.
+0054[05]: Text. Text scrap[Grey]="Zero"
+0054[09]: @> Close name.
+0054[11]: @Z Zero calls.
+0054[13]: @{ Open defn.
+0054[15]: Text. Text scrap[Grey]="Sloth"
+0054[20]: @n Parameter. Parameterno=1.
+0054[22]: Text. Text scrap[Grey]="Walrus"
+0054[28]: @} Close defn.
+0054[30]: Text. Text scrap[White]="<010>
+"
+0055[01]: @A New section (Level 1).
+0055[03]: @< Open name.
+0055[05]: Text. Text scrap[Grey]="Error recovery point"
+0055[25]: @> Close name.
+0055[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0057[01]: @$ Macro defn.
+0057[03]: @< Open name.
+0057[05]: Text. Text scrap[Grey]="One"
+0057[08]: @> Close name.
+0057[10]: @( Open param.
+0057[12]: @n Parameter. Parameterno=1.
+0057[14]: @} Close param.
+0057[16]: @Z Zero calls.
+0057[18]: @{ Open defn.
+0057[20]: Text. Text scrap[Grey]="Sloth"
+0057[25]: @n Parameter. Parameterno=2.
+0057[27]: Text. Text scrap[Grey]="Walrus"
+0057[33]: @} Close defn.
+0057[35]: Text. Text scrap[White]="<010>
+"
+0058[01]: @A New section (Level 1).
+0058[03]: @< Open name.
+0058[05]: Text. Text scrap[Grey]="Error recovery point"
+0058[25]: @> Close name.
+0058[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0060[01]: @$ Macro defn.
+0060[03]: @< Open name.
+0060[05]: Text. Text scrap[Grey]="Many"
+0060[09]: @> Close name.
+0060[11]: @( Open param.
+0060[13]: @n Parameter. Parameterno=7.
+0060[15]: @} Close param.
+0060[17]: @Z Zero calls.
+0060[19]: @{ Open defn.
+0060[21]: Text. Text scrap[Grey]="Sloth"
+0060[26]: @n Parameter. Parameterno=8.
+0060[28]: Text. Text scrap[Grey]="Walrus"
+0060[34]: @} Close defn.
+0060[36]: Text. Text scrap[White]="<010>
+"
+0061[01]: @A New section (Level 1).
+0061[03]: @< Open name.
+0061[05]: Text. Text scrap[Grey]="Error recovery point"
+0061[25]: @> Close name.
+0061[27]: Text. Text scrap[White]="<010>
+"
+0062[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#file"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#line"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#timestamp"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Elephant"
+Defined? : Yes.
+Parameters : 0
+Additive? : Yes.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=4, Pos(L,C)=(48,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Turkey"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Many"
+Defined? : Yes.
+Parameters : 7
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=7, Pos(L,C)=(60,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Sloth"
+------ End Text Element ------
+
+
+-- Start Parameter Element --
+Parameter number=8.
+Parameter is of macro "Many".
+--- End Parameter Element ---
+
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "One"
+Defined? : Yes.
+Parameters : 1
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=6, Pos(L,C)=(57,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Sloth"
+------ End Text Element ------
+
+
+-- Start Parameter Element --
+Parameter number=2.
+Parameter is of macro "One".
+--- End Parameter Element ---
+
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth 1"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth 2"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth 3"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth 4"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth 5"
+Defined? : No.
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Unicorn"
+Defined? : Yes.
+Parameters : 3
+Additive? : Yes.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=3, Pos(L,C)=(43,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Turkey"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Walrus 1"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=1, Pos(L,C)=(33,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Sloth"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Walrus 2"
+Defined? : Yes.
+Parameters : 0
+Additive? : Yes.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=2, Pos(L,C)=(38,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Sloth"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Zero"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=5, Pos(L,C)=(54,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Sloth"
+------ End Text Element ------
+
+
+-- Start Parameter Element --
+Parameter number=1.
+Parameter is of macro "Zero".
+--- End Parameter Element ---
+
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR08: Test semantic checking of macro definitions.<010>
+<010>
+Trip parser to be sure that we won't get any output files!<010>
+"
+--- End of Text Scrap List ---
+
+
+TEXT COMPONENT: Pos(L,C)=(4,3).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+1. File macro has parameters. Error.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(8,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+2. File macro is additive. Error.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(12,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+3. File macro has too long a name. The test name has 1200 characters. Err.<010>
+Note: This test can't test the error message if the maximum length of a<010>
+macro name is less than the maximum length of a file name as the name<010>
+error is caught first.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "3", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(20,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+4. File macro has zero or many attributes. Error.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(24,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "5", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(27,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "6", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(30,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+5. Previous definition is full, current is additive.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(33,1).
+Part 1 of macro @<Walrus 1@>.
+
+TEXT COMPONENT: Pos(L,C)=(33,26).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "7", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(35,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+6. Previous definition is additive, current is full.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(38,1).
+Part 1 of macro @<Walrus 2@>.
+
+TEXT COMPONENT: Pos(L,C)=(38,26).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "8", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(40,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+7. Non-first body part of partial has parameter.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(43,1).
+Part 1 of macro @<Unicorn@>.
+
+TEXT COMPONENT: Pos(L,C)=(43,32).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "9", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(45,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+8. Zero or many attributes on non-first body part of additive.<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(48,1).
+Part 1 of macro @<Elephant@>.
+
+TEXT COMPONENT: Pos(L,C)=(48,31).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "10", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(50,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+9. Check that non-existent formal parameters are caught.<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(54,1).
+Part 1 of macro @<Zero@>.
+
+TEXT COMPONENT: Pos(L,C)=(54,30).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "11", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(55,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(57,1).
+Part 1 of macro @<One@>.
+
+TEXT COMPONENT: Pos(L,C)=(57,35).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "12", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(58,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(60,1).
+Part 1 of macro @<Many@>.
+
+TEXT COMPONENT: Pos(L,C)=(60,36).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "13", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(61,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| PR08: Test semantic checking of macro definitions.
+ 2 2|
+ 3 3| Trip parser to be sure that we won't get any output files!
+ 4 4| @>
+ Error|.^The parser was at the top level and was expecting
+ |.^one of: {Directive, Text, Macro definition, EOF}.
+ 5 5|
+ 6 6| 1. File macro has parameters. Error.
+ 7 7| @O@<Sloth 1@>@(@3@)@{Walrus@}
+ |...^Macro definition ignored.
+ Error|................^Macros attached to output files cannot be parameterized.
+ |................^Reason: No actual parameters would be available during
+ |................^ output file generation.
+ |....................^Skipping after error to the next major construct...
+ 8 8| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 9 9|
+ 10 10| 2. File macro is additive. Error.
+ 11 11| @O@<Sloth 2@>+=@{Walrus@}
+ |...^Macro definition ignored.
+ Error|..............^Macros attached to output files cannot be additive.
+ |..............^Reason: Preventing this makes it easy to find output
+ |..............^file macros later, because there will be exactly one
+ |..............^@O declaration in the input file for each output file.
+ |..............^To do what you are trying to do, just create an additive
+ |..............^bridging macro, like this:
+ |..............^ @O@<prog.c@>@{@<Bridge@>@}
+ |..............^ @$@<Bridge@>+=@{void stringhack()...@}
+ |..............^ @$@<Bridge@>+=@{main()...@}
+ |................^Skipping after error to the next major construct...
+ 12 12| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 13 13|
+ 14 14| 3. File macro has too long a name. The test name has 1200 characters. Err.
+ 15 15| Note: This test can't test the error message if the maximum length of a
+ 16 16| macro name is less than the maximum length of a file name as the name
+ 17 17| error is caught first.
+ 18 18| @p maximum_input_line_length = infinity
+ 19 19| @O@<123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890@>@{@}
+ Error|.....^Name is too long.
+ |.....^The maximum length of a legal name is 80 characters.
+ |.....^Skipping after error to the next major construct...
+ 20 20| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 21 21|
+ 22 22| 4. File macro has zero or many attributes. Error.
+ 23 23| @O@<Sloth 3@>@Z@{Walrus@}
+ |...^Macro definition ignored.
+ Error|..............^Macros attached to output files cannot have @Z or @M.
+ |..............^Reason: They are always called once to generate their
+ |..............^output file and they cannot be called from other macros.
+ |..............^Hence they are always called exactly once and so there
+ |..............^can be no need for @Z or @M in their declarations.
+ |................^Skipping after error to the next major construct...
+ 24 24| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 25 25|
+ 26 26| @O@<Sloth 4@>@M@{Walrus@}
+ |...^Macro definition ignored.
+ Error|..............^Macros attached to output files cannot have @Z or @M.
+ |..............^Reason: They are always called once to generate their
+ |..............^output file and they cannot be called from other macros.
+ |..............^Hence they are always called exactly once and so there
+ |..............^can be no need for @Z or @M in their declarations.
+ |................^Skipping after error to the next major construct...
+ 27 27| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 28 28|
+ 29 29| @O@<Sloth 5@>@Z@M@{Walrus@}
+ |...^Macro definition ignored.
+ Error|..............^Macros attached to output files cannot have @Z or @M.
+ |..............^Reason: They are always called once to generate their
+ |..............^output file and they cannot be called from other macros.
+ |..............^Hence they are always called exactly once and so there
+ |..............^can be no need for @Z or @M in their declarations.
+ |..................^Skipping after error to the next major construct...
+ 30 30| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 31 31|
+ 32 32| 5. Previous definition is full, current is additive.
+ 33 33| @$@<Walrus 1@>==@{Sloth@}
+ 34 34| @$@<Walrus 1@>+=@{Aardvark@}
+ Error|...^A full definition of this macro appears at line 33.
+ |...^Full and additive definitions of the same macro cannot coexist.
+ |...^Macro definition ignored.
+ |.................^Skipping after error to the next major construct...
+ 35 35| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 36 36|
+ 37 37| 6. Previous definition is additive, current is full.
+ 38 38| @$@<Walrus 2@>+=@{Sloth@}
+ 39 39| @$@<Walrus 2@>==@{Aardvark@}
+ Error|...^An additive definition of this macro appears at line 38.
+ |...^Full and additive definitions of the same macro cannot coexist.
+ |...^Macro definition ignored.
+ |.................^Skipping after error to the next major construct...
+ 40 40| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 41 41|
+ 42 42| 7. Non-first body part of partial has parameter.
+ 43 43| @$@<Unicorn@>@(@3@)+=@{Turkey@}
+ 44 44| @$@<Unicorn@>@(@3@)+=@{Turkey@}
+ |...^Macro definition ignored.
+ Error|................^The formal parameter list of an additive macro
+ |................^must be placed only in the first definition part.
+ |................^The first part of this macro appears at line 43.
+ |......................^Skipping after error to the next major construct...
+ 45 45| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 46 46|
+ 47 47| 8. Zero or many attributes on non-first body part of additive.
+ 48 48| @$@<Elephant@>@Z@M+=@{Turkey@}
+ 49 49| @$@<Elephant@>@Z@M+=@{Turkey@}
+ |...^Macro definition ignored.
+ Error|...............^@Z and @M modifiers for additive macros must
+ |...............^be placed only in the first definition part.
+ |...............^The first part of this macro appears at line 48.
+ |.....................^Skipping after error to the next major construct...
+ 50 50| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 51 51|
+ 52 52| 9. Check that non-existent formal parameters are caught.
+ 53 53|
+ 54 54| @$@<Zero@>@Z@{Sloth@1Walrus@}
+ Error|....................^Macro being defined has only 0 parameters.
+ 55 55| @A@<Error recovery point@>
+ 56 56|
+ 57 57| @$@<One@>@(@1@)@Z@{Sloth@2Walrus@}
+ Error|.........................^Macro being defined has only 1 parameter.
+ 58 58| @A@<Error recovery point@>
+ 59 59|
+ 60 60| @$@<Many@>@(@7@)@Z@{Sloth@8Walrus@}
+ Error|..........................^Macro being defined has only 7 parameters.
+ 61 61| @A@<Error recovery point@>
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 14 Errors.
diff --git a/web/funnelAC/results/pr09.lis b/web/funnelAC/results/pr09.lis
new file mode 100644
index 0000000000..1b42ee5601
--- /dev/null
+++ b/web/funnelAC/results/pr09.lis
@@ -0,0 +1,2234 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 30 39 3A 20 54 65 73 74 20 63 61 6C 6C 73 | PR09: Test calls |
+| 20 61 6E 64 20 61 63 74 75 61 6C 20 70 61 72 61 | and actual para |
+| 6D 65 74 65 72 20 6C 69 73 74 73 2E 0A 0A 46 69 | meter lists...Fi |
+| 72 73 74 20 74 72 69 70 20 75 70 20 74 68 65 20 | rst trip up the |
+| 70 61 72 73 65 72 20 73 6F 20 77 65 20 64 6F 6E | parser so we don |
+| 27 74 20 67 65 74 20 61 6E 79 20 66 75 72 74 68 | 't get any furth |
+| 65 72 2E 0A 40 3E 0A 0A 4E 6F 77 20 64 65 66 69 | er..@>..Now defi |
+| 6E 65 20 73 6F 6D 65 20 6D 61 63 72 6F 73 20 74 | ne some macros t |
+| 6F 20 63 61 6C 6C 2E 20 4E 6F 20 65 72 72 6F 72 | o call. No error |
+| 2E 0A 0A 40 24 40 3C 5A 65 72 6F 40 3E 40 7B 40 | ...@$@<Zero@>@{@ |
+| 7D 0A 40 24 40 3C 4F 6E 65 40 3E 40 28 40 31 40 | }.@$@<One@>@(@1@ |
+| 29 40 7B 40 7D 0A 40 24 40 3C 54 77 6F 40 3E 40 | )@{@}.@$@<Two@>@ |
+| 28 40 32 40 29 40 7B 40 7D 0A 40 24 40 3C 54 68 | (@2@)@{@}.@$@<Th |
+| 72 65 65 40 3E 40 28 40 33 40 29 40 7B 40 7D 0A | ree@>@(@3@)@{@}. |
+| 40 24 40 3C 4E 69 6E 65 40 3E 40 28 40 39 40 29 | @$@<Nine@>@(@9@) |
+| 40 7B 40 7D 0A 40 24 40 23 22 40 7B 40 7D 0A 0A | @{@}.@$@#"@{@}.. |
+| 54 68 65 20 66 6F 6C 6C 6F 77 69 6E 67 20 74 65 | The following te |
+| 73 74 20 63 61 6C 6C 73 20 73 68 6F 75 6C 64 20 | st calls should |
+| 4E 4F 54 20 67 65 6E 65 72 61 74 65 20 61 6E 79 | NOT generate any |
+| 20 65 72 72 6F 72 73 2E 0A 0A 40 24 40 3C 4D 61 | errors...@$@<Ma |
+| 63 72 6F 20 63 6F 6E 74 61 69 6E 69 6E 67 20 74 | cro containing t |
+| 68 65 20 74 65 73 74 20 6D 61 63 72 6F 20 63 61 | he test macro ca |
+| 6C 6C 73 2E 40 3E 3D 3D 40 7B 0A 31 2E 20 54 65 | lls.@>==@{.1. Te |
+| 73 74 20 6D 61 63 72 6F 20 63 61 6C 6C 20 77 69 | st macro call wi |
+| 74 68 20 6E 6F 20 70 61 72 61 6D 65 74 65 72 20 | th no parameter |
+| 6C 69 73 74 2E 0A 40 3C 5A 65 72 6F 40 3E 0A 0A | list..@<Zero@>.. |
+| 32 2E 20 54 65 73 74 20 6D 61 63 72 6F 20 63 61 | 2. Test macro ca |
+| 6C 6C 20 77 69 74 68 20 71 75 69 63 6B 20 6E 61 | ll with quick na |
+| 6D 65 2E 0A 40 23 22 0A 0A 33 2E 20 54 65 73 74 | me..@#"..3. Test |
+| 20 6D 61 63 72 6F 20 63 61 6C 6C 20 77 69 74 68 | macro call with |
+| 20 6F 6E 65 20 70 61 72 61 6D 65 74 65 72 2E 0A | one parameter.. |
+| 40 3C 4F 6E 65 40 3E 40 28 54 6F 75 63 61 6E 40 | @<One@>@(Toucan@ |
+| 29 0A 0A 34 2E 20 54 65 73 74 20 6D 61 63 72 6F | )..4. Test macro |
+| 20 63 61 6C 6C 20 77 69 74 68 20 6D 61 6E 79 20 | call with many |
+| 70 61 72 61 6D 65 74 65 72 73 2E 0A 40 3C 54 77 | parameters..@<Tw |
+| 6F 40 3E 40 28 54 6F 75 63 61 6E 40 2C 54 65 61 | o@>@(Toucan@,Tea |
+| 70 6F 74 40 29 0A 40 3C 54 68 72 65 65 40 3E 40 | pot@).@<Three@>@ |
+| 28 54 6F 75 63 61 6E 40 2C 54 65 61 70 6F 74 40 | (Toucan@,Teapot@ |
+| 2C 57 61 6C 72 75 73 40 29 0A 40 3C 4E 69 6E 65 | ,Walrus@).@<Nine |
+| 40 3E 40 28 54 6F 75 63 61 6E 40 2C 54 65 61 70 | @>@(Toucan@,Teap |
+| 6F 74 40 2C 57 61 6C 72 75 73 40 2C 0A 20 20 20 | ot@,Walrus@,. |
+| 20 20 20 20 20 20 20 54 6F 75 63 61 6E 40 2C 54 | Toucan@,T |
+| 65 61 70 6F 74 40 2C 57 61 6C 72 75 73 40 2C 0A | eapot@,Walrus@,. |
+| 20 20 20 20 20 20 20 20 20 20 54 6F 75 63 61 6E | Toucan |
+| 40 2C 54 65 61 70 6F 74 40 2C 57 61 6C 72 75 73 | @,Teapot@,Walrus |
+| 40 29 0A 0A 35 2E 20 54 65 73 74 20 6D 61 63 72 | @)..5. Test macr |
+| 6F 20 63 61 6C 6C 73 20 77 69 74 68 20 64 6F 75 | o calls with dou |
+| 62 6C 65 20 71 75 6F 74 65 73 20 6F 6E 20 70 61 | ble quotes on pa |
+| 72 61 6D 65 74 65 72 73 2E 0A 40 3C 4F 6E 65 40 | rameters..@<One@ |
+| 3E 40 28 20 40 22 54 6F 75 63 61 6E 40 22 40 29 | >@( @"Toucan@"@) |
+| 0A 40 3C 54 77 6F 40 3E 40 28 40 22 54 6F 75 63 | .@<Two@>@(@"Touc |
+| 61 6E 40 22 20 20 20 40 2C 20 20 20 40 22 54 65 | an@" @, @"Te |
+| 61 70 6F 74 40 22 40 29 0A 40 3C 54 68 72 65 65 | apot@"@).@<Three |
+| 40 3E 40 28 40 22 54 6F 75 63 61 6E 40 22 20 40 | @>@(@"Toucan@" @ |
+| 2C 0A 20 20 20 20 20 20 20 20 20 20 20 40 22 54 | ,. @"T |
+| 65 61 70 6F 74 40 22 20 40 2C 0A 20 20 20 20 20 | eapot@" @,. |
+| 20 20 20 20 20 20 40 22 57 61 6C 72 75 73 40 22 | @"Walrus@" |
+| 20 40 29 0A 40 3C 4E 69 6E 65 40 3E 40 28 20 40 | @).@<Nine@>@( @ |
+| 22 54 6F 75 63 61 6E 40 22 20 40 2C 20 40 22 54 | "Toucan@" @, @"T |
+| 65 61 70 6F 74 40 22 20 40 2C 20 40 22 57 61 6C | eapot@" @, @"Wal |
+| 72 75 73 40 22 20 40 2C 0A 20 20 20 20 20 20 20 | rus@" @,. |
+| 20 20 20 20 40 22 54 6F 75 63 61 6E 40 22 20 40 | @"Toucan@" @ |
+| 2C 20 40 22 54 65 61 70 6F 74 40 22 20 40 2C 20 | , @"Teapot@" @, |
+| 40 22 57 61 6C 72 75 73 40 22 20 40 2C 0A 20 20 | @"Walrus@" @,. |
+| 20 20 20 20 20 20 20 20 20 40 22 54 6F 75 63 61 | @"Touca |
+| 6E 40 22 20 40 2C 20 40 22 54 65 61 70 6F 74 40 | n@" @, @"Teapot@ |
+| 22 20 40 2C 20 40 22 57 61 6C 72 75 73 40 22 20 | " @, @"Walrus@" |
+| 40 29 0A 0A 37 2E 20 54 65 73 74 20 6D 61 63 72 | @)..7. Test macr |
+| 6F 20 63 61 6C 6C 73 20 77 69 74 68 20 6D 69 78 | o calls with mix |
+| 65 64 20 64 6F 75 62 6C 65 20 71 75 6F 74 65 73 | ed double quotes |
+| 20 6F 6E 20 70 61 72 61 6D 65 74 65 72 73 2E 0A | on parameters.. |
+| 40 3C 54 77 6F 40 3E 40 28 40 22 54 6F 75 63 61 | @<Two@>@(@"Touca |
+| 6E 40 22 20 20 20 40 2C 54 65 61 70 6F 74 40 29 | n@" @,Teapot@) |
+| 0A 40 3C 54 68 72 65 65 40 3E 40 28 40 22 54 6F | .@<Three@>@(@"To |
+| 75 63 61 6E 40 22 20 40 2C 0A 20 20 20 20 20 20 | ucan@" @,. |
+| 20 20 20 20 20 40 22 54 65 61 70 6F 74 40 22 20 | @"Teapot@" |
+| 40 2C 57 61 6C 72 75 73 40 29 0A 40 3C 4E 69 6E | @,Walrus@).@<Nin |
+| 65 40 3E 40 28 20 40 22 54 6F 75 63 61 6E 40 22 | e@>@( @"Toucan@" |
+| 20 40 2C 20 40 22 54 65 61 70 6F 74 40 22 20 40 | @, @"Teapot@" @ |
+| 2C 20 20 20 57 61 6C 72 75 73 20 20 20 40 2C 0A | , Walrus @,. |
+| 20 20 20 20 20 20 20 20 20 20 20 40 22 54 6F 75 | @"Tou |
+| 63 61 6E 40 22 20 40 2C 20 20 20 54 65 61 70 6F | can@" @, Teapo |
+| 74 20 20 20 40 2C 20 40 22 57 61 6C 72 75 73 40 | t @, @"Walrus@ |
+| 22 20 40 2C 0A 20 20 20 20 20 20 20 20 20 20 20 | " @,. |
+| 40 22 54 6F 75 63 61 6E 40 22 20 40 2C 20 40 22 | @"Toucan@" @, @" |
+| 54 65 61 70 6F 74 40 22 20 40 2C 20 40 22 57 61 | Teapot@" @, @"Wa |
+| 6C 72 75 73 40 22 20 40 29 0A 0A 40 7D 20 40 21 | lrus@" @)..@} @! |
+| 20 45 6E 64 20 6F 66 20 6D 61 63 72 6F 20 64 65 | End of macro de |
+| 66 69 6E 69 74 69 6F 6E 20 65 6E 63 6C 6F 73 69 | finition enclosi |
+| 6E 67 20 61 6C 6C 20 74 68 65 73 65 20 6C 65 67 | ng all these leg |
+| 61 6C 20 74 65 73 74 73 2E 0A 0A 38 2E 20 54 65 | al tests...8. Te |
+| 73 74 20 6D 61 63 72 6F 20 63 61 6C 6C 73 20 77 | st macro calls w |
+| 69 74 68 20 61 20 76 61 72 69 65 74 79 20 6F 66 | ith a variety of |
+| 20 73 79 6E 74 61 78 20 65 72 72 6F 72 73 20 69 | syntax errors i |
+| 6E 20 70 61 72 61 6D 65 74 65 72 20 6C 69 73 74 | n parameter list |
+| 2E 0A 40 24 40 3C 45 72 72 6F 72 31 40 3E 40 7B | ..@$@<Error1@>@{ |
+| 0A 40 3C 5A 65 72 6F 40 3E 40 28 0A 40 7D 0A 40 | .@<Zero@>@(.@}.@ |
+| 41 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 72 | A@<Error recover |
+| 79 20 70 6F 69 6E 74 40 3E 0A 0A 40 24 40 3C 45 | y point@>..@$@<E |
+| 72 72 6F 72 32 40 3E 40 7B 0A 40 3C 5A 65 72 6F | rror2@>@{.@<Zero |
+| 40 3E 40 29 0A 40 7D 0A 40 41 40 3C 45 72 72 6F | @>@).@}.@A@<Erro |
+| 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 | r recovery point |
+| 40 3E 0A 0A 40 24 40 3C 45 72 72 6F 72 33 40 3E | @>..@$@<Error3@> |
+| 40 7B 0A 40 3C 4F 6E 65 40 3E 40 28 40 22 54 6F | @{.@<One@>@(@"To |
+| 75 63 61 6E 40 29 0A 40 7D 0A 40 41 40 3C 45 72 | ucan@).@}.@A@<Er |
+| 72 6F 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 | ror recovery poi |
+| 6E 74 40 3E 0A 0A 40 24 40 3C 45 72 72 6F 72 34 | nt@>..@$@<Error4 |
+| 40 3E 40 7B 0A 40 3C 4F 6E 65 40 3E 40 28 40 22 | @>@{.@<One@>@(@" |
+| 54 6F 75 63 61 6E 40 22 40 22 53 6C 6F 74 68 40 | Toucan@"@"Sloth@ |
+| 22 40 29 0A 40 7D 0A 40 41 40 3C 45 72 72 6F 72 | "@).@}.@A@<Error |
+| 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 40 | recovery point@ |
+| 3E 0A 0A 40 24 40 3C 45 72 72 6F 72 35 40 3E 40 | >..@$@<Error5@>@ |
+| 7B 0A 40 3C 54 77 6F 40 3E 40 28 40 22 54 6F 75 | {.@<Two@>@(@"Tou |
+| 63 61 6E 40 22 54 65 61 70 6F 74 40 29 0A 40 7D | can@"Teapot@).@} |
+| 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 | .@A@<Error recov |
+| 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 40 24 40 | ery point@>..@$@ |
+| 3C 45 72 72 6F 72 36 40 3E 40 7B 0A 40 3C 54 77 | <Error6@>@{.@<Tw |
+| 6F 40 3E 40 28 40 22 54 6F 75 63 61 6E 40 22 54 | o@>@(@"Toucan@"T |
+| 65 61 70 6F 74 0A 40 7D 0A 40 41 40 3C 45 72 72 | eapot.@}.@A@<Err |
+| 6F 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E | or recovery poin |
+| 74 40 3E 0A 0A 40 24 40 3C 45 72 72 6F 72 37 40 | t@>..@$@<Error7@ |
+| 3E 40 7B 0A 40 3C 54 77 6F 40 3E 40 28 40 22 54 | >@{.@<Two@>@(@"T |
+| 6F 75 63 61 6E 40 22 54 65 61 70 6F 74 0A 40 3C | oucan@"Teapot.@< |
+| 54 68 72 65 65 40 3E 40 28 54 6F 75 63 61 6E 40 | Three@>@(Toucan@ |
+| 2C 0A 20 20 20 20 20 20 20 20 20 20 20 40 22 54 | ,. @"T |
+| 65 61 70 6F 74 40 2C 57 61 6C 72 75 73 0A 0A 40 | eapot@,Walrus..@ |
+| 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F | }.@A@<Error reco |
+| 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A | very point@>.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR09: Test calls and actual parameter lists.<010>
+00002 00002| <010>
+00003 00003| First trip up the parser so we don't get any further.<010>
+00004 00004| @><010>
+00005 00005| <010>
+00006 00006| Now define some macros to call. No error.<010>
+00007 00007| <010>
+00008 00008| @$@<Zero@>@{@}<010>
+00009 00009| @$@<One@>@(@1@)@{@}<010>
+00010 00010| @$@<Two@>@(@2@)@{@}<010>
+00011 00011| @$@<Three@>@(@3@)@{@}<010>
+00012 00012| @$@<Nine@>@(@9@)@{@}<010>
+00013 00013| @$@#"@{@}<010>
+00014 00014| <010>
+00015 00015| The following test calls should NOT generate any errors.<010>
+00016 00016| <010>
+00017 00017| @$@<Macro containing the test macro calls.@>==@{<010>
+00018 00018| 1. Test macro call with no parameter list.<010>
+00019 00019| @<Zero@><010>
+00020 00020| <010>
+00021 00021| 2. Test macro call with quick name.<010>
+00022 00022| @#"<010>
+00023 00023| <010>
+00024 00024| 3. Test macro call with one parameter.<010>
+00025 00025| @<One@>@(Toucan@)<010>
+00026 00026| <010>
+00027 00027| 4. Test macro call with many parameters.<010>
+00028 00028| @<Two@>@(Toucan@,Teapot@)<010>
+00029 00029| @<Three@>@(Toucan@,Teapot@,Walrus@)<010>
+00030 00030| @<Nine@>@(Toucan@,Teapot@,Walrus@,<010>
+00031 00031| Toucan@,Teapot@,Walrus@,<010>
+00032 00032| Toucan@,Teapot@,Walrus@)<010>
+00033 00033| <010>
+00034 00034| 5. Test macro calls with double quotes on parameters.<010>
+00035 00035| @<One@>@( @"Toucan@"@)<010>
+00036 00036| @<Two@>@(@"Toucan@" @, @"Teapot@"@)<010>
+00037 00037| @<Three@>@(@"Toucan@" @,<010>
+00038 00038| @"Teapot@" @,<010>
+00039 00039| @"Walrus@" @)<010>
+00040 00040| @<Nine@>@( @"Toucan@" @, @"Teapot@" @, @"Walrus@" @,<010>
+00041 00041| @"Toucan@" @, @"Teapot@" @, @"Walrus@" @,<010>
+00042 00042| @"Toucan@" @, @"Teapot@" @, @"Walrus@" @)<010>
+00043 00043| <010>
+00044 00044| 7. Test macro calls with mixed double quotes on parameters.<010>
+00045 00045| @<Two@>@(@"Toucan@" @,Teapot@)<010>
+00046 00046| @<Three@>@(@"Toucan@" @,<010>
+00047 00047| @"Teapot@" @,Walrus@)<010>
+00048 00048| @<Nine@>@( @"Toucan@" @, @"Teapot@" @, Walrus @,<010>
+00049 00049| @"Toucan@" @, Teapot @, @"Walrus@" @,<010>
+00050 00050| @"Toucan@" @, @"Teapot@" @, @"Walrus@" @)<010>
+00051 00051| <010>
+00052 00052| @} @! End of macro definition enclosing all these legal tests.<010>
+00053 00053| <010>
+00054 00054| 8. Test macro calls with a variety of syntax errors in parameter list.<010>
+00055 00055| @$@<Error1@>@{<010>
+00056 00056| @<Zero@>@(<010>
+00057 00057| @}<010>
+00058 00058| @A@<Error recovery point@><010>
+00059 00059| <010>
+00060 00060| @$@<Error2@>@{<010>
+00061 00061| @<Zero@>@)<010>
+00062 00062| @}<010>
+00063 00063| @A@<Error recovery point@><010>
+00064 00064| <010>
+00065 00065| @$@<Error3@>@{<010>
+00066 00066| @<One@>@(@"Toucan@)<010>
+00067 00067| @}<010>
+00068 00068| @A@<Error recovery point@><010>
+00069 00069| <010>
+00070 00070| @$@<Error4@>@{<010>
+00071 00071| @<One@>@(@"Toucan@"@"Sloth@"@)<010>
+00072 00072| @}<010>
+00073 00073| @A@<Error recovery point@><010>
+00074 00074| <010>
+00075 00075| @$@<Error5@>@{<010>
+00076 00076| @<Two@>@(@"Toucan@"Teapot@)<010>
+00077 00077| @}<010>
+00078 00078| @A@<Error recovery point@><010>
+00079 00079| <010>
+00080 00080| @$@<Error6@>@{<010>
+00081 00081| @<Two@>@(@"Toucan@"Teapot<010>
+00082 00082| @}<010>
+00083 00083| @A@<Error recovery point@><010>
+00084 00084| <010>
+00085 00085| @$@<Error7@>@{<010>
+00086 00086| @<Two@>@(@"Toucan@"Teapot<010>
+00087 00087| @<Three@>@(Toucan@,<010>
+00088 00088| @"Teapot@,Walrus<010>
+00089 00089| <010>
+00090 00090| @}<010>
+00091 00091| @A@<Error recovery point@><010>
+00092 00092| <010>
+00093 00093| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 467 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR09: Test calls and actual parameter lists.<010>
+<010>
+First trip up the parser so we don't get any further.<010>
+"
+0004[01]: @> Close name.
+0004[03]: Text. Text scrap[Grey]="<010>
+<010>
+Now define some macros to call. No error.<010>
+<010>
+"
+0008[01]: @$ Macro defn.
+0008[03]: @< Open name.
+0008[05]: Text. Text scrap[Grey]="Zero"
+0008[09]: @> Close name.
+0008[11]: @{ Open defn.
+0008[13]: @} Close defn.
+0008[15]: Text. Text scrap[White]="<010>
+"
+0009[01]: @$ Macro defn.
+0009[03]: @< Open name.
+0009[05]: Text. Text scrap[Grey]="One"
+0009[08]: @> Close name.
+0009[10]: @( Open param.
+0009[12]: @n Parameter. Parameterno=1.
+0009[14]: @} Close param.
+0009[16]: @{ Open defn.
+0009[18]: @} Close defn.
+0009[20]: Text. Text scrap[White]="<010>
+"
+0010[01]: @$ Macro defn.
+0010[03]: @< Open name.
+0010[05]: Text. Text scrap[Grey]="Two"
+0010[08]: @> Close name.
+0010[10]: @( Open param.
+0010[12]: @n Parameter. Parameterno=2.
+0010[14]: @} Close param.
+0010[16]: @{ Open defn.
+0010[18]: @} Close defn.
+0010[20]: Text. Text scrap[White]="<010>
+"
+0011[01]: @$ Macro defn.
+0011[03]: @< Open name.
+0011[05]: Text. Text scrap[Grey]="Three"
+0011[10]: @> Close name.
+0011[12]: @( Open param.
+0011[14]: @n Parameter. Parameterno=3.
+0011[16]: @} Close param.
+0011[18]: @{ Open defn.
+0011[20]: @} Close defn.
+0011[22]: Text. Text scrap[White]="<010>
+"
+0012[01]: @$ Macro defn.
+0012[03]: @< Open name.
+0012[05]: Text. Text scrap[Grey]="Nine"
+0012[09]: @> Close name.
+0012[11]: @( Open param.
+0012[13]: @n Parameter. Parameterno=9.
+0012[15]: @} Close param.
+0012[17]: @{ Open defn.
+0012[19]: @} Close defn.
+0012[21]: Text. Text scrap[White]="<010>
+"
+0013[01]: @$ Macro defn.
+0013[03]: @# Name. Character='"'.
+0013[06]: @{ Open defn.
+0013[08]: @} Close defn.
+0013[10]: Text. Text scrap[Grey]="<010>
+<010>
+The following test calls should NOT generate any errors.<010>
+<010>
+"
+0017[01]: @$ Macro defn.
+0017[03]: @< Open name.
+0017[05]: Text. Text scrap[Grey]="Macro containing the test macro calls."
+0017[43]: @> Close name.
+0017[45]: Text. Text scrap[Grey]="=="
+0017[47]: @{ Open defn.
+0017[49]: Text. Text scrap[Grey]="<010>
+1. Test macro call with no parameter list.<010>
+"
+0019[01]: @< Open name.
+0019[03]: Text. Text scrap[Grey]="Zero"
+0019[07]: @> Close name.
+0019[09]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test macro call with quick name.<010>
+"
+0022[01]: @# Name. Character='"'.
+0022[04]: Text. Text scrap[Grey]="<010>
+<010>
+3. Test macro call with one parameter.<010>
+"
+0025[01]: @< Open name.
+0025[03]: Text. Text scrap[Grey]="One"
+0025[06]: @> Close name.
+0025[08]: @( Open param.
+0025[10]: Text. Text scrap[Grey]="Toucan"
+0025[16]: @} Close param.
+0025[18]: Text. Text scrap[Grey]="<010>
+<010>
+4. Test macro call with many parameters.<010>
+"
+0028[01]: @< Open name.
+0028[03]: Text. Text scrap[Grey]="Two"
+0028[06]: @> Close name.
+0028[08]: @( Open param.
+0028[10]: Text. Text scrap[Grey]="Toucan"
+0028[16]: @, Comma.
+0028[18]: Text. Text scrap[Grey]="Teapot"
+0028[24]: @} Close param.
+0028[26]: Text. Text scrap[White]="<010>
+"
+0029[01]: @< Open name.
+0029[03]: Text. Text scrap[Grey]="Three"
+0029[08]: @> Close name.
+0029[10]: @( Open param.
+0029[12]: Text. Text scrap[Grey]="Toucan"
+0029[18]: @, Comma.
+0029[20]: Text. Text scrap[Grey]="Teapot"
+0029[26]: @, Comma.
+0029[28]: Text. Text scrap[Grey]="Walrus"
+0029[34]: @} Close param.
+0029[36]: Text. Text scrap[White]="<010>
+"
+0030[01]: @< Open name.
+0030[03]: Text. Text scrap[Grey]="Nine"
+0030[07]: @> Close name.
+0030[09]: @( Open param.
+0030[11]: Text. Text scrap[Grey]="Toucan"
+0030[17]: @, Comma.
+0030[19]: Text. Text scrap[Grey]="Teapot"
+0030[25]: @, Comma.
+0030[27]: Text. Text scrap[Grey]="Walrus"
+0030[33]: @, Comma.
+0030[35]: Text. Text scrap[Grey]="<010>
+ Toucan"
+0031[17]: @, Comma.
+0031[19]: Text. Text scrap[Grey]="Teapot"
+0031[25]: @, Comma.
+0031[27]: Text. Text scrap[Grey]="Walrus"
+0031[33]: @, Comma.
+0031[35]: Text. Text scrap[Grey]="<010>
+ Toucan"
+0032[17]: @, Comma.
+0032[19]: Text. Text scrap[Grey]="Teapot"
+0032[25]: @, Comma.
+0032[27]: Text. Text scrap[Grey]="Walrus"
+0032[33]: @} Close param.
+0032[35]: Text. Text scrap[Grey]="<010>
+<010>
+5. Test macro calls with double quotes on parameters.<010>
+"
+0035[01]: @< Open name.
+0035[03]: Text. Text scrap[Grey]="One"
+0035[06]: @> Close name.
+0035[08]: @( Open param.
+0035[10]: Text. Text scrap[White]=" "
+0035[11]: @" Quote.
+0035[13]: Text. Text scrap[Grey]="Toucan"
+0035[19]: @" Quote.
+0035[21]: @} Close param.
+0035[23]: Text. Text scrap[White]="<010>
+"
+0036[01]: @< Open name.
+0036[03]: Text. Text scrap[Grey]="Two"
+0036[06]: @> Close name.
+0036[08]: @( Open param.
+0036[10]: @" Quote.
+0036[12]: Text. Text scrap[Grey]="Toucan"
+0036[18]: @" Quote.
+0036[20]: Text. Text scrap[White]=" "
+0036[23]: @, Comma.
+0036[25]: Text. Text scrap[White]=" "
+0036[28]: @" Quote.
+0036[30]: Text. Text scrap[Grey]="Teapot"
+0036[36]: @" Quote.
+0036[38]: @} Close param.
+0036[40]: Text. Text scrap[White]="<010>
+"
+0037[01]: @< Open name.
+0037[03]: Text. Text scrap[Grey]="Three"
+0037[08]: @> Close name.
+0037[10]: @( Open param.
+0037[12]: @" Quote.
+0037[14]: Text. Text scrap[Grey]="Toucan"
+0037[20]: @" Quote.
+0037[22]: Text. Text scrap[White]=" "
+0037[23]: @, Comma.
+0037[25]: Text. Text scrap[White]="<010>
+ "
+0038[12]: @" Quote.
+0038[14]: Text. Text scrap[Grey]="Teapot"
+0038[20]: @" Quote.
+0038[22]: Text. Text scrap[White]=" "
+0038[23]: @, Comma.
+0038[25]: Text. Text scrap[White]="<010>
+ "
+0039[12]: @" Quote.
+0039[14]: Text. Text scrap[Grey]="Walrus"
+0039[20]: @" Quote.
+0039[22]: Text. Text scrap[White]=" "
+0039[23]: @} Close param.
+0039[25]: Text. Text scrap[White]="<010>
+"
+0040[01]: @< Open name.
+0040[03]: Text. Text scrap[Grey]="Nine"
+0040[07]: @> Close name.
+0040[09]: @( Open param.
+0040[11]: Text. Text scrap[White]=" "
+0040[12]: @" Quote.
+0040[14]: Text. Text scrap[Grey]="Toucan"
+0040[20]: @" Quote.
+0040[22]: Text. Text scrap[White]=" "
+0040[23]: @, Comma.
+0040[25]: Text. Text scrap[White]=" "
+0040[26]: @" Quote.
+0040[28]: Text. Text scrap[Grey]="Teapot"
+0040[34]: @" Quote.
+0040[36]: Text. Text scrap[White]=" "
+0040[37]: @, Comma.
+0040[39]: Text. Text scrap[White]=" "
+0040[40]: @" Quote.
+0040[42]: Text. Text scrap[Grey]="Walrus"
+0040[48]: @" Quote.
+0040[50]: Text. Text scrap[White]=" "
+0040[51]: @, Comma.
+0040[53]: Text. Text scrap[White]="<010>
+ "
+0041[12]: @" Quote.
+0041[14]: Text. Text scrap[Grey]="Toucan"
+0041[20]: @" Quote.
+0041[22]: Text. Text scrap[White]=" "
+0041[23]: @, Comma.
+0041[25]: Text. Text scrap[White]=" "
+0041[26]: @" Quote.
+0041[28]: Text. Text scrap[Grey]="Teapot"
+0041[34]: @" Quote.
+0041[36]: Text. Text scrap[White]=" "
+0041[37]: @, Comma.
+0041[39]: Text. Text scrap[White]=" "
+0041[40]: @" Quote.
+0041[42]: Text. Text scrap[Grey]="Walrus"
+0041[48]: @" Quote.
+0041[50]: Text. Text scrap[White]=" "
+0041[51]: @, Comma.
+0041[53]: Text. Text scrap[White]="<010>
+ "
+0042[12]: @" Quote.
+0042[14]: Text. Text scrap[Grey]="Toucan"
+0042[20]: @" Quote.
+0042[22]: Text. Text scrap[White]=" "
+0042[23]: @, Comma.
+0042[25]: Text. Text scrap[White]=" "
+0042[26]: @" Quote.
+0042[28]: Text. Text scrap[Grey]="Teapot"
+0042[34]: @" Quote.
+0042[36]: Text. Text scrap[White]=" "
+0042[37]: @, Comma.
+0042[39]: Text. Text scrap[White]=" "
+0042[40]: @" Quote.
+0042[42]: Text. Text scrap[Grey]="Walrus"
+0042[48]: @" Quote.
+0042[50]: Text. Text scrap[White]=" "
+0042[51]: @} Close param.
+0042[53]: Text. Text scrap[Grey]="<010>
+<010>
+7. Test macro calls with mixed double quotes on parameters.<010>
+"
+0045[01]: @< Open name.
+0045[03]: Text. Text scrap[Grey]="Two"
+0045[06]: @> Close name.
+0045[08]: @( Open param.
+0045[10]: @" Quote.
+0045[12]: Text. Text scrap[Grey]="Toucan"
+0045[18]: @" Quote.
+0045[20]: Text. Text scrap[White]=" "
+0045[23]: @, Comma.
+0045[25]: Text. Text scrap[Grey]="Teapot"
+0045[31]: @} Close param.
+0045[33]: Text. Text scrap[White]="<010>
+"
+0046[01]: @< Open name.
+0046[03]: Text. Text scrap[Grey]="Three"
+0046[08]: @> Close name.
+0046[10]: @( Open param.
+0046[12]: @" Quote.
+0046[14]: Text. Text scrap[Grey]="Toucan"
+0046[20]: @" Quote.
+0046[22]: Text. Text scrap[White]=" "
+0046[23]: @, Comma.
+0046[25]: Text. Text scrap[White]="<010>
+ "
+0047[12]: @" Quote.
+0047[14]: Text. Text scrap[Grey]="Teapot"
+0047[20]: @" Quote.
+0047[22]: Text. Text scrap[White]=" "
+0047[23]: @, Comma.
+0047[25]: Text. Text scrap[Grey]="Walrus"
+0047[31]: @} Close param.
+0047[33]: Text. Text scrap[White]="<010>
+"
+0048[01]: @< Open name.
+0048[03]: Text. Text scrap[Grey]="Nine"
+0048[07]: @> Close name.
+0048[09]: @( Open param.
+0048[11]: Text. Text scrap[White]=" "
+0048[12]: @" Quote.
+0048[14]: Text. Text scrap[Grey]="Toucan"
+0048[20]: @" Quote.
+0048[22]: Text. Text scrap[White]=" "
+0048[23]: @, Comma.
+0048[25]: Text. Text scrap[White]=" "
+0048[26]: @" Quote.
+0048[28]: Text. Text scrap[Grey]="Teapot"
+0048[34]: @" Quote.
+0048[36]: Text. Text scrap[White]=" "
+0048[37]: @, Comma.
+0048[39]: Text. Text scrap[Grey]=" Walrus "
+0048[51]: @, Comma.
+0048[53]: Text. Text scrap[White]="<010>
+ "
+0049[12]: @" Quote.
+0049[14]: Text. Text scrap[Grey]="Toucan"
+0049[20]: @" Quote.
+0049[22]: Text. Text scrap[White]=" "
+0049[23]: @, Comma.
+0049[25]: Text. Text scrap[Grey]=" Teapot "
+0049[37]: @, Comma.
+0049[39]: Text. Text scrap[White]=" "
+0049[40]: @" Quote.
+0049[42]: Text. Text scrap[Grey]="Walrus"
+0049[48]: @" Quote.
+0049[50]: Text. Text scrap[White]=" "
+0049[51]: @, Comma.
+0049[53]: Text. Text scrap[White]="<010>
+ "
+0050[12]: @" Quote.
+0050[14]: Text. Text scrap[Grey]="Toucan"
+0050[20]: @" Quote.
+0050[22]: Text. Text scrap[White]=" "
+0050[23]: @, Comma.
+0050[25]: Text. Text scrap[White]=" "
+0050[26]: @" Quote.
+0050[28]: Text. Text scrap[Grey]="Teapot"
+0050[34]: @" Quote.
+0050[36]: Text. Text scrap[White]=" "
+0050[37]: @, Comma.
+0050[39]: Text. Text scrap[White]=" "
+0050[40]: @" Quote.
+0050[42]: Text. Text scrap[Grey]="Walrus"
+0050[48]: @" Quote.
+0050[50]: Text. Text scrap[White]=" "
+0050[51]: @} Close param.
+0050[53]: Text. Text scrap[White]="<010>
+<010>
+"
+0052[01]: @} Close defn.
+0052[03]: Text. Text scrap[White]=" "
+0053[01]: Text. Text scrap[Grey]="<010>
+8. Test macro calls with a variety of syntax errors in parameter list.<010>
+"
+0055[01]: @$ Macro defn.
+0055[03]: @< Open name.
+0055[05]: Text. Text scrap[Grey]="Error1"
+0055[11]: @> Close name.
+0055[13]: @{ Open defn.
+0055[15]: Text. Text scrap[White]="<010>
+"
+0056[01]: @< Open name.
+0056[03]: Text. Text scrap[Grey]="Zero"
+0056[07]: @> Close name.
+0056[09]: @( Open param.
+0056[11]: Text. Text scrap[White]="<010>
+"
+0057[01]: @} Close defn.
+0057[03]: Text. Text scrap[White]="<010>
+"
+0058[01]: @A New section (Level 1).
+0058[03]: @< Open name.
+0058[05]: Text. Text scrap[Grey]="Error recovery point"
+0058[25]: @> Close name.
+0058[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0060[01]: @$ Macro defn.
+0060[03]: @< Open name.
+0060[05]: Text. Text scrap[Grey]="Error2"
+0060[11]: @> Close name.
+0060[13]: @{ Open defn.
+0060[15]: Text. Text scrap[White]="<010>
+"
+0061[01]: @< Open name.
+0061[03]: Text. Text scrap[Grey]="Zero"
+0061[07]: @> Close name.
+0061[09]: @} Close param.
+0061[11]: Text. Text scrap[White]="<010>
+"
+0062[01]: @} Close defn.
+0062[03]: Text. Text scrap[White]="<010>
+"
+0063[01]: @A New section (Level 1).
+0063[03]: @< Open name.
+0063[05]: Text. Text scrap[Grey]="Error recovery point"
+0063[25]: @> Close name.
+0063[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0065[01]: @$ Macro defn.
+0065[03]: @< Open name.
+0065[05]: Text. Text scrap[Grey]="Error3"
+0065[11]: @> Close name.
+0065[13]: @{ Open defn.
+0065[15]: Text. Text scrap[White]="<010>
+"
+0066[01]: @< Open name.
+0066[03]: Text. Text scrap[Grey]="One"
+0066[06]: @> Close name.
+0066[08]: @( Open param.
+0066[10]: @" Quote.
+0066[12]: Text. Text scrap[Grey]="Toucan"
+0066[18]: @} Close param.
+0066[20]: Text. Text scrap[White]="<010>
+"
+0067[01]: @} Close defn.
+0067[03]: Text. Text scrap[White]="<010>
+"
+0068[01]: @A New section (Level 1).
+0068[03]: @< Open name.
+0068[05]: Text. Text scrap[Grey]="Error recovery point"
+0068[25]: @> Close name.
+0068[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0070[01]: @$ Macro defn.
+0070[03]: @< Open name.
+0070[05]: Text. Text scrap[Grey]="Error4"
+0070[11]: @> Close name.
+0070[13]: @{ Open defn.
+0070[15]: Text. Text scrap[White]="<010>
+"
+0071[01]: @< Open name.
+0071[03]: Text. Text scrap[Grey]="One"
+0071[06]: @> Close name.
+0071[08]: @( Open param.
+0071[10]: @" Quote.
+0071[12]: Text. Text scrap[Grey]="Toucan"
+0071[18]: @" Quote.
+0071[20]: @" Quote.
+0071[22]: Text. Text scrap[Grey]="Sloth"
+0071[27]: @" Quote.
+0071[29]: @} Close param.
+0071[31]: Text. Text scrap[White]="<010>
+"
+0072[01]: @} Close defn.
+0072[03]: Text. Text scrap[White]="<010>
+"
+0073[01]: @A New section (Level 1).
+0073[03]: @< Open name.
+0073[05]: Text. Text scrap[Grey]="Error recovery point"
+0073[25]: @> Close name.
+0073[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0075[01]: @$ Macro defn.
+0075[03]: @< Open name.
+0075[05]: Text. Text scrap[Grey]="Error5"
+0075[11]: @> Close name.
+0075[13]: @{ Open defn.
+0075[15]: Text. Text scrap[White]="<010>
+"
+0076[01]: @< Open name.
+0076[03]: Text. Text scrap[Grey]="Two"
+0076[06]: @> Close name.
+0076[08]: @( Open param.
+0076[10]: @" Quote.
+0076[12]: Text. Text scrap[Grey]="Toucan"
+0076[18]: @" Quote.
+0076[20]: Text. Text scrap[Grey]="Teapot"
+0076[26]: @} Close param.
+0076[28]: Text. Text scrap[White]="<010>
+"
+0077[01]: @} Close defn.
+0077[03]: Text. Text scrap[White]="<010>
+"
+0078[01]: @A New section (Level 1).
+0078[03]: @< Open name.
+0078[05]: Text. Text scrap[Grey]="Error recovery point"
+0078[25]: @> Close name.
+0078[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0080[01]: @$ Macro defn.
+0080[03]: @< Open name.
+0080[05]: Text. Text scrap[Grey]="Error6"
+0080[11]: @> Close name.
+0080[13]: @{ Open defn.
+0080[15]: Text. Text scrap[White]="<010>
+"
+0081[01]: @< Open name.
+0081[03]: Text. Text scrap[Grey]="Two"
+0081[06]: @> Close name.
+0081[08]: @( Open param.
+0081[10]: @" Quote.
+0081[12]: Text. Text scrap[Grey]="Toucan"
+0081[18]: @" Quote.
+0081[20]: Text. Text scrap[Grey]="Teapot<010>
+"
+0082[01]: @} Close defn.
+0082[03]: Text. Text scrap[White]="<010>
+"
+0083[01]: @A New section (Level 1).
+0083[03]: @< Open name.
+0083[05]: Text. Text scrap[Grey]="Error recovery point"
+0083[25]: @> Close name.
+0083[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0085[01]: @$ Macro defn.
+0085[03]: @< Open name.
+0085[05]: Text. Text scrap[Grey]="Error7"
+0085[11]: @> Close name.
+0085[13]: @{ Open defn.
+0085[15]: Text. Text scrap[White]="<010>
+"
+0086[01]: @< Open name.
+0086[03]: Text. Text scrap[Grey]="Two"
+0086[06]: @> Close name.
+0086[08]: @( Open param.
+0086[10]: @" Quote.
+0086[12]: Text. Text scrap[Grey]="Toucan"
+0086[18]: @" Quote.
+0086[20]: Text. Text scrap[Grey]="Teapot<010>
+"
+0087[01]: @< Open name.
+0087[03]: Text. Text scrap[Grey]="Three"
+0087[08]: @> Close name.
+0087[10]: @( Open param.
+0087[12]: Text. Text scrap[Grey]="Toucan"
+0087[18]: @, Comma.
+0087[20]: Text. Text scrap[White]="<010>
+ "
+0088[12]: @" Quote.
+0088[14]: Text. Text scrap[Grey]="Teapot"
+0088[20]: @, Comma.
+0088[22]: Text. Text scrap[Grey]="Walrus<010>
+<010>
+"
+0090[01]: @} Close defn.
+0090[03]: Text. Text scrap[White]="<010>
+"
+0091[01]: @A New section (Level 1).
+0091[03]: @< Open name.
+0091[05]: Text. Text scrap[Grey]="Error recovery point"
+0091[25]: @> Close name.
+0091[27]: Text. Text scrap[White]="<010>
+<010>
+"
+0093[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : """
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+ Call 1: Parameters=0, Sequence num=7, Position(L,C)=(22,1).
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=6, Pos(L,C)=(13,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#file"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#line"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#timestamp"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error1"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error2"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error3"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error4"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error5"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=8, Pos(L,C)=(75,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Two@>
+This invocation has 1 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error6"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Error7"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Macro containing the test macro calls."
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=7, Pos(L,C)=(17,3), Expression follows:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="<010>
+1. Test macro call with no parameter list.<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Zero@>
+No actual parameters.
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[Grey]="<010>
+<010>
+2. Test macro call with quick name.<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<"@>
+No actual parameters.
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[Grey]="<010>
+<010>
+3. Test macro call with one parameter.<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<One@>
+This invocation has 1 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[Grey]="<010>
+<010>
+4. Test macro call with many parameters.<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Two@>
+This invocation has 2 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 2:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Three@>
+This invocation has 3 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 2:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 3:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Nine@>
+This invocation has 9 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 2:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 3:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 4:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="<010>
+ Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 5:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 6:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 7:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="<010>
+ Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 8:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 9:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[Grey]="<010>
+<010>
+5. Test macro calls with double quotes on parameters.<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<One@>
+This invocation has 1 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Two@>
+This invocation has 2 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 2:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Three@>
+This invocation has 3 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 2:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 3:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Nine@>
+This invocation has 9 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 2:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 3:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 4:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 5:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 6:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 7:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 8:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 9:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[Grey]="<010>
+<010>
+7. Test macro calls with mixed double quotes on parameters.<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Two@>
+This invocation has 2 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 2:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Three@>
+This invocation has 3 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 2:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 3:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+"
+------ End Text Element ------
+
+
+-- Begin Invocation Element --
+Invocation of macro @<Nine@>
+This invocation has 9 actual parameters.
+Actual parameter list follows as a sequence of expressions:
+(Text crud before and after parameter has been omitted).
+Expression for parameter number 1:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 2:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 3:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]=" Walrus "
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 4:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 5:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]=" Teapot "
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 6:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 7:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Toucan"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 8:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Teapot"
+------ End Text Element ------
+
+----- End of Expression -----
+
+Expression for parameter number 9:
+
+---- Start of Expression ----
+
+----- Start Text Element -----
+Text scrap[Grey]="Walrus"
+------ End Text Element ------
+
+----- End of Expression -----
+
+--- End Invocation Element ---
+
+
+----- Start Text Element -----
+Text scrap[White]="<010>
+<010>
+"
+------ End Text Element ------
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Nine"
+Defined? : Yes.
+Parameters : 9
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+ Call 1: Parameters=9, Sequence num=7, Position(L,C)=(30,1).
+ Call 2: Parameters=9, Sequence num=7, Position(L,C)=(40,1).
+ Call 3: Parameters=9, Sequence num=7, Position(L,C)=(48,1).
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=5, Pos(L,C)=(12,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "One"
+Defined? : Yes.
+Parameters : 1
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+ Call 1: Parameters=1, Sequence num=7, Position(L,C)=(25,1).
+ Call 2: Parameters=1, Sequence num=7, Position(L,C)=(35,1).
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=2, Pos(L,C)=(9,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Three"
+Defined? : Yes.
+Parameters : 3
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+ Call 1: Parameters=3, Sequence num=7, Position(L,C)=(29,1).
+ Call 2: Parameters=3, Sequence num=7, Position(L,C)=(37,1).
+ Call 3: Parameters=3, Sequence num=7, Position(L,C)=(46,1).
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=4, Pos(L,C)=(11,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Two"
+Defined? : Yes.
+Parameters : 2
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+ Call 1: Parameters=2, Sequence num=7, Position(L,C)=(28,1).
+ Call 2: Parameters=2, Sequence num=7, Position(L,C)=(36,1).
+ Call 3: Parameters=2, Sequence num=7, Position(L,C)=(45,1).
+ Call 4: Parameters=1, Sequence num=8, Position(L,C)=(76,1).
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=3, Pos(L,C)=(10,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Zero"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+ Call 1: Parameters=0, Sequence num=7, Position(L,C)=(19,1).
+ Call 2: Parameters=0, Sequence num=8, Position(L,C)=(61,1).
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=1, Pos(L,C)=(8,3), Expression follows:
+
+---- Start of Expression ----
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR09: Test calls and actual parameter lists.<010>
+<010>
+First trip up the parser so we don't get any further.<010>
+"
+--- End of Text Scrap List ---
+
+
+TEXT COMPONENT: Pos(L,C)=(4,3).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+Now define some macros to call. No error.<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(8,1).
+Part 1 of macro @<Zero@>.
+
+TEXT COMPONENT: Pos(L,C)=(8,15).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(9,1).
+Part 1 of macro @<One@>.
+
+TEXT COMPONENT: Pos(L,C)=(9,20).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(10,1).
+Part 1 of macro @<Two@>.
+
+TEXT COMPONENT: Pos(L,C)=(10,20).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(11,1).
+Part 1 of macro @<Three@>.
+
+TEXT COMPONENT: Pos(L,C)=(11,22).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(12,1).
+Part 1 of macro @<Nine@>.
+
+TEXT COMPONENT: Pos(L,C)=(12,21).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(13,1).
+Part 1 of macro @<"@>.
+
+TEXT COMPONENT: Pos(L,C)=(13,10).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+The following test calls should NOT generate any errors.<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(17,1).
+Part 1 of macro @<Macro containing the test macro calls.@>.
+
+TEXT COMPONENT: Pos(L,C)=(52,3).
+
+-- Start of Text Scrap List --
+Text scrap[White]=" "
+Text scrap[Grey]="<010>
+8. Test macro calls with a variety of syntax errors in parameter list.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(58,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(63,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "3", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(68,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "4", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(73,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+MACRO DEFINITION COMPONENT: Pos(L,C)=(75,1).
+Part 1 of macro @<Error5@>.
+
+TEXT COMPONENT: Pos(L,C)=(77,3).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "5", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(78,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "6", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(83,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "7", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(91,27).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| PR09: Test calls and actual parameter lists.
+ 2 2|
+ 3 3| First trip up the parser so we don't get any further.
+ 4 4| @>
+ Error|.^The parser was at the top level and was expecting
+ |.^one of: {Directive, Text, Macro definition, EOF}.
+ 5 5|
+ 6 6| Now define some macros to call. No error.
+ 7 7|
+ 8 8| @$@<Zero@>@{@}
+ 9 9| @$@<One@>@(@1@)@{@}
+ 10 10| @$@<Two@>@(@2@)@{@}
+ 11 11| @$@<Three@>@(@3@)@{@}
+ 12 12| @$@<Nine@>@(@9@)@{@}
+ 13 13| @$@#"@{@}
+ 14 14|
+ 15 15| The following test calls should NOT generate any errors.
+ 16 16|
+ 17 17| @$@<Macro containing the test macro calls.@>==@{
+ 18 18| 1. Test macro call with no parameter list.
+ 19 19| @<Zero@>
+ 20 20|
+ 21 21| 2. Test macro call with quick name.
+ 22 22| @#"
+ 23 23|
+ 24 24| 3. Test macro call with one parameter.
+ 25 25| @<One@>@(Toucan@)
+ 26 26|
+ 27 27| 4. Test macro call with many parameters.
+ 28 28| @<Two@>@(Toucan@,Teapot@)
+ 29 29| @<Three@>@(Toucan@,Teapot@,Walrus@)
+ 30 30| @<Nine@>@(Toucan@,Teapot@,Walrus@,
+ 31 31| Toucan@,Teapot@,Walrus@,
+ 32 32| Toucan@,Teapot@,Walrus@)
+ 33 33|
+ 34 34| 5. Test macro calls with double quotes on parameters.
+ 35 35| @<One@>@( @"Toucan@"@)
+ 36 36| @<Two@>@(@"Toucan@" @, @"Teapot@"@)
+ 37 37| @<Three@>@(@"Toucan@" @,
+ 38 38| @"Teapot@" @,
+ 39 39| @"Walrus@" @)
+ 40 40| @<Nine@>@( @"Toucan@" @, @"Teapot@" @, @"Walrus@" @,
+ 41 41| @"Toucan@" @, @"Teapot@" @, @"Walrus@" @,
+ 42 42| @"Toucan@" @, @"Teapot@" @, @"Walrus@" @)
+ 43 43|
+ 44 44| 7. Test macro calls with mixed double quotes on parameters.
+ 45 45| @<Two@>@(@"Toucan@" @,Teapot@)
+ 46 46| @<Three@>@(@"Toucan@" @,
+ 47 47| @"Teapot@" @,Walrus@)
+ 48 48| @<Nine@>@( @"Toucan@" @, @"Teapot@" @, Walrus @,
+ 49 49| @"Toucan@" @, Teapot @, @"Walrus@" @,
+ 50 50| @"Toucan@" @, @"Teapot@" @, @"Walrus@" @)
+ 51 51|
+ 52 52| @} @! End of macro definition enclosing all these legal tests.
+ 53 53|
+ 54 54| 8. Test macro calls with a variety of syntax errors in parameter list.
+ 55 55| @$@<Error1@>@{
+ 56 56| @<Zero@>@(
+ 57 57| @}
+ Error|.^Expecting @" or @, or @).
+ |.^Skipping after error to the next major construct...
+ 58 58| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 59 59|
+ 60 60| @$@<Error2@>@{
+ 61 61| @<Zero@>@)
+ Error|.........^Expecting '@}'.
+ |.........^Skipping after error to the next major construct...
+ 62 62| @}
+ 63 63| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 64 64|
+ 65 65| @$@<Error3@>@{
+ 66 66| @<One@>@(@"Toucan@)
+ Error|..................^Expecting '@"'.
+ |..................^Skipping after error to the next major construct...
+ 67 67| @}
+ 68 68| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 69 69|
+ 70 70| @$@<Error4@>@{
+ 71 71| @<One@>@(@"Toucan@"@"Sloth@"@)
+ Error|....................^Expecting @, or @).
+ |....................^Skipping after error to the next major construct...
+ 72 72| @}
+ 73 73| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 74 74|
+ 75 75| @$@<Error5@>@{
+ 76 76| @<Two@>@(@"Toucan@"Teapot@)
+ Error|....................^Expecting whitespace text.
+ 77 77| @}
+ 78 78| @A@<Error recovery point@>
+ 79 79|
+ 80 80| @$@<Error6@>@{
+ 81 81| @<Two@>@(@"Toucan@"Teapot
+ Error|....................^Expecting whitespace text.
+ 82 82| @}
+ Error|.^Expecting @, or @).
+ |.^Skipping after error to the next major construct...
+ 83 83| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 84 84|
+ 85 85| @$@<Error7@>@{
+ 86 86| @<Two@>@(@"Toucan@"Teapot
+ Error|....................^Expecting whitespace text.
+ 87 87| @<Three@>@(Toucan@,
+ Error|.^Expecting @, or @).
+ |.^Skipping after error to the next major construct...
+ 88 88| @"Teapot@,Walrus
+ 89 89|
+ 90 90| @}
+ 91 91| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 92 92|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 10 Errors.
diff --git a/web/funnelAC/results/pr10.lis b/web/funnelAC/results/pr10.lis
new file mode 100644
index 0000000000..2575a8c12c
--- /dev/null
+++ b/web/funnelAC/results/pr10.lis
@@ -0,0 +1,487 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 50 52 31 30 3A 20 54 65 73 74 20 73 79 6E 74 61 | PR10: Test synta |
+| 63 74 69 63 20 65 72 72 6F 72 20 72 65 63 6F 76 | ctic error recov |
+| 65 72 79 2E 0A 0A 31 2E 20 54 65 73 74 20 72 65 | ery...1. Test re |
+| 63 6F 76 65 72 79 20 61 74 20 74 6F 70 20 70 61 | covery at top pa |
+| 72 73 69 6E 67 20 6C 65 76 65 6C 2E 0A 40 3C 0A | rsing level..@<. |
+| 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 | .@A@<Error recov |
+| 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 32 2E 20 | ery point@>..2. |
+| 54 65 73 74 20 72 65 63 6F 76 65 72 79 20 69 6E | Test recovery in |
+| 73 69 64 65 20 6D 61 63 72 6F 20 64 65 66 69 6E | side macro defin |
+| 69 74 69 6F 6E 2E 0A 0A 40 24 40 3C 53 6C 6F 74 | ition...@$@<Slot |
+| 68 31 40 3E 40 3E 3D 3D 40 7B 0A 57 61 6C 72 75 | h1@>@>==@{.Walru |
+| 73 40 7D 0A 0A 40 24 40 3C 53 6C 6F 74 68 32 40 | s@}..@$@<Sloth2@ |
+| 3E 3D 3D 40 7B 0A 40 3C 57 61 6C 72 75 73 40 3C | >==@{.@<Walrus@< |
+| 0A 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 | .@}.@A@<Error re |
+| 63 6F 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A | covery point@>.. |
+| 33 2E 20 54 65 73 74 20 72 65 63 6F 76 65 72 79 | 3. Test recovery |
+| 20 69 6E 73 69 64 65 20 61 63 74 75 61 6C 20 70 | inside actual p |
+| 61 72 61 6D 65 74 65 72 20 6C 69 73 74 20 69 6E | arameter list in |
+| 20 6D 61 63 72 6F 20 64 65 66 69 6E 69 74 69 6F | macro definitio |
+| 6E 2E 0A 40 24 40 3C 53 6C 6F 74 68 33 40 3E 3D | n..@$@<Sloth3@>= |
+| 3D 40 7B 0A 40 3C 57 61 6C 72 75 73 40 3E 40 28 | =@{.@<Walrus@>@( |
+| 40 22 61 61 72 64 76 61 72 6B 40 3E 0A 40 7D 0A | @"aardvark@>.@}. |
+| 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 | @A@<Error recove |
+| 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 34 2E 20 54 | ry point@>..4. T |
+| 65 73 74 20 45 4F 46 20 69 6E 20 74 68 65 20 6D | est EOF in the m |
+| 69 64 64 6C 65 20 6F 66 20 61 20 63 6F 6D 70 6C | iddle of a compl |
+| 69 63 61 74 65 64 20 63 6F 6E 73 74 72 75 63 74 | icated construct |
+| 2E 0A 54 68 65 20 66 6F 6C 6C 6F 77 69 6E 67 20 | ..The following |
+| 6D 61 6B 65 73 20 74 68 65 20 65 6E 64 20 6F 66 | makes the end of |
+| 20 74 68 65 20 66 69 6C 65 20 6C 6F 6F 6B 65 64 | the file looked |
+| 20 63 68 6F 70 70 65 64 20 6F 66 66 2C 20 62 75 | chopped off, bu |
+| 74 20 69 74 20 69 73 0A 61 63 74 75 61 6C 6C 79 | t it is.actually |
+| 20 69 6E 74 65 6E 74 69 6F 6E 61 6C 2E 0A 40 24 | intentional..@$ |
+| 40 3C 53 6C 6F 74 68 34 40 3E 3D 3D 40 7B 0A 40 | @<Sloth4@>==@{.@ |
+| 3C 57 61 6C 72 75 73 40 3E 40 28 40 22 61 61 72 | <Walrus@>@(@"aar |
+| 64 76 61 0A | dva. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| PR10: Test syntactic error recovery.<010>
+00002 00002| <010>
+00003 00003| 1. Test recovery at top parsing level.<010>
+00004 00004| @<<010>
+00005 00005| <010>
+00006 00006| @A@<Error recovery point@><010>
+00007 00007| <010>
+00008 00008| 2. Test recovery inside macro definition.<010>
+00009 00009| <010>
+00010 00010| @$@<Sloth1@>@>==@{<010>
+00011 00011| Walrus@}<010>
+00012 00012| <010>
+00013 00013| @$@<Sloth2@>==@{<010>
+00014 00014| @<Walrus@<<010>
+00015 00015| @}<010>
+00016 00016| @A@<Error recovery point@><010>
+00017 00017| <010>
+00018 00018| 3. Test recovery inside actual parameter list in macro definition.<010>
+00019 00019| @$@<Sloth3@>==@{<010>
+00020 00020| @<Walrus@>@(@"aardvark@><010>
+00021 00021| @}<010>
+00022 00022| @A@<Error recovery point@><010>
+00023 00023| <010>
+00024 00024| 4. Test EOF in the middle of a complicated construct.<010>
+00025 00025| The following makes the end of the file looked chopped off, but it is<010>
+00026 00026| actually intentional.<010>
+00027 00027| @$@<Sloth4@>==@{<010>
+00028 00028| @<Walrus@>@(@"aardva<010>
+00029 00029| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 72 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="PR10: Test syntactic error recovery.<010>
+<010>
+1. Test recovery at top parsing level.<010>
+"
+0004[01]: @< Open name.
+0004[03]: Text. Text scrap[White]="<010>
+<010>
+"
+0006[01]: @A New section (Level 1).
+0006[03]: @< Open name.
+0006[05]: Text. Text scrap[Grey]="Error recovery point"
+0006[25]: @> Close name.
+0006[27]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test recovery inside macro definition.<010>
+<010>
+"
+0010[01]: @$ Macro defn.
+0010[03]: @< Open name.
+0010[05]: Text. Text scrap[Grey]="Sloth1"
+0010[11]: @> Close name.
+0010[13]: @> Close name.
+0010[15]: Text. Text scrap[Grey]="=="
+0010[17]: @{ Open defn.
+0010[19]: Text. Text scrap[Grey]="<010>
+Walrus"
+0011[07]: @} Close defn.
+0011[09]: Text. Text scrap[White]="<010>
+<010>
+"
+0013[01]: @$ Macro defn.
+0013[03]: @< Open name.
+0013[05]: Text. Text scrap[Grey]="Sloth2"
+0013[11]: @> Close name.
+0013[13]: Text. Text scrap[Grey]="=="
+0013[15]: @{ Open defn.
+0013[17]: Text. Text scrap[White]="<010>
+"
+0014[01]: @< Open name.
+0014[03]: Text. Text scrap[Grey]="Walrus"
+0014[09]: @< Open name.
+0014[11]: Text. Text scrap[White]="<010>
+"
+0015[01]: @} Close defn.
+0015[03]: Text. Text scrap[White]="<010>
+"
+0016[01]: @A New section (Level 1).
+0016[03]: @< Open name.
+0016[05]: Text. Text scrap[Grey]="Error recovery point"
+0016[25]: @> Close name.
+0016[27]: Text. Text scrap[Grey]="<010>
+<010>
+3. Test recovery inside actual parameter list in macro definition.<010>
+"
+0019[01]: @$ Macro defn.
+0019[03]: @< Open name.
+0019[05]: Text. Text scrap[Grey]="Sloth3"
+0019[11]: @> Close name.
+0019[13]: Text. Text scrap[Grey]="=="
+0019[15]: @{ Open defn.
+0019[17]: Text. Text scrap[White]="<010>
+"
+0020[01]: @< Open name.
+0020[03]: Text. Text scrap[Grey]="Walrus"
+0020[09]: @> Close name.
+0020[11]: @( Open param.
+0020[13]: @" Quote.
+0020[15]: Text. Text scrap[Grey]="aardvark"
+0020[23]: @> Close name.
+0020[25]: Text. Text scrap[White]="<010>
+"
+0021[01]: @} Close defn.
+0021[03]: Text. Text scrap[White]="<010>
+"
+0022[01]: @A New section (Level 1).
+0022[03]: @< Open name.
+0022[05]: Text. Text scrap[Grey]="Error recovery point"
+0022[25]: @> Close name.
+0022[27]: Text. Text scrap[Grey]="<010>
+<010>
+4. Test EOF in the middle of a complicated construct.<010>
+The following makes the end of the file looked chopped off, but it is<010>
+actually intentional.<010>
+"
+0027[01]: @$ Macro defn.
+0027[03]: @< Open name.
+0027[05]: Text. Text scrap[Grey]="Sloth4"
+0027[11]: @> Close name.
+0027[13]: Text. Text scrap[Grey]="=="
+0027[15]: @{ Open defn.
+0027[17]: Text. Text scrap[White]="<010>
+"
+0028[01]: @< Open name.
+0028[03]: Text. Text scrap[Grey]="Walrus"
+0028[09]: @> Close name.
+0028[11]: @( Open param.
+0028[13]: @" Quote.
+0028[15]: Text. Text scrap[Grey]="aardva<010>
+"
+0029[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#file"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#line"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#timestamp"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth1"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth2"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth3"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "Sloth4"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : No.
+Many Calls? : No.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 0 body parts.
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="PR10: Test syntactic error recovery.<010>
+<010>
+1. Test recovery at top parsing level.<010>
+"
+--- End of Text Scrap List ---
+
+
+TEXT COMPONENT: Pos(L,C)=(4,3).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "1", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(6,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+2. Test recovery inside macro definition.<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "2", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(16,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+3. Test recovery inside actual parameter list in macro definition.<010>
+"
+--- End of Text Scrap List ---
+
+
+TYPESETTER DIRECTIVE COMPONENT:
+ Section "3", Section name="Error recovery point".
+
+TEXT COMPONENT: Pos(L,C)=(22,27).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="<010>
+<010>
+4. Test EOF in the middle of a complicated construct.<010>
+The following makes the end of the file looked chopped off, but it is<010>
+actually intentional.<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| PR10: Test syntactic error recovery.
+ 2 2|
+ 3 3| 1. Test recovery at top parsing level.
+ 4 4| @<
+ Error|.^The parser was at the top level and was expecting
+ |.^one of: {Directive, Text, Macro definition, EOF}.
+ 5 5|
+ 6 6| @A@<Error recovery point@>
+ 7 7|
+ 8 8| 2. Test recovery inside macro definition.
+ 9 9|
+ 10 10| @$@<Sloth1@>@>==@{
+ Error|.............^Expecting '@{'.
+ |.............^Skipping after error to the next major construct...
+ 11 11| Walrus@}
+ 12 12|
+ 13 13| @$@<Sloth2@>==@{
+ |.^...skipped to here after the error.
+ 14 14| @<Walrus@<
+ Error|.........^Illegal character or symbol in name.
+ |.........^Skipping after error to the next major construct...
+ 15 15| @}
+ 16 16| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 17 17|
+ 18 18| 3. Test recovery inside actual parameter list in macro definition.
+ 19 19| @$@<Sloth3@>==@{
+ 20 20| @<Walrus@>@(@"aardvark@>
+ Error|.......................^Expecting '@"'.
+ |.......................^Skipping after error to the next major construct...
+ 21 21| @}
+ 22 22| @A@<Error recovery point@>
+ |.^...skipped to here after the error.
+ 23 23|
+ 24 24| 4. Test EOF in the middle of a complicated construct.
+ 25 25| The following makes the end of the file looked chopped off, but it is
+ 26 26| actually intentional.
+ 27 27| @$@<Sloth4@>==@{
+ 28 28| @<Walrus@>@(@"aardva
+ | <End-Of-File>
+ Error|.^Expecting '@"'.
+ |.^Skipping after error to the next major construct...
+ |.^...skipped to here after the error.
+------------+-------------------------------------------------------------------
+
+There were 5 Errors.
diff --git a/web/funnelAC/results/sc01.lis b/web/funnelAC/results/sc01.lis
new file mode 100644
index 0000000000..63a28eb6b6
--- /dev/null
+++ b/web/funnelAC/results/sc01.lis
@@ -0,0 +1,35 @@
+FUNNELWEB LISTING FILE
+======================
+
+S: Error opening input file "<<Suppressed>>".
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 1 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+There was 1 Severe error.
diff --git a/web/funnelAC/results/sc02.lis b/web/funnelAC/results/sc02.lis
new file mode 100644
index 0000000000..c56ff926c9
--- /dev/null
+++ b/web/funnelAC/results/sc02.lis
@@ -0,0 +1,143 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 1 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#file"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#line"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#timestamp"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ | <End-Of-File>
+ Warning|.^Input file is empty (not a byte in syte)!
+------------+-------------------------------------------------------------------
+
+There was 1 Error and 1 Warning.
diff --git a/web/funnelAC/results/sc03.lis b/web/funnelAC/results/sc03.lis
new file mode 100644
index 0000000000..7ab141b85a
--- /dev/null
+++ b/web/funnelAC/results/sc03.lis
@@ -0,0 +1,154 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 0A | . |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| <010>
+00002 00002| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 2 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[White]="<010>
+"
+0002[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#file"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#line"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#timestamp"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+There was 1 Error.
diff --git a/web/funnelAC/results/sc04.lis b/web/funnelAC/results/sc04.lis
new file mode 100644
index 0000000000..7f5a985041
--- /dev/null
+++ b/web/funnelAC/results/sc04.lis
@@ -0,0 +1,157 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 0A 0A | .. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| <010>
+00002 00002| <010>
+00003 00003| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 2 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[White]="<010>
+<010>
+"
+0003[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#file"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#line"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#timestamp"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[White]="<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+There was 1 Error.
diff --git a/web/funnelAC/results/sc05.lis b/web/funnelAC/results/sc05.lis
new file mode 100644
index 0000000000..1a1d59e6d0
--- /dev/null
+++ b/web/funnelAC/results/sc05.lis
@@ -0,0 +1,158 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 30 35 3A 20 54 68 69 73 20 69 6E 70 75 74 | SC05: This input |
+| 20 66 69 6C 65 20 63 6F 6E 74 61 69 6E 73 20 61 | file contains a |
+| 20 73 69 6E 67 6C 65 20 6C 69 6E 65 20 63 6F 6E | single line con |
+| 74 61 69 6E 69 6E 67 20 74 68 69 73 20 74 65 78 | taining this tex |
+| 74 21 0A | t!. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC05: This input file contains a single line containing this text!<010>
+00002 00002| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 2 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC05: This input file contains a single line containing this text!<010>
+"
+0002[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#file"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#line"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#timestamp"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="SC05: This input file contains a single line containing this text!<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+There was 1 Error.
diff --git a/web/funnelAC/results/sc06.lis b/web/funnelAC/results/sc06.lis
new file mode 100644
index 0000000000..3eaf782140
--- /dev/null
+++ b/web/funnelAC/results/sc06.lis
@@ -0,0 +1,166 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 30 36 3A 20 54 65 73 74 20 46 75 6E 6E 65 | SC06: Test Funne |
+| 6C 57 65 62 20 6F 6E 20 61 20 66 69 6C 65 20 77 | lWeb on a file w |
+| 68 6F 73 65 20 6C 61 73 74 20 6C 69 6E 65 20 69 | hose last line i |
+| 73 20 6E 6F 74 20 74 65 72 6D 69 6E 61 74 65 64 | s not terminated |
+| 20 70 72 6F 70 65 72 6C 79 0A 77 69 74 68 20 61 | properly.with a |
+| 6E 20 65 6E 64 20 6F 66 20 6C 69 6E 65 20 6D 61 | n end of line ma |
+| 72 6B 65 72 2E 0A 0A | rker... |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC06: Test FunnelWeb on a file whose last line is not terminated properly<010>
+00002 00002| with an end of line marker.<010>
+00003 00003| <010>
+00004 00004| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 2 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC06: Test FunnelWeb on a file whose last line is not terminated properly<010>
+with an end of line marker.<010>
+<010>
+"
+0004[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#file"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#line"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#timestamp"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="SC06: Test FunnelWeb on a file whose last line is not terminated properly<010>
+with an end of line marker.<010>
+<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+There was 1 Error.
diff --git a/web/funnelAC/results/sc07.lis b/web/funnelAC/results/sc07.lis
new file mode 100644
index 0000000000..b4f069ddcf
--- /dev/null
+++ b/web/funnelAC/results/sc07.lis
@@ -0,0 +1,187 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 30 37 3A 20 50 72 6F 63 65 73 73 69 6E 67 | SC07: Processing |
+| 20 6F 66 20 6C 6F 6E 67 20 6C 69 6E 65 73 2E 0A | of long lines.. |
+| 0A 53 43 30 37 2E 31 3A 20 44 65 74 65 63 74 69 | .SC07.1: Detecti |
+| 6F 6E 20 6F 66 20 61 20 6C 69 6E 65 20 6C 6F 6E | on of a line lon |
+| 67 65 72 20 74 68 61 6E 20 74 68 65 20 64 65 66 | ger than the def |
+| 61 75 6C 74 20 6C 69 6D 69 74 2E 0A 0A 54 68 65 | ault limit...The |
+| 20 64 65 66 61 75 6C 74 20 6C 69 6D 69 74 20 69 | default limit i |
+| 73 20 38 30 20 63 68 61 72 61 63 74 65 72 73 20 | s 80 characters |
+| 73 6F 20 77 65 20 77 69 6C 6C 20 74 65 73 74 20 | so we will test |
+| 6F 6E 20 65 69 74 68 65 72 20 73 69 64 65 20 6F | on either side o |
+| 66 0A 74 68 61 74 3A 0A 20 20 20 20 20 20 20 20 | f.that:. |
+| 20 31 20 20 20 20 20 20 20 20 20 32 20 20 20 20 | 1 2 |
+| 20 20 20 20 20 33 20 20 20 20 20 20 20 20 20 34 | 3 4 |
+| 20 20 20 20 20 20 20 20 20 35 20 20 20 20 20 20 | 5 |
+| 20 20 20 36 20 20 20 20 20 20 20 20 20 37 20 20 | 6 7 |
+| 20 20 20 20 20 20 20 38 0A 31 32 33 34 35 36 37 | 8.1234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 0A 54 68 65 20 61 62 | 234567890.The ab |
+| 6F 76 65 20 73 68 6F 75 6C 64 20 6E 6F 74 20 74 | ove should not t |
+| 72 69 67 67 65 72 20 61 20 22 6C 69 6E 65 20 74 | rigger a "line t |
+| 6F 6F 20 6C 6F 6E 67 20 65 72 72 6F 72 22 2E 20 | oo long error". |
+| 42 75 74 20 74 68 69 73 20 6C 69 6E 65 20 73 68 | But this line sh |
+| 6F 75 6C 64 21 2D 2D 2D 2D 2D 2D 0A 0A 53 43 30 | ould!------..SC0 |
+| 37 2E 33 3A 20 54 65 73 74 20 74 68 65 20 6C 69 | 7.3: Test the li |
+| 6D 69 74 20 73 65 74 20 61 74 20 69 6E 66 69 6E | mit set at infin |
+| 69 74 79 2E 0A 0A 40 70 20 6D 61 78 69 6D 75 6D | ity...@p maximum |
+| 5F 69 6E 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 | _input_line_leng |
+| 74 68 20 3D 20 69 6E 66 69 6E 69 74 79 0A 0A 20 | th = infinity.. |
+| 20 20 20 20 20 20 20 20 31 20 20 20 20 20 20 20 | 1 |
+| 20 20 32 20 20 20 20 20 20 20 20 20 33 20 20 20 | 2 3 |
+| 20 20 20 20 20 20 34 20 20 20 20 20 20 20 20 20 | 4 |
+| 35 20 20 20 20 20 20 20 20 20 36 20 20 20 20 20 | 5 6 |
+| 20 20 20 20 37 20 20 20 20 20 20 20 20 20 38 0A | 7 8. |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 0A 54 68 65 20 61 62 6F 76 65 20 73 68 6F 75 6C | .The above shoul |
+| 64 20 6E 6F 74 20 74 72 69 67 67 65 72 20 61 20 | d not trigger a |
+| 22 6C 69 6E 65 20 74 6F 6F 20 6C 6F 6E 67 20 65 | "line too long e |
+| 72 72 6F 72 22 2E 20 4E 6F 72 20 73 68 6F 75 6C | rror". Nor shoul |
+| 64 20 74 68 69 73 20 6F 6E 65 21 2D 2D 2D 2D 2D | d this one!----- |
+| 2D 2D 0A 0A 53 43 30 37 2E 33 3A 20 54 65 73 74 | --..SC07.3: Test |
+| 20 74 68 65 20 6C 69 6D 69 74 20 73 65 74 20 6C | the limit set l |
+| 6F 77 65 72 2E 0A 0A 40 70 20 6D 61 78 69 6D 75 | ower...@p maximu |
+| 6D 5F 69 6E 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E | m_input_line_len |
+| 67 74 68 20 3D 20 35 30 0A 0A 20 20 20 20 20 20 | gth = 50.. |
+| 20 20 20 31 20 20 20 20 20 20 20 20 20 32 20 20 | 1 2 |
+| 20 20 20 20 20 20 20 33 20 20 20 20 20 20 20 20 | 3 |
+| 20 34 20 20 20 20 20 20 20 20 20 35 0A 31 32 33 | 4 5.123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 0A | 678901234567890. |
+| 4E 6F 20 65 72 72 6F 72 20 66 6F 72 20 74 68 65 | No error for the |
+| 20 61 62 6F 76 65 20 62 75 74 20 74 68 69 73 20 | above but this |
+| 6C 69 6E 65 20 77 69 6C 6C 21 2D 2D 2D 2D 2D 2D | line will!------ |
+| 2D 2D 2D 0A | ---. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC07: Processing of long lines.<010>
+00002 00002| <010>
+00003 00003| SC07.1: Detection of a line longer than the default limit.<010>
+00004 00004| <010>
+00005 00005| The default limit is 80 characters so we will test on either side of<010>
+00006 00006| that:<010>
+00007 00007| 1 2 3 4 5 6 7 8<010>
+00008 00008| 12345678901234567890123456789012345678901234567890123456789012345678901234567890<010>
+00009 00009| The above should not trigger a "line too long error". But this line should!------<010>
+00010 00010| <010>
+00011 00011| SC07.3: Test the limit set at infinity.<010>
+00012 00012| <010>
+00013 00013| @p maximum_input_line_length = infinity<010>
+00014 00014| <010>
+00015 00015| 1 2 3 4 5 6 7 8<010>
+00016 00016| 12345678901234567890123456789012345678901234567890123456789012345678901234567890<010>
+00017 00017| The above should not trigger a "line too long error". Nor should this one!-------<010>
+00018 00018| <010>
+00019 00019| SC07.3: Test the limit set lower.<010>
+00020 00020| <010>
+00021 00021| @p maximum_input_line_length = 50<010>
+00022 00022| <010>
+00023 00023| 1 2 3 4 5<010>
+00024 00024| 12345678901234567890123456789012345678901234567890<010>
+00025 00025| No error for the above but this line will!---------<010>
+00026 00026| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 4 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC07: Processing of long lines.<010>
+<010>
+SC07.1: Detection of a line longer than the default limit.<010>
+<010>
+The default limit is 80 characters so we will test on either side of<010>
+that:<010>
+ 1 2 3 4 5 6 7 8<010>
+12345678901234567890123456789012345678901234567890123456789012345678901234567890<010>
+The above should not trigger a "line too long error". But this line should!------<010>
+<010>
+SC07.3: Test the limit set at infinity.<010>
+<010>
+"
+0014[01]: Text. Text scrap[Grey]="<010>
+ 1 2 3 4 5 6 7 8<010>
+12345678901234567890123456789012345678901234567890123456789012345678901234567890<010>
+The above should not trigger a "line too long error". Nor should this one!-------<010>
+<010>
+SC07.3: Test the limit set lower.<010>
+<010>
+"
+0022[01]: Text. Text scrap[Grey]="<010>
+ 1 2 3 4 5<010>
+12345678901234567890123456789012345678901234567890<010>
+No error for the above but this line will!---------<010>
+"
+0026[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC07: Processing of long lines.
+ 2 2|
+ 3 3| SC07.1: Detection of a line longer than the default limit.
+ 4 4|
+ 5 5| The default limit is 80 characters so we will test on either side of
+ 6 6| that:
+ 7 7| 1 2 3 4 5 6 7 8
+ 8 8| 12345678901234567890123456789012345678901234567890123456789012345678901234567890
+ 9 9| The above should not trigger a "line too long error". But this line should!------
+ Error|.................................................................................^Input line is too long (this character is the first offender).
+ |.................................................................................^Currently, the maximum allowable input line length is 80.
+ |.................................................................................^Note: You can change this using a pragma directive (@p).
+ 10 10|
+ 11 11| SC07.3: Test the limit set at infinity.
+ 12 12|
+ 13 13| @p maximum_input_line_length = infinity
+ 14 14|
+ 15 15| 1 2 3 4 5 6 7 8
+ 16 16| 12345678901234567890123456789012345678901234567890123456789012345678901234567890
+ 17 17| The above should not trigger a "line too long error". Nor should this one!-------
+ 18 18|
+ 19 19| SC07.3: Test the limit set lower.
+ 20 20|
+ 21 21| @p maximum_input_line_length = 50
+ 22 22|
+ 23 23| 1 2 3 4 5
+ 24 24| 12345678901234567890123456789012345678901234567890
+ 25 25| No error for the above but this line will!---------
+ Error|...................................................^Input line is too long (this character is the first offender).
+ |...................................................^Currently, the maximum allowable input line length is 50.
+ |...................................................^Note: You can change this using a pragma directive (@p).
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 2 Errors.
diff --git a/web/funnelAC/results/sc08.lis b/web/funnelAC/results/sc08.lis
new file mode 100644
index 0000000000..3651c0a371
--- /dev/null
+++ b/web/funnelAC/results/sc08.lis
@@ -0,0 +1,190 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 30 38 3A 20 44 65 74 65 63 74 69 6F 6E 20 | SC08: Detection |
+| 6F 66 20 74 72 61 69 6C 69 6E 67 20 73 70 61 63 | of trailing spac |
+| 65 73 2E 0A 0A 54 68 69 73 20 6C 69 6E 65 20 68 | es...This line h |
+| 61 73 20 7A 65 72 6F 20 20 74 72 61 69 6C 69 6E | as zero trailin |
+| 67 20 73 70 61 63 65 73 20 7C 0A 54 68 69 73 20 | g spaces |.This |
+| 6C 69 6E 65 20 68 61 73 20 6F 6E 65 20 20 20 74 | line has one t |
+| 72 61 69 6C 69 6E 67 20 73 70 61 63 65 20 20 7C | railing space | |
+| 20 0A 54 68 69 73 20 6C 69 6E 65 20 68 61 73 20 | .This line has |
+| 74 77 6F 20 20 20 74 72 61 69 6C 69 6E 67 20 73 | two trailing s |
+| 70 61 63 65 73 20 7C 20 20 0A 54 68 69 73 20 6C | paces | .This l |
+| 69 6E 65 20 68 61 73 20 74 68 72 65 65 20 74 72 | ine has three tr |
+| 61 69 6C 69 6E 67 20 73 70 61 63 65 73 20 7C 20 | ailing spaces | |
+| 20 20 0A | . |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC08: Detection of trailing spaces.<010>
+00002 00002| <010>
+00003 00003| This line has zero trailing spaces |<010>
+00004 00004| This line has one trailing space | <010>
+00005 00005| This line has two trailing spaces | <010>
+00006 00006| This line has three trailing spaces | <010>
+00007 00007| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 2 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC08: Detection of trailing spaces.<010>
+<010>
+This line has zero trailing spaces |<010>
+This line has one trailing space | <010>
+This line has two trailing spaces | <010>
+This line has three trailing spaces | <010>
+"
+0007[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#file"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#line"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#timestamp"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="SC08: Detection of trailing spaces.<010>
+<010>
+This line has zero trailing spaces |<010>
+This line has one trailing space | <010>
+This line has two trailing spaces | <010>
+This line has three trailing spaces | <010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC08: Detection of trailing spaces.
+ 2 2|
+ 3 3| This line has zero trailing spaces |
+ 4 4| This line has one trailing space |
+ Warning|......................................^Line has trailing spaces up to and including this space.
+ 5 5| This line has two trailing spaces |
+ Warning|.......................................^Line has trailing spaces up to and including this space.
+ 6 6| This line has three trailing spaces |
+ Warning|........................................^Line has trailing spaces up to and including this space.
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There was 1 Error and 3 Warnings.
diff --git a/web/funnelAC/results/sc09.lis b/web/funnelAC/results/sc09.lis
new file mode 100644
index 0000000000..eeea2f8c82
--- /dev/null
+++ b/web/funnelAC/results/sc09.lis
@@ -0,0 +1,106 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 30 39 3A 20 44 65 74 65 63 74 69 6F 6E 20 | SC09: Detection |
+| 6F 66 20 63 6F 6E 74 72 6F 6C 20 63 68 61 72 61 | of control chara |
+| 63 74 65 72 73 2E 0A 0A 53 43 30 39 2E 31 20 54 | cters...SC09.1 T |
+| 65 73 74 20 74 68 61 74 20 63 6F 6E 74 72 6F 6C | est that control |
+| 20 63 68 61 72 61 63 74 65 72 73 20 61 72 65 20 | characters are |
+| 64 65 74 65 63 74 65 64 20 61 6E 64 20 72 65 70 | detected and rep |
+| 6C 61 63 65 64 20 62 79 20 22 3F 22 2E 0A 53 43 | laced by "?"..SC |
+| 30 39 2E 32 20 54 65 73 74 20 6E 6F 6E 20 70 72 | 09.2 Test non pr |
+| 69 6E 74 61 62 6C 65 20 74 68 61 74 20 68 61 73 | intable that has |
+| 20 61 20 6D 6E 65 6D 6F 6E 69 63 2E 0A 0A 54 68 | a mnemonic...Th |
+| 65 72 65 20 69 73 20 61 20 74 61 62 20 62 65 74 | ere is a tab bet |
+| 77 65 65 6E 20 74 68 65 73 65 20 74 77 6F 20 62 | ween these two b |
+| 61 72 73 20 7C 09 7C 20 77 68 69 63 68 20 73 68 | ars |.| which sh |
+| 6F 75 6C 64 20 63 6F 6D 65 20 6F 75 74 20 61 73 | ould come out as |
+| 20 22 3F 22 2E 0A 54 68 65 20 61 62 6F 76 65 20 | "?"..The above |
+| 65 72 72 6F 72 20 6D 65 73 73 61 67 65 20 73 68 | error message sh |
+| 6F 75 6C 64 20 63 6F 6E 74 61 69 6E 20 74 68 65 | ould contain the |
+| 20 6D 6E 65 6D 6F 6E 69 63 20 22 48 54 22 2E 0A | mnemonic "HT".. |
+| 0A 53 43 30 39 2E 33 20 54 65 73 74 20 6E 6F 6E | .SC09.3 Test non |
+| 20 70 72 69 6E 74 61 62 6C 65 20 74 68 61 74 20 | printable that |
+| 68 61 73 20 6E 6F 20 6D 6E 65 6D 6F 6E 69 63 2E | has no mnemonic. |
+| 0A 0A 54 68 65 72 65 20 69 73 20 61 20 6E 6F 6E | ..There is a non |
+| 2D 6D 6E 65 6D 6F 6E 69 63 20 63 6F 6E 74 72 6F | -mnemonic contro |
+| 6C 20 63 68 61 72 61 63 74 65 72 20 62 65 74 77 | l character betw |
+| 65 65 6E 20 74 68 65 73 65 20 62 61 72 73 20 7C | een these bars | |
+| EA 7C 2E 0A | .|.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC09: Detection of control characters.<010>
+00002 00002| <010>
+00003 00003| SC09.1 Test that control characters are detected and replaced by "?".<010>
+00004 00004| SC09.2 Test non printable that has a mnemonic.<010>
+00005 00005| <010>
+00006 00006| There is a tab between these two bars |?| which should come out as "?".<010>
+00007 00007| The above error message should contain the mnemonic "HT".<010>
+00008 00008| <010>
+00009 00009| SC09.3 Test non printable that has no mnemonic.<010>
+00010 00010| <010>
+00011 00011| There is a non-mnemonic control character between these bars |?|.<010>
+00012 00012| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 2 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC09: Detection of control characters.<010>
+<010>
+SC09.1 Test that control characters are detected and replaced by "?".<010>
+SC09.2 Test non printable that has a mnemonic.<010>
+<010>
+There is a tab between these two bars |?| which should come out as "?".<010>
+The above error message should contain the mnemonic "HT".<010>
+<010>
+SC09.3 Test non printable that has no mnemonic.<010>
+<010>
+There is a non-mnemonic control character between these bars |?|.<010>
+"
+0012[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC09: Detection of control characters.
+ 2 2|
+ 3 3| SC09.1 Test that control characters are detected and replaced by "?".
+ 4 4| SC09.2 Test non printable that has a mnemonic.
+ 5 5|
+ 6 6| There is a tab between these two bars |?| which should come out as "?".
+ Error|........................................^Non printable character (Sym=HT, Dec=009, Hex=09, Oct=011).
+ 7 7| The above error message should contain the mnemonic "HT".
+ 8 8|
+ 9 9| SC09.3 Test non printable that has no mnemonic.
+ 10 10|
+ 11 11| There is a non-mnemonic control character between these bars |?|.
+ Error|...............................................................^Non printable character (Sym=<none>, Dec=234, Hex=EA, Oct=352).
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 2 Errors.
diff --git a/web/funnelAC/results/sc10.lis b/web/funnelAC/results/sc10.lis
new file mode 100644
index 0000000000..55bfe19df8
--- /dev/null
+++ b/web/funnelAC/results/sc10.lis
@@ -0,0 +1,882 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 63 61 6E 6E 65 72 20 54 65 73 74 3A 20 53 70 | Scanner Test: Sp |
+| 65 63 69 61 6C 20 53 65 71 75 65 6E 63 65 20 52 | ecial Sequence R |
+| 65 63 6F 67 6E 69 74 69 6F 6E 0A 3D 3D 3D 3D 3D | ecognition.===== |
+| 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D | ================ |
+| 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D | ================ |
+| 3D 3D 3D 3D 3D 0A 54 68 69 73 20 74 65 73 74 20 | =====.This test |
+| 74 65 73 74 73 20 74 6F 20 73 65 65 20 74 68 61 | tests to see tha |
+| 74 20 46 75 6E 6E 65 6C 57 65 62 20 69 73 20 72 | t FunnelWeb is r |
+| 65 63 6F 67 6E 69 73 69 6E 67 20 74 68 65 20 66 | ecognising the f |
+| 75 6C 6C 20 73 65 74 20 6F 66 20 73 70 65 63 69 | ull set of speci |
+| 61 6C 0A 73 65 71 75 65 6E 63 65 73 2E 0A 0A 54 | al.sequences...T |
+| 75 72 6E 20 4F 66 66 20 74 68 65 20 50 61 72 73 | urn Off the Pars |
+| 65 72 0A 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D | er.------------- |
+| 2D 2D 2D 2D 2D 2D 0A 46 69 72 73 74 20 77 65 20 | ------.First we |
+| 63 61 75 73 65 20 61 20 64 65 6C 69 62 65 72 61 | cause a delibera |
+| 74 65 20 73 63 61 6E 6E 65 72 20 65 72 72 6F 72 | te scanner error |
+| 20 73 6F 20 61 73 20 74 6F 20 70 72 65 76 65 6E | so as to preven |
+| 74 20 74 68 65 20 70 61 72 73 65 72 20 66 72 6F | t the parser fro |
+| 6D 0A 67 65 6E 65 72 61 74 69 6E 67 20 6C 6F 74 | m.generating lot |
+| 73 20 6F 66 20 65 72 72 6F 72 73 20 6F 76 65 72 | s of errors over |
+| 20 74 68 65 20 73 79 6E 74 61 63 74 69 63 20 72 | the syntactic r |
+| 75 62 62 69 73 68 20 70 72 65 73 65 6E 74 65 64 | ubbish presented |
+| 20 68 65 72 65 2E 0A 0A 20 20 20 40 20 0A 0A 4C | here... @ ..L |
+| 69 73 74 20 6F 66 20 41 6C 6C 20 50 6F 73 73 69 | ist of All Possi |
+| 62 6C 65 20 53 70 65 63 69 61 6C 20 53 65 71 75 | ble Special Sequ |
+| 65 6E 63 65 73 0A 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D | ences.---------- |
+| 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D | ---------------- |
+| 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 0A 54 68 65 | ------------.The |
+| 20 66 6F 6C 6C 6F 77 69 6E 67 20 69 73 20 61 20 | following is a |
+| 6C 69 73 74 20 6F 66 20 74 68 65 20 64 65 66 61 | list of the defa |
+| 75 6C 74 20 73 70 65 63 69 61 6C 20 63 68 61 72 | ult special char |
+| 61 63 74 65 72 20 66 6F 6C 6C 6F 77 65 64 20 62 | acter followed b |
+| 79 20 65 61 63 68 20 6F 66 0A 74 68 65 20 41 53 | y each of.the AS |
+| 43 49 49 20 70 72 69 6E 74 61 62 6C 65 73 2E 0A | CII printables.. |
+| 30 30 30 20 74 6F 20 30 33 31 20 61 72 65 20 75 | 000 to 031 are u |
+| 6E 70 72 69 6E 74 61 62 6C 65 20 63 6F 6E 74 72 | nprintable contr |
+| 6F 6C 20 63 68 61 72 61 63 74 65 72 73 2E 0A 0A | ol characters... |
+| 30 33 32 20 20 40 20 20 20 20 2D 20 49 4C 4C 45 | 032 @ - ILLE |
+| 47 41 4C 2E 20 20 28 4E 6F 74 65 3A 20 48 79 70 | GAL. (Note: Hyp |
+| 68 65 6E 20 69 73 20 6E 65 65 64 65 64 20 74 6F | hen is needed to |
+| 20 61 76 6F 69 64 20 74 72 61 69 6C 69 6E 67 20 | avoid trailing |
+| 62 6C 61 6E 6B 73 20 65 72 72 6F 72 2E 29 0A 30 | blanks error.).0 |
+| 33 33 20 20 40 21 20 20 20 2D 20 43 6F 6D 6D 65 | 33 @! - Comme |
+| 6E 74 2E 0A 30 33 34 20 20 40 22 20 20 20 2D 20 | nt..034 @" - |
+| 50 61 72 61 6D 65 74 65 72 20 64 65 6C 69 6D 65 | Parameter delime |
+| 74 65 72 2E 0A 30 33 35 20 20 40 23 58 20 20 2D | ter..035 @#X - |
+| 20 53 68 6F 72 74 20 6E 61 6D 65 20 73 65 71 75 | Short name sequ |
+| 65 6E 63 65 2E 0A 40 24 20 20 20 30 33 36 20 20 | ence..@$ 036 |
+| 2D 20 44 65 66 69 6E 65 20 6D 61 63 72 6F 2E 20 | - Define macro. |
+| 48 61 73 20 74 6F 20 62 65 20 61 74 20 73 74 61 | Has to be at sta |
+| 72 74 20 6F 66 20 6C 69 6E 65 2E 0A 30 33 37 20 | rt of line..037 |
+| 20 40 25 20 20 20 2D 20 49 4C 4C 45 47 41 4C 2E | @% - ILLEGAL. |
+| 0A 30 33 38 20 20 40 26 20 20 20 2D 20 49 4C 4C | .038 @& - ILL |
+| 45 47 41 4C 2E 0A 30 33 39 20 20 40 27 20 20 20 | EGAL..039 @' |
+| 2D 20 49 4C 4C 45 47 41 4C 2E 0A 30 34 30 20 20 | - ILLEGAL..040 |
+| 40 28 20 20 20 2D 20 4F 70 65 6E 20 70 61 72 61 | @( - Open para |
+| 6D 65 74 65 72 20 6C 69 73 74 2E 0A 30 34 31 20 | meter list..041 |
+| 20 40 29 20 20 20 2D 20 43 6C 6F 73 65 20 70 61 | @) - Close pa |
+| 72 61 6D 65 74 65 72 20 6C 69 73 74 2E 0A 30 34 | rameter list..04 |
+| 32 0A 40 2A 20 20 20 20 20 20 20 20 2D 20 4F 6C | 2.@* - Ol |
+| 64 20 66 61 73 68 69 6F 6E 65 64 20 73 65 63 74 | d fashioned sect |
+| 69 6F 6E 20 6D 61 72 6B 65 72 20 28 68 61 73 20 | ion marker (has |
+| 74 6F 20 62 65 20 61 74 20 73 74 61 72 74 20 6F | to be at start o |
+| 66 20 61 20 6C 69 6E 65 2E 29 2E 0A 30 34 33 20 | f a line.)..043 |
+| 20 40 2B 20 20 20 2D 20 49 6E 73 65 72 74 20 6E | @+ - Insert n |
+| 65 77 6C 69 6E 65 2E 0A 30 34 34 20 20 40 2C 20 | ewline..044 @, |
+| 20 20 2D 20 50 61 72 61 6D 65 74 65 72 20 73 65 | - Parameter se |
+| 70 61 72 61 74 6F 72 2E 0A 30 34 35 20 20 40 2D | parator..045 @- |
+| 0A 20 20 20 20 20 20 20 20 20 20 2D 20 49 67 6E | . - Ign |
+| 6F 72 65 20 65 6E 64 20 6F 66 20 6C 69 6E 65 20 | ore end of line |
+| 6D 61 72 6B 65 72 20 28 68 61 73 20 74 6F 20 62 | marker (has to b |
+| 65 20 61 74 20 65 6E 64 20 6F 66 20 6C 69 6E 65 | e at end of line |
+| 29 2E 0A 30 34 36 20 20 40 2E 20 20 20 2D 20 49 | )..046 @. - I |
+| 4C 4C 45 47 41 4C 2E 0A 30 34 37 20 20 40 2F 20 | LLEGAL..047 @/ |
+| 20 20 2D 20 45 6D 70 68 61 73 69 73 65 64 20 74 | - Emphasised t |
+| 65 78 74 2E 0A 30 34 38 20 20 40 30 20 20 20 2D | ext..048 @0 - |
+| 20 49 4C 4C 45 47 41 4C 2E 0A 30 34 39 20 20 40 | ILLEGAL..049 @ |
+| 31 20 20 20 2D 20 46 6F 72 6D 61 6C 20 70 61 72 | 1 - Formal par |
+| 61 6D 65 74 65 72 20 31 2E 0A 30 35 30 20 20 40 | ameter 1..050 @ |
+| 32 20 20 20 2D 20 46 6F 72 6D 61 6C 20 70 61 72 | 2 - Formal par |
+| 61 6D 65 74 65 72 20 32 2E 0A 30 35 31 20 20 40 | ameter 2..051 @ |
+| 33 20 20 20 2D 20 46 6F 72 6D 61 6C 20 70 61 72 | 3 - Formal par |
+| 61 6D 65 74 65 72 20 33 2E 0A 30 35 32 20 20 40 | ameter 3..052 @ |
+| 34 20 20 20 2D 20 46 6F 72 6D 61 6C 20 70 61 72 | 4 - Formal par |
+| 61 6D 65 74 65 72 20 34 2E 0A 30 35 33 20 20 40 | ameter 4..053 @ |
+| 35 20 20 20 2D 20 46 6F 72 6D 61 6C 20 70 61 72 | 5 - Formal par |
+| 61 6D 65 74 65 72 20 35 2E 0A 30 35 34 20 20 40 | ameter 5..054 @ |
+| 36 20 20 20 2D 20 46 6F 72 6D 61 6C 20 70 61 72 | 6 - Formal par |
+| 61 6D 65 74 65 72 20 36 2E 0A 30 35 35 20 20 40 | ameter 6..055 @ |
+| 37 20 20 20 2D 20 46 6F 72 6D 61 6C 20 70 61 72 | 7 - Formal par |
+| 61 6D 65 74 65 72 20 37 2E 0A 30 35 36 20 20 40 | ameter 7..056 @ |
+| 38 20 20 20 2D 20 46 6F 72 6D 61 6C 20 70 61 72 | 8 - Formal par |
+| 61 6D 65 74 65 72 20 38 2E 0A 30 35 37 20 20 40 | ameter 8..057 @ |
+| 39 20 20 20 2D 20 46 6F 72 6D 61 6C 20 70 61 72 | 9 - Formal par |
+| 61 6D 65 74 65 72 20 39 2E 0A 30 35 38 20 20 40 | ameter 9..058 @ |
+| 3A 20 20 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 30 | : - ILLEGAL..0 |
+| 35 39 20 20 40 3B 20 20 20 2D 20 49 4C 4C 45 47 | 59 @; - ILLEG |
+| 41 4C 2E 0A 30 36 30 20 20 40 3C 20 20 20 2D 20 | AL..060 @< - |
+| 4F 70 65 6E 20 6D 61 63 72 6F 20 6E 61 6D 65 2E | Open macro name. |
+| 0A 30 36 31 20 20 40 3D 40 20 20 2D 20 53 65 74 | .061 @=@ - Set |
+| 20 73 70 65 63 69 61 6C 20 63 68 61 72 61 63 74 | special charact |
+| 65 72 2E 0A 30 36 32 20 20 40 3E 20 20 20 2D 20 | er..062 @> - |
+| 43 6C 6F 73 65 20 6D 61 63 72 6F 20 6E 61 6D 65 | Close macro name |
+| 2E 0A 30 36 33 20 20 40 3F 20 20 20 2D 20 49 4C | ..063 @? - IL |
+| 4C 45 47 41 4C 2E 0A 30 36 34 20 20 40 40 20 20 | LEGAL..064 @@ |
+| 20 2D 20 49 6E 73 65 72 74 20 73 70 65 63 69 61 | - Insert specia |
+| 6C 20 63 68 61 72 61 63 74 65 72 20 69 6E 74 6F | l character into |
+| 20 74 65 78 74 2E 0A 40 41 20 20 30 36 35 20 20 | text..@A 065 |
+| 20 2D 20 4E 65 77 20 73 65 63 74 69 6F 6E 20 28 | - New section ( |
+| 6C 65 76 65 6C 20 31 29 2E 20 4D 75 73 74 20 62 | level 1). Must b |
+| 65 20 61 74 20 73 74 61 72 74 20 6F 66 20 61 20 | e at start of a |
+| 6C 69 6E 65 2E 0A 40 42 20 20 30 36 36 20 20 20 | line..@B 066 |
+| 2D 20 4E 65 77 20 73 65 63 74 69 6F 6E 20 28 6C | - New section (l |
+| 65 76 65 6C 20 32 29 2E 20 4D 75 73 74 20 62 65 | evel 2). Must be |
+| 20 61 74 20 73 74 61 72 74 20 6F 66 20 61 20 6C | at start of a l |
+| 69 6E 65 2E 0A 40 43 20 20 30 36 37 20 20 20 2D | ine..@C 067 - |
+| 20 4E 65 77 20 73 65 63 74 69 6F 6E 20 28 6C 65 | New section (le |
+| 76 65 6C 20 33 29 2E 20 4D 75 73 74 20 62 65 20 | vel 3). Must be |
+| 61 74 20 73 74 61 72 74 20 6F 66 20 61 20 6C 69 | at start of a li |
+| 6E 65 2E 0A 40 44 20 20 30 36 38 20 20 20 2D 20 | ne..@D 068 - |
+| 4E 65 77 20 73 65 63 74 69 6F 6E 20 28 6C 65 76 | New section (lev |
+| 65 6C 20 34 29 2E 20 4D 75 73 74 20 62 65 20 61 | el 4). Must be a |
+| 74 20 73 74 61 72 74 20 6F 66 20 61 20 6C 69 6E | t start of a lin |
+| 65 2E 0A 40 45 20 20 30 36 39 20 20 20 2D 20 4E | e..@E 069 - N |
+| 65 77 20 73 65 63 74 69 6F 6E 20 28 6C 65 76 65 | ew section (leve |
+| 6C 20 35 29 2E 20 4D 75 73 74 20 62 65 20 61 74 | l 5). Must be at |
+| 20 73 74 61 72 74 20 6F 66 20 61 20 6C 69 6E 65 | start of a line |
+| 2E 0A 30 37 30 20 20 40 46 20 20 20 2D 20 49 4C | ..070 @F - IL |
+| 4C 45 47 41 4C 2E 0A 30 37 31 20 20 40 47 20 20 | LEGAL..071 @G |
+| 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 30 37 32 20 | - ILLEGAL..072 |
+| 20 40 48 20 20 20 2D 20 49 4C 4C 45 47 41 4C 2E | @H - ILLEGAL. |
+| 0A 30 37 33 20 20 40 49 20 20 20 2D 20 49 6E 63 | .073 @I - Inc |
+| 6C 75 64 65 20 66 69 6C 65 2E 20 57 69 6C 6C 20 | lude file. Will |
+| 70 72 6F 76 6F 6B 65 20 61 6E 20 65 72 72 6F 72 | provoke an error |
+| 20 68 65 72 65 20 74 68 6F 75 67 68 2E 0A 30 37 | here though..07 |
+| 34 20 20 40 4A 20 20 20 2D 20 49 4C 4C 45 47 41 | 4 @J - ILLEGA |
+| 4C 2E 0A 30 37 35 20 20 40 4B 20 20 20 2D 20 49 | L..075 @K - I |
+| 4C 4C 45 47 41 4C 2E 0A 30 37 36 20 20 40 4C 20 | LLEGAL..076 @L |
+| 20 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 30 37 37 | - ILLEGAL..077 |
+| 20 20 40 4D 20 20 20 2D 20 54 61 67 73 20 6D 61 | @M - Tags ma |
+| 63 72 6F 20 61 73 20 62 65 69 6E 67 20 61 6C 6C | cro as being all |
+| 6F 77 65 64 20 74 6F 20 62 65 20 63 61 6C 6C 65 | owed to be calle |
+| 64 20 6D 61 6E 79 20 74 69 6D 65 73 2E 0A 30 37 | d many times..07 |
+| 38 20 20 40 4E 20 20 20 2D 20 49 4C 4C 45 47 41 | 8 @N - ILLEGA |
+| 4C 2E 0A 40 4F 20 20 20 30 37 39 20 20 2D 20 4E | L..@O 079 - N |
+| 65 77 20 6D 61 63 72 6F 20 61 74 74 61 63 68 65 | ew macro attache |
+| 64 20 74 6F 20 6F 75 74 70 75 74 20 66 69 6C 65 | d to output file |
+| 2E 20 48 61 73 20 74 6F 20 62 65 20 61 74 20 73 | . Has to be at s |
+| 74 61 72 74 20 6F 66 20 6C 69 6E 65 2E 0A 30 38 | tart of line..08 |
+| 30 20 20 40 50 20 20 20 2D 20 50 72 61 67 6D 61 | 0 @P - Pragma |
+| 2E 20 57 69 6C 6C 20 63 61 75 73 65 20 65 72 72 | . Will cause err |
+| 6F 72 20 68 65 72 65 20 74 68 6F 75 67 68 2E 0A | or here though.. |
+| 30 38 31 20 20 40 51 20 20 20 2D 20 49 4C 4C 45 | 081 @Q - ILLE |
+| 47 41 4C 2E 0A 30 38 32 20 20 40 52 20 20 20 2D | GAL..082 @R - |
+| 20 49 4C 4C 45 47 41 4C 2E 0A 30 38 33 20 20 40 | ILLEGAL..083 @ |
+| 53 20 20 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 30 | S - ILLEGAL..0 |
+| 38 34 20 20 40 54 20 20 20 2D 20 54 79 70 65 73 | 84 @T - Types |
+| 65 74 74 65 72 20 64 69 72 65 63 74 69 76 65 2E | etter directive. |
+| 20 57 69 6C 6C 20 63 61 75 73 65 20 61 6E 20 65 | Will cause an e |
+| 72 72 6F 72 20 68 65 72 65 20 74 68 6F 75 67 68 | rror here though |
+| 2E 0A 30 38 35 20 20 40 55 20 20 20 2D 20 49 4C | ..085 @U - IL |
+| 4C 45 47 41 4C 2E 0A 30 38 36 20 20 40 56 20 20 | LEGAL..086 @V |
+| 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 30 38 37 20 | - ILLEGAL..087 |
+| 20 40 57 20 20 20 2D 20 49 4C 4C 45 47 41 4C 2E | @W - ILLEGAL. |
+| 0A 30 38 38 20 20 40 58 20 20 20 2D 20 49 4C 4C | .088 @X - ILL |
+| 45 47 41 4C 2E 0A 30 38 39 20 20 40 59 20 20 20 | EGAL..089 @Y |
+| 2D 20 49 4C 4C 45 47 41 4C 2E 0A 30 39 30 20 20 | - ILLEGAL..090 |
+| 40 5A 20 20 20 2D 20 54 61 67 73 20 6D 61 63 72 | @Z - Tags macr |
+| 6F 20 61 73 20 62 65 69 6E 67 20 61 6C 6C 6F 77 | o as being allow |
+| 65 64 20 74 6F 20 62 65 20 63 61 6C 6C 65 64 20 | ed to be called |
+| 7A 65 72 6F 20 74 69 6D 65 73 2E 0A 30 39 31 20 | zero times..091 |
+| 20 40 5B 20 20 20 2D 20 49 4C 4C 45 47 41 4C 2E | @[ - ILLEGAL. |
+| 0A 30 39 32 20 20 40 5C 20 20 20 2D 20 49 4C 4C | .092 @\ - ILL |
+| 45 47 41 4C 2E 0A 30 39 33 20 20 40 5D 20 20 20 | EGAL..093 @] |
+| 2D 20 49 4C 4C 45 47 41 4C 2E 0A 30 39 34 20 20 | - ILLEGAL..094 |
+| 40 5E 44 28 30 36 35 29 20 2D 20 49 6E 73 65 72 | @^D(065) - Inser |
+| 74 20 63 6F 6E 74 72 6F 6C 20 63 68 61 72 61 63 | t control charac |
+| 74 65 72 20 69 6E 74 6F 20 74 65 78 74 0A 30 39 | ter into text.09 |
+| 35 20 20 40 5F 20 20 20 2D 20 49 4C 4C 45 47 41 | 5 @_ - ILLEGA |
+| 4C 2E 0A 30 39 36 20 20 40 60 20 20 20 2D 20 49 | L..096 @` - I |
+| 4C 4C 45 47 41 4C 2E 0A 40 61 20 20 20 30 39 37 | LLEGAL..@a 097 |
+| 20 20 2D 20 4E 65 77 20 73 65 63 74 69 6F 6E 20 | - New section |
+| 28 6C 65 76 65 6C 20 31 29 2E 20 4D 75 73 74 20 | (level 1). Must |
+| 62 65 20 61 74 20 73 74 61 72 74 20 6F 66 20 61 | be at start of a |
+| 20 6C 69 6E 65 2E 0A 40 62 20 20 20 30 39 38 20 | line..@b 098 |
+| 20 2D 20 4E 65 77 20 73 65 63 74 69 6F 6E 20 28 | - New section ( |
+| 6C 65 76 65 6C 20 31 29 2E 20 4D 75 73 74 20 62 | level 1). Must b |
+| 65 20 61 74 20 73 74 61 72 74 20 6F 66 20 61 20 | e at start of a |
+| 6C 69 6E 65 2E 0A 40 63 20 20 20 30 39 39 20 20 | line..@c 099 |
+| 2D 20 4E 65 77 20 73 65 63 74 69 6F 6E 20 28 6C | - New section (l |
+| 65 76 65 6C 20 31 29 2E 20 4D 75 73 74 20 62 65 | evel 1). Must be |
+| 20 61 74 20 73 74 61 72 74 20 6F 66 20 61 20 6C | at start of a l |
+| 69 6E 65 2E 0A 40 64 20 20 20 31 30 30 20 20 2D | ine..@d 100 - |
+| 20 4E 65 77 20 73 65 63 74 69 6F 6E 20 28 6C 65 | New section (le |
+| 76 65 6C 20 31 29 2E 20 4D 75 73 74 20 62 65 20 | vel 1). Must be |
+| 61 74 20 73 74 61 72 74 20 6F 66 20 61 20 6C 69 | at start of a li |
+| 6E 65 2E 0A 40 65 20 20 20 31 30 31 20 20 2D 20 | ne..@e 101 - |
+| 4E 65 77 20 73 65 63 74 69 6F 6E 20 28 6C 65 76 | New section (lev |
+| 65 6C 20 31 29 2E 20 4D 75 73 74 20 62 65 20 61 | el 1). Must be a |
+| 74 20 73 74 61 72 74 20 6F 66 20 61 20 6C 69 6E | t start of a lin |
+| 65 2E 0A 31 30 32 20 20 40 66 20 20 20 2D 20 49 | e..102 @f - I |
+| 4C 4C 45 47 41 4C 2E 0A 31 30 33 20 20 40 67 20 | LLEGAL..103 @g |
+| 20 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 31 30 34 | - ILLEGAL..104 |
+| 20 20 40 68 20 20 20 2D 20 49 4C 4C 45 47 41 4C | @h - ILLEGAL |
+| 2E 0A 31 30 35 20 20 40 69 20 20 20 2D 20 49 6E | ..105 @i - In |
+| 63 6C 75 64 65 20 66 69 6C 65 2E 20 57 69 6C 6C | clude file. Will |
+| 20 70 72 6F 76 6F 6B 65 20 61 6E 20 65 72 72 6F | provoke an erro |
+| 72 20 68 65 72 65 20 74 68 6F 75 67 68 2E 0A 31 | r here though..1 |
+| 30 36 20 20 40 6A 20 20 20 2D 20 49 4C 4C 45 47 | 06 @j - ILLEG |
+| 41 4C 2E 0A 31 30 37 20 20 40 6B 20 20 20 2D 20 | AL..107 @k - |
+| 49 4C 4C 45 47 41 4C 2E 0A 31 30 38 20 20 40 6C | ILLEGAL..108 @l |
+| 20 20 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 31 30 | - ILLEGAL..10 |
+| 39 20 20 40 6D 20 20 20 2D 20 54 61 67 73 20 6D | 9 @m - Tags m |
+| 61 63 72 6F 20 61 73 20 62 65 69 6E 67 20 61 6C | acro as being al |
+| 6C 6F 77 65 64 20 74 6F 20 62 65 20 63 61 6C 6C | lowed to be call |
+| 65 64 20 6D 61 6E 79 20 74 69 6D 65 73 2E 0A 31 | ed many times..1 |
+| 31 30 20 20 40 6E 20 20 20 2D 20 49 4C 4C 45 47 | 10 @n - ILLEG |
+| 41 4C 2E 0A 40 4F 20 20 20 31 31 31 20 20 2D 20 | AL..@O 111 - |
+| 4E 65 77 20 6D 61 63 72 6F 20 61 74 74 61 63 68 | New macro attach |
+| 65 64 20 74 6F 20 6F 75 74 70 75 74 20 66 69 6C | ed to output fil |
+| 65 2E 20 48 61 73 20 74 6F 20 62 65 20 61 74 20 | e. Has to be at |
+| 73 74 61 72 74 20 6F 66 20 6C 69 6E 65 2E 0A 31 | start of line..1 |
+| 31 32 20 20 40 70 20 20 20 2D 20 50 72 61 67 6D | 12 @p - Pragm |
+| 61 2E 20 57 69 6C 6C 20 63 61 75 73 65 20 65 72 | a. Will cause er |
+| 72 6F 72 20 68 65 72 65 20 74 68 6F 75 67 68 2E | ror here though. |
+| 0A 31 31 33 20 20 40 71 20 20 20 2D 20 49 4C 4C | .113 @q - ILL |
+| 45 47 41 4C 2E 0A 31 31 34 20 20 40 72 20 20 20 | EGAL..114 @r |
+| 2D 20 49 4C 4C 45 47 41 4C 2E 0A 31 31 35 20 20 | - ILLEGAL..115 |
+| 40 73 20 20 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A | @s - ILLEGAL.. |
+| 31 31 36 20 20 40 74 20 20 20 2D 20 54 79 70 65 | 116 @t - Type |
+| 73 65 74 74 65 72 20 64 69 72 65 63 74 69 76 65 | setter directive |
+| 2E 20 57 69 6C 6C 20 63 61 75 73 65 20 61 6E 20 | . Will cause an |
+| 65 72 72 6F 72 20 68 65 72 65 20 74 68 6F 75 67 | error here thoug |
+| 68 2E 0A 31 31 37 20 20 40 75 20 20 20 2D 20 49 | h..117 @u - I |
+| 4C 4C 45 47 41 4C 2E 0A 31 31 38 20 20 40 76 20 | LLEGAL..118 @v |
+| 20 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 31 31 39 | - ILLEGAL..119 |
+| 20 20 40 77 20 20 20 2D 20 49 4C 4C 45 47 41 4C | @w - ILLEGAL |
+| 2E 0A 31 32 30 20 20 40 78 20 20 20 2D 20 49 4C | ..120 @x - IL |
+| 4C 45 47 41 4C 2E 0A 31 32 31 20 20 40 79 20 20 | LEGAL..121 @y |
+| 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 31 32 32 20 | - ILLEGAL..122 |
+| 20 40 7A 20 20 20 2D 20 54 61 67 73 20 6D 61 63 | @z - Tags mac |
+| 72 6F 20 61 73 20 62 65 69 6E 67 20 61 6C 6C 6F | ro as being allo |
+| 77 65 64 20 74 6F 20 62 65 20 63 61 6C 6C 65 64 | wed to be called |
+| 20 7A 65 72 6F 20 74 69 6D 65 73 2E 0A 31 32 33 | zero times..123 |
+| 20 20 40 7B 20 20 20 2D 20 4F 70 65 6E 20 6D 61 | @{ - Open ma |
+| 63 72 6F 20 62 6F 64 79 2E 0A 31 32 34 20 20 40 | cro body..124 @ |
+| 7C 20 20 20 2D 20 49 4C 4C 45 47 41 4C 2E 0A 31 | | - ILLEGAL..1 |
+| 32 35 20 20 40 7D 20 20 20 2D 20 43 6C 6F 73 65 | 25 @} - Close |
+| 20 6D 61 63 72 6F 20 62 6F 64 79 2E 0A 31 32 36 | macro body..126 |
+| 20 20 40 7E 20 20 20 2D 20 49 4C 4C 45 47 41 4C | @~ - ILLEGAL |
+| 2E 0A 31 32 37 20 74 6F 20 32 35 35 20 61 72 65 | ..127 to 255 are |
+| 20 6E 6F 74 20 73 74 61 6E 64 61 72 64 20 70 72 | not standard pr |
+| 69 6E 74 61 62 6C 65 20 41 53 43 49 49 20 63 68 | intable ASCII ch |
+| 61 72 61 63 74 65 72 73 2E 0A | aracters.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| Scanner Test: Special Sequence Recognition<010>
+00002 00002| ==========================================<010>
+00003 00003| This test tests to see that FunnelWeb is recognising the full set of special<010>
+00004 00004| sequences.<010>
+00005 00005| <010>
+00006 00006| Turn Off the Parser<010>
+00007 00007| -------------------<010>
+00008 00008| First we cause a deliberate scanner error so as to prevent the parser from<010>
+00009 00009| generating lots of errors over the syntactic rubbish presented here.<010>
+00010 00010| <010>
+00011 00011| @ <010>
+00012 00012| <010>
+00013 00013| List of All Possible Special Sequences<010>
+00014 00014| --------------------------------------<010>
+00015 00015| The following is a list of the default special character followed by each of<010>
+00016 00016| the ASCII printables.<010>
+00017 00017| 000 to 031 are unprintable control characters.<010>
+00018 00018| <010>
+00019 00019| 032 @ - ILLEGAL. (Note: Hyphen is needed to avoid trailing blanks error.)<010>
+00020 00020| 033 @! - Comment.<010>
+00021 00021| 034 @" - Parameter delimeter.<010>
+00022 00022| 035 @#X - Short name sequence.<010>
+00023 00023| @$ 036 - Define macro. Has to be at start of line.<010>
+00024 00024| 037 @% - ILLEGAL.<010>
+00025 00025| 038 @& - ILLEGAL.<010>
+00026 00026| 039 @' - ILLEGAL.<010>
+00027 00027| 040 @( - Open parameter list.<010>
+00028 00028| 041 @) - Close parameter list.<010>
+00029 00029| 042<010>
+00030 00030| @* - Old fashioned section marker (has to be at start of a line.).<010>
+00031 00031| 043 @+ - Insert newline.<010>
+00032 00032| 044 @, - Parameter separator.<010>
+00033 00033| 045 @-<010>
+00034 00034| - Ignore end of line marker (has to be at end of line).<010>
+00035 00035| 046 @. - ILLEGAL.<010>
+00036 00036| 047 @/ - Emphasised text.<010>
+00037 00037| 048 @0 - ILLEGAL.<010>
+00038 00038| 049 @1 - Formal parameter 1.<010>
+00039 00039| 050 @2 - Formal parameter 2.<010>
+00040 00040| 051 @3 - Formal parameter 3.<010>
+00041 00041| 052 @4 - Formal parameter 4.<010>
+00042 00042| 053 @5 - Formal parameter 5.<010>
+00043 00043| 054 @6 - Formal parameter 6.<010>
+00044 00044| 055 @7 - Formal parameter 7.<010>
+00045 00045| 056 @8 - Formal parameter 8.<010>
+00046 00046| 057 @9 - Formal parameter 9.<010>
+00047 00047| 058 @: - ILLEGAL.<010>
+00048 00048| 059 @; - ILLEGAL.<010>
+00049 00049| 060 @< - Open macro name.<010>
+00050 00050| 061 @=@ - Set special character.<010>
+00051 00051| 062 @> - Close macro name.<010>
+00052 00052| 063 @? - ILLEGAL.<010>
+00053 00053| 064 @@ - Insert special character into text.<010>
+00054 00054| @A 065 - New section (level 1). Must be at start of a line.<010>
+00055 00055| @B 066 - New section (level 2). Must be at start of a line.<010>
+00056 00056| @C 067 - New section (level 3). Must be at start of a line.<010>
+00057 00057| @D 068 - New section (level 4). Must be at start of a line.<010>
+00058 00058| @E 069 - New section (level 5). Must be at start of a line.<010>
+00059 00059| 070 @F - ILLEGAL.<010>
+00060 00060| 071 @G - ILLEGAL.<010>
+00061 00061| 072 @H - ILLEGAL.<010>
+00062 00062| 073 @I - Include file. Will provoke an error here though.<010>
+00063 00063| 074 @J - ILLEGAL.<010>
+00064 00064| 075 @K - ILLEGAL.<010>
+00065 00065| 076 @L - ILLEGAL.<010>
+00066 00066| 077 @M - Tags macro as being allowed to be called many times.<010>
+00067 00067| 078 @N - ILLEGAL.<010>
+00068 00068| @O 079 - New macro attached to output file. Has to be at start of line.<010>
+00069 00069| 080 @P - Pragma. Will cause error here though.<010>
+00070 00070| 081 @Q - ILLEGAL.<010>
+00071 00071| 082 @R - ILLEGAL.<010>
+00072 00072| 083 @S - ILLEGAL.<010>
+00073 00073| 084 @T - Typesetter directive. Will cause an error here though.<010>
+00074 00074| 085 @U - ILLEGAL.<010>
+00075 00075| 086 @V - ILLEGAL.<010>
+00076 00076| 087 @W - ILLEGAL.<010>
+00077 00077| 088 @X - ILLEGAL.<010>
+00078 00078| 089 @Y - ILLEGAL.<010>
+00079 00079| 090 @Z - Tags macro as being allowed to be called zero times.<010>
+00080 00080| 091 @[ - ILLEGAL.<010>
+00081 00081| 092 @\ - ILLEGAL.<010>
+00082 00082| 093 @] - ILLEGAL.<010>
+00083 00083| 094 @^D(065) - Insert control character into text<010>
+00084 00084| 095 @_ - ILLEGAL.<010>
+00085 00085| 096 @` - ILLEGAL.<010>
+00086 00086| @a 097 - New section (level 1). Must be at start of a line.<010>
+00087 00087| @b 098 - New section (level 1). Must be at start of a line.<010>
+00088 00088| @c 099 - New section (level 1). Must be at start of a line.<010>
+00089 00089| @d 100 - New section (level 1). Must be at start of a line.<010>
+00090 00090| @e 101 - New section (level 1). Must be at start of a line.<010>
+00091 00091| 102 @f - ILLEGAL.<010>
+00092 00092| 103 @g - ILLEGAL.<010>
+00093 00093| 104 @h - ILLEGAL.<010>
+00094 00094| 105 @i - Include file. Will provoke an error here though.<010>
+00095 00095| 106 @j - ILLEGAL.<010>
+00096 00096| 107 @k - ILLEGAL.<010>
+00097 00097| 108 @l - ILLEGAL.<010>
+00098 00098| 109 @m - Tags macro as being allowed to be called many times.<010>
+00099 00099| 110 @n - ILLEGAL.<010>
+00100 00100| @O 111 - New macro attached to output file. Has to be at start of line.<010>
+00101 00101| 112 @p - Pragma. Will cause error here though.<010>
+00102 00102| 113 @q - ILLEGAL.<010>
+00103 00103| 114 @r - ILLEGAL.<010>
+00104 00104| 115 @s - ILLEGAL.<010>
+00105 00105| 116 @t - Typesetter directive. Will cause an error here though.<010>
+00106 00106| 117 @u - ILLEGAL.<010>
+00107 00107| 118 @v - ILLEGAL.<010>
+00108 00108| 119 @w - ILLEGAL.<010>
+00109 00109| 120 @x - ILLEGAL.<010>
+00110 00110| 121 @y - ILLEGAL.<010>
+00111 00111| 122 @z - Tags macro as being allowed to be called zero times.<010>
+00112 00112| 123 @{ - Open macro body.<010>
+00113 00113| 124 @| - ILLEGAL.<010>
+00114 00114| 125 @} - Close macro body.<010>
+00115 00115| 126 @~ - ILLEGAL.<010>
+00116 00116| 127 to 255 are not standard printable ASCII characters.<010>
+00117 00117| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 137 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="Scanner Test: Special Sequence Recognition<010>
+==========================================<010>
+This test tests to see that FunnelWeb is recognising the full set of special<010>
+sequences.<010>
+<010>
+Turn Off the Parser<010>
+-------------------<010>
+First we cause a deliberate scanner error so as to prevent the parser from<010>
+generating lots of errors over the syntactic rubbish presented here.<010>
+<010>
+ "
+0011[06]: Text. Text scrap[Grey]="<010>
+<010>
+List of All Possible Special Sequences<010>
+--------------------------------------<010>
+The following is a list of the default special character followed by each of<010>
+the ASCII printables.<010>
+000 to 031 are unprintable control characters.<010>
+<010>
+032 "
+0019[08]: Text. Text scrap[Grey]=" - ILLEGAL. (Note: Hyphen is needed to avoid trailing blanks error.)<010>
+033 "
+0021[01]: Text. Text scrap[Grey]="034 "
+0021[06]: @" Quote.
+0021[08]: Text. Text scrap[Grey]=" - Parameter delimeter.<010>
+035 "
+0022[06]: @# Name. Character='X'.
+0022[09]: Text. Text scrap[Grey]=" - Short name sequence.<010>
+"
+0023[01]: @$ Macro defn.
+0023[03]: Text. Text scrap[Grey]=" 036 - Define macro. Has to be at start of line.<010>
+037 "
+0024[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+038 "
+0025[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+039 "
+0026[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+040 "
+0027[06]: @( Open param.
+0027[08]: Text. Text scrap[Grey]=" - Open parameter list.<010>
+041 "
+0028[06]: @} Close param.
+0028[08]: Text. Text scrap[Grey]=" - Close parameter list.<010>
+042<010>
+"
+0030[03]: Text. Text scrap[Grey]=" - Old fashioned section marker (has to be at start of a line.).<010>
+043 "
+0031[06]: Text. Text scrap[White]="<010>
+"
+0031[08]: Text. Text scrap[Grey]=" - Insert newline.<010>
+044 "
+0032[06]: @, Comma.
+0032[08]: Text. Text scrap[Grey]=" - Parameter separator.<010>
+045 "
+0034[01]: Text. Text scrap[Grey]=" - Ignore end of line marker (has to be at end of line).<010>
+046 "
+0035[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+047 "
+0036[06]: @/ Emphasise.
+0036[08]: Text. Text scrap[Grey]=" - Emphasised text.<010>
+048 "
+0037[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+049 "
+0038[06]: @n Parameter. Parameterno=1.
+0038[08]: Text. Text scrap[Grey]=" - Formal parameter 1.<010>
+050 "
+0039[06]: @n Parameter. Parameterno=2.
+0039[08]: Text. Text scrap[Grey]=" - Formal parameter 2.<010>
+051 "
+0040[06]: @n Parameter. Parameterno=3.
+0040[08]: Text. Text scrap[Grey]=" - Formal parameter 3.<010>
+052 "
+0041[06]: @n Parameter. Parameterno=4.
+0041[08]: Text. Text scrap[Grey]=" - Formal parameter 4.<010>
+053 "
+0042[06]: @n Parameter. Parameterno=5.
+0042[08]: Text. Text scrap[Grey]=" - Formal parameter 5.<010>
+054 "
+0043[06]: @n Parameter. Parameterno=6.
+0043[08]: Text. Text scrap[Grey]=" - Formal parameter 6.<010>
+055 "
+0044[06]: @n Parameter. Parameterno=7.
+0044[08]: Text. Text scrap[Grey]=" - Formal parameter 7.<010>
+056 "
+0045[06]: @n Parameter. Parameterno=8.
+0045[08]: Text. Text scrap[Grey]=" - Formal parameter 8.<010>
+057 "
+0046[06]: @n Parameter. Parameterno=9.
+0046[08]: Text. Text scrap[Grey]=" - Formal parameter 9.<010>
+058 "
+0047[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+059 "
+0048[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+060 "
+0049[06]: @< Open name.
+0049[08]: Text. Text scrap[Grey]=" - Open macro name.<010>
+061 "
+0050[09]: Text. Text scrap[Grey]=" - Set special character.<010>
+062 "
+0051[06]: @> Close name.
+0051[08]: Text. Text scrap[Grey]=" - Close macro name.<010>
+063 "
+0052[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+064 "
+0053[06]: Text. Text scrap[Grey]="@"
+0053[08]: Text. Text scrap[Grey]=" - Insert special character into text.<010>
+"
+0054[01]: @A New section (Level 1).
+0054[03]: Text. Text scrap[Grey]=" 065 - New section (level 1). Must be at start of a line.<010>
+"
+0055[01]: @B New section (Level 2).
+0055[03]: Text. Text scrap[Grey]=" 066 - New section (level 2). Must be at start of a line.<010>
+"
+0056[01]: @C New section (Level 3).
+0056[03]: Text. Text scrap[Grey]=" 067 - New section (level 3). Must be at start of a line.<010>
+"
+0057[01]: @D New section (Level 4).
+0057[03]: Text. Text scrap[Grey]=" 068 - New section (level 4). Must be at start of a line.<010>
+"
+0058[01]: @E New section (Level 5).
+0058[03]: Text. Text scrap[Grey]=" 069 - New section (level 5). Must be at start of a line.<010>
+070 "
+0059[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+071 "
+0060[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+072 "
+0061[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+073 "
+0063[01]: Text. Text scrap[Grey]="074 "
+0063[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+075 "
+0064[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+076 "
+0065[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+077 "
+0066[06]: @M Many calls.
+0066[08]: Text. Text scrap[Grey]=" - Tags macro as being allowed to be called many times.<010>
+078 "
+0067[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+"
+0068[01]: @F File defn.
+0068[03]: Text. Text scrap[Grey]=" 079 - New macro attached to output file. Has to be at start of line.<010>
+080 "
+0070[01]: Text. Text scrap[Grey]="081 "
+0070[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+082 "
+0071[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+083 "
+0072[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+084 "
+0074[01]: Text. Text scrap[Grey]="085 "
+0074[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+086 "
+0075[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+087 "
+0076[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+088 "
+0077[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+089 "
+0078[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+090 "
+0079[06]: @Z Zero calls.
+0079[08]: Text. Text scrap[Grey]=" - Tags macro as being allowed to be called zero times.<010>
+091 "
+0080[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+092 "
+0081[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+093 "
+0082[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+094 "
+0083[06]: Text. Text scrap[Grey]="A"
+0083[14]: Text. Text scrap[Grey]=" - Insert control character into text<010>
+095 "
+0084[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+096 "
+0085[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+"
+0086[01]: @A New section (Level 1).
+0086[03]: Text. Text scrap[Grey]=" 097 - New section (level 1). Must be at start of a line.<010>
+"
+0087[01]: @B New section (Level 2).
+0087[03]: Text. Text scrap[Grey]=" 098 - New section (level 1). Must be at start of a line.<010>
+"
+0088[01]: @C New section (Level 3).
+0088[03]: Text. Text scrap[Grey]=" 099 - New section (level 1). Must be at start of a line.<010>
+"
+0089[01]: @D New section (Level 4).
+0089[03]: Text. Text scrap[Grey]=" 100 - New section (level 1). Must be at start of a line.<010>
+"
+0090[01]: @E New section (Level 5).
+0090[03]: Text. Text scrap[Grey]=" 101 - New section (level 1). Must be at start of a line.<010>
+102 "
+0091[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+103 "
+0092[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+104 "
+0093[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+105 "
+0095[01]: Text. Text scrap[Grey]="106 "
+0095[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+107 "
+0096[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+108 "
+0097[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+109 "
+0098[06]: @M Many calls.
+0098[08]: Text. Text scrap[Grey]=" - Tags macro as being allowed to be called many times.<010>
+110 "
+0099[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+"
+0100[01]: @F File defn.
+0100[03]: Text. Text scrap[Grey]=" 111 - New macro attached to output file. Has to be at start of line.<010>
+112 "
+0102[01]: Text. Text scrap[Grey]="113 "
+0102[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+114 "
+0103[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+115 "
+0104[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+116 "
+0106[01]: Text. Text scrap[Grey]="117 "
+0106[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+118 "
+0107[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+119 "
+0108[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+120 "
+0109[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+121 "
+0110[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+122 "
+0111[06]: @Z Zero calls.
+0111[08]: Text. Text scrap[Grey]=" - Tags macro as being allowed to be called zero times.<010>
+123 "
+0112[06]: @{ Open defn.
+0112[08]: Text. Text scrap[Grey]=" - Open macro body.<010>
+124 "
+0113[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+125 "
+0114[06]: @} Close defn.
+0114[08]: Text. Text scrap[Grey]=" - Close macro body.<010>
+126 "
+0115[08]: Text. Text scrap[Grey]=" - ILLEGAL.<010>
+127 to 255 are not standard printable ASCII characters.<010>
+"
+0117[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| Scanner Test: Special Sequence Recognition
+ 2 2| ==========================================
+ 3 3| This test tests to see that FunnelWeb is recognising the full set of special
+ 4 4| sequences.
+ 5 5|
+ 6 6| Turn Off the Parser
+ 7 7| -------------------
+ 8 8| First we cause a deliberate scanner error so as to prevent the parser from
+ 9 9| generating lots of errors over the syntactic rubbish presented here.
+ 10 10|
+ 11 11| @
+ Error|....^<special><space> is not a legal special sequence.
+ Warning|.....^Line has trailing spaces up to and including this space.
+ 12 12|
+ 13 13| List of All Possible Special Sequences
+ 14 14| --------------------------------------
+ 15 15| The following is a list of the default special character followed by each of
+ 16 16| the ASCII printables.
+ 17 17| 000 to 031 are unprintable control characters.
+ 18 18|
+ 19 19| 032 @ - ILLEGAL. (Note: Hyphen is needed to avoid trailing blanks error.)
+ Error|......^<special><space> is not a legal special sequence.
+ 20 20| 033 @! - Comment.
+ 21 21| 034 @" - Parameter delimeter.
+ 22 22| 035 @#X - Short name sequence.
+ 23 23| @$ 036 - Define macro. Has to be at start of line.
+ 24 24| 037 @% - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 25 25| 038 @& - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 26 26| 039 @' - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 27 27| 040 @( - Open parameter list.
+ 28 28| 041 @) - Close parameter list.
+ 29 29| 042
+ 30 30| @* - Old fashioned section marker (has to be at start of a line.).
+ Error|.^Unknown special sequence.
+ 31 31| 043 @+ - Insert newline.
+ 32 32| 044 @, - Parameter separator.
+ 33 33| 045 @-
+ 34 34| - Ignore end of line marker (has to be at end of line).
+ 35 35| 046 @. - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 36 36| 047 @/ - Emphasised text.
+ 37 37| 048 @0 - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 38 38| 049 @1 - Formal parameter 1.
+ 39 39| 050 @2 - Formal parameter 2.
+ 40 40| 051 @3 - Formal parameter 3.
+ 41 41| 052 @4 - Formal parameter 4.
+ 42 42| 053 @5 - Formal parameter 5.
+ 43 43| 054 @6 - Formal parameter 6.
+ 44 44| 055 @7 - Formal parameter 7.
+ 45 45| 056 @8 - Formal parameter 8.
+ 46 46| 057 @9 - Formal parameter 9.
+ 47 47| 058 @: - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 48 48| 059 @; - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 49 49| 060 @< - Open macro name.
+ 50 50| 061 @=@ - Set special character.
+ 51 51| 062 @> - Close macro name.
+ 52 52| 063 @? - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 53 53| 064 @@ - Insert special character into text.
+ 54 54| @A 065 - New section (level 1). Must be at start of a line.
+ 55 55| @B 066 - New section (level 2). Must be at start of a line.
+ 56 56| @C 067 - New section (level 3). Must be at start of a line.
+ 57 57| @D 068 - New section (level 4). Must be at start of a line.
+ 58 58| @E 069 - New section (level 5). Must be at start of a line.
+ 59 59| 070 @F - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 60 60| 071 @G - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 61 61| 072 @H - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 62 62| 073 @I - Include file. Will provoke an error here though.
+ Error|......^Include sequence must be at the beginning of a line.
+ |......^Include ignored.
+ 63 63| 074 @J - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 64 64| 075 @K - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 65 65| 076 @L - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 66 66| 077 @M - Tags macro as being allowed to be called many times.
+ 67 67| 078 @N - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 68 68| @O 079 - New macro attached to output file. Has to be at start of line.
+ 69 69| 080 @P - Pragma. Will cause error here though.
+ Error|......^Pragma sequence @p must be at the start of a line.
+ |......^The rest of this line will be ignored.
+ Error|......^Unrecognised pragma. Possible legal pragmas are:
+ |......^ @p indentation = none | blank
+ |......^ @p maximum_input_line_length = <num>|infinity
+ |......^ @p maximum_output_line_length = <num>|infinity
+ |......^ @p typesetter = none | tex | hypertext | html
+ |......^ @p no_doc_header
+ |......^ @p raw_macro_and_section_names
+ |......^ @p ignore_text_after_special_minus
+ |......^ @p no_paragraph_markups
+ |......^ @p declare_source_code_type "<name>"
+ |......^ @p automatic_line_directive_macro = "<name>"
+ |......^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+ |......^ @p #line_offset = <num>
+ |......^ @p #line_depth = <num>
+ |......^The blanks between arguments are important.
+ |......^Pragma ignored.
+ 70 70| 081 @Q - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 71 71| 082 @R - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 72 72| 083 @S - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 73 73| 084 @T - Typesetter directive. Will cause an error here though.
+ Error|......^Typesetter directive @t must be at the start of a line.
+ |......^The rest of this line will be ignored.
+ Error|......^Unrecognised typesetter directive. Legal ones are:
+ |......^ @t new_page
+ |......^ @t table_of_contents
+ |......^ @t title <font> <align> <string>
+ |......^ @t vskip <num> mm
+ |......^The blanks between arguments are important.
+ |......^Typesetter directive ignored.
+ 74 74| 085 @U - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 75 75| 086 @V - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 76 76| 087 @W - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 77 77| 088 @X - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 78 78| 089 @Y - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 79 79| 090 @Z - Tags macro as being allowed to be called zero times.
+ 80 80| 091 @[ - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 81 81| 092 @\ - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 82 82| 093 @] - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 83 83| 094 @^D(065) - Insert control character into text
+ 84 84| 095 @_ - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 85 85| 096 @` - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 86 86| @a 097 - New section (level 1). Must be at start of a line.
+ 87 87| @b 098 - New section (level 1). Must be at start of a line.
+ 88 88| @c 099 - New section (level 1). Must be at start of a line.
+ 89 89| @d 100 - New section (level 1). Must be at start of a line.
+ 90 90| @e 101 - New section (level 1). Must be at start of a line.
+ 91 91| 102 @f - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 92 92| 103 @g - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 93 93| 104 @h - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 94 94| 105 @i - Include file. Will provoke an error here though.
+ Error|......^Include sequence must be at the beginning of a line.
+ |......^Include ignored.
+ 95 95| 106 @j - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 96 96| 107 @k - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 97 97| 108 @l - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 98 98| 109 @m - Tags macro as being allowed to be called many times.
+ 99 99| 110 @n - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 100 100| @O 111 - New macro attached to output file. Has to be at start of line.
+ 101 101| 112 @p - Pragma. Will cause error here though.
+ Error|......^Pragma sequence @p must be at the start of a line.
+ |......^The rest of this line will be ignored.
+ Error|......^Unrecognised pragma. Possible legal pragmas are:
+ |......^ @p indentation = none | blank
+ |......^ @p maximum_input_line_length = <num>|infinity
+ |......^ @p maximum_output_line_length = <num>|infinity
+ |......^ @p typesetter = none | tex | hypertext | html
+ |......^ @p no_doc_header
+ |......^ @p raw_macro_and_section_names
+ |......^ @p ignore_text_after_special_minus
+ |......^ @p no_paragraph_markups
+ |......^ @p declare_source_code_type "<name>"
+ |......^ @p automatic_line_directive_macro = "<name>"
+ |......^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+ |......^ @p #line_offset = <num>
+ |......^ @p #line_depth = <num>
+ |......^The blanks between arguments are important.
+ |......^Pragma ignored.
+ 102 102| 113 @q - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 103 103| 114 @r - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 104 104| 115 @s - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 105 105| 116 @t - Typesetter directive. Will cause an error here though.
+ Error|......^Typesetter directive @t must be at the start of a line.
+ |......^The rest of this line will be ignored.
+ Error|......^Unrecognised typesetter directive. Legal ones are:
+ |......^ @t new_page
+ |......^ @t table_of_contents
+ |......^ @t title <font> <align> <string>
+ |......^ @t vskip <num> mm
+ |......^The blanks between arguments are important.
+ |......^Typesetter directive ignored.
+ 106 106| 117 @u - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 107 107| 118 @v - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 108 108| 119 @w - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 109 109| 120 @x - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 110 110| 121 @y - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 111 111| 122 @z - Tags macro as being allowed to be called zero times.
+ 112 112| 123 @{ - Open macro body.
+ 113 113| 124 @| - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 114 114| 125 @} - Close macro body.
+ 115 115| 126 @~ - ILLEGAL.
+ Error|......^Unknown special sequence.
+ 116 116| 127 to 255 are not standard printable ASCII characters.
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 58 Errors and 1 Warning.
diff --git a/web/funnelAC/results/sc11.lis b/web/funnelAC/results/sc11.lis
new file mode 100644
index 0000000000..6082c059c4
--- /dev/null
+++ b/web/funnelAC/results/sc11.lis
@@ -0,0 +1,307 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 31 3A 20 53 79 6E 74 61 78 20 6F 66 20 | SC11: Syntax of |
+| 74 68 65 20 69 6E 63 6C 75 64 65 20 70 72 61 67 | the include prag |
+| 6D 61 2E 0A 0A 31 2E 20 54 65 73 74 20 69 6E 63 | ma...1. Test inc |
+| 6C 75 64 65 20 70 72 61 67 6D 61 20 6E 6F 74 20 | lude pragma not |
+| 61 74 20 73 74 61 72 74 20 6F 66 20 6C 69 6E 65 | at start of line |
+| 2E 0A 0A 20 20 20 40 69 0A 0A 32 2E 20 54 65 73 | ... @i..2. Tes |
+| 74 20 41 54 69 20 6E 6F 74 20 66 6F 6C 6C 6F 77 | t ATi not follow |
+| 65 64 20 62 79 20 61 20 62 6C 61 6E 6B 2E 0A 0A | ed by a blank... |
+| 40 69 78 0A 0A 33 2E 20 54 65 73 74 20 69 6E 63 | @ix..3. Test inc |
+| 6C 75 64 65 20 66 69 6C 65 6E 61 6D 65 20 69 73 | lude filename is |
+| 20 74 6F 6F 20 6C 6F 6E 67 2E 20 54 68 65 20 6D | too long. The m |
+| 61 78 69 6D 75 6D 20 6F 6E 20 74 68 65 20 4D 61 | aximum on the Ma |
+| 63 69 6E 74 6F 73 68 20 69 73 0A 20 20 20 32 35 | cintosh is. 25 |
+| 35 20 62 75 74 20 77 65 20 77 69 6C 6C 20 75 73 | 5 but we will us |
+| 65 20 61 20 66 69 6C 65 6E 61 6D 65 20 6F 66 20 | e a filename of |
+| 6F 76 65 72 20 31 30 32 34 20 63 68 61 72 61 63 | over 1024 charac |
+| 74 65 72 73 20 73 6F 20 61 73 20 74 6F 20 6D 61 | ters so as to ma |
+| 6B 65 0A 20 20 20 74 68 65 20 74 65 73 74 20 70 | ke. the test p |
+| 6F 72 74 61 62 6C 65 2E 20 54 68 65 20 61 63 74 | ortable. The act |
+| 75 61 6C 20 6C 65 6E 67 74 68 20 75 73 65 64 20 | ual length used |
+| 69 73 20 31 31 30 30 20 63 68 61 72 61 63 74 65 | is 1100 characte |
+| 72 73 20 69 6E 20 74 68 65 0A 20 20 20 66 69 6C | rs in the. fil |
+| 65 6E 61 6D 65 2E 0A 0A 20 20 20 20 20 20 20 20 | ename... |
+| 20 20 20 20 31 20 20 20 20 20 20 20 20 20 32 20 | 1 2 |
+| 20 20 20 20 20 20 20 20 33 20 20 20 20 20 20 20 | 3 |
+| 20 20 34 20 20 20 20 20 20 20 20 20 35 20 20 20 | 4 5 |
+| 20 20 20 20 20 20 36 20 20 20 20 20 20 20 20 20 | 6 |
+| 37 20 20 20 20 20 20 20 20 20 38 20 20 20 20 20 | 7 8 |
+| 20 20 20 20 39 20 20 20 20 20 20 20 20 20 30 20 | 9 0 |
+| 20 20 20 20 20 20 20 20 31 20 20 20 20 20 20 20 | 1 |
+| 20 20 32 20 20 20 20 20 20 20 20 20 33 20 20 20 | 2 3 |
+| 20 20 20 20 20 20 34 20 20 20 20 20 20 20 20 20 | 4 |
+| 35 20 20 20 20 20 20 20 20 20 36 20 20 20 20 20 | 5 6 |
+| 20 20 20 20 37 20 20 20 20 20 20 20 20 20 38 20 | 7 8 |
+| 20 20 20 20 20 20 20 20 39 20 20 20 20 20 20 20 | 9 |
+| 20 20 30 20 20 20 20 20 20 20 20 20 31 20 20 20 | 0 1 |
+| 20 20 20 20 20 20 32 20 20 20 20 20 20 20 20 20 | 2 |
+| 33 20 20 20 20 20 20 20 20 20 34 20 20 20 20 20 | 3 4 |
+| 20 20 20 20 35 20 20 20 20 20 20 20 20 20 36 20 | 5 6 |
+| 20 20 20 20 20 20 20 20 37 20 20 20 20 20 20 20 | 7 |
+| 20 20 38 20 20 20 20 20 20 20 20 20 39 20 20 20 | 8 9 |
+| 20 20 20 20 20 20 30 20 20 20 20 20 20 20 20 20 | 0 |
+| 31 20 20 20 20 20 20 20 20 20 32 20 20 20 20 20 | 1 2 |
+| 20 20 20 20 33 20 20 20 20 20 20 20 20 20 34 20 | 3 4 |
+| 20 20 20 20 20 20 20 20 35 20 20 20 20 20 20 20 | 5 |
+| 20 20 36 20 20 20 20 20 20 20 20 20 37 20 20 20 | 6 7 |
+| 20 20 20 20 20 20 38 20 20 20 20 20 20 20 20 20 | 8 |
+| 39 20 20 20 20 20 20 20 20 20 30 20 20 20 20 20 | 9 0 |
+| 20 20 20 20 31 20 20 20 20 20 20 20 20 20 32 20 | 1 2 |
+| 20 20 20 20 20 20 20 20 33 20 20 20 20 20 20 20 | 3 |
+| 20 20 34 20 20 20 20 20 20 20 20 20 35 20 20 20 | 4 5 |
+| 20 20 20 20 20 20 36 20 20 20 20 20 20 20 20 20 | 6 |
+| 37 20 20 20 20 20 20 20 20 20 38 20 20 20 20 20 | 7 8 |
+| 20 20 20 20 39 20 20 20 20 20 20 20 20 20 30 20 | 9 0 |
+| 20 20 20 20 20 20 20 20 31 20 20 20 20 20 20 20 | 1 |
+| 20 20 32 20 20 20 20 20 20 20 20 20 33 20 20 20 | 2 3 |
+| 20 20 20 20 20 20 34 20 20 20 20 20 20 20 20 20 | 4 |
+| 35 20 20 20 20 20 20 20 20 20 36 20 20 20 20 20 | 5 6 |
+| 20 20 20 20 37 20 20 20 20 20 20 20 20 20 38 20 | 7 8 |
+| 20 20 20 20 20 20 20 20 39 20 20 20 20 20 20 20 | 9 |
+| 20 20 30 20 20 20 20 20 20 20 20 20 31 20 20 20 | 0 1 |
+| 20 20 20 20 20 20 32 20 20 20 20 20 20 20 20 20 | 2 |
+| 33 20 20 20 20 20 20 20 20 20 34 20 20 20 20 20 | 3 4 |
+| 20 20 20 20 35 20 20 20 20 20 20 20 20 20 36 20 | 5 6 |
+| 20 20 20 20 20 20 20 20 37 20 20 20 20 20 20 20 | 7 |
+| 20 20 38 20 20 20 20 20 20 20 20 20 39 20 20 20 | 8 9 |
+| 20 20 20 20 20 20 30 20 20 20 20 20 20 20 20 20 | 0 |
+| 31 20 20 20 20 20 20 20 20 20 32 20 20 20 20 20 | 1 2 |
+| 20 20 20 20 33 20 20 20 20 20 20 20 20 20 34 20 | 3 4 |
+| 20 20 20 20 20 20 20 20 35 20 20 20 20 20 20 20 | 5 |
+| 20 20 36 20 20 20 20 20 20 20 20 20 37 20 20 20 | 6 7 |
+| 20 20 20 20 20 20 38 20 20 20 20 20 20 20 20 20 | 8 |
+| 39 20 20 20 20 20 20 20 20 20 30 20 20 20 20 20 | 9 0 |
+| 20 20 20 20 31 20 20 20 20 20 20 20 20 20 32 20 | 1 2 |
+| 20 20 20 20 20 20 20 20 33 20 20 20 20 20 20 20 | 3 |
+| 20 20 34 20 20 20 20 20 20 20 20 20 35 20 20 20 | 4 5 |
+| 20 20 20 20 20 20 36 20 20 20 20 20 20 20 20 20 | 6 |
+| 37 20 20 20 20 20 20 20 20 20 38 20 20 20 20 20 | 7 8 |
+| 20 20 20 20 39 20 20 20 20 20 20 20 20 20 30 20 | 9 0 |
+| 20 20 20 20 20 20 20 20 31 20 20 20 20 20 20 20 | 1 |
+| 20 20 32 20 20 20 20 20 20 20 20 20 33 20 20 20 | 2 3 |
+| 20 20 20 20 20 20 34 20 20 20 20 20 20 20 20 20 | 4 |
+| 35 20 20 20 20 20 20 20 20 20 36 20 20 20 20 20 | 5 6 |
+| 20 20 20 20 37 20 20 20 20 20 20 20 20 20 38 20 | 7 8 |
+| 20 20 20 20 20 20 20 20 39 20 20 20 20 20 20 20 | 9 |
+| 20 20 30 20 20 20 20 20 20 20 20 20 31 20 20 20 | 0 1 |
+| 20 20 20 20 20 20 32 20 20 20 20 20 20 20 20 20 | 2 |
+| 33 20 20 20 20 20 20 20 20 20 34 20 20 20 20 20 | 3 4 |
+| 20 20 20 20 35 20 20 20 20 20 20 20 20 20 36 20 | 5 6 |
+| 20 20 20 20 20 20 20 20 37 20 20 20 20 20 20 20 | 7 |
+| 20 20 38 20 20 20 20 20 20 20 20 20 39 20 20 20 | 8 9 |
+| 20 20 20 20 20 20 30 0A 40 69 20 31 32 33 34 35 | 0.@i 12345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 0A 0A 34 2E 20 49 6E 63 6C | 4567890..4. Incl |
+| 75 64 65 20 70 72 61 67 6D 61 20 68 61 73 20 61 | ude pragma has a |
+| 6E 20 65 6D 70 74 79 20 66 69 6C 65 6E 61 6D 65 | n empty filename |
+| 2E 20 4E 6F 74 65 3A 20 42 65 63 61 75 73 65 20 | . Note: Because |
+| 74 68 65 20 41 54 69 20 68 61 73 20 74 6F 20 62 | the ATi has to b |
+| 65 0A 20 20 20 66 6F 6C 6C 6F 77 65 64 20 62 79 | e. followed by |
+| 20 61 20 62 6C 61 6E 6B 2C 20 77 65 20 68 61 76 | a blank, we hav |
+| 65 20 74 6F 20 69 6E 63 75 72 20 61 20 74 72 61 | e to incur a tra |
+| 69 6C 69 6E 67 20 62 6C 61 6E 6B 20 65 72 72 6F | iling blank erro |
+| 72 20 68 65 72 65 20 69 6E 0A 20 20 20 6F 72 64 | r here in. ord |
+| 65 72 20 74 6F 20 70 72 6F 76 6F 6B 65 20 74 68 | er to provoke th |
+| 65 20 65 72 72 6F 72 20 77 65 20 72 65 61 6C 6C | e error we reall |
+| 79 20 77 61 6E 74 20 74 6F 20 73 65 65 2E 0A 0A | y want to see... |
+| 40 69 20 0A 0A | @i .. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC11: Syntax of the include pragma.<010>
+00002 00002| <010>
+00003 00003| 1. Test include pragma not at start of line.<010>
+00004 00004| <010>
+00005 00005| @i<010>
+00006 00006| <010>
+00007 00007| 2. Test ATi not followed by a blank.<010>
+00008 00008| <010>
+00009 00009| @ix<010>
+00010 00010| <010>
+00011 00011| 3. Test include filename is too long. The maximum on the Macintosh is<010>
+00012 00012| 255 but we will use a filename of over 1024 characters so as to make<010>
+00013 00013| the test portable. The actual length used is 1100 characters in the<010>
+00014 00014| filename.<010>
+00015 00015| <010>
+00016 00016| 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0<010>
+00017 00017| @i 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890<010>
+00018 00018| <010>
+00019 00019| 4. Include pragma has an empty filename. Note: Because the ATi has to be<010>
+00020 00020| followed by a blank, we have to incur a trailing blank error here in<010>
+00021 00021| order to provoke the error we really want to see.<010>
+00022 00022| <010>
+00023 00023| @i <010>
+00024 00024| <010>
+00025 00025| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 6 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC11: Syntax of the include pragma.<010>
+<010>
+1. Test include pragma not at start of line.<010>
+<010>
+ "
+0006[01]: Text. Text scrap[Grey]="<010>
+2. Test ATi not followed by a blank.<010>
+<010>
+"
+0010[01]: Text. Text scrap[Grey]="<010>
+3. Test include filename is too long. The maximum on the Macintosh is<010>
+ 255 but we will use a filename of over 1024 characters so as to make<010>
+ the test portable. The actual length used is 1100 characters in the<010>
+ filename.<010>
+<010>
+ 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0<010>
+"
+0018[01]: Text. Text scrap[Grey]="<010>
+4. Include pragma has an empty filename. Note: Because the ATi has to be<010>
+ followed by a blank, we have to incur a trailing blank error here in<010>
+ order to provoke the error we really want to see.<010>
+<010>
+"
+0024[01]: Text. Text scrap[White]="<010>
+"
+0025[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC11: Syntax of the include pragma.
+ 2 2|
+ 3 3| 1. Test include pragma not at start of line.
+ 4 4|
+ 5 5| @i
+ Error|....^Include sequence must be at the beginning of a line.
+ |....^Include ignored.
+ 6 6|
+ 7 7| 2. Test ATi not followed by a blank.
+ 8 8|
+ 9 9| @ix
+ Error|...^Include sequence (@i) must be followed by a blank.
+ |...^Example include: @i macros.fwi
+ |...^Include ignored.
+ 10 10|
+ 11 11| 3. Test include filename is too long. The maximum on the Macintosh is
+ 12 12| 255 but we will use a filename of over 1024 characters so as to make
+ 13 13| the test portable. The actual length used is 1100 characters in the
+ 14 14| filename.
+ 15 15|
+ 16 16| 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
+ Error|.................................................................................^Input line is too long (this character is the first offender).
+ |.................................................................................^Currently, the maximum allowable input line length is 80.
+ |.................................................................................^Note: You can change this using a pragma directive (@p).
+ 17 17| @i 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
+ Error|.^This include command's file specification is too long.
+ |.^The maximum file name length is <<Suppressed>> characters.
+ |.^Include ignored.
+ Error|.................................................................................^Input line is too long (this character is the first offender).
+ |.................................................................................^Currently, the maximum allowable input line length is 80.
+ |.................................................................................^Note: You can change this using a pragma directive (@p).
+ 18 18|
+ 19 19| 4. Include pragma has an empty filename. Note: Because the ATi has to be
+ 20 20| followed by a blank, we have to incur a trailing blank error here in
+ 21 21| order to provoke the error we really want to see.
+ 22 22|
+ 23 23| @i
+ Warning|...^Line has trailing spaces up to and including this space.
+ Error|....^Expecting the name of a file to include.
+ 24 24|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 6 Errors and 1 Warning.
diff --git a/web/funnelAC/results/sc12.lis b/web/funnelAC/results/sc12.lis
new file mode 100644
index 0000000000..1421eacfbc
--- /dev/null
+++ b/web/funnelAC/results/sc12.lis
@@ -0,0 +1,77 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 32 3A 20 49 6E 63 6C 75 64 65 20 66 69 | SC12: Include fi |
+| 6C 65 20 63 61 6E 6E 6F 74 20 62 65 20 66 6F 75 | le cannot be fou |
+| 6E 64 2E 0A 54 65 73 74 20 70 65 72 73 6F 6E 3A | nd..Test person: |
+| 20 44 4F 4E 54 20 63 72 65 61 74 65 20 73 63 31 | DONT create sc1 |
+| 32 61 2E 69 6E 63 2E 20 49 74 20 69 73 20 6E 6F | 2a.inc. It is no |
+| 74 20 73 75 70 70 6F 73 65 64 20 74 6F 20 65 78 | t supposed to ex |
+| 69 73 74 21 0A 54 68 65 20 66 6F 6C 6C 6F 77 69 | ist!.The followi |
+| 6E 67 20 69 6E 63 6C 75 64 65 20 73 68 6F 75 6C | ng include shoul |
+| 64 20 79 69 65 6C 64 20 61 20 22 66 69 6C 65 20 | d yield a "file |
+| 6E 6F 74 20 66 6F 75 6E 64 20 65 72 72 6F 72 2E | not found error. |
+| 22 0A 0A 40 69 20 73 63 31 32 61 2E 69 6E 63 0A | "..@i sc12a.inc. |
+| 0A | . |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC12: Include file cannot be found.<010>
+00002 00002| Test person: DONT create sc12a.inc. It is not supposed to exist!<010>
+00003 00003| The following include should yield a "file not found error."<010>
+00004 00004| <010>
+00005 00005| @i sc12a.inc<010>
+00006 00006| <010>
+00007 00007| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 3 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC12: Include file cannot be found.<010>
+Test person: DONT create sc12a.inc. It is not supposed to exist!<010>
+The following include should yield a "file not found error."<010>
+<010>
+"
+0006[01]: Text. Text scrap[White]="<010>
+"
+0007[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC12: Include file cannot be found.
+ 2 2| Test person: DONT create sc12a.inc. It is not supposed to exist!
+ 3 3| The following include should yield a "file not found error."
+ 4 4|
+ 5 5| @i sc12a.inc
+ Error|....^Error opening include file.
+ |....^The include file's expanded name was "<<Suppressed>>".
+ 6 6|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There was 1 Error.
diff --git a/web/funnelAC/results/sc13.lis b/web/funnelAC/results/sc13.lis
new file mode 100644
index 0000000000..39e82c6a79
--- /dev/null
+++ b/web/funnelAC/results/sc13.lis
@@ -0,0 +1,500 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 33 3A 20 56 61 72 69 6F 75 73 20 6B 69 | SC13: Various ki |
+| 6E 64 73 20 6F 66 20 69 6E 63 6C 75 64 65 20 66 | nds of include f |
+| 69 6C 65 2E 0A 0A 31 2E 20 49 6E 63 6C 75 64 65 | ile...1. Include |
+| 20 66 69 6C 65 20 69 73 20 65 6D 70 74 79 2E 0A | file is empty.. |
+| 42 65 66 6F 72 65 20 69 6E 63 6C 75 64 65 0A 40 | Before include.@ |
+| 69 20 73 63 31 33 61 0A 41 66 74 65 72 20 69 6E | i sc13a.After in |
+| 63 6C 75 64 65 0A 0A 32 2E 20 49 6E 63 6C 75 64 | clude..2. Includ |
+| 65 20 66 69 6C 65 20 63 6F 6E 74 61 69 6E 73 20 | e file contains |
+| 61 20 73 69 6E 67 6C 65 20 62 6C 61 6E 6B 20 6C | a single blank l |
+| 69 6E 65 2E 0A 42 65 66 6F 72 65 20 69 6E 63 6C | ine..Before incl |
+| 75 64 65 0A 40 69 20 73 63 31 33 62 0A 41 66 74 | ude.@i sc13b.Aft |
+| 65 72 20 69 6E 63 6C 75 64 65 0A 0A 33 2E 20 49 | er include..3. I |
+| 6E 63 6C 75 64 65 20 66 69 6C 65 20 63 6F 6E 74 | nclude file cont |
+| 61 69 6E 73 20 74 77 6F 20 62 6C 61 6E 6B 20 6C | ains two blank l |
+| 69 6E 65 73 2E 0A 42 65 66 6F 72 65 20 69 6E 63 | ines..Before inc |
+| 6C 75 64 65 0A 40 69 20 73 63 31 33 63 0A 41 66 | lude.@i sc13c.Af |
+| 74 65 72 20 69 6E 63 6C 75 64 65 0A 0A 34 2E 20 | ter include..4. |
+| 49 6E 63 6C 75 64 65 20 66 69 6C 65 20 63 6F 6E | Include file con |
+| 74 61 69 6E 73 20 61 20 73 69 6E 67 6C 65 20 6C | tains a single l |
+| 69 6E 65 20 77 69 74 68 20 74 65 78 74 20 6F 6E | ine with text on |
+| 20 69 74 2E 0A 42 65 66 6F 72 65 20 69 6E 63 6C | it..Before incl |
+| 75 64 65 0A 40 69 20 73 63 31 33 64 0A 41 66 74 | ude.@i sc13d.Aft |
+| 65 72 20 69 6E 63 6C 75 64 65 0A 0A 35 2E 20 49 | er include..5. I |
+| 6E 63 6C 75 64 65 20 66 69 6C 65 27 73 20 6C 61 | nclude file's la |
+| 73 74 20 6C 69 6E 65 20 69 73 20 6E 6F 74 20 70 | st line is not p |
+| 72 6F 70 65 72 6C 79 20 74 65 72 6D 69 6E 61 74 | roperly terminat |
+| 65 64 2E 0A 42 65 66 6F 72 65 20 69 6E 63 6C 75 | ed..Before inclu |
+| 64 65 0A 40 69 20 73 63 31 33 65 0A 41 66 74 65 | de.@i sc13e.Afte |
+| 72 20 69 6E 63 6C 75 64 65 0A 0A 36 2E 20 49 6E | r include..6. In |
+| 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 6F 72 | clude file is or |
+| 64 69 6E 61 72 79 2E 0A 42 65 66 6F 72 65 20 69 | dinary..Before i |
+| 6E 63 6C 75 64 65 0A 40 69 20 73 63 31 33 66 0A | nclude.@i sc13f. |
+| 41 66 74 65 72 20 69 6E 63 6C 75 64 65 0A 0A 37 | After include..7 |
+| 2E 20 54 65 73 74 20 75 70 70 65 72 20 63 61 73 | . Test upper cas |
+| 65 20 49 20 61 6E 64 20 66 69 6C 65 20 65 78 74 | e I and file ext |
+| 65 6E 73 69 6F 6E 20 69 6E 68 65 72 69 74 61 6E | ension inheritan |
+| 63 65 2E 0A 42 65 66 6F 72 65 20 69 6E 63 6C 75 | ce..Before inclu |
+| 64 65 0A 40 49 20 73 63 31 33 66 0A 41 66 74 65 | de.@I sc13f.Afte |
+| 72 20 69 6E 63 6C 75 64 65 0A 0A 45 6E 64 20 6F | r include..End o |
+| 66 20 74 65 73 74 20 46 69 6C 65 2E 0A | f test File.. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 0A | . |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 0A 0A | .. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 54 68 69 73 20 69 73 20 74 68 65 20 69 6E 63 6C | This is the incl |
+| 75 64 65 20 66 69 6C 65 20 66 6F 72 20 74 65 73 | ude file for tes |
+| 74 20 53 43 31 33 64 2E 20 4A 75 73 74 20 61 20 | t SC13d. Just a |
+| 66 69 6C 65 20 63 6F 6E 74 61 69 6E 69 6E 67 20 | file containing |
+| 6F 6E 65 20 6C 69 6E 65 2E 0A | one line.. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 54 68 69 73 20 69 73 20 74 68 65 20 69 6E 63 6C | This is the incl |
+| 75 64 65 20 66 69 6C 65 20 66 6F 72 20 74 65 73 | ude file for tes |
+| 74 20 53 43 31 33 65 2E 20 54 68 65 20 74 65 73 | t SC13e. The tes |
+| 74 20 69 73 20 74 6F 20 73 65 65 20 68 6F 77 20 | t is to see how |
+| 46 75 6E 6E 65 6C 57 65 62 0A 63 6F 70 65 73 20 | FunnelWeb.copes |
+| 77 69 74 68 20 61 6E 20 69 6E 63 6C 75 64 65 20 | with an include |
+| 66 69 6C 65 20 74 68 61 74 20 68 61 73 20 61 6E | file that has an |
+| 20 69 6D 70 72 6F 70 65 72 6C 79 20 74 65 72 6D | improperly term |
+| 69 6E 61 74 65 64 20 6C 61 73 74 20 6C 69 6E 65 | inated last line |
+| 2E 0A 0A | ... |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 54 68 69 73 20 69 73 20 74 68 65 20 69 6E 63 6C | This is the incl |
+| 75 64 65 20 66 69 6C 65 20 66 6F 72 20 74 65 73 | ude file for tes |
+| 74 73 20 53 43 31 33 2E 36 20 61 6E 64 20 53 43 | ts SC13.6 and SC |
+| 31 33 2E 37 2E 0A 54 68 65 72 65 20 61 72 65 20 | 13.7..There are |
+| 6F 6E 6C 79 20 74 77 6F 20 6C 69 6E 65 73 2C 20 | only two lines, |
+| 61 6E 64 20 74 68 69 73 20 69 73 20 74 68 65 20 | and this is the |
+| 73 65 63 6F 6E 64 20 6F 6E 65 2E 0A | second one.. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 54 68 69 73 20 69 73 20 74 68 65 20 69 6E 63 6C | This is the incl |
+| 75 64 65 20 66 69 6C 65 20 66 6F 72 20 74 65 73 | ude file for tes |
+| 74 73 20 53 43 31 33 2E 36 20 61 6E 64 20 53 43 | ts SC13.6 and SC |
+| 31 33 2E 37 2E 0A 54 68 65 72 65 20 61 72 65 20 | 13.7..There are |
+| 6F 6E 6C 79 20 74 77 6F 20 6C 69 6E 65 73 2C 20 | only two lines, |
+| 61 6E 64 20 74 68 69 73 20 69 73 20 74 68 65 20 | and this is the |
+| 73 65 63 6F 6E 64 20 6F 6E 65 2E 0A | second one.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC13: Various kinds of include file.<010>
+00002 00002| <010>
+00003 00003| 1. Include file is empty.<010>
+00004 00004| Before include<010>
+00005 00005| @i sc13a<010>
+00006 00006| After include<010>
+00007 00007| <010>
+00008 00008| 2. Include file contains a single blank line.<010>
+00009 00009| Before include<010>
+00010 00010| @i sc13b<010>
+00011 00001| <010>
+00012 00011| After include<010>
+00013 00012| <010>
+00014 00013| 3. Include file contains two blank lines.<010>
+00015 00014| Before include<010>
+00016 00015| @i sc13c<010>
+00017 00001| <010>
+00018 00002| <010>
+00019 00016| After include<010>
+00020 00017| <010>
+00021 00018| 4. Include file contains a single line with text on it.<010>
+00022 00019| Before include<010>
+00023 00020| @i sc13d<010>
+00024 00001| This is the include file for test SC13d. Just a file containing one line.<010>
+00025 00021| After include<010>
+00026 00022| <010>
+00027 00023| 5. Include file's last line is not properly terminated.<010>
+00028 00024| Before include<010>
+00029 00025| @i sc13e<010>
+00030 00001| This is the include file for test SC13e. The test is to see how FunnelWeb<010>
+00031 00002| copes with an include file that has an improperly terminated last line.<010>
+00032 00003| <010>
+00033 00026| After include<010>
+00034 00027| <010>
+00035 00028| 6. Include file is ordinary.<010>
+00036 00029| Before include<010>
+00037 00030| @i sc13f<010>
+00038 00001| This is the include file for tests SC13.6 and SC13.7.<010>
+00039 00002| There are only two lines, and this is the second one.<010>
+00040 00031| After include<010>
+00041 00032| <010>
+00042 00033| 7. Test upper case I and file extension inheritance.<010>
+00043 00034| Before include<010>
+00044 00035| @I sc13f<010>
+00045 00001| This is the include file for tests SC13.6 and SC13.7.<010>
+00046 00002| There are only two lines, and this is the second one.<010>
+00047 00036| After include<010>
+00048 00037| <010>
+00049 00038| End of test File.<010>
+00050 00039| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 15 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC13: Various kinds of include file.<010>
+<010>
+1. Include file is empty.<010>
+Before include<010>
+"
+0006[01]: Text. Text scrap[Grey]="After include<010>
+<010>
+2. Include file contains a single blank line.<010>
+Before include<010>
+"
+0011[01]: Text. Text scrap[White]="<010>
+"
+0012[01]: Text. Text scrap[Grey]="After include<010>
+<010>
+3. Include file contains two blank lines.<010>
+Before include<010>
+"
+0017[01]: Text. Text scrap[White]="<010>
+<010>
+"
+0019[01]: Text. Text scrap[Grey]="After include<010>
+<010>
+4. Include file contains a single line with text on it.<010>
+Before include<010>
+"
+0024[01]: Text. Text scrap[Grey]="This is the include file for test SC13d. Just a file containing one line.<010>
+"
+0025[01]: Text. Text scrap[Grey]="After include<010>
+<010>
+5. Include file's last line is not properly terminated.<010>
+Before include<010>
+"
+0030[01]: Text. Text scrap[Grey]="This is the include file for test SC13e. The test is to see how FunnelWeb<010>
+copes with an include file that has an improperly terminated last line.<010>
+<010>
+"
+0033[01]: Text. Text scrap[Grey]="After include<010>
+<010>
+6. Include file is ordinary.<010>
+Before include<010>
+"
+0038[01]: Text. Text scrap[Grey]="This is the include file for tests SC13.6 and SC13.7.<010>
+There are only two lines, and this is the second one.<010>
+"
+0040[01]: Text. Text scrap[Grey]="After include<010>
+<010>
+7. Test upper case I and file extension inheritance.<010>
+Before include<010>
+"
+0045[01]: Text. Text scrap[Grey]="This is the include file for tests SC13.6 and SC13.7.<010>
+There are only two lines, and this is the second one.<010>
+"
+0047[01]: Text. Text scrap[Grey]="After include<010>
+<010>
+End of test File.<010>
+"
+0050[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#file"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#line"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#timestamp"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="SC13: Various kinds of include file.<010>
+<010>
+1. Include file is empty.<010>
+Before include<010>
+"
+Text scrap[Grey]="After include<010>
+<010>
+2. Include file contains a single blank line.<010>
+Before include<010>
+"
+Text scrap[White]="<010>
+"
+Text scrap[Grey]="After include<010>
+<010>
+3. Include file contains two blank lines.<010>
+Before include<010>
+"
+Text scrap[White]="<010>
+<010>
+"
+Text scrap[Grey]="After include<010>
+<010>
+4. Include file contains a single line with text on it.<010>
+Before include<010>
+"
+Text scrap[Grey]="This is the include file for test SC13d. Just a file containing one line.<010>
+"
+Text scrap[Grey]="After include<010>
+<010>
+5. Include file's last line is not properly terminated.<010>
+Before include<010>
+"
+Text scrap[Grey]="This is the include file for test SC13e. The test is to see how FunnelWeb<010>
+copes with an include file that has an improperly terminated last line.<010>
+<010>
+"
+Text scrap[Grey]="After include<010>
+<010>
+6. Include file is ordinary.<010>
+Before include<010>
+"
+Text scrap[Grey]="This is the include file for tests SC13.6 and SC13.7.<010>
+There are only two lines, and this is the second one.<010>
+"
+Text scrap[Grey]="After include<010>
+<010>
+7. Test upper case I and file extension inheritance.<010>
+Before include<010>
+"
+Text scrap[Grey]="This is the include file for tests SC13.6 and SC13.7.<010>
+There are only two lines, and this is the second one.<010>
+"
+Text scrap[Grey]="After include<010>
+<010>
+End of test File.<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC13: Various kinds of include file.
+ 2 2|
+ 3 3| 1. Include file is empty.
+ 4 4| Before include
+ 5 5| @i sc13a
+ Warning|.^Include file is empty (not a byte in syte)!
+ 6 6| After include
+ 7 7|
+ 8 8| 2. Include file contains a single blank line.
+ 9 9| Before include
+ 10 10| @i sc13b
+ 11 1|
+ 12 11| After include
+ 13 12|
+ 14 13| 3. Include file contains two blank lines.
+ 15 14| Before include
+ 16 15| @i sc13c
+ 17 1|
+ 18 2|
+ 19 16| After include
+ 20 17|
+ 21 18| 4. Include file contains a single line with text on it.
+ 22 19| Before include
+ 23 20| @i sc13d
+ 24 1| This is the include file for test SC13d. Just a file containing one line.
+ 25 21| After include
+ 26 22|
+ 27 23| 5. Include file's last line is not properly terminated.
+ 28 24| Before include
+ 29 25| @i sc13e
+ 30 1| This is the include file for test SC13e. The test is to see how FunnelWeb
+ 31 2| copes with an include file that has an improperly terminated last line.
+ 32 3|
+ 33 26| After include
+ 34 27|
+ 35 28| 6. Include file is ordinary.
+ 36 29| Before include
+ 37 30| @i sc13f
+ 38 1| This is the include file for tests SC13.6 and SC13.7.
+ 39 2| There are only two lines, and this is the second one.
+ 40 31| After include
+ 41 32|
+ 42 33| 7. Test upper case I and file extension inheritance.
+ 43 34| Before include
+ 44 35| @I sc13f
+ 45 1| This is the include file for tests SC13.6 and SC13.7.
+ 46 2| There are only two lines, and this is the second one.
+ 47 36| After include
+ 48 37|
+ 49 38| End of test File.
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There was 1 Error and 1 Warning.
diff --git a/web/funnelAC/results/sc14.lis b/web/funnelAC/results/sc14.lis
new file mode 100644
index 0000000000..228c6c5f64
--- /dev/null
+++ b/web/funnelAC/results/sc14.lis
@@ -0,0 +1,477 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 34 3A 20 54 65 73 74 20 74 68 61 74 20 | SC14: Test that |
+| 74 68 65 20 6D 61 78 69 6D 75 6D 20 6E 75 6D 62 | the maximum numb |
+| 65 72 20 6F 66 20 6C 65 76 65 6C 73 20 6F 66 20 | er of levels of |
+| 69 6E 63 6C 75 64 65 20 66 69 6C 65 20 69 73 20 | include file is |
+| 31 30 2E 0A 54 68 69 73 20 69 73 20 6D 6F 73 74 | 10..This is most |
+| 20 65 61 73 69 6C 79 20 64 6F 6E 65 20 77 69 74 | easily done wit |
+| 68 20 61 20 72 65 63 75 72 73 69 76 65 20 69 6E | h a recursive in |
+| 63 6C 75 73 69 6F 6E 2E 0A 0A 42 65 66 6F 72 65 | clusion...Before |
+| 20 74 68 65 20 69 6E 63 6C 75 64 65 0A 40 69 20 | the include.@i |
+| 73 63 31 34 2E 66 77 0A 41 66 74 65 72 20 74 68 | sc14.fw.After th |
+| 65 20 69 6E 63 6C 75 64 65 0A | e include. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00002 00002| This is most easily done with a recursive inclusion.<010>
+00003 00003| <010>
+00004 00004| Before the include<010>
+00005 00005| @i sc14.fw<010>
+00006 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00007 00002| This is most easily done with a recursive inclusion.<010>
+00008 00003| <010>
+00009 00004| Before the include<010>
+00010 00005| @i sc14.fw<010>
+00011 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00012 00002| This is most easily done with a recursive inclusion.<010>
+00013 00003| <010>
+00014 00004| Before the include<010>
+00015 00005| @i sc14.fw<010>
+00016 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00017 00002| This is most easily done with a recursive inclusion.<010>
+00018 00003| <010>
+00019 00004| Before the include<010>
+00020 00005| @i sc14.fw<010>
+00021 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00022 00002| This is most easily done with a recursive inclusion.<010>
+00023 00003| <010>
+00024 00004| Before the include<010>
+00025 00005| @i sc14.fw<010>
+00026 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00027 00002| This is most easily done with a recursive inclusion.<010>
+00028 00003| <010>
+00029 00004| Before the include<010>
+00030 00005| @i sc14.fw<010>
+00031 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00032 00002| This is most easily done with a recursive inclusion.<010>
+00033 00003| <010>
+00034 00004| Before the include<010>
+00035 00005| @i sc14.fw<010>
+00036 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00037 00002| This is most easily done with a recursive inclusion.<010>
+00038 00003| <010>
+00039 00004| Before the include<010>
+00040 00005| @i sc14.fw<010>
+00041 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00042 00002| This is most easily done with a recursive inclusion.<010>
+00043 00003| <010>
+00044 00004| Before the include<010>
+00045 00005| @i sc14.fw<010>
+00046 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00047 00002| This is most easily done with a recursive inclusion.<010>
+00048 00003| <010>
+00049 00004| Before the include<010>
+00050 00005| @i sc14.fw<010>
+00051 00001| SC14: Test that the maximum number of levels of include file is 10.<010>
+00052 00002| This is most easily done with a recursive inclusion.<010>
+00053 00003| <010>
+00054 00004| Before the include<010>
+00055 00005| @i sc14.fw<010>
+00056 00006| After the include<010>
+00057 00006| After the include<010>
+00058 00006| After the include<010>
+00059 00006| After the include<010>
+00060 00006| After the include<010>
+00061 00006| After the include<010>
+00062 00006| After the include<010>
+00063 00006| After the include<010>
+00064 00006| After the include<010>
+00065 00006| After the include<010>
+00066 00006| After the include<010>
+00067 00007| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 23 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0006[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0011[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0016[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0021[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0026[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0031[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0036[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0041[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0046[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0051[01]: Text. Text scrap[Grey]="SC14: Test that the maximum number of levels of include file is 10.<010>
+This is most easily done with a recursive inclusion.<010>
+<010>
+Before the include<010>
+"
+0056[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0057[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0058[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0059[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0060[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0061[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0062[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0063[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0064[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0065[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0066[01]: Text. Text scrap[Grey]="After the include<010>
+"
+0067[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC14: Test that the maximum number of levels of include file is 10.
+ 2 2| This is most easily done with a recursive inclusion.
+ 3 3|
+ 4 4| Before the include
+ 5 5| @i sc14.fw
+ 6 1| SC14: Test that the maximum number of levels of include file is 10.
+ 7 2| This is most easily done with a recursive inclusion.
+ 8 3|
+ 9 4| Before the include
+ 10 5| @i sc14.fw
+ 11 1| SC14: Test that the maximum number of levels of include file is 10.
+ 12 2| This is most easily done with a recursive inclusion.
+ 13 3|
+ 14 4| Before the include
+ 15 5| @i sc14.fw
+ 16 1| SC14: Test that the maximum number of levels of include file is 10.
+ 17 2| This is most easily done with a recursive inclusion.
+ 18 3|
+ 19 4| Before the include
+ 20 5| @i sc14.fw
+ 21 1| SC14: Test that the maximum number of levels of include file is 10.
+ 22 2| This is most easily done with a recursive inclusion.
+ 23 3|
+ 24 4| Before the include
+ 25 5| @i sc14.fw
+ 26 1| SC14: Test that the maximum number of levels of include file is 10.
+ 27 2| This is most easily done with a recursive inclusion.
+ 28 3|
+ 29 4| Before the include
+ 30 5| @i sc14.fw
+ 31 1| SC14: Test that the maximum number of levels of include file is 10.
+ 32 2| This is most easily done with a recursive inclusion.
+ 33 3|
+ 34 4| Before the include
+ 35 5| @i sc14.fw
+ 36 1| SC14: Test that the maximum number of levels of include file is 10.
+ 37 2| This is most easily done with a recursive inclusion.
+ 38 3|
+ 39 4| Before the include
+ 40 5| @i sc14.fw
+ 41 1| SC14: Test that the maximum number of levels of include file is 10.
+ 42 2| This is most easily done with a recursive inclusion.
+ 43 3|
+ 44 4| Before the include
+ 45 5| @i sc14.fw
+ 46 1| SC14: Test that the maximum number of levels of include file is 10.
+ 47 2| This is most easily done with a recursive inclusion.
+ 48 3|
+ 49 4| Before the include
+ 50 5| @i sc14.fw
+ 51 1| SC14: Test that the maximum number of levels of include file is 10.
+ 52 2| This is most easily done with a recursive inclusion.
+ 53 3|
+ 54 4| Before the include
+ 55 5| @i sc14.fw
+ Error|.^This include file is nested too deeply. It's probably recursive.
+ |.^The maximum level of nested includes is 10.
+ |.^Include ignored.
+ 56 6| After the include
+ 57 6| After the include
+ 58 6| After the include
+ 59 6| After the include
+ 60 6| After the include
+ 61 6| After the include
+ 62 6| After the include
+ 63 6| After the include
+ 64 6| After the include
+ 65 6| After the include
+ 66 6| After the include
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There was 1 Error.
diff --git a/web/funnelAC/results/sc15.lis b/web/funnelAC/results/sc15.lis
new file mode 100644
index 0000000000..317e9453cc
--- /dev/null
+++ b/web/funnelAC/results/sc15.lis
@@ -0,0 +1,355 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 35 3A 20 54 65 73 74 20 74 68 61 74 20 | SC15: Test that |
+| 63 65 72 74 61 69 6E 20 61 74 74 72 69 62 75 74 | certain attribut |
+| 65 73 20 61 72 65 20 73 61 76 65 64 20 61 63 72 | es are saved acr |
+| 6F 73 73 20 69 6E 63 6C 75 73 69 6F 6E 73 2E 0A | oss inclusions.. |
+| 0A 31 2E 20 4D 61 78 69 6D 75 6D 20 69 6E 70 75 | .1. Maximum inpu |
+| 74 20 6C 69 6E 65 20 6C 65 6E 67 74 68 2E 0A 32 | t line length..2 |
+| 2E 20 53 70 65 63 69 61 6C 20 63 68 61 72 61 63 | . Special charac |
+| 74 65 72 2E 0A 33 2E 20 4C 6F 63 61 6C 20 6C 69 | ter..3. Local li |
+| 6E 65 20 6E 75 6D 62 65 72 2E 0A 0A 54 6F 20 74 | ne number...To t |
+| 65 73 74 20 74 68 69 73 2C 20 77 65 20 66 69 72 | est this, we fir |
+| 73 74 20 73 65 74 20 74 68 65 20 66 69 72 73 74 | st set the first |
+| 20 74 77 6F 20 61 74 74 72 69 62 75 74 65 73 20 | two attributes |
+| 61 77 61 79 20 66 72 6F 6D 20 74 68 65 0A 64 65 | away from the.de |
+| 66 61 75 6C 74 2E 20 54 68 69 73 20 77 69 6C 6C | fault. This will |
+| 20 65 6E 61 62 6C 65 20 75 73 20 74 6F 20 62 65 | enable us to be |
+| 20 73 75 72 65 20 74 68 61 74 20 77 68 65 6E 20 | sure that when |
+| 74 68 65 79 20 61 72 65 20 72 65 73 74 6F 72 65 | they are restore |
+| 64 20 74 68 61 74 0A 74 68 65 79 20 61 72 65 20 | d that.they are |
+| 62 65 69 6E 67 20 72 65 73 74 6F 72 65 64 20 74 | being restored t |
+| 6F 20 74 68 65 69 72 20 66 6F 72 6D 65 72 20 76 | o their former v |
+| 61 6C 75 65 73 20 61 6E 64 20 6E 6F 74 20 6A 75 | alues and not ju |
+| 73 74 20 73 65 74 20 74 6F 20 74 68 65 0A 64 65 | st set to the.de |
+| 66 61 75 6C 74 2E 0A 0A 40 3D 2A 20 20 20 2A 21 | fault...@=* *! |
+| 20 43 68 61 6E 67 65 20 74 68 65 20 73 70 65 63 | Change the spec |
+| 69 61 6C 20 63 68 61 72 61 63 74 65 72 2E 0A 2A | ial character..* |
+| 70 20 6D 61 78 69 6D 75 6D 5F 69 6E 70 75 74 5F | p maximum_input_ |
+| 6C 69 6E 65 5F 6C 65 6E 67 74 68 20 3D 20 37 35 | line_length = 75 |
+| 0A 0A 42 65 66 6F 72 65 20 69 6E 63 6C 75 64 65 | ..Before include |
+| 2E 0A 2A 69 20 73 63 31 35 61 0A 41 66 74 65 72 | ..*i sc15a.After |
+| 20 69 6E 63 6C 75 64 65 2E 0A 0A 49 66 20 74 68 | include...If th |
+| 65 20 6D 61 78 69 6D 75 6D 20 69 6E 70 75 74 20 | e maximum input |
+| 6C 69 6E 65 20 6C 65 6E 67 74 68 20 68 61 73 20 | line length has |
+| 62 65 65 6E 20 63 6F 72 72 65 63 74 6C 79 20 72 | been correctly r |
+| 65 73 74 6F 72 65 64 20 74 68 65 6E 20 74 68 65 | estored then the |
+| 0A 73 65 63 6F 6E 64 20 6F 66 20 74 68 65 20 66 | .second of the f |
+| 6F 6C 6C 6F 77 69 6E 67 20 74 77 6F 20 6C 69 6E | ollowing two lin |
+| 65 73 20 73 68 6F 75 6C 64 20 67 69 76 65 20 61 | es should give a |
+| 6E 20 65 72 72 6F 72 2C 20 62 75 74 20 6E 6F 74 | n error, but not |
+| 20 74 68 65 20 66 69 72 73 74 2E 0A 31 32 33 34 | the first..1234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 0A 31 32 33 34 35 36 37 38 | 9012345.12345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 0A 0A 49 66 20 74 68 65 20 73 70 65 | 3456..If the spe |
+| 63 69 61 6C 20 63 68 61 72 61 63 74 65 72 20 68 | cial character h |
+| 61 73 20 62 65 65 6E 20 70 72 65 73 65 72 76 65 | as been preserve |
+| 64 2C 20 74 68 65 6E 20 74 68 65 20 66 6F 6C 6C | d, then the foll |
+| 6F 77 69 6E 67 20 73 68 6F 75 6C 64 0A 67 65 6E | owing should.gen |
+| 65 72 61 74 65 20 61 6E 20 65 72 72 6F 72 2E 0A | erate an error.. |
+| 0A 2A 20 20 20 2D 20 54 68 69 73 20 73 68 6F 75 | .* - This shou |
+| 6C 64 20 67 65 6E 65 72 61 74 65 20 61 6E 20 65 | ld generate an e |
+| 72 72 6F 72 20 69 66 20 61 6C 6C 20 69 73 20 77 | rror if all is w |
+| 65 6C 6C 2E 0A 0A 50 72 65 73 65 72 76 61 74 69 | ell...Preservati |
+| 6F 6E 20 6F 66 20 74 68 65 20 6C 6F 63 61 6C 20 | on of the local |
+| 6C 69 6E 65 20 6E 75 6D 62 65 72 20 63 61 6E 20 | line number can |
+| 62 65 20 63 68 65 63 6B 65 64 20 62 79 20 6C 6F | be checked by lo |
+| 6F 6B 69 6E 67 20 61 74 20 74 68 65 0A 6C 69 73 | oking at the.lis |
+| 74 69 6E 67 20 66 69 6C 65 2E 0A | ting file.. |
++-------------------------------------------------+------------------+
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 54 68 69 73 20 69 73 20 74 68 65 20 69 6E 63 6C | This is the incl |
+| 75 64 65 20 66 69 6C 65 20 66 6F 72 20 74 65 73 | ude file for tes |
+| 74 20 53 43 31 35 2E 20 54 68 65 20 53 43 31 35 | t SC15. The SC15 |
+| 20 74 65 73 74 20 63 68 65 63 6B 73 20 74 6F 20 | test checks to |
+| 6D 61 6B 65 0A 73 75 72 65 20 74 68 61 74 20 46 | make.sure that F |
+| 75 6E 6E 65 6C 57 65 62 20 69 73 20 73 61 76 69 | unnelWeb is savi |
+| 6E 67 20 61 6E 64 20 72 65 73 74 6F 72 69 6E 67 | ng and restoring |
+| 20 74 68 72 65 65 20 73 63 61 6E 6E 69 6E 67 0A | three scanning. |
+| 61 74 74 72 69 62 75 74 65 73 20 61 63 72 6F 73 | attributes acros |
+| 73 20 69 6E 63 6C 75 64 65 20 66 69 6C 65 73 2E | s include files. |
+| 20 57 65 20 61 6C 73 6F 20 77 61 6E 74 20 74 6F | We also want to |
+| 20 6D 61 6B 65 20 73 75 72 65 0A 74 68 61 74 20 | make sure.that |
+| 74 68 65 20 73 63 61 6E 6E 65 72 20 69 73 20 69 | the scanner is i |
+| 6E 69 74 69 61 6C 69 7A 69 6E 67 20 74 68 65 73 | nitializing thes |
+| 65 20 61 74 74 72 69 62 75 74 65 73 20 63 6F 72 | e attributes cor |
+| 72 65 63 74 6C 79 20 77 69 74 68 69 6E 0A 74 68 | rectly within.th |
+| 65 20 69 6E 63 6C 75 64 65 20 66 69 6C 65 2E 0A | e include file.. |
+| 0A 53 43 31 35 2E 34 3A 20 4D 61 6B 65 20 73 75 | .SC15.4: Make su |
+| 72 65 20 74 68 61 74 20 74 68 65 20 73 70 65 63 | re that the spec |
+| 69 61 6C 20 63 68 61 72 61 63 74 65 72 20 69 73 | ial character is |
+| 20 41 54 20 61 74 20 74 68 65 20 73 74 61 72 74 | AT at the start |
+| 20 6F 66 0A 69 6E 63 6C 75 64 65 20 66 69 6C 65 | of.include file |
+| 73 2E 0A 0A 40 20 20 20 20 2D 20 54 68 69 73 20 | s...@ - This |
+| 73 68 6F 75 6C 64 20 79 69 65 6C 64 20 61 6E 20 | should yield an |
+| 65 72 72 6F 72 2E 0A 0A 53 43 31 35 2E 35 20 45 | error...SC15.5 E |
+| 6E 73 75 72 65 20 74 68 61 74 20 74 68 65 20 6D | nsure that the m |
+| 61 78 69 6D 75 6D 20 69 6E 70 75 74 20 6C 69 6E | aximum input lin |
+| 65 20 6C 65 6E 67 74 68 20 69 73 20 38 30 20 61 | e length is 80 a |
+| 74 20 74 68 65 20 73 74 61 72 74 0A 6F 66 20 61 | t the start.of a |
+| 6E 20 69 6E 63 6C 75 64 65 20 66 69 6C 65 2E 20 | n include file. |
+| 49 66 20 61 6C 6C 20 69 73 20 77 65 6C 6C 2C 20 | If all is well, |
+| 6F 6E 6C 79 20 74 68 65 20 73 65 63 6F 6E 64 20 | only the second |
+| 6F 66 20 74 68 65 20 66 6F 6C 6C 6F 77 69 6E 67 | of the following |
+| 20 74 77 6F 0A 6C 69 6E 65 73 20 77 69 6C 6C 20 | two.lines will |
+| 70 72 6F 76 6F 6B 65 20 61 20 22 6C 69 6E 65 20 | provoke a "line |
+| 74 6F 6F 20 6C 6F 6E 67 22 20 65 72 72 6F 72 2E | too long" error. |
+| 0A 0A 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | ..12345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 0A 31 32 33 34 35 36 37 38 39 30 31 32 33 | 90.1234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 0A 0A 4E 6F 77 20 74 68 61 74 20 77 | 8901..Now that w |
+| 65 20 68 61 76 65 20 63 68 65 63 6B 65 64 20 74 | e have checked t |
+| 68 65 20 64 65 66 61 75 6C 74 20 61 74 74 72 69 | he default attri |
+| 62 75 74 65 73 20 6F 6E 20 65 6E 74 65 72 69 6E | butes on enterin |
+| 67 20 61 6E 20 69 6E 63 6C 75 64 65 20 66 69 6C | g an include fil |
+| 65 2C 0A 77 65 20 77 61 6E 74 20 74 6F 20 73 74 | e,.we want to st |
+| 75 66 66 20 74 68 65 6D 20 75 70 20 73 6F 20 61 | uff them up so a |
+| 73 20 74 6F 20 6D 61 6B 65 20 73 75 72 65 20 74 | s to make sure t |
+| 68 61 74 20 74 68 65 20 61 74 74 72 69 62 75 74 | hat the attribut |
+| 65 73 0A 70 72 65 76 61 69 6C 69 6E 67 20 77 68 | es.prevailing wh |
+| 65 6E 20 74 68 65 20 69 6E 63 6C 75 64 65 20 77 | en the include w |
+| 61 73 20 68 69 74 20 61 72 65 20 72 65 73 74 6F | as hit are resto |
+| 72 65 64 2E 0A 0A 40 70 20 6D 61 78 69 6D 75 6D | red...@p maximum |
+| 5F 69 6E 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 | _input_line_leng |
+| 74 68 20 3D 20 36 35 0A 40 3D 2B 0A 0A | th = 65.@=+.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC15: Test that certain attributes are saved across inclusions.<010>
+00002 00002| <010>
+00003 00003| 1. Maximum input line length.<010>
+00004 00004| 2. Special character.<010>
+00005 00005| 3. Local line number.<010>
+00006 00006| <010>
+00007 00007| To test this, we first set the first two attributes away from the<010>
+00008 00008| default. This will enable us to be sure that when they are restored that<010>
+00009 00009| they are being restored to their former values and not just set to the<010>
+00010 00010| default.<010>
+00011 00011| <010>
+00012 00012| @=* *! Change the special character.<010>
+00013 00013| *p maximum_input_line_length = 75<010>
+00014 00014| <010>
+00015 00015| Before include.<010>
+00016 00016| *i sc15a<010>
+00017 00001| This is the include file for test SC15. The SC15 test checks to make<010>
+00018 00002| sure that FunnelWeb is saving and restoring three scanning<010>
+00019 00003| attributes across include files. We also want to make sure<010>
+00020 00004| that the scanner is initializing these attributes correctly within<010>
+00021 00005| the include file.<010>
+00022 00006| <010>
+00023 00007| SC15.4: Make sure that the special character is AT at the start of<010>
+00024 00008| include files.<010>
+00025 00009| <010>
+00026 00010| @ - This should yield an error.<010>
+00027 00011| <010>
+00028 00012| SC15.5 Ensure that the maximum input line length is 80 at the start<010>
+00029 00013| of an include file. If all is well, only the second of the following two<010>
+00030 00014| lines will provoke a "line too long" error.<010>
+00031 00015| <010>
+00032 00016| 12345678901234567890123456789012345678901234567890123456789012345678901234567890<010>
+00033 00017| 123456789012345678901234567890123456789012345678901234567890123456789012345678901<010>
+00034 00018| <010>
+00035 00019| Now that we have checked the default attributes on entering an include file,<010>
+00036 00020| we want to stuff them up so as to make sure that the attributes<010>
+00037 00021| prevailing when the include was hit are restored.<010>
+00038 00022| <010>
+00039 00023| @p maximum_input_line_length = 65<010>
+00040 00024| @=+<010>
+00041 00025| <010>
+00042 00017| After include.<010>
+00043 00018| <010>
+00044 00019| If the maximum input line length has been correctly restored then the<010>
+00045 00020| second of the following two lines should give an error, but not the first.<010>
+00046 00021| 123456789012345678901234567890123456789012345678901234567890123456789012345<010>
+00047 00022| 1234567890123456789012345678901234567890123456789012345678901234567890123456<010>
+00048 00023| <010>
+00049 00024| If the special character has been preserved, then the following should<010>
+00050 00025| generate an error.<010>
+00051 00026| <010>
+00052 00027| * - This should generate an error if all is well.<010>
+00053 00028| <010>
+00054 00029| Preservation of the local line number can be checked by looking at the<010>
+00055 00030| listing file.<010>
+00056 00031| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 9 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC15: Test that certain attributes are saved across inclusions.<010>
+<010>
+1. Maximum input line length.<010>
+2. Special character.<010>
+3. Local line number.<010>
+<010>
+To test this, we first set the first two attributes away from the<010>
+default. This will enable us to be sure that when they are restored that<010>
+they are being restored to their former values and not just set to the<010>
+default.<010>
+<010>
+"
+0012[04]: Text. Text scrap[White]=" "
+0014[01]: Text. Text scrap[Grey]="<010>
+Before include.<010>
+"
+0017[01]: Text. Text scrap[Grey]="This is the include file for test SC15. The SC15 test checks to make<010>
+sure that FunnelWeb is saving and restoring three scanning<010>
+attributes across include files. We also want to make sure<010>
+that the scanner is initializing these attributes correctly within<010>
+the include file.<010>
+<010>
+SC15.4: Make sure that the special character is AT at the start of<010>
+include files.<010>
+<010>
+"
+0026[03]: Text. Text scrap[Grey]=" - This should yield an error.<010>
+<010>
+SC15.5 Ensure that the maximum input line length is 80 at the start<010>
+of an include file. If all is well, only the second of the following two<010>
+lines will provoke a "line too long" error.<010>
+<010>
+12345678901234567890123456789012345678901234567890123456789012345678901234567890<010>
+123456789012345678901234567890123456789012345678901234567890123456789012345678901<010>
+<010>
+Now that we have checked the default attributes on entering an include file,<010>
+we want to stuff them up so as to make sure that the attributes<010>
+prevailing when the include was hit are restored.<010>
+<010>
+"
+0040[04]: Text. Text scrap[White]="<010>
+<010>
+"
+0042[01]: Text. Text scrap[Grey]="After include.<010>
+<010>
+If the maximum input line length has been correctly restored then the<010>
+second of the following two lines should give an error, but not the first.<010>
+123456789012345678901234567890123456789012345678901234567890123456789012345<010>
+1234567890123456789012345678901234567890123456789012345678901234567890123456<010>
+<010>
+If the special character has been preserved, then the following should<010>
+generate an error.<010>
+<010>
+"
+0052[03]: Text. Text scrap[Grey]=" - This should generate an error if all is well.<010>
+<010>
+Preservation of the local line number can be checked by looking at the<010>
+listing file.<010>
+"
+0056[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC15: Test that certain attributes are saved across inclusions.
+ 2 2|
+ 3 3| 1. Maximum input line length.
+ 4 4| 2. Special character.
+ 5 5| 3. Local line number.
+ 6 6|
+ 7 7| To test this, we first set the first two attributes away from the
+ 8 8| default. This will enable us to be sure that when they are restored that
+ 9 9| they are being restored to their former values and not just set to the
+ 10 10| default.
+ 11 11|
+ 12 12| @=* *! Change the special character.
+ 13 13| *p maximum_input_line_length = 75
+ 14 14|
+ 15 15| Before include.
+ 16 16| *i sc15a
+ 17 1| This is the include file for test SC15. The SC15 test checks to make
+ 18 2| sure that FunnelWeb is saving and restoring three scanning
+ 19 3| attributes across include files. We also want to make sure
+ 20 4| that the scanner is initializing these attributes correctly within
+ 21 5| the include file.
+ 22 6|
+ 23 7| SC15.4: Make sure that the special character is AT at the start of
+ 24 8| include files.
+ 25 9|
+ 26 10| @ - This should yield an error.
+ Error|.^<special><space> is not a legal special sequence.
+ 27 11|
+ 28 12| SC15.5 Ensure that the maximum input line length is 80 at the start
+ 29 13| of an include file. If all is well, only the second of the following two
+ 30 14| lines will provoke a "line too long" error.
+ 31 15|
+ 32 16| 12345678901234567890123456789012345678901234567890123456789012345678901234567890
+ 33 17| 123456789012345678901234567890123456789012345678901234567890123456789012345678901
+ Error|.................................................................................^Input line is too long (this character is the first offender).
+ |.................................................................................^Currently, the maximum allowable input line length is 80.
+ |.................................................................................^Note: You can change this using a pragma directive (@p).
+ 34 18|
+ 35 19| Now that we have checked the default attributes on entering an include file,
+ 36 20| we want to stuff them up so as to make sure that the attributes
+ 37 21| prevailing when the include was hit are restored.
+ 38 22|
+ 39 23| @p maximum_input_line_length = 65
+ 40 24| @=+
+ 41 25|
+ 42 17| After include.
+ 43 18|
+ 44 19| If the maximum input line length has been correctly restored then the
+ 45 20| second of the following two lines should give an error, but not the first.
+ 46 21| 123456789012345678901234567890123456789012345678901234567890123456789012345
+ 47 22| 1234567890123456789012345678901234567890123456789012345678901234567890123456
+ Error|............................................................................^Input line is too long (this character is the first offender).
+ |............................................................................^Currently, the maximum allowable input line length is 75.
+ |............................................................................^Note: You can change this using a pragma directive (@p).
+ 48 23|
+ 49 24| If the special character has been preserved, then the following should
+ 50 25| generate an error.
+ 51 26|
+ 52 27| * - This should generate an error if all is well.
+ Error|.^<special><space> is not a legal special sequence.
+ 53 28|
+ 54 29| Preservation of the local line number can be checked by looking at the
+ 55 30| listing file.
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 4 Errors.
diff --git a/web/funnelAC/results/sc16.lis b/web/funnelAC/results/sc16.lis
new file mode 100644
index 0000000000..3170ba293f
--- /dev/null
+++ b/web/funnelAC/results/sc16.lis
@@ -0,0 +1,456 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 36 3A 20 54 65 73 74 20 3C 73 70 65 63 | SC16: Test <spec |
+| 69 61 6C 3E 5E 20 73 65 71 75 65 6E 63 65 2E 0A | ial>^ sequence.. |
+| 0A 31 2E 20 54 65 73 74 20 74 68 61 74 20 61 6C | .1. Test that al |
+| 6C 20 62 61 73 65 20 63 68 61 72 61 63 74 65 72 | l base character |
+| 73 20 77 6F 72 6B 20 28 69 6E 20 62 6F 74 68 20 | s work (in both |
+| 63 61 73 65 73 29 2E 0A 20 20 20 54 68 65 73 65 | cases).. These |
+| 20 73 68 6F 75 6C 64 20 70 72 6F 76 6F 6B 65 20 | should provoke |
+| 6E 6F 20 65 72 72 6F 72 73 2E 0A 0A 20 20 20 40 | no errors... @ |
+| 5E 42 28 30 30 30 30 30 30 30 30 29 20 20 20 40 | ^B(00000000) @ |
+| 5E 62 28 30 30 30 30 30 30 30 30 29 0A 20 20 20 | ^b(00000000). |
+| 40 5E 4F 28 30 30 30 29 20 20 20 40 5E 6F 28 30 | @^O(000) @^o(0 |
+| 30 30 29 0A 20 20 20 40 5E 51 28 30 30 30 29 20 | 00). @^Q(000) |
+| 20 20 40 5E 71 28 30 30 30 29 0A 20 20 20 40 5E | @^q(000). @^ |
+| 44 28 30 30 30 29 20 20 20 40 5E 64 28 30 30 30 | D(000) @^d(000 |
+| 29 0A 20 20 20 40 5E 48 28 30 30 29 20 20 20 20 | ). @^H(00) |
+| 40 5E 68 28 30 30 29 0A 20 20 20 40 5E 58 28 30 | @^h(00). @^X(0 |
+| 30 29 20 20 20 20 40 5E 78 28 30 30 29 0A 0A 32 | 0) @^x(00)..2 |
+| 2E 20 54 65 73 74 20 74 68 61 74 20 73 6F 6D 65 | . Test that some |
+| 20 6F 74 68 65 72 20 62 61 73 65 20 63 68 61 72 | other base char |
+| 61 63 74 65 72 73 20 67 65 6E 65 72 61 74 65 20 | acters generate |
+| 61 6E 20 65 72 72 6F 72 2E 0A 0A 20 20 20 40 5E | an error... @^ |
+| 75 28 30 29 0A 20 20 20 40 5E 79 0A 20 20 20 40 | u(0). @^y. @ |
+| 5E 23 0A 20 20 20 40 5E 28 0A 0A 33 2E 20 54 65 | ^#. @^(..3. Te |
+| 73 74 20 74 68 61 74 20 61 6E 20 65 72 72 6F 72 | st that an error |
+| 20 69 73 20 67 65 6E 65 72 61 74 65 64 20 69 66 | is generated if |
+| 20 70 61 72 65 6E 74 68 65 73 69 73 20 69 73 20 | parenthesis is |
+| 6D 69 73 73 69 6E 67 2E 0A 0A 20 20 20 40 5E 44 | missing... @^D |
+| 33 34 29 0A 0A 34 2E 20 54 65 73 74 20 6C 65 67 | 34)..4. Test leg |
+| 61 6C 20 64 69 67 69 74 73 20 69 6E 20 65 61 63 | al digits in eac |
+| 68 20 62 61 73 65 2E 0A 0A 20 20 20 40 5E 42 28 | h base... @^B( |
+| 30 30 30 30 31 31 31 31 29 0A 20 20 20 40 5E 4F | 00001111). @^O |
+| 28 30 31 32 29 20 20 40 5E 4F 28 30 33 34 29 20 | (012) @^O(034) |
+| 40 5E 4F 28 30 35 36 29 20 40 5E 4F 28 30 37 37 | @^O(056) @^O(077 |
+| 29 0A 20 20 20 40 5E 44 28 30 31 32 29 20 20 40 | ). @^D(012) @ |
+| 5E 44 28 30 33 34 29 20 40 5E 44 28 30 35 36 29 | ^D(034) @^D(056) |
+| 20 40 5E 44 28 30 37 38 29 20 40 5E 44 28 30 39 | @^D(078) @^D(09 |
+| 39 29 0A 20 20 20 40 5E 48 28 30 31 29 20 40 5E | 9). @^H(01) @^ |
+| 48 28 32 33 29 20 40 5E 48 28 34 35 29 20 40 5E | H(23) @^H(45) @^ |
+| 48 28 36 37 29 0A 20 20 20 40 5E 48 28 38 39 29 | H(67). @^H(89) |
+| 20 40 5E 48 28 41 42 29 20 40 5E 58 28 43 44 29 | @^H(AB) @^X(CD) |
+| 20 40 5E 58 28 45 46 29 20 20 40 5E 78 28 61 66 | @^X(EF) @^x(af |
+| 29 0A 0A 35 2E 20 54 65 73 74 20 69 6C 6C 65 67 | )..5. Test illeg |
+| 61 6C 20 64 69 67 69 74 73 20 69 6E 20 65 61 63 | al digits in eac |
+| 68 20 62 61 73 65 2E 0A 0A 20 20 20 40 5E 42 28 | h base... @^B( |
+| 30 30 30 30 30 30 30 32 29 0A 20 20 20 40 5E 4F | 00000002). @^O |
+| 28 30 30 38 29 0A 20 20 20 40 5E 44 28 30 30 41 | (008). @^D(00A |
+| 29 0A 20 20 20 40 5E 48 28 30 47 29 0A 0A 36 2E | ). @^H(0G)..6. |
+| 20 54 65 73 74 20 77 68 61 74 20 68 61 70 70 65 | Test what happe |
+| 6E 73 20 69 66 20 74 68 65 72 65 20 61 72 65 20 | ns if there are |
+| 74 68 65 20 77 72 6F 6E 67 20 6E 75 6D 62 65 72 | the wrong number |
+| 20 6F 66 20 64 69 67 69 74 73 0A 20 20 20 28 74 | of digits. (t |
+| 6F 6F 20 66 65 77 2C 20 74 6F 6F 20 6D 61 6E 79 | oo few, too many |
+| 29 2E 0A 0A 20 20 20 40 5E 42 28 31 29 0A 20 20 | )... @^B(1). |
+| 20 40 5E 4F 28 31 29 0A 20 20 20 40 5E 44 28 31 | @^O(1). @^D(1 |
+| 29 0A 20 20 20 40 5E 48 28 31 29 0A 0A 20 20 20 | ). @^H(1).. |
+| 40 5E 42 28 30 30 30 30 30 30 30 30 31 29 0A 20 | @^B(000000001). |
+| 20 20 40 5E 4F 28 30 30 30 34 29 0A 20 20 20 40 | @^O(0004). @ |
+| 5E 44 28 30 30 30 31 29 0A 20 20 20 40 5E 48 28 | ^D(0001). @^H( |
+| 30 30 35 29 0A 0A 37 2E 20 54 65 73 74 20 74 68 | 005)..7. Test th |
+| 61 74 20 61 6E 20 65 72 72 6F 72 20 69 73 20 67 | at an error is g |
+| 65 6E 65 72 61 74 65 64 20 66 6F 72 20 61 20 6D | enerated for a m |
+| 69 73 73 69 6E 67 20 63 6C 6F 73 69 6E 67 20 70 | issing closing p |
+| 61 72 65 6E 74 68 65 73 69 73 2E 0A 0A 20 20 40 | arenthesis... @ |
+| 5E 42 28 30 30 30 30 30 30 30 30 0A 20 20 40 5E | ^B(00000000. @^ |
+| 44 28 30 34 35 28 0A 0A 38 2E 20 54 65 73 74 20 | D(045(..8. Test |
+| 77 68 61 74 20 68 61 70 70 65 6E 73 20 69 6E 20 | what happens in |
+| 6E 75 6D 62 65 72 20 69 73 20 6F 75 74 20 6F 66 | number is out of |
+| 20 74 68 65 20 72 61 6E 67 65 20 5B 30 2C 32 35 | the range [0,25 |
+| 35 5D 2E 0A 0A 20 20 40 5E 44 28 32 35 35 29 0A | 5]... @^D(255). |
+| 20 20 40 5E 44 28 32 35 36 29 0A 20 20 40 5E 44 | @^D(256). @^D |
+| 28 39 39 39 29 0A 0A | (999).. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC16: Test <special>^ sequence.<010>
+00002 00002| <010>
+00003 00003| 1. Test that all base characters work (in both cases).<010>
+00004 00004| These should provoke no errors.<010>
+00005 00005| <010>
+00006 00006| @^B(00000000) @^b(00000000)<010>
+00007 00007| @^O(000) @^o(000)<010>
+00008 00008| @^Q(000) @^q(000)<010>
+00009 00009| @^D(000) @^d(000)<010>
+00010 00010| @^H(00) @^h(00)<010>
+00011 00011| @^X(00) @^x(00)<010>
+00012 00012| <010>
+00013 00013| 2. Test that some other base characters generate an error.<010>
+00014 00014| <010>
+00015 00015| @^u(0)<010>
+00016 00016| @^y<010>
+00017 00017| @^#<010>
+00018 00018| @^(<010>
+00019 00019| <010>
+00020 00020| 3. Test that an error is generated if parenthesis is missing.<010>
+00021 00021| <010>
+00022 00022| @^D34)<010>
+00023 00023| <010>
+00024 00024| 4. Test legal digits in each base.<010>
+00025 00025| <010>
+00026 00026| @^B(00001111)<010>
+00027 00027| @^O(012) @^O(034) @^O(056) @^O(077)<010>
+00028 00028| @^D(012) @^D(034) @^D(056) @^D(078) @^D(099)<010>
+00029 00029| @^H(01) @^H(23) @^H(45) @^H(67)<010>
+00030 00030| @^H(89) @^H(AB) @^X(CD) @^X(EF) @^x(af)<010>
+00031 00031| <010>
+00032 00032| 5. Test illegal digits in each base.<010>
+00033 00033| <010>
+00034 00034| @^B(00000002)<010>
+00035 00035| @^O(008)<010>
+00036 00036| @^D(00A)<010>
+00037 00037| @^H(0G)<010>
+00038 00038| <010>
+00039 00039| 6. Test what happens if there are the wrong number of digits<010>
+00040 00040| (too few, too many).<010>
+00041 00041| <010>
+00042 00042| @^B(1)<010>
+00043 00043| @^O(1)<010>
+00044 00044| @^D(1)<010>
+00045 00045| @^H(1)<010>
+00046 00046| <010>
+00047 00047| @^B(000000001)<010>
+00048 00048| @^O(0004)<010>
+00049 00049| @^D(0001)<010>
+00050 00050| @^H(005)<010>
+00051 00051| <010>
+00052 00052| 7. Test that an error is generated for a missing closing parenthesis.<010>
+00053 00053| <010>
+00054 00054| @^B(00000000<010>
+00055 00055| @^D(045(<010>
+00056 00056| <010>
+00057 00057| 8. Test what happens in number is out of the range [0,255].<010>
+00058 00058| <010>
+00059 00059| @^D(255)<010>
+00060 00060| @^D(256)<010>
+00061 00061| @^D(999)<010>
+00062 00062| <010>
+00063 00063| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 87 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC16: Test <special>^ sequence.<010>
+<010>
+1. Test that all base characters work (in both cases).<010>
+ These should provoke no errors.<010>
+<010>
+ "
+0006[04]: Text. Text scrap[Grey]="<000>"
+0006[17]: Text. Text scrap[White]=" "
+0006[20]: Text. Text scrap[Grey]="<000>"
+0006[33]: Text. Text scrap[White]="<010>
+ "
+0007[04]: Text. Text scrap[Grey]="<000>"
+0007[12]: Text. Text scrap[White]=" "
+0007[15]: Text. Text scrap[Grey]="<000>"
+0007[23]: Text. Text scrap[White]="<010>
+ "
+0008[04]: Text. Text scrap[Grey]="<000>"
+0008[12]: Text. Text scrap[White]=" "
+0008[15]: Text. Text scrap[Grey]="<000>"
+0008[23]: Text. Text scrap[White]="<010>
+ "
+0009[04]: Text. Text scrap[Grey]="<000>"
+0009[12]: Text. Text scrap[White]=" "
+0009[15]: Text. Text scrap[Grey]="<000>"
+0009[23]: Text. Text scrap[White]="<010>
+ "
+0010[04]: Text. Text scrap[Grey]="<000>"
+0010[11]: Text. Text scrap[White]=" "
+0010[15]: Text. Text scrap[Grey]="<000>"
+0010[22]: Text. Text scrap[White]="<010>
+ "
+0011[04]: Text. Text scrap[Grey]="<000>"
+0011[11]: Text. Text scrap[White]=" "
+0011[15]: Text. Text scrap[Grey]="<000>"
+0011[22]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test that some other base characters generate an error.<010>
+<010>
+ "
+0015[07]: Text. Text scrap[Grey]="(0)<010>
+ "
+0016[07]: Text. Text scrap[White]="<010>
+ "
+0017[07]: Text. Text scrap[White]="<010>
+ "
+0018[07]: Text. Text scrap[Grey]="<010>
+<010>
+3. Test that an error is generated if parenthesis is missing.<010>
+<010>
+ "
+0022[08]: Text. Text scrap[Grey]="4)<010>
+<010>
+4. Test legal digits in each base.<010>
+<010>
+ "
+0026[04]: Text. Text scrap[Grey]="<015>"
+0026[17]: Text. Text scrap[White]="<010>
+ "
+0027[04]: Text. Text scrap[Grey]="<010>
+"
+0027[12]: Text. Text scrap[White]=" "
+0027[14]: Text. Text scrap[Grey]="<028>"
+0027[22]: Text. Text scrap[White]=" "
+0027[23]: Text. Text scrap[Grey]="."
+0027[31]: Text. Text scrap[White]=" "
+0027[32]: Text. Text scrap[Grey]="?"
+0027[40]: Text. Text scrap[White]="<010>
+ "
+0028[04]: Text. Text scrap[Grey]="<012>"
+0028[12]: Text. Text scrap[White]=" "
+0028[14]: Text. Text scrap[Grey]="""
+0028[22]: Text. Text scrap[White]=" "
+0028[23]: Text. Text scrap[Grey]="8"
+0028[31]: Text. Text scrap[White]=" "
+0028[32]: Text. Text scrap[Grey]="N"
+0028[40]: Text. Text scrap[White]=" "
+0028[41]: Text. Text scrap[Grey]="c"
+0028[49]: Text. Text scrap[White]="<010>
+ "
+0029[04]: Text. Text scrap[Grey]="<001>"
+0029[11]: Text. Text scrap[White]=" "
+0029[12]: Text. Text scrap[Grey]="#"
+0029[19]: Text. Text scrap[White]=" "
+0029[20]: Text. Text scrap[Grey]="E"
+0029[27]: Text. Text scrap[White]=" "
+0029[28]: Text. Text scrap[Grey]="g"
+0029[35]: Text. Text scrap[White]="<010>
+ "
+0030[04]: Text. Text scrap[Grey]="<137>"
+0030[11]: Text. Text scrap[White]=" "
+0030[12]: Text. Text scrap[Grey]="<171>"
+0030[19]: Text. Text scrap[White]=" "
+0030[20]: Text. Text scrap[Grey]="<205>"
+0030[27]: Text. Text scrap[White]=" "
+0030[28]: Text. Text scrap[Grey]="<239>"
+0030[35]: Text. Text scrap[White]=" "
+0030[37]: Text. Text scrap[Grey]="<175>"
+0030[44]: Text. Text scrap[Grey]="<010>
+<010>
+5. Test illegal digits in each base.<010>
+<010>
+ "
+0034[16]: Text. Text scrap[Grey]=")<010>
+ "
+0035[11]: Text. Text scrap[Grey]=")<010>
+ "
+0036[11]: Text. Text scrap[Grey]=")<010>
+ "
+0037[10]: Text. Text scrap[Grey]=")<010>
+<010>
+6. Test what happens if there are the wrong number of digits<010>
+ (too few, too many).<010>
+<010>
+ "
+0042[10]: Text. Text scrap[White]="<010>
+ "
+0043[10]: Text. Text scrap[White]="<010>
+ "
+0044[10]: Text. Text scrap[White]="<010>
+ "
+0045[10]: Text. Text scrap[White]="<010>
+<010>
+ "
+0047[17]: Text. Text scrap[Grey]=")<010>
+ "
+0048[12]: Text. Text scrap[Grey]=")<010>
+ "
+0049[12]: Text. Text scrap[Grey]=")<010>
+ "
+0050[11]: Text. Text scrap[Grey]=")<010>
+<010>
+7. Test that an error is generated for a missing closing parenthesis.<010>
+<010>
+ "
+0055[01]: Text. Text scrap[White]=" "
+0055[11]: Text. Text scrap[Grey]="<010>
+<010>
+8. Test what happens in number is out of the range [0,255].<010>
+<010>
+ "
+0059[03]: Text. Text scrap[Grey]="<255>"
+0059[11]: Text. Text scrap[White]="<010>
+ "
+0060[11]: Text. Text scrap[White]="<010>
+ "
+0061[11]: Text. Text scrap[White]="<010>
+<010>
+"
+0063[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC16: Test <special>^ sequence.
+ 2 2|
+ 3 3| 1. Test that all base characters work (in both cases).
+ 4 4| These should provoke no errors.
+ 5 5|
+ 6 6| @^B(00000000) @^b(00000000)
+ 7 7| @^O(000) @^o(000)
+ 8 8| @^Q(000) @^q(000)
+ 9 9| @^D(000) @^d(000)
+ 10 10| @^H(00) @^h(00)
+ 11 11| @^X(00) @^x(00)
+ 12 12|
+ 13 13| 2. Test that some other base characters generate an error.
+ 14 14|
+ 15 15| @^u(0)
+ Error|......^Expecting one of 'B', 'Q', 'D', 'H'.
+ |......^(For Binary, Octal, Decimal, and Hexadecimal).
+ |......^A decimal character representation takes the form "@^D(ddd)".
+ |......^(exactly 3 digits) where each digit d is in the range 0..9.
+ 16 16| @^y
+ Error|......^Expecting one of 'B', 'Q', 'D', 'H'.
+ |......^(For Binary, Octal, Decimal, and Hexadecimal).
+ |......^A decimal character representation takes the form "@^D(ddd)".
+ |......^(exactly 3 digits) where each digit d is in the range 0..9.
+ 17 17| @^#
+ Error|......^Expecting one of 'B', 'Q', 'D', 'H'.
+ |......^(For Binary, Octal, Decimal, and Hexadecimal).
+ |......^A decimal character representation takes the form "@^D(ddd)".
+ |......^(exactly 3 digits) where each digit d is in the range 0..9.
+ 18 18| @^(
+ Error|......^Expecting one of 'B', 'Q', 'D', 'H'.
+ |......^(For Binary, Octal, Decimal, and Hexadecimal).
+ |......^A decimal character representation takes the form "@^D(ddd)".
+ |......^(exactly 3 digits) where each digit d is in the range 0..9.
+ 19 19|
+ 20 20| 3. Test that an error is generated if parenthesis is missing.
+ 21 21|
+ 22 22| @^D34)
+ Error|.......^Expecting '('.
+ |.......^A decimal character representation takes the form "@^D(ddd)".
+ |.......^(exactly 3 digits) where each digit d is in the range 0..9.
+ 23 23|
+ 24 24| 4. Test legal digits in each base.
+ 25 25|
+ 26 26| @^B(00001111)
+ 27 27| @^O(012) @^O(034) @^O(056) @^O(077)
+ 28 28| @^D(012) @^D(034) @^D(056) @^D(078) @^D(099)
+ 29 29| @^H(01) @^H(23) @^H(45) @^H(67)
+ 30 30| @^H(89) @^H(AB) @^X(CD) @^X(EF) @^x(af)
+ 31 31|
+ 32 32| 5. Test illegal digits in each base.
+ 33 33|
+ 34 34| @^B(00000002)
+ Error|...............^Illegal digit.
+ |...............^A binary character representation takes the form "@^B(dddddddd)".
+ |...............^(exactly 8 digits) where each digit d is either 0 or 1.
+ 35 35| @^O(008)
+ Error|..........^Illegal digit.
+ |..........^An octal character representation takes the form "@^Q(ddd)" (or "@^O(ddd)").
+ |..........^(exactly 3 digits) where each digit d is in the range 0..7.
+ 36 36| @^D(00A)
+ Error|..........^Illegal digit.
+ |..........^A decimal character representation takes the form "@^D(ddd)".
+ |..........^(exactly 3 digits) where each digit d is in the range 0..9.
+ 37 37| @^H(0G)
+ Error|.........^Illegal digit.
+ |.........^A hexadecimal character representation takes the form "@^X(dd)" (or "@^H(dd)").
+ |.........^(exactly 2 digits) where each digit d is in the range 0..9,A..F.
+ 38 38|
+ 39 39| 6. Test what happens if there are the wrong number of digits
+ 40 40| (too few, too many).
+ 41 41|
+ 42 42| @^B(1)
+ Error|.........^Illegal digit.
+ |.........^A binary character representation takes the form "@^B(dddddddd)".
+ |.........^(exactly 8 digits) where each digit d is either 0 or 1.
+ 43 43| @^O(1)
+ Error|.........^Illegal digit.
+ |.........^An octal character representation takes the form "@^Q(ddd)" (or "@^O(ddd)").
+ |.........^(exactly 3 digits) where each digit d is in the range 0..7.
+ 44 44| @^D(1)
+ Error|.........^Illegal digit.
+ |.........^A decimal character representation takes the form "@^D(ddd)".
+ |.........^(exactly 3 digits) where each digit d is in the range 0..9.
+ 45 45| @^H(1)
+ Error|.........^Illegal digit.
+ |.........^A hexadecimal character representation takes the form "@^X(dd)" (or "@^H(dd)").
+ |.........^(exactly 2 digits) where each digit d is in the range 0..9,A..F.
+ 46 46|
+ 47 47| @^B(000000001)
+ Error|................^Expecting ')'.
+ |................^A binary character representation takes the form "@^B(dddddddd)".
+ |................^(exactly 8 digits) where each digit d is either 0 or 1.
+ 48 48| @^O(0004)
+ Error|...........^Expecting ')'.
+ |...........^An octal character representation takes the form "@^Q(ddd)" (or "@^O(ddd)").
+ |...........^(exactly 3 digits) where each digit d is in the range 0..7.
+ 49 49| @^D(0001)
+ Error|...........^Expecting ')'.
+ |...........^A decimal character representation takes the form "@^D(ddd)".
+ |...........^(exactly 3 digits) where each digit d is in the range 0..9.
+ 50 50| @^H(005)
+ Error|..........^Expecting ')'.
+ |..........^A hexadecimal character representation takes the form "@^X(dd)" (or "@^H(dd)").
+ |..........^(exactly 2 digits) where each digit d is in the range 0..9,A..F.
+ 51 51|
+ 52 52| 7. Test that an error is generated for a missing closing parenthesis.
+ 53 53|
+ 54 54| @^B(00000000
+ Error|...............^Expecting ')'.
+ |...............^A binary character representation takes the form "@^B(dddddddd)".
+ |...............^(exactly 8 digits) where each digit d is either 0 or 1.
+ 55 55| @^D(045(
+ Error|..........^Expecting ')'.
+ |..........^A decimal character representation takes the form "@^D(ddd)".
+ |..........^(exactly 3 digits) where each digit d is in the range 0..9.
+ 56 56|
+ 57 57| 8. Test what happens in number is out of the range [0,255].
+ 58 58|
+ 59 59| @^D(255)
+ 60 60| @^D(256)
+ Error|..........^Character number is too large.
+ |..........^Character number must be in the range [0,255] (decimal).
+ |..........^A decimal character representation takes the form "@^D(ddd)".
+ |..........^(exactly 3 digits) where each digit d is in the range 0..9.
+ 61 61| @^D(999)
+ Error|..........^Character number is too large.
+ |..........^Character number must be in the range [0,255] (decimal).
+ |..........^A decimal character representation takes the form "@^D(ddd)".
+ |..........^(exactly 3 digits) where each digit d is in the range 0..9.
+ 62 62|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 21 Errors.
diff --git a/web/funnelAC/results/sc17.lis b/web/funnelAC/results/sc17.lis
new file mode 100644
index 0000000000..e23bf05b1d
--- /dev/null
+++ b/web/funnelAC/results/sc17.lis
@@ -0,0 +1,352 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 37 3A 20 54 65 73 74 20 3C 73 70 65 63 | SC17: Test <spec |
+| 69 61 6C 3E 23 2E 0A 0A 46 69 72 73 74 20 77 65 | ial>#...First we |
+| 20 74 72 69 70 20 75 70 20 74 68 65 20 73 63 61 | trip up the sca |
+| 6E 6E 65 72 20 73 6F 20 6E 6F 20 66 75 72 74 68 | nner so no furth |
+| 65 72 20 70 61 73 73 65 73 20 74 61 6B 65 20 70 | er passes take p |
+| 6C 61 63 65 2E 0A 0A 40 0A 0A 31 2E 20 54 65 73 | lace...@..1. Tes |
+| 74 20 77 69 74 68 20 61 6C 6C 20 70 6F 73 73 69 | t with all possi |
+| 62 6C 65 20 70 72 69 6E 74 61 62 6C 65 20 63 68 | ble printable ch |
+| 61 72 61 63 74 65 72 73 2E 0A 0A 40 23 21 20 40 | aracters...@#! @ |
+| 23 22 20 40 23 23 20 40 23 24 20 40 23 25 20 40 | #" @## @#$ @#% @ |
+| 23 26 20 40 23 27 20 40 23 28 20 40 23 29 20 40 | #& @#' @#( @#) @ |
+| 23 2A 20 40 23 2B 20 40 23 2C 20 40 23 2D 20 40 | #* @#+ @#, @#- @ |
+| 23 2E 20 40 23 2F 0A 40 23 30 20 40 23 31 20 40 | #. @#/.@#0 @#1 @ |
+| 23 32 20 40 23 33 20 40 23 34 20 40 23 35 20 40 | #2 @#3 @#4 @#5 @ |
+| 23 36 20 40 23 37 20 40 23 38 20 40 23 39 20 40 | #6 @#7 @#8 @#9 @ |
+| 23 3A 20 40 23 3B 20 40 23 3C 20 40 23 3D 20 40 | #: @#; @#< @#= @ |
+| 23 3E 0A 40 23 3F 20 40 23 40 20 40 23 41 20 40 | #>.@#? @#@ @#A @ |
+| 23 42 20 40 23 43 20 40 23 44 20 40 23 45 20 40 | #B @#C @#D @#E @ |
+| 23 46 20 40 23 47 20 40 23 48 20 40 23 49 20 40 | #F @#G @#H @#I @ |
+| 23 4A 20 40 23 4B 20 40 23 4C 20 40 23 4D 0A 40 | #J @#K @#L @#M.@ |
+| 23 4E 20 40 23 4F 20 40 23 50 20 40 23 51 20 40 | #N @#O @#P @#Q @ |
+| 23 52 20 40 23 53 20 40 23 54 20 40 23 55 20 40 | #R @#S @#T @#U @ |
+| 23 56 20 40 23 57 20 40 23 58 20 40 23 59 20 40 | #V @#W @#X @#Y @ |
+| 23 5A 20 40 23 5B 20 40 23 5C 0A 40 23 5D 20 40 | #Z @#[ @#\.@#] @ |
+| 23 5E 20 40 23 5F 20 40 23 60 20 40 23 61 20 40 | #^ @#_ @#` @#a @ |
+| 23 62 20 40 23 63 20 40 23 64 20 40 23 65 20 40 | #b @#c @#d @#e @ |
+| 23 66 20 40 23 67 20 40 23 68 20 40 23 69 20 40 | #f @#g @#h @#i @ |
+| 23 6A 20 40 23 6B 0A 40 23 6C 20 40 23 6D 20 40 | #j @#k.@#l @#m @ |
+| 23 6E 20 40 23 6F 20 40 23 70 20 40 23 71 20 40 | #n @#o @#p @#q @ |
+| 23 72 20 40 23 73 20 40 23 74 20 40 23 75 20 40 | #r @#s @#t @#u @ |
+| 23 76 20 40 23 77 20 40 23 78 20 40 23 79 20 40 | #v @#w @#x @#y @ |
+| 23 7A 0A 40 23 7B 20 40 23 7C 20 40 23 7D 20 40 | #z.@#{ @#| @#} @ |
+| 23 7E 0A 0A 32 2E 20 54 65 73 74 20 74 68 61 74 | #~..2. Test that |
+| 20 3C 73 70 65 63 69 61 6C 3E 23 3C 73 70 61 63 | <special>#<spac |
+| 65 3E 20 69 73 20 66 6C 61 67 67 65 64 20 61 73 | e> is flagged as |
+| 20 61 6E 20 65 72 72 6F 72 2E 0A 0A 20 20 20 40 | an error... @ |
+| 23 20 20 20 20 20 40 21 20 53 68 6F 75 6C 64 20 | # @! Should |
+| 62 65 20 66 6C 61 67 67 65 64 20 61 73 20 61 6E | be flagged as an |
+| 20 65 72 72 6F 72 2E 0A 0A 33 2E 20 54 65 73 74 | error...3. Test |
+| 20 74 68 61 74 20 3C 73 70 65 63 69 61 6C 3E 23 | that <special># |
+| 45 4F 4C 20 69 73 20 66 6C 61 67 67 65 64 20 61 | EOL is flagged a |
+| 73 20 61 6E 20 65 72 72 6F 72 2E 0A 0A 20 20 20 | s an error... |
+| 40 23 0A 0A | @#.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC17: Test <special>#.<010>
+00002 00002| <010>
+00003 00003| First we trip up the scanner so no further passes take place.<010>
+00004 00004| <010>
+00005 00005| @<010>
+00006 00006| <010>
+00007 00007| 1. Test with all possible printable characters.<010>
+00008 00008| <010>
+00009 00009| @#! @#" @## @#$ @#% @#& @#' @#( @#) @#* @#+ @#, @#- @#. @#/<010>
+00010 00010| @#0 @#1 @#2 @#3 @#4 @#5 @#6 @#7 @#8 @#9 @#: @#; @#< @#= @#><010>
+00011 00011| @#? @#@ @#A @#B @#C @#D @#E @#F @#G @#H @#I @#J @#K @#L @#M<010>
+00012 00012| @#N @#O @#P @#Q @#R @#S @#T @#U @#V @#W @#X @#Y @#Z @#[ @#\<010>
+00013 00013| @#] @#^ @#_ @#` @#a @#b @#c @#d @#e @#f @#g @#h @#i @#j @#k<010>
+00014 00014| @#l @#m @#n @#o @#p @#q @#r @#s @#t @#u @#v @#w @#x @#y @#z<010>
+00015 00015| @#{ @#| @#} @#~<010>
+00016 00016| <010>
+00017 00017| 2. Test that <special>#<space> is flagged as an error.<010>
+00018 00018| <010>
+00019 00019| @# @! Should be flagged as an error.<010>
+00020 00020| <010>
+00021 00021| 3. Test that <special>#EOL is flagged as an error.<010>
+00022 00022| <010>
+00023 00023| @#<010>
+00024 00024| <010>
+00025 00025| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 194 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC17: Test <special>#.<010>
+<010>
+First we trip up the scanner so no further passes take place.<010>
+<010>
+"
+0006[01]: Text. Text scrap[Grey]="<010>
+1. Test with all possible printable characters.<010>
+<010>
+"
+0009[01]: @# Name. Character='!'.
+0009[04]: Text. Text scrap[White]=" "
+0009[05]: @# Name. Character='"'.
+0009[08]: Text. Text scrap[White]=" "
+0009[09]: @# Name. Character='#'.
+0009[12]: Text. Text scrap[White]=" "
+0009[13]: @# Name. Character='$'.
+0009[16]: Text. Text scrap[White]=" "
+0009[17]: @# Name. Character='%'.
+0009[20]: Text. Text scrap[White]=" "
+0009[21]: @# Name. Character='&'.
+0009[24]: Text. Text scrap[White]=" "
+0009[25]: @# Name. Character='''.
+0009[28]: Text. Text scrap[White]=" "
+0009[29]: @# Name. Character='('.
+0009[32]: Text. Text scrap[White]=" "
+0009[33]: @# Name. Character=')'.
+0009[36]: Text. Text scrap[White]=" "
+0009[37]: @# Name. Character='*'.
+0009[40]: Text. Text scrap[White]=" "
+0009[41]: @# Name. Character='+'.
+0009[44]: Text. Text scrap[White]=" "
+0009[45]: @# Name. Character=','.
+0009[48]: Text. Text scrap[White]=" "
+0009[49]: @# Name. Character='-'.
+0009[52]: Text. Text scrap[White]=" "
+0009[53]: @# Name. Character='.'.
+0009[56]: Text. Text scrap[White]=" "
+0009[57]: @# Name. Character='/'.
+0009[60]: Text. Text scrap[White]="<010>
+"
+0010[01]: @# Name. Character='0'.
+0010[04]: Text. Text scrap[White]=" "
+0010[05]: @# Name. Character='1'.
+0010[08]: Text. Text scrap[White]=" "
+0010[09]: @# Name. Character='2'.
+0010[12]: Text. Text scrap[White]=" "
+0010[13]: @# Name. Character='3'.
+0010[16]: Text. Text scrap[White]=" "
+0010[17]: @# Name. Character='4'.
+0010[20]: Text. Text scrap[White]=" "
+0010[21]: @# Name. Character='5'.
+0010[24]: Text. Text scrap[White]=" "
+0010[25]: @# Name. Character='6'.
+0010[28]: Text. Text scrap[White]=" "
+0010[29]: @# Name. Character='7'.
+0010[32]: Text. Text scrap[White]=" "
+0010[33]: @# Name. Character='8'.
+0010[36]: Text. Text scrap[White]=" "
+0010[37]: @# Name. Character='9'.
+0010[40]: Text. Text scrap[White]=" "
+0010[41]: @# Name. Character=':'.
+0010[44]: Text. Text scrap[White]=" "
+0010[45]: @# Name. Character=';'.
+0010[48]: Text. Text scrap[White]=" "
+0010[49]: @# Name. Character='<'.
+0010[52]: Text. Text scrap[White]=" "
+0010[53]: @# Name. Character='='.
+0010[56]: Text. Text scrap[White]=" "
+0010[57]: @# Name. Character='>'.
+0010[60]: Text. Text scrap[White]="<010>
+"
+0011[01]: @# Name. Character='?'.
+0011[04]: Text. Text scrap[White]=" "
+0011[05]: @# Name. Character='@'.
+0011[08]: Text. Text scrap[White]=" "
+0011[09]: @# Name. Character='A'.
+0011[12]: Text. Text scrap[White]=" "
+0011[13]: @# Name. Character='B'.
+0011[16]: Text. Text scrap[White]=" "
+0011[17]: @# Name. Character='C'.
+0011[20]: Text. Text scrap[White]=" "
+0011[21]: @# Name. Character='D'.
+0011[24]: Text. Text scrap[White]=" "
+0011[25]: @# Name. Character='E'.
+0011[28]: Text. Text scrap[White]=" "
+0011[29]: @# Name. Character='F'.
+0011[32]: Text. Text scrap[White]=" "
+0011[33]: @# Name. Character='G'.
+0011[36]: Text. Text scrap[White]=" "
+0011[37]: @# Name. Character='H'.
+0011[40]: Text. Text scrap[White]=" "
+0011[41]: @# Name. Character='I'.
+0011[44]: Text. Text scrap[White]=" "
+0011[45]: @# Name. Character='J'.
+0011[48]: Text. Text scrap[White]=" "
+0011[49]: @# Name. Character='K'.
+0011[52]: Text. Text scrap[White]=" "
+0011[53]: @# Name. Character='L'.
+0011[56]: Text. Text scrap[White]=" "
+0011[57]: @# Name. Character='M'.
+0011[60]: Text. Text scrap[White]="<010>
+"
+0012[01]: @# Name. Character='N'.
+0012[04]: Text. Text scrap[White]=" "
+0012[05]: @# Name. Character='O'.
+0012[08]: Text. Text scrap[White]=" "
+0012[09]: @# Name. Character='P'.
+0012[12]: Text. Text scrap[White]=" "
+0012[13]: @# Name. Character='Q'.
+0012[16]: Text. Text scrap[White]=" "
+0012[17]: @# Name. Character='R'.
+0012[20]: Text. Text scrap[White]=" "
+0012[21]: @# Name. Character='S'.
+0012[24]: Text. Text scrap[White]=" "
+0012[25]: @# Name. Character='T'.
+0012[28]: Text. Text scrap[White]=" "
+0012[29]: @# Name. Character='U'.
+0012[32]: Text. Text scrap[White]=" "
+0012[33]: @# Name. Character='V'.
+0012[36]: Text. Text scrap[White]=" "
+0012[37]: @# Name. Character='W'.
+0012[40]: Text. Text scrap[White]=" "
+0012[41]: @# Name. Character='X'.
+0012[44]: Text. Text scrap[White]=" "
+0012[45]: @# Name. Character='Y'.
+0012[48]: Text. Text scrap[White]=" "
+0012[49]: @# Name. Character='Z'.
+0012[52]: Text. Text scrap[White]=" "
+0012[53]: @# Name. Character='['.
+0012[56]: Text. Text scrap[White]=" "
+0012[57]: @# Name. Character='\'.
+0012[60]: Text. Text scrap[White]="<010>
+"
+0013[01]: @# Name. Character=']'.
+0013[04]: Text. Text scrap[White]=" "
+0013[05]: @# Name. Character='^'.
+0013[08]: Text. Text scrap[White]=" "
+0013[09]: @# Name. Character='_'.
+0013[12]: Text. Text scrap[White]=" "
+0013[13]: @# Name. Character='`'.
+0013[16]: Text. Text scrap[White]=" "
+0013[17]: @# Name. Character='a'.
+0013[20]: Text. Text scrap[White]=" "
+0013[21]: @# Name. Character='b'.
+0013[24]: Text. Text scrap[White]=" "
+0013[25]: @# Name. Character='c'.
+0013[28]: Text. Text scrap[White]=" "
+0013[29]: @# Name. Character='d'.
+0013[32]: Text. Text scrap[White]=" "
+0013[33]: @# Name. Character='e'.
+0013[36]: Text. Text scrap[White]=" "
+0013[37]: @# Name. Character='f'.
+0013[40]: Text. Text scrap[White]=" "
+0013[41]: @# Name. Character='g'.
+0013[44]: Text. Text scrap[White]=" "
+0013[45]: @# Name. Character='h'.
+0013[48]: Text. Text scrap[White]=" "
+0013[49]: @# Name. Character='i'.
+0013[52]: Text. Text scrap[White]=" "
+0013[53]: @# Name. Character='j'.
+0013[56]: Text. Text scrap[White]=" "
+0013[57]: @# Name. Character='k'.
+0013[60]: Text. Text scrap[White]="<010>
+"
+0014[01]: @# Name. Character='l'.
+0014[04]: Text. Text scrap[White]=" "
+0014[05]: @# Name. Character='m'.
+0014[08]: Text. Text scrap[White]=" "
+0014[09]: @# Name. Character='n'.
+0014[12]: Text. Text scrap[White]=" "
+0014[13]: @# Name. Character='o'.
+0014[16]: Text. Text scrap[White]=" "
+0014[17]: @# Name. Character='p'.
+0014[20]: Text. Text scrap[White]=" "
+0014[21]: @# Name. Character='q'.
+0014[24]: Text. Text scrap[White]=" "
+0014[25]: @# Name. Character='r'.
+0014[28]: Text. Text scrap[White]=" "
+0014[29]: @# Name. Character='s'.
+0014[32]: Text. Text scrap[White]=" "
+0014[33]: @# Name. Character='t'.
+0014[36]: Text. Text scrap[White]=" "
+0014[37]: @# Name. Character='u'.
+0014[40]: Text. Text scrap[White]=" "
+0014[41]: @# Name. Character='v'.
+0014[44]: Text. Text scrap[White]=" "
+0014[45]: @# Name. Character='w'.
+0014[48]: Text. Text scrap[White]=" "
+0014[49]: @# Name. Character='x'.
+0014[52]: Text. Text scrap[White]=" "
+0014[53]: @# Name. Character='y'.
+0014[56]: Text. Text scrap[White]=" "
+0014[57]: @# Name. Character='z'.
+0014[60]: Text. Text scrap[White]="<010>
+"
+0015[01]: @# Name. Character='{'.
+0015[04]: Text. Text scrap[White]=" "
+0015[05]: @# Name. Character='|'.
+0015[08]: Text. Text scrap[White]=" "
+0015[09]: @# Name. Character='}'.
+0015[12]: Text. Text scrap[White]=" "
+0015[13]: @# Name. Character='~'.
+0015[16]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test that <special>#<space> is flagged as an error.<010>
+<010>
+ "
+0019[07]: Text. Text scrap[White]=" "
+0020[01]: Text. Text scrap[Grey]="<010>
+3. Test that <special>#EOL is flagged as an error.<010>
+<010>
+ "
+0024[01]: Text. Text scrap[White]="<010>
+"
+0025[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC17: Test <special>#.
+ 2 2|
+ 3 3| First we trip up the scanner so no further passes take place.
+ 4 4|
+ 5 5| @
+ Error|.^<special><endofline> is not a legal special sequence.
+ 6 6|
+ 7 7| 1. Test with all possible printable characters.
+ 8 8|
+ 9 9| @#! @#" @## @#$ @#% @#& @#' @#( @#) @#* @#+ @#, @#- @#. @#/
+ 10 10| @#0 @#1 @#2 @#3 @#4 @#5 @#6 @#7 @#8 @#9 @#: @#; @#< @#= @#>
+ 11 11| @#? @#@ @#A @#B @#C @#D @#E @#F @#G @#H @#I @#J @#K @#L @#M
+ 12 12| @#N @#O @#P @#Q @#R @#S @#T @#U @#V @#W @#X @#Y @#Z @#[ @#\
+ 13 13| @#] @#^ @#_ @#` @#a @#b @#c @#d @#e @#f @#g @#h @#i @#j @#k
+ 14 14| @#l @#m @#n @#o @#p @#q @#r @#s @#t @#u @#v @#w @#x @#y @#z
+ 15 15| @#{ @#| @#} @#~
+ 16 16|
+ 17 17| 2. Test that <special>#<space> is flagged as an error.
+ 18 18|
+ 19 19| @# @! Should be flagged as an error.
+ Error|......^Expecting a printable character.
+ 20 20|
+ 21 21| 3. Test that <special>#EOL is flagged as an error.
+ 22 22|
+ 23 23| @#
+ Error|......^Expecting a printable character.
+ 24 24|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 3 Errors.
diff --git a/web/funnelAC/results/sc18.lis b/web/funnelAC/results/sc18.lis
new file mode 100644
index 0000000000..1442d3938d
--- /dev/null
+++ b/web/funnelAC/results/sc18.lis
@@ -0,0 +1,261 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 38 3A 20 54 65 73 74 20 3C 73 70 65 63 | SC18: Test <spec |
+| 69 61 6C 3E 23 3D 0A 0A 46 69 72 73 74 20 77 65 | ial>#=..First we |
+| 20 74 72 69 70 20 75 70 20 74 68 65 20 73 63 61 | trip up the sca |
+| 6E 6E 65 72 20 73 6F 20 6E 6F 20 66 75 72 74 68 | nner so no furth |
+| 65 72 20 70 61 73 73 65 73 20 74 61 6B 65 20 70 | er passes take p |
+| 6C 61 63 65 2E 0A 0A 40 0A 0A 31 2E 20 54 65 73 | lace...@..1. Tes |
+| 74 20 77 69 74 68 20 61 6C 6C 20 70 6F 73 73 69 | t with all possi |
+| 62 6C 65 20 70 72 69 6E 74 61 62 6C 65 20 63 68 | ble printable ch |
+| 61 72 61 63 74 65 72 73 2E 0A 0A 40 3D 21 20 21 | aracters...@=! ! |
+| 3D 22 20 22 3D 23 20 23 3D 24 20 24 3D 25 20 25 | =" "=# #=$ $=% % |
+| 3D 26 20 26 3D 27 20 27 3D 28 20 28 3D 29 20 29 | =& &=' '=( (=) ) |
+| 3D 2A 20 2A 3D 2B 20 2B 3D 2C 20 2C 3D 2D 20 2D | =* *=+ +=, ,=- - |
+| 3D 2E 20 2E 3D 2F 0A 2F 3D 30 20 30 3D 31 20 31 | =. .=/./=0 0=1 1 |
+| 3D 32 20 32 3D 33 20 33 3D 34 20 34 3D 35 20 35 | =2 2=3 3=4 4=5 5 |
+| 3D 36 20 36 3D 37 20 37 3D 38 20 38 3D 39 20 39 | =6 6=7 7=8 8=9 9 |
+| 3D 3A 20 3A 3D 3B 20 3B 3D 3C 20 3C 3D 3D 20 3D | =: :=; ;=< <== = |
+| 3D 3E 0A 3E 3D 3F 20 3F 3D 40 20 40 3D 41 20 41 | =>.>=? ?=@ @=A A |
+| 3D 42 20 42 3D 43 20 43 3D 44 20 44 3D 45 20 45 | =B B=C C=D D=E E |
+| 3D 46 20 46 3D 47 20 47 3D 48 20 48 3D 49 20 49 | =F F=G G=H H=I I |
+| 3D 4A 20 4A 3D 4B 20 4B 3D 4C 20 4C 3D 4D 0A 4D | =J J=K K=L L=M.M |
+| 3D 4E 20 4E 3D 4F 20 4F 3D 50 20 50 3D 51 20 51 | =N N=O O=P P=Q Q |
+| 3D 52 20 52 3D 53 20 53 3D 54 20 54 3D 55 20 55 | =R R=S S=T T=U U |
+| 3D 56 20 56 3D 57 20 57 3D 58 20 58 3D 59 20 59 | =V V=W W=X X=Y Y |
+| 3D 5A 20 5A 3D 5B 20 5B 3D 5C 0A 5C 3D 5D 20 5D | =Z Z=[ [=\.\=] ] |
+| 3D 5E 20 5E 3D 5F 20 5F 3D 60 20 60 3D 61 20 61 | =^ ^=_ _=` `=a a |
+| 3D 62 20 62 3D 63 20 63 3D 64 20 64 3D 65 20 65 | =b b=c c=d d=e e |
+| 3D 66 20 66 3D 67 20 67 3D 68 20 68 3D 69 20 69 | =f f=g g=h h=i i |
+| 3D 6A 20 6A 3D 6B 0A 6B 3D 6C 20 6C 3D 6D 20 6D | =j j=k.k=l l=m m |
+| 3D 6E 20 6E 3D 6F 20 6F 3D 70 20 70 3D 71 20 71 | =n n=o o=p p=q q |
+| 3D 72 20 72 3D 73 20 73 3D 74 20 74 3D 75 20 75 | =r r=s s=t t=u u |
+| 3D 76 20 76 3D 77 20 77 3D 78 20 78 3D 79 20 79 | =v v=w w=x x=y y |
+| 3D 7A 0A 7A 3D 7B 20 7B 3D 7C 20 7C 3D 7D 20 7D | =z.z={ {=| |=} } |
+| 3D 7E 20 7E 3D 40 0A 0A 32 2E 20 54 65 73 74 20 | =~ ~=@..2. Test |
+| 74 68 61 74 20 3C 73 70 65 63 69 61 6C 3E 3D 3C | that <special>=< |
+| 73 70 61 63 65 3E 20 69 73 20 66 6C 61 67 67 65 | space> is flagge |
+| 64 20 61 73 20 61 6E 20 65 72 72 6F 72 2E 0A 0A | d as an error... |
+| 20 20 20 40 3D 20 20 20 20 20 40 21 20 53 68 6F | @= @! Sho |
+| 75 6C 64 20 62 65 20 66 6C 61 67 67 65 64 20 61 | uld be flagged a |
+| 73 20 61 6E 20 65 72 72 6F 72 2E 0A 0A 33 2E 20 | s an error...3. |
+| 54 65 73 74 20 74 68 61 74 20 3C 73 70 65 63 69 | Test that <speci |
+| 61 6C 3E 3D 45 4F 4C 20 69 73 20 66 6C 61 67 67 | al>=EOL is flagg |
+| 65 64 20 61 73 20 61 6E 20 65 72 72 6F 72 2E 0A | ed as an error.. |
+| 0A 20 20 20 40 3D 0A 0A | . @=.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC18: Test <special>#=<010>
+00002 00002| <010>
+00003 00003| First we trip up the scanner so no further passes take place.<010>
+00004 00004| <010>
+00005 00005| @<010>
+00006 00006| <010>
+00007 00007| 1. Test with all possible printable characters.<010>
+00008 00008| <010>
+00009 00009| @=! !=" "=# #=$ $=% %=& &=' '=( (=) )=* *=+ +=, ,=- -=. .=/<010>
+00010 00010| /=0 0=1 1=2 2=3 3=4 4=5 5=6 6=7 7=8 8=9 9=: :=; ;=< <== ==><010>
+00011 00011| >=? ?=@ @=A A=B B=C C=D D=E E=F F=G G=H H=I I=J J=K K=L L=M<010>
+00012 00012| M=N N=O O=P P=Q Q=R R=S S=T T=U U=V V=W W=X X=Y Y=Z Z=[ [=\<010>
+00013 00013| \=] ]=^ ^=_ _=` `=a a=b b=c c=d d=e e=f f=g g=h h=i i=j j=k<010>
+00014 00014| k=l l=m m=n n=o o=p p=q q=r r=s s=t t=u u=v v=w w=x x=y y=z<010>
+00015 00015| z={ {=| |=} }=~ ~=@<010>
+00016 00016| <010>
+00017 00017| 2. Test that <special>=<space> is flagged as an error.<010>
+00018 00018| <010>
+00019 00019| @= @! Should be flagged as an error.<010>
+00020 00020| <010>
+00021 00021| 3. Test that <special>=EOL is flagged as an error.<010>
+00022 00022| <010>
+00023 00023| @=<010>
+00024 00024| <010>
+00025 00025| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 101 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC18: Test <special>#=<010>
+<010>
+First we trip up the scanner so no further passes take place.<010>
+<010>
+"
+0006[01]: Text. Text scrap[Grey]="<010>
+1. Test with all possible printable characters.<010>
+<010>
+"
+0009[04]: Text. Text scrap[White]=" "
+0009[08]: Text. Text scrap[White]=" "
+0009[12]: Text. Text scrap[White]=" "
+0009[16]: Text. Text scrap[White]=" "
+0009[20]: Text. Text scrap[White]=" "
+0009[24]: Text. Text scrap[White]=" "
+0009[28]: Text. Text scrap[White]=" "
+0009[32]: Text. Text scrap[White]=" "
+0009[36]: Text. Text scrap[White]=" "
+0009[40]: Text. Text scrap[White]=" "
+0009[44]: Text. Text scrap[White]=" "
+0009[48]: Text. Text scrap[White]=" "
+0009[52]: Text. Text scrap[White]=" "
+0009[56]: Text. Text scrap[White]=" "
+0009[60]: Text. Text scrap[White]="<010>
+"
+0010[04]: Text. Text scrap[White]=" "
+0010[08]: Text. Text scrap[White]=" "
+0010[12]: Text. Text scrap[White]=" "
+0010[16]: Text. Text scrap[White]=" "
+0010[20]: Text. Text scrap[White]=" "
+0010[24]: Text. Text scrap[White]=" "
+0010[28]: Text. Text scrap[White]=" "
+0010[32]: Text. Text scrap[White]=" "
+0010[36]: Text. Text scrap[White]=" "
+0010[40]: Text. Text scrap[White]=" "
+0010[44]: Text. Text scrap[White]=" "
+0010[48]: Text. Text scrap[White]=" "
+0010[52]: Text. Text scrap[White]=" "
+0010[56]: Text. Text scrap[White]=" "
+0010[60]: Text. Text scrap[White]="<010>
+"
+0011[04]: Text. Text scrap[White]=" "
+0011[08]: Text. Text scrap[White]=" "
+0011[12]: Text. Text scrap[White]=" "
+0011[16]: Text. Text scrap[White]=" "
+0011[20]: Text. Text scrap[White]=" "
+0011[24]: Text. Text scrap[White]=" "
+0011[28]: Text. Text scrap[White]=" "
+0011[32]: Text. Text scrap[White]=" "
+0011[36]: Text. Text scrap[White]=" "
+0011[40]: Text. Text scrap[White]=" "
+0011[44]: Text. Text scrap[White]=" "
+0011[48]: Text. Text scrap[White]=" "
+0011[52]: Text. Text scrap[White]=" "
+0011[56]: Text. Text scrap[White]=" "
+0011[60]: Text. Text scrap[White]="<010>
+"
+0012[04]: Text. Text scrap[White]=" "
+0012[08]: Text. Text scrap[White]=" "
+0012[12]: Text. Text scrap[White]=" "
+0012[16]: Text. Text scrap[White]=" "
+0012[20]: Text. Text scrap[White]=" "
+0012[24]: Text. Text scrap[White]=" "
+0012[28]: Text. Text scrap[White]=" "
+0012[32]: Text. Text scrap[White]=" "
+0012[36]: Text. Text scrap[White]=" "
+0012[40]: Text. Text scrap[White]=" "
+0012[44]: Text. Text scrap[White]=" "
+0012[48]: Text. Text scrap[White]=" "
+0012[52]: Text. Text scrap[White]=" "
+0012[56]: Text. Text scrap[White]=" "
+0012[60]: Text. Text scrap[White]="<010>
+"
+0013[04]: Text. Text scrap[White]=" "
+0013[08]: Text. Text scrap[White]=" "
+0013[12]: Text. Text scrap[White]=" "
+0013[16]: Text. Text scrap[White]=" "
+0013[20]: Text. Text scrap[White]=" "
+0013[24]: Text. Text scrap[White]=" "
+0013[28]: Text. Text scrap[White]=" "
+0013[32]: Text. Text scrap[White]=" "
+0013[36]: Text. Text scrap[White]=" "
+0013[40]: Text. Text scrap[White]=" "
+0013[44]: Text. Text scrap[White]=" "
+0013[48]: Text. Text scrap[White]=" "
+0013[52]: Text. Text scrap[White]=" "
+0013[56]: Text. Text scrap[White]=" "
+0013[60]: Text. Text scrap[White]="<010>
+"
+0014[04]: Text. Text scrap[White]=" "
+0014[08]: Text. Text scrap[White]=" "
+0014[12]: Text. Text scrap[White]=" "
+0014[16]: Text. Text scrap[White]=" "
+0014[20]: Text. Text scrap[White]=" "
+0014[24]: Text. Text scrap[White]=" "
+0014[28]: Text. Text scrap[White]=" "
+0014[32]: Text. Text scrap[White]=" "
+0014[36]: Text. Text scrap[White]=" "
+0014[40]: Text. Text scrap[White]=" "
+0014[44]: Text. Text scrap[White]=" "
+0014[48]: Text. Text scrap[White]=" "
+0014[52]: Text. Text scrap[White]=" "
+0014[56]: Text. Text scrap[White]=" "
+0014[60]: Text. Text scrap[White]="<010>
+"
+0015[04]: Text. Text scrap[White]=" "
+0015[08]: Text. Text scrap[White]=" "
+0015[12]: Text. Text scrap[White]=" "
+0015[16]: Text. Text scrap[White]=" "
+0015[20]: Text. Text scrap[Grey]="<010>
+<010>
+2. Test that <special>=<space> is flagged as an error.<010>
+<010>
+ "
+0019[07]: Text. Text scrap[White]=" "
+0020[01]: Text. Text scrap[Grey]="<010>
+3. Test that <special>=EOL is flagged as an error.<010>
+<010>
+ "
+0024[01]: Text. Text scrap[White]="<010>
+"
+0025[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC18: Test <special>#=
+ 2 2|
+ 3 3| First we trip up the scanner so no further passes take place.
+ 4 4|
+ 5 5| @
+ Error|.^<special><endofline> is not a legal special sequence.
+ 6 6|
+ 7 7| 1. Test with all possible printable characters.
+ 8 8|
+ 9 9| @=! !=" "=# #=$ $=% %=& &=' '=( (=) )=* *=+ +=, ,=- -=. .=/
+ 10 10| /=0 0=1 1=2 2=3 3=4 4=5 5=6 6=7 7=8 8=9 9=: :=; ;=< <== ==>
+ 11 11| >=? ?=@ @=A A=B B=C C=D D=E E=F F=G G=H H=I I=J J=K K=L L=M
+ 12 12| M=N N=O O=P P=Q Q=R R=S S=T T=U U=V V=W W=X X=Y Y=Z Z=[ [=\
+ 13 13| \=] ]=^ ^=_ _=` `=a a=b b=c c=d d=e e=f f=g g=h h=i i=j j=k
+ 14 14| k=l l=m m=n n=o o=p p=q q=r r=s s=t t=u u=v v=w w=x x=y y=z
+ 15 15| z={ {=| |=} }=~ ~=@
+ 16 16|
+ 17 17| 2. Test that <special>=<space> is flagged as an error.
+ 18 18|
+ 19 19| @= @! Should be flagged as an error.
+ Error|....^You cannot set the special character to <space>!
+ |....^Special sequence ignored.
+ 20 20|
+ 21 21| 3. Test that <special>=EOL is flagged as an error.
+ 22 22|
+ 23 23| @=
+ Error|....^You cannot set the special character to <endofline>!
+ |....^Special sequence ignored.
+ 24 24|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 3 Errors.
diff --git a/web/funnelAC/results/sc19.lis b/web/funnelAC/results/sc19.lis
new file mode 100644
index 0000000000..50da9c5e30
--- /dev/null
+++ b/web/funnelAC/results/sc19.lis
@@ -0,0 +1,96 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 31 39 3A 20 54 65 73 74 20 3C 73 70 65 63 | SC19: Test <spec |
+| 69 61 6C 3E 2D 0A 0A 31 2E 20 54 65 73 74 20 74 | ial>-..1. Test t |
+| 68 61 74 20 65 72 72 6F 72 20 69 73 20 66 6C 61 | hat error is fla |
+| 67 67 65 64 20 69 66 20 73 65 71 75 65 6E 63 65 | gged if sequence |
+| 20 69 73 20 6E 6F 74 20 61 74 20 74 68 65 20 65 | is not at the e |
+| 6E 64 20 6F 66 20 61 20 6C 69 6E 65 2E 0A 0A 54 | nd of a line...T |
+| 68 69 73 20 69 73 20 61 20 6C 69 6E 65 20 63 6F | his is a line co |
+| 6E 74 61 69 6E 69 6E 67 20 40 2D 20 74 68 65 20 | ntaining @- the |
+| 65 6E 64 20 6F 66 20 6C 69 6E 65 20 73 75 70 70 | end of line supp |
+| 72 65 73 73 6F 72 2E 0A 0A 32 2E 20 54 65 73 74 | ressor...2. Test |
+| 20 74 68 65 20 73 65 71 75 65 6E 63 65 20 66 6F | the sequence fo |
+| 6C 6C 6F 77 65 64 20 62 79 20 74 72 61 69 6C 69 | llowed by traili |
+| 6E 67 20 62 6C 61 6E 6B 73 2E 0A 0A 20 20 20 20 | ng blanks... |
+| 20 40 2D 20 20 20 0A 0A | @- .. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC19: Test <special>-<010>
+00002 00002| <010>
+00003 00003| 1. Test that error is flagged if sequence is not at the end of a line.<010>
+00004 00004| <010>
+00005 00005| This is a line containing @- the end of line suppressor.<010>
+00006 00006| <010>
+00007 00007| 2. Test the sequence followed by trailing blanks.<010>
+00008 00008| <010>
+00009 00009| @- <010>
+00010 00010| <010>
+00011 00011| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 4 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC19: Test <special>-<010>
+<010>
+1. Test that error is flagged if sequence is not at the end of a line.<010>
+<010>
+This is a line containing "
+0005[29]: Text. Text scrap[Grey]=" the end of line suppressor.<010>
+<010>
+2. Test the sequence followed by trailing blanks.<010>
+<010>
+ "
+0009[08]: Text. Text scrap[White]=" <010>
+<010>
+"
+0011[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC19: Test <special>-
+ 2 2|
+ 3 3| 1. Test that error is flagged if sequence is not at the end of a line.
+ 4 4|
+ 5 5| This is a line containing @- the end of line suppressor.
+ Error|...........................^Suppress EOL sequence is legal only at the end of a line
+ |...........................^unless `@p ignore_text_after_special_minus' is used.
+ 6 6|
+ 7 7| 2. Test the sequence followed by trailing blanks.
+ 8 8|
+ 9 9| @-
+ Error|......^Suppress EOL sequence is legal only at the end of a line
+ |......^unless `@p ignore_text_after_special_minus' is used.
+ Warning|..........^Line has trailing spaces up to and including this space.
+ 10 10|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 2 Errors and 1 Warning.
diff --git a/web/funnelAC/results/sc20.lis b/web/funnelAC/results/sc20.lis
new file mode 100644
index 0000000000..8b81e40626
--- /dev/null
+++ b/web/funnelAC/results/sc20.lis
@@ -0,0 +1,198 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 30 3A 20 54 65 73 74 20 40 21 0A 0A 31 | SC20: Test @!..1 |
+| 2E 20 54 65 73 74 20 61 74 20 74 68 65 20 73 74 | . Test at the st |
+| 61 72 74 20 6F 66 20 61 20 6C 69 6E 65 2E 0A 0A | art of a line... |
+| 40 21 20 54 68 69 73 20 69 73 20 61 20 63 6F 6D | @! This is a com |
+| 6D 65 6E 74 20 61 6E 64 20 77 65 20 63 61 6E 20 | ment and we can |
+| 73 74 69 63 6B 20 61 6E 79 20 73 6F 72 74 20 6F | stick any sort o |
+| 66 20 72 75 62 62 69 73 68 20 69 6E 20 69 74 2E | f rubbish in it. |
+| 0A 40 21 20 40 23 20 40 69 20 40 5E 64 73 3B 61 | .@! @# @i @^ds;a |
+| 66 3B 6C 73 64 6D 66 3B 6C 61 6E 64 20 6F 74 68 | f;lsdmf;land oth |
+| 65 72 20 40 20 72 75 62 62 69 73 68 2E 0A 0A 32 | er @ rubbish...2 |
+| 2E 20 54 65 73 74 20 68 61 6C 66 77 61 79 20 74 | . Test halfway t |
+| 68 72 6F 75 67 68 20 61 20 6C 69 6E 65 2E 0A 0A | hrough a line... |
+| 54 68 69 73 20 69 73 20 61 20 6C 69 6E 65 20 40 | This is a line @ |
+| 21 20 77 68 6F 73 65 20 73 65 63 6F 6E 64 20 68 | ! whose second h |
+| 61 6C 66 20 6E 65 76 65 72 20 73 65 65 73 20 74 | alf never sees t |
+| 68 65 20 64 61 79 6C 69 67 68 74 2E 20 40 69 20 | he daylight. @i |
+| 40 3C 0A 0A | @<.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC20: Test @!<010>
+00002 00002| <010>
+00003 00003| 1. Test at the start of a line.<010>
+00004 00004| <010>
+00005 00005| @! This is a comment and we can stick any sort of rubbish in it.<010>
+00006 00006| @! @# @i @^ds;af;lsdmf;land other @ rubbish.<010>
+00007 00007| <010>
+00008 00008| 2. Test halfway through a line.<010>
+00009 00009| <010>
+00010 00010| This is a line @! whose second half never sees the daylight. @i @<<010>
+00011 00011| <010>
+00012 00012| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 5 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC20: Test "
+0002[01]: Text. Text scrap[Grey]="<010>
+1. Test at the start of a line.<010>
+<010>
+"
+0007[01]: Text. Text scrap[Grey]="<010>
+2. Test halfway through a line.<010>
+<010>
+This is a line "
+0011[01]: Text. Text scrap[White]="<010>
+"
+0012[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+
+========================== Start of MACRO TABLE DUMP ===========================
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#file"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#line"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+------------------- Start of Macro Dump --------------------
+Macro Name : "#timestamp"
+Defined? : Yes.
+Parameters : 0
+Additive? : No.
+Zero Calls? : Yes.
+Many Calls? : Yes.
+Output File?: No.
+Automatic Line Directive Macro?: No.
+Call list :
+Macro body :
+
+--Start of List of Body Parts--
+This macro has 1 body part.
+Body part 1: Seqnum=0, Pos(L,C)=(5369005744,5368823512), Expression follows:
+
+---- Start of Expression ----
+
+--- Start Special Function ---
+---- End Special Function ----
+
+----- End of Expression -----
+
+---End of List of Body Parts---
+
+-------------------- End of Macro Dump ---------------------
+
+
+
+=========================== End of MACRO TABLE DUMP ============================
+
+
+========================= Start of DOCUMENT LIST DUMP ==========================
+
+
+TEXT COMPONENT: Pos(L,C)=(1,1).
+
+-- Start of Text Scrap List --
+Text scrap[Grey]="SC20: Test "
+Text scrap[Grey]="<010>
+1. Test at the start of a line.<010>
+<010>
+"
+Text scrap[Grey]="<010>
+2. Test halfway through a line.<010>
+<010>
+This is a line "
+Text scrap[White]="<010>
+"
+--- End of Text Scrap List ---
+
+
+========================== End of DOCUMENT LIST DUMP ===========================
+
+E: No output files specified.
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+There was 1 Error.
diff --git a/web/funnelAC/results/sc21.lis b/web/funnelAC/results/sc21.lis
new file mode 100644
index 0000000000..84cae9a495
--- /dev/null
+++ b/web/funnelAC/results/sc21.lis
@@ -0,0 +1,411 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 31 3A 20 54 65 73 74 20 67 65 6E 65 72 | SC21: Test gener |
+| 69 63 20 73 79 6E 74 61 78 20 63 68 65 63 6B 69 | ic syntax checki |
+| 6E 67 20 6F 66 20 70 72 61 67 6D 61 73 20 61 6E | ng of pragmas an |
+| 64 20 74 79 70 65 73 65 74 74 65 72 20 64 69 72 | d typesetter dir |
+| 65 63 74 69 76 65 73 2E 0A 0A 31 2E 20 54 65 73 | ectives...1. Tes |
+| 74 20 70 72 61 67 6D 61 20 6E 6F 74 20 61 74 20 | t pragma not at |
+| 74 68 65 20 73 74 61 72 74 20 6F 66 20 6C 69 6E | the start of lin |
+| 65 2E 0A 20 20 20 40 70 0A 20 20 20 40 74 0A 0A | e.. @p. @t.. |
+| 32 2E 20 54 65 73 74 20 63 68 61 72 61 63 74 65 | 2. Test characte |
+| 72 20 66 6F 6C 6C 6F 77 69 6E 67 20 3C 73 70 65 | r following <spe |
+| 63 69 61 6C 3E 70 20 69 73 20 6E 6F 74 20 61 20 | cial>p is not a |
+| 62 6C 61 6E 6B 2E 0A 40 70 78 0A 40 74 78 0A 40 | blank..@px.@tx.@ |
+| 70 0A 40 74 0A 0A 33 2E 20 54 65 73 74 20 70 72 | p.@t..3. Test pr |
+| 61 67 6D 61 20 6C 69 6E 65 20 69 73 20 74 6F 6F | agma line is too |
+| 20 6C 6F 6E 67 20 28 6C 69 6D 69 74 20 69 73 20 | long (limit is |
+| 31 30 30 29 0A 20 20 20 20 20 20 20 20 20 31 20 | 100). 1 |
+| 20 20 20 20 20 20 20 20 32 20 20 20 20 20 20 20 | 2 |
+| 20 20 33 20 20 20 20 20 20 20 20 20 34 20 20 20 | 3 4 |
+| 20 20 20 20 20 20 35 20 20 20 20 20 20 20 20 20 | 5 |
+| 36 20 20 20 20 20 20 20 20 20 37 20 20 20 20 20 | 6 7 |
+| 20 20 20 20 38 20 20 20 20 20 20 20 20 20 39 20 | 8 9 |
+| 20 20 20 20 20 20 20 20 31 0A 40 70 20 34 35 36 | 1.@p 456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 0A 40 | 78901234567890.@ |
+| 70 20 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | p 45678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 0A 40 74 20 34 35 36 37 38 39 30 31 | 8901.@t 45678901 |
+| 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 | 2345678901234567 |
+| 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 | 8901234567890123 |
+| 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 | 4567890123456789 |
+| 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 | 0123456789012345 |
+| 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 | 6789012345678901 |
+| 32 33 34 35 36 37 38 39 30 0A 40 74 20 34 35 36 | 234567890.@t 456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
+| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
+| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
+| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
+| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
+| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 0A | 789012345678901. |
+| 0A 34 2E 20 54 65 73 74 20 76 61 72 69 6F 75 73 | .4. Test various |
+| 20 64 69 66 66 65 72 65 6E 74 20 70 72 61 67 6D | different pragm |
+| 61 20 6C 69 6E 65 73 2E 0A 40 70 20 24 23 25 40 | a lines..@p $#%@ |
+| 20 32 35 32 35 20 20 73 6C 6F 74 68 0A 40 74 20 | 2525 sloth.@t |
+| 24 23 25 40 20 32 35 32 35 20 20 73 6C 6F 74 68 | $#%@ 2525 sloth |
+| 0A 0A 35 2E 20 54 65 73 74 20 70 72 61 67 6D 61 | ..5. Test pragma |
+| 20 77 69 74 68 20 6E 6F 20 61 72 67 75 6D 65 6E | with no argumen |
+| 74 73 2E 20 28 57 69 6C 6C 20 67 65 74 20 61 20 | ts. (Will get a |
+| 74 72 61 69 6C 69 6E 67 20 62 6C 61 6E 6B 73 20 | trailing blanks |
+| 65 72 72 6F 72 2E 29 2E 0A 40 70 20 20 20 20 0A | error.)..@p . |
+| 40 74 20 20 20 20 0A 0A 36 2E 20 54 65 73 74 20 | @t ..6. Test |
+| 70 72 61 67 6D 61 20 77 69 74 68 20 74 6F 6F 20 | pragma with too |
+| 6D 61 6E 79 20 61 72 67 75 6D 65 6E 74 73 2E 0A | many arguments.. |
+| 40 70 20 61 20 62 20 63 20 64 20 65 20 66 20 67 | @p a b c d e f g |
+| 20 68 20 69 20 6A 20 6B 20 6C 20 6D 20 6E 20 6F | h i j k l m n o |
+| 20 70 20 71 20 72 20 73 20 74 20 75 20 76 20 77 | p q r s t u v w |
+| 20 78 20 79 20 7A 0A 40 74 20 61 20 62 20 63 20 | x y z.@t a b c |
+| 64 20 65 20 66 20 67 20 68 20 69 20 6A 20 6B 20 | d e f g h i j k |
+| 6C 20 6D 20 6E 20 6F 20 70 20 71 20 72 20 73 20 | l m n o p q r s |
+| 74 20 75 20 76 20 77 20 78 20 79 20 7A 0A 0A | t u v w x y z.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC21: Test generic syntax checking of pragmas and typesetter directives.<010>
+00002 00002| <010>
+00003 00003| 1. Test pragma not at the start of line.<010>
+00004 00004| @p<010>
+00005 00005| @t<010>
+00006 00006| <010>
+00007 00007| 2. Test character following <special>p is not a blank.<010>
+00008 00008| @px<010>
+00009 00009| @tx<010>
+00010 00010| @p<010>
+00011 00011| @t<010>
+00012 00012| <010>
+00013 00013| 3. Test pragma line is too long (limit is 100)<010>
+00014 00014| 1 2 3 4 5 6 7 8 9 1<010>
+00015 00015| @p 4567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890<010>
+00016 00016| @p 45678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901<010>
+00017 00017| @t 4567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890<010>
+00018 00018| @t 45678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901<010>
+00019 00019| <010>
+00020 00020| 4. Test various different pragma lines.<010>
+00021 00021| @p $#%@ 2525 sloth<010>
+00022 00022| @t $#%@ 2525 sloth<010>
+00023 00023| <010>
+00024 00024| 5. Test pragma with no arguments. (Will get a trailing blanks error.).<010>
+00025 00025| @p <010>
+00026 00026| @t <010>
+00027 00027| <010>
+00028 00028| 6. Test pragma with too many arguments.<010>
+00029 00029| @p a b c d e f g h i j k l m n o p q r s t u v w x y z<010>
+00030 00030| @t a b c d e f g h i j k l m n o p q r s t u v w x y z<010>
+00031 00031| <010>
+00032 00032| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 9 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC21: Test generic syntax checking of pragmas and typesetter directives.<010>
+<010>
+1. Test pragma not at the start of line.<010>
+ "
+0005[01]: Text. Text scrap[White]=" "
+0006[01]: Text. Text scrap[Grey]="<010>
+2. Test character following <special>p is not a blank.<010>
+"
+0012[01]: Text. Text scrap[Grey]="<010>
+3. Test pragma line is too long (limit is 100)<010>
+ 1 2 3 4 5 6 7 8 9 1<010>
+"
+0019[01]: Text. Text scrap[Grey]="<010>
+4. Test various different pragma lines.<010>
+"
+0023[01]: Text. Text scrap[Grey]="<010>
+5. Test pragma with no arguments. (Will get a trailing blanks error.).<010>
+"
+0027[01]: Text. Text scrap[Grey]="<010>
+6. Test pragma with too many arguments.<010>
+"
+0031[01]: Text. Text scrap[White]="<010>
+"
+0032[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC21: Test generic syntax checking of pragmas and typesetter directives.
+ 2 2|
+ 3 3| 1. Test pragma not at the start of line.
+ 4 4| @p
+ Error|....^Pragma sequence @p must be at the start of a line.
+ |....^The rest of this line will be ignored.
+ Error|....^Unrecognised pragma. Possible legal pragmas are:
+ |....^ @p indentation = none | blank
+ |....^ @p maximum_input_line_length = <num>|infinity
+ |....^ @p maximum_output_line_length = <num>|infinity
+ |....^ @p typesetter = none | tex | hypertext | html
+ |....^ @p no_doc_header
+ |....^ @p raw_macro_and_section_names
+ |....^ @p ignore_text_after_special_minus
+ |....^ @p no_paragraph_markups
+ |....^ @p declare_source_code_type "<name>"
+ |....^ @p automatic_line_directive_macro = "<name>"
+ |....^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+ |....^ @p #line_offset = <num>
+ |....^ @p #line_depth = <num>
+ |....^The blanks between arguments are important.
+ |....^Pragma ignored.
+ 5 5| @t
+ Error|....^Typesetter directive @t must be at the start of a line.
+ |....^The rest of this line will be ignored.
+ Error|....^Unrecognised typesetter directive. Legal ones are:
+ |....^ @t new_page
+ |....^ @t table_of_contents
+ |....^ @t title <font> <align> <string>
+ |....^ @t vskip <num> mm
+ |....^The blanks between arguments are important.
+ |....^Typesetter directive ignored.
+ 6 6|
+ 7 7| 2. Test character following <special>p is not a blank.
+ 8 8| @px
+ Error|.^Pragma sequence @p must be followed by a blank.
+ Error|.^Unrecognised pragma. Possible legal pragmas are:
+ |.^ @p indentation = none | blank
+ |.^ @p maximum_input_line_length = <num>|infinity
+ |.^ @p maximum_output_line_length = <num>|infinity
+ |.^ @p typesetter = none | tex | hypertext | html
+ |.^ @p no_doc_header
+ |.^ @p raw_macro_and_section_names
+ |.^ @p ignore_text_after_special_minus
+ |.^ @p no_paragraph_markups
+ |.^ @p declare_source_code_type "<name>"
+ |.^ @p automatic_line_directive_macro = "<name>"
+ |.^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+ |.^ @p #line_offset = <num>
+ |.^ @p #line_depth = <num>
+ |.^The blanks between arguments are important.
+ |.^Pragma ignored.
+ 9 9| @tx
+ Error|.^Typesetter directive @t must be followed by a blank.
+ Error|.^Unrecognised typesetter directive. Legal ones are:
+ |.^ @t new_page
+ |.^ @t table_of_contents
+ |.^ @t title <font> <align> <string>
+ |.^ @t vskip <num> mm
+ |.^The blanks between arguments are important.
+ |.^Typesetter directive ignored.
+ 10 10| @p
+ Error|.^Pragma sequence @p must be followed by a blank.
+ Error|.^Unrecognised pragma. Possible legal pragmas are:
+ |.^ @p indentation = none | blank
+ |.^ @p maximum_input_line_length = <num>|infinity
+ |.^ @p maximum_output_line_length = <num>|infinity
+ |.^ @p typesetter = none | tex | hypertext | html
+ |.^ @p no_doc_header
+ |.^ @p raw_macro_and_section_names
+ |.^ @p ignore_text_after_special_minus
+ |.^ @p no_paragraph_markups
+ |.^ @p declare_source_code_type "<name>"
+ |.^ @p automatic_line_directive_macro = "<name>"
+ |.^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+ |.^ @p #line_offset = <num>
+ |.^ @p #line_depth = <num>
+ |.^The blanks between arguments are important.
+ |.^Pragma ignored.
+ 11 11| @t
+ Error|.^Typesetter directive @t must be followed by a blank.
+ Error|.^Unrecognised typesetter directive. Legal ones are:
+ |.^ @t new_page
+ |.^ @t table_of_contents
+ |.^ @t title <font> <align> <string>
+ |.^ @t vskip <num> mm
+ |.^The blanks between arguments are important.
+ |.^Typesetter directive ignored.
+ 12 12|
+ 13 13| 3. Test pragma line is too long (limit is 100)
+ 14 14| 1 2 3 4 5 6 7 8 9 1
+ Error|.................................................................................^Input line is too long (this character is the first offender).
+ |.................................................................................^Currently, the maximum allowable input line length is 80.
+ |.................................................................................^Note: You can change this using a pragma directive (@p).
+ 15 15| @p 4567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
+ Error|.^Unrecognised pragma. Possible legal pragmas are:
+ |.^ @p indentation = none | blank
+ |.^ @p maximum_input_line_length = <num>|infinity
+ |.^ @p maximum_output_line_length = <num>|infinity
+ |.^ @p typesetter = none | tex | hypertext | html
+ |.^ @p no_doc_header
+ |.^ @p raw_macro_and_section_names
+ |.^ @p ignore_text_after_special_minus
+ |.^ @p no_paragraph_markups
+ |.^ @p declare_source_code_type "<name>"
+ |.^ @p automatic_line_directive_macro = "<name>"
+ |.^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+ |.^ @p #line_offset = <num>
+ |.^ @p #line_depth = <num>
+ |.^The blanks between arguments are important.
+ |.^Pragma ignored.
+ Error|.................................................................................^Input line is too long (this character is the first offender).
+ |.................................................................................^Currently, the maximum allowable input line length is 80.
+ |.................................................................................^Note: You can change this using a pragma directive (@p).
+ 16 16| @p 45678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901
+ Error|.^This pragma line is too long.
+ |.^The maximum pragma line length is 100 characters.
+ Error|.^Unrecognised pragma. Possible legal pragmas are:
+ |.^ @p indentation = none | blank
+ |.^ @p maximum_input_line_length = <num>|infinity
+ |.^ @p maximum_output_line_length = <num>|infinity
+ |.^ @p typesetter = none | tex | hypertext | html
+ |.^ @p no_doc_header
+ |.^ @p raw_macro_and_section_names
+ |.^ @p ignore_text_after_special_minus
+ |.^ @p no_paragraph_markups
+ |.^ @p declare_source_code_type "<name>"
+ |.^ @p automatic_line_directive_macro = "<name>"
+ |.^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+ |.^ @p #line_offset = <num>
+ |.^ @p #line_depth = <num>
+ |.^The blanks between arguments are important.
+ |.^Pragma ignored.
+ Error|.................................................................................^Input line is too long (this character is the first offender).
+ |.................................................................................^Currently, the maximum allowable input line length is 80.
+ |.................................................................................^Note: You can change this using a pragma directive (@p).
+ 17 17| @t 4567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
+ Error|.^Unrecognised typesetter directive. Legal ones are:
+ |.^ @t new_page
+ |.^ @t table_of_contents
+ |.^ @t title <font> <align> <string>
+ |.^ @t vskip <num> mm
+ |.^The blanks between arguments are important.
+ |.^Typesetter directive ignored.
+ Error|.................................................................................^Input line is too long (this character is the first offender).
+ |.................................................................................^Currently, the maximum allowable input line length is 80.
+ |.................................................................................^Note: You can change this using a pragma directive (@p).
+ 18 18| @t 45678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901
+ Error|.^This typestter directive line is too long.
+ |.^The maximum typesetter directive line length is 100 characters.
+ Error|.^Unrecognised typesetter directive. Legal ones are:
+ |.^ @t new_page
+ |.^ @t table_of_contents
+ |.^ @t title <font> <align> <string>
+ |.^ @t vskip <num> mm
+ |.^The blanks between arguments are important.
+ |.^Typesetter directive ignored.
+ Error|.................................................................................^Input line is too long (this character is the first offender).
+ |.................................................................................^Currently, the maximum allowable input line length is 80.
+ |.................................................................................^Note: You can change this using a pragma directive (@p).
+ 19 19|
+ 20 20| 4. Test various different pragma lines.
+ 21 21| @p $#%@ 2525 sloth
+ Error|.^Unrecognised pragma. Possible legal pragmas are:
+ |.^ @p indentation = none | blank
+ |.^ @p maximum_input_line_length = <num>|infinity
+ |.^ @p maximum_output_line_length = <num>|infinity
+ |.^ @p typesetter = none | tex | hypertext | html
+ |.^ @p no_doc_header
+ |.^ @p raw_macro_and_section_names
+ |.^ @p ignore_text_after_special_minus
+ |.^ @p no_paragraph_markups
+ |.^ @p declare_source_code_type "<name>"
+ |.^ @p automatic_line_directive_macro = "<name>"
+ |.^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+ |.^ @p #line_offset = <num>
+ |.^ @p #line_depth = <num>
+ |.^The blanks between arguments are important.
+ |.^Pragma ignored.
+ 22 22| @t $#%@ 2525 sloth
+ Error|.^Unrecognised typesetter directive. Legal ones are:
+ |.^ @t new_page
+ |.^ @t table_of_contents
+ |.^ @t title <font> <align> <string>
+ |.^ @t vskip <num> mm
+ |.^The blanks between arguments are important.
+ |.^Typesetter directive ignored.
+ 23 23|
+ 24 24| 5. Test pragma with no arguments. (Will get a trailing blanks error.).
+ 25 25| @p
+ Error|.^Pragma sequence @p must be followed by a keyword.
+ Error|.^Unrecognised pragma. Possible legal pragmas are:
+ |.^ @p indentation = none | blank
+ |.^ @p maximum_input_line_length = <num>|infinity
+ |.^ @p maximum_output_line_length = <num>|infinity
+ |.^ @p typesetter = none | tex | hypertext | html
+ |.^ @p no_doc_header
+ |.^ @p raw_macro_and_section_names
+ |.^ @p ignore_text_after_special_minus
+ |.^ @p no_paragraph_markups
+ |.^ @p declare_source_code_type "<name>"
+ |.^ @p automatic_line_directive_macro = "<name>"
+ |.^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+ |.^ @p #line_offset = <num>
+ |.^ @p #line_depth = <num>
+ |.^The blanks between arguments are important.
+ |.^Pragma ignored.
+ Warning|......^Line has trailing spaces up to and including this space.
+ 26 26| @t
+ Error|.^Typesetter directive @t must be followed by a keyword.
+ Error|.^Unrecognised typesetter directive. Legal ones are:
+ |.^ @t new_page
+ |.^ @t table_of_contents
+ |.^ @t title <font> <align> <string>
+ |.^ @t vskip <num> mm
+ |.^The blanks between arguments are important.
+ |.^Typesetter directive ignored.
+ Warning|......^Line has trailing spaces up to and including this space.
+ 27 27|
+ 28 28| 6. Test pragma with too many arguments.
+ 29 29| @p a b c d e f g h i j k l m n o p q r s t u v w x y z
+ Error|.^Unrecognised pragma. Possible legal pragmas are:
+ |.^ @p indentation = none | blank
+ |.^ @p maximum_input_line_length = <num>|infinity
+ |.^ @p maximum_output_line_length = <num>|infinity
+ |.^ @p typesetter = none | tex | hypertext | html
+ |.^ @p no_doc_header
+ |.^ @p raw_macro_and_section_names
+ |.^ @p ignore_text_after_special_minus
+ |.^ @p no_paragraph_markups
+ |.^ @p declare_source_code_type "<name>"
+ |.^ @p automatic_line_directive_macro = "<name>"
+ |.^ @p automatic_line_directive_macro = "<name>" "<srctype>"
+ |.^ @p #line_offset = <num>
+ |.^ @p #line_depth = <num>
+ |.^The blanks between arguments are important.
+ |.^Pragma ignored.
+ 30 30| @t a b c d e f g h i j k l m n o p q r s t u v w x y z
+ Error|.^Unrecognised typesetter directive. Legal ones are:
+ |.^ @t new_page
+ |.^ @t table_of_contents
+ |.^ @t title <font> <align> <string>
+ |.^ @t vskip <num> mm
+ |.^The blanks between arguments are important.
+ |.^Typesetter directive ignored.
+ 31 31|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 31 Errors and 2 Warnings.
diff --git a/web/funnelAC/results/sc22.lis b/web/funnelAC/results/sc22.lis
new file mode 100644
index 0000000000..5fd10d7311
--- /dev/null
+++ b/web/funnelAC/results/sc22.lis
@@ -0,0 +1,165 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 32 3A 20 54 65 73 74 20 73 79 6E 74 61 | SC22: Test synta |
+| 78 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 69 6E | x checking of in |
+| 70 75 74 20 6C 69 6E 65 20 6C 65 6E 67 74 68 20 | put line length |
+| 70 72 61 67 6D 61 2E 0A 0A 31 2E 20 54 65 73 74 | pragma...1. Test |
+| 20 6E 6F 74 20 74 68 72 65 65 20 61 72 67 75 6D | not three argum |
+| 65 6E 74 73 2E 0A 40 70 20 6D 61 78 69 6D 75 6D | ents..@p maximum |
+| 5F 69 6E 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 | _input_line_leng |
+| 74 68 0A 40 70 20 6D 61 78 69 6D 75 6D 5F 69 6E | th.@p maximum_in |
+| 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 74 68 20 | put_line_length |
+| 3D 0A 40 70 20 6D 61 78 69 6D 75 6D 5F 69 6E 70 | =.@p maximum_inp |
+| 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 74 68 20 3D | ut_line_length = |
+| 20 78 78 78 20 79 79 79 0A 0A 32 2E 20 54 65 73 | xxx yyy..2. Tes |
+| 74 20 73 65 63 6F 6E 64 20 61 72 67 75 6D 65 6E | t second argumen |
+| 74 20 6E 6F 74 20 22 3D 22 2E 0A 40 70 20 6D 61 | t not "="..@p ma |
+| 78 69 6D 75 6D 5F 69 6E 70 75 74 5F 6C 69 6E 65 | ximum_input_line |
+| 5F 6C 65 6E 67 74 68 20 78 20 73 6C 6F 74 68 0A | _length x sloth. |
+| 0A 33 2E 20 54 65 73 74 20 76 61 6C 75 65 20 6F | .3. Test value o |
+| 66 20 69 6E 66 69 6E 69 74 79 2E 0A 40 70 20 6D | f infinity..@p m |
+| 61 78 69 6D 75 6D 5F 69 6E 70 75 74 5F 6C 69 6E | aximum_input_lin |
+| 65 5F 6C 65 6E 67 74 68 20 3D 20 69 6E 66 69 6E | e_length = infin |
+| 69 74 79 0A 0A 34 2E 20 54 65 73 74 20 6E 6F 6E | ity..4. Test non |
+| 2D 64 65 63 69 6D 61 6C 20 64 69 67 69 74 20 69 | -decimal digit i |
+| 6E 20 6E 75 6D 62 65 72 2E 0A 40 70 20 6D 61 78 | n number..@p max |
+| 69 6D 75 6D 5F 69 6E 70 75 74 5F 6C 69 6E 65 5F | imum_input_line_ |
+| 6C 65 6E 67 74 68 20 3D 20 32 65 66 0A 0A 35 2E | length = 2ef..5. |
+| 20 54 65 73 74 20 6E 75 6D 62 65 72 20 69 73 20 | Test number is |
+| 6D 6F 72 65 20 74 68 61 6E 20 65 69 67 68 74 20 | more than eight |
+| 64 69 67 69 74 73 20 6C 6F 6E 67 2E 0A 40 70 20 | digits long..@p |
+| 6D 61 78 69 6D 75 6D 5F 69 6E 70 75 74 5F 6C 69 | maximum_input_li |
+| 6E 65 5F 6C 65 6E 67 74 68 20 3D 20 31 32 33 34 | ne_length = 1234 |
+| 35 36 37 38 39 0A 0A 36 2E 20 54 65 73 74 20 6E | 56789..6. Test n |
+| 75 6D 62 65 72 20 69 73 20 65 78 61 63 74 6C 79 | umber is exactly |
+| 20 65 69 67 68 74 20 64 69 67 69 74 73 20 6C 6F | eight digits lo |
+| 6E 67 2E 0A 40 70 20 6D 61 78 69 6D 75 6D 5F 69 | ng..@p maximum_i |
+| 6E 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 74 68 | nput_line_length |
+| 20 3D 20 31 32 33 34 35 36 37 38 0A 0A 0A | = 12345678... |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC22: Test syntax checking of input line length pragma.<010>
+00002 00002| <010>
+00003 00003| 1. Test not three arguments.<010>
+00004 00004| @p maximum_input_line_length<010>
+00005 00005| @p maximum_input_line_length =<010>
+00006 00006| @p maximum_input_line_length = xxx yyy<010>
+00007 00007| <010>
+00008 00008| 2. Test second argument not "=".<010>
+00009 00009| @p maximum_input_line_length x sloth<010>
+00010 00010| <010>
+00011 00011| 3. Test value of infinity.<010>
+00012 00012| @p maximum_input_line_length = infinity<010>
+00013 00013| <010>
+00014 00014| 4. Test non-decimal digit in number.<010>
+00015 00015| @p maximum_input_line_length = 2ef<010>
+00016 00016| <010>
+00017 00017| 5. Test number is more than eight digits long.<010>
+00018 00018| @p maximum_input_line_length = 123456789<010>
+00019 00019| <010>
+00020 00020| 6. Test number is exactly eight digits long.<010>
+00021 00021| @p maximum_input_line_length = 12345678<010>
+00022 00022| <010>
+00023 00023| <010>
+00024 00024| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 8 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC22: Test syntax checking of input line length pragma.<010>
+<010>
+1. Test not three arguments.<010>
+"
+0007[01]: Text. Text scrap[Grey]="<010>
+2. Test second argument not "=".<010>
+"
+0010[01]: Text. Text scrap[Grey]="<010>
+3. Test value of infinity.<010>
+"
+0013[01]: Text. Text scrap[Grey]="<010>
+4. Test non-decimal digit in number.<010>
+"
+0016[01]: Text. Text scrap[Grey]="<010>
+5. Test number is more than eight digits long.<010>
+"
+0019[01]: Text. Text scrap[Grey]="<010>
+6. Test number is exactly eight digits long.<010>
+"
+0022[01]: Text. Text scrap[White]="<010>
+<010>
+"
+0024[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC22: Test syntax checking of input line length pragma.
+ 2 2|
+ 3 3| 1. Test not three arguments.
+ 4 4| @p maximum_input_line_length
+ Error|.^This pragma has the wrong number of arguments.
+ |.^The correct format is: "@p maximum_input_line_length = <num>|infinity".
+ |.^Pragma ignored.
+ 5 5| @p maximum_input_line_length =
+ Error|.^This pragma has the wrong number of arguments.
+ |.^The correct format is: "@p maximum_input_line_length = <num>|infinity".
+ |.^Pragma ignored.
+ 6 6| @p maximum_input_line_length = xxx yyy
+ Error|.^This pragma has the wrong number of arguments.
+ |.^The correct format is: "@p maximum_input_line_length = <num>|infinity".
+ |.^Pragma ignored.
+ 7 7|
+ 8 8| 2. Test second argument not "=".
+ 9 9| @p maximum_input_line_length x sloth
+ |.^The correct format is: "@p maximum_input_line_length = <num>|infinity".
+ |.^Pragma ignored.
+ Error|..............................^Expecting "=".
+ 10 10|
+ 11 11| 3. Test value of infinity.
+ 12 12| @p maximum_input_line_length = infinity
+ 13 13|
+ 14 14| 4. Test non-decimal digit in number.
+ 15 15| @p maximum_input_line_length = 2ef
+ Error|.................................^Illegal digit. Value must consist entirely of decimal digits.
+ |.................................^You can also use the value "infinity".
+ |.................................^Pragma ignored.
+ 16 16|
+ 17 17| 5. Test number is more than eight digits long.
+ 18 18| @p maximum_input_line_length = 123456789
+ Error|................................^Too many digits. The maximum is eight.
+ |................................^Pragma ignored.
+ 19 19|
+ 20 20| 6. Test number is exactly eight digits long.
+ 21 21| @p maximum_input_line_length = 12345678
+ 22 22|
+ 23 23|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 6 Errors.
diff --git a/web/funnelAC/results/sc23.lis b/web/funnelAC/results/sc23.lis
new file mode 100644
index 0000000000..df72bd6601
--- /dev/null
+++ b/web/funnelAC/results/sc23.lis
@@ -0,0 +1,188 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 33 3A 20 54 65 73 74 20 73 79 6E 74 61 | SC23: Test synta |
+| 78 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 6F 75 | x checking of ou |
+| 74 70 75 74 20 6C 69 6E 65 20 6C 65 6E 67 74 68 | tput line length |
+| 20 70 72 61 67 6D 61 2E 0A 0A 31 2E 20 54 65 73 | pragma...1. Tes |
+| 74 20 6E 6F 74 20 74 68 72 65 65 20 61 72 67 75 | t not three argu |
+| 6D 65 6E 74 73 2E 0A 40 70 20 6D 61 78 69 6D 75 | ments..@p maximu |
+| 6D 5F 6F 75 74 70 75 74 5F 6C 69 6E 65 5F 6C 65 | m_output_line_le |
+| 6E 67 74 68 0A 40 70 20 6D 61 78 69 6D 75 6D 5F | ngth.@p maximum_ |
+| 6F 75 74 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 | output_line_leng |
+| 74 68 20 3D 0A 40 70 20 6D 61 78 69 6D 75 6D 5F | th =.@p maximum_ |
+| 6F 75 74 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 | output_line_leng |
+| 74 68 20 3D 20 78 78 78 20 79 79 79 0A 0A 32 2E | th = xxx yyy..2. |
+| 20 54 65 73 74 20 73 65 63 6F 6E 64 20 61 72 67 | Test second arg |
+| 75 6D 65 6E 74 20 6E 6F 74 20 22 3D 22 2E 0A 40 | ument not "="..@ |
+| 70 20 6D 61 78 69 6D 75 6D 5F 6F 75 74 70 75 74 | p maximum_output |
+| 5F 6C 69 6E 65 5F 6C 65 6E 67 74 68 20 78 20 73 | _line_length x s |
+| 6C 6F 74 68 0A 0A 33 2E 20 54 65 73 74 20 76 61 | loth..3. Test va |
+| 6C 75 65 20 6F 66 20 69 6E 66 69 6E 69 74 79 2E | lue of infinity. |
+| 0A 40 70 20 6D 61 78 69 6D 75 6D 5F 6F 75 74 70 | .@p maximum_outp |
+| 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 74 68 20 3D | ut_line_length = |
+| 20 69 6E 66 69 6E 69 74 79 0A 0A 34 2E 20 54 65 | infinity..4. Te |
+| 73 74 20 6E 6F 6E 2D 64 65 63 69 6D 61 6C 20 64 | st non-decimal d |
+| 69 67 69 74 20 69 6E 20 6E 75 6D 62 65 72 2E 0A | igit in number.. |
+| 40 70 20 6D 61 78 69 6D 75 6D 5F 6F 75 74 70 75 | @p maximum_outpu |
+| 74 5F 6C 69 6E 65 5F 6C 65 6E 67 74 68 20 3D 20 | t_line_length = |
+| 32 65 66 0A 0A 35 2E 20 54 65 73 74 20 6E 75 6D | 2ef..5. Test num |
+| 62 65 72 20 69 73 20 6D 6F 72 65 20 74 68 61 6E | ber is more than |
+| 20 65 69 67 68 74 20 64 69 67 69 74 73 20 6C 6F | eight digits lo |
+| 6E 67 2E 0A 40 70 20 6D 61 78 69 6D 75 6D 5F 6F | ng..@p maximum_o |
+| 75 74 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 74 | utput_line_lengt |
+| 68 20 3D 20 31 32 33 34 35 36 37 38 39 0A 0A 36 | h = 123456789..6 |
+| 2E 20 54 65 73 74 20 6E 75 6D 62 65 72 20 69 73 | . Test number is |
+| 20 65 78 61 63 74 6C 79 20 65 69 67 68 74 20 64 | exactly eight d |
+| 69 67 69 74 73 20 6C 6F 6E 67 2E 0A 37 2E 20 54 | igits long..7. T |
+| 65 73 74 20 70 72 61 67 6D 61 20 6F 70 70 6F 73 | est pragma oppos |
+| 69 6E 67 20 65 61 72 6C 69 65 72 20 70 72 61 67 | ing earlier prag |
+| 6D 61 2E 0A 40 70 20 6D 61 78 69 6D 75 6D 5F 6F | ma..@p maximum_o |
+| 75 74 70 75 74 5F 6C 69 6E 65 5F 6C 65 6E 67 74 | utput_line_lengt |
+| 68 20 3D 20 31 32 33 34 35 36 37 38 0A 0A 38 2E | h = 12345678..8. |
+| 20 54 65 73 74 20 70 72 61 67 6D 61 20 6E 6F 74 | Test pragma not |
+| 20 6F 70 70 6F 73 69 6E 67 20 65 61 72 6C 69 65 | opposing earlie |
+| 72 20 70 72 61 67 6D 61 2E 0A 40 70 20 6D 61 78 | r pragma..@p max |
+| 69 6D 75 6D 5F 6F 75 74 70 75 74 5F 6C 69 6E 65 | imum_output_line |
+| 5F 6C 65 6E 67 74 68 20 3D 20 69 6E 66 69 6E 69 | _length = infini |
+| 74 79 0A 0A | ty.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC23: Test syntax checking of output line length pragma.<010>
+00002 00002| <010>
+00003 00003| 1. Test not three arguments.<010>
+00004 00004| @p maximum_output_line_length<010>
+00005 00005| @p maximum_output_line_length =<010>
+00006 00006| @p maximum_output_line_length = xxx yyy<010>
+00007 00007| <010>
+00008 00008| 2. Test second argument not "=".<010>
+00009 00009| @p maximum_output_line_length x sloth<010>
+00010 00010| <010>
+00011 00011| 3. Test value of infinity.<010>
+00012 00012| @p maximum_output_line_length = infinity<010>
+00013 00013| <010>
+00014 00014| 4. Test non-decimal digit in number.<010>
+00015 00015| @p maximum_output_line_length = 2ef<010>
+00016 00016| <010>
+00017 00017| 5. Test number is more than eight digits long.<010>
+00018 00018| @p maximum_output_line_length = 123456789<010>
+00019 00019| <010>
+00020 00020| 6. Test number is exactly eight digits long.<010>
+00021 00021| 7. Test pragma opposing earlier pragma.<010>
+00022 00022| @p maximum_output_line_length = 12345678<010>
+00023 00023| <010>
+00024 00024| 8. Test pragma not opposing earlier pragma.<010>
+00025 00025| @p maximum_output_line_length = infinity<010>
+00026 00026| <010>
+00027 00027| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 9 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC23: Test syntax checking of output line length pragma.<010>
+<010>
+1. Test not three arguments.<010>
+"
+0007[01]: Text. Text scrap[Grey]="<010>
+2. Test second argument not "=".<010>
+"
+0010[01]: Text. Text scrap[Grey]="<010>
+3. Test value of infinity.<010>
+"
+0013[01]: Text. Text scrap[Grey]="<010>
+4. Test non-decimal digit in number.<010>
+"
+0016[01]: Text. Text scrap[Grey]="<010>
+5. Test number is more than eight digits long.<010>
+"
+0019[01]: Text. Text scrap[Grey]="<010>
+6. Test number is exactly eight digits long.<010>
+7. Test pragma opposing earlier pragma.<010>
+"
+0023[01]: Text. Text scrap[Grey]="<010>
+8. Test pragma not opposing earlier pragma.<010>
+"
+0026[01]: Text. Text scrap[White]="<010>
+"
+0027[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC23: Test syntax checking of output line length pragma.
+ 2 2|
+ 3 3| 1. Test not three arguments.
+ 4 4| @p maximum_output_line_length
+ Error|.^This pragma has the wrong number of arguments.
+ |.^The correct format is: "@p maximum_output_line_length = <num>|infinity".
+ |.^Pragma ignored.
+ 5 5| @p maximum_output_line_length =
+ Error|.^This pragma has the wrong number of arguments.
+ |.^The correct format is: "@p maximum_output_line_length = <num>|infinity".
+ |.^Pragma ignored.
+ 6 6| @p maximum_output_line_length = xxx yyy
+ Error|.^This pragma has the wrong number of arguments.
+ |.^The correct format is: "@p maximum_output_line_length = <num>|infinity".
+ |.^Pragma ignored.
+ 7 7|
+ 8 8| 2. Test second argument not "=".
+ 9 9| @p maximum_output_line_length x sloth
+ |.^The correct format is: "@p maximum_output_line_length = <num>|infinity".
+ |.^Pragma ignored.
+ Error|...............................^Expecting "=".
+ 10 10|
+ 11 11| 3. Test value of infinity.
+ 12 12| @p maximum_output_line_length = infinity
+ |.^This pragma is opposed by the pragma at line 22.
+ 13 13|
+ 14 14| 4. Test non-decimal digit in number.
+ 15 15| @p maximum_output_line_length = 2ef
+ Error|..................................^Illegal digit. Value must consist entirely of decimal digits.
+ |..................................^You can also use the value "infinity".
+ |..................................^Pragma ignored.
+ 16 16|
+ 17 17| 5. Test number is more than eight digits long.
+ 18 18| @p maximum_output_line_length = 123456789
+ Error|.................................^Too many digits. The maximum is eight.
+ |.................................^Pragma ignored.
+ 19 19|
+ 20 20| 6. Test number is exactly eight digits long.
+ 21 21| 7. Test pragma opposing earlier pragma.
+ 22 22| @p maximum_output_line_length = 12345678
+ Error|.^This pragma opposes the pragma at line 12.
+ |.^You can have as many output line length pragmas
+ |.^as you like, but they all have to be the same!
+ |.^Pragma ignored.
+ 23 23|
+ 24 24| 8. Test pragma not opposing earlier pragma.
+ 25 25| @p maximum_output_line_length = infinity
+ 26 26|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 7 Errors.
diff --git a/web/funnelAC/results/sc24.lis b/web/funnelAC/results/sc24.lis
new file mode 100644
index 0000000000..804e5e5d64
--- /dev/null
+++ b/web/funnelAC/results/sc24.lis
@@ -0,0 +1,162 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 33 3A 20 54 65 73 74 20 73 79 6E 74 61 | SC23: Test synta |
+| 78 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 69 6E | x checking of in |
+| 64 65 6E 74 61 74 69 6F 6E 20 70 72 61 67 6D 61 | dentation pragma |
+| 2E 0A 0A 31 2E 20 54 65 73 74 20 6E 6F 74 20 74 | ...1. Test not t |
+| 68 72 65 65 20 61 72 67 75 6D 65 6E 74 73 2E 0A | hree arguments.. |
+| 40 70 20 69 6E 64 65 6E 74 61 74 69 6F 6E 0A 40 | @p indentation.@ |
+| 70 20 69 6E 64 65 6E 74 61 74 69 6F 6E 20 3D 0A | p indentation =. |
+| 40 70 20 69 6E 64 65 6E 74 61 74 69 6F 6E 20 3D | @p indentation = |
+| 20 78 78 78 20 79 79 79 0A 0A 32 2E 20 54 65 73 | xxx yyy..2. Tes |
+| 74 20 73 65 63 6F 6E 64 20 61 72 67 75 6D 65 6E | t second argumen |
+| 74 20 6E 6F 74 20 22 3D 22 2E 0A 40 70 20 69 6E | t not "="..@p in |
+| 64 65 6E 74 61 74 69 6F 6E 20 78 20 73 6C 6F 74 | dentation x slot |
+| 68 0A 0A 33 2E 20 54 65 73 74 20 74 68 69 72 64 | h..3. Test third |
+| 20 61 72 67 75 6D 65 6E 74 20 69 73 20 6E 6F 74 | argument is not |
+| 20 6C 65 67 61 6C 2E 0A 40 70 20 69 6E 64 65 6E | legal..@p inden |
+| 74 61 74 69 6F 6E 20 3D 20 73 6C 6F 74 68 0A 0A | tation = sloth.. |
+| 34 2E 20 54 65 73 74 20 74 68 69 72 64 20 61 72 | 4. Test third ar |
+| 67 75 6D 65 6E 74 20 69 73 20 6E 6F 6E 65 2E 0A | gument is none.. |
+| 40 70 20 69 6E 64 65 6E 74 61 74 69 6F 6E 20 3D | @p indentation = |
+| 20 6E 6F 6E 65 0A 0A 35 2E 20 54 65 73 74 20 74 | none..5. Test t |
+| 68 69 72 64 20 61 72 67 75 6D 65 6E 74 20 69 73 | hird argument is |
+| 20 62 6C 61 6E 6B 2E 0A 36 2E 20 54 65 73 74 20 | blank..6. Test |
+| 70 72 61 67 6D 61 20 6F 70 70 6F 73 65 73 20 65 | pragma opposes e |
+| 61 72 6C 69 65 72 20 70 72 61 67 6D 61 2E 0A 40 | arlier pragma..@ |
+| 70 20 69 6E 64 65 6E 74 61 74 69 6F 6E 20 3D 20 | p indentation = |
+| 62 6C 61 6E 6B 0A 0A 37 2E 20 54 65 73 74 20 70 | blank..7. Test p |
+| 72 61 67 6D 61 20 64 6F 65 73 20 6E 6F 74 20 6F | ragma does not o |
+| 70 70 6F 73 65 20 65 61 72 6C 69 65 72 20 70 72 | ppose earlier pr |
+| 61 67 6D 61 2E 0A 40 70 20 69 6E 64 65 6E 74 61 | agma..@p indenta |
+| 74 69 6F 6E 20 3D 20 6E 6F 6E 65 0A 0A | tion = none.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC23: Test syntax checking of indentation pragma.<010>
+00002 00002| <010>
+00003 00003| 1. Test not three arguments.<010>
+00004 00004| @p indentation<010>
+00005 00005| @p indentation =<010>
+00006 00006| @p indentation = xxx yyy<010>
+00007 00007| <010>
+00008 00008| 2. Test second argument not "=".<010>
+00009 00009| @p indentation x sloth<010>
+00010 00010| <010>
+00011 00011| 3. Test third argument is not legal.<010>
+00012 00012| @p indentation = sloth<010>
+00013 00013| <010>
+00014 00014| 4. Test third argument is none.<010>
+00015 00015| @p indentation = none<010>
+00016 00016| <010>
+00017 00017| 5. Test third argument is blank.<010>
+00018 00018| 6. Test pragma opposes earlier pragma.<010>
+00019 00019| @p indentation = blank<010>
+00020 00020| <010>
+00021 00021| 7. Test pragma does not oppose earlier pragma.<010>
+00022 00022| @p indentation = none<010>
+00023 00023| <010>
+00024 00024| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 8 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC23: Test syntax checking of indentation pragma.<010>
+<010>
+1. Test not three arguments.<010>
+"
+0007[01]: Text. Text scrap[Grey]="<010>
+2. Test second argument not "=".<010>
+"
+0010[01]: Text. Text scrap[Grey]="<010>
+3. Test third argument is not legal.<010>
+"
+0013[01]: Text. Text scrap[Grey]="<010>
+4. Test third argument is none.<010>
+"
+0016[01]: Text. Text scrap[Grey]="<010>
+5. Test third argument is blank.<010>
+6. Test pragma opposes earlier pragma.<010>
+"
+0020[01]: Text. Text scrap[Grey]="<010>
+7. Test pragma does not oppose earlier pragma.<010>
+"
+0023[01]: Text. Text scrap[White]="<010>
+"
+0024[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC23: Test syntax checking of indentation pragma.
+ 2 2|
+ 3 3| 1. Test not three arguments.
+ 4 4| @p indentation
+ Error|.^This indentation pragma has the wrong number of arguments.
+ |.^The correct format is: "@p indentation = none|blank".
+ |.^Pragma ignored.
+ 5 5| @p indentation =
+ Error|.^This indentation pragma has the wrong number of arguments.
+ |.^The correct format is: "@p indentation = none|blank".
+ |.^Pragma ignored.
+ 6 6| @p indentation = xxx yyy
+ Error|.^This indentation pragma has the wrong number of arguments.
+ |.^The correct format is: "@p indentation = none|blank".
+ |.^Pragma ignored.
+ 7 7|
+ 8 8| 2. Test second argument not "=".
+ 9 9| @p indentation x sloth
+ |.^The correct format is: "@p indentation = none|blank".
+ |.^Pragma ignored.
+ Error|................^Expecting "=".
+ 10 10|
+ 11 11| 3. Test third argument is not legal.
+ 12 12| @p indentation = sloth
+ |.^The correct format is: "@p indentation = none|blank".
+ |.^Pragma ignored.
+ Error|..................^Expecting either "none" or "blank".
+ 13 13|
+ 14 14| 4. Test third argument is none.
+ 15 15| @p indentation = none
+ |.^This pragma is opposed by the pragma at line 19.
+ 16 16|
+ 17 17| 5. Test third argument is blank.
+ 18 18| 6. Test pragma opposes earlier pragma.
+ 19 19| @p indentation = blank
+ Error|.^This pragma opposes the pragma at line 15.
+ |.^You can have as many indentation pragmas as you like,
+ |.^but they all have to be the same!
+ |.^Pragma ignored.
+ 20 20|
+ 21 21| 7. Test pragma does not oppose earlier pragma.
+ 22 22| @p indentation = none
+ 23 23|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 6 Errors.
diff --git a/web/funnelAC/results/sc25.lis b/web/funnelAC/results/sc25.lis
new file mode 100644
index 0000000000..0182f4e147
--- /dev/null
+++ b/web/funnelAC/results/sc25.lis
@@ -0,0 +1,85 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 35 3A 20 54 65 73 74 20 73 79 6E 74 61 | SC25: Test synta |
+| 78 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 6E 65 | x checking of ne |
+| 77 20 70 61 67 65 20 74 79 70 65 73 65 74 74 65 | w page typesette |
+| 72 20 64 69 72 65 63 74 69 76 65 2E 0A 0A 31 2E | r directive...1. |
+| 20 4D 61 6B 65 20 73 75 72 65 20 74 68 61 74 20 | Make sure that |
+| 61 20 6C 65 67 61 6C 20 6E 65 77 20 70 61 67 65 | a legal new page |
+| 20 64 69 72 65 63 74 69 76 65 20 69 73 20 4F 4B | directive is OK |
+| 2E 0A 40 74 20 6E 65 77 5F 70 61 67 65 0A 0A 32 | ..@t new_page..2 |
+| 2E 20 43 68 65 63 6B 20 74 68 61 74 20 69 74 20 | . Check that it |
+| 64 6F 65 73 6E 27 74 20 73 74 61 6E 64 20 66 6F | doesn't stand fo |
+| 72 20 61 6E 79 20 6E 6F 6E 73 65 6E 73 65 2E 0A | r any nonsense.. |
+| 40 74 20 6E 65 77 5F 70 61 67 65 20 6E 6F 6E 73 | @t new_page nons |
+| 65 6E 73 65 0A 0A | ense.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC25: Test syntax checking of new page typesetter directive.<010>
+00002 00002| <010>
+00003 00003| 1. Make sure that a legal new page directive is OK.<010>
+00004 00004| @t new_page<010>
+00005 00005| <010>
+00006 00006| 2. Check that it doesn't stand for any nonsense.<010>
+00007 00007| @t new_page nonsense<010>
+00008 00008| <010>
+00009 00009| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 5 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC25: Test syntax checking of new page typesetter directive.<010>
+<010>
+1. Make sure that a legal new page directive is OK.<010>
+"
+0004[01]: @t.. Newpage.
+0005[01]: Text. Text scrap[Grey]="<010>
+2. Check that it doesn't stand for any nonsense.<010>
+"
+0008[01]: Text. Text scrap[White]="<010>
+"
+0009[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC25: Test syntax checking of new page typesetter directive.
+ 2 2|
+ 3 3| 1. Make sure that a legal new page directive is OK.
+ 4 4| @t new_page
+ 5 5|
+ 6 6| 2. Check that it doesn't stand for any nonsense.
+ 7 7| @t new_page nonsense
+ Error|.............^The new_page directive does not take arguments.
+ |.............^Directive ignored.
+ 8 8|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There was 1 Error.
diff --git a/web/funnelAC/results/sc26.lis b/web/funnelAC/results/sc26.lis
new file mode 100644
index 0000000000..5cb968aa74
--- /dev/null
+++ b/web/funnelAC/results/sc26.lis
@@ -0,0 +1,87 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 36 3A 20 54 65 73 74 20 73 79 6E 74 61 | SC26: Test synta |
+| 78 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 74 61 | x checking of ta |
+| 62 6C 65 20 6F 66 20 63 6F 6E 74 65 6E 74 73 20 | ble of contents |
+| 74 79 70 65 73 65 74 74 69 6E 67 20 70 72 61 67 | typesetting prag |
+| 6D 61 2E 0A 0A 31 2E 20 4D 61 6B 65 20 73 75 72 | ma...1. Make sur |
+| 65 20 74 68 61 74 20 61 20 6C 65 67 61 6C 20 74 | e that a legal t |
+| 61 62 6C 65 20 6F 66 20 63 6F 6E 74 65 6E 74 73 | able of contents |
+| 20 64 69 72 65 63 74 69 76 65 20 69 73 20 4F 4B | directive is OK |
+| 2E 0A 40 74 20 74 61 62 6C 65 5F 6F 66 5F 63 6F | ..@t table_of_co |
+| 6E 74 65 6E 74 73 0A 0A 32 2E 20 43 68 65 63 6B | ntents..2. Check |
+| 20 74 68 61 74 20 69 74 20 64 6F 65 73 6E 27 74 | that it doesn't |
+| 20 73 74 61 6E 64 20 66 6F 72 20 61 6E 79 20 6E | stand for any n |
+| 6F 6E 73 65 6E 73 65 2E 0A 40 74 20 74 61 62 6C | onsense..@t tabl |
+| 65 5F 6F 66 5F 63 6F 6E 74 65 6E 74 73 20 6E 6F | e_of_contents no |
+| 6E 73 65 6E 73 65 0A 0A | nsense.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC26: Test syntax checking of table of contents typesetting pragma.<010>
+00002 00002| <010>
+00003 00003| 1. Make sure that a legal table of contents directive is OK.<010>
+00004 00004| @t table_of_contents<010>
+00005 00005| <010>
+00006 00006| 2. Check that it doesn't stand for any nonsense.<010>
+00007 00007| @t table_of_contents nonsense<010>
+00008 00008| <010>
+00009 00009| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 5 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC26: Test syntax checking of table of contents typesetting pragma.<010>
+<010>
+1. Make sure that a legal table of contents directive is OK.<010>
+"
+0004[01]: @t.. TOC.
+0005[01]: Text. Text scrap[Grey]="<010>
+2. Check that it doesn't stand for any nonsense.<010>
+"
+0008[01]: Text. Text scrap[White]="<010>
+"
+0009[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC26: Test syntax checking of table of contents typesetting pragma.
+ 2 2|
+ 3 3| 1. Make sure that a legal table of contents directive is OK.
+ 4 4| @t table_of_contents
+ 5 5|
+ 6 6| 2. Check that it doesn't stand for any nonsense.
+ 7 7| @t table_of_contents nonsense
+ Error|......................^The table_of_contents directive does not take arguments.
+ |......................^Directive ignored.
+ 8 8|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There was 1 Error.
diff --git a/web/funnelAC/results/sc27.lis b/web/funnelAC/results/sc27.lis
new file mode 100644
index 0000000000..404a5b2827
--- /dev/null
+++ b/web/funnelAC/results/sc27.lis
@@ -0,0 +1,145 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 37 3A 20 54 65 73 74 20 73 79 6E 74 61 | SC27: Test synta |
+| 78 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 76 73 | x checking of vs |
+| 6B 69 70 20 74 79 70 65 73 65 74 74 69 6E 67 20 | kip typesetting |
+| 64 69 72 65 63 74 69 76 65 2E 0A 0A 31 2E 20 54 | directive...1. T |
+| 65 73 74 20 6E 6F 74 20 65 78 61 63 74 6C 79 20 | est not exactly |
+| 74 68 72 65 65 20 61 72 67 75 6D 65 6E 74 73 20 | three arguments |
+| 28 69 6E 63 6C 75 64 65 73 20 76 73 6B 69 70 29 | (includes vskip) |
+| 2E 0A 40 74 20 76 73 6B 69 70 0A 40 74 20 76 73 | ..@t vskip.@t vs |
+| 6B 69 70 20 6F 6E 65 0A 40 74 20 76 73 6B 69 70 | kip one.@t vskip |
+| 20 6F 6E 65 20 74 77 6F 20 74 68 72 65 65 20 66 | one two three f |
+| 6F 75 72 0A 0A 32 2E 20 54 65 73 74 20 74 68 69 | our..2. Test thi |
+| 72 64 20 61 72 67 75 6D 65 6E 74 20 6E 6F 74 20 | rd argument not |
+| 22 6D 6D 22 2E 0A 40 74 20 76 73 6B 69 70 20 33 | "mm"..@t vskip 3 |
+| 32 20 78 78 0A 0A 33 2E 20 54 65 73 74 20 73 65 | 2 xx..3. Test se |
+| 63 6F 6E 64 20 61 72 67 75 6D 65 6E 74 20 68 61 | cond argument ha |
+| 73 20 62 61 64 20 64 69 67 69 74 2E 0A 40 74 20 | s bad digit..@t |
+| 76 73 6B 69 70 20 33 66 20 6D 6D 0A 0A 34 2E 20 | vskip 3f mm..4. |
+| 54 65 73 74 20 6E 75 6D 62 65 72 20 68 61 73 20 | Test number has |
+| 6D 6F 72 65 20 74 68 61 6E 20 74 68 72 65 65 20 | more than three |
+| 64 69 67 69 74 73 0A 0A 40 74 20 76 73 6B 69 70 | digits..@t vskip |
+| 20 34 33 35 35 20 6D 6D 0A 0A 35 2E 20 54 65 73 | 4355 mm..5. Tes |
+| 74 20 61 20 6C 65 67 61 6C 20 6F 6E 65 20 74 6F | t a legal one to |
+| 6F 2E 0A 40 74 20 76 73 6B 69 70 20 32 30 20 6D | o..@t vskip 20 m |
+| 6D 0A 0A | m.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC27: Test syntax checking of vskip typesetting directive.<010>
+00002 00002| <010>
+00003 00003| 1. Test not exactly three arguments (includes vskip).<010>
+00004 00004| @t vskip<010>
+00005 00005| @t vskip one<010>
+00006 00006| @t vskip one two three four<010>
+00007 00007| <010>
+00008 00008| 2. Test third argument not "mm".<010>
+00009 00009| @t vskip 32 xx<010>
+00010 00010| <010>
+00011 00011| 3. Test second argument has bad digit.<010>
+00012 00012| @t vskip 3f mm<010>
+00013 00013| <010>
+00014 00014| 4. Test number has more than three digits<010>
+00015 00015| <010>
+00016 00016| @t vskip 4355 mm<010>
+00017 00017| <010>
+00018 00018| 5. Test a legal one too.<010>
+00019 00019| @t vskip 20 mm<010>
+00020 00020| <010>
+00021 00021| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 8 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC27: Test syntax checking of vskip typesetting directive.<010>
+<010>
+1. Test not exactly three arguments (includes vskip).<010>
+"
+0007[01]: Text. Text scrap[Grey]="<010>
+2. Test third argument not "mm".<010>
+"
+0010[01]: Text. Text scrap[Grey]="<010>
+3. Test second argument has bad digit.<010>
+"
+0013[01]: Text. Text scrap[Grey]="<010>
+4. Test number has more than three digits<010>
+<010>
+"
+0017[01]: Text. Text scrap[Grey]="<010>
+5. Test a legal one too.<010>
+"
+0019[01]: @t.. Vertical skip. Vertical space skipped=20mm.
+0020[01]: Text. Text scrap[White]="<010>
+"
+0021[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC27: Test syntax checking of vskip typesetting directive.
+ 2 2|
+ 3 3| 1. Test not exactly three arguments (includes vskip).
+ 4 4| @t vskip
+ Error|.^This directive has the wrong number of arguments.
+ |.^The correct format is: "@t vskip <num> mm".
+ |.^Directive ignored.
+ 5 5| @t vskip one
+ Error|.^This directive has the wrong number of arguments.
+ |.^The correct format is: "@t vskip <num> mm".
+ |.^Directive ignored.
+ 6 6| @t vskip one two three four
+ Error|.^This directive has the wrong number of arguments.
+ |.^The correct format is: "@t vskip <num> mm".
+ |.^Directive ignored.
+ 7 7|
+ 8 8| 2. Test third argument not "mm".
+ 9 9| @t vskip 32 xx
+ |.^The correct format is: "@t vskip <num> mm".
+ |.^Directive ignored.
+ Error|.............^Expecting "mm".
+ 10 10|
+ 11 11| 3. Test second argument has bad digit.
+ 12 12| @t vskip 3f mm
+ Error|...........^Illegal digit.
+ |...........^Value must consist entirely of decimal digits.
+ |...........^Directive ignored.
+ 13 13|
+ 14 14| 4. Test number has more than three digits
+ 15 15|
+ 16 16| @t vskip 4355 mm
+ Error|..........^Too many digits. The maximum is three.
+ |..........^Directive ignored.
+ 17 17|
+ 18 18| 5. Test a legal one too.
+ 19 19| @t vskip 20 mm
+ 20 20|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 6 Errors.
diff --git a/web/funnelAC/results/sc28.lis b/web/funnelAC/results/sc28.lis
new file mode 100644
index 0000000000..8208193d4b
--- /dev/null
+++ b/web/funnelAC/results/sc28.lis
@@ -0,0 +1,253 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 38 3A 20 54 65 73 74 20 73 79 6E 74 61 | SC28: Test synta |
+| 78 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 74 69 | x checking of ti |
+| 74 6C 65 20 74 79 70 65 73 65 74 74 69 6E 67 20 | tle typesetting |
+| 64 69 72 65 63 74 69 76 65 2E 0A 0A 31 2E 20 54 | directive...1. T |
+| 65 73 74 20 6C 65 73 73 20 74 68 61 6E 20 66 6F | est less than fo |
+| 75 72 20 61 72 67 75 6D 65 6E 74 73 20 28 69 6E | ur arguments (in |
+| 63 6C 75 64 65 73 20 74 69 74 6C 65 29 2E 0A 4E | cludes title)..N |
+| 6F 74 65 3A 20 54 68 65 20 74 69 74 6C 65 20 63 | ote: The title c |
+| 6F 6D 6D 61 6E 64 20 70 75 6C 6C 73 20 61 20 68 | ommand pulls a h |
+| 61 63 6B 20 74 72 65 61 74 69 6E 67 20 74 68 65 | ack treating the |
+| 20 72 65 73 74 20 6F 66 20 74 68 65 20 6C 69 6E | rest of the lin |
+| 65 20 61 66 74 65 72 0A 74 77 6F 20 61 72 67 75 | e after.two argu |
+| 6D 65 6E 74 73 20 61 73 20 74 68 65 20 73 74 72 | ments as the str |
+| 69 6E 67 2E 20 53 6F 20 69 74 20 63 61 6E 27 74 | ing. So it can't |
+| 20 64 65 74 65 63 74 20 61 6E 20 45 58 43 45 53 | detect an EXCES |
+| 53 20 6F 66 20 61 72 67 75 6D 65 6E 74 73 21 0A | S of arguments!. |
+| 40 74 20 74 69 74 6C 65 0A 40 74 20 74 69 74 6C | @t title.@t titl |
+| 65 20 74 77 6F 0A 40 74 20 74 69 74 6C 65 20 74 | e two.@t title t |
+| 77 6F 20 74 68 72 65 65 0A 0A 32 2E 20 54 65 73 | wo three..2. Tes |
+| 74 20 6F 75 74 20 62 61 64 20 66 6F 6E 74 2E 0A | t out bad font.. |
+| 40 74 20 74 69 74 6C 65 20 73 6C 6F 74 68 66 6F | @t title slothfo |
+| 6E 74 20 6C 65 66 74 20 22 53 6C 6F 74 68 22 0A | nt left "Sloth". |
+| 0A 33 2E 20 54 65 73 74 20 6F 75 74 20 62 61 64 | .3. Test out bad |
+| 20 61 6C 69 67 6E 6D 65 6E 74 2E 0A 40 74 20 74 | alignment..@t t |
+| 69 74 6C 65 20 74 69 74 6C 65 66 6F 6E 74 20 77 | itle titlefont w |
+| 65 73 74 77 61 72 64 20 22 53 6C 6F 74 68 22 0A | estward "Sloth". |
+| 0A 34 2E 20 54 65 73 74 20 6F 75 74 20 66 75 6E | .4. Test out fun |
+| 6E 79 20 73 74 72 69 6E 67 73 2E 0A 40 74 20 74 | ny strings..@t t |
+| 69 74 6C 65 20 74 69 74 6C 65 66 6F 6E 74 20 6C | itle titlefont l |
+| 65 66 74 20 22 0A 40 74 20 74 69 74 6C 65 20 74 | eft ".@t title t |
+| 69 74 6C 65 66 6F 6E 74 20 6C 65 66 74 20 22 22 | itlefont left "" |
+| 0A 40 21 20 4E 6F 74 65 3A 20 54 68 65 20 66 6F | .@! Note: The fo |
+| 6C 6C 6F 77 69 6E 67 2C 20 62 65 6C 69 65 76 65 | llowing, believe |
+| 20 69 74 20 6F 72 20 6E 6F 74 2C 20 69 73 20 61 | it or not, is a |
+| 63 74 75 61 6C 6C 79 20 4C 45 47 41 4C 21 0A 40 | ctually LEGAL!.@ |
+| 74 20 74 69 74 6C 65 20 74 69 74 6C 65 66 6F 6E | t title titlefon |
+| 74 20 6C 65 66 74 20 22 73 6C 6F 74 68 22 73 6C | t left "sloth"sl |
+| 6F 74 68 22 0A 0A 35 2E 20 54 65 73 74 20 6F 75 | oth"..5. Test ou |
+| 74 20 61 6C 6C 20 63 6F 6D 62 69 6E 61 74 69 6F | t all combinatio |
+| 6E 73 20 6F 66 20 66 6F 6E 74 20 61 6E 64 20 61 | ns of font and a |
+| 6C 69 67 6E 6D 65 6E 74 2E 0A 40 74 20 74 69 74 | lignment..@t tit |
+| 6C 65 20 74 69 74 6C 65 66 6F 6E 74 20 20 20 20 | le titlefont |
+| 20 20 6C 65 66 74 20 20 20 22 53 6C 6F 74 68 22 | left "Sloth" |
+| 0A 40 74 20 74 69 74 6C 65 20 74 69 74 6C 65 66 | .@t title titlef |
+| 6F 6E 74 20 20 20 20 20 20 63 65 6E 74 72 65 20 | ont centre |
+| 22 53 6C 6F 74 68 22 0A 40 74 20 74 69 74 6C 65 | "Sloth".@t title |
+| 20 74 69 74 6C 65 66 6F 6E 74 20 20 20 20 20 20 | titlefont |
+| 72 69 67 68 74 20 20 22 53 6C 6F 74 68 22 0A 40 | right "Sloth".@ |
+| 74 20 74 69 74 6C 65 20 73 6D 61 6C 6C 74 69 74 | t title smalltit |
+| 6C 65 66 6F 6E 74 20 6C 65 66 74 20 20 20 22 53 | lefont left "S |
+| 6C 6F 74 68 22 0A 40 74 20 74 69 74 6C 65 20 73 | loth".@t title s |
+| 6D 61 6C 6C 74 69 74 6C 65 66 6F 6E 74 20 63 65 | malltitlefont ce |
+| 6E 74 72 65 20 22 53 6C 6F 74 68 22 0A 40 74 20 | ntre "Sloth".@t |
+| 74 69 74 6C 65 20 73 6D 61 6C 6C 74 69 74 6C 65 | title smalltitle |
+| 66 6F 6E 74 20 72 69 67 68 74 20 20 22 53 6C 6F | font right "Slo |
+| 74 68 22 0A 40 74 20 74 69 74 6C 65 20 6E 6F 72 | th".@t title nor |
+| 6D 61 6C 66 6F 6E 74 20 20 20 20 20 6C 65 66 74 | malfont left |
+| 20 20 20 22 53 6C 6F 74 68 22 0A 40 74 20 74 69 | "Sloth".@t ti |
+| 74 6C 65 20 6E 6F 72 6D 61 6C 66 6F 6E 74 20 20 | tle normalfont |
+| 20 20 20 63 65 6E 74 72 65 20 22 53 6C 6F 74 68 | centre "Sloth |
+| 22 0A 40 74 20 74 69 74 6C 65 20 6E 6F 72 6D 61 | ".@t title norma |
+| 6C 66 6F 6E 74 20 20 20 20 20 72 69 67 68 74 20 | lfont right |
+| 20 22 53 6C 6F 74 68 22 0A 0A 36 2E 20 54 65 73 | "Sloth"..6. Tes |
+| 74 20 6D 69 73 73 70 65 6C 6C 69 6E 67 20 6F 66 | t misspelling of |
+| 20 63 65 6E 74 72 65 20 28 52 6F 73 73 27 73 20 | centre (Ross's |
+| 72 65 76 65 6E 67 65 29 2E 0A 40 74 20 74 69 74 | revenge)..@t tit |
+| 6C 65 20 6E 6F 72 6D 61 6C 66 6F 6E 74 20 20 20 | le normalfont |
+| 20 20 63 65 6E 74 65 72 20 22 53 6C 6F 74 68 22 | center "Sloth" |
+| 0A | . |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC28: Test syntax checking of title typesetting directive.<010>
+00002 00002| <010>
+00003 00003| 1. Test less than four arguments (includes title).<010>
+00004 00004| Note: The title command pulls a hack treating the rest of the line after<010>
+00005 00005| two arguments as the string. So it can't detect an EXCESS of arguments!<010>
+00006 00006| @t title<010>
+00007 00007| @t title two<010>
+00008 00008| @t title two three<010>
+00009 00009| <010>
+00010 00010| 2. Test out bad font.<010>
+00011 00011| @t title slothfont left "Sloth"<010>
+00012 00012| <010>
+00013 00013| 3. Test out bad alignment.<010>
+00014 00014| @t title titlefont westward "Sloth"<010>
+00015 00015| <010>
+00016 00016| 4. Test out funny strings.<010>
+00017 00017| @t title titlefont left "<010>
+00018 00018| @t title titlefont left ""<010>
+00019 00019| @! Note: The following, believe it or not, is actually LEGAL!<010>
+00020 00020| @t title titlefont left "sloth"sloth"<010>
+00021 00021| <010>
+00022 00022| 5. Test out all combinations of font and alignment.<010>
+00023 00023| @t title titlefont left "Sloth"<010>
+00024 00024| @t title titlefont centre "Sloth"<010>
+00025 00025| @t title titlefont right "Sloth"<010>
+00026 00026| @t title smalltitlefont left "Sloth"<010>
+00027 00027| @t title smalltitlefont centre "Sloth"<010>
+00028 00028| @t title smalltitlefont right "Sloth"<010>
+00029 00029| @t title normalfont left "Sloth"<010>
+00030 00030| @t title normalfont centre "Sloth"<010>
+00031 00031| @t title normalfont right "Sloth"<010>
+00032 00032| <010>
+00033 00033| 6. Test misspelling of centre (Ross's revenge).<010>
+00034 00034| @t title normalfont center "Sloth"<010>
+00035 00035| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 18 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC28: Test syntax checking of title typesetting directive.<010>
+<010>
+1. Test less than four arguments (includes title).<010>
+Note: The title command pulls a hack treating the rest of the line after<010>
+two arguments as the string. So it can't detect an EXCESS of arguments!<010>
+"
+0009[01]: Text. Text scrap[Grey]="<010>
+2. Test out bad font.<010>
+"
+0012[01]: Text. Text scrap[Grey]="<010>
+3. Test out bad alignment.<010>
+"
+0015[01]: Text. Text scrap[Grey]="<010>
+4. Test out funny strings.<010>
+"
+0018[01]: @t.. Title. Font=Title, Alignment=Left. Title text follows:
+Text scrap[Grey]=""
+0020[01]: @t.. Title. Font=Title, Alignment=Left. Title text follows:
+Text scrap[Grey]="sloth"sloth"
+0021[01]: Text. Text scrap[Grey]="<010>
+5. Test out all combinations of font and alignment.<010>
+"
+0023[01]: @t.. Title. Font=Title, Alignment=Left. Title text follows:
+Text scrap[Grey]="Sloth"
+0024[01]: @t.. Title. Font=Title, Alignment=Centre. Title text follows:
+Text scrap[Grey]="Sloth"
+0025[01]: @t.. Title. Font=Title, Alignment=Right. Title text follows:
+Text scrap[Grey]="Sloth"
+0026[01]: @t.. Title. Font=Small Title, Alignment=Left. Title text follows:
+Text scrap[Grey]="Sloth"
+0027[01]: @t.. Title. Font=Small Title, Alignment=Centre. Title text follows:
+Text scrap[Grey]="Sloth"
+0028[01]: @t.. Title. Font=Small Title, Alignment=Right. Title text follows:
+Text scrap[Grey]="Sloth"
+0029[01]: @t.. Title. Font=Normal, Alignment=Left. Title text follows:
+Text scrap[Grey]="Sloth"
+0030[01]: @t.. Title. Font=Normal, Alignment=Centre. Title text follows:
+Text scrap[Grey]="Sloth"
+0031[01]: @t.. Title. Font=Normal, Alignment=Right. Title text follows:
+Text scrap[Grey]="Sloth"
+0032[01]: Text. Text scrap[Grey]="<010>
+6. Test misspelling of centre (Ross's revenge).<010>
+"
+0035[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC28: Test syntax checking of title typesetting directive.
+ 2 2|
+ 3 3| 1. Test less than four arguments (includes title).
+ 4 4| Note: The title command pulls a hack treating the rest of the line after
+ 5 5| two arguments as the string. So it can't detect an EXCESS of arguments!
+ 6 6| @t title
+ Error|.^This directive has too few arguments.
+ |.^The correct format is: "@t title <font> <align> <text>".
+ |.^ where <font> = titlefont | smalltitlefont | normalfont.
+ |.^ and <align> = left | centre | right.
+ |.^ and <text> = text delimited by double quotes.
+ |.^Directive ignored.
+ 7 7| @t title two
+ Error|.^This directive has too few arguments.
+ |.^The correct format is: "@t title <font> <align> <text>".
+ |.^ where <font> = titlefont | smalltitlefont | normalfont.
+ |.^ and <align> = left | centre | right.
+ |.^ and <text> = text delimited by double quotes.
+ |.^Directive ignored.
+ 8 8| @t title two three
+ Error|.^This directive has too few arguments.
+ |.^The correct format is: "@t title <font> <align> <text>".
+ |.^ where <font> = titlefont | smalltitlefont | normalfont.
+ |.^ and <align> = left | centre | right.
+ |.^ and <text> = text delimited by double quotes.
+ |.^Directive ignored.
+ 9 9|
+ 10 10| 2. Test out bad font.
+ 11 11| @t title slothfont left "Sloth"
+ Error|..........^Expecting one of {titlefont,smalltitlefont,normalfont}.
+ |..........^Directive ignored.
+ 12 12|
+ 13 13| 3. Test out bad alignment.
+ 14 14| @t title titlefont westward "Sloth"
+ Error|....................^Expecting one of {left,right,centre}.
+ |....................^Directive ignored.
+ 15 15|
+ 16 16| 4. Test out funny strings.
+ 17 17| @t title titlefont left "
+ Error|.........................^Text argument must be delimited by double quotes.
+ |.........................^Directive ignored.
+ 18 18| @t title titlefont left ""
+ 19 19| @! Note: The following, believe it or not, is actually LEGAL!
+ 20 20| @t title titlefont left "sloth"sloth"
+ 21 21|
+ 22 22| 5. Test out all combinations of font and alignment.
+ 23 23| @t title titlefont left "Sloth"
+ 24 24| @t title titlefont centre "Sloth"
+ 25 25| @t title titlefont right "Sloth"
+ 26 26| @t title smalltitlefont left "Sloth"
+ 27 27| @t title smalltitlefont centre "Sloth"
+ 28 28| @t title smalltitlefont right "Sloth"
+ 29 29| @t title normalfont left "Sloth"
+ 30 30| @t title normalfont centre "Sloth"
+ 31 31| @t title normalfont right "Sloth"
+ 32 32|
+ 33 33| 6. Test misspelling of centre (Ross's revenge).
+ 34 34| @t title normalfont center "Sloth"
+ Error|.........................^Expecting one of {left,right,centre}.
+ |.........................^Note: Centre is spelt centRE, not centER.
+ |.........................^ This is my revenge for years of getting error messages
+ |.........................^ from TeX whenever I accidentally wrote \centreline - Ross Williams.
+ |.........................^Directive ignored.
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 7 Errors.
diff --git a/web/funnelAC/results/sc29.lis b/web/funnelAC/results/sc29.lis
new file mode 100644
index 0000000000..8b3ee9059b
--- /dev/null
+++ b/web/funnelAC/results/sc29.lis
@@ -0,0 +1,170 @@
+FUNNELWEB LISTING FILE
+======================
+
+Dump of mapped file "<<Suppressed>>".
+
+MEMORY DUMP OF MAPPED FILE
+==========================
+
++-------------------------------------------------+------------------+
+| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
++-------------------------------------------------+------------------+
+| 53 43 32 39 3A 20 54 65 73 74 20 73 79 6E 74 61 | SC29: Test synta |
+| 78 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 74 79 | x checking of ty |
+| 70 65 73 65 74 74 65 72 20 70 72 61 67 6D 61 2E | pesetter pragma. |
+| 0A 0A 31 2E 20 54 65 73 74 20 6E 6F 74 20 74 68 | ..1. Test not th |
+| 72 65 65 20 61 72 67 75 6D 65 6E 74 73 2E 0A 40 | ree arguments..@ |
+| 70 20 74 79 70 65 73 65 74 74 65 72 0A 40 70 20 | p typesetter.@p |
+| 74 79 70 65 73 65 74 74 65 72 20 3D 0A 40 70 20 | typesetter =.@p |
+| 74 79 70 65 73 65 74 74 65 72 20 3D 20 78 78 78 | typesetter = xxx |
+| 20 79 79 79 0A 0A 32 2E 20 54 65 73 74 20 73 65 | yyy..2. Test se |
+| 63 6F 6E 64 20 61 72 67 75 6D 65 6E 74 20 6E 6F | cond argument no |
+| 74 20 22 3D 22 2E 0A 40 70 20 74 79 70 65 73 65 | t "="..@p typese |
+| 74 74 65 72 20 78 20 73 6C 6F 74 68 0A 0A 33 2E | tter x sloth..3. |
+| 20 54 65 73 74 20 74 68 69 72 64 20 61 72 67 75 | Test third argu |
+| 6D 65 6E 74 20 69 73 20 6E 6F 74 20 6C 65 67 61 | ment is not lega |
+| 6C 2E 0A 40 70 20 74 79 70 65 73 65 74 74 65 72 | l..@p typesetter |
+| 20 3D 20 73 6C 6F 74 68 0A 0A 34 2E 20 54 65 73 | = sloth..4. Tes |
+| 74 20 74 68 69 72 64 20 61 72 67 75 6D 65 6E 74 | t third argument |
+| 20 69 73 20 6E 6F 6E 65 2E 0A 40 70 20 74 79 70 | is none..@p typ |
+| 65 73 65 74 74 65 72 20 3D 20 6E 6F 6E 65 0A 0A | esetter = none.. |
+| 35 2E 20 54 65 73 74 20 74 68 69 72 64 20 61 72 | 5. Test third ar |
+| 67 75 6D 65 6E 74 20 69 73 20 74 65 78 2E 0A 36 | gument is tex..6 |
+| 2E 20 54 65 73 74 20 70 72 61 67 6D 61 20 6F 70 | . Test pragma op |
+| 70 6F 73 65 73 20 65 61 72 6C 69 65 72 20 70 72 | poses earlier pr |
+| 61 67 6D 61 2E 0A 40 70 20 74 79 70 65 73 65 74 | agma..@p typeset |
+| 74 65 72 20 3D 20 74 65 78 0A 0A 37 2E 20 54 65 | ter = tex..7. Te |
+| 73 74 20 70 72 61 67 6D 61 20 64 6F 65 73 20 6E | st pragma does n |
+| 6F 74 20 6F 70 70 6F 73 65 20 65 61 72 6C 69 65 | ot oppose earlie |
+| 72 20 70 72 61 67 6D 61 2E 0A 40 70 20 74 79 70 | r pragma..@p typ |
+| 65 73 65 74 74 65 72 20 3D 20 6E 6F 6E 65 0A 0A | esetter = none.. |
++-------------------------------------------------+------------------+
+
+
+=========================== Start of LINE LIST DUMP ============================
+
+Globl Local| Text
+-----------+--------------------------------------------------------------------
+00001 00001| SC29: Test syntax checking of typesetter pragma.<010>
+00002 00002| <010>
+00003 00003| 1. Test not three arguments.<010>
+00004 00004| @p typesetter<010>
+00005 00005| @p typesetter =<010>
+00006 00006| @p typesetter = xxx yyy<010>
+00007 00007| <010>
+00008 00008| 2. Test second argument not "=".<010>
+00009 00009| @p typesetter x sloth<010>
+00010 00010| <010>
+00011 00011| 3. Test third argument is not legal.<010>
+00012 00012| @p typesetter = sloth<010>
+00013 00013| <010>
+00014 00014| 4. Test third argument is none.<010>
+00015 00015| @p typesetter = none<010>
+00016 00016| <010>
+00017 00017| 5. Test third argument is tex.<010>
+00018 00018| 6. Test pragma opposes earlier pragma.<010>
+00019 00019| @p typesetter = tex<010>
+00020 00020| <010>
+00021 00021| 7. Test pragma does not oppose earlier pragma.<010>
+00022 00022| @p typesetter = none<010>
+00023 00023| <010>
+00024 00024| <End-Of-File><010>
+-----------+--------------------------------------------------------------------
+Globl Local| Text
+
+============================ End of LINE LIST DUMP =============================
+
+
+=========================== Start of TOKEN LIST DUMP ===========================
+
+Summary: There are 8 tokens in the token list.
+
+Line[Column]: Token Description
+-------------------------------
+
+0001[01]: Text. Text scrap[Grey]="SC29: Test syntax checking of typesetter pragma.<010>
+<010>
+1. Test not three arguments.<010>
+"
+0007[01]: Text. Text scrap[Grey]="<010>
+2. Test second argument not "=".<010>
+"
+0010[01]: Text. Text scrap[Grey]="<010>
+3. Test third argument is not legal.<010>
+"
+0013[01]: Text. Text scrap[Grey]="<010>
+4. Test third argument is none.<010>
+"
+0016[01]: Text. Text scrap[Grey]="<010>
+5. Test third argument is tex.<010>
+6. Test pragma opposes earlier pragma.<010>
+"
+0020[01]: Text. Text scrap[Grey]="<010>
+7. Test pragma does not oppose earlier pragma.<010>
+"
+0023[01]: Text. Text scrap[White]="<010>
+"
+0024[01]: End Of File.
+============================ End of TOKEN LIST DUMP ============================
+
+Macro table dump skipped (Parser was not invoked).
+Document list dump skipped (Parser was not invoked).
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+ 1 1| SC29: Test syntax checking of typesetter pragma.
+ 2 2|
+ 3 3| 1. Test not three arguments.
+ 4 4| @p typesetter
+ Error|.^This typesetter pragma has the wrong number of arguments.
+ |.^The correct format is: "@p typesetter = none|tex"
+ |.^ or for hypertext "@p typesetter = hypertext|html".
+ |.^Pragma ignored.
+ 5 5| @p typesetter =
+ Error|.^This typesetter pragma has the wrong number of arguments.
+ |.^The correct format is: "@p typesetter = none|tex"
+ |.^ or for hypertext "@p typesetter = hypertext|html".
+ |.^Pragma ignored.
+ 6 6| @p typesetter = xxx yyy
+ Error|.^This typesetter pragma has the wrong number of arguments.
+ |.^The correct format is: "@p typesetter = none|tex"
+ |.^ or for hypertext "@p typesetter = hypertext|html".
+ |.^Pragma ignored.
+ 7 7|
+ 8 8| 2. Test second argument not "=".
+ 9 9| @p typesetter x sloth
+ |.^The correct format is: "@p typesetter = none|tex"
+ |.^ or for hypertext "@p typesetter = hypertext|html".
+ |.^Pragma ignored.
+ Error|...............^Expecting "=".
+ 10 10|
+ 11 11| 3. Test third argument is not legal.
+ 12 12| @p typesetter = sloth
+ |.^The correct format is: "@p typesetter = none|tex"
+ |.^ or for hypertext "@p typesetter = hypertext|html".
+ |.^Pragma ignored.
+ Error|.................^Expecting one of:
+ Error|.................^ (i) "none"
+ Error|.................^ (ii) "tex"
+ Error|.................^ (iii) "hypertext"
+ Error|.................^ (iv) "html".
+ 13 13|
+ 14 14| 4. Test third argument is none.
+ 15 15| @p typesetter = none
+ |.^This pragma is opposed by the pragma at line 19.
+ 16 16|
+ 17 17| 5. Test third argument is tex.
+ 18 18| 6. Test pragma opposes earlier pragma.
+ 19 19| @p typesetter = tex
+ Error|.^This pragma opposes the pragma at line 15.
+ |.^You can have as many typesetter pragmas as you like,
+ |.^but they all have to be the same!
+ |.^Pragma ignored.
+ 20 20|
+ 21 21| 7. Test pragma does not oppose earlier pragma.
+ 22 22| @p typesetter = none
+ 23 23|
+ | <End-Of-File>
+------------+-------------------------------------------------------------------
+
+There were 10 Errors.
diff --git a/web/funnelAC/results/tg01.lis b/web/funnelAC/results/tg01.lis
new file mode 100644
index 0000000000..47a43fdf7f
--- /dev/null
+++ b/web/funnelAC/results/tg01.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed .out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/tg01.out b/web/funnelAC/results/tg01.out
new file mode 100644
index 0000000000..148e1e38a0
--- /dev/null
+++ b/web/funnelAC/results/tg01.out
@@ -0,0 +1,3 @@
+Patterson's prayer:
+ "There is nothing I would rather be, than chairman of the ABC."
+ - Les Patterson
diff --git a/web/funnelAC/results/tg02.lis b/web/funnelAC/results/tg02.lis
new file mode 100644
index 0000000000..a9dac774ec
--- /dev/null
+++ b/web/funnelAC/results/tg02.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed tg02.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/tg02.out b/web/funnelAC/results/tg02.out
new file mode 100644
index 0000000000..4f731e9543
--- /dev/null
+++ b/web/funnelAC/results/tg02.out
@@ -0,0 +1,23 @@
+The other day upon the stair,
+I met a man who wasn't there.
+He wasn't there again today,
+I think he's from the CIA.
+
+In the output begin0 should be at the left margin, then begin1 to begin wayout
+should be indented by three spaces. Then the "It's scary" should be
+positioned over the "a" ofd margin. The rest should be at the left margin.
+
+begin0
+ begin1
+ begin2
+ begin3
+ begin4
+ begin wayout----------V
+ It's scary out here
+So far from the left margin.
+end wayout----------^
+end4
+end3
+end2
+end1
+end0
diff --git a/web/funnelAC/results/tg03.lis b/web/funnelAC/results/tg03.lis
new file mode 100644
index 0000000000..346577fb0d
--- /dev/null
+++ b/web/funnelAC/results/tg03.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed tg03.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/tg03.out b/web/funnelAC/results/tg03.out
new file mode 100644
index 0000000000..1d638b1c32
--- /dev/null
+++ b/web/funnelAC/results/tg03.out
@@ -0,0 +1,21 @@
+The other day upon the stair,
+I met a man who wasn't there.
+He wasn't there again today,
+I think he's from the CIA.
+
+The following nest of begin and ends should be indented in a nest.
+
+begin0
+ begin1
+ begin2
+ begin3
+ begin4
+ begin wayout----------V
+ It's scary out here
+ So far from the left margin.
+ end wayout----------^
+ end4
+ end3
+ end2
+ end1
+end0
diff --git a/web/funnelAC/results/tg04.lis b/web/funnelAC/results/tg04.lis
new file mode 100644
index 0000000000..0ffe1aacf9
--- /dev/null
+++ b/web/funnelAC/results/tg04.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed tg04.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/tg04.out b/web/funnelAC/results/tg04.out
new file mode 100644
index 0000000000..e65d9bf4ab
--- /dev/null
+++ b/web/funnelAC/results/tg04.out
@@ -0,0 +1,22 @@
+
+
+1. Test macro call with no parameters.
+"Teapot" =
+"Teapot"
+
+2. Test macro call with one parameter.
+"Left Testing Right" =
+"Left Testing Right"
+
+3. Test macro call with many parameters.
+"Left x Middle y Right" =
+"Left x Middle y Right"
+
+4. Test macro call as a parameter of another macro call.
+"Left Ostrich Middle Left Wombat Right Right" =
+"Left Ostrich Middle Left Wombat Right Right"
+
+5. Test expression recursive macro call.
+"[X[[Walrus]]Y]" =
+"[X[[Walrus]]Y]"
+
diff --git a/web/funnelAC/results/tg05.lis b/web/funnelAC/results/tg05.lis
new file mode 100644
index 0000000000..a9502089a9
--- /dev/null
+++ b/web/funnelAC/results/tg05.lis
@@ -0,0 +1,17 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+E: Product file line is too long (line 4 of "<<Suppressed>>").
+ Product file line length limit is 80 characters.
+ Note: You can change the limit by specifying.
+ @p maximum_output_line_length = <desired length>
+ somewhere in the input file.
+Tangle: Completed tg05.out.
+
+There was 1 Error.
diff --git a/web/funnelAC/results/tg05.out b/web/funnelAC/results/tg05.out
new file mode 100644
index 0000000000..1cc2528cae
--- /dev/null
+++ b/web/funnelAC/results/tg05.out
@@ -0,0 +1,4 @@
+We test the default limit of 80 characters.
+Only the second of the following two lines should provoke an error.
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+123456789012345678901234567890123456789012345678901234567890123456789012345678901
diff --git a/web/funnelAC/results/tg06.lis b/web/funnelAC/results/tg06.lis
new file mode 100644
index 0000000000..749c27a39f
--- /dev/null
+++ b/web/funnelAC/results/tg06.lis
@@ -0,0 +1,17 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+E: Product file line is too long (line 6 of "<<Suppressed>>").
+ Product file line length limit is 60 characters.
+ Note: You can change the limit by specifying.
+ @p maximum_output_line_length = <desired length>
+ somewhere in the input file.
+Tangle: Completed tg06.out.
+
+There was 1 Error.
diff --git a/web/funnelAC/results/tg06.out b/web/funnelAC/results/tg06.out
new file mode 100644
index 0000000000..6d95ce3bf8
--- /dev/null
+++ b/web/funnelAC/results/tg06.out
@@ -0,0 +1,6 @@
+We test the user-set limit of 60 characters.
+Only the third of the following three lines
+should provoke an error.
+ 1 2 3 4 5 6
+123456789012345678901234567890123456789012345678901234567890
+1234567890123456789012345678901234567890123456789012345678901
diff --git a/web/funnelAC/results/tg07.lis b/web/funnelAC/results/tg07.lis
new file mode 100644
index 0000000000..d6bcf21b41
--- /dev/null
+++ b/web/funnelAC/results/tg07.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed tg07.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/tg07.out b/web/funnelAC/results/tg07.out
new file mode 100644
index 0000000000..113b1fac7b
--- /dev/null
+++ b/web/funnelAC/results/tg07.out
@@ -0,0 +1,2 @@
+The following long line should not blow the line length limit.
+12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
diff --git a/web/funnelAC/results/tg08.lis b/web/funnelAC/results/tg08.lis
new file mode 100644
index 0000000000..a3d0140430
--- /dev/null
+++ b/web/funnelAC/results/tg08.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed tg08.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/tg08.out b/web/funnelAC/results/tg08.out
new file mode 100644
index 0000000000..aab49f17ad
--- /dev/null
+++ b/web/funnelAC/results/tg08.out
@@ -0,0 +1,7 @@
+Is this a mouse I see before me?
+Its contours moulded for my hand?
+Come, let me clutch thee!
+
+Now might I drink hot jolt cola
+And create hacks in C
+That would not bear witness of the Sun.
diff --git a/web/funnelAC/results/tg09.lis b/web/funnelAC/results/tg09.lis
new file mode 100644
index 0000000000..f8c0868d36
--- /dev/null
+++ b/web/funnelAC/results/tg09.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Tangle: Completed tg09.out.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/tg09.out b/web/funnelAC/results/tg09.out
new file mode 100644
index 0000000000..64d7ff5028
--- /dev/null
+++ b/web/funnelAC/results/tg09.out
@@ -0,0 +1,23 @@
+A Megastar's Mantras
+--------------------
+(Things that Mean a Lot to Me)
+
+A is for Australia
+The land I adore;
+It's so spotless and clean
+You can eat off the floor.
+
+B is for Boomerang,
+Which our quaint Abos launch
+In the hope it will bring back
+A roast quokka's haunch.
+
+C is for Culture
+Which blossoms unchecked,
+You can't move in my homeland
+for Beckett and Brecht.
+
+...more...
+
+- Dame Edna Everage,
+"Neglected Poems and Other Creatures" by Barry Humphries, 1991.
diff --git a/web/funnelAC/results/wv01.lis b/web/funnelAC/results/wv01.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/results/wv01.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/wv01.tex b/web/funnelAC/results/wv01.tex
new file mode 100644
index 0000000000..83e0d3a42a
--- /dev/null
+++ b/web/funnelAC/results/wv01.tex
@@ -0,0 +1,367 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+WV01: Test basic typeset file output mechanism.
+
+\fwseca{1}{A section for no particular reason}
+
+\fwbeginmacro
+\fwfilename{wv01.out}{1}\fwequals \fwodef \fwbtx[Some text for no particular reason.
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/results/wv02.lis b/web/funnelAC/results/wv02.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/results/wv02.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/wv02.tex b/web/funnelAC/results/wv02.tex
new file mode 100644
index 0000000000..aab813ee0f
--- /dev/null
+++ b/web/funnelAC/results/wv02.tex
@@ -0,0 +1,454 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+WV05: Test typesetting features.
+
+\fwbeginmacro
+\fwfilename{wv05.out}{1}\fwequals \fwodef \fwbtx[
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+
+1. Test all five levels of headings with explicit titles.
+
+\fwseca{1}{One}
+\fwsecb{1.1}{Two}
+\fwsecc{1.1.1}{Three}
+\fwsecd{1.1.1.1}{Four}
+\fwsece{1.1.1.1.1}{Five}
+
+2. Test all five levels of headings with implicit titles.
+
+\fwseca{2}{Macro at level one}
+\fwbeginmacro
+\fwmacroname{Macro at level one}{2}\fwzero{}\fwequals \fwodef \fwbtx[Sloth]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsecb{2.1}{Macro at level two}
+\fwbeginmacro
+\fwmacroname{Macro at level two}{3}\fwzero{}\fwequals \fwodef \fwbtx[Walrus]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsecc{2.1.1}{Macro at level three}
+\fwbeginmacro
+\fwmacroname{Macro at level three}{4}\fwzero{}\fwequals \fwodef \fwbtx[Aardvark]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsecd{2.1.1.1}{Macro at level four}
+\fwbeginmacro
+\fwmacroname{Macro at level four}{5}\fwzero{}\fwequals \fwodef \fwbtx[Teapot]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwsece{2.1.1.1.1}{Macro at level five}
+\fwbeginmacro
+\fwmacroname{Macro at level five}{6}\fwzero{}\fwequals \fwodef \fwbtx[Emu]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+3. Test the table of contents directive.
+
+\fwtocstart{}
+\fwtoca{1}{One}
+\fwtocb{1.1}{Two}
+\fwtocc{1.1.1}{Three}
+\fwtocd{1.1.1.1}{Four}
+\fwtoce{1.1.1.1.1}{Five}
+\fwtoca{2}{Macro at level one}
+\fwtocb{2.1}{Macro at level two}
+\fwtocc{2.1.1}{Macro at level three}
+\fwtocd{2.1.1.1}{Macro at level four}
+\fwtoce{2.1.1.1.1}{Macro at level five}
+\fwtocfinish{}
+
+
+4. Test the newpage directive.
+
+\fwnewpage
+
+
+5. Test the vskip directive.
+\fwvskip{50}
+
+6. Test the title directive.
+\fwcenterline{\fwfonttitle{This is a test Title}}
+
+
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/results/wv03.lis b/web/funnelAC/results/wv03.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/results/wv03.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/wv03.tex b/web/funnelAC/results/wv03.tex
new file mode 100644
index 0000000000..f9d5bda6cd
--- /dev/null
+++ b/web/funnelAC/results/wv03.tex
@@ -0,0 +1,568 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+WV03: Test the typesetting of various kinds of macros.
+
+First create an output file to keep the analyser happy.
+\fwbeginmacro
+\fwfilename{wv03.out}{1}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+
+1. Test macro never used.
+\fwbeginmacro
+\fwmacroname{Never Used}{2}\fwzero{}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+2. Test a macro used once.
+\fwbeginmacro
+\fwmacroname{Used Once}{3}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is invoked in definition 7.}
+\fwendmacronotes
+\fwendmacro
+
+
+3. Test a macro used twice.
+\fwbeginmacro
+\fwmacroname{Used Twice}{4}\fwmany{}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is invoked in definitions 7 and 8.}
+\fwendmacronotes
+\fwendmacro
+
+
+4. Test a macro used three times.
+\fwbeginmacro
+\fwmacroname{Used Thrice}{5}\fwmany{}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is invoked in definitions 7, 8, and 9.}
+\fwendmacronotes
+\fwendmacro
+
+
+5. Test a macro used five times.
+\fwbeginmacro
+\fwmacroname{Used Quice}{6}\fwmany{}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is invoked in definitions 7, 8, 9, 10, and 11.}
+\fwendmacronotes
+\fwendmacro
+
+
+Here is the macro that does all the calling for the above.
+\fwbeginmacro
+\fwmacroname{Dummy1}{7}\fwzero{}\fwequals \fwodef \fwmacroname{Used Once}{3}\fwbtx[
+]fwetx=%
+\fwmacroname{Used Twice}{4}\fwbtx[
+]fwetx=%
+\fwmacroname{Used Thrice}{5}\fwbtx[
+]fwetx=%
+\fwmacroname{Used Quice}{6}\fwbtx[
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwbeginmacro
+\fwmacroname{Dummy2}{8}\fwzero{}\fwequals \fwodef \fwmacroname{Used Twice}{4}\fwbtx[
+]fwetx=%
+\fwmacroname{Used Thrice}{5}\fwbtx[
+]fwetx=%
+\fwmacroname{Used Quice}{6}\fwbtx[
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwbeginmacro
+\fwmacroname{Dummy3}{9}\fwzero{}\fwequals \fwodef \fwmacroname{Used Thrice}{5}\fwbtx[
+]fwetx=%
+\fwmacroname{Used Quice}{6}\fwbtx[
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwbeginmacro
+\fwmacroname{Dummy4}{10}\fwzero{}\fwequals \fwodef \fwmacroname{Used Quice}{6}\fwbtx[
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+\fwbeginmacro
+\fwmacroname{Dummy5}{11}\fwzero{}\fwequals \fwodef \fwmacroname{Used Quice}{6}\fwbtx[
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+6. Test a macro with two body parts.
+\fwbeginmacro
+\fwmacroname{Two body parts}{12}\fwzero{}\fwplusequals \fwodef \fwbtx[Sloth]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 12 and 13.}
+\fwusedin{This macro is invoked in definition 21.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Two body parts}{13}\fwzero{}\fwplusequals \fwodef \fwbtx[Walrus]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 12 and 13.}
+\fwusedin{This macro is invoked in definition 21.}
+\fwendmacronotes
+\fwendmacro
+
+
+7. Test a macro with three body parts.
+\fwbeginmacro
+\fwmacroname{Three body parts}{14}\fwzero{}\fwplusequals \fwodef \fwbtx[Sloth]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 14, 15, and 16.}
+\fwusedin{This macro is invoked in definition 19.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Three body parts}{15}\fwzero{}\fwplusequals \fwodef \fwbtx[Walrus]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 14, 15, and 16.}
+\fwusedin{This macro is invoked in definition 19.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Three body parts}{16}\fwzero{}\fwplusequals \fwodef \fwbtx[Aardvaark]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 14, 15, and 16.}
+\fwusedin{This macro is invoked in definition 19.}
+\fwendmacronotes
+\fwendmacro
+
+
+8. Test a macro with five body parts.
+\fwbeginmacro
+\fwmacroname{Five body parts}{17}\fwzero{}\fwplusequals \fwodef \fwbtx[Sloth]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 17, 18, 19, 20, and 21.}
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Five body parts}{18}\fwzero{}\fwplusequals \fwodef \fwbtx[Walrus]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 17, 18, 19, 20, and 21.}
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Five body parts}{19}\fwzero{}\fwplusequals \fwodef \fwmacroname{Three body parts}{14}\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 17, 18, 19, 20, and 21.}
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Five body parts}{20}\fwzero{}\fwplusequals \fwodef \fwbtx[Aardvaark]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 17, 18, 19, 20, and 21.}
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{Five body parts}{21}\fwzero{}\fwplusequals \fwodef \fwmacroname{Two body parts}{12}\fwcdef
+\fwbeginmacronotes
+\fwseealso{This macro is defined in definitions 17, 18, 19, 20, and 21.}
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/results/wv04.lis b/web/funnelAC/results/wv04.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/results/wv04.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/wv04.tex b/web/funnelAC/results/wv04.tex
new file mode 100644
index 0000000000..f60d8158a3
--- /dev/null
+++ b/web/funnelAC/results/wv04.tex
@@ -0,0 +1,397 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+WV04: Test ugly string processing.
+
+\fwbeginmacro
+\fwfilename{wv04.out}{1}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+
+1. Test ugly string in section name.
+\fwseca{1}{ !\char`\"\#\$\%'()*+,-./0123456789:;$<$=$>$?}
+\fwseca{2}{ABCDEFGHIJKLMNOPQRSTUVWXYZ[$\backslash$]\char`\^\_`}
+\fwseca{3}{abcdefghijklmnopqrstuvwxyz$\{$$|$$\}$\char`\~}
+
+2. Test ugly string in macro name.
+\fwbeginmacro
+\fwmacroname{ !\char`\"\#\$\%'()*+,-./0123456789:;$<$=$>$?}{2}\fwzero{}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{ABCDEFGHIJKLMNOPQRSTUVWXYZ[$\backslash$]\char`\^\_`}{3}\fwzero{}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+\fwbeginmacro
+\fwmacroname{abcdefghijklmnopqrstuvwxyz$\{$$|$$\}$\char`\~}{4}\fwzero{}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwusedin{This macro is NEVER invoked.}
+\fwendmacronotes
+\fwendmacro
+
+
+3. Test ugly string in literal section.
+\fwlit{ !\char`\"\#\$\%'()*+,-./0123456789:;\char`\<=\char`\>?}
+\fwlit{ABCDEFGHIJKLMNOPQRSTUVWXYZ[\char`\\]\char`\^\_`}
+\fwlit{abcdefghijklmnopqrstuvwxyz\char`\{\char`\|\char`\}\char`\~}
+
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/results/wv05.lis b/web/funnelAC/results/wv05.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/results/wv05.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/wv05.tex b/web/funnelAC/results/wv05.tex
new file mode 100644
index 0000000000..833907b66e
--- /dev/null
+++ b/web/funnelAC/results/wv05.tex
@@ -0,0 +1,442 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+WV05: Test processing of ugly strings as ordinary and protected text
+with no typesetter set.
+
+\fwbeginmacro
+\fwfilename{wv05.out}{1}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+
+A paragraph in ordinary mode.
+
+33 con!text
+34 con\char`\"text
+35 con\#text
+36 con\$text
+37 con\%text
+38 con\&text
+39 con'text
+40 con(text
+41 con)text
+42 con*text
+43 con+text
+44 con,text
+45 con-text
+46 con.text
+47 con/text
+48-57 con0123456789text
+58 con:text
+59 con;text
+60 con$<$text
+61 con=text
+62 con$>$text
+63 con?text
+64 con@text
+65-90 conABCDEFGHIJKLMNOPQRSTUVWXYZtext
+91 con[text
+92 con$\backslash$text
+93 con]text
+94 con\char`\^text
+95 con\_text
+96 con`text
+97-122 conabcdefghijklmnopqrstuvwxyztext
+123 con$\{$text
+124 con$|$text
+125 con$\}$text
+126 con\char`\~text
+
+Now again, but this time inside protective braces.
+
+\fwlit{
+33 con!text
+34 con\char`\"text
+35 con\#text
+36 con\$text
+37 con\%text
+38 con\&text
+39 con'text
+40 con(text
+41 con)text
+42 con*text
+43 con+text
+44 con,text
+45 con-text
+46 con.text
+47 con/text
+48-57 con0123456789text
+58 con:text
+59 con;text
+60 con\char`\<text
+61 con=text
+62 con\char`\>text
+63 con?text
+64 con@text
+65-90 conABCDEFGHIJKLMNOPQRSTUVWXYZtext
+91 con[text
+92 con\char`\\text
+93 con]text
+94 con\char`\^text
+95 con\_text
+96 con`text
+97-122 conabcdefghijklmnopqrstuvwxyztext
+123 con\char`\{text
+124 con\char`\|text
+125 con\char`\}text
+126 con\char`\~text
+}
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/results/wv06.lis b/web/funnelAC/results/wv06.lis
new file mode 100644
index 0000000000..342bdb414d
--- /dev/null
+++ b/web/funnelAC/results/wv06.lis
@@ -0,0 +1,12 @@
+FUNNELWEB LISTING FILE
+======================
+
+
+Global Local| Input File
+------------+-------------------------------------------------------------------
+.................
+------------+-------------------------------------------------------------------
+
+Weave: Completed <<Suppressed>>.
+
+SUCCESS: No diagnostics.
diff --git a/web/funnelAC/results/wv06.tex b/web/funnelAC/results/wv06.tex
new file mode 100644
index 0000000000..e2626dbb69
--- /dev/null
+++ b/web/funnelAC/results/wv06.tex
@@ -0,0 +1,443 @@
+
+%*******************************************************************************
+%* START OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+%* *
+%* This TeX file was automatically generated by the FunnelWeb preprocessor. *
+%* You can typeset this file to produce printed documentation by running it *
+%* through the TeX typesetter using a command such as: *
+%* tex thisfilename *
+%* The resultant file thisfilename.dvi can be printed using a command such as: *
+%* lpr -Pcslw -d thisfilename.dvi *
+%* *
+%* FunnelWeb is a preprocessor that allows programmers to weave programs and *
+%* their documentation together in a single document. The FunnelWeb program *
+%* analyses such documents producing both program files and typeset *
+%* documentation such as this TeX file. *
+%* FunnelWeb was created by Ross Williams. *
+%* *
+%* For more information on FunnelWeb look in the following FTP archive: *
+%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *
+%* Directory: ~pub/funnelweb/ *
+%* (or some other appropriately named directory). *
+%* or email Ross Williams at ross@spam.adelaide.edu.au *
+%* *
+%*******************************************************************************
+
+
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
+WV06: Test processing of ugly strings as ordinary and protected text
+with typesetter = tex.
+
+
+\fwbeginmacro
+\fwfilename{wv06.out}{1}\fwequals \fwodef \fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+
+A paragraph in ordinary mode.
+
+33 con!text
+34 con"text
+35 con#text
+36 con$text
+37 con%text
+38 con&text
+39 con'text
+40 con(text
+41 con)text
+42 con*text
+43 con+text
+44 con,text
+45 con-text
+46 con.text
+47 con/text
+48-57 con0123456789text
+58 con:text
+59 con;text
+60 con<text
+61 con=text
+62 con>text
+63 con?text
+64 con@text
+65-90 conABCDEFGHIJKLMNOPQRSTUVWXYZtext
+91 con[text
+92 con\text
+93 con]text
+94 con^text
+95 con_text
+96 con`text
+97-122 conabcdefghijklmnopqrstuvwxyztext
+123 con{text
+124 con|text
+125 con}text
+126 con~text
+
+Now again, but this time inside protective braces.
+
+\fwlit{
+33 con!text
+34 con\char`\"text
+35 con\#text
+36 con\$text
+37 con\%text
+38 con\&text
+39 con'text
+40 con(text
+41 con)text
+42 con*text
+43 con+text
+44 con,text
+45 con-text
+46 con.text
+47 con/text
+48-57 con0123456789text
+58 con:text
+59 con;text
+60 con\char`\<text
+61 con=text
+62 con\char`\>text
+63 con?text
+64 con@text
+65-90 conABCDEFGHIJKLMNOPQRSTUVWXYZtext
+91 con[text
+92 con\char`\\text
+93 con]text
+94 con\char`\^text
+95 con\_text
+96 con`text
+97-122 conabcdefghijklmnopqrstuvwxyztext
+123 con\char`\{text
+124 con\char`\|text
+125 con\char`\}text
+126 con\char`\~text
+}
+\bye
+
+
+%*******************************************************************************
+%* END OF AUTOMATICALLY GENERATED TEX FILE *
+%*******************************************************************************
+
diff --git a/web/funnelAC/scripts/0license.txt b/web/funnelAC/scripts/0license.txt
new file mode 100644
index 0000000000..8c2fba8bec
--- /dev/null
+++ b/web/funnelAC/scripts/0license.txt
@@ -0,0 +1,37 @@
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+The files in this directory are:
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+###############################################################################
+
diff --git a/web/funnelAC/scripts/master.fws b/web/funnelAC/scripts/master.fws
new file mode 100644
index 0000000000..2267c3492a
--- /dev/null
+++ b/web/funnelAC/scripts/master.fws
@@ -0,0 +1,295 @@
+!============================<Start of Master Script>===========================
+!
+! FUNNELWEB MASTER TEST SCRIPT
+! ============================
+! This is the master FunnelWeb test script.
+! To test FunnelWeb:
+! 1. Create the following directory tree:
+! <anyname>
+! scripts - A directory containing .fws scripts.
+! tests - A directory containing .fw test files.
+! results - An empty directory to receive results of testing.
+! answers - A directory containing the correct answers.
+! 2. Modify the "root test directory" section of this script as described.
+! 3. Ensure that all of the directories and files are on Read/Write access.
+! 4. Set default to the "scripts" directory.
+! 5. Invoke FunnelWeb with the "+k" option.
+! 6. Give the command "execute master.fws".
+! 7. The test should last for a few minutes.
+! 8. Read the test summary on the console at the end of the test.
+!
+! Notes on Script Mechanics
+! -------------------------
+! * FunnelWeb predefines "$/" to be the character that separates
+! directory specifications from file names on whatever machine it is
+! running on. (e.g. Mac=":", Sun="/", Vax="]", PC="\").
+
+write ""
+write "FUNNELWEB TEST SCRIPT"
+write "====================="
+write "This FunnelWeb shellscript applies FunnelWeb to a suite of test files."
+write "The result is a differences report comparing the result files of this"
+write "run with a predefined set of correct "answer" files."
+write ""
+write "Do not be alarmed by errors occurring during the testing as these"
+write "are a consequence of tests of FunnelWeb's detection of various errors."
+write ""
+write "This script cleans up files lying around before testing, so if"
+write "it fails for some reason, you can run it again without having."
+write "to worry about cleaning up after the results of the previous run."
+write ""
+write "This script takes about 10 minutes to run on a 1 MIP machine."
+write "Here we go!"
+write ""
+!
+! Define Symbol For The Root Test Directory
+! -----------------------------------------
+! IMPORTANT: THIS DEFINITION IS ALL YOU HAVE TO CHANGE TO GET THIS
+! SCRIPT WORKING ON YOUR MACHINE.
+! The script substitution variable <dollar>R must point to the root
+! directory <anyname> (see above). Here are some examples of definitions
+! of <dollar>R on various machines onto which FunnelWeb has been ported.
+
+!SUN: define R "/usr2/users/ross/fwdir/"
+!VMS: define R "$$USERS:[ROSS.FWDIR."
+!PC : define R "\fwdir\"
+!Mac: define R "fatdisk:fwdir:"
+!AXP: define R "/usrdsk/user/coates/tmp/funnelweb/"
+!OS2: define R "E:\sources\funnelweb\"
+
+! Place your definition here.
+
+define R "/usr/var/tmp/funnelweb/"
+
+! Define Symbols for Test Directories
+! -----------------------------------
+! S - The directory containing the .fws FunnelWeb test scripts.
+! I - The directory containing the .fw input files.
+! O - The directory where all the test output goes.
+! A - The directory containing all the correct answers.
+! D - The differences file.
+define S "$Rscripts$/"
+define I "$Rtests$/"
+define O "$Rresults$/"
+define A "$Ranswers$/"
+define D "$Rresults$/0testres.dif"
+
+! Set FunnelWeb Options Default
+! -----------------------------
+! The following options remain as default for all the runs.
+! The only two options turned on are +c100 and +b7.
+! The sub-scripts turn on the options they need explicitly.
+! -f No input file specified.
+! -j No journal file.
+! =i..Include files come from the input directory.
+! -o No product file(s).
+! -t No typeset file.
+! -l No Listing file.
+! -d No deletion of output files.
+! +c100 No suppression of listing in listing file.
+! -q Messages to screen.
+! -x No default script file to execute.
+! -w No limit on product file line length imposed by command line.
+! -k No interactive mode.
+! -b1 No dump of input file map.
+! -b2 No dump of line list.
+! -b3 No dump of token list.
+! -b4 No dump of macro table.
+! -b5 No dump of document list.
+! -b6 No dump of timing results.
+! +b7 DONT write anything non-deterministic.
+set -f -j =i$I -o -t -l -d +c100 -q -x -w -k -b123456 +b7
+
+! Delete any Old Differences File
+! -------------------------------
+eneo $D
+
+! Zero the Difference Summary Counters
+! ------------------------------------
+! This is necessary in case the user runs this script twice in one session.
+diffzero
+
+! Clean Test Scripts
+! ------------------
+! When text files are copied from one machine to another, they can sometimes
+! end up with end-of-line characters that are incorrect for the target machine.
+! The following commands clean up the sub-scripts that we are about to invoke.
+fixeols $Stest_ld.fws
+fixeols $Stest_l.fws
+fixeols $Stest_lo.fws
+fixeols $Stest_lt.fws
+fixeols $Stest_lot.fws
+fixeols $Stest_lo2.fws
+
+! Generate Tricky Test Files
+! --------------------------
+! This process is a bit messy and requires operations similar to those in the
+! other sub-scripts (test_ld.fws...), and so I have placed it all in
+! test_gen.fws.
+execute $Stest_gen.fws
+
+! Clean up the Include Files
+! --------------------------
+! The test scripts all "purify" their file arguments by running them through
+! the "fixeols" command. However, the include files aren't automated in this
+! way, so we have to do them here explicitly.
+fixeols $Isc13a.fwi
+fixeols $Isc13b.fwi
+fixeols $Isc13c.fwi
+fixeols $Isc13d.fwi
+fixeols $Isc13e.fwi
+fixeols $Isc13f.fwi
+fixeols $Isc15a.fwi
+fixeols $Itg08a.fwi
+fixeols $Iex09a.fwi
+fixeols $Iex10a.fwi
+
+! Skip Some Tests
+! ---------------
+! If you are debugging some tests, you may wish to move the "here" command
+! further down in the testing so as to skip to the desired tests.
+! X must be defined because FunnelWeb expands command lines even while skipping
+! and generates a "leading spaces" error if X is not defined to be non-blank.
+define X "!"
+skipto
+here
+
+! Test Scanner and Parser
+! -----------------------
+define X "execute $Stest_ld.fws"
+! Special cases:
+! sc01 does not exist (test of non-existence input file).
+! sc09 contains control characters that we don't want FIXEOLS to frob.
+$X sc01 !
+$X sc02
+$X sc03
+$X sc04
+$X sc05
+$X sc06
+$X sc07
+$X sc08
+$X sc09 !
+$X sc10
+$X sc11
+$X sc12
+$X sc13
+$X sc14
+$X sc15
+$X sc16
+$X sc17
+$X sc18
+$X sc19
+$X sc20
+$X sc21
+$X sc22
+$X sc23
+$X sc24
+$X sc25
+$X sc26
+$X sc27
+$X sc28
+$X sc29
+
+$X pr01
+$X pr02
+$X pr03
+$X pr04
+$X pr05
+$X pr06
+$X pr07
+$X pr08
+$X pr09
+$X pr10
+
+! Test Analyser
+! -------------
+define X "execute $Stest_l.fws"
+$X an01
+$X an02
+$X an03
+$X an04
+
+! Test Tangle
+! -----------
+define X "execute $Stest_lo.fws"
+$X tg01
+$X tg02
+$X tg03
+$X tg04
+$X tg05
+$X tg06
+$X tg07
+$X tg08
+$X tg09
+
+! Test Weave
+! ----------
+define X "execute $Stest_lt.fws"
+$X wv01
+$X wv02
+$X wv03
+$X wv04
+$X wv05
+$X wv06
+
+! Examples in User Manual Tutorial
+! --------------------------------
+define X "execute $Stest_lo.fws"
+$X ex01
+$X ex02
+define X "execute $Stest_l.fws"
+$X ex03
+define X "execute $Stest_lo.fws"
+$X ex04
+$X ex05
+$X ex06
+$X ex07
+$X ex08
+$X ex09
+$X ex10
+
+define X "execute $Stest_lt.fws"
+$X ex11
+$X ex12
+$X ex13
+$X ex14
+$X ex15
+
+define X "execute $Stest_lot.fws"
+$X ex16
+
+! Examples in Hints Chapter
+! -------------------------
+define X "execute $Stest_lo.fws"
+$X hi01
+$X hi02
+$X hi03
+$X hi04
+$X hi05
+define X "execute $Stest_lo2.fws"
+$X hi06
+$X hi07
+define X "execute $Stest_lo.fws"
+$X hi08
+$X hi09
+$X hi10
+
+! Final Test Summary
+! ------------------
+write ""
+write ""
+write "The FunnelWeb test suite script has successfully completed."
+write ""
+diffsummary
+write ""
+write "If the differences summary above gives Different=0, then FunnelWeb"
+write "has passed the test suite and is ready for use."
+write ""
+write "If not, you should examine the file"
+write " "$D""
+write "to see what went wrong."
+write ""
+write "By the way, there should be 1 Severe, 277 Errors, and 12 Warnings."
+write ""
+!=============================<End of Master Script>============================
+
diff --git a/web/funnelAC/scripts/test_gen.fws b/web/funnelAC/scripts/test_gen.fws
new file mode 100644
index 0000000000..6b938e763c
--- /dev/null
+++ b/web/funnelAC/scripts/test_gen.fws
@@ -0,0 +1,58 @@
+!==========================<Start of test_gen Script>===========================
+!
+! Generate Tricky Input Files
+! ---------------------------
+! This script processes the "generate.fw" test file which not only tests
+! FunnelWeb to some extent, but also generates a few ".fw" input test
+! files which are tested later on in the test suite process.
+!
+! Inputs: None.
+! Outputs:
+! Listing file.
+! Product files (which appear in the input $I directory as .fw files).
+! Appendage to differences file.
+
+! Announce this test.
+write ""
+write ""
+writeu "Basic Test and Generate Some Tricky Input Files"
+
+! Delete any previous output files.
+eneo $Isc06.fw
+eneo $Isc08.fw
+eneo $Isc09.fw
+eneo $Isc13e.fwi
+eneo $Ogenerate.log
+eneo $Ogenerate.lis
+eneo $Ogenerate.tex
+eneo $Ogenerate.out
+
+! Check input and answer files.
+exists $Igenerate.fw
+exists $Agenerate.lis
+absent $Agenerate.out
+absent $Agenerate.tex
+
+! Clean input and answer files.
+fixeols $Igenerate.fw
+fixeols $Agenerate.lis
+
+! Perform the actual FunnelWeb run.
+fw $Igenerate.fw +L$Ogenerate.lis +O$I
+
+! Ensure that the correct files were generated.
+absent $Ogenerate.log
+absent $Ogenerate.tex
+absent $Ogenerate.out
+exists $Ogenerate.lis
+exists $Isc06.fw
+exists $Isc08.fw
+exists $Isc09.fw
+exists $Isc13e.fwi
+
+! Compare the listing file with the correct answer.
+! We can't check the other files because of the original problem this whole
+! generation script is designed to solve!
+diff $Ogenerate.lis $Agenerate.lis $D
+
+!===========================<End of test_gen Script>============================
diff --git a/web/funnelAC/scripts/test_l.fws b/web/funnelAC/scripts/test_l.fws
new file mode 100644
index 0000000000..fe88166d53
--- /dev/null
+++ b/web/funnelAC/scripts/test_l.fws
@@ -0,0 +1,50 @@
+!===========================<Start of test_l Script>============================
+!
+! Test With A Plain Listing File
+! ------------------------------
+! Inputs:
+! $1 = Name of the .fw file to be tested (e.g. $1="sc01").
+! $I = Directory containing .fw files.
+! $A = Directory containing Answer files.
+! $O = Directory to place Result files.
+! $D = Name of the differences file.
+! Outputs:
+! Listing file.
+! Appendage to differences file.
+
+! Announce this test.
+write ""
+write ""
+writeu "Performing Test $1"
+
+! Delete any previous output files.
+eneo $O$1.log
+eneo $O$1.lis
+eneo $O$1.tex
+eneo $O$1.out
+
+! Check input and answer files.
+exists $I$1.fw
+exists $A$1.lis
+absent $A$1.out
+absent $A$1.tex
+
+! Clean input and answer files.
+fixeols $I$1.fw
+fixeols $A$1.lis
+
+! Perform the actual FunnelWeb run.
+! Tolerate means "don't abort on warning, error, or severe".
+tolerate
+fw $I$1.fw +l$O$1.lis
+
+! Ensure that only a listing file was generated.
+absent $O$1.log
+absent $O$1.tex
+absent $O$1.out
+exists $O$1.lis
+
+! Compare the listing file with the answer file.
+diff $O$1.lis $A$1.lis $D
+
+!============================<End of Test_l Script>=============================
diff --git a/web/funnelAC/scripts/test_ld.fws b/web/funnelAC/scripts/test_ld.fws
new file mode 100644
index 0000000000..4cfc4db857
--- /dev/null
+++ b/web/funnelAC/scripts/test_ld.fws
@@ -0,0 +1,58 @@
+!===========================<Start of test_ld Script>===========================
+!
+! Test With Listing File and Scanner Dumps
+! ----------------------------------------
+! Inputs:
+! $1 = Name of the .fw file to be tested (e.g. $1="sc01").
+! $2 = Empty ("") or "!" to suppress FIXEOLing and existence check
+! of input file.
+! $I = Directory containing .fw files.
+! $A = Directory containing Answer files.
+! $O = Directory to place Result files.
+! $D = Name of the differences file.
+! Outputs:
+! Listing file containing dumps.
+! Appendage to differences file.
+
+! Announce this test.
+write ""
+write ""
+writeu "Performing Test $1"
+
+! Delete any previous output files.
+eneo $O$1.log
+eneo $O$1.lis
+eneo $O$1.tex
+eneo $O$1.out
+
+! Check input and answer files.
+$2exists $I$1.fw
+exists $A$1.lis
+absent $A$1.out
+absent $A$1.tex
+
+! Clean input and answer files.
+$2fixeols $I$1.fw
+fixeols $A$1.lis
+
+! Perform the actual FunnelWeb run.
+! Tolerate means "don't abort on warning, error, or severe".
+! Options:
+! +b1 Dump input file map.
+! +b2 Dump line list.
+! +b3 Dump token list.
+! +b4 Dump macro table.
+! +b5 Dump document list.
+tolerate
+fw $I$1.fw +l$O$1.lis +b12345
+
+! Ensure that only a listing file was generated.
+absent $O$1.log
+absent $O$1.tex
+absent $O$1.out
+exists $O$1.lis
+
+! Compare the listing file with the answer file.
+diff $O$1.lis $A$1.lis $D
+
+!============================<End of test_ld Script>============================
diff --git a/web/funnelAC/scripts/test_lo.fws b/web/funnelAC/scripts/test_lo.fws
new file mode 100644
index 0000000000..572a12e556
--- /dev/null
+++ b/web/funnelAC/scripts/test_lo.fws
@@ -0,0 +1,53 @@
+!===========================<Start of test_lo Script>===========================
+!
+! Test With Listing File and Product File
+! ---------------------------------------
+! Inputs:
+! $1 = Name of the .fw file to be tested (e.g. $1="sc01").
+! $I = Directory containing .fw files.
+! $A = Directory containing Answer files.
+! $O = Directory to place Result files.
+! $D = Name of the differences file.
+! Outputs:
+! Listing file.
+! Product file.
+! Appendage to differences file.
+
+! Announce this test.
+write ""
+write ""
+writeu "Performing Test $1"
+
+! Delete any previous output files.
+eneo $O$1.log
+eneo $O$1.lis
+eneo $O$1.tex
+eneo $O$1.out
+
+! Check input and answer files.
+exists $I$1.fw
+exists $A$1.lis
+exists $A$1.out
+absent $A$1.tex
+
+! Clean input and answer files.
+fixeols $I$1.fw
+fixeols $A$1.lis
+fixeols $A$1.out
+
+! Perform the actual FunnelWeb run.
+! Tolerate means "don't abort on warning, error, or severe".
+tolerate
+fw $I$1.fw +l$O$1.lis +o$O$1.out
+
+! Ensure that only a listing and an product file were generated.
+absent $O$1.log
+absent $O$1.tex
+exists $O$1.lis
+exists $O$1.out
+
+! Compare the results with the answers.
+diff $O$1.lis $A$1.lis $D
+diff $O$1.out $A$1.out $D
+
+!============================<End of test_lo Script>============================
diff --git a/web/funnelAC/scripts/test_lo2.fws b/web/funnelAC/scripts/test_lo2.fws
new file mode 100644
index 0000000000..798c489680
--- /dev/null
+++ b/web/funnelAC/scripts/test_lo2.fws
@@ -0,0 +1,59 @@
+!===========================<Start of test_lo2 Script>==========================
+!
+! Test With Listing File and Two Product Files
+! --------------------------------------------
+! Inputs:
+! $1 = Name of the .fw file to be tested (e.g. $1="sc01").
+! $I = Directory containing .fw files.
+! $A = Directory containing Answer files.
+! $O = Directory to place Result files.
+! $D = Name of the differences file.
+! Outputs:
+! Listing file.
+! Product file a.
+! Product file b.
+! Appendage to differences file.
+
+! Announce this test.
+write ""
+write ""
+writeu "Performing Test $1"
+
+! Delete any previous output files.
+eneo $O$1.log
+eneo $O$1.lis
+eneo $O$1.tex
+eneo $O$1a.out
+eneo $O$1b.out
+
+! Check input and answer files.
+exists $I$1.fw
+exists $A$1.lis
+exists $A$1a.out
+exists $A$1b.out
+absent $A$1.tex
+
+! Clean input and answer files.
+fixeols $I$1.fw
+fixeols $A$1.lis
+fixeols $A$1a.out
+fixeols $A$1b.out
+
+! Perform the actual FunnelWeb run.
+! Tolerate means "don't abort on warning, error, or severe".
+tolerate
+fw $I$1.fw +l$O$1.lis +o$O$1.out
+
+! Ensure that only a listing and two product files were generated.
+absent $O$1.log
+absent $O$1.tex
+exists $O$1.lis
+exists $O$1a.out
+exists $O$1b.out
+
+! Compare the results with the answers.
+diff $O$1.lis $A$1.lis $D
+diff $O$1a.out $A$1a.out $D
+diff $O$1b.out $A$1b.out $D
+
+!============================<End of test_lo2 Script>===========================
diff --git a/web/funnelAC/scripts/test_lot.fws b/web/funnelAC/scripts/test_lot.fws
new file mode 100644
index 0000000000..fbbe4ec22d
--- /dev/null
+++ b/web/funnelAC/scripts/test_lot.fws
@@ -0,0 +1,56 @@
+!==========================<Start of test_lot Script>===========================
+!
+! Test With Listing File and Product File and Typeset File
+! --------------------------------------------------------
+! Inputs:
+! $1 = Name of the .fw file to be tested (e.g. $1="sc01").
+! $I = Directory containing .fw files.
+! $A = Directory containing Answer files.
+! $O = Directory to place Result files.
+! $D = Name of the differences file.
+! Outputs:
+! Listing file.
+! Product file.
+! Typeset file.
+! Appendage to differences file.
+
+! Announce this test.
+write ""
+write ""
+writeu "Performing Test $1"
+
+! Delete any previous output files.
+eneo $O$1.log
+eneo $O$1.lis
+eneo $O$1.tex
+eneo $O$1.out
+
+! Check input and answer files.
+exists $I$1.fw
+exists $A$1.lis
+exists $A$1.tex
+exists $A$1.out
+
+! Clean input and answer files.
+fixeols $I$1.fw
+fixeols $A$1.lis
+fixeols $A$1.tex
+fixeols $A$1.out
+
+! Perform the actual FunnelWeb run.
+! Tolerate means "don't abort on warning, error, or severe".
+tolerate
+fw $I$1.fw +l$O$1.lis +o$O +t$O$1.tex
+
+! Ensure that all three output files were generated.
+absent $O$1.log
+exists $O$1.out
+exists $O$1.lis
+exists $O$1.tex
+
+! Compare the results with the answers.
+diff $O$1.lis $A$1.lis $D
+diff $O$1.out $A$1.out $D
+diff $O$1.tex $A$1.tex $D
+
+!===========================<End of Test_lot Script>============================
diff --git a/web/funnelAC/scripts/test_lt.fws b/web/funnelAC/scripts/test_lt.fws
new file mode 100644
index 0000000000..ebbd7c57e6
--- /dev/null
+++ b/web/funnelAC/scripts/test_lt.fws
@@ -0,0 +1,53 @@
+!===========================<Start of test_lt Script>===========================
+!
+! Test With Listing File and Typeset File
+! ---------------------------------------
+! Inputs:
+! $1 = Name of the .fw file to be tested (e.g. $1="sc01").
+! $I = Directory containing .fw files.
+! $A = Directory containing Answer files.
+! $O = Directory to place Result files.
+! $D = Name of the differences file.
+! Outputs:
+! Listing file.
+! Typeset file.
+! Appendage to differences file.
+
+! Announce this test.
+write ""
+write ""
+writeu "Performing Test $1"
+
+! Delete any previous output files.
+eneo $O$1.log
+eneo $O$1.lis
+eneo $O$1.tex
+eneo $O$1.out
+
+! Check input and answer files.
+exists $I$1.fw
+exists $A$1.lis
+exists $A$1.tex
+absent $A$1.out
+
+! Clean input and answer files.
+fixeols $I$1.fw
+fixeols $A$1.lis
+fixeols $A$1.tex
+
+! Perform the actual FunnelWeb run.
+! Tolerate means "don't abort on warning, error, or severe".
+tolerate
+fw $I$1.fw +l$O$1.lis +t$O$1.tex
+
+! Ensure that only a listing and a typeset file were generated.
+absent $O$1.log
+absent $O$1.out
+exists $O$1.lis
+exists $O$1.tex
+
+! Compare the results with the answers.
+diff $O$1.lis $A$1.lis $D
+diff $O$1.tex $A$1.tex $D
+
+!============================<End of test_lt Script>============================
diff --git a/web/funnelAC/sources/analyse.c b/web/funnelAC/sources/analyse.c
new file mode 100644
index 0000000000..56191baf2d
--- /dev/null
+++ b/web/funnelAC/sources/analyse.c
@@ -0,0 +1,296 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* ANALYSE.C */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "analyse.h"
+#include "as.h"
+#include "data.h"
+#include "lister.h"
+#include "misc.h"
+#include "table.h"
+
+/******************************************************************************/
+
+LOCAL void chk_mac P_((p_ma_t));
+LOCAL void chk_mac (p_ma)
+p_ma_t p_ma;
+{
+ mc_t *call;
+
+ /* Deal with undefined macros by flagging the first invocation. */
+ if (!p_ma->ma_defn.md_isdef)
+ {
+ ls_loo(p_ma->ma_calls,(ulong) 1,PPV &call);
+ as_cold(call!=NULL,"check_macro: No instances of \"undefined\" macro!");
+ lr_err(&call->mc_ps,"Call to undefined macro.");
+ return;
+ }
+
+ /* Assert: The macro has a definition. */
+
+ /* Check that all the calls to the macro have the correct number of params. */
+ ls_fir(p_ma->ma_calls);
+ ls_nxt(p_ma->ma_calls,PPV &call);
+ while (call!=NULL)
+ {
+ if (call->mc_npar != p_ma->ma_defn.md_npar)
+ {
+ sprintf(linet1,"Call has %lu parameter%s, but the macro",
+ (ulong) call->mc_npar,
+ call->mc_npar==1 ? "" : "s");
+ lr_err(&(call->mc_ps),linet1);
+ sprintf(linet1,"definition at line %lu specifies %lu parameter%s.",
+ (ulong) p_ma->ma_defn.md_ps.ps_line,
+ (ulong) p_ma->ma_defn.md_npar,
+ p_ma->ma_defn.md_npar==1 ? "" : "s");
+ lr_mes(&(call->mc_ps),linet1);
+ if (p_ma->ma_defn.md_npar==0 && call->mc_npar==1)
+ {
+ lr_mes(&(call->mc_ps),"Note: If your call looks like this: @<Macro@>@(@) then you");
+ lr_mes(&(call->mc_ps),"should be aware that FunnelWeb treats this as a call with");
+ lr_mes(&(call->mc_ps),"a single parameter consisting of the empty string. This");
+ lr_mes(&(call->mc_ps),"is a consequence of parameter delimiters @\"@\" being optional.");
+ }
+ }
+ ls_nxt(p_ma->ma_calls,PPV &call);
+ }
+
+ /* Check that the number of calls of the macro is legal. */
+ if (p_ma->ma_defn.md_isfil)
+ {
+ /* Flag all calls to a file macro as errors. */
+ if (ls_len(p_ma->ma_calls)>0)
+ {
+ lr_mes(&p_ma->ma_defn.md_ps,
+ "This file macro is called one or more times.");
+ lr_mes(&p_ma->ma_defn.md_ps,
+ "Each call has been flagged with an error message.");
+ }
+ ls_fir(p_ma->ma_calls);
+ ls_nxt(p_ma->ma_calls,PPV &call);
+ while (call!=NULL)
+ {
+ lr_err(&(call->mc_ps),"Calls to file macros are not allowed.");
+ lr_mes(&(call->mc_ps),"Reason: It should be possible to comment out a");
+ lr_mes(&(call->mc_ps),"file macro without a big fuss. Calling a file macro");
+ lr_mes(&(call->mc_ps),"just tangles it up in the macro structure,");
+ lr_mes(&(call->mc_ps),"making it more difficult to comment out later.");
+ ls_nxt(p_ma->ma_calls,PPV &call);
+ }
+ }
+ else
+ {
+ /* Non-file macros. */
+ if (ls_len(p_ma->ma_calls)==0 && !p_ma->ma_defn.md_iszer)
+ lr_err(&p_ma->ma_defn.md_ps,
+ "This macro is never used (and has no @Z).");
+
+ if (ls_len(p_ma->ma_calls)>1 && !p_ma->ma_defn.md_isman)
+ lr_err(&p_ma->ma_defn.md_ps,
+ "This macro is used more than once (and has no @M).");
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void chk_rec P_((void));
+LOCAL void chk_rec()
+/* This macro analyses the calls between the macros in the macro */
+/* table and flags all recursive macros with an error message. */
+/* */
+/* Def: A macro is a "level 0 macro" if it does not call any macros. */
+/* Def: A macro is a "level n macro" if it calls at least one macro of level */
+/* n-1, but does not call any macros of level n or higher. */
+/* Def: A macro is a "level infinity macro" if it directly or indirectly */
+/* calls itself. */
+/* */
+/* This function totally ignores undefined macros. This means that it can be */
+/* invoked even if problems are detected by the other checks. */
+/* */
+/* Although the actions of this may seem rather time expensive, they may not */
+/* be. The function repeatedly runs through the macro table and each macro's */
+/* bodypart list and expression lists. However, there are not likely to be */
+/* many macros and each definition expression list is likely to be quite */
+/* short, as each macro will be mainly text. */
+/* Even if this stuff does take a while, it is better to detect recursion now */
+/* than at tangle time! */
+{
+ p_ma_t p_ma; /* General purpose pointer to macro. */
+ name_t dummy_name; /* Dummy name variable acts as a placeholder in calls. */
+ uword level; /* Level of macro currently being tagged. */
+ bool gotone; /* TRUE iff current loop iteration tagged >0 macros. */
+
+/* We need a concrete number to stand for level infinity. */
+/* 30000 is a nice, large 15 bit number. */
+#define LEVINF 30000
+
+ /* Make sure that our idea of infinity is big enough. */
+ as_cold(tb_len(macro_table)<LEVINF,"ana_rec: too many macros.");
+
+ /* Tag all the macros as being at level infinity. */
+ /* This could be done in the parser, but it's neater to do it here. */
+ tb_fir(macro_table);
+ while (tb_rea(macro_table,PV dummy_name,PV &p_ma))
+ if (p_ma->ma_defn.md_isdef)
+ p_ma->ma_level=LEVINF;
+
+ gotone=TRUE;
+ /* Work from level 0 upwards identifying macros of successive levels. */
+ for (level=0; level<LEVINF && gotone; level++)
+ {
+ /* Identify all macros of level 'level'. */
+ /* Gotone tells us if we managed to tag a macro during this iteration. */
+ gotone=FALSE;
+
+ /* Run through table tagging all macros at level 'level'. */
+ tb_fir(macro_table);
+ while (tb_rea(macro_table,PV dummy_name,PV &p_ma))
+ {
+ if (p_ma->ma_defn.md_isdef && p_ma->ma_level == LEVINF)
+ {
+ p_bpls_t p_bpls = p_ma->ma_defn.md_body;
+ /* Run through each body part of the macro. */
+ ls_fir(p_bpls);
+ while (TRUE)
+ {
+ p_bp_t p_bp;
+ ls_nxt(p_bpls,PPV &p_bp);
+ if (p_bp==NULL) break;
+ /* Run through the list of expression elements. */
+ ls_fir(p_bp->bp_ex);
+ while (TRUE)
+ {
+ p_el_t p_el;
+ ls_nxt(p_bp->bp_ex,PPV &p_el);
+ if (p_el==NULL) break;
+ /* Don't tag anything that calls anything that isn't tagged. */
+ if ((p_el->el_kind==EL_INVC ) &&
+ (p_el->el_p_mac->ma_defn.md_isdef) &&
+
+ (p_el->el_p_mac->ma_level==LEVINF))
+ goto nextmacro;
+ }
+ }
+ /* If we got this far, then our macro must have called nothing but */
+ /* macros of levels [0,level-1]. Thus, we can tag it level 'level'. */
+ p_ma->ma_level=level;
+ gotone=TRUE;
+ } /* End if */
+ nextmacro:;
+ } /* End while */
+ } /* End for loop. */
+
+ /* At this point, we have tagged all macros with their level number. Note */
+ /* that level infinity macros are discovered simply because they do not get */
+ /* tagged. The following loop flags all such recursive macros with errors. */
+ tb_fir(macro_table);
+ while (tb_rea(macro_table,PV dummy_name,PV &p_ma))
+ if (p_ma->ma_defn.md_isdef && p_ma->ma_level==LEVINF)
+ lr_err(&p_ma->ma_defn.md_ps,"This macro has an infinite expansion.");
+
+ /* Note: The above message is not "This macro is defined recursively", */
+ /* because this function catches not only recursive macros, but also all the */
+ /* non-recursive macros that call the recursive macros!! To detect only */
+ /* the recursive macros, we really ought to use Tarjan's algorithm for the */
+ /* detection of strongly connected components. However, I don't have the */
+ /* reference handy right now and I want to finish this version of FunnelWeb */
+ /* soon, so I'll leave the installation of Tarjan's algorithm as a possible */
+ /* future enhancement. Then the error message can be changed. */
+}
+
+/******************************************************************************/
+
+EXPORT void analyse()
+{
+ name_t dummy_name;
+ p_ma_t p_ma;
+
+ /* Issue an error if there are no macros. */
+ if (tb_len(macro_table)==0)
+ {
+ char *m="E: No macros defined.";
+ wl_l(m);
+ if (option.op_s_b)
+ wl_sj(m);
+ num_err++;
+ }
+
+ /* Issue an error if there are no product (output) files. */
+ if (tb_len(file_table)==0)
+ {
+ char *m="E: No output files specified.";
+ wl_l(m);
+ if (option.op_s_b)
+ wl_sj(m);
+ num_err++;
+ }
+
+ /* Take a look at each macro and issue appropriate diagnostics. */
+ tb_fir(macro_table);
+ while (tb_rea(macro_table,PV dummy_name,PV &p_ma))
+ chk_mac(p_ma);
+
+ /* Check for recursive macros. */
+ chk_rec();
+
+ /* Run through the document list and flag any sections that still have not */
+ /* been given names. */
+ ls_fir(document_list);
+ while (TRUE)
+ {
+ p_dc_t p_dc;
+ ls_nxt(document_list,PPV &p_dc);
+ if (p_dc==NULL) break;
+ if (p_dc->dc_kind==DC_TYPE &&
+ p_dc->dc_ty.ty_kind==TY_NSEC &&
+ !p_dc->dc_ty.ty_isnam)
+ {
+ lr_err(&p_dc->dc_ps,"This section has no name.");
+ lr_mes(&p_dc->dc_ps,"You can give it one explicitly (As in @A@<Sloth@>) or implicitly by");
+ lr_mes(&p_dc->dc_ps,"defining a macro (whose name will be inherited) within the section.");
+ }
+ }
+}
+
+/******************************************************************************/
+/* End of ANALYSE.C */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/analyse.h b/web/funnelAC/sources/analyse.h
new file mode 100644
index 0000000000..3c2826b810
--- /dev/null
+++ b/web/funnelAC/sources/analyse.h
@@ -0,0 +1,61 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* ANALYSE.H */
+/******************************************************************************/
+/* */
+/* This package exports a single function called analyse() that should be */
+/* invoked just after the parser has finished. The scanner and parser */
+/* serve only to construct a structured representation of the input file in */
+/* memory; they do not critique it beyond syntax. In contrast, analyse() */
+/* analyses the representation, checking it for "semantic" errors. Any */
+/* problems that are found are sent to the lister package with appropriate */
+/* positioning information so that the messages appear at exactly the right */
+/* spot in the listing. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+EXPORT void analyse P_((void));
+
+/******************************************************************************/
+/* End of ANALYSE.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/as.c b/web/funnelAC/sources/as.c
new file mode 100644
index 0000000000..4deddcb3a1
--- /dev/null
+++ b/web/funnelAC/sources/as.c
@@ -0,0 +1,60 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* AS.C */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "as.h"
+#include "machin.h"
+
+/******************************************************************************/
+
+EXPORT void as_bomb(message)
+char *message;
+{
+ fprintf(stderr,"%s\n",message);
+ fprintf(stderr,"An assertion has failed! See the line above.\n");
+ fprintf(stderr,"Press return to abort FunnelWeb>\n"); (void) getchar();
+ exit(EXIT_FAILURE);
+}
+
+/******************************************************************************/
+/* AS.C */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/as.h b/web/funnelAC/sources/as.h
new file mode 100644
index 0000000000..ab89d73e83
--- /dev/null
+++ b/web/funnelAC/sources/as.h
@@ -0,0 +1,119 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* AS.H */
+/******************************************************************************/
+/* */
+/* ASSERTION PACKAGE */
+/* ================= */
+/* This package contains macros and functions that support assertions. An */
+/* assertion is a boolean condition that is supposed always to be true at a */
+/* particular point during program execution. An assertion statement tests */
+/* such a condition and bombs the program if it is false; better to be */
+/* alerted to such a condition rather than suffer and erroneous execution. */
+/* */
+/* Standard C supports asertions with the <assert.h> header file providing */
+/* the "assert" macro. Unfortunately, this does not meet the needs of */
+/* FunnelWeb for two reasons: */
+/* */
+/* 1) Portability is emphasised in FunnelWeb and the assert macro is fairly */
+/* recent. Its only argument is the boolean condition, which means that */
+/* without the ANSI macros __FILE__ and __LINE__, the macro would be */
+/* unable to indicate where an assertion failure occurred, in a non-ANSI */
+/* environment. */
+/* */
+/* 2) There is only one assert macro and it can be either on or off, the */
+/* implication being that in production code, it should be turned off. In */
+/* contrast, the execution speed of the assert macro will usually matter */
+/* only in a small portion of the code as, in most programs, a small */
+/* portion of the code accounts for most of the execution time. By having */
+/* two categories of assertion, we can leave most of the assertions turned */
+/* on in the production program. */
+/* */
+/* This reasoning leads to the slightly different assertion facilty provided */
+/* by this package. Here, there are two assertion routines/macros, HOT */
+/* assertions for HOT code (code in a program hot spot) and COLD assertions */
+/* for COLD code (not in a hot spot). Only the HOT assertions can be turned */
+/* off. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_AS
+#define DONE_AS
+
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+/* The following #define determines whether hot assertions are to be turned */
+/* on or off. Set to 0 for OFF and 1 for ON. */
+/* Note: I have left hot assertions on in the production version as FunnelWeb */
+/* doesn't go slowly enough to make me want to turn it off. */
+#define AS_DOHOT 1
+
+/******************************************************************************/
+
+EXPORT void as_bomb P_((char *));
+/* This function writes out its argument string and then bombs the program. */
+/* It should be called at any point where it has been determined that an */
+/* illegal condition has been detected. The other assertion routines/macros */
+/* call this function. */
+
+/* The following two macros define hot and cold assertions. Be sure never to */
+/* call them with arguments with side effects! */
+#define as_cold(e,s) {if (!(e)) as_bomb(s);}
+
+#if AS_DOHOT
+#define as_hot(e,s) {if (!(e)) as_bomb(s);}
+#define AS_HCODE(CODE) {CODE}
+#else
+#define as_hot(e,s) ((void) 0)
+#define AS_HCODE(CODE) ((void) 0)
+#endif
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* AS.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/clock.c b/web/funnelAC/sources/clock.c
new file mode 100644
index 0000000000..886b1bff55
--- /dev/null
+++ b/web/funnelAC/sources/clock.c
@@ -0,0 +1,125 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* CLOCK.C */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "as.h"
+#include "clock.h"
+#include "machin.h"
+
+/******************************************************************************/
+
+#define MAGIC_HEAD (565854L)
+#define MAGIC_TAIL (256194L)
+
+/******************************************************************************/
+
+LOCAL void ck_check P_((p_ck_t));
+LOCAL void ck_check(p_ck)
+p_ck_t p_ck;
+{
+ as_cold(p_ck!=NULL,"ck_check: Clock pointer is NULL.");
+ as_cold(p_ck->ck_mhead==MAGIC_HEAD,
+ "ck_check: Magic number at head of record is incorrect.");
+ as_cold(p_ck->ck_mtail==MAGIC_TAIL,
+ "ck_check: Magic number at tail of record is incorrect.");
+}
+
+/******************************************************************************/
+
+EXPORT void ck_ini(p_ck)
+p_ck_t p_ck;
+{
+ p_ck->ck_mhead = MAGIC_HEAD;
+ p_ck->ck_run = FALSE;
+ p_ck->ck_csum = 0.0;
+ p_ck->ck_rsum = 0.0;
+ /* ck_csta and ck_rsta are undefined in a stopped clock. */
+ p_ck->ck_mtail = MAGIC_TAIL;
+}
+
+/******************************************************************************/
+
+EXPORT void ck_start(p_ck)
+p_ck_t p_ck;
+{
+ ck_check(p_ck);
+ as_cold(!p_ck->ck_run,"ck_start: Clock is already running!");
+ p_ck->ck_run = TRUE;
+ p_ck->ck_csta = tim_cpu();
+ p_ck->ck_rsta = tim_real();
+}
+
+/******************************************************************************/
+
+EXPORT void ck_stop(p_ck)
+p_ck_t p_ck;
+{
+ ck_check(p_ck);
+ as_cold(p_ck->ck_run,"ck_stop: Clock is already stopped!");
+ p_ck->ck_run = FALSE;
+ p_ck->ck_csum += tim_cpu () - p_ck->ck_csta;
+ p_ck->ck_rsum += tim_real() - p_ck->ck_rsta;
+}
+
+/******************************************************************************/
+
+EXPORT float ck_cpu(p_ck)
+p_ck_t p_ck;
+{
+ ck_check(p_ck);
+ as_cold(!p_ck->ck_run,"ck_cpu: Clock is running.");
+ return p_ck->ck_csum;
+}
+
+/******************************************************************************/
+
+EXPORT float ck_real(p_ck)
+p_ck_t p_ck;
+{
+ ck_check(p_ck);
+ as_cold(!p_ck->ck_run,"ck_real: Clock is running.");
+ return p_ck->ck_rsum;
+}
+
+/******************************************************************************/
+/* End of CLOCK.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/clock.h b/web/funnelAC/sources/clock.h
new file mode 100644
index 0000000000..906879db1b
--- /dev/null
+++ b/web/funnelAC/sources/clock.h
@@ -0,0 +1,107 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* CLOCK.H */
+/******************************************************************************/
+/* */
+/* This package implements a clock abstraction that is used to generate */
+/* timing statistics which are useful for performance tuning. The package */
+/* allows the measurement of both real and CPU time. This package gets its */
+/* raw information from the tim_cpu() and tim_real() functions of the machine */
+/* dependent module "machin". */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_CLOCK
+#define DONE_CLOCK
+
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+/* The following clock type is supposed to be an ADT so don't frob any of its */
+/* fields manually! */
+typedef struct
+ {
+ ulong ck_mhead; /* Magic number helps detect corruptions. */
+ bool ck_run; /* TRUE iff the clock is running. */
+ float ck_csum; /* Accumulated CPU time. */
+ float ck_rsum; /* Accumulated real time. */
+ float ck_csta; /* ck_run => CPU time when clock was started. */
+ float ck_rsta; /* ck_run => Real time when clock was started. */
+ ulong ck_mtail; /* Magic number helps detect corruptions. */
+ } ck_t;
+
+typedef ck_t *p_ck_t;
+
+/******************************************************************************/
+
+EXPORT void ck_ini P_((p_ck_t));
+/* Initializes the clock. After this call, the argument clock will be in the */
+/* STOPPED state and all its registers will be zero. A clock must be */
+/* initialized before any other operations are performed on it. */
+
+EXPORT void ck_start P_((p_ck_t));
+/* Changes the clock from the STOPPED state to the RUNNING state. Starts */
+/* accumulating real time and CPU time on its registers. */
+/* Raises an error if the clock is not in the STOPPED state. */
+
+EXPORT void ck_stop P_((p_ck_t));
+/* Changes the clock from the RUNNING state to the STOPPED state. Stops */
+/* accumulating real time and CPU time on its registers. */
+/* Raises an error if the clock is not in the RUNNING state. */
+
+EXPORT float ck_cpu P_((p_ck_t));
+/* Returns the number of seconds of CPU time accumulated on the clock. */
+/* Raises an error if the clock is not in the STOPPED state. */
+
+EXPORT float ck_real P_((p_ck_t));
+/* Returns the number of seconds of real time accumulated on the clock. */
+/* Raises an error if the clock is not in the STOPPED state. */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of CLOCK.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/command.c b/web/funnelAC/sources/command.c
new file mode 100644
index 0000000000..c38b5594ca
--- /dev/null
+++ b/web/funnelAC/sources/command.c
@@ -0,0 +1,2111 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* COMMAND.C */
+/******************************************************************************/
+
+#include <ctype.h>
+#include "style.h"
+
+#include "analyse.h"
+#include "as.h"
+#include "command.h"
+#include "data.h"
+#include "dump.h"
+#include "lister.h"
+#include "memory.h"
+#include "mapper.h"
+#include "misc.h"
+#include "option.h"
+#include "parser.h"
+#include "scanner.h"
+#include "tangle.h"
+#include "weave.h"
+
+/******************************************************************************/
+
+/* Because FunnelWeb has so many options ,it is convenient to allow the user */
+/* to construct a startup file. This is its name. */
+#define INITFILE "fwinit.fws"
+
+/******************************************************************************/
+
+/* Three variables hold options information in FunnelWeb. */
+/* 'p_comopt' holds the options conveyed by the original raw command line. */
+/* 'p_defopt' holds the options that are default in the FunnelWeb shell. */
+/* 'option' is global and holds the options that have been specified for the */
+/* current invocation of FunnelWeb proper. */
+/* 'option' is global so here we see only 'p_comopt' and 'p_defopt'. */
+LOCVAR op_t *p_comopt; /* Initial command line options. */
+LOCVAR op_t *p_defopt; /* Default shell options. */
+
+/* The FunnelWeb shell interpreter has many different commands and it is */
+/* worth them sharing the same basic command line scanner. These two */
+/* variables hold the numer of arguments and a pointer to strings holding */
+/* copies of each argument. */
+/* Note: The first argument is placed in arr_arg[0]. */
+#define ARG_MAX 5
+LOCVAR uword arg_num;
+LOCVAR char *arg_arr[ARG_MAX+1]; /* Is this +1 necessary? */
+
+/* The FunnelWeb command interpreter allows 10 substitution strings. */
+/* These strings are stored in the following array. */
+#define NUM_SUBS (10+26) /* 0..9 and A..Z */
+LOCVAR char *subval[NUM_SUBS];
+
+LOCVAR ulong old_war;
+LOCVAR ulong old_err;
+LOCVAR ulong old_sev;
+
+/* The FunnelWeb script interpreter can echo (trace) each command before it */
+/* executes it. Whether it does is determined by this variable. */
+LOCVAR bool tracing;
+
+/* If this variable is set to true then the interpreter will not abort if the */
+/* very next command (and that one only) generates an error or severe error. */
+LOCVAR bool noabort;
+
+/* If the following boolean is true, the interpreter skips lines until it */
+/* hits the HERE command. */
+LOCVAR bool skipping;
+
+/* The following variables count how many times DIFF is invoked and how many */
+/* times it succeeded. This allows us to output a summary at the end of the */
+/* processing of the test suite. */
+LOCVAR ulong difftotl = 0;
+LOCVAR ulong diffsucc = 0;
+
+/******************************************************************************/
+
+/* Here are the prototypes for recursive or out-of-order functions. */
+LOCAL void interstr P_((char *));
+LOCAL void do_set P_((char *));
+
+/******************************************************************************/
+
+LOCAL char *sing P_((ulong,char *,char *));
+LOCAL char *sing(num,sinstr,plustr)
+/* Return one or other string depending on whether first argument is singular.*/
+ulong num;
+char *sinstr;
+char *plustr;
+{
+ if (num==1)
+ return sinstr;
+ else
+ return plustr;
+}
+
+/******************************************************************************/
+
+LOCAL uword numpos P_((ulong,ulong,ulong));
+LOCAL uword numpos(a,b,c)
+/* Returns the number of its arguments that are positive. */
+ulong a,b,c;
+{
+ uword result=0;
+ if (a>0) result++;
+ if (b>0) result++;
+ if (c>0) result++;
+ return result;
+}
+
+/******************************************************************************/
+
+LOCAL void errsum P_((ulong,ulong,ulong,ulong));
+LOCAL void errsum(fat,sev,err,war)
+/* Supply as arguments, the number of various kinds of diagnostics. */
+/* Places in linet1 a string describing the diagnostics. */
+ulong fat,sev,err,war;
+{
+ char linet2[100];
+
+ if (fat+sev+err+war==0)
+ {strcpy(linet1,"SUCCESS: No diagnostics."); return;}
+
+ strcpy(linet1,"There ");
+
+ /* "Was" or "were" depending on the plurality of highest level diagnostic. */
+ if (fat>0) strcat(linet1,sing(fat,"was","were"));
+ else if (sev>0) strcat(linet1,sing(sev,"was","were"));
+ else if (err>0) strcat(linet1,sing(err,"was","were"));
+ else if (war>0) strcat(linet1,sing(war,"was","were"));
+ else as_bomb("errsum: Error hierarchy failed!");
+
+ strcat(linet1," ");
+
+ /* Fatal errors. */
+ if (fat>0)
+ {
+ sprintf(linet2,"%1lu Fatal error",fat); strcat(linet1,linet2);
+ strcat(linet1,sing(fat,"","s"));
+ }
+
+ /* Joiner stuff. */
+ if (fat>0 && numpos(sev,err,war)>=2) strcat(linet1,", ");
+ if (fat>0 && sev>0 && err==0 && war==0) strcat(linet1," and ");
+
+ /* Severe errors. */
+ if (sev>0)
+ {
+ sprintf(linet2,"%1lu Severe error",sev); strcat(linet1,linet2);
+ strcat(linet1,sing(sev,"","s"));
+ }
+
+ /* Joiner stuff. */
+ if (fat+sev>0 && err>0 && war >0) strcat(linet1,", ");
+ if (fat+sev>0 && err>0 && war==0) strcat(linet1," and ");
+
+ /* Errors. */
+ if (err>0)
+ {
+ sprintf(linet2,"%1lu Error",err); strcat(linet1,linet2);
+ strcat(linet1,sing(err,"","s"));
+ }
+
+ /* Joiner stuff. */
+ if (fat+sev+err>0 && war>0) strcat(linet1," and ");
+
+ /* Warnings. */
+ if (war > 0)
+ {
+ sprintf(linet2,"%1lu Warning",war); strcat(linet1,linet2);
+ strcat(linet1,sing(war,"","s"));
+ }
+
+ /* The final full stop! */
+ strcat(linet1,".");
+}
+
+/******************************************************************************/
+
+LOCAL void allocarg P_((void));
+LOCAL void allocarg()
+/* Some compilers don't allow much room for statics and so it is necessary to */
+/* declare some variables as pointers and allocate them explicitly. This */
+/* function allocates the command line argument array to point to strings. */
+{
+ uword i;
+ for (i=0;i<=ARG_MAX;i++)
+ arg_arr[i]=(char *) mm_perm(sizeof(cl_t));
+
+ /* Also initialize the substitution strings. */
+ for (i=0;i<NUM_SUBS;i++)
+ {
+ subval[i]=(char *) mm_perm(sizeof(cl_t));
+ subval[i][0]=EOS;
+ }
+ p_comopt=(p_op_t) mm_perm(sizeof(op_t));
+ p_defopt=(p_op_t) mm_perm(sizeof(op_t));
+}
+
+/******************************************************************************/
+
+LOCAL void zerdia P_((void));
+LOCAL void zerdia()
+{
+ old_war=num_war;
+ old_err=num_err;
+ old_sev=num_sev;
+ num_sev=num_err=num_war=0;
+}
+
+LOCAL void sumdia P_((void));
+LOCAL void sumdia()
+{
+ sum_sev+=num_sev;
+ sum_err+=num_err;
+ sum_war+=num_war;
+}
+
+LOCAL void restdia P_((void));
+LOCAL void restdia()
+{
+ num_sev+=old_sev;
+ num_err+=old_err;
+ num_war+=old_war;
+}
+
+/******************************************************************************/
+
+LOCAL void explode P_((char *));
+LOCAL void explode(p)
+/* Parses the string p into a set of non-blank sequences. Copies each */
+/* distinct run of non-blanks into successive values of arg_arr. Places the */
+/* number of runs of non-blanks into arg_num. DOESN'T generate an error if */
+/* there are too many arguments. */
+char *p;
+{
+ arg_num=0;
+ while (TRUE)
+ {
+ char *x;
+
+ /* Skip to the next argument. */
+ while (*p==' ') p++;
+
+ /* Exit if we have hit the end of the string. */
+ if (*p==EOS) break;
+
+ /* Exit if we are already full up with arguments. */
+ if (arg_num==ARG_MAX) break;
+
+ /* Copy the next argument. */
+ x=arg_arr[arg_num];
+ while (*p!=' ' && *p!=EOS) *x++ = *p++;
+ *x=EOS;
+ arg_num++;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void dollsub P_((char *));
+LOCAL void dollsub(p_comlin)
+/* Assumes that it's string argument is in a command line object. */
+/* Performs dollar substitutions. */
+char *p_comlin;
+{
+ char *p=p_comlin;
+ cl_t cl;
+ char *t;
+
+ t = &cl[0];
+
+ /* Copy the unexpanded command line to the temporary from which we expand it */
+ /* back from whence it came. */
+ strcpy(t,p);
+
+ /* Work through the unexpanded command line expanding. */
+ while (*t != EOS)
+ {
+ /* Complain if there is not room for one more character. */
+ if ((p-p_comlin) == COMLINE_FWMAX) goto toobig;
+
+ /* If no dollar sign, no tricks. Just copy the character over. */
+ if (*t!='$') {*p++ = *t++; continue;}
+
+ /* We have seen a dollar sign. Move onto the next character. */
+ t++;
+
+ /* The only legal escapes are decimal digits, slash, and the dollar sign. */
+ if (!isdigit(*t) && !isupper(*t) && *t!='$' && *t!='/')
+ {
+ wl_sj("S: Illegal dollar subtitution sequence in command line.");
+ wl_sj("Legal sequences are $0..$9, $A..$Z, $/, and $$.");
+ num_sev++;
+ strcpy(p,t);
+ return;
+ }
+
+ /* A dollar escape is easy to process. */
+ if (*t=='$') {*p++ = *t++; continue;}
+
+ /* A slash escape is easy to process. */
+ if (*t=='/') {*p++ = FN_DELIM; t++; continue;}
+
+ /* Substitutions have to be expanded. */
+ if (isdigit(*t) || isupper(*t))
+ {
+ ubyte num;
+ char *q;
+ if (isdigit(*t))
+ num = *t-'0';
+ else
+ num = 10+(*t-'A');
+ as_cold(num<NUM_SUBS,"dollsub: num is too bug!");
+ q=subval[num];
+ if ((p-p_comlin)+strlen(subval[num]) > COMLINE_FWMAX) goto toobig;
+ while (*q!=EOS) *p++ = *q++;
+ t++;
+ }
+ }
+ *p=EOS;
+ return;
+
+ toobig:
+ wl_sj("S: Expanded (i.e. after $1 etc) command line is too long.");
+ num_sev++;
+ strcpy(p,t);
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void fwonerun P_((void));
+LOCAL void fwonerun()
+/* Performs a single run of FunnelWeb proper, using the global variable */
+/* 'options' as the input command line. */
+{
+ fn_t lisnam;
+
+ /* The following clocks record the time taken by various parts of FunnelWeb. */
+ ck_t mappck;
+ ck_t scanck;
+ ck_t parsck;
+ ck_t analck;
+ ck_t dumpck;
+ ck_t lstrck;
+ ck_t tangck;
+ ck_t weavck;
+ ck_t totlck;
+
+ /* Intialize/zero all the clocks. */
+ ck_ini(&mappck);
+ ck_ini(&scanck);
+ ck_ini(&parsck);
+ ck_ini(&analck);
+ ck_ini(&dumpck);
+ ck_ini(&lstrck);
+ ck_ini(&tangck);
+ ck_ini(&weavck);
+ ck_ini(&totlck);
+
+ /* Start the total time clock ticking. A total time clock is used to gather */
+ /* up the gaps between the invocations of the other clocks. */
+ ck_start(&totlck);
+
+ ck_start(&lstrck);
+
+ /* Establish the listing file output stream. */
+ strcpy(lisnam,""); /* Start with an empty string. */
+ fn_ins(lisnam,option.op_f_s); /* Insert input file name. */
+ fn_ins(lisnam,".lis"); /* Insert constant extension. */
+ fn_ins(lisnam,option.op_l_s); /* Insert command line spec. */
+ wf_ini(&f_l,option.op_l_b); /* Initialize the stream. */
+ wf_ope(&f_l,lisnam); /* Create the file. */
+ if (option.op_l_b && wf_err(&f_l))
+ {
+ sprintf(linet1,"S: Error creating listing file \"%s\".",lisnam);
+ wl_sj(linet1);
+ wl_sj("Aborting...");
+ num_sev++;
+ return;
+ }
+
+ wl_l("FUNNELWEB LISTING FILE");
+ wl_l("======================");
+ wl_l("");
+
+ /* Initialize the lister for this run. */
+ lr_ini();
+
+ ck_stop(&lstrck);
+
+ /* Scanner comes first. */
+ ck_start(&scanck);
+ scanner(&mappck,&scanck);
+ ck_stop(&scanck);
+
+ /* Dump the line and token lists if requested. The scanner supplies sensible */
+ /* lists even if it encounters errors, so there is no danger here. */
+ ck_start(&dumpck);
+ if (option.op_b2_b) dm_lnls(&f_l);
+ if (option.op_b3_b) dm_tkls(&f_l);
+ ck_stop(&dumpck);
+
+ /* Invoke the parser if there were no serious scanner errors. */
+ if (num_sev+num_err==0)
+ {
+ ck_start(&parsck);
+ parser();
+ ck_stop(&parsck);
+ /* Only perform post parser dumps if the parser was run. */
+ ck_start(&dumpck);
+ if (option.op_b4_b) dm_matb(&f_l);
+ if (option.op_b5_b) dm_dcls(&f_l);
+ ck_stop(&dumpck);
+ }
+ else
+ {
+ if (option.op_b4_b)
+ wl_l("Macro table dump skipped (Parser was not invoked).");
+ if (option.op_b5_b)
+ wl_l("Document list dump skipped (Parser was not invoked).");
+ }
+
+ /* Invoke the macro structure analyser if still no errors. */
+ if (num_sev+num_err==0)
+ {
+ ck_start(&analck);
+ analyse();
+ ck_stop(&analck);
+ }
+
+ /* The scanner, parser, and analyser send errors to the lister package. */
+ /* Send sorted listing to the listing file (and screen if desired). */
+ ck_start(&lstrck);
+ if (option.op_l_b) lr_gen(&f_l,option.op_c_i);
+ if (option.op_s_b) lr_gen(&f_s,option.op_s_i);
+ if (option.op_s_b) lr_gen(&f_j,option.op_s_i);
+ ck_stop(&lstrck);
+
+ /* If the first stages went OK, invoke tangle and weave. */
+ if (num_sev+num_err==0)
+ {
+ if (option.op_o_b)
+ {
+ ck_start(&tangck);
+ tangle();
+ ck_stop(&tangck);
+ }
+ if (option.op_t_b)
+ {
+ ck_start(&weavck);
+ weave();
+ ck_stop(&weavck);
+ }
+ /* Leave output lines from Tangle and Weave joined, but separate them */
+ /* from any further output. */
+ if (option.op_t_b || option.op_o_b)
+ wl_sjl("");
+ }
+ else
+ {
+ /* Otherwise tell the user that back-end phases will be skipped. */
+ if ( option.op_o_b || option.op_t_b)
+ {
+ if (num_sev+num_err==1)
+ wr_sjl("Error caused ");
+ else
+ wr_sjl("Errors caused ");
+ }
+ if ( option.op_o_b && option.op_t_b) wr_sjl("tangle and weave phases");
+ if ( option.op_o_b && !option.op_t_b) wr_sjl("tangle phase");
+ if (!option.op_o_b && option.op_t_b) wr_sjl("weave phase");
+ if ( option.op_o_b || option.op_t_b)
+ {wl_sjl(" to be skipped."); wl_sjl("");}
+ }
+
+ ck_stop(&totlck);
+
+ /* If requested write out a summary of the time taken. */
+ if (option.op_b6_b)
+ dm_times(&f_l,
+ &mappck,&scanck,&parsck,&analck,
+ &dumpck,&lstrck,&tangck,&weavck,&totlck);
+
+ /* Write out a line summarizing the diagnostics for this run. */
+ errsum(0L,num_sev,num_err,num_war); wl_sjl(linet1);
+
+ /* Close the listing file. */
+ if (!option.op_l_b) goto finishoff;
+ if (wf_err(&f_l))
+ {
+ wl_sj("S: Error writing to listing file. Aborting...");
+ num_sev++;
+ goto finishoff;
+ }
+ wf_clo(&f_l);
+ if (wf_err(&f_l))
+ {
+ wl_sj("S: Error flushing and closing listing file. Aborting...");
+ num_sev++;
+ }
+
+ finishoff:
+ /* VERY IMPORTANT: Ask the memory management package to free up all the */
+ /* temporary memory (allocated using mm_temp) that has been allocated. This */
+ /* ensures that the memory allocated for this FunnelWeb run will be recycled.*/
+ mm_zapt();
+
+} /* End of fwonerun */
+
+/******************************************************************************/
+
+LOCAL void do_absen P_((void));
+LOCAL void do_absen ()
+{
+ if (arg_num != 2)
+ {
+ wl_sj("S: The ABSENT command requires exactly one argument.");
+ num_sev++;
+ return;
+ }
+ if (fexists(arg_arr[1]))
+ {
+ sprintf(linet1,"S: ABSENT found \"%s\".",arg_arr[1]);
+ wl_sj(linet1);
+ num_sev++;
+ return;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void do_cody P_((void));
+LOCAL void do_cody ()
+/* The CODIFY command takes an input text file and generates an output text */
+/* file containing C code to write out the input text file. The need for this */
+/* command springs from the weaver. Experience with FunnelWeb showed that use */
+/* of a separate header file, to be included, while apparently sensible, */
+/* caused no end of problems. In particular, problems with portably */
+/* specifying where the header file should be found. In the end, it was */
+/* decided that it would be better to write the header file out with the */
+/* weave output. As the header file is quite long, it is best to automate the */
+/* process of converting the file from text to C code to write out the text. */
+/* That is what the CODIFY command does. */
+{
+ FILE *file1;
+ FILE *file2;
+
+#define MAXHACK 1000
+ char hackline[MAXHACK+1];
+ uword lineno;
+
+ if (arg_num != 3)
+ {
+ wl_sj("S: The CODIFY command requires exactly two arguments.");
+ num_sev++;
+ return;
+ }
+
+ /* Open the input file for text reading. */
+ file1=fopen(arg_arr[1],"r");
+ if (file1 == FOPEN_F)
+ {
+ wl_sj("S: Error opening the input file.");
+ num_sev++;
+ return;
+ }
+ file2=fopen(arg_arr[2],"w");
+ if (file2 == FOPEN_F)
+ {
+ fclose(file1);
+ wl_sj("S: Error creating the output file.");
+ num_sev++;
+ return;
+ }
+
+ lineno=0;
+
+ /* PROCESS A SINGLE LINE PER ITERATION. */
+ while (TRUE)
+ {
+ uword linelength;
+ uword i;
+
+ /* Read in a line of input and terminate loop if there are no more lines. */
+ fgets(hackline,MAXHACK,file1);
+ if (ferror(file1))
+ {wl_sj("S: Error reading the input file.");num_sev++;return;}
+ if (feof(file1)) break;
+ lineno++;
+
+ /* Complain if the input line is too long. */
+ if (strlen(hackline)>81)
+ {
+ sprintf(linet1,"Line %lu of input file is too long.",
+ (ulong) strlen(hackline));
+ wl_sj(linet1);
+ wl_sj("The maximum allowable length is 80 characters.");
+ num_sev++;
+ return;
+ }
+
+ /* Write the start-of-line string. */
+ if (fputs(" WX(\"",file2) == FPUTS_F) goto write_failure;
+
+ /* Write out the line in sanitized form. */
+ linelength=strlen(hackline);
+ for (i=0;i<linelength;i++)
+ {
+ char ch = hackline[i];
+ if (ch==EOL)
+ ; /* Ignore this. */
+ else
+ if (ch=='\"')
+ {if (fputs("\\\"",file2) == FPUTS_F) goto write_failure;}
+ else
+ if (ch=='\\')
+ {if (fputs("\\\\",file2) == FPUTS_F) goto write_failure;}
+ else
+ {if (fputc(ch,file2) == FPUTC_F) goto write_failure;}
+ }
+
+ /* Write the end of line string. */
+ if (fputs("\");\n",file2) == FPUTS_F) goto write_failure;
+ }
+
+ if (fflush(file2) != FFLUSH_S)
+ {wl_sj("S: Error flushing the output file.");num_sev++;return;}
+ if (fclose(file1) == FCLOSE_F)
+ {wl_sj("S: Error closing the input file.");num_sev++;return;}
+ if (fclose(file2) == FCLOSE_F)
+ {wl_sj("S: Error closing the output file.");num_sev++;return;}
+ return;
+
+ write_failure:
+ wl_sj("S: Error writing the output file.");num_sev++;return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_comp P_((void));
+LOCAL void do_comp ()
+/* The compare command should have two arguments being file names. It */
+/* compares the two files and raises a fatal error if they differ. */
+{
+ char *errstr;
+ bool result;
+ if (arg_num != 3)
+ {
+ wl_sj("S: COMPARE command must be given exactly two arguments.");
+ num_sev++;
+ return;
+ }
+ errstr=eq_files(arg_arr[1],arg_arr[2],&result);
+ if (errstr!=NULL)
+ {
+ wl_sj("S: COMPARE command ran into a problem:");
+ wl_sj(errstr);
+ num_sev++;
+ return;
+ }
+ if (!result)
+ {
+ wl_sj("S: A comparison FAILED. Two files compared were not identical!");
+ sprintf(linet1," File1: \"%s\".",arg_arr[1]); wl_sj(linet1);
+ sprintf(linet1," File2: \"%s\".",arg_arr[2]); wl_sj(linet1);
+ wl_sj(" FunnelWeb has just FAILED a regression test.");
+ wl_sj(" You should now inspect the two files to see how the result of");
+ wl_sj(" this run of FunnelWeb differed from the \"correct answer\" in");
+ wl_sj(" the answer directory.");
+ num_sev++;
+ return;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void do_defin P_((char *));
+LOCAL void do_defin (p_comlin)
+/* The define command associates a string with a $n. */
+char *p_comlin;
+{
+ char *p;
+ ubyte defnum;
+
+ /* p is our scanning pointer and starts at the start of the command line. */
+ p=p_comlin;
+
+ /* Skip past the DEFINE command onto the second argument. */
+ while ((*p!=' ') && (*p!=EOS)) p++;
+ while (*p==' ') p++;
+
+ /* There should be a single digit or upper case letter there. */
+ if (!isdigit(*p) && !isupper(*p))
+ {wl_sj("S: The first argument to DEFINE must be a decimal digit or");
+ wl_sj(" upper case letter.");
+ wl_sj(" Example: define 3 \"A Walrus in Spain is a Walrus in Vain.\"");
+ num_sev++;return;}
+ if (isdigit(*p))
+ defnum = *p-'0';
+ else
+ defnum = 10+(*p-'A');
+ as_cold(defnum<NUM_SUBS,"do_defin: num is too bug!");
+
+ /* Move past the digit. */
+ p++;
+
+ /* Skip blanks to get to the next argument. */
+ while (*p==' ') p++;
+
+ /* Complain if there is no second argument. */
+ if (*p==EOS)
+ {wl_sj("S: The DEFINE command expected a second argument.");
+ num_sev++; return;}
+
+ /* Otherwise make sure that we have a double quoted string. */
+ if (*p!='"' || *(p+1)==EOS || p[strlen(p)-1]!='"')
+ {wl_sj("S: Second argument to DEFINE must be in double quotes.");
+ num_sev++;return;}
+
+ /* All is checked. Now it is safe to copy over the string. */
+ p++;
+ strcpy(subval[defnum],p);
+ subval[defnum][strlen(subval[defnum])-1]=EOS;
+
+ /* TRACE: All the definitions.
+ {
+ ubyte i;
+ for (i=0;i<NUM_SUB;i++)
+ printf("$%u=\"%s\"\n",(unsigned) i,subval[i]);
+ }
+ */
+}
+
+/******************************************************************************/
+
+LOCAL void do_diff P_((void));
+/* COMMAND FORMAT: diff file1 file2 logfile [abort] */
+/* This function/command performs a proper text differences on two files. */
+/* This function is long and messy because of C's lack of nested functions. */
+/* I don't want to create global variables here, and defining subfunctions */
+/* that do not have access to the variables of this function would provoke */
+/* too wide an interface to be worth the trouble. So it's code city. */
+/* How I wish that I had FunnelWeb to help me write this function! */
+LOCAL void do_diff()
+{
+ bool diffabort; /* TRUE iff we should abort if files are different. */
+ bool is_same = FALSE; /* True iff files are proven to be the same. */
+ FILE *logfile; /* File to write result of comparison. */
+ bool badwrite = FALSE; /* TRUE if we couldn't write to the logfile. */
+ char *p_file1; /* Pointer to mapping of first file to compare. */
+ char *p_file2; /* Pointer to mapping of second file to compare. */
+ ulong len_file1; /* Number of bytes in mapping of first file. */
+ ulong len_file2; /* Number of bytes in mapping of second file. */
+ char *mess1; /* Error message from mapper for first file. */
+ char *mess2; /* Error message from mapper for second file. */
+ bool is_image; /* TRUE iff mapped images are identical. */
+ bool anydiff = FALSE; /* TRUE iff any differences detected during loop. */
+
+ /* Check that the number of arguments is correct. */
+ if (arg_num < 4 || arg_num > 5)
+ {
+ wl_sj("S: The DIFF command must be given either 3 or 4 arguments.");
+ wl_sj(" Usage: diff f1 f2 logfile [abort]");
+ num_sev++;
+ return;
+ }
+
+ /* Check that the fourth argument, if present, is legal. */
+ diffabort=FALSE;
+ if (arg_num == 5)
+ if (strcmp(arg_arr[4],"ABORT")==0 || strcmp(arg_arr[4],"abort")==0)
+ diffabort=TRUE;
+ else
+ {
+ wl_sj(
+ "S: The DIFF command's fourth argument, if present, must be ABORT.");
+ wl_sj(" Usage: diff f1 f2 logfile [abort]");
+ num_sev++;
+ return;
+ }
+
+ /* Now open the log file to append result of compare. */
+ logfile=fopen(arg_arr[3],"a");
+ if (logfile == FOPEN_F)
+ {
+ wl_sj("S: DIFF: Error opening the log file (to append result of compare).");
+ num_sev++;
+ return;
+ }
+
+ /* The following define simplifies writing to the log file. */
+#define LOGLINE {if (fputs(linet1,logfile) == FPUTS_F) badwrite=TRUE;}
+#define LOGSTR(STR) {if (fputs((STR),logfile) == FPUTS_F) badwrite=TRUE;}
+#define LOGCHAR(CH) {if (fputc((CH),logfile) == FPUTC_F) badwrite=TRUE;}
+
+ /* Write the header for this comparison to the log file. */
+ sprintf(linet1,"\n\n" ); LOGLINE;
+ sprintf(linet1,"Comparing \"%s\"\n" ,arg_arr[1]); LOGLINE;
+ sprintf(linet1," with \"%s\".\n",arg_arr[2]); LOGLINE;
+
+ /* Now map in the two files to be compared. */
+ /* Once this is done, we MUST do a mm_zapt later or memory will leak. */
+ /* We attempt to map the second file, even if the first mapping has failed */
+ /* as, if the first file is absent, there is a good chance that the second */
+ /* is absent too, and it is useful to the user to know this. */
+ mess1=map_file(arg_arr[1],&p_file1,&len_file1);
+ mess2=map_file(arg_arr[2],&p_file2,&len_file2);
+ if (mess1 != NULL)
+ {
+ sprintf(linet1,"Error mapping \"%s\".\n",arg_arr[1]); LOGLINE;
+ wr_sj("E: DIFF: "); wr_sj(linet1);
+ sprintf(linet1," %s\n",mess1); LOGLINE; wr_sj(linet1);
+ num_err++;
+ }
+ if (mess2 != NULL)
+ {
+ sprintf(linet1,"Error mapping \"%s\".\n",arg_arr[2]); LOGLINE;
+ wr_sj("E: DIFF: "); wr_sj(linet1);
+ sprintf(linet1," %s\n",mess2); LOGLINE; wr_sj(linet1);
+ num_err++;
+ }
+ if ((mess1 != NULL) || (mess2 != NULL))
+ goto frombadmap;
+
+ /* At this point the two files to be compared are sitting in memory and we */
+ /* have a ready-for-writing log file. We are now ready to compare. */
+
+ /* First perform a binary image comparison as a check for later. */
+ /* We could do this later, but it is better to do this now, in case the */
+ /* complicated comparison code somehow corrupts one of the images. */
+ is_image= ((len_file1 == len_file2) &&
+ (memcmp(p_file1,p_file2,(size_t) len_file1) == 0));
+
+ /* This anonymous block performs the actual comparison. */
+ {
+ /* The comparison is performed by scrolling the two input files through two */
+ /* fixed-length line buffers (buf1 and buf2 - see below). To avoid copying, */
+ /* the buffers are made circular. Processing takes place by comparing the */
+ /* first line of each buffer. If the line is the same, the buffers are */
+ /* scrolled by one line. If they are different, then we have encountered a */
+ /* DIFFERENCES SECTION and we have to compare lines near the top of the */
+ /* buffers to find a match. When a match is found, each buffer is scrolled */
+ /* down to its match point and processing continues. */
+
+/* LBUFSIZ is the number of number of lines that each buffer can hold. */
+/* Lines are indexed from [0,LBUFSIZ-1]. */
+/* WARNING: LBUFSIZ must be a power of two corresponding to WRAP(X). */
+/* WARNING: Totally different input files will provoke O(LBUFSIZ^2) */
+/* checksum comparisons per LBUFSIZ input lines. */
+/* WRAP(X) is a macro that performs wraparound of buffer indices. */
+/* GAP is the number of lines that have to match to end a diff section. */
+/* MAXDIST is the maximum "distance" that is tested when matching. */
+#define LBUFSIZ 64
+#define WRAP(X) ((X) & 0x3F)
+#define GAP 3
+#define MAXDIST (LBUFSIZ-GAP)
+
+/* The following macro compares two lines in the buffers. */
+/* The arguments are absolute buffer indices, not relative ones. */
+/* We assume that checksums will mismatch more often than line lengths. */
+#define COMPLINE(INDA,INDB) \
+ ((buf1[INDA].c_line == buf2[INDB].c_line) && \
+ (buf1[INDA].l_line == buf2[INDB].l_line) && \
+ (memcmp(buf1[INDA].p_line,buf2[INDB].p_line, \
+ (size_t) buf1[INDA].l_line)==0))
+
+ /* The two line buffers buf1 and buf2 (see below) don't actually store */
+ /* lines. Instead they store line structures which store pointers to the */
+ /* lines in the mapped images of the files. They also store the length of */
+ /* each line, and a checksum of the line. The checksum is useful for */
+ /* speeding up the comparisons between lines when processing a differences */
+ /* section. */
+ typedef
+ struct
+ {
+ char *p_line; /* Pointer to first byte in the line. */
+ ulong l_line; /* Number of bytes in the line. */
+ uword c_line; /* Checksum of the line. */
+ } line_t;
+
+ char *p_next1 = p_file1; /* Points to next line in file1. */
+ char *p_next2 = p_file2; /* Points to next line in file2. */
+ char *p_post1 = p_file1+len_file1; /* Byte following image of file1. */
+ char *p_post2 = p_file2+len_file2; /* Byte following image of file2. */
+ line_t buf1[LBUFSIZ]; /* Comparison buffer for first file. */
+ line_t buf2[LBUFSIZ]; /* Comparison buffer for second file. */
+ ulong buf1top = 0; /* Index of first line in first buffer. */
+ ulong buf2top = 0; /* Index of first line in second buffer. */
+ ulong buf1fil = 0; /* Number of lines in first buffer. */
+ ulong buf2fil = 0; /* Number of lines in second buffer. */
+ ulong topnum1 = 1; /* Line number of first line of first buffer. */
+ ulong topnum2 = 1; /* Line number of first line of second buffer. */
+
+ /* The following loop compares the line(s) at the top of the two buffers */
+ /* and processes (lines1,lines2) lines of each. */
+ while (TRUE)
+ {
+ ulong lines1; /* Lines of file1 processed during this loop iteration. */
+ ulong lines2; /* Lines of file2 processed during this loop iteration. */
+ ulong d,g; /* Used in comparison loops. */
+
+ /* The first thing we do is to fill each buffer as full as possible. At */
+ /* the end of the next two lumps of code, the only reason that a file's */
+ /* is not full is that we have reached the end of the file. */
+
+ /* Fill the first buffer as full as possible. */
+ while ((buf1fil < LBUFSIZ) && (p_next1 != p_post1))
+ {
+ ulong ind = WRAP(buf1top + buf1fil);
+ ulong len = 0;
+ uword csum = 0;
+ char *p_lin = p_next1;
+ while (TRUE)
+ {
+ if (p_next1 == p_post1) break;
+ len++;
+ csum=(csum+*p_next1++) & 0xFFFF;
+ if (*(p_next1-1) == EOL) break;
+ }
+ buf1[ind].p_line = p_lin;
+ buf1[ind].l_line = len;
+ buf1[ind].c_line = csum;
+ buf1fil++;
+ }
+
+ /* Fill the second buffer as full as possible. */
+ while ((buf2fil < LBUFSIZ) && (p_next2 != p_post2))
+ {
+ ulong ind = WRAP(buf2top + buf2fil);
+ ulong len = 0;
+ uword csum = 0;
+ char *p_lin = p_next2;
+ while (TRUE)
+ {
+ if (p_next2 == p_post2) break;
+ len++;
+ csum=(csum+*p_next2++) & 0xFFFF;
+ if (*(p_next2-1) == EOL) break;
+ }
+ buf2[ind].p_line = p_lin;
+ buf2[ind].l_line = len;
+ buf2[ind].c_line = csum;
+ buf2fil++;
+ }
+
+ /* If the buffers are empty then we must be at the end of each file. */
+ if (buf1fil==0 && buf2fil==0)
+ break;
+
+ /* Try to peel a pair of matching lines off the top of the buffer. */
+ /* If we succeed, zip down to the end of the loop and flush them. */
+ /* We can't integrate this code into the next part because the next part */
+ /* requires GAP matches, whereas here we require just one. */
+ if ((buf1fil>0) && (buf2fil>0) && COMPLINE(buf1top,buf2top))
+ {lines1=lines2=1; goto flushlines;}
+
+ /* At this point, we know we have a differences section. */
+ anydiff=TRUE;
+
+ /* We now compare the top lines of the two buffers for a match. A match */
+ /* is only considered to have been found if we match GAP consecutive */
+ /* lines. The best match minimizes the DISTANCE which is the sum of the */
+ /* offsets (lines1,lines2) (in lines) from the top of each buffer where */
+ /* the match starts. Even better matches minimize abs(lines1-lines2) as */
+ /* well. All these nested loops are to ensure that we search best first. */
+ for (d=1;d<=MAXDIST;d++)
+ {
+ /* Calculate half distance on the high side. */
+ long half = (d/2)+1;
+ long off;
+ long sign_v;
+ /* Explore up and down simultaneously from the halfway mark. */
+ for (off=0;off<=half;off++)
+ for (sign_v= -1;sign_v<2;sign_v+=2)
+ {
+ long x = half + sign_v*off;
+ /* The following test allows the above loops to be sloppy. */
+ if (0<=x && x<=d)
+ {
+ lines1=x;
+ lines2=d-lines1;
+ /* We now know that we want to test at (lines1,lines2). */
+ /* So compare the GAP lines starting at those positions. */
+ /* Note: lines1 and lines2, as well as being the number */
+ /* of lines processed, are also the offset to the first */
+ /* match line in our match gap. */
+ for (g=0;g<GAP;g++)
+ { /* Note: R for relative, A for absolute. */
+ ulong t1r = lines1 + g;
+ ulong t2r = lines2 + g;
+ ulong t1a,t2a;
+
+ /* If both files have run out at this point, it's a match!*/
+ if ((t1r>=buf1fil) && (t2r>=buf2fil)) continue;
+
+ /* If just one of the files has run out it's a mismatch. */
+ if ((t1r>=buf1fil) || (t2r>=buf2fil)) goto gapfail;
+
+ /* We now know that we have two real lines. Compare them. */
+ /* Variables are to avoid big nested macro expansions. */
+ t1a = WRAP(buf1top+t1r);
+ t2a = WRAP(buf2top+t2r);
+ if (!COMPLINE(t1a,t2a)) goto gapfail;
+ }
+ /* If we dropped out of the gap loop, we must have found */
+ /* GAP consecutive matches. So we can run off and write out */
+ /* the difference section. */
+ goto writediff;
+
+ /* Here's where we jump if we found a mismatch during gap */
+ /* looping. All we do is try next pair of offsets. */
+ gapfail:;
+ } /* End sloppy if. */
+ } /* End for sign_v. */
+ } /* End for distance loop. */
+
+ /* If we got to here then we must have dropped out of the search loop */
+ /* which means that there must have been no match at all between the */
+ /* buffers. The only thing to do is to write out what we have as */
+ /* a differences section. */
+ lines1=buf1fil;
+ lines2=buf2fil;
+
+ /* Write out the differences section (lines1,lines2) to the log file. */
+ writediff:
+ { /* Begin writediff */
+ ulong i,j;
+ LOGSTR("\n");
+ LOGSTR(" +-----\n");
+ for (i=0;i<lines1;i++)
+ {
+ ulong nline = WRAP(buf1top+i);
+ sprintf(linet1,"%05lu|",(ulong) topnum1+i); LOGLINE;
+ for (j=0;j<buf1[nline].l_line;j++)
+ LOGCHAR(*(buf1[nline].p_line+j));
+ }
+ LOGSTR(" +-----\n");
+ for (i=0;i<lines2;i++)
+ {
+ ulong nline = WRAP(buf2top+i);
+ sprintf(linet1,"%05lu|",(ulong) topnum2+i); LOGLINE;
+ for (j=0;j<buf2[nline].l_line;j++)
+ LOGCHAR(*(buf2[nline].p_line+j));
+ }
+ LOGSTR(" +-----\n");
+ } /* End writediff. */
+
+ /* Flush from buffer however many lines we ended up processing. */
+ flushlines:
+ buf1top=WRAP(buf1top+lines1); topnum1+=lines1; buf1fil-=lines1;
+ buf2top=WRAP(buf2top+lines2); topnum2+=lines2; buf2fil-=lines2;
+
+ } /* End the while loop that runs through the two files. */
+ } /* End of anonymous block for doing actual comparison. */
+
+ /* The anydiff flag tells us if the loop found any difference sections. */
+ is_same=!anydiff;
+
+ /* Target position if we couldn't map in the input files earlier. */
+ frombadmap:
+
+ /* Release the memory allocated by the mapper for the input files. */
+ /* Failure to do this will result in a memory leak! */
+ mm_zapt();
+
+ /* If the two files are identical, tell the log file. */
+ if (is_same)
+ LOGSTR("The two files are IDENTICAL.\n");
+
+ /* Invalidate this test in the log file, if inconsistent (see later). */
+ if (is_same != is_image)
+ LOGSTR("<<CONSISTENCY FAILURE: ABOVE COMPARISON INVALID>>\n");
+
+ /* If we had problems with the log file at any stage, kick up a fuss now. */
+ if (badwrite)
+ {wl_sj("S: DIFF: Error writing to log file."); num_sev++;}
+
+ /* Close the log file. */
+ if (fclose(logfile) == FCLOSE_F)
+ {wl_sj("S: DIFF: Error closing the log file."); num_sev++;}
+
+ /* The above code is quite tricky and there is a chance that it contains */
+ /* bugs. So, as a safety check we compare the results from the binary memory */
+ /* image comparison performed earlier and the more complicated text */
+ /* comparison above. If they differ, then it's time to go kaboom. */
+ if (is_image && !is_same)
+ as_bomb("do_diff: Image comparison succeeded, but text comparison failed.");
+ if (!is_image && is_same)
+ as_bomb("do_diff: Image comparison failed, but text comparison succeeded.");
+
+ /* If files are non-same and ABORT option is turned on, set severe status. */
+ if (!is_same && diffabort)
+ {
+ wl_sj(
+ "S: DIFF: Files have not been proven identical, and ABORT option is on.");
+ num_sev++;
+ }
+
+ /* Tell the console whether comparison succeeded. */
+ if (is_same)
+ wl_sj("The two files are IDENTICAL.");
+ else
+ wl_sj("The two files are DIFFERENT (see the differences file for the details).");
+
+ /* Increment the difference summary counters. */
+ difftotl++;
+ if (is_same)
+ diffsucc++;
+}
+
+/******************************************************************************/
+
+LOCAL void do_dsum P_((void));
+LOCAL void do_dsum ()
+{
+ sprintf(linet1,"Summary of Differences"); wl_sj(linet1);
+ sprintf(linet1,"----------------------"); wl_sj(linet1);
+ sprintf(linet1,"Identical = %lu.",(ulong) diffsucc); wl_sj(linet1);
+ sprintf(linet1,"Different = %lu.",(ulong) (difftotl-diffsucc)); wl_sj(linet1);
+ sprintf(linet1,"Total = %lu.",(ulong) difftotl); wl_sj(linet1);
+}
+
+/******************************************************************************/
+
+LOCAL void do_dzer P_((void));
+LOCAL void do_dzer ()
+/* Zaps difference counters. */
+{
+ difftotl = 0;
+ diffsucc = 0;
+}
+
+/******************************************************************************/
+
+LOCAL void do_eneo P_((void));
+LOCAL void do_eneo ()
+{
+ if (arg_num != 2)
+ {
+ wl_sj("S: The ENEO command must be given exactly one argument.");
+ num_sev++;
+ return;
+ }
+ if (fexists(arg_arr[1]))
+ if (remove(arg_arr[1]) != REMOVE_S)
+ {
+ sprintf(linet1,"S: ENEO failed to delete \"%s\".",arg_arr[1]);
+ wl_sj(linet1);
+ num_sev++;
+ return;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void do_exec P_((void));
+LOCAL void do_exec ()
+{
+ uword i;
+
+ if (arg_num < 2)
+ {
+ wl_sj("S: The EXECUTE command requires at least one argument.");
+ num_sev++;
+ return;
+ }
+ if (arg_num > 10)
+ {
+ wl_sj("S: The EXECUTE command can have at most nine arguments.");
+ num_sev++;
+ return;
+ }
+
+ /* Zap all the numeric arguments. */
+ for (i=0; i<10; i++)
+ subval[i][0]=EOS;
+
+ /* Copy the arguments over to the $1 $2 etc substitution variables. */
+ for (i=1;i<arg_num; i++)
+ strcpy(subval[i-1],arg_arr[i]);
+
+ /* Run up a new FunnelWeb shell and interpret the file. */
+ interstr(arg_arr[1]);
+}
+
+/******************************************************************************/
+
+LOCAL void do_exist P_((void));
+LOCAL void do_exist ()
+{
+ if (arg_num != 2)
+ {
+ wl_sj("S: The EXISTS command requires exactly one argument.");
+ num_sev++;
+ return;
+ }
+ if (!fexists(arg_arr[1]))
+ {
+ sprintf(linet1,"S: EXISTS failed to find \"%s\".",arg_arr[1]);
+ wl_sj(linet1);
+ num_sev++;
+ return;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void do_fix P_((void));
+LOCAL void do_fix ()
+/* When the test suite is moved from one machine to another, it is possible */
+/* that at some stage it will be moved using a BINARY transfer rather than a */
+/* text file transfer. The result is that the test files will contain lines */
+/* terminated with a sequence of control characters that the local buffered */
+/* IO library will not convert to '\n' upon reading in. The are a few */
+/* solutions to this problem, but one of the most direct is to have a command */
+/* such as this one that can convert the file over. */
+/* */
+/* Once we have identified an end of line, it is easy to write it out as we */
+/* can just send a '\n' and the local buffered IO library will write the */
+/* right codes for us. The tricky part is deciding what an EOL is in the */
+/* input stream. Well, I could have made the control characters for the */
+/* remote EOL a parameter of this command, but instead I decided to use a */
+/* simple algorithm that should cover nearly all cases... */
+/* ALGORITHM: Parse the input into alternating blocks of control characters */
+/* and non-control characters. Parse each block of control characters into */
+/* subblocks by parsing it from left to right and starting a new subblock the */
+/* moment a character of the subblock currently being parsed appears again. */
+/* This covers at least the following cases, and probably many more: */
+/* UNIX LF */
+/* MSDOS CR LF */
+/* Macintosh CR */
+{
+ /* Erk! But I found out the hard way, it doesn't work on a VAX! */
+ /* I'm making this do nothing on a VAX rather than generate an error as I */
+ /* want the scripts to work silently on the VAX without modification. */
+#if !VMS
+ FILE *infile; /* File variable for input file. */
+ FILE *tmpfile; /* File variable for temporary output file. */
+ char *p_target; /* Name of final (target) output file. */
+ STAVAR char *p_temp=NULL; /* Name of temporary output file. */
+
+ bool seen[256]; /* TRUE if char is in current control sequence. */
+ char undo[256]; /* undo[0..length-1] contains current control sequence. */
+ uword length; /* Number of control bytes in our buffer. */
+ uword i;
+ int status;
+
+ /* Allocate the temporary file name if not already allocated. */
+ if (p_temp==NULL) p_temp=(p_fn_t) mm_perm(sizeof(fn_t));
+
+ /* We can take one or two arguments. One argument means that we should */
+ /* fix up the input file, leaving the result in the input file. */
+ if (arg_num != 2 && arg_num != 3)
+ {
+ wl_sj("S: The FIXEOLS command requires one or two filename arguments.");
+ num_sev++;
+ return;
+ }
+
+ /* Change to two arguments if the input name is the same as output name. */
+ if (arg_num==3 && strcmp(arg_arr[1],arg_arr[2])==0) arg_num=2;
+
+ /* Work out what the target name is going to be. */
+ p_target=(arg_num==2) ? arg_arr[1] : arg_arr[2];
+
+ /* Generate a temporary filename for the output file. This is tricky because */
+ /* on many machines, one cannot rename across devices or directories. This */
+ /* means that the temporary file has to be created in the same directory as */
+ /* the file that we are going to rename it to later (the target file). */
+ strcpy(p_temp,p_target);
+ fn_ins(p_temp,fn_temp());
+
+ /* Open the input file for BINARY reading. */
+ infile=fopen(arg_arr[1],"rb");
+ if (infile == FOPEN_F)
+ {
+ sprintf(linet1,"S: FIXEOLS: Error opening \"%s\".",arg_arr[1]);
+ wl_sj(linet1);
+ num_sev++;
+ return;
+ }
+
+ /* Create the output file for TEXT writing. */
+ tmpfile=fopen(p_temp,"w");
+ if (tmpfile == FOPEN_F)
+ {
+ fclose(infile);
+ wl_sj("S: FIXEOLS: Error creating the temporary output file.");
+ num_sev++;
+ return;
+ }
+
+ /* Initialialize the control character buffer to empty. */
+ for (i=0;i<256;i++) seen[i]=FALSE;
+ length=0;
+
+ while (TRUE)
+ {
+ /* Read in the next character from the input file. */
+ char ch=getc(infile);
+ if (ferror(infile))
+ {wl_sj("S: FIXEOLS: Error reading the input file.");num_sev++;return;}
+ if (feof(infile)) break;
+
+ /* Does character terminate a non-empty buffer? If so, flush it. */
+ if (length>0 && (isascprn(ch) || seen[ch]))
+ {
+ if (fputc(EOL,tmpfile) == FPUTC_F) goto write_failure;
+ for (i=0;i<length;i++) seen[undo[i]]=FALSE;
+ length=0;
+ }
+
+ /* Now we can approach the character cleanly and freshly. */
+ if (isascprn(ch))
+ {if (fputc(ch,tmpfile) == FPUTC_F) goto write_failure;}
+ else
+ {undo[length++]=ch; seen[ch]=TRUE;}
+ }
+ if (length>0)
+ {if (fputc(EOL,tmpfile) == FPUTC_F) goto write_failure;}
+
+ if (fflush(tmpfile) != FFLUSH_S)
+ {wl_sj("S: FIXEOLS: Error flushing the temporary output file.");num_sev++;return;}
+ if (fclose(infile) == FCLOSE_F)
+ {wl_sj("S: FIXEOLS: Error closing the input file.");num_sev++;return;}
+ if (fclose(tmpfile) == FCLOSE_F)
+ {wl_sj("S: FIXEOLS: Error closing the temporary output file.");num_sev++;return;}
+
+ /* If renaming to the input file, we have to delete the input file first. */
+ if (arg_num==2)
+ {
+ status=remove(arg_arr[1]);
+ if (status != REMOVE_S)
+ {
+ wl_sj("S: FIXEOLS: Error deleting existing input file to replace it");
+ wl_sj(" with the temporary output file. Deleting temporary and aborting...");
+ remove(p_temp);
+ num_sev++;
+ return;
+ }
+ }
+
+ /* Rename the temporary file to the target output file. */
+ status=rename(p_temp,p_target);
+
+ /* Do the error checking. */
+ if (status != RENAME_S)
+ {
+ wl_sjl("S: FIXEOLS: Error renaming temporary output file to output file.");
+ sprintf(linet1,"Temporary file name was \"%s\".",p_temp);
+ wl_sjl(linet1);
+ sprintf(linet1,"Output file name was \"%s\".",p_target);
+ wl_sjl(linet1);
+ wl_sjl("FunnelWeb will leave both files intact so you can look at them.");
+ num_sev++;
+ return;
+ }
+
+ return;
+
+ write_failure:
+ wl_sj("S: FIXEOLS: Error writing the output file.");num_sev++;return;
+#endif
+}
+
+/******************************************************************************/
+
+LOCAL void do_fweb P_((char *));
+LOCAL void do_fweb(p_cl)
+/* This function performs a single run of FunnelWeb proper. */
+char *p_cl;
+{
+ op_t saveop;
+
+ /* Do set can do all the work for us. However, it operates on p_defopt so we */
+ /* have to do some juggling. */
+ ASSIGN(saveop,*p_defopt);
+ do_set(p_cl);
+ ASSIGN(option,*p_defopt);
+ ASSIGN(*p_defopt,saveop);
+ if (num_sev>0) return;
+
+ /* do_set ensures that the user hasn't specified any action parameters such */
+ /* as +X and +K, but it necessarily doesn't check to make sure that the user */
+ /* has actually specified an input file! */
+ if (!option.op_f_b)
+ {
+ wl_sj("S: No input file specified in FW command.");
+ num_sev++;
+ return;
+ }
+ fwonerun();
+}
+
+/******************************************************************************/
+
+LOCAL void do_help P_((void));
+LOCAL void do_help()
+{
+ uword messno;
+
+ if (arg_num == 1)
+ {
+ hel_wri(wr_sj,HL_MEN);
+ return;
+ }
+ if (arg_num > 2)
+ {
+ wl_sj("S: The HELP command takes at most one argument.");
+ num_sev++;
+ return;
+ }
+
+ /* Translate message name to number. */
+
+ messno=hel_num(arg_arr[1]);
+ if (messno == HL_ERR)
+ {
+ wl_sj(
+ "S: Unrecognised help message name. Try just \"help\" for a list of names.");
+ num_sev++;
+ return;
+ }
+
+ hel_wri(wr_sj,messno);
+}
+
+/******************************************************************************/
+
+LOCAL void do_set(p_comlin)
+/* The SET command allows the user to specify default FunnelWeb options. */
+char *p_comlin;
+{
+ op_t tmpopt;
+
+ /* Experiment with temporary options, not the real thing. */
+ ASSIGN(tmpopt,*p_defopt);
+
+ /* Now execute the effect of the command line on 'p_defopt'. */
+ if (!op_add(&tmpopt,p_comlin,wr_sj))
+ {
+ wl_s("This is a severe error (S). Aborting to FunnelWeb shell...");
+ num_sev++;
+ return;
+ }
+
+ /* Now make sure that the user didn't specify an option to do with the */
+ /* entire FunnelWeb run and not just this invocation of FunnelWeb proper. */
+ if (tmpopt.op_j_b)
+ {
+ wl_s("S: You cannot invoke FunnelWeb with +J from the FunnelWeb shell.");
+ wl_s(" To create a journal file, exit FunnelWeb and reinvoke with \"fw +j\".");
+ wl_s("This is a severe error. Aborting to FunnelWeb shell...");
+ num_sev++;
+ return;
+ }
+ if (tmpopt.op_x_b)
+ {
+ wl_s("S: You cannot invoke FunnelWeb with +X from the FunnelWeb shell.");
+ wl_s("Use the interactive command EXECUTE instead.");
+ wl_s("This is a severe error. Aborting to FunnelWeb shell...");
+ num_sev++;
+ return;
+ }
+ if (tmpopt.op_k_b)
+ {
+ wl_s("S: You cannot invoke FunnelWeb with +K from the FunnelWeb shell.");
+ wl_s("This is a severe error. Aborting to FunnelWeb shell...");
+ num_sev++;
+ return;
+ }
+ if (tmpopt.op_h_b)
+ {
+ wl_s("S: You cannot invoke FunnelWeb with +H from the FunnelWeb shell.");
+ wl_s("Use the interactive command HELP instead.");
+ wl_s("This is a severe error. Aborting to FunnelWeb shell...");
+ num_sev++;
+ return;
+ }
+
+ /* If we get to here, the options must be OK so we can set them as default. */
+ ASSIGN(*p_defopt,tmpopt);
+}
+
+/******************************************************************************/
+
+LOCAL void do_show P_((void));
+LOCAL void do_show()
+/* The SHOW command writes out the current options. */
+{
+ if (arg_num != 1)
+ {
+ wl_sj("S: The SHOW command does not take arguments.");
+ num_sev++;
+ return;
+ }
+ wl_sj("Here are the FunnelWeb command line options that are");
+ wl_sj("current in this FunnelWeb session:");
+ op_wri(p_defopt,wr_sj);
+}
+
+/******************************************************************************/
+
+LOCAL void do_stat P_((void));
+LOCAL void do_stat ()
+/* The status command checks the number of diagnostics generated by the run. */
+{
+ uword i;
+ char *thing;
+ ulong cnum;
+
+ if (arg_num<1 || arg_num>4)
+ {
+ wl_sj("S: The STATUS command requires zero to three arguments.");
+ num_sev++;
+ return;
+ }
+
+ /* Zero arguments just means write out status. */
+ if (arg_num == 1)
+ {
+ sprintf(linet1,"Last command: Severes=%lu, Errors=%lu, Warnings=%lu.",
+ (ulong) old_sev, (ulong) old_err, (ulong) old_war);
+ wl_sj(linet1);
+ sprintf(linet1,"Totals : Severes=%lu, Errors=%lu, Warnings=%lu.",
+ (ulong) sum_sev, (ulong) sum_err, (ulong) sum_war);
+ wl_sj(linet1);
+ return;
+ }
+
+ /* More than one argument means CHECK status. */
+ for (i=1;i<arg_num;i++)
+ {
+ char ch=toupper(arg_arr[i][0]);
+ unsigned num;
+ if (ch!='W' && ch!='E' && ch!='S')
+ {
+ sprintf(linet1,
+ "S: Argument %u of STATUS command has bad letter.",
+ (unsigned) i);
+ wl_sj(linet1);
+ wl_sj("Arguments must be of the form ('W'|'E'|'S')<decimalnumber>.");
+ num_sev++;
+ return;
+ }
+ if (sscanf(&arg_arr[i][1],"%u",&num) != 1)
+ {
+ sprintf(linet1,
+ "S: Argument %u of STATUS command has bad number.",
+ (unsigned) i);
+ wl_sj(linet1);
+ wl_sj(" Arguments must be of the form ('W'|'E'|'S')<decimalnumber>.");
+ num_sev++;
+ return;
+ }
+ switch(ch)
+ {
+ case 'W': cnum=old_war; thing="warnings"; break;
+ case 'E': cnum=old_err; thing="errors" ; break;
+ case 'S': cnum=old_sev; thing="severes" ; break;
+ default : as_bomb("do_stat: case defaulted.");
+ }
+ if (cnum != num)
+ {
+ sprintf(linet1,
+ "S: STATUS command detected wrong number of %s.",thing);
+ wl_sj(linet1);
+ sprintf(linet1, "Specifed %s=%u, Actual %s=%u.",
+ thing,(unsigned) num,thing,(unsigned) cnum);
+ wl_sj(linet1);
+ num_sev++;
+ }
+ }
+}
+
+/******************************************************************************/
+
+
+LOCAL void do_trace P_((void));
+LOCAL void do_trace()
+{
+ if (arg_num != 2) goto help;
+ strupper(arg_arr[1]);
+ if (strcmp(arg_arr[1],"OFF") == 0) {tracing=FALSE; return;}
+ if (strcmp(arg_arr[1], "ON") == 0) {tracing=TRUE ; return;}
+
+ help:
+ wl_sj("S: The TRACE command has two forms:");
+ wl_sj(" TRACE OFF");
+ wl_sj(" TRACE ON");
+ num_sev++;
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_write P_((char *));
+LOCAL void do_write(p)
+char *p;
+{
+ uword len;
+
+ /* Skip over the main command and the following blanks. */
+ while (*p!=' ' && *p!=EOS) p++;
+ while (*p==' ') p++;
+
+ /* Now make sure that the remaining string is delimited by double quotes. */
+ len=strlen(p);
+ if ((*p != '\"') || (p[len-1] != '\"') || len<2)
+ {
+ wl_sj("W: The argument to WRITE should be delimited by double quotes.");
+ wl_sj(p);
+ num_war++;
+ return;
+ }
+
+ /* Now temporarily hack out the quotes and write out the string. */
+ p[len-1]=EOS;
+ wl_sj(p+1);
+ p[len-1]='\"';
+}
+
+/******************************************************************************/
+
+LOCAL void do_writu P_((char *));
+LOCAL void do_writu(p)
+char *p;
+{
+ uword len;
+
+ /* Skip over the main command and the following blanks. */
+ while (*p!=' ' && *p!=EOS) p++;
+ while (*p==' ') p++;
+
+ /* Now make sure that the remaining string is delimited by double quotes. */
+ len=strlen(p);
+ if ((*p != '\"') || (p[len-1] != '\"') || len<2)
+ {
+ wl_sj("W: The argument to WRITEU should be delimited by double quotes.");
+ wl_sj(p);
+ num_war++;
+ return;
+ }
+
+ /* Now temporarily hack out the quotes and write out the string. */
+ p[len-1]=EOS;
+ wl_sj(p+1);
+ p[len-1]='\"';
+
+ /* Now write out another line underlining the above. */
+ {uword i; for (i=0;i<len-2;i++) wr_sj("-"); wl_sj("");}
+}
+
+/******************************************************************************/
+
+LOCAL bool do_command P_((char *));
+LOCAL bool do_command(p_command)
+/* Execute a single FunnelWeb shell command. */
+char *p_command;
+{
+ char *v;
+ bool result=FALSE;
+
+ zerdia();
+
+ /* Check the command for non-printables. */
+ {
+ char *s=p_command;
+ while (*s!=EOS)
+ {
+ if (!isascprn(*s))
+ {
+ sprintf(linet1,
+ "S: Command line has non-printable at column %u.",
+ (unsigned) (s-p_command)+1);
+ wl_sj(linet1);
+ num_sev++;
+ goto finished;
+ }
+ s++;
+ }
+ }
+
+ /* Perform substitutions. */
+ dollsub(p_command); if (num_sev>0) goto finished;
+
+ /* Ignore commands consisting entirely of blanks (or empty commands). */
+ {
+ char *s=p_command;
+ while (*s==' ') s++;
+ if (*s==EOS) goto finished;
+ }
+
+ /* Reject command lines beginning with a blank. */
+ if (p_command[0]==' ')
+ {
+ wl_sj("S: Leading blanks are not allowed in command lines.");
+ num_sev++;
+ goto finished;
+ }
+
+ /* Ignore command lines commencing with the comment character. */
+ if (p_command[0]=='!')
+ {restdia(); goto finished;}
+
+ /* Parse the command line into arguments. */
+ explode(p_command);
+
+ /* Complain if there is no command verb. */
+ as_cold(arg_num>0,"do_command: zero arguments!");
+
+ /* It's convenient to have v pointing to verb. */
+ v=arg_arr[0];
+
+ /* Convert the verb to upper case. */
+ strupper(v);
+
+
+ /* Execute the verb. */
+
+ if (strcmp(v,"HERE")==0) skipping=FALSE;
+ else if (!skipping)
+ if (strcmp(v,"ABSENT" )==0) do_absen();
+ else if (strcmp(v,"CODIFY" )==0) do_cody ();
+ else if (strcmp(v,"COMPARE" )==0) do_comp ();
+ else if (strcmp(v,"DEFINE" )==0) do_defin(&p_command[0]);
+ else if (strcmp(v,"DIFF" )==0) do_diff();
+ else if (strcmp(v,"DIFFSUMMARY")==0) do_dsum();
+ else if (strcmp(v,"DIFFZERO" )==0) do_dzer();
+ else if (strcmp(v,"ENEO" )==0) do_eneo ();
+ else if (strcmp(v,"EXECUTE" )==0) do_exec ();
+ else if (strcmp(v,"EXISTS" )==0) do_exist();
+ else if (strcmp(v,"FIXEOLS" )==0) do_fix ();
+ else if (strcmp(v,"FW" )==0) do_fweb (&p_command[0]);
+ else if (strcmp(v,"HELP" )==0) do_help ();
+ else if (strcmp(v,"QUIT" )==0) result=TRUE;
+ else if (strcmp(v,"SET" )==0) do_set (&p_command[0]);
+ else if (strcmp(v,"SHOW" )==0) do_show ();
+ else if (strcmp(v,"SKIPTO" )==0) skipping=TRUE;
+ else if (strcmp(v,"STATUS" )==0) do_stat ();
+ else if (strcmp(v,"TOLERATE" )==0) noabort=TRUE;
+ else if (strcmp(v,"TRACE" )==0) do_trace();
+ else if (strcmp(v,"WRITE" )==0) do_write(&p_command[0]);
+ else if (strcmp(v,"WRITEU" )==0) do_writu(&p_command[0]);
+ else
+ {
+ /* The following trace is likely to confuse beginners. */
+ /* sprintf(linet1,"Expanded command line=\"%s\".",p_command); */
+ /* wl_sj(linet1); */
+ wl_sj("S: Unknown command. Type HELP for a list of commands.");
+ num_sev++;
+ goto finished;
+ }
+
+ finished:
+ sumdia();
+ return result;
+}
+
+/******************************************************************************/
+
+LOCAL void interpret P_((FILE *,char *));
+LOCAL void interpret(p_file,filnam)
+/* p_file must be a file opened for reading. The file's name must be supplied */
+/* in filnam for error reporting reasons. The function reads each line from */
+/* the file and feeds it to the FunnelWeb interpreter command executer. */
+FILE *p_file;
+char *filnam;
+{
+ ulong lineno=0;
+ char *result;
+ bool b;
+ cl_t comline;
+ char *p_comline;
+
+ p_comline = &comline[0];
+
+ while (TRUE)
+ {
+ bool oldnoabort = noabort;
+ noabort=FALSE;
+
+ if (p_file == stdin || tracing)
+ wr_sj("FunnelWeb>");
+
+ result=fgets(p_comline,(int) COMLINE_FWMAX,p_file);
+ if (feof(p_file))
+ {
+ sprintf(linet1,"<End of Script File \"%s\">",filnam);
+ if (p_file == stdin || tracing)
+ wl_sj(linet1);
+ break;
+ }
+ if (ferror(p_file) || (result == FGETS_FE))
+ {
+ sprintf(linet1,"F: Error reading command file \"%s\".",filnam);
+ wl_sj(linet1);
+ wl_sj("Aborting...");
+ sum_fat++;
+ return;
+ }
+ if (p_file == stdin || tracing) wr_j(p_comline);
+ if (p_file != stdin && tracing) wr_s(p_comline);
+
+ lineno++;
+ if (strlen(p_comline)==COMLINE_FWMAX)
+ {
+ sprintf(linet1,"F: Line %lu of command file \"%s\" is too long.",
+ (unsigned long) lineno,filnam);
+ wl_sj(linet1);
+ wl_sj("Aborting...");
+ sum_fat++;
+ return;
+ }
+ as_cold(p_comline[strlen(p_comline)-1]==EOL,"interpret: NO NEWLINE!");
+ p_comline[strlen(p_comline)-1]=EOS;
+ as_cold(strlen(p_comline)<COMLINE_FWMAX,"interpret: Filename too long.");
+
+ b=do_command(p_comline);
+ if (b) break;
+
+ if (sum_fat>0) break;
+ if ((p_file != stdin) && (num_sev+num_err>0) && !oldnoabort)
+ {
+ wl_sj("Error caused termination of FunnelWeb shellscript.");
+ break;
+ }
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void interstr(filnam)
+/* The 'interpret' function (above) interprets each line of a file already */
+/* opened for reading. This function does a little more, opening and closing */
+/* the file before and after calling 'interpret'. */
+char *filnam;
+{
+ FILE *p_file;
+ fn_t fn;
+
+ /* Set up a default of ".fws" as a file extension. */
+ strcpy(&fn[0],".fws");
+
+ /* Inherit the actual filename. */
+ as_cold(strlen(filnam)<=FILENAME_FWMAX,"interstr: Filename blasted.");
+ fn_ins(&fn[0],filnam);
+
+ p_file=fopen(fn,"r");
+ if (p_file == FOPEN_F)
+ {
+ sprintf(linet1,"S: Error opening command file \"%s\".",fn);
+ wl_sj(linet1);
+ sum_sev++;
+ return;
+ }
+
+ interpret(p_file,&fn[0]); if (sum_fat>0) return;
+
+ if (fclose(p_file) == FCLOSE_F)
+ {
+ sprintf(linet1,"F: Error closing command file \"%s\".",fn);
+ wl_sj(linet1);
+ wl_sj("Aborting...");
+ sum_fat++;
+ return;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void chk_cline P_((void));
+LOCAL void chk_cline()
+/* Checks to make sure that the command line specifies exactly one action. */
+{
+ uword countopt=0;
+
+ /* Count the number of active action options are turned on. */
+ if (p_comopt->op_f_b) countopt++;
+ if (p_comopt->op_x_b) countopt++;
+ if (p_comopt->op_k_b) countopt++;
+ if (p_comopt->op_h_b) countopt++;
+
+ if (countopt == 0)
+ {
+ wl_sj("Your command line does not specify an action.");
+ wl_sj("Here some common ways of invoking FunnelWeb.");
+ wl_sj("");
+ wl_sj(" fw filename Tangle filename.web.");
+ wl_sj(" fw filename +t Tangle and weave filename.web.");
+ wl_sj(" fw +k Enter interactive mode.");
+ wl_sj(" fw +xfilename Execute FunnelWeb shellscript filename.fws.");
+ wl_sj(" fw +h Display help information about FunnelWeb.");
+ wl_sj("");
+ if (countopt == 0)
+ wl_sj("F: Aborting because command line does not specify an action.");
+ sum_fat++;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void open_j P_((void));
+LOCAL void open_j()
+/* Creates and opens the journal file. Note that the journal output stream is */
+/* established regardless of whether the user requested a journal file. The */
+/* only difference is that if the user did not specify a journal file, the */
+/* stream is created in error mode which means that it never actually writes. */
+{
+ fn_t jname;
+
+ /* Establish the journal file output stream. */
+ strcpy(jname,""); /* Start with an empty string. */
+ fn_ins(jname,p_comopt->op_f_s); /* Insert input file name. */
+ fn_ins(jname,".jrn"); /* Insert file extension. */
+ fn_ins(jname,p_comopt->op_j_s); /* Insert command line spec. */
+ wf_ini(&f_j,p_comopt->op_j_b); /* Initialize the stream. */
+ wf_ope(&f_j,jname); /* Create the file. */
+ if (p_comopt->op_j_b && wf_err(&f_j))
+ {
+ sprintf(linet1,"F: Error creating journal file \"%s\".",jname);
+ wl_s(linet1);
+ wl_s("Aborting...");
+ sum_fat++;
+ return;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void close_j P_((void));
+LOCAL void close_j()
+/* Closes the journal file. */
+{
+ if (!p_comopt->op_j_b) return;
+ if (wf_err(&f_j))
+ {
+ wl_s("F: Error writing to journal file. Aborting...");
+ sum_fat++;
+ return;
+ }
+ wf_clo(&f_j);
+ if (wf_err(&f_j))
+ {
+ wl_s("F: Error flushing and closing journal file. Aborting...");
+ sum_fat++;
+ return;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void cl_help P_((void));
+LOCAL void cl_help ()
+{
+ uword messno;
+
+ /* Translate message name to number. This ought to work, as the options */
+ /* package is already have supposed to have cleared this argument as OK. */
+ messno=hel_num(p_comopt->op_h_s);
+ as_cold(messno!=HL_ERR,"cl_help: Unknown help argument.");
+
+ /* Write out the message. */
+ hel_wri(wr_sj,messno);
+}
+
+/******************************************************************************/
+
+EXPORT void command(p_comline)
+/* Execute the top level command line. This is the place where we do all the */
+/* "once per shell" things as opposed to the "once per run" things. */
+/* If a fatal error occurs, the correct course of action here is to increment */
+/* sum_fat and return immediately. The main() function deals with delivering */
+/* the correct return status to the operating system. */
+char *p_comline;
+{
+ old_war=old_err=old_sev=0;
+
+ tracing=FALSE;
+ noabort=FALSE;
+ skipping=FALSE;
+
+ /* Allocate space for command line arguments. */
+ allocarg();
+
+ /* Set up the standard output (stdout) screen (console) output stream. */
+ wf_ini(&f_s,TRUE);
+ wf_att(&f_s,stdout);
+
+ /* Parse the command line and place the information in p_comopt-> */
+ op_ini(p_comopt);
+ if (!op_add(p_comopt,p_comline,wr_s))
+ {wr_s("F: Command line error. Aborting..."); sum_fat++; goto windup;}
+
+ /* If the user asked for some peace and quiet by setting +Q, disable the */
+ /* console stream. Note: FunnelWeb main() always issues a message using a */
+ /* printf if any diagnostics have been generated. */
+ if (p_comopt->op_q_b) wf_ini(&f_s,FALSE);
+
+ /* Create and open the journal file. */
+ open_j(); if (sum_fat>0) goto windup;
+
+ wl_sj("FunnelWeb Version 3.0 (May 1992)");
+ wl_sj("--------------------------------");
+ wl_sj("Copyright (C) Ross Williams 1992. There is ABSOLUTELY NO WARRANTY.");
+ wl_sj("You are welcome to distribute this software under certain conditions.");
+ if (p_comopt->op_k_b)
+ wl_sj("For more information, type HELP.");
+ else
+ wl_sj("For more information, use the +h (help) option (e.g. \"fw +h\").");
+ wl_sj("");
+
+ /* Ensure that the user has specified at least one action. */
+ chk_cline(); if (sum_fat>0) goto windup;
+
+ /* Establish the default options for the shell run (if any). */
+ /* Get rid of any options not to do with a single run of FunnelWeb proper. */
+ ASSIGN(*p_defopt,*p_comopt);
+ p_defopt->op_j_b=FALSE;
+ p_defopt->op_x_b=FALSE;
+ p_defopt->op_k_b=FALSE;
+
+ /* In the absence of everything else, command line options are run options. */
+ ASSIGN(option,*p_comopt);
+
+ /* Execute initialization file if any. */
+ if (fexists(INITFILE))
+ interstr(INITFILE);
+
+ /* Execute the specified actions. */
+ if (p_comopt->op_x_b) interstr(p_comopt->op_x_s);
+ if (p_comopt->op_f_b) {zerdia(); fwonerun(); sumdia();}
+ if (p_comopt->op_h_b) cl_help();
+ if (p_comopt->op_k_b) interpret(stdin,"standard_input");
+
+ /* If we weren't in onerun mode, give a grand summary of errors. */
+ if (p_comopt->op_k_b || p_comopt->op_x_b)
+ {
+ wr_sj("Final diagnostics totals: ");
+ errsum(sum_fat,sum_sev,sum_err,sum_war);
+ wl_sj(linet1);
+ }
+
+ /* Close the journal file. */
+ close_j(); if (sum_fat>0) goto windup;
+
+ /* Check for errors on the screen stream (standard output). */
+ if (p_comopt->op_s_b && wf_err(&f_s))
+ {
+ /* No point in trying to write a message to the screen! */
+ /* But we can at least register a fatal error. */
+ sum_fat++;
+ }
+
+ windup:
+
+ /* If the user has set +Q to turn off screen output and one or more */
+ /* diagnostics have been generated, we need to break through to warn the */
+ /* user. */
+ {
+ ulong sum_all=sum_fat+sum_sev+sum_err+sum_war;
+ if (p_comopt->op_q_b && sum_all>0)
+ {
+ errsum(sum_fat,sum_sev,sum_err,sum_war);
+ fprintf(stderr,"%s\n",linet1);
+ }
+ }
+}
+
+/******************************************************************************/
+/* End of COMMAND.C */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/command.h b/web/funnelAC/sources/command.h
new file mode 100644
index 0000000000..1419a7c8f8
--- /dev/null
+++ b/web/funnelAC/sources/command.h
@@ -0,0 +1,61 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* COMMAND.H */
+/******************************************************************************/
+/* */
+/* The command package is the mover and shaker of FunnelWeb. It exports a */
+/* single function, whose argument is the command line given to FunnelWeb */
+/* when it is invoked at the operating system level. The command package */
+/* routine examines the command line and executes it, possibly invoking a */
+/* mini-interpreter or calling the different component of FunnelWeb in turn */
+/* (e.g. the parser). */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+#include "machin.h"
+
+/******************************************************************************/
+
+void command P_((p_cl_t));
+/* Executes the command line which is passed as the argument. */
+
+/******************************************************************************/
+/* End of COMMAND.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/data.c b/web/funnelAC/sources/data.c
new file mode 100644
index 0000000000..7c96c7d566
--- /dev/null
+++ b/web/funnelAC/sources/data.c
@@ -0,0 +1,50 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* DATA.C */
+/******************************************************************************/
+
+/* The following definition causes the definitions in data.h to be treated */
+/* as real meaty declarations and not wimpy "external" ones. */
+#define EXTERN
+
+#include "data.h"
+
+/******************************************************************************/
+/* End of DATA.C */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/data.h b/web/funnelAC/sources/data.h
new file mode 100644
index 0000000000..019564ef03
--- /dev/null
+++ b/web/funnelAC/sources/data.h
@@ -0,0 +1,512 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* DATA.H */
+/******************************************************************************/
+/* */
+/* This package (data.h, data.c) contains ALL of the global variables in */
+/* FunnelWeb. Some of the FunnelWeb packages (e.g. the lister) harbour hidden */
+/* static state variables which could be considered to be a global variable, */
+/* but, these aside, this package contains all the variables that are used */
+/* directly by more than one package. In many programs, it would likely be */
+/* appropriate to have a separate package for each distinct group of shared */
+/* data so that only those packages needing a particular group of data need */
+/* see it. However, in FunnelWeb's case, the variables are so few, and their */
+/* use so widespread that they are clustered here in one package for all to */
+/* see. */
+/* */
+/* This package also contains type definitions for the central FunnelWeb data */
+/* structures. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_DATA
+#define DONE_DATA
+
+/******************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include "style.h"
+#include "clock.h"
+#include "list.h"
+#include "table.h"
+#include "option.h"
+#include "section.h"
+#include "writfile.h"
+
+/******************************************************************************/
+/* */
+/* DATA TYPES */
+/* ========== */
+/* The following section contains all the data types of the global variables. */
+/* */
+/******************************************************************************/
+
+/* The following structure defines a position in the global listing of the */
+/* input data by storing a line number and a column number. The line number */
+/* is a global line number meaning that it increases continuously through */
+/* the lines of included files. The first line is line number 1. The first */
+/* (leftmost) column is column number 1. */
+typedef
+ struct
+ {
+ ulong ps_line;
+ ulong ps_column;
+ } ps_t ;
+
+typedef ps_t *p_ps_t; /* A pointer to a position is handy too! */
+
+/******************************************************************************/
+
+/* A macro name is represented simply as a character array. */
+#define NAME_MAX 80
+typedef char name_t[NAME_MAX+1];
+typedef name_t *p_name_t;
+
+/******************************************************************************/
+
+/* SC stands for SCrap of text. A scrap of text is a contiguous group of */
+/* printable bytes in memory. The following structure defines such a group by */
+/* storing a pointer to the first and last character of the scrap. */
+/* The scrap must contain at least one character (i.e. sc_last>=sc_first). */
+typedef
+ struct
+ {
+ char *sc_first; /* Pointer to the first byte of the scrap. */
+ char *sc_last; /* Pointer to the last byte of the scrap. */
+ bool sc_white; /* TRUE iff the scrap consists entirely of whitespace. */
+ } sc_t;
+
+typedef sc_t *p_sc_t;
+
+/******************************************************************************/
+
+/* LN stands for LiNe. This record holds global and local line numbers as */
+/* well as a scrap that points to the line in question. The scanner (which */
+/* generates this list) guarantees that the last character of the line scrap */
+/* is an EOL. */
+typedef
+ struct
+ {
+ sc_t ln_body; /* Scrap pointing to the line. Line ends in EOL. */
+ ulong ln_global; /* Global line number of this line. */
+ ulong ln_local; /* Local line number of this line. */
+ } ln_t;
+
+/* The global line list is simply a list of lines of the following type. */
+typedef p_ls_t p_lnls_t;
+
+/******************************************************************************/
+
+/* The following enumerated type identifies a font. */
+#define FT_NORM 1
+#define FT_TITL 2
+#define FT_STIT 3
+
+/* The following enumerated type identifies a horizontal alignment. */
+#define LR_LEFT 1
+#define LR_RIGH 2
+#define LR_CENT 3
+
+/* We want to pack a font and an alignment into the tk_gen byte of the token */
+/* record (we could create a new field, but as none of the other token kinds */
+/* require an extra field, we choose to pack instead. The formula is this: */
+/* Packed byte=LRFT_PACK*FONT+ALIGNMENT. */
+#define LRFT_PACK 10
+
+/******************************************************************************/
+
+/* The following enumerated type identifies the kind of a token. */
+#define TK_TEXT 1 /* Text segment. */
+#define TK_NSEC 2 /* @A..New section. */
+#define TK_MDEF 3 /* @$ Macro definition. */
+#define TK_FDEF 4 /* @F File definition. */
+#define TK_ONAM 5 /* @< Open name. */
+#define TK_CNAM 6 /* @> Close name. */
+#define TK_ODEF 7 /* @{ Open definition. */
+#define TK_CDEF 8 /* @} Close definition. */
+#define TK_OPAR 9 /* @( Open parameter list. */
+#define TK_CPAR 10 /* @) Close parameter list. */
+#define TK_COMA 11 /* @, Comma. */
+#define TK_QUOT 12 /* @" Quote. */
+#define TK_PARM 13 /* @1 Parameter. */
+#define TK_ZERO 14 /* @Z Zero calls allowed. */
+#define TK_MANY 15 /* @M Many calls allowed. */
+#define TK_NAME 16 /* @# Self contained name. */
+#define TK_EMPH 17 /* @/ Emphasize text. */
+#define TK_NPAG 18 /* @t..Newpage. */
+#define TK_TOCS 19 /* @t..Table of contents. */
+#define TK_SKIP 20 /* @t..Vertical skip. */
+#define TK_TITL 21 /* @t..Title text. */
+#define TK_EOF 22 /* End of file. */
+typedef ubyte tk_k_t;
+
+/* The following structure conveys all the information about a single token. */
+/* As well as the kind of token, the parser needs to know where the token is */
+/* in the input file and what the text of the token is if it is a text token. */
+/* Some other tokens have a numeric attribute associated with them and the */
+/* tk_gen field provides a place for this. The attributes are: */
+/* TK_PARM - The number of the parameter [1,9]. */
+/* TK_NAME - The number of the character forming the name [0,255]. */
+/* TK_NSEC - The level of the section [0,5]. 0=@*, 1=@A, 2=@B,..,5=@E. */
+/* TK_SKIP - Number of millimetres to skip vertically [0,255]. */
+/* TK_TITL - Font and alignment packed into byte as specified earlier. */
+/* tk_sc is the text to be set as a title. */
+typedef
+ struct
+ {
+ tk_k_t tk_kind; /* Kind of this token. */
+ ps_t tk_ps; /* Position of the first character of this token. */
+ sc_t tk_sc; /* Scrap constituting token. */
+ ubyte tk_gen; /* General token attribute. */
+ } tk_t;
+
+typedef p_ls_t p_tkls_t; /* A list of tokens. */
+
+/******************************************************************************/
+
+typedef p_ls_t p_scls_t; /* List of scraps. */
+typedef p_ls_t p_scll_t; /* List of list of scraps =TEXT. */
+
+typedef p_ls_t p_ells_t; /* List of pointers to elements = EXPRESSION. */
+typedef p_ls_t p_elll_t; /* List of list of pointers to elements. */
+typedef p_ls_t p_ell3_t; /* List of list of list of pointers to elements. */
+
+/******************************************************************************/
+
+/* This structure's signature is BP for Body Part. FunnelWeb macros can */
+/* be defined in a series of "+=" definitions scattered through the input */
+/* file. The definition of the macro is the concatenation of all the parts. */
+/* The contributory part of a part consists of a single expression. */
+/* Throughout the document, body parts (definition parts) are numbered */
+/* sequentially by a sequence number. */
+typedef
+ struct
+ {
+ p_ells_t bp_ex; /* Expression that is logically appended to definition. */
+ ulong bp_seq; /* Sequence number of body part. */
+ ps_t bp_ps; /* Position at which the definition appears. */
+ } bp_t;
+
+typedef bp_t *p_bp_t;
+
+/* A list of body parts constitutes the full body of a macro. */
+typedef p_ls_t p_bpls_t;
+
+/******************************************************************************/
+
+/* The following structure summarizes a macro CALL. Each macro table entry */
+/* contains a field ma_calls which contains a list of these structures. The */
+/* list is used to generate diagnostics (e.g. if a call has the wrong number */
+/* of parameters) and also to give cross reference information in the typeset */
+/* documentation. */
+typedef
+ struct
+ {
+ ulong mc_seq; /* Sequence number of body part containing call. */
+ ps_t mc_ps; /* Position at which the call occurred. */
+ ulong mc_npar; /* Number of parameters in call. */
+ } mc_t;
+
+typedef mc_t *p_mc_t;
+
+/* A list of calls summarizes the entire usage of a macro in a document. */
+typedef p_ls_t p_mcls_t;
+
+/******************************************************************************/
+
+/* This structure stores the definition of a single macro. The first field */
+/* md_isdef indicates whether a definition for this macro has so far been */
+/* seen. If it has, md_isdef=TRUE and the remaining fields are well defined. */
+typedef
+ struct
+ {
+ bool md_isdef; /* TRUE iff the macro is defined. */
+ ps_t md_ps; /* isdef=> Position of first definition part. */
+ ubyte md_npar; /* isdef=> Number of params specified in defn. */
+ bool md_isadd; /* isdef=> TRUE iff additively defined. */
+ bool md_iszer; /* isdef=> TRUE iff zero calls allowed. */
+ bool md_isman; /* isdef=> TRUE iff many calls allowed. */
+ bool md_isfil; /* isdef=> TRUE iff macro is bound to an outp file. */
+ p_bpls_t md_body; /* isdef=> Body of the macro (list of parts). */
+ } md_t;
+
+/******************************************************************************/
+
+/* The following structure contains the full information about a macro. */
+typedef
+ struct
+ {
+ name_t ma_name; /* Name of the macro. */
+ p_mcls_t ma_calls; /* List of calls of this macro in the document. */
+ md_t ma_defn; /* Definition of this macro. */
+ p_ell3_t ma_actn; /* Used by tangle. List of actual parameter lists. */
+ uword ma_level; /* Used by analyser. Depth of deepest call. */
+ } ma_t;
+
+/* A pointer to the comprehensive macro structure defined above is the way */
+/* that FunnelWeb refers to macros internally. */
+typedef ma_t *p_ma_t;
+
+/******************************************************************************/
+
+/* An expression consists of a sequence of ELEMENTS each of which can */
+/* be one of three kinds: */
+/* */
+/* 1. A block of text. */
+/* 2. An invocation of another macro. */
+/* 3. A parameter of the current macro. */
+/* */
+/* The following enumerated type identifies one of these three alternatives. */
+#define EL_TEXT 1
+#define EL_INVC 2
+#define EL_PARM 3
+typedef ubyte el_k_t;
+
+/* The following rather messy structure contains information about a single */
+/* element. As mentioned above, an element can be one of three kinds and the */
+/* following structure should, strictly speaking, be defined as a C union so */
+/* as to emphasize the mutually exclusive nature of most of its fields. */
+/* At one stage this structure did contain a union, however, it introduced */
+/* more mess than it brought clarity (because of the extra two subnames) and */
+/* was eventually dropped. */
+/* A few fields deserve some explanation: */
+/* el_pretx and el_postx hold the exact whitespace appearing between */
+/* actual parameters in a macro call. This enables the call to be */
+/* formatted properly in the typeset output. */
+/* el_which is part of the macro parameter element (e.g. @1) and points to */
+/* the macro within which the @1 appears. Strictly speaking this should */
+/* not be necessary, but it is convenient for the tangler to have this */
+/* information when it is half way through expanding an expression. */
+typedef
+ struct
+ {
+ el_k_t el_kind; /* Indicates what kind of element structure holds. */
+
+ p_scls_t el_text; /* EL_TEXT => List of scraps forming a text chunk. */
+
+ p_ma_t el_p_mac; /* EL_INVC => Pointer to macro being invoked. */
+ p_elll_t el_parls; /* EL_INVC => List of actual parameters. */
+ p_scll_t el_pretx; /* EL_INVC => Text before each parameter. */
+ p_scll_t el_postx; /* EL_INVC => Text after each parameter. */
+
+ p_ma_t el_which; /* EL_PARM => Macro in which this element appears. */
+ ubyte el_parno; /* EL_PARM => Parameter number of this actual param. */
+ } el_t;
+
+typedef el_t *p_el_t;
+
+/******************************************************************************/
+
+/* A document component (represented by the DC_ data structures (see below) */
+/* can be one of three things: a lump of text, a typesetter-generic */
+/* typesetting directive, or a macro definition. The second of these consists */
+/* of a whole collection of typesetting commands and so rather than */
+/* cluttering up the dc_ record, they have been separated out here. */
+#define TY_NSEC 1 /* New section. */
+#define TY_OLIT 2 /* Open literal. */
+#define TY_CLIT 3 /* Close literal. */
+#define TY_OEMP 4 /* Open emphasise. */
+#define TY_CEMP 5 /* Close emphasise. */
+#define TY_NPAG 6 /* New page. */
+#define TY_TOCS 7 /* Table of contents. */
+#define TY_SKIP 8 /* Skip vertical. */
+#define TY_TITL 9 /* Title. */
+typedef ubyte ty_k_t;
+
+typedef
+ struct
+ {
+ ty_k_t ty_kind; /* Kind of this typesetting directive. */
+ sn_t ty_sn; /* TY_NSEC=> Hierarchical section number. */
+ bool ty_isnam; /* TY_NSEC=> TRUE iff the section is named. */
+ name_t ty_name; /* TY_NSEC=> ty_isnam=> Name of section. */
+
+ uword ty_mm; /* TY_SKIP=> Millimetres to skip. */
+
+ ubyte ty_font; /* TY_TITL=> Font in which to write title. */
+ ubyte ty_align; /* TY_TITL=> Alignment with which to write title. */
+ sc_t ty_sc; /* TY_TITL=> Scrap that is title text. */
+ } ty_t;
+
+typedef ty_t *p_ty_t;
+
+/******************************************************************************/
+
+/* The document list contains a representation of the input document in the */
+/* form in which it was fed to FunnelWeb. This structured representation of */
+/* the input is used by the weaver to generate the typeset output. */
+/* Here, a document is represented by a list of DOCUMENT COMPONENTs (DC) each */
+/* of which contains information about a major chunk of the document. The */
+/* following enumerated type dc_k_t (document component kind type) is used to */
+/* indicate which kind of component each list element contains. */
+#define DC_TEXT 1 /* Text component consists of a block of text. */
+#define DC_TYPE 2 /* Typesettting component affecting document typesetting. */
+#define DC_MACR 3 /* A MACRo definition. */
+typedef ubyte dc_k_t;
+
+/* The following structure stores a single document component. Like the el_t */
+/* type, the dc_t type should really be a union type, but a union construct */
+/* has been avoided to make the naming simpler. */
+typedef
+ struct
+ {
+ ps_t dc_ps; /* Position of this component. */
+ dc_k_t dc_kind; /* Kind of this component. */
+
+ p_scls_t dc_text; /* DC_TEXT=> Text segment constituting this compnt. */
+
+ ty_t dc_ty; /* DC_TYPE=> Typesetting object record. */
+
+ p_ma_t dc_p_ma; /* DC_MACR=> Pointer to the macro defined. */
+ ulong dc_part; /* DC_MACR=> Part number of this part of macro defn. */
+ } dc_t;
+
+typedef dc_t *p_dc_t;
+
+/* A list of document components constitutes the global document list */
+/* declared later. */
+typedef p_ls_t p_dcls_t;
+
+/******************************************************************************/
+
+/* This enumerated type identifies a typesetter. */
+/* TR_NONE - No specific typesetter specified. */
+/* TR_TEX - The TeX typesetter. */
+#define TR_NONE 1
+#define TR_TEX 2
+/* Add more typesetters here later. */
+typedef ubyte tr_k_t;
+
+
+/******************************************************************************/
+/* */
+/* VARIABLES */
+/* ========= */
+/* This section contains external declarations of the global variables. */
+/* The global variables themselves appear in DATA.C. */
+/* */
+/******************************************************************************/
+
+/* This #ifndef is part of a mechanism that makes the following definitions */
+/* visible to other modules declared as "extern", and visible to data.c */
+/* declared as ordinary declarations. This prevents inconsistencies. */
+#ifndef EXTERN
+#define EXTERN extern
+#endif
+
+/* This global options variable holds the options that were transmitted to */
+/* FunnelWeb proper through the command line. */
+EXTERN GLOVAR op_t option;
+
+/* The following option variable is set by the scanner and is used by the */
+/* tangler. It determines whether the tangler will use natural indenting. */
+/* TRUE => Tangler should use space indenting. FALSE=>No indenting. */
+EXTERN GLOVAR bool tgindent;
+
+/* The following option variable is set by the scanner and is used by the */
+/* tangler. It sets a limit on the length of the lines of the product files */
+/* generated by tangle. A value of TGMAXINF indicates that no checking need */
+/* be performed. */
+#define TGMAXINF (ULONG_MAX)
+EXTERN GLOVAR ulong tglinmax;
+
+/* The following variable is written by the scanner and read by weave. It */
+/* stores the typesetter format possibly specified by the user in the input. */
+EXTERN GLOVAR tr_k_t tr_codes;
+
+/* The following five lists and tables constitute the major data structures */
+/* that are communicated between the major components of FunnelWeb. */
+/* The TOKEN_LIST contains a tokenized representation of the input file. */
+/* The LINE_LIST contains a list of the lines of the input file. */
+/* The DOCUMENT_LIST contains a structured representation of the input file. */
+/* The MACRO_TABLE describes the macros defined in the input file. */
+/* The FILE_TABLE identifies macros that are connected to product files. */
+/* Created By Used By */
+/* ---------- ------- */
+EXTERN GLOVAR p_tkls_t token_list; /* Scanner Parser */
+EXTERN GLOVAR p_lnls_t line_list; /* Scanner Lister */
+EXTERN GLOVAR p_dcls_t document_list; /* Parser Weaver */
+EXTERN GLOVAR p_tb_t macro_table; /* Parser Tangler, Weaver */
+EXTERN GLOVAR p_tb_t file_table; /* Parser Tangler, Weaver */
+
+/* Three output streams are accessible globally. */
+/* The SCREEN FILE is connected to standard output (the user screen). */
+/* The JOURNAL FILE logs FunnelWeb command language transactions. */
+/* The LISTING FILE is created by an single invocation of FunnelWeb proper. */
+EXTERN GLOVAR wf_t f_s; /* Screen file. */
+EXTERN GLOVAR wf_t f_j; /* Journal file. */
+EXTERN GLOVAR wf_t f_l; /* Listing file. */
+
+/* Many of the FunnelWeb IO functions accept a single string as a parameter. */
+/* This means that sprintf and a temporary string must be used in order to */
+/* produce parameterized formatted output. Rather than declare temporary */
+/* strings in each local function, we declare them globally. */
+EXTERN GLOVAR char linet1[2000];
+
+/* Definitions of Diagnostic Levels */
+/* -------------------------------- */
+/* A WARNING has no effect except to cause a message to be issued. */
+/* An ERROR causes FunnelWeb to abort to the shell at the end of the phase. */
+/* Example: An error during scanning means that the FunnelWeb run will */
+/* terminate to the shell at the end of the scanning phase. */
+/* A SEVERE ERROR causes FunnelWeb to abort to the shell immediately. */
+/* A FATAL ERROR causes FunnelWeb to abort to the OS immediately. */
+
+/* The following variables count diagnostics over a single FunnelWeb run. */
+EXTERN GLOVAR ulong num_war; /* Number of warnings. */
+EXTERN GLOVAR ulong num_err; /* Number of errors. */
+EXTERN GLOVAR ulong num_sev; /* Number of severe errors. */
+
+/* The following variables count diagnostics over multiple FunnelWeb runs. */
+EXTERN GLOVAR ulong sum_war; /* Number of warnings. */
+EXTERN GLOVAR ulong sum_err; /* Number of errors. */
+EXTERN GLOVAR ulong sum_sev; /* Number of severe errors. */
+EXTERN GLOVAR ulong sum_fat; /* Number of fatal errors. */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of DATA.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/dump.c b/web/funnelAC/sources/dump.c
new file mode 100644
index 0000000000..62b6331f97
--- /dev/null
+++ b/web/funnelAC/sources/dump.c
@@ -0,0 +1,816 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* DUMP.C */
+/******************************************************************************/
+
+#include <ctype.h>
+#include "style.h"
+
+#include "as.h"
+#include "clock.h"
+#include "data.h"
+#include "dump.h"
+#include "misc.h"
+
+/******************************************************************************/
+
+#define DUMP_WIDTH (80)
+
+/******************************************************************************/
+
+/* The following advance declarations are required because of recursion. */
+LOCAL void dm_ex P_((p_wf_t,p_ells_t));
+
+/******************************************************************************/
+
+LOCAL void centerln P_((p_wf_t,uword,int,char *));
+LOCAL void centerln(p_wf,width,ch,s)
+/* Writes string s in a line surrounded by character ch to specified width. */
+/* Example: centerln(*,20,'-',"sloth") would write: "------ sloth -------" */
+p_wf_t p_wf;
+uword width;
+int ch;
+char *s;
+{
+ uword sidebar,i;
+ char linet2[100];
+ /* Warning: linet2 can't be too big, or it will blow the Mac's limited */
+ /* stack space. Perhaps it should be put in the heap with a static pointer. */
+
+ as_cold(width>=5,"centerln: Width is too small.");
+ as_cold(width<=80,"centerln: Width is too large.");
+ as_cold(strlen(s) <= width-4,"centerln: Width is too narrow for string.");
+
+ /* Construct a sidebar string. */
+ sidebar=(width-strlen(s)-2)/2;
+ for (i=0;i<sidebar;i++) linet2[i]=ch;
+ linet2[sidebar]=EOS;
+
+ /* Now construct the result string. */
+ strcpy(linet1,linet2);
+ strcat(linet1," ");
+ strcat(linet1,s);
+ strcat(linet1," ");
+ strcat(linet1,linet2);
+
+ /* If the sidebar division removed a character, and the line is long enough */
+ /* for the user not to notice the imbalance, tack a character on the end. */
+ if (width>40 && strlen(linet1)==width-1)
+ {
+ uword len=strlen(linet1);
+ linet1[len]=ch;
+ linet1[len+1]=EOS;
+ }
+
+ /* Write the result string to the specified stream. */
+ wf_wl(p_wf,linet1);
+}
+
+/******************************************************************************/
+
+LOCAL char * fontname P_((ubyte));
+LOCAL char * fontname(font)
+/* Given a font number, returns a pointer to a static string containing the */
+/* name of the font. */
+ubyte font;
+{
+ switch (font)
+ {
+ case FT_NORM: return "Normal";
+ case FT_TITL: return "Title";
+ case FT_STIT: return "Small Title";
+ default : as_bomb("fontname: Font switch defaulted.");
+ }
+ /* Keep GCC warnings happy. */
+ as_bomb("fontname: Dropped out of switch.");
+ return "Failure";
+}
+
+/******************************************************************************/
+
+LOCAL char * alignname P_((ubyte));
+LOCAL char * alignname(align)
+/* Given an alignment number, returns a pointer to a static string containing */
+/* the name of the alignment. */
+ubyte align;
+{
+ switch (align)
+ {
+ case LR_LEFT: return "Left";
+ case LR_RIGH: return "Right";
+ case LR_CENT: return "Centre";
+ default : as_bomb("alignname: Alignment switch defaulted.");
+ }
+ /* Keep GCC warnings happy. */
+ as_bomb("alignnamename: Dropped out of switch.");
+ return "Failure";
+}
+
+/******************************************************************************/
+
+EXPORT void dm_mem(p_wf,p_mem,length)
+p_wf_t p_wf;
+char *p_mem;
+ulong length;
+{
+ ubyte_ *p_base = (ubyte_ *) p_mem;
+ long len = length;
+
+ wf_wl(p_wf,"");
+ wf_wl(p_wf,"MEMORY DUMP OF MAPPED FILE");
+ wf_wl(p_wf,"==========================");
+ wf_wl(p_wf,"");
+ wf_wr(p_wf,"+-------------------------------------------------+------------------+\n");
+ wf_wr(p_wf,"| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |\n");
+ wf_wr(p_wf,"+-------------------------------------------------+------------------+\n");
+
+ while (len>0)
+ {/* Write a single line of 16 bytes per iteration. */
+ uword j;
+ wf_wr(p_wf,"| ");
+ for (j=0;j<16;j++)
+ if (j>=len)
+ wf_wr(p_wf," ");
+ else
+ {
+ char s[10];
+ sprintf(s,"%02X ",(unsigned int) p_base[j]);
+ wf_wr(p_wf,s);
+ }
+ wf_wr(p_wf,"| ");
+ for (j=0;j<16;j++)
+ if (j>=len)
+ wf_chr(p_wf,' ');
+ else
+ {
+ char ch=p_base[j];
+ /* DON'T use library function "isprint" - it is too loose. */
+ /* e.g. The vax "isprint" accepts top bit characters. */
+ if (!isascprn(ch)) ch='.';
+ wf_chr(p_wf,ch);
+ }
+ wf_wr(p_wf," |\n");
+ p_base+=16;
+ len-=16;
+ } /* End while */
+
+ wf_wr(p_wf,"+-------------------------------------------------+------------------+\n");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+LOCAL void dm_byte P_((p_wf_t,ubyte));
+LOCAL void dm_byte(p_wf,b)
+/* Dumps a text representation of the given byte to the specified stream. */
+p_wf_t p_wf;
+ubyte b;
+{
+ char t[10];
+ /* DON'T use library function "isprint" - it is too loose. */
+ /* e.g. The vax "isprint" accepts top bit characters. */
+ if (isascprn(b))
+ sprintf(t,"%c",(char) b);
+ else
+ sprintf(t,"<%03u>",(unsigned) b);
+ wf_wr(p_wf,t);
+}
+
+/******************************************************************************/
+
+EXPORT void dm_lnls(p_wf)
+p_wf_t p_wf;
+{
+ wf_wl(p_wf,"");
+ centerln(p_wf,DUMP_WIDTH,'=',"Start of LINE LIST DUMP");
+ wf_wl(p_wf,"");
+ /*12345678901234567890123456789012345678901234567890123456789012345678901234567890*/
+ wf_wl(p_wf,"Globl Local| Text");
+ wf_wl(p_wf,"-----------+--------------------------------------------------------------------");
+ ls_fir(line_list);
+ while (TRUE)
+ {
+ ln_t *p_line;
+ char *p;
+ ls_nxt(line_list,PPV &p_line);
+ if (p_line==NULL) break;
+ sprintf(linet1,"%05lu %05lu| ",
+ (ulong) p_line->ln_global,
+ (ulong) p_line->ln_local);
+ wf_wr(p_wf,linet1);
+ for (p=p_line->ln_body.sc_first; p<=p_line->ln_body.sc_last; p++)
+ dm_byte(p_wf,*((ubyte_ *)p));
+ wf_wl(p_wf,"");
+ }
+ wf_wl(p_wf,"-----------+--------------------------------------------------------------------");
+ wf_wl(p_wf,"Globl Local| Text");
+ wf_wl(p_wf,"");
+ centerln(p_wf,DUMP_WIDTH,'=',"End of LINE LIST DUMP");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+LOCAL void dm_sc P_((p_wf_t,p_sc_t));
+LOCAL void dm_sc(p_wf,p_sc)
+/* Dumps the specified scrap to the specified stream. */
+p_wf_t p_wf;
+p_sc_t p_sc;
+{
+ char *p;
+
+ as_cold(p_sc->sc_first !=NULL,"dm_sc: NULL ptr1.");
+ as_cold(p_sc->sc_last !=NULL,"dm_sc: NULL ptr2.");
+
+ if (p_sc->sc_white)
+ wf_wr(p_wf,"Text scrap[White]=");
+ else
+ wf_wr(p_wf,"Text scrap[Grey]=");
+ wf_wr(p_wf,"\"");
+ for (p=p_sc->sc_first; p<=p_sc->sc_last; p++)
+ {
+ dm_byte(p_wf,*((ubyte_ *) p));
+ if (*p=='\n')
+ wf_wl(p_wf,"");
+ }
+ wf_wl(p_wf,"\"");
+}
+
+/******************************************************************************/
+
+LOCAL void dm_scls P_((p_wf_t,p_scls_t));
+LOCAL void dm_scls(p_wf,p_scls)
+/* Dumps the specified scrap list to the specified stream. */
+p_wf_t p_wf;
+p_scls_t p_scls;
+{
+ wf_wl(p_wf,"");
+ centerln(p_wf,30,'-',"Start of Text Scrap List");
+ ls_fir(p_scls);
+ while (TRUE)
+ {
+ p_sc_t p_sc;
+ ls_nxt(p_scls,PPV &p_sc);
+ if (p_sc==NULL) break;
+ dm_sc(p_wf,p_sc);
+ }
+ centerln(p_wf,30,'-',"End of Text Scrap List");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+EXPORT void dm_tkls(p_wf)
+p_wf_t p_wf;
+{
+ tk_t *token;
+ char *m;
+ ubyte font;
+ ubyte align;
+
+ wf_wl(p_wf,"");
+ centerln(p_wf,DUMP_WIDTH,'=',"Start of TOKEN LIST DUMP");
+ wf_wl(p_wf,"");
+ sprintf(linet1,"Summary: There are %lu tokens in the token list.",
+ (ulong) ls_len(token_list));
+ wf_wl(p_wf,linet1);
+ wf_wl(p_wf,"");
+ wf_wl(p_wf,"Line[Column]: Token Description");
+ wf_wl(p_wf,"-------------------------------");
+ wf_wl(p_wf,"");
+
+ ls_fir(token_list);
+ ls_nxt(token_list,PPV &token);
+ while (token != NULL)
+ {
+ sprintf(linet1,"%04lu[%02lu]: ",
+ (ulong) token->tk_ps.ps_line,
+ (ulong) token->tk_ps.ps_column);
+ wf_wr(p_wf,linet1);
+ switch (token->tk_kind)
+ {
+ case TK_TEXT: m="Text." ; break;
+ case TK_MDEF: m="@$ Macro defn." ; break;
+ case TK_FDEF: m="@F File defn." ; break;
+ case TK_ONAM: m="@< Open name." ; break;
+ case TK_CNAM: m="@> Close name." ; break;
+ case TK_ODEF: m="@{ Open defn." ; break;
+ case TK_CDEF: m="@} Close defn." ; break;
+ case TK_OPAR: m="@( Open param." ; break;
+ case TK_CPAR: m="@} Close param." ; break;
+ case TK_COMA: m="@, Comma." ; break;
+ case TK_QUOT: m="@\" Quote." ; break;
+ case TK_PARM: m="@n Parameter." ; break;
+ case TK_ZERO: m="@Z Zero calls." ; break;
+ case TK_MANY: m="@M Many calls." ; break;
+ case TK_NAME: m="@# Name." ; break;
+ case TK_EMPH: m="@/ Emphasise." ; break;
+ case TK_NPAG: m="@t.. Newpage." ; break;
+ case TK_TOCS: m="@t.. TOC." ; break;
+ case TK_SKIP: m="@t.. Vertical skip."; break;
+ case TK_TITL: m="@t.. Title." ; break;
+ case TK_EOF : m="End Of File." ; break;
+ case TK_NSEC:
+ switch (token->tk_gen)
+ {
+ case 0: m="@* New section (Level 0)."; break;
+ case 1: m="@A New section (Level 1)."; break;
+ case 2: m="@B New section (Level 2)."; break;
+ case 3: m="@C New section (Level 3)."; break;
+ case 4: m="@D New section (Level 4)."; break;
+ case 5: m="@E New section (Level 5)."; break;
+ default: as_bomb("dmtkls: Level case defaulted.");
+ }
+ break;
+ default: as_bomb("dmtkls: Token case defaulted.");
+ }
+ wf_wr(p_wf,m);
+ wf_wr(p_wf," ");
+ switch (token->tk_kind)
+ {
+ case TK_PARM:
+ sprintf(linet1,"Parameterno=%u.",(unsigned) token->tk_gen);
+ wf_wl(p_wf,linet1);
+ break;
+ case TK_NAME:
+ wf_wr(p_wf,"Character='");
+ dm_byte(p_wf,token->tk_gen);
+ wf_wl(p_wf,"'.");
+ break;
+ case TK_TEXT:
+ dm_sc(p_wf,&token->tk_sc);
+ break;
+ case TK_SKIP:
+ sprintf(linet1,"Vertical space skipped=%lumm.",
+ (ulong) token->tk_gen);
+ wf_wl(p_wf,linet1);
+ break;
+ case TK_TITL:
+ font = token->tk_gen / LRFT_PACK;
+ align = token->tk_gen % LRFT_PACK;
+ wf_wr(p_wf,"Font="); wf_wr(p_wf,fontname(font));
+ wf_wr(p_wf,", Alignment="); wf_wr(p_wf,alignname(align));
+ wf_wl(p_wf,". Title text follows:");
+ dm_sc(p_wf,&token->tk_sc);
+ break;
+ default: wf_wl(p_wf,""); break;
+ }
+ ls_nxt(token_list,PPV &token);
+ } /* End of while loop. */
+
+ centerln(p_wf,DUMP_WIDTH,'=',"End of TOKEN LIST DUMP");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+LOCAL void dm_eltx P_((p_wf_t,p_el_t));
+LOCAL void dm_eltx (p_wf,p_el)
+/* Dumps the specified text element to the specified stream. */
+p_wf_t p_wf;
+p_el_t p_el;
+{
+ p_sc_t p_sc;
+
+ wf_wl(p_wf,"");
+ centerln(p_wf,30,'-',"Start Text Element");
+
+ ls_fir(p_el->el_text);
+ ls_nxt(p_el->el_text,PPV &p_sc);
+ while (p_sc != NULL)
+ {
+ dm_sc(p_wf,p_sc);
+ ls_nxt(p_el->el_text,PPV &p_sc);
+ }
+ centerln(p_wf,30,'-',"End Text Element");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+LOCAL void dm_elin P_((p_wf_t,p_el_t));
+LOCAL void dm_elin(p_wf,p_el)
+/* Dumps the specified invocation element to the specified stream. */
+p_wf_t p_wf;
+p_el_t p_el;
+{
+ ulong parno;
+ p_ells_t *pp_ex;
+ p_ells_t p_ex;
+ p_elll_t p_elll = p_el->el_parls;
+
+ wf_wl(p_wf,"");
+ centerln(p_wf,30,'-',"Begin Invocation Element");
+
+ sprintf(linet1,"Invocation of macro @<%s@>",&p_el->el_p_mac->ma_name[0]);
+ wf_wl(p_wf,linet1);
+
+ if (ls_len(p_elll)==0)
+ wf_wl(p_wf,"No actual parameters.");
+ else
+ {
+ sprintf(linet1,"This invocation has %lu actual parameters.",
+ (ulong) ls_len(p_elll));
+ wf_wl(p_wf,linet1);
+ wf_wl(p_wf,
+ "Actual parameter list follows as a sequence of expressions:");
+ wf_wl(p_wf,"(Text crud before and after parameter has been omitted).");
+ parno=1;
+ ls_fir(p_elll);
+ while (TRUE)
+ {
+ ls_nxt(p_elll,PPV &pp_ex);
+ if (pp_ex==NULL) break;
+ p_ex = *pp_ex;
+ sprintf(linet1,"Expression for parameter number %lu:",(ulong) parno);
+ wf_wl(p_wf,linet1);
+ dm_ex(p_wf,p_ex);
+ parno++;
+ }
+ }
+
+ centerln(p_wf,30,'-',"End Invocation Element");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+LOCAL void dm_elpr P_((p_wf_t,p_el_t));
+LOCAL void dm_elpr(p_wf,p_el)
+/* Dumps the specified parameter element to the specified stream. */
+p_wf_t p_wf;
+p_el_t p_el;
+{
+ wf_wl(p_wf,"");
+ centerln(p_wf,30,'-',"Start Parameter Element");
+ sprintf(linet1,"Parameter number=%lu.",(ulong) p_el->el_parno);
+ wf_wl(p_wf,linet1);
+ sprintf(linet1,"Parameter is of macro \"%s\".",
+ &p_el->el_which->ma_name[0]);
+ wf_wl(p_wf,linet1);
+ centerln(p_wf,30,'-',"End Parameter Element");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+LOCAL void dm_ex(p_wf,p_ex)
+/* Dumps the specified expression to the specified stream. */
+p_wf_t p_wf;
+p_ells_t p_ex;
+{
+ p_el_t p_el;
+
+ wf_wl(p_wf,"");
+ centerln(p_wf,30,'-',"Start of Expression");
+ ls_fir(p_ex);
+ ls_nxt(p_ex,PPV &p_el);
+ while (p_el != NULL)
+ {
+ switch (p_el->el_kind)
+ {
+ case EL_TEXT: dm_eltx(p_wf,p_el); break;
+ case EL_INVC: dm_elin(p_wf,p_el); break;
+ case EL_PARM: dm_elpr(p_wf,p_el); break;
+ default : as_bomb("dm_ex: Case defaulted.");
+ }
+ ls_nxt(p_ex,PPV &p_el);
+ }
+ centerln(p_wf,30,'-',"End of Expression");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+LOCAL void dm_macro P_((p_wf_t,p_ma_t));
+LOCAL void dm_macro(p_wf,p_ma)
+/* Dump all the information on the specified macro. */
+p_wf_t p_wf;
+p_ma_t p_ma;
+{
+ wf_wl(p_wf,"");
+ centerln(p_wf,DUMP_WIDTH-20,'-',"Start of Macro Dump");
+
+ /* A macro can't exist in the macro table without a name. */
+ sprintf(linet1,"Macro Name : \"%s\"",p_ma->ma_name); wf_wl(p_wf,linet1);
+
+ /* Is the macro defined? */
+ if (!p_ma->ma_defn.md_isdef) wf_wl(p_wf,"Defined? : No.");
+ else wf_wl(p_wf,"Defined? : Yes.");
+
+ /* Defined macros carry lots more information. */
+ if (p_ma->ma_defn.md_isdef)
+ {
+ /* Number of parameters the macro has. */
+ sprintf(linet1,"Parameters : %lu",(ulong) p_ma->ma_defn.md_npar);
+ wf_wl(p_wf,linet1);
+
+ /* Is the macro additive? */
+ if (p_ma->ma_defn.md_isadd) wf_wl(p_wf,"Additive? : Yes.");
+ else wf_wl(p_wf,"Additive? : No.");
+
+ /* Is the macro allowed to be called zero times? */
+ if (p_ma->ma_defn.md_iszer) wf_wl(p_wf,"Zero Calls? : Yes.");
+ else wf_wl(p_wf,"Zero Calls? : No.");
+
+ /* Is the macro allowed to be called many times? */
+ if (p_ma->ma_defn.md_isman) wf_wl(p_wf,"Many Calls? : Yes.");
+ else wf_wl(p_wf,"Many Calls? : No.");
+
+ /* Is the macro connected to an product file? */
+ if (p_ma->ma_defn.md_isfil) wf_wl(p_wf,"Output File?: Yes.");
+ else wf_wl(p_wf,"Output File?: No.");
+
+ /* Dump a list of all the calls to the macro. */
+ {
+ p_mc_t p_mc;
+ ulong mcnum;
+ wf_wl(p_wf,"Call list :");
+ ls_fir(p_ma->ma_calls);
+ ls_nxt(p_ma->ma_calls,PPV &p_mc);
+ mcnum=1;
+ while (p_mc != NULL)
+ {
+ sprintf(linet1,
+ " Call %lu: Parameters=%lu, Sequence num=%lu, Position(L,C)=(%lu,%lu).",
+ (ulong) mcnum,
+ (ulong) p_mc->mc_npar,
+ (ulong) p_mc->mc_seq,
+ (ulong) p_mc->mc_ps.ps_line,
+ (ulong) p_mc->mc_ps.ps_column);
+ wf_wl(p_wf,linet1);
+ ls_nxt(p_ma->ma_calls,PPV &p_mc);
+ mcnum++;
+ }
+ }
+
+ /* Dump a list of the body parts of the macro. */
+ {
+ p_bp_t p_bp;
+ ulong bpnum;
+ ulong bptot = ls_len(p_ma->ma_defn.md_body);
+ wf_wl(p_wf,"Macro body :");
+ wf_wl(p_wf,"");
+ wf_wl(p_wf,"--Start of List of Body Parts--");
+ sprintf(linet1,"This macro has %lu body part",(ulong) bptot);
+ if (bptot!=1) strcat(linet1,"s");
+ strcat(linet1,".");
+ wf_wl(p_wf,linet1);
+ bpnum=1;
+ ls_fir(p_ma->ma_defn.md_body);
+ ls_nxt(p_ma->ma_defn.md_body,PPV &p_bp);
+ while (p_bp != NULL)
+ {
+ sprintf(linet1,
+ "Body part %lu: Seqnum=%lu, Pos(L,C)=(%lu,%lu), Expression follows:",
+ (ulong) bpnum,
+ (ulong) p_bp->bp_seq,
+ (ulong) p_bp->bp_ps.ps_line,
+ (ulong) p_bp->bp_ps.ps_column);
+ wf_wl(p_wf,linet1);
+ dm_ex(p_wf,p_bp->bp_ex);
+ ls_nxt(p_ma->ma_defn.md_body,PPV &p_bp);
+ bpnum++;
+ }
+ wf_wl(p_wf,"---End of List of Body Parts---");
+ wf_wl(p_wf,"");
+ }
+
+ } /* End of IF defined. */
+
+ centerln(p_wf,DUMP_WIDTH-20,'-',"End of Macro Dump");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+EXPORT void dm_matb P_((p_wf_t));
+EXPORT void dm_matb(p_wf)
+p_wf_t p_wf;
+{
+ wf_wl(p_wf,"");
+ centerln(p_wf,DUMP_WIDTH,'=',"Start of MACRO TABLE DUMP");
+ wf_wl(p_wf,"");
+ tb_fir(macro_table);
+ while (TRUE)
+ {
+ name_t name;
+ p_ma_t p_ma;
+ if (!tb_rea(macro_table,PV &name[0],PV &p_ma)) break;
+ dm_macro(p_wf,p_ma);
+ wf_wl(p_wf,"");
+ }
+ wf_wl(p_wf,"");
+ centerln(p_wf,DUMP_WIDTH,'=',"End of MACRO TABLE DUMP");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+LOCAL void dm_ty P_((p_wf_t,p_ty_t));
+LOCAL void dm_ty(p_wf,p_ty)
+p_wf_t p_wf;
+p_ty_t p_ty;
+{
+ char linet2[200];
+ char linet3[200];
+
+ switch (p_ty->ty_kind)
+ {
+ case TY_NSEC:
+ sn_str(&p_ty->ty_sn,linet2);
+ strcpy(linet3,"<No name>");
+ if (p_ty->ty_isnam) strcpy(linet3,&p_ty->ty_name[0]);
+ sprintf(linet1," Section \"%s\", Section name=\"%s\".",linet2,linet3);
+ wf_wl(p_wf,"");
+ wf_wl(p_wf,linet1);
+ break;
+ case TY_OLIT: wf_wl(p_wf," Open literal." ); break;
+ case TY_CLIT: wf_wl(p_wf," Close literal." ); break;
+ case TY_OEMP: wf_wl(p_wf," Open emphasise." ); break;
+ case TY_CEMP: wf_wl(p_wf," Close emphasise." ); break;
+ case TY_NPAG: wf_wl(p_wf," New page." ); break;
+ case TY_TOCS: wf_wl(p_wf," Table of contents."); break;
+ case TY_SKIP:
+ sprintf(linet1," Vertical skip by %lu mm.",(ulong) p_ty->ty_mm);
+ wf_wl(p_wf,linet1);
+ break;
+ case TY_TITL:
+ wf_wr(p_wf,"Font="); wf_wr(p_wf,fontname(p_ty->ty_font));
+ wf_wr(p_wf,", Alignment="); wf_wr(p_wf,alignname(p_ty->ty_align));
+ wf_wl(p_wf,". Title text follows:");
+ dm_sc(p_wf,&p_ty->ty_sc);
+ break;
+ default: as_bomb("dm_ty: Typesetter directive switch defaulted.");
+ }
+}
+
+/******************************************************************************/
+
+EXPORT void dm_dcls(p_wf)
+/* Dumps a text representation of the document list to the given stream. */
+p_wf_t p_wf;
+{
+ wf_wl(p_wf,"");
+ centerln(p_wf,DUMP_WIDTH,'=',"Start of DOCUMENT LIST DUMP");
+ wf_wl(p_wf,"");
+
+ ls_fir(document_list);
+ while (TRUE)
+ {
+ p_dc_t p_dc;
+ ls_nxt(document_list,PPV &p_dc);
+ if (p_dc == NULL) break;
+ wf_wl(p_wf,"");
+ sprintf(linet1,"Pos(L,C)=(%lu,%lu). ",
+ p_dc->dc_ps.ps_line,
+ p_dc->dc_ps.ps_column);
+ switch (p_dc->dc_kind)
+ {
+ case DC_TEXT:
+ wf_wr(p_wf,"TEXT COMPONENT: "); wf_wl(p_wf,linet1);
+ dm_scls(p_wf,p_dc->dc_text);
+ break;
+
+ case DC_TYPE:
+ wf_wr(p_wf,"TYPESETTER DIRECTIVE COMPONENT: ");
+ dm_ty(p_wf,&p_dc->dc_ty);
+ break;
+
+ case DC_MACR:
+ wf_wr(p_wf,"MACRO DEFINITION COMPONENT: "); wf_wl(p_wf,linet1);
+ sprintf(linet1,"Part %lu of macro @<%s@>.",
+ p_dc->dc_part,
+ &p_dc->dc_p_ma->ma_name[0]);
+ wf_wl(p_wf,linet1);
+ break;
+
+ default: as_bomb("dm_scls: Case defaulted.");
+ }
+ }
+
+ wf_wl(p_wf,"");
+ centerln(p_wf,DUMP_WIDTH,'=',"End of DOCUMENT LIST DUMP");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+
+LOCAL void tm_for P_((p_wf_t,char *,p_ck_t,p_ck_t));
+LOCAL void tm_for(p_wf,s,p_val,p_tot)
+/* This rather ragged function simplifies the formatting in dm_times. */
+p_wf_t p_wf;
+char *s;
+p_ck_t p_val;
+p_ck_t p_tot;
+{
+ sprintf(linet1,"|%s| %3d%% | %8.2f | %8.2f | %3d%% |",
+ s,
+ (int) ((100.0*ck_cpu(p_val))/ck_cpu(p_tot)),
+ (float) ck_cpu(p_val),
+ (float) ck_real(p_val),
+ (int) ((100.0*ck_real(p_val))/ck_real(p_tot))
+ );
+ wf_wl(p_wf,linet1);
+}
+
+/******************************************************************************/
+
+EXPORT void dm_times(p_wf,
+ p_mapp,p_scan,p_pars,p_anal,
+ p_dump,p_lstr,p_tang,p_weav,p_totl)
+p_wf_t p_wf;
+p_ck_t p_mapp;
+p_ck_t p_scan;
+p_ck_t p_pars;
+p_ck_t p_anal;
+p_ck_t p_dump;
+p_ck_t p_lstr;
+p_ck_t p_tang;
+p_ck_t p_weav;
+p_ck_t p_totl;
+{
+ float cputot;
+ float realtot;
+ float cpuerr;
+ float realerr;
+
+ cputot = ck_cpu(p_mapp) + ck_cpu(p_scan) + ck_cpu(p_pars) +
+ ck_cpu(p_anal) + ck_cpu(p_dump) + ck_cpu(p_lstr) +
+ ck_cpu(p_tang) + ck_cpu(p_weav);
+
+ realtot = ck_real(p_mapp) + ck_real(p_scan) + ck_real(p_pars) +
+ ck_real(p_anal) + ck_real(p_dump) + ck_real(p_lstr) +
+ ck_real(p_tang) + ck_real(p_weav);
+
+ cpuerr = ck_cpu (p_totl)-cputot;
+ realerr = ck_real(p_totl)-realtot;
+
+ wf_wl(p_wf,"");
+ wf_wl(p_wf,"Summary of time used by each subsystem of Funnelweb (seconds).");
+ wf_wl(p_wf,"");
+ wf_wl(p_wf, "+------------+------+----------+----------+------+");
+ wf_wl(p_wf, "| Subsystem | CPU% | CPU Time | RealTime | RT% |");
+ wf_wl(p_wf, "+------------+------+----------+----------+------+");
+ tm_for(p_wf," Mapper ",p_mapp,p_totl);
+ tm_for(p_wf," Scanner ",p_scan,p_totl);
+ tm_for(p_wf," Parser ",p_pars,p_totl);
+ tm_for(p_wf," Analyser ",p_anal,p_totl);
+ tm_for(p_wf," Dumper ",p_dump,p_totl);
+ tm_for(p_wf," Lister ",p_lstr,p_totl);
+ tm_for(p_wf," Tangler ",p_tang,p_totl);
+ tm_for(p_wf," Weaver ",p_weav,p_totl);
+ sprintf(linet1,"|%s| %3d%% | %8.2f | %8.2f | %3d%% |",
+ " Clock Err ",
+ (int) ((100.0*cpuerr )/ck_cpu (p_totl)),
+ (float) cpuerr,
+ (float) realerr,
+ (int) ((100.0*realerr)/ck_real(p_totl))
+ );
+ wf_wl(p_wf,linet1);
+
+ wf_wl(p_wf, "+------------+------+----------+----------+------+");
+ tm_for(p_wf," Total ",p_totl,p_totl);
+ wf_wl(p_wf, "+------------+------+----------+----------+------+");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+/* End of DUMP.C */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/dump.h b/web/funnelAC/sources/dump.h
new file mode 100644
index 0000000000..a02222428f
--- /dev/null
+++ b/web/funnelAC/sources/dump.h
@@ -0,0 +1,78 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* DUMP.H */
+/******************************************************************************/
+/* */
+/* This package contains functions that dump text representations of */
+/* FunnelWeb data structures. Each function accepts a wf stream on which it */
+/* writes its text representation. These functions are used in testing and */
+/* debugging only and are not used ordinarily in the program. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "clock.h"
+#include "writfile.h"
+
+/******************************************************************************/
+
+EXPORT void dm_mem P_((p_wf_t,char *,ulong));
+/* Writes a hex and ascii dump of the specified block of memory to the */
+/* specified stream. */
+
+EXPORT void dm_lnls P_((p_wf_t));
+/* Dumps a text representation of the global line list to the given stream. */
+
+EXPORT void dm_tkls P_((p_wf_t));
+/* Dumps a text representation of the global token list to the given stream. */
+
+EXPORT void dm_matb P_((p_wf_t));
+/* Dumps a text representation of the macro table to the given stream. */
+
+EXPORT void dm_dcls P_((p_wf_t));
+/* Dumps a text representation of the document list to the given stream. */
+
+EXPORT void dm_times P_((p_wf_t,p_ck_t,p_ck_t,p_ck_t,p_ck_t,
+ p_ck_t,p_ck_t,p_ck_t,p_ck_t,p_ck_t));
+/* Dumps a text representation of the execution times to the given stream. */
+
+/******************************************************************************/
+/* End of DUMP.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/environ.h b/web/funnelAC/sources/environ.h
new file mode 100644
index 0000000000..e9b468e31d
--- /dev/null
+++ b/web/funnelAC/sources/environ.h
@@ -0,0 +1,231 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* ENVIRON.H */
+/******************************************************************************/
+/* */
+/* WARNING: DO NOT ADD ANY PROGRAM-DEPENDENT DEFINITIONS. */
+/* */
+/* This header file environ.h contains definitions and objects whose values */
+/* depends directly on the compilation and execution environment, but are */
+/* otherwise independent of any particular computer program. */
+/* */
+/* This is one of two machine-dependent, program-independent modules. The */
+/* other module is machin (machin.h,machin.c). This "environ" module contains */
+/* definitions and objects that are considered essential. The "machin" module */
+/* contains less essential definitions. Motivation for the division came from */
+/* the fact that style.h (used by almost every module) includes environ.h */
+/* (this file), and from the need for the stuff in style.h by some */
+/* environment-dependent definitions. */
+/* */
+/* There seems to be two ways to organize a module such as this one. The */
+/* first is to have a different version of this module for each target */
+/* environment. The second is to have a single file that uses #defines and */
+/* #ifs to select between code for each target environment. I have chosen the */
+/* latter method as this allows many different environments to share the same */
+/* definitions. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_ENVIRON
+#define DONE_ENVIRON
+
+/******************************************************************************/
+
+/* Select An Environment */
+/* --------------------- */
+/* Choose the environment in which the program will be compiled and executed. */
+/* This may be the only change you need to make to get FunnelWeb to compile. */
+/* */
+/* If your exact environment is not listed, try one that is close. */
+/* If problems arise, an attempt should be made to solve them */
+/* without creating a new environment definition. However, if this is not */
+/* possible, define a new environment below and "implement" it by going */
+/* through environ.h and machin.h and machin.c and adding appropriate */
+/* definitions. */
+/* */
+/* The following table lists real/defined environment pairs under which */
+/* FunnelWeb is known to compile cleanly. */
+/* */
+/* Symbol = Processor Machine OS Compiler */
+/* ------ --------- ------- -- -------- */
+/* MAC = 68000 Macintosh-SE Mac THINK-C V4.0.5 */
+/* SUN = SPARC SUN ELC Unix(SunOS) GNUC */
+/* VMS = VAX VAXStation VMS VAXC */
+/* PC = 386 IBM PC Clone MSDOS5.0 Borland C++ */
+/* */
+/* Set exactly one of the following environments to 1, the others to 0. */
+
+#define MAC 0
+#define SUN 1
+#define VMS 0
+#define PC 0
+
+/* Ensure that exactly one environment has been selected. */
+#if MAC+SUN+VMS+PC != 1
+ #error Error: You must choose exactly one machine in ENVIRON.H.
+#endif
+
+/******************************************************************************/
+
+/* Establish Presence or Absence of __STDC__ */
+/* ----------------------------------------- */
+/* The __STDC__ symbol is very useful for determining if the compiler is */
+/* ANSI. However, some "nearly ANSI" compilers don't set this symbol, and */
+/* experience shows that things turn out better if it is set. */
+/* This section decides if __STDC__ should be defined. */
+
+/* The Macintosh THINK C compiler seems to be ANSI standard but, strangely */
+/* does not define the standard preprocessor symbol __STDC__ that indicates */
+/* this. Instead it defines THINK_C. Here, we execute the link manually. */
+/* For more information see the THINK C User's Manual, Chapter 57: "Language */
+/* Reference", Section 12.10, p.442. */
+#ifdef THINK_C
+#define __STDC__ 1
+#endif
+
+/* The problem seems to exist with VAX C too. */
+#if VMS
+#define __STDC__ 1
+#endif
+
+/******************************************************************************/
+
+/* Switch From Definedness to Boolean Symbols */
+/* ------------------------------------------ */
+/* Use of the definedness of a preprocessor symbol to detect a condition is */
+/* convenient if it is desired that only one condition be tested at a time. */
+/* However, if we want to OR conditions, it is more convenient to use defined */
+/* symbols that are either 0 or 1. This section contains ifdefs that do this. */
+
+#ifdef __STDC__
+#define STDC 1
+#else
+#define STDC 0
+#endif
+
+/* Note: If THINK_C is predefined, it is predefined to be 1. */
+#ifndef THINK_C
+#define THINK_C 0
+#endif
+
+/******************************************************************************/
+
+/* Void */
+/* ---- */
+/* Define void if necessary and define pointer to void. */
+/* This idea from the book "Portable C", p.41. */
+/* If necessary, add a boolean condition to cover your environment. */
+/* Note: The "| SUN" is a last minute desperate hack. */
+#if STDC | SUN
+typedef void *p_void;
+#else
+typedef int void;
+typedef char *p_void;
+#endif
+
+/* The following function is here solely to act as a first tripping point for */
+/* environments with no "void" so that the users trying to port this code */
+/* will look here first instead of starting to delete voids in the program. */
+extern void test_void();
+
+/******************************************************************************/
+
+/* Const */
+/* ----- */
+/* It's useful to be able to specify that certain objects are constants. */
+/* Unfortunately, the "const" construct is only available in ANSI C and so we */
+/* have to have a macro so as to cope with non-ANSI compilers. */
+/* Note: THINK-C is nearly ANSI, but does not support "const". */
+#if STDC & !THINK_C
+#define CONST const
+#else
+#define CONST
+#endif
+
+/******************************************************************************/
+
+/* Prototypes */
+/* ---------- */
+/* Define a macro to wrap around prototype parameter lists so as to support */
+/* compilers with and without prototypes. */
+/* This idea came from the book "Portable C", S3.1, p.32. */
+#if STDC
+#define P_(A) A
+#else
+#define P_(A) ()
+#endif
+
+/******************************************************************************/
+
+/* Structure Assignments */
+/* --------------------- */
+/* Structure assignments are not supported on some of the older compilers and */
+/* so we use a macro to perform such operations. */
+/* This idea came from the book "Portable C", S8.2.2, p.184. */
+#if STDC
+#define ASSIGN(a,b) ((a)=(b))
+#else
+#define ASSIGN(a,b) (memcpy((char *)&(a),(char *)&(b),sizeof(a)))
+#endif
+
+/******************************************************************************/
+
+/* VMS EXIT STATUS */
+/* --------------- */
+/* The VAX C compiler I used doesn't seem to be ANSI. This means that the */
+/* exit symbols aren't set up properly. Furthermore, the sensible defaults */
+/* in the style.h file don't work for VMS. The upshot is that we have to do */
+/* a special case. Note: The top bit set in a VMS exit status means suppress */
+/* diagnostic message. Even status means failure. Odd means success. */
+#if VMS
+#undef EXIT_SUCCESS
+#undef EXIT_FAILURE
+#define EXIT_SUCCESS 1
+#define EXIT_FAILURE (0x10000002)
+#endif
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of ENVIRON.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/help.c b/web/funnelAC/sources/help.c
new file mode 100644
index 0000000000..83911b3a07
--- /dev/null
+++ b/web/funnelAC/sources/help.c
@@ -0,0 +1,605 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* HELP.C */
+/******************************************************************************/
+/* */
+/* REPRESENTING MESSAGES AS C CODE */
+/* =============================== */
+/* Experience has shown that it is much more reliable to code text messages */
+/* into a program than to expect the program to track down text files */
+/* containing the messages at run time. Worthwhile for smallish files (such */
+/* as these help messages) at least. For this reason, most the messages in */
+/* this module are represented by code (e.g. as in printf statements). */
+/* */
+/* The only exception is the 18K Gnu license message which is a bit too big */
+/* to be done by hand. It has been moved to the help_gnu module. */
+/* */
+/******************************************************************************/
+
+#include <ctype.h>
+#include "style.h"
+
+#include "as.h"
+#include "help.h"
+#include "help_gnu.h"
+#include "misc.h"
+#include "option.h"
+
+/******************************************************************************/
+
+/* This module contains many many output statements that call an output */
+/* function. To neaten up all these calls, we define a global variable to */
+/* hold a pointer to the function and simple macro to write output using */
+/* the function. */
+LOCVAR void (*pf) P_((char *));
+
+#define WX(STR) (*pf)(STR)
+
+/******************************************************************************/
+
+LOCAL void hel_men P_((void));
+LOCAL void hel_men ()
+{
+ WX("\n");
+ WX("FunnelWeb Help Messages\n");
+ WX("-----------------------\n");
+ WX("Introduction - Introduction to FunnelWeb.\n");
+ WX("DOcumentation - How to obtain FunnelWeb documentation.\n");
+ WX("Options - Command line options.\n");
+ WX("DEfoptions - Default command line options.\n");
+ WX("COMmands - Interactive commands.\n");
+ WX("Registration - How to register as an \"official\" FunnelWeb user.\n");
+ WX("Support - How you can help support FunnelWeb development.\n");
+ WX("COPyright - Copyright notice.\n");
+ WX("License - The license under which this software is distributed (long).\n");
+ WX("Nowarranty - Extract from the GNU license concerning lack of warranty.\n");
+ WX("DIstribution - Extract from the GNU license concerning distribution.\n");
+ WX("MOdification - Read this message if you intend to modify FunnelWeb.\n");
+ WX("Versions - A list of existing versions of FunnelWeb.\n");
+ WX("Acknowledge - Thanks to people who helped with FunnelWeb development.\n");
+ WX("MEnu - The message you are reading (the default help message).\n");
+ WX("\n");
+ WX("To display a message, give its (optionally abbreviated) name in a help command.\n");
+ WX("To capture a message to a file, add +J<filename> to the fw command. Examples:\n");
+ WX("\n");
+ WX(" fw +Hintroduction +Jintro.txt -- From the operating system level.\n");
+ WX(" help introduction -- From FunnelWeb interactive mode.\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_int P_((void));
+LOCAL void hel_int ()
+{
+ WX("\n");
+ WX("FunnelWeb Introduction\n");
+ WX("----------------------\n");
+ WX("Welcome to FunnelWeb, a literate-programming macro preprocessor.\n");
+ WX("\n");
+ WX("Traditional computer programs are primarily written for computers and consist\n");
+ WX("of code laced with comments. In contrast, literate programs are primarily\n");
+ WX("written for humans and consist of comments laced with code. While simple, the\n");
+ WX("effect of this inversion can be so profound as to change one's whole approach\n");
+ WX("to programming. The literate programmer focuses on conveying meaning to other\n");
+ WX("intelligent beings rather than merely convincing the computer to behave in a\n");
+ WX("particular way. It is the difference between performing and exposing a magic\n");
+ WX("trick.\n");
+ WX("\n");
+ WX("FunnelWeb is a production-quality literate-programming tool that emphasises\n");
+ WX("simplicity and reliability. It provides a macro facility, and assists in the\n");
+ WX("production of typeset documentation. FunnelWeb runs on most popular machines\n");
+ WX("(Sun, VAX, Mac, PC) and its highly portable source code in C is freely\n");
+ WX("available under a GNU license.\n");
+ WX("\n");
+ WX("To get started with FunnelWeb, obtain a printed copy of the \"FunnelWeb User's\n");
+ WX("Manual\" (see the \"DOCUMENTATION\" help message). Read the introduction and work\n");
+ WX("through the tutorial. The manual contains an overview of FunnelWeb, an\n");
+ WX("introductory tutorial, and a comprehensive reference manual. Try it!\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_opt P_((void));
+LOCAL void hel_opt ()
+{
+ WX("\n");
+ WX("FunnelWeb Command Line Options\n");
+ WX("------------------------------\n");
+ WX("Options are of the form (\"+\" | \"=\" | \"-\") <letter> [<string>].\n");
+ WX("+ turns on an option. - turns it off. = doesn't affect it's onoffedness.\n");
+ WX("The case (e.g. upper or lower) of <letter> does not matter.\n");
+ WX("<string> is usually a filename or directory, but sometimes a number.\n");
+ WX("Convention: f=filename, n=decimal number, h=help message name.\n");
+ WX("\n");
+ WX("Example: fw sloth +L +Jaardvark.xxx +W80 -Q =Twalrus.tex\n");
+ WX("\n");
+ WX("Action options: (choose at least one when you invoke FunnelWeb from the OS).\n");
+ WX("If you choose more than one, they will be executed in the order given here.\n");
+ WX(" +Xf Execute specified Funnelweb script.\n");
+ WX(" +Ff Process specified input file.\n");
+ WX(" +Hh Display specified help message.\n");
+ WX(" +K Invoke FunnelWeb's interative mode.\n");
+ WX("\n");
+ WX("Other options:\n");
+ WX(" +B1 Diagnostic: Dump image of input file to listing file.\n");
+ WX(" +B2 Diagnostic: Dump scanner's line list to listing file.\n");
+ WX(" +B3 Diagnostic: Dump scanner's token list to listing file.\n");
+ WX(" +B4 Diagnostic: Dump parser's macro table to listing file.\n");
+ WX(" +B5 Diagnostic: Dump parser's document list to listing file.\n");
+ WX(" +B6 Diagnostic: Dump time breakdown report to listing file.\n");
+ WX(" +B7 Diagnostic: Suppress non-deterministic output.\n");
+ WX(" +Cn Number of lines of context around diagnostics in listing file.\n");
+ WX(" +D Delete each output file identical to its previous version.\n");
+ WX(" +If Default file specification for include files.\n");
+ WX(" +Jf Generate journal file. Default file specification.\n");
+ WX(" +Lf Generate listing file. Default file specification.\n");
+ WX(" +Of Generate product files. Default file specification.\n");
+ WX(" +Q Quiet mode. Only really important messages displayed on console.\n");
+ WX(" +Tf Generate typesetter file. Default file specification.\n");
+ WX(" +Sn Send errors to console with specified number of lines of context.\n");
+ WX(" +Wn Set maximum length of lines in product files.\n");
+ WX("\n");
+ WX("If an option appears more than once, the rightmost one dominates.\n");
+ WX("For more detailed information, refer to the FunnelWeb User's Manual.\n");
+ WX("For default values refer to the \"DEFOPTIONS\" help message.\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_dop P_((void));
+LOCAL void hel_dop ()
+{
+ op_t defop;
+
+ WX("\n");
+ WX("FunnelWeb Default Option Settings\n");
+ WX("---------------------------------\n");
+ WX("These are the settings FunnelWeb STARTS UP with.\n");
+ op_ini(&defop);
+ WX("\n");
+ op_wri(&defop,pf);
+ WX("\n");
+ WX("See the OPTIONS help message for a brief description of these options.\n");
+ WX("For more detailed information, refer to the FunnelWeb User's Manual.\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_com P_((void));
+LOCAL void hel_com ()
+{
+ WX("\n");
+ WX("FunnelWeb Interactive Commands\n");
+ WX("------------------------------\n");
+ WX(" ! - Comment. Ignores the whole line. \n");
+ WX(" ABSENT fn - Aborts if specified file exists. \n");
+ WX(" CODIFY ftext fC - Convert text file into C code to write text. \n");
+ WX(" COMPARE f1 f2 - Aborts if two files are different. \n");
+ WX(" DEFINE n \"text\" - Defines $n to translate to text. \n");
+ WX(" DIFF f1 f2 logf [ABORT] - Writes differences between f1 and f2 to logf.\n");
+ WX(" - Severe if different and ABORT is present. \n");
+ WX(" DIFFSUMMARY - Summary of differences done since DIFFZERO. \n");
+ WX(" DIFFZERO - Zeros differences counters. \n");
+ WX(" ENEO fn - Establish Non Existence Of file. \n");
+ WX(" EXECUTE fn - Execute commands in specified file. \n");
+ WX(" EXISTS fn - Aborts if file does not exist. \n");
+ WX(" FIXEOLS fn [outf] - Fixes up EOL markers in specified file. \n");
+ WX(" FW options - Invoke FunnelWeb-proper once. \n");
+ WX(" HELP [name] - Displays specified help message. \n");
+ WX(" HERE - Terminates effect of SKIPTO command. \n");
+ WX(" QUIT - Quits FunnelWeb. \n");
+ WX(" SET options - Sets options. \n");
+ WX(" SHOW - Displays currently active options. \n");
+ WX(" SKIPTO - Ignore commands until HERE command. \n");
+ WX(" STATUS - Write out status and diagnostic counts. \n");
+ WX(" STATUS [Sn] [En] [Wn] - Aborts if status is not as specified. \n");
+ WX(" TOLERATE - Don't abort script if next commmand gens err.\n");
+ WX(" TRACE ON | OFF - Turns command tracing ON or OFF. \n");
+ WX(" WRITE \"text\" - Writes specified text to screen and journal. \n");
+ WX(" WRITEU \"text\" - Same as WRITE but underlines text. \n");
+ WX("\n");
+ WX("More detailed information can be found in the FunnelWeb User's Manual.\n");
+ WX("\n");
+ WX("Most of these commands were created to support regression testing and\n");
+ WX("can be ignored by most users. In fact most users will never need to invoke\n");
+ WX("FunnelWeb's interactive mode at all. If you are just getting started\n");
+ WX("with FunnelWeb, it's probably best to run FunnelWeb directly from your\n");
+ WX("command interface and ignore the +K command line option for now.\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_doc P_((void));
+LOCAL void hel_doc ()
+{
+ WX("\n");
+ WX("FunnelWeb Documentation\n");
+ WX("-----------------------\n");
+ WX("The following FunnelWeb documentation is available:\n");
+ WX("\n");
+ WX(" \"FunnelWeb User's Manual\": Tutorial, Hints, Reference Manual.\n");
+ WX(" \"FunnelWeb Hacker's Manual\": Notes on Design and Implementation.\n");
+ WX("\n");
+ WX("Everyone involved with FunnelWeb should read the User's Manual.\n");
+ WX("It contains everything you need to learn how to use FunnelWeb.\n");
+ WX("\n");
+ WX("The Hacker's Manual is for those who want to install, modify, fix,\n");
+ WX("fiddle with, and generally hack the FunnelWeb C source code.\n");
+ WX("\n");
+ WX("Both of these manuals are shipped with the FunnelWeb distribution\n");
+ WX("kit, and should be available on your machine in the form of LaTeX text\n");
+ WX("files. If you cannot find them, you can obtain them by FTP from:\n");
+ WX("\n");
+ WX(" Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3].\n");
+ WX(" Directory: ~pub/funnelweb/ (or a directory of similar name).\n");
+ WX("\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_reg P_((void));
+LOCAL void hel_reg ()
+{
+ WX("FunnelWeb Registration\n");
+ WX("----------------------\n");
+ WX("If you install or use FunnelWeb, please fill in and return this form:\n");
+ WX("\n");
+ WX(" +----------------------FunnelWeb Registration Form----------------------+\n");
+ WX(" | 1. Date: |\n");
+ WX(" | 2. Title and name: |\n");
+ WX(" | 3. Internet email address: |\n");
+ WX(" | 4. Snail mail address: |\n");
+ WX(" | 5. Work phone number (country,area,number): |\n");
+ WX(" | 6. Which category of FunnelWeb user best describes you? |\n");
+ WX(" | Latent - Installed FunnelWeb, but don't intend to use it. |\n");
+ WX(" | Beginner - Haven't used FunnelWeb much yet; have an open mind. |\n");
+ WX(" | Casual - Use FunnelWeb occasionally. |\n");
+ WX(" | Convert - Use FunnelWeb to do most programming. |\n");
+ WX(" | Fanatic - FunnelWeb has become a way of life. |\n");
+ WX(" | 7. What changes or new features would you like to see in FunnelWeb? |\n");
+ WX(" | 8. Do you want to be kept informed of new FunnelWeb developments? |\n");
+ WX(" | 9. Email this form to \"ross@spam.adelaide.edu.au\", OR snail mail to |\n");
+ WX(" | Ross Williams, 16 Lerwick Avenue, Hazelwood Park 5066, Australia. |\n");
+ WX(" +-----------------------------------------------------------------------+\n");
+ WX("To write this form to a file, use \"fw +hreg +jregform.txt\".\n");
+ WX("You may wish to make a contribution when you register. See SUPPORT.\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_cop P_((void));
+LOCAL void hel_cop ()
+{
+ WX("\n");
+ WX("FunnelWeb Copyright\n");
+ WX("-------------------\n");
+ WX("Copyright (C) 1992 Ross Williams.\n");
+ WX("\n");
+ WX("However, FunnelWeb has been released by the author and copyright owner Ross\n");
+ WX("Williams (ross@spam.adelaide.edu.au) under Version 2 of the GNU General Public\n");
+ WX("License published by the Free Software Foundation. This means that you can\n");
+ WX("redistribute FunnelWeb and/or modify it under the terms of the license.\n");
+ WX("\n");
+ WX("Note: This program is distributed WITHOUT ANY WARRANTY; without even the\n");
+ WX("implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
+ WX("\n");
+ WX("The following help messages provide further information:\n");
+ WX("\n");
+ WX(" License - The license under which this software is distributed (long).\n");
+ WX(" DIstribution - Extract from the GNU license concerning distribution.\n");
+ WX(" Nowarranty - Extract from the GNU license concerning lack of warranty.\n");
+ WX(" MOdification - Read this message if you intend to modify FunnelWeb.\n");
+ WX(" Registration - How to register as an \"official\" FunnelWeb user.\n");
+ WX("\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_now P_((void));
+LOCAL void hel_now ()
+{
+ WX("\n");
+ WX("FunnelWeb Comes With No Warranty\n");
+ WX("--------------------------------\n");
+ WX("Here is an extract from the GNU General Public License Version 2, under which\n");
+ WX("FunnelWeb is distributed. See help message \"LICENSE\" for the full license.\n");
+ WX("\n");
+ WX(" 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n");
+ WX(" FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n");
+ WX(" OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n");
+ WX(" PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n");
+ WX(" OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n");
+ WX(" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n");
+ WX(" TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n");
+ WX(" PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n");
+ WX(" REPAIR OR CORRECTION.\n");
+ WX("\n");
+ WX(" 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n");
+ WX(" WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n");
+ WX(" REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n");
+ WX(" INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n");
+ WX(" OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n");
+ WX(" TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n");
+ WX(" YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n");
+ WX(" PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n");
+ WX(" POSSIBILITY OF SUCH DAMAGES.\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_dis P_((void));
+LOCAL void hel_dis ()
+{
+ WX("\n");
+ WX("FunnelWeb Distribution\n");
+ WX("----------------------\n");
+ WX("The following is an extract from the GNU General Public License Version 2,\n");
+ WX("under which FunnelWeb is distributed.\n");
+ WX("\n");
+ WX(" 1. You may copy and distribute verbatim copies of the Program's\n");
+ WX(" source code as you receive it, in any medium, provided that you\n");
+ WX(" conspicuously and appropriately publish on each copy an appropriate\n");
+ WX(" copyright notice and disclaimer of warranty; keep intact all the\n");
+ WX(" notices that refer to this License and to the absence of any warranty;\n");
+ WX(" and give any other recipients of the Program a copy of this License\n");
+ WX(" along with the Program.\n");
+ WX("\n");
+ WX(" You may charge a fee for the physical act of transferring a copy, and\n");
+ WX(" you may at your option offer warranty protection in exchange for a fee.\n");
+ WX("\n");
+ WX("The license also allows you other freedoms. For more information refer\n");
+ WX("to the full text of the license in the help message \"LICENSE\".\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_ack P_((void));
+LOCAL void hel_ack ()
+{
+ WX("\n");
+ WX("FunnelWeb Acknowledgements\n");
+ WX("--------------------------\n");
+ WX("The following people assisted with the preparation of FunnelWeb V3.0.\n");
+ WX("\n");
+ WX("Many thanks go to DAVID HULSE (dave@cs.adelaide.edu.au) who translated the 1986\n");
+ WX("version of FunnelWeb (V1) written in Ada into a public domain C version (V2).\n");
+ WX("The C code written by David formed the basis of V3 of FunnelWeb, but was\n");
+ WX("entirely rewritten during the intensive refinement and feature-injection\n");
+ WX("period leading up to this release (V3 is about 3 times the size of V2).\n");
+ WX("\n");
+ WX("Thanks go to SIMON HACKETT (simon@internode.com.au) of Internode Systems\n");
+ WX("Pty Ltd for the use of his Sun, Mac, and PC, for assistance in porting\n");
+ WX("FunnelWeb to the Sun and PC, and for helpful discussions.\n");
+ WX("\n");
+ WX("Thanks go to JEREMY BEGG (jeremy@vsm.com.au) of VSM Software Services\n");
+ WX("for the use of his VAX, and for assistance with the VMS-specific code.\n");
+ WX("\n");
+ WX("Ross Williams (ross@spam.adelaide.edu.au), 12 May 1992.\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_ver P_((void));
+LOCAL void hel_ver ()
+{
+ WX("\n");
+ WX("FunnelWeb Versions\n");
+ WX("------------------\n");
+ WX("FunnelWeb was created in 1986 and was used extensively by Ross Williams\n");
+ WX("(ross@spam.adelaide.edu.au) for three years. However, Version 1.0 was written\n");
+ WX("in Ada and was not very portable (it was fairly VAX/VMS specific). David Hulse\n");
+ WX("(dave@cs.adelaide.edu.au) took the first step towards a release by translating\n");
+ WX("the Ada code into C. Ross Williams then extensively reworked the C code, making\n");
+ WX("it robust and portable, adding new features, and polishing it to its current\n");
+ WX("form.\n");
+ WX("\n");
+ WX("Vers Lang Created Released Author Copyright Licensing \n");
+ WX("---- ---- ------- -------- -------------- ------------- --------- \n");
+ WX("V1.0 Ada 1986 Never Ross Williams Ross Williams \n");
+ WX("V2.0 C 1989 Never David Hulse Public domain No restriction.\n");
+ WX("V3.0 C 1992 May-1992 Ross Williams Ross Williams GNU release. \n");
+ WX("\n");
+ WX("This is FunnelWeb Version 3.0. Unless otherwise specified, all references\n");
+ WX("in this release to \"FunnelWeb\" refer either to the abstract identity\n");
+ WX("of FunnelWeb, or to this version, FunnelWeb Version 3.0.\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_sup P_((void));
+LOCAL void hel_sup ()
+{
+ WX("\n");
+ WX("FunnelWeb Support\n");
+ WX("-----------------\n");
+ WX("FunnelWeb is released \"as is\" under a GNU license, and no formal support\n");
+ WX("is available. You have the right to make changes to FunnelWeb and to use\n");
+ WX("the modified versions created by random programmers. However, this is\n");
+ WX("discouraged (see the MODIFICATION help message).\n");
+ WX("\n");
+ WX("In fact the support that is most needed is your financial support for the\n");
+ WX("FunnelWeb developers! It has taken MONTHS of full-time UNPAID work to bring\n");
+ WX("FunnelWeb to you in its current form. I don't want to inconvenience users\n");
+ WX("who install FunnelWeb, play with it, and then hardly ever use it. If you are\n");
+ WX("in this category, please register, but don't bother contributing. However,\n");
+ WX("if you find that FunnelWeb has become a useful programming tool, a contribution\n");
+ WX("of some positive multiple of US$50 would be appreciated.\n");
+ WX("\n");
+ WX("To make a contribution, send payment with a completed registration form\n");
+ WX("(see the REGISTRATION help message) to:\n");
+ WX("\n");
+ WX(" Renaissance Software Pty Ltd\n");
+ WX(" Email: ross@spam.adelaide.edu.au\n");
+ WX(" Snail: 16 Lerwick Avenue, Hazelwood Park 5066, Australia.\n");
+ WX("\n");
+ WX("Payment can be by personal or bank cheque to any bank in the world or by\n");
+ WX("Visa or Mastercard. Please give the card name, number, expiry date, and\n");
+ WX("the amount to be paid in US dollars. All contributions will be appreciated\n");
+ WX("and will encourage further FunnelWeb development. However, no undertaking\n");
+ WX("is made whatsoever about how the money will be used.\n");
+ WX("\n");
+ WX("Ross Williams (ross@spam.adelaide.edu.au), 12 May 1992.\n");
+}
+
+/******************************************************************************/
+
+LOCAL void hel_mod P_((void));
+LOCAL void hel_mod ()
+{
+ WX("\n");
+ WX("FunnelWeb Modifications\n");
+ WX("-----------------------\n");
+ WX("FunnelWeb is distributed under a GNU license, and you are free to modify the\n");
+ WX("source code and distribute modified copies (see the help message LICENSE).\n");
+ WX("However, there are good reasons why you should avoid doing this.\n");
+ WX("\n");
+ WX(" 1) If you distribute modified versions of FunnelWeb, you run the risk of\n");
+ WX(" creating a version that will diverge from the \"official\" version of\n");
+ WX(" FunnelWeb which I intend to maintain.\n");
+ WX("\n");
+ WX(" 2) If you release a version of FunnelWeb with a changed input language,\n");
+ WX(" users of your modified version will create source files that will no\n");
+ WX(" longer work on other versions of FunnelWeb. The result will be chaos.\n");
+ WX("\n");
+ WX("For these reasons I request that you do not distribute modified versions of\n");
+ WX("FunnelWeb, particularly versions with a modified language. However, if you must\n");
+ WX("distribute a version with a modified language, PLEASE CHANGE ITS NAME (i.e.\n");
+ WX("from \"FunnelWeb\" to something else). Please also allocate a new file extension\n");
+ WX("to replace \".fw\" as the extension for source files written in the modified\n");
+ WX("language. For more information, refer to the FunnelWeb Hacker's Manual.\n");
+ WX("\n");
+ WX("Ross Williams (ross@spam.adelaide.edu.au), 12 May 1992.\n");
+}
+
+/******************************************************************************/
+
+LOCAL bool prefeq P_((char *,char *));
+LOCAL bool prefeq (p_pref,p_target)
+/* Returns TRUE iff string p_pref is a case insensitive prefix of p_target. */
+char *p_pref;
+char *p_target;
+{
+ char *p,*q;
+
+ if (strlen(p_pref) > strlen(p_target))
+ return FALSE;
+
+ p=p_pref;
+ q=p_target;
+ while (*p != EOS)
+ {
+ if (toupper(*p) != toupper(*q)) return FALSE;
+ p++;
+ q++;
+ }
+ return TRUE;
+}
+
+/******************************************************************************/
+
+EXPORT uword hel_num (p_name)
+char *p_name;
+{
+ uword matches = 0;
+ uword messnum;
+
+ /* We want to be fairly lenient on the user here as the user is trying to */
+ /* obtain help and will probably get annoyed and give up if it doesn't work, */
+ /* so we perform case insensitive prefix matching. However, we don't want */
+ /* to match if the user inputs a prefix that matches two message names. This */
+ /* means we can't just return when we find a match; we have to see if there */
+ /* are any others as well. */
+
+ if (prefeq(p_name,"MENU" )) {messnum=HL_MEN; matches++;}
+ if (prefeq(p_name,"INTRODUCTION" )) {messnum=HL_INT; matches++;}
+ if (prefeq(p_name,"OPTIONS" )) {messnum=HL_OPT; matches++;}
+ if (prefeq(p_name,"DEFOPTIONS" )) {messnum=HL_DOP; matches++;}
+ if (prefeq(p_name,"COMMANDS" )) {messnum=HL_COM; matches++;}
+ if (prefeq(p_name,"DOCUMENTATION")) {messnum=HL_DOC; matches++;}
+ if (prefeq(p_name,"REGISTRATION" )) {messnum=HL_REG; matches++;}
+ if (prefeq(p_name,"LICENSE" )) {messnum=HL_GNU; matches++;}
+ if (prefeq(p_name,"COPYRIGHT" )) {messnum=HL_COP; matches++;}
+ if (prefeq(p_name,"NOWARRANTY" )) {messnum=HL_NOW; matches++;}
+ if (prefeq(p_name,"DISTRIBUTION" )) {messnum=HL_DIS; matches++;}
+ if (prefeq(p_name,"ACKNOWLEDGE" )) {messnum=HL_ACK; matches++;}
+ if (prefeq(p_name,"VERSIONS" )) {messnum=HL_VER; matches++;}
+ if (prefeq(p_name,"SUPPORT" )) {messnum=HL_SUP; matches++;}
+ if (prefeq(p_name,"MODIFICATION" )) {messnum=HL_MOD; matches++;}
+
+ if (matches != 1) return HL_ERR;
+
+ return messnum;
+}
+
+/******************************************************************************/
+
+EXPORT void hel_wri (p_outf,messno)
+void (*p_outf) P_((char *));
+uword messno;
+{
+ as_cold( 1 <= messno, "hel_wri: Message number is zero.");
+ as_cold(messno <= HL_MAX, "hel_wri: Message number is greater than HL_MAX.");
+
+ /* Set the global output function pointer. */
+ pf=p_outf;
+
+ switch(messno)
+ {
+ case HL_MEN: hel_men(); break;
+ case HL_INT: hel_int(); break;
+ case HL_OPT: hel_opt(); break;
+ case HL_DOP: hel_dop(); break;
+ case HL_COM: hel_com(); break;
+ case HL_DOC: hel_doc(); break;
+ case HL_REG: hel_reg(); break;
+ case HL_GNU: hel_gnu(p_outf); break; /* Calling another module. */
+ case HL_COP: hel_cop(); break;
+ case HL_NOW: hel_now(); break;
+ case HL_DIS: hel_dis(); break;
+ case HL_ACK: hel_ack(); break;
+ case HL_VER: hel_ver(); break;
+ case HL_SUP: hel_sup(); break;
+ case HL_MOD: hel_mod(); break;
+ default : as_bomb("hel_wri: switch defaulted.");
+ }
+}
+
+/******************************************************************************/
+/* End of HELP.C */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/help.h b/web/funnelAC/sources/help.h
new file mode 100644
index 0000000000..fc50010c6a
--- /dev/null
+++ b/web/funnelAC/sources/help.h
@@ -0,0 +1,161 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* HELP.H */
+/******************************************************************************/
+/* */
+/* HELP PACKAGE */
+/* ============ */
+/* As I came closer and closer to completing the release version of */
+/* FunnelWeb, I noticed that the online help was a bit of a mess. I had */
+/* random commands and command line options here and there to provide bits of */
+/* information. After a close look and some thought, I decided to centralize */
+/* all of FunnelWeb's help messages into one module, and provide a clean and */
+/* consistent interface to the help messages, both in the command line, and */
+/* in interactive mode. */
+/* */
+/* The result is that all of the help messages have been moved to */
+/* this module. Each help message has a name consisting of a string. One */
+/* particular message has the name "MENU" and is the root help message (the */
+/* "menu message"). It contains a list of all the help messages available and */
+/* their names. */
+/* */
+/* The command line connects to help by providing a single command line */
+/* option called +Hx which has the effect of displaying the help message */
+/* called x. The default is -Hmenu. The "-" means that help is not invoked by */
+/* default, but that if the user specifies +H, the menu message will be */
+/* printed. If the user specifies (say) +Hsloth, message SLOTH will be */
+/* displayed. The menu message is printed if the user invokes FunnelWeb with */
+/* no actions. The +H option is classified as an action option. */
+/* */
+/* Interactive mode connects to help through the HELP command. In the spirit */
+/* of the command line interface, if no argument is given, the menu message */
+/* is displayed. If an argument is given, the specified message is written */
+/* out. */
+/* */
+/* This module contributes two things to this process: */
+/* 1) Provides a mapping from message names to messages. */
+/* 2) Acts as a repository for the messages themselves. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_HELP
+#define DONE_HELP
+
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+/* Place a bound on help name length, and define an array type to hold them. */
+#define HL_NMLEN 20
+typedef char hn_t[HL_NMLEN+1];
+
+/******************************************************************************/
+
+/* Each of the messages has a unique symbol and number. The reason for */
+/* defining these symbols instead of just using the message names in the code */
+/* is that doing it this way allows us to change the exact message names */
+/* without having to track down all their occurences in the code, or getting */
+/* nasty surprises later down the track at run time (the compiler will tell */
+/* you in a call containing HL_SLT that the symbol doesn't exist, but it */
+/* won't complain about a string argument that just happens not to be the */
+/* name of a message anymore). */
+
+/* HL_ERR is the non-existent message. */
+#define HL_ERR 0
+
+/* HL_MEN - Help messages. */
+/* HL_INT - Introduction to FunnelWeb. */
+/* HL_OPT - Command line options. */
+/* HL_DOP - Option defaults. */
+/* HL_COM - Interactive commands. */
+/* HL_DOC - Documentation. */
+/* HL_REG - Registration. */
+/* HL_LIC - The GNU License. */
+/* HL_COP - Copyright notice. */
+/* HL_NOW - No Warranty notice. */
+/* HL_DIS - Distribution notice. */
+/* HL_ACK - Acknowledgements. */
+/* HL_VER - Versions. */
+/* HL_SUP - Support. */
+/* HL_MOD - Modifications. */
+#define HL_MEN 1
+#define HL_INT 2
+#define HL_OPT 3
+#define HL_DOP 4
+#define HL_COM 5
+#define HL_DOC 6
+#define HL_REG 7
+#define HL_GNU 8
+#define HL_COP 9
+#define HL_NOW 10
+#define HL_DIS 11
+#define HL_ACK 12
+#define HL_VER 13
+#define HL_SUP 14
+#define HL_MOD 15
+
+/* The following symbol does not represent a message. It is the number of */
+/* messages. This is useful for range checking and possibly in for loops. */
+#define HL_MAX 15
+
+/******************************************************************************/
+
+EXPORT uword hel_num P_((char *));
+/* Accepts a character string that is supposed to be the name of a message */
+/* and returns the number of the message, or HL_ERR if the string does not */
+/* correspond to any defined message. A match will occur if the argument */
+/* string is the same (with case independent matching) as the prefix (of */
+/* corresponding length) of exactly one message name. */
+
+EXPORT void hel_wri P_((void (*)(char *),uword));
+/* Accepts a message number and writes the message using the function */
+/* provided in the first argument. Bombs the program if the message number in */
+/* the second argument is not in the range [1,HL_MAX]. */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of HELP.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/help_gnu.c b/web/funnelAC/sources/help_gnu.c
new file mode 100644
index 0000000000..20555d3b14
--- /dev/null
+++ b/web/funnelAC/sources/help_gnu.c
@@ -0,0 +1,105 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* HELP_GNU.C */
+/******************************************************************************/
+/* */
+/* REPRESENTING MESSAGES AS C CODE */
+/* =============================== */
+/* Experience has shown that it is much more reliable to code text messages */
+/* into a program than to expect the program to track down text files */
+/* containing the messages at run time. Worthwhile for smallish files (such */
+/* as these help messages) at least. For this reason, all the messages in */
+/* this module are represented by code (e.g. as in printf statements). */
+/* */
+/* There is no difficulty turning a short message into code; simply place it */
+/* in output statements. However, large messages (e.g. the GNU license) are */
+/* more tedious, and also present more of a problem if it is necessary to */
+/* change them substantially at a later date. This problem has been solved in */
+/* FunnelWeb by writing a small program that reads a text file and writes out */
+/* C code that writes the text file. The files involved are: */
+/* */
+/* help_gnu.mes - The original message. */
+/* help_gnu.c - C code to write out the original message. */
+/* */
+/* To turn help_gnu.mes into help_gnu.c, give the following command in */
+/* FunnelWeb interactive mode: codify help_gnu.txt help_gnu.c */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "help_gnu.h"
+
+/******************************************************************************/
+
+/* This module contains many many output statements that call an output */
+/* function. To neaten up all these calls, we define a global variable to */
+/* hold a pointer to the function and simple macro to write output using */
+/* the function. */
+LOCVAR void (*pf) P_((char *));
+
+#define WX(STR) (*pf)(STR);(*pf)("\n")
+#define WY(STR) (*pf)(STR)
+
+/******************************************************************************/
+
+EXPORT void hel_gnu (p_outf)
+void (*p_outf) P_((char *));
+{
+ pf=p_outf;
+ WY("\n");
+ WY("FunnelWeb License\n");
+ WY("-----------------\n");
+ WY("FunnelWeb is distributed under the following license.\n");
+ WY("\n");
+ WY("--<Start of GNU License>--\n");
+#include "help_gnu.ctx"
+ WY("--<End of GNU License>--\n");
+ WY("\n");
+ WY("If all that scrolled off your screen too quickly, don't worry. You can\n");
+ WY("capture this message (or any other FunnelWeb output) in a file by\n");
+ WY("specifying the +J option when you invoke FunnelWeb. For example:\n");
+ WY("\n");
+ WY(" fw +hlicense +jresult.txt\n");
+ WY("\n");
+}
+
+/******************************************************************************/
+/* End of HELP_GNU.C */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/help_gnu.ctx b/web/funnelAC/sources/help_gnu.ctx
new file mode 100644
index 0000000000..34af6039b0
--- /dev/null
+++ b/web/funnelAC/sources/help_gnu.ctx
@@ -0,0 +1,339 @@
+ WX(" GNU GENERAL PUBLIC LICENSE");
+ WX(" Version 2, June 1991");
+ WX("");
+ WX(" Copyright (C) 1989, 1991 Free Software Foundation, Inc.");
+ WX(" 675 Mass Ave, Cambridge, MA 02139, USA");
+ WX(" Everyone is permitted to copy and distribute verbatim copies");
+ WX(" of this license document, but changing it is not allowed.");
+ WX("");
+ WX(" Preamble");
+ WX("");
+ WX(" The licenses for most software are designed to take away your");
+ WX("freedom to share and change it. By contrast, the GNU General Public");
+ WX("License is intended to guarantee your freedom to share and change free");
+ WX("software--to make sure the software is free for all its users. This");
+ WX("General Public License applies to most of the Free Software");
+ WX("Foundation's software and to any other program whose authors commit to");
+ WX("using it. (Some other Free Software Foundation software is covered by");
+ WX("the GNU Library General Public License instead.) You can apply it to");
+ WX("your programs, too.");
+ WX("");
+ WX(" When we speak of free software, we are referring to freedom, not");
+ WX("price. Our General Public Licenses are designed to make sure that you");
+ WX("have the freedom to distribute copies of free software (and charge for");
+ WX("this service if you wish), that you receive source code or can get it");
+ WX("if you want it, that you can change the software or use pieces of it");
+ WX("in new free programs; and that you know you can do these things.");
+ WX("");
+ WX(" To protect your rights, we need to make restrictions that forbid");
+ WX("anyone to deny you these rights or to ask you to surrender the rights.");
+ WX("These restrictions translate to certain responsibilities for you if you");
+ WX("distribute copies of the software, or if you modify it.");
+ WX("");
+ WX(" For example, if you distribute copies of such a program, whether");
+ WX("gratis or for a fee, you must give the recipients all the rights that");
+ WX("you have. You must make sure that they, too, receive or can get the");
+ WX("source code. And you must show them these terms so they know their");
+ WX("rights.");
+ WX("");
+ WX(" We protect your rights with two steps: (1) copyright the software, and");
+ WX("(2) offer you this license which gives you legal permission to copy,");
+ WX("distribute and/or modify the software.");
+ WX("");
+ WX(" Also, for each author's protection and ours, we want to make certain");
+ WX("that everyone understands that there is no warranty for this free");
+ WX("software. If the software is modified by someone else and passed on, we");
+ WX("want its recipients to know that what they have is not the original, so");
+ WX("that any problems introduced by others will not reflect on the original");
+ WX("authors' reputations.");
+ WX("");
+ WX(" Finally, any free program is threatened constantly by software");
+ WX("patents. We wish to avoid the danger that redistributors of a free");
+ WX("program will individually obtain patent licenses, in effect making the");
+ WX("program proprietary. To prevent this, we have made it clear that any");
+ WX("patent must be licensed for everyone's free use or not licensed at all.");
+ WX("");
+ WX(" The precise terms and conditions for copying, distribution and");
+ WX("modification follow.");
+ WX("");
+ WX(" GNU GENERAL PUBLIC LICENSE");
+ WX(" TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION");
+ WX("");
+ WX(" 0. This License applies to any program or other work which contains");
+ WX("a notice placed by the copyright holder saying it may be distributed");
+ WX("under the terms of this General Public License. The \"Program\", below,");
+ WX("refers to any such program or work, and a \"work based on the Program\"");
+ WX("means either the Program or any derivative work under copyright law:");
+ WX("that is to say, a work containing the Program or a portion of it,");
+ WX("either verbatim or with modifications and/or translated into another");
+ WX("language. (Hereinafter, translation is included without limitation in");
+ WX("the term \"modification\".) Each licensee is addressed as \"you\".");
+ WX("");
+ WX("Activities other than copying, distribution and modification are not");
+ WX("covered by this License; they are outside its scope. The act of");
+ WX("running the Program is not restricted, and the output from the Program");
+ WX("is covered only if its contents constitute a work based on the");
+ WX("Program (independent of having been made by running the Program).");
+ WX("Whether that is true depends on what the Program does.");
+ WX("");
+ WX(" 1. You may copy and distribute verbatim copies of the Program's");
+ WX("source code as you receive it, in any medium, provided that you");
+ WX("conspicuously and appropriately publish on each copy an appropriate");
+ WX("copyright notice and disclaimer of warranty; keep intact all the");
+ WX("notices that refer to this License and to the absence of any warranty;");
+ WX("and give any other recipients of the Program a copy of this License");
+ WX("along with the Program.");
+ WX("");
+ WX("You may charge a fee for the physical act of transferring a copy, and");
+ WX("you may at your option offer warranty protection in exchange for a fee.");
+ WX("");
+ WX(" 2. You may modify your copy or copies of the Program or any portion");
+ WX("of it, thus forming a work based on the Program, and copy and");
+ WX("distribute such modifications or work under the terms of Section 1");
+ WX("above, provided that you also meet all of these conditions:");
+ WX("");
+ WX(" a) You must cause the modified files to carry prominent notices");
+ WX(" stating that you changed the files and the date of any change.");
+ WX("");
+ WX(" b) You must cause any work that you distribute or publish, that in");
+ WX(" whole or in part contains or is derived from the Program or any");
+ WX(" part thereof, to be licensed as a whole at no charge to all third");
+ WX(" parties under the terms of this License.");
+ WX("");
+ WX(" c) If the modified program normally reads commands interactively");
+ WX(" when run, you must cause it, when started running for such");
+ WX(" interactive use in the most ordinary way, to print or display an");
+ WX(" announcement including an appropriate copyright notice and a");
+ WX(" notice that there is no warranty (or else, saying that you provide");
+ WX(" a warranty) and that users may redistribute the program under");
+ WX(" these conditions, and telling the user how to view a copy of this");
+ WX(" License. (Exception: if the Program itself is interactive but");
+ WX(" does not normally print such an announcement, your work based on");
+ WX(" the Program is not required to print an announcement.)");
+ WX("");
+ WX("These requirements apply to the modified work as a whole. If");
+ WX("identifiable sections of that work are not derived from the Program,");
+ WX("and can be reasonably considered independent and separate works in");
+ WX("themselves, then this License, and its terms, do not apply to those");
+ WX("sections when you distribute them as separate works. But when you");
+ WX("distribute the same sections as part of a whole which is a work based");
+ WX("on the Program, the distribution of the whole must be on the terms of");
+ WX("this License, whose permissions for other licensees extend to the");
+ WX("entire whole, and thus to each and every part regardless of who wrote it.");
+ WX("");
+ WX("Thus, it is not the intent of this section to claim rights or contest");
+ WX("your rights to work written entirely by you; rather, the intent is to");
+ WX("exercise the right to control the distribution of derivative or");
+ WX("collective works based on the Program.");
+ WX("");
+ WX("In addition, mere aggregation of another work not based on the Program");
+ WX("with the Program (or with a work based on the Program) on a volume of");
+ WX("a storage or distribution medium does not bring the other work under");
+ WX("the scope of this License.");
+ WX("");
+ WX(" 3. You may copy and distribute the Program (or a work based on it,");
+ WX("under Section 2) in object code or executable form under the terms of");
+ WX("Sections 1 and 2 above provided that you also do one of the following:");
+ WX("");
+ WX(" a) Accompany it with the complete corresponding machine-readable");
+ WX(" source code, which must be distributed under the terms of Sections");
+ WX(" 1 and 2 above on a medium customarily used for software interchange; or,");
+ WX("");
+ WX(" b) Accompany it with a written offer, valid for at least three");
+ WX(" years, to give any third party, for a charge no more than your");
+ WX(" cost of physically performing source distribution, a complete");
+ WX(" machine-readable copy of the corresponding source code, to be");
+ WX(" distributed under the terms of Sections 1 and 2 above on a medium");
+ WX(" customarily used for software interchange; or,");
+ WX("");
+ WX(" c) Accompany it with the information you received as to the offer");
+ WX(" to distribute corresponding source code. (This alternative is");
+ WX(" allowed only for noncommercial distribution and only if you");
+ WX(" received the program in object code or executable form with such");
+ WX(" an offer, in accord with Subsection b above.)");
+ WX("");
+ WX("The source code for a work means the preferred form of the work for");
+ WX("making modifications to it. For an executable work, complete source");
+ WX("code means all the source code for all modules it contains, plus any");
+ WX("associated interface definition files, plus the scripts used to");
+ WX("control compilation and installation of the executable. However, as a");
+ WX("special exception, the source code distributed need not include");
+ WX("anything that is normally distributed (in either source or binary");
+ WX("form) with the major components (compiler, kernel, and so on) of the");
+ WX("operating system on which the executable runs, unless that component");
+ WX("itself accompanies the executable.");
+ WX("");
+ WX("If distribution of executable or object code is made by offering");
+ WX("access to copy from a designated place, then offering equivalent");
+ WX("access to copy the source code from the same place counts as");
+ WX("distribution of the source code, even though third parties are not");
+ WX("compelled to copy the source along with the object code.");
+ WX("");
+ WX(" 4. You may not copy, modify, sublicense, or distribute the Program");
+ WX("except as expressly provided under this License. Any attempt");
+ WX("otherwise to copy, modify, sublicense or distribute the Program is");
+ WX("void, and will automatically terminate your rights under this License.");
+ WX("However, parties who have received copies, or rights, from you under");
+ WX("this License will not have their licenses terminated so long as such");
+ WX("parties remain in full compliance.");
+ WX("");
+ WX(" 5. You are not required to accept this License, since you have not");
+ WX("signed it. However, nothing else grants you permission to modify or");
+ WX("distribute the Program or its derivative works. These actions are");
+ WX("prohibited by law if you do not accept this License. Therefore, by");
+ WX("modifying or distributing the Program (or any work based on the");
+ WX("Program), you indicate your acceptance of this License to do so, and");
+ WX("all its terms and conditions for copying, distributing or modifying");
+ WX("the Program or works based on it.");
+ WX("");
+ WX(" 6. Each time you redistribute the Program (or any work based on the");
+ WX("Program), the recipient automatically receives a license from the");
+ WX("original licensor to copy, distribute or modify the Program subject to");
+ WX("these terms and conditions. You may not impose any further");
+ WX("restrictions on the recipients' exercise of the rights granted herein.");
+ WX("You are not responsible for enforcing compliance by third parties to");
+ WX("this License.");
+ WX("");
+ WX(" 7. If, as a consequence of a court judgment or allegation of patent");
+ WX("infringement or for any other reason (not limited to patent issues),");
+ WX("conditions are imposed on you (whether by court order, agreement or");
+ WX("otherwise) that contradict the conditions of this License, they do not");
+ WX("excuse you from the conditions of this License. If you cannot");
+ WX("distribute so as to satisfy simultaneously your obligations under this");
+ WX("License and any other pertinent obligations, then as a consequence you");
+ WX("may not distribute the Program at all. For example, if a patent");
+ WX("license would not permit royalty-free redistribution of the Program by");
+ WX("all those who receive copies directly or indirectly through you, then");
+ WX("the only way you could satisfy both it and this License would be to");
+ WX("refrain entirely from distribution of the Program.");
+ WX("");
+ WX("If any portion of this section is held invalid or unenforceable under");
+ WX("any particular circumstance, the balance of the section is intended to");
+ WX("apply and the section as a whole is intended to apply in other");
+ WX("circumstances.");
+ WX("");
+ WX("It is not the purpose of this section to induce you to infringe any");
+ WX("patents or other property right claims or to contest validity of any");
+ WX("such claims; this section has the sole purpose of protecting the");
+ WX("integrity of the free software distribution system, which is");
+ WX("implemented by public license practices. Many people have made");
+ WX("generous contributions to the wide range of software distributed");
+ WX("through that system in reliance on consistent application of that");
+ WX("system; it is up to the author/donor to decide if he or she is willing");
+ WX("to distribute software through any other system and a licensee cannot");
+ WX("impose that choice.");
+ WX("");
+ WX("This section is intended to make thoroughly clear what is believed to");
+ WX("be a consequence of the rest of this License.");
+ WX("");
+ WX(" 8. If the distribution and/or use of the Program is restricted in");
+ WX("certain countries either by patents or by copyrighted interfaces, the");
+ WX("original copyright holder who places the Program under this License");
+ WX("may add an explicit geographical distribution limitation excluding");
+ WX("those countries, so that distribution is permitted only in or among");
+ WX("countries not thus excluded. In such case, this License incorporates");
+ WX("the limitation as if written in the body of this License.");
+ WX("");
+ WX(" 9. The Free Software Foundation may publish revised and/or new versions");
+ WX("of the General Public License from time to time. Such new versions will");
+ WX("be similar in spirit to the present version, but may differ in detail to");
+ WX("address new problems or concerns.");
+ WX("");
+ WX("Each version is given a distinguishing version number. If the Program");
+ WX("specifies a version number of this License which applies to it and \"any");
+ WX("later version\", you have the option of following the terms and conditions");
+ WX("either of that version or of any later version published by the Free");
+ WX("Software Foundation. If the Program does not specify a version number of");
+ WX("this License, you may choose any version ever published by the Free Software");
+ WX("Foundation.");
+ WX("");
+ WX(" 10. If you wish to incorporate parts of the Program into other free");
+ WX("programs whose distribution conditions are different, write to the author");
+ WX("to ask for permission. For software which is copyrighted by the Free");
+ WX("Software Foundation, write to the Free Software Foundation; we sometimes");
+ WX("make exceptions for this. Our decision will be guided by the two goals");
+ WX("of preserving the free status of all derivatives of our free software and");
+ WX("of promoting the sharing and reuse of software generally.");
+ WX("");
+ WX(" NO WARRANTY");
+ WX("");
+ WX(" 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY");
+ WX("FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN");
+ WX("OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES");
+ WX("PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED");
+ WX("OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF");
+ WX("MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS");
+ WX("TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE");
+ WX("PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,");
+ WX("REPAIR OR CORRECTION.");
+ WX("");
+ WX(" 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING");
+ WX("WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR");
+ WX("REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,");
+ WX("INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING");
+ WX("OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED");
+ WX("TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY");
+ WX("YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER");
+ WX("PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE");
+ WX("POSSIBILITY OF SUCH DAMAGES.");
+ WX("");
+ WX(" END OF TERMS AND CONDITIONS");
+ WX("");
+ WX(" Appendix: How to Apply These Terms to Your New Programs");
+ WX("");
+ WX(" If you develop a new program, and you want it to be of the greatest");
+ WX("possible use to the public, the best way to achieve this is to make it");
+ WX("free software which everyone can redistribute and change under these terms.");
+ WX("");
+ WX(" To do so, attach the following notices to the program. It is safest");
+ WX("to attach them to the start of each source file to most effectively");
+ WX("convey the exclusion of warranty; and each file should have at least");
+ WX("the \"copyright\" line and a pointer to where the full notice is found.");
+ WX("");
+ WX(" <one line to give the program's name and a brief idea of what it does.>");
+ WX(" Copyright (C) 19yy <name of author>");
+ WX("");
+ WX(" This program is free software; you can redistribute it and/or modify");
+ WX(" it under the terms of the GNU General Public License as published by");
+ WX(" the Free Software Foundation; either version 2 of the License, or");
+ WX(" (at your option) any later version.");
+ WX("");
+ WX(" This program is distributed in the hope that it will be useful,");
+ WX(" but WITHOUT ANY WARRANTY; without even the implied warranty of");
+ WX(" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the");
+ WX(" GNU General Public License for more details.");
+ WX("");
+ WX(" You should have received a copy of the GNU General Public License");
+ WX(" along with this program; if not, write to the Free Software");
+ WX(" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.");
+ WX("");
+ WX("Also add information on how to contact you by electronic and paper mail.");
+ WX("");
+ WX("If the program is interactive, make it output a short notice like this");
+ WX("when it starts in an interactive mode:");
+ WX("");
+ WX(" Gnomovision version 69, Copyright (C) 19yy name of author");
+ WX(" Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.");
+ WX(" This is free software, and you are welcome to redistribute it");
+ WX(" under certain conditions; type `show c' for details.");
+ WX("");
+ WX("The hypothetical commands `show w' and `show c' should show the appropriate");
+ WX("parts of the General Public License. Of course, the commands you use may");
+ WX("be called something other than `show w' and `show c'; they could even be");
+ WX("mouse-clicks or menu items--whatever suits your program.");
+ WX("");
+ WX("You should also get your employer (if you work as a programmer) or your");
+ WX("school, if any, to sign a \"copyright disclaimer\" for the program, if");
+ WX("necessary. Here is a sample; alter the names:");
+ WX("");
+ WX(" Yoyodyne, Inc., hereby disclaims all copyright interest in the program");
+ WX(" `Gnomovision' (which makes passes at compilers) written by James Hacker.");
+ WX("");
+ WX(" <signature of Ty Coon>, 1 April 1989");
+ WX(" Ty Coon, President of Vice");
+ WX("");
+ WX("This General Public License does not permit incorporating your program into");
+ WX("proprietary programs. If your program is a subroutine library, you may");
+ WX("consider it more useful to permit linking proprietary applications with the");
+ WX("library. If this is what you want to do, use the GNU Library General");
+ WX("Public License instead of this License.");
diff --git a/web/funnelAC/sources/help_gnu.h b/web/funnelAC/sources/help_gnu.h
new file mode 100644
index 0000000000..8844e1463a
--- /dev/null
+++ b/web/funnelAC/sources/help_gnu.h
@@ -0,0 +1,58 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* HELP_GNU.H */
+/******************************************************************************/
+/* */
+/* This module is used solely by the help module, and is really part of the */
+/* help module, but has been separated out because THINK C on the Macintosh */
+/* couldn't cope with more than 32K of code in one module. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+EXPORT void hel_gnu P_((void (*)(char *)));
+/* Writes out the GNU General Public License Version 2 using the specified */
+/* output function. */
+
+/******************************************************************************/
+/* End of HELP_GNU.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/help_gnu.txt b/web/funnelAC/sources/help_gnu.txt
new file mode 100644
index 0000000000..b8cf3a1ab2
--- /dev/null
+++ b/web/funnelAC/sources/help_gnu.txt
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/web/funnelAC/sources/list.c b/web/funnelAC/sources/list.c
new file mode 100644
index 0000000000..f082600186
--- /dev/null
+++ b/web/funnelAC/sources/list.c
@@ -0,0 +1,325 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* LIST.C */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "as.h"
+#include "machin.h"
+#include "memory.h"
+
+/******************************************************************************/
+
+/* In order to catch uninitialized and corrupted lists, the first and last */
+/* fields of legitimate list objects contain magic numbers. The following */
+/* #defines give the values of these numbers. The first thing that each */
+/* function of this package does is to check the two magic number fields of */
+/* the list it has just been passed, and bomb the package if the fields have */
+/* the wrong values. This technique is likely to pick uninitialized lists, */
+/* as well as lists that have been partially overwritten. */
+#define MAGIC_HEAD_VALUE (97673812L)
+#define MAGIC_TAIL_VALUE (49357294L)
+
+/******************************************************************************/
+
+typedef struct node_t_ /* Structure used to compose the list proper. */
+ {
+ struct node_t_ *p_prev; /* Points to adjacent node closer to head. */
+ struct node_t_ *p_next; /* Points to adjacent node closer to tail. */
+ p_void p_data; /* Points to data in heap for this element. */
+ }
+ node_t;
+
+typedef node_t *p_node_t; /* Pointer to node type. */
+
+typedef struct /* Main list object containing all the goodies. */
+ {
+ ulong magic_head; /* Helpful in catching list object corruptions. */
+ p_node_t p_head; /* Points to the head of the list (or NULL). */
+ p_node_t p_tail; /* Points to the tail of the list (or NULL). */
+ p_node_t p_mark; /* Points to the marked element (or NULL). */
+ size_t data_bytes; /* Number of bytes in this list's data elements. */
+ ulong length; /* Number of elements in this list. */
+ ulong magic_tail; /* Helpful in catching list object corruptions. */
+ }
+ ls_t;
+
+typedef ls_t *p_ls_t; /* Main list view type. */
+
+typedef p_void p_lsel_t; /* Escalating pointers to data elements! */
+typedef p_lsel_t *pp_lsel_t;
+
+/* We need the function prototypes from list.h. The #define ensures that the */
+/* abstract exported definition of a list is not visible to us here. */
+#define INLISTC
+#include "list.h"
+
+/******************************************************************************/
+
+LOCAL void ls_check P_((p_ls_t));
+LOCAL void ls_check(p_ls)
+/* Accepts a pointer to a list and performs a series of checks to make sure */
+/* that the list has not been corrupted in some way. */
+/* This function is the sort of function that is normally turned off in */
+/* production versions. However, we are too scared to in FunnelWeb because */
+/* lists are not typesafe and are used throughout the program. */
+p_ls_t p_ls;
+{
+ as_cold(p_ls!=NULL,"ls_check: List pointer is NULL.");
+ as_cold(p_ls->magic_head==MAGIC_HEAD_VALUE,
+ "ls_check: Magic number at head of record is incorrect.");
+ as_cold(p_ls->magic_tail==MAGIC_TAIL_VALUE,
+ "ls_check: Magic number at tail of record is incorrect.");
+}
+
+/******************************************************************************/
+
+EXPORT p_ls_t ls_cre (data_bytes)
+size_t data_bytes;
+{
+ p_ls_t p_ls;
+
+ p_ls=(p_ls_t) mm_temp(sizeof(ls_t));
+ p_ls->magic_head = MAGIC_HEAD_VALUE;
+ p_ls->p_head = NULL;
+ p_ls->p_tail = NULL;
+ p_ls->p_mark = NULL;
+ p_ls->data_bytes = data_bytes;
+ p_ls->length = 0;
+ p_ls->magic_tail = MAGIC_TAIL_VALUE;
+ return p_ls;
+}
+
+/******************************************************************************/
+
+EXPORT void ls_add(p_ls,p_lsel)
+p_ls_t p_ls;
+p_void p_lsel;
+{
+ p_node_t p_node;
+
+ AS_HCODE(ls_check(p_ls);)
+
+ /* Create the list node and the data node hanging off it. Copy the data in. */
+ p_node =(p_node_t) mm_temp(sizeof(node_t));
+ p_node->p_data=(p_void) mm_temp(p_ls->data_bytes);
+ memcpy(p_node->p_data,p_lsel,p_ls->data_bytes);
+
+ /* Attach the new node to the tail of the list. */
+
+ p_node->p_prev=p_ls->p_tail; /* Pointers in the new node itself. */
+ p_node->p_next=NULL;
+
+ if (p_ls->p_head == NULL) /* Headside pointer pointing to new node. */
+ p_ls->p_head=p_node;
+ else
+ p_ls->p_tail->p_next=p_node;
+
+ p_ls->p_tail=p_node; /* Tailside pointer pointing to new node. */
+
+ /* Inc the length. */
+ p_ls->length++;
+}
+
+/******************************************************************************/
+
+EXPORT void ls_lop(p_ls)
+p_ls_t p_ls;
+{
+ /* p_node_t p_targ; ONLY NEEDED IF DEALLOCATING */
+
+ AS_HCODE(ls_check(p_ls);)
+
+ as_cold(p_ls->length>0,"ls_lop: List is empty.");
+
+ /* Make a note of the node being deleted. */
+ /* p_targ=p_ls->p_tail; ONLY NEEDED IF DEALLOCATED. */
+
+ /* If the target node was the only node, stitch up the ends of the list. */
+ if (--p_ls->length==0)
+ {
+ p_ls->p_head=NULL;
+ p_ls->p_tail=NULL;
+ }
+ else
+ { /* Unhook node from tail of list. */
+ p_ls->p_tail = p_ls->p_tail->p_prev;
+ p_ls->p_tail->p_next = NULL;
+ }
+
+ /* The following two commented calls show what we WOULD have to do to */
+ /* deallocate the list node. However, in FunnelWeb, all list items are */
+ /* allocated under the mm package watermark system using mm_temp calls so */
+ /* there is no need to free up the memory here. */
+ /* DEALLOCATE(PV p_targ->p_data); */
+ /* DEALLOCATE(PV p_targ); */
+}
+
+/******************************************************************************/
+
+EXPORT ulong ls_len(p_ls)
+p_ls_t p_ls;
+{
+ AS_HCODE(ls_check(p_ls);)
+ return p_ls->length;
+}
+
+/******************************************************************************/
+
+EXPORT void ls_fir(p_ls)
+p_ls_t p_ls;
+{
+ ls_check(p_ls);
+ p_ls->p_mark=p_ls->p_head;
+}
+
+/******************************************************************************/
+
+EXPORT void ls_nxt(p_ls,pp_lsel)
+p_ls_t p_ls;
+pp_lsel_t pp_lsel;
+{
+ AS_HCODE(ls_check(p_ls);)
+
+ if (p_ls->p_mark==NULL)
+ {*pp_lsel=NULL; return;}
+ *pp_lsel=p_ls->p_mark->p_data;
+ p_ls->p_mark=p_ls->p_mark->p_next;
+}
+
+/******************************************************************************/
+
+EXPORT void ls_loo(p_ls,index,pp_lsel)
+p_ls_t p_ls;
+ulong index;
+pp_lsel_t pp_lsel;
+{
+ p_node_t p;
+ ulong i;
+
+ AS_HCODE(ls_check(p_ls);)
+
+ p=p_ls->p_head;
+ as_cold(p!=NULL,"is_loo: List is empty.");
+ for(i=1;i<index;i++)
+ {
+ p=p->p_next;
+ as_cold(p!=NULL,"is_loo: Index is too high for this list.");
+ }
+ *pp_lsel=p->p_data;
+}
+
+/******************************************************************************/
+
+EXPORT void ls_tai(p_ls,pp_lsel)
+p_ls_t p_ls;
+pp_lsel_t pp_lsel;
+{
+ AS_HCODE(ls_check(p_ls);)
+
+ as_cold(p_ls->p_tail!=NULL,"ls_tai: List is empty.");
+ *pp_lsel=p_ls->p_tail->p_data;
+}
+
+/******************************************************************************/
+
+EXPORT void ls_emp(p_ls)
+p_ls_t p_ls;
+{
+ AS_HCODE(ls_check(p_ls);)
+
+ /* The following loop WOULD be required if we had to deallocate the list */
+ /* elements explicitly. However, as all list elements are allocated using */
+ /* mm_temp, it is possible to claim them later as a block. So here, we just */
+ /* let the list items drift off into the sunset. */
+ /* p_node_t p_curr; */
+ /* p_curr=p_ls->p_head; */
+ /* while (p_curr != NULL) */
+ /* { */
+ /* p_node_t p_targ=p_curr; */
+ /* p_curr=p_curr->p_next; */
+ /* my_free(PV p_targ->p_data); */
+ /* my_free(PV p_targ); */
+ /* } */
+
+ p_ls->p_head=NULL;
+ p_ls->p_tail=NULL;
+ p_ls->p_mark=NULL;
+ p_ls->length=0;
+}
+
+/******************************************************************************/
+
+EXPORT void ls_des(p_ls)
+p_ls_t p_ls;
+{
+ ls_check(p_ls);
+
+ ls_emp(p_ls);
+ p_ls->magic_head=0; /* Zap the magic numbers in case memory is reused. */
+ p_ls->magic_tail=0;
+
+ /* The following call WOULD be required if it wasn't for the MM watermark */
+ /* system of memory allocation. */
+ /* my_free(PV p_ls); */
+}
+
+/******************************************************************************/
+
+EXPORT p_void ls_mar (p_ls)
+p_ls_t p_ls;
+{
+ AS_HCODE(ls_check(p_ls);)
+ return PV p_ls->p_mark;
+}
+
+/******************************************************************************/
+
+EXPORT void ls_set(p_ls,p_m)
+p_ls_t p_ls;
+p_void p_m;
+{
+ AS_HCODE(ls_check(p_ls);)
+ p_ls->p_mark=(p_node_t) p_m;
+}
+
+/******************************************************************************/
+/* End of LIST.C */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/list.h b/web/funnelAC/sources/list.h
new file mode 100644
index 0000000000..f7cadf90a7
--- /dev/null
+++ b/web/funnelAC/sources/list.h
@@ -0,0 +1,207 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* LIST.H */
+/******************************************************************************/
+/* */
+/* Introduction */
+/* ------------ */
+/* This list package (list.h and list.c) implements a list abstraction. */
+/* */
+/* Facts about Lists */
+/* ----------------- */
+/* - A LIST stores zero or more LIST ELEMENTS. */
+/* - The user decides the type of element to be stored in each list. */
+/* - Each list stores only one type of list element; lists are homogeneous. */
+/* - Lists store copies of elements rather than pointers to elements. */
+/* - Each list can hold from zero to about 2^31 elements. */
+/* - Each list has a HEAD end and a TAIL end. */
+/* - Elements can be appended and deleted only at the tail of the list. */
+/* - The elements of a list can be read sequentially from head to tail. */
+/* - A MARKER stores the current position in the list for sequential reading. */
+/* - Upon list creation, the marker is positioned at the tail of the list. */
+/* - In a list of n elements, elements are numbered from 1 to n. */
+/* - Element 1 is at the head of the list. Element n is at the tail. */
+/* - The identifier "ls" is used as an abbreviation for "list". */
+/* - The identifier "el" is used as an abbreviation for "element". */
+/* - Longer names are desirable, but shorter ones have been used so as to */
+/* enhance the portability of the package. */
+/* - IMPORTANT: Lists get all their memory using mm_temp calls. */
+/* */
+/* How To Use This List Package */
+/* ---------------------------- */
+/* 1. Include this .H file in your program file. */
+/* 2. Identify the type of elements to be placed in the list. */
+/* 3. Define a variable of type p_ls as a view to a list. */
+/* 4. Use the ls_* functions to perform the desired operations. */
+/* Start with a call to ls_cre and (optionally) end with a call to ls_des. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_LIST
+#define DONE_LIST
+
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+/* Users manipulate lists through pointers to lists (p_ls_t). The following */
+/* declaration serves the list user of the package while hiding the */
+/* implementation details (which appear in a similar declaration in list.c). */
+/* The #ifndef stops list.c from seeing these public declarations. */
+#ifndef INLISTC
+typedef struct {word NEVER_USE_THIS_FIELD_UQJTKC;} ls_yqwx; /* Don't use! */
+typedef ls_yqwx *p_ls_t;
+typedef p_void p_lsel_t;
+typedef p_lsel_t *pp_lsel_t;
+#endif
+
+/******************************************************************************/
+/* */
+/* General Notes About These Functions */
+/* ----------------------------------- */
+/* - All lists and elements are passed by pointer. Whether a parameter is */
+/* read or written is determined by it's function's description. */
+/* - Each function (except ls_cre) accepts a single pointer to a list and */
+/* each function's description is assumed to be referring to the list. */
+/* - "Raising an error" means calling the external function "error" to */
+/* write out a message and bomb the program. */
+/* - You must create a list using ls_cre before performing any operations */
+/* upon it. A list function will usually raise an error if it is */
+/* handed a pointer that does not point to a properly CREated list. */
+/* */
+/* WARNING: This package copies values into its internal data structures */
+/* (through ls_add), but returns only POINTERS to elements when asked to */
+/* retrieve them. These pointers are valid only so long as the element */
+/* that they point to remains in the list. If the element is deleted somehow, */
+/* the pointer points to garbage and becomes dangerous. */
+/* So, if you have been handed a pointer to an element in a list (ls_nxt, */
+/* ls_loo), do not subsequently delete the element (ls_lop, ls_emp, ls_des) */
+/* and then attempt to access the element through the pointer. */
+/* One sure way to avoid the problem is always to use the pointer handed back */
+/* by ls_nxt or ls_loo to copy the element immediately. */
+
+/* The Functions */
+/* ------------- */
+EXPORT p_ls_t ls_cre P_((size_t));
+/* CREate. Creates a new list and returns a pointer to the new list. The user */
+/* must specify in the parameter the size of elements that are to be stored */
+/* in the list. Specify the size of elements in bytes (usually using sizeof). */
+/* The sequential reading marker is set to position n+1=1=tail of the list. */
+
+EXPORT void ls_add P_((p_ls_t,p_lsel_t));
+/* ADD. Adds a new element onto the tail of the list (at position n+1). */
+/* The user must supply in the second parameter a pointer to the element to */
+/* be added. ls_add takes a copy of the element (it knows from the earlier */
+/* call to ls_cre how many bytes to copy) and stores the copy in its own */
+/* internal data structures. */
+
+EXPORT void ls_lop P_((p_ls_t));
+/* LOP. Removes (lops) element n from the tail of the list. */
+/* Raises an error if the list is empty. */
+
+EXPORT ulong ls_len P_((p_ls_t));
+/* LENgth. Returns the number of elements in the list (n). */
+
+EXPORT void ls_fir P_((p_ls_t));
+/* FIRst. Sets the sequential reading marker to element 1. */
+/* If the list is empty (n=0) the marker is placed at the tail of the list */
+/* and subsequent calls to ls_add will leave it there until the next call to */
+/* ls_fir. */
+
+EXPORT void ls_nxt P_((p_ls_t,pp_lsel_t));
+/* NeXT. Returns the list element under the marker and advances the marker */
+/* one position towards the tail of the list. */
+/* The method of returning the list element is a little messy. The user */
+/* supplies a pointer to a pointer in the second parameter, and the function */
+/* writes the address of the element in the list into the pointer. */
+/* If the marker is at position n+1 upon entry to ls_nxt, the marker position */
+/* doesn't change and NULL is written to the argument pointer. */
+
+EXPORT void ls_loo P_((p_ls_t,ulong,pp_lsel_t));
+/* LOOkup. Returns (using the same mechanism as ls_nxt) the k'th element of */
+/* the specified list where k is the second (ulong) parameter and the first */
+/* element (at the head of the list) is numbered number one (1). */
+/* Raises an error if the index k is out of the range [1,n]. */
+
+EXPORT void ls_tai P_((p_ls_t,pp_lsel_t));
+/* Lookup TAIl. Returns (using the same mechanism as ls_nxt) the tail element */
+/* of the specified list. */
+/* Raises an error if the list is empty. */
+
+EXPORT void ls_emp P_((p_ls_t));
+/* EMPty. Empties the specified list, deallocating all the space used by the */
+/* list elements. Upon completion, the list will be empty and the list marker */
+/* will be positioned at the tail of the list. */
+
+EXPORT void ls_des P_((p_ls_t));
+/* DEStroy. Destroys a list, destroying all its elements and deallocating all */
+/* the memory used by the list. */
+
+/* Marker Functions */
+/* ---------------- */
+/* The following two functions ls_mar and ls_set were hacked in to this list */
+/* package when it was discovered that the tangler sometimes needs to run */
+/* more than one context down a list at the same time. The two new functions */
+/* allow the list package user to save and restore the current mark. */
+/* These functions are not tightly controlled and so care must be taken in */
+/* their use. */
+
+EXPORT p_void ls_mar P_((p_ls_t));
+/* Returns a representation of the current list marker. */
+
+EXPORT void ls_set P_((p_ls_t,p_void));
+/* Sets the position of the marker to an earlier saved position. */
+/* Calls to this function should satisfy the following conditions: */
+/* 1. The marker argument (p_void) must be the result of an earlier call */
+/* to ls_mar with the same list as an argument. */
+/* 2. No part of the list should have been modified in the interim. In */
+/* particular, this means that no calls to ls_add, ls_lop, ls_emp or */
+/* ls_des can be made between linked calls to ls_mar and ls_set. */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of LIST.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/lister.c b/web/funnelAC/sources/lister.c
new file mode 100644
index 0000000000..1f86e9ef4a
--- /dev/null
+++ b/web/funnelAC/sources/lister.c
@@ -0,0 +1,368 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* LISTER.C */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "as.h"
+#include "data.h"
+#include "list.h"
+#include "lister.h"
+#include "machin.h"
+#include "misc.h"
+#include "table.h"
+#include "writfile.h"
+
+/******************************************************************************/
+
+#define LISTWIDTH 80 /* Nominal width of listing file. Can be wider. */
+#define INDENTQ 3 /* Indentation quantum for include files. */
+#define MESSMAXCH 200 /* Maximum number of characters in a message. */
+#define CTXINF 100 /* Special value that signals infinite context. */
+#define MAXLINES 10000 /* Maximum number of lines in input file. */
+
+/******************************************************************************/
+
+/* The following #defines and typedef define an enumerated type for message */
+/* kinds. There are four kinds of message, and we need a type for storing */
+/* this information. mess_k_t stands for message_kind_type. */
+/* We use #defines instead of enums as enums are not portable enough. */
+#define MESS_MES 1
+#define MESS_WAR 2
+#define MESS_ERR 3
+#define MESS_SEV 4
+typedef ubyte mess_k_t;
+
+/* We wish to store messages in a table with message positions as keys. */
+/* However, the table package will not tolerate duplicate keys. To solve this */
+/* problem, we create a new type 'unqpos_t' (unique position type) which has */
+/* not only a position but a serial number as well. */
+typedef struct
+ {
+ ps_t up_pos;
+ ulong up_serial;
+ } unqpos_t;
+
+/* The following structure stores a single message. As we are storing COPIES */
+/* of the messages, we impose a maximum limit (MESSMAXCH) to their length. */
+typedef struct
+ {
+ mess_k_t ms_kind;
+ char ms_text[MESSMAXCH+1];
+ } mess_t;
+
+/******************************************************************************/
+
+LOCVAR p_tb_t p_msgtab; /* The message table storing diagnostics. */
+LOCVAR ulong serial_next; /* Serial number for numbering messages. */
+
+/******************************************************************************/
+
+LOCAL int cmpuqpos P_((unqpos_t *,unqpos_t *));
+LOCAL int cmpuqpos(p1,p2)
+/* Compare two unique positions for the table package and returns [-1,0,1]. */
+unqpos_t *p1;
+unqpos_t *p2;
+{
+ long diff;
+ ubyte i;
+
+ for (i=1; i<=3; i++)
+ {
+ switch (i)
+ {
+ case 1: diff= p1->up_pos.ps_line - p2->up_pos.ps_line; break;
+ case 2: diff= p1->up_pos.ps_column - p2->up_pos.ps_column; break;
+ case 3: diff= p1->up_serial - p2->up_serial; break;
+ default: as_bomb("cmpuqpos: Case defaulted.");
+ }
+ if (diff<0)
+ return -1;
+ else
+ if (diff>0)
+ return 1;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+
+/* Converts a value of message kind type into a representative string. */
+/* This routine unused at present.
+LOCAL char *mess_let P_((mess_k_t));
+LOCAL char *mess_let (mess_k)
+mess_k_t mess_k;
+{
+ switch (mess_k)
+ {
+ case MESS_MES : return "M";
+ case MESS_WAR : return "W";
+ case MESS_ERR : return "E";
+ case MESS_SEV : return "S";
+ default: as_bomb("mess_let: Case defaulted.");
+ }
+ as_bomb("mess_let: Switch dropped out.");
+ return "Failure";
+}
+*/
+
+/******************************************************************************/
+
+#define DUPMAX 200
+
+LOCAL char *dup P_((int,uword));
+LOCAL char *dup(ch,count)
+/* Returns a pointer to a STAVAR string containing 'count' copies of 'ch'. */
+/* Count must be in the range [0,DUPMAX]. The pointer returned always points */
+/* to the same address which is a 'STAVAR' inside this function. */
+int ch;
+uword count;
+{
+ STAVAR char buffer[DUPMAX+1];
+
+ as_cold(count<DUPMAX,"lister.dup: count>=DUPMAX");
+ /* The IF in the following is just in case 'memset' is brain damaged. */
+ if (count>0) memset(&buffer[0],ch,(size_t) count);
+ buffer[count]=EOS;
+ return &buffer[0];
+}
+
+/******************************************************************************/
+
+LOCAL void mess_wri P_((p_wf_t,mess_t *,uword,uword));
+LOCAL void mess_wri(p_wf,p_mess,indent,column)
+/* Writes message p_mess to file p_wf indented by INDENTQ*indent+column. */
+p_wf_t p_wf;
+mess_t *p_mess;
+uword indent;
+uword column;
+{
+ switch (p_mess->ms_kind)
+ {
+ case MESS_MES : wf_wr(p_wf," "); break;
+ case MESS_WAR : wf_wr(p_wf," Warning"); break;
+ case MESS_ERR : wf_wr(p_wf," Error"); break;
+ case MESS_SEV : wf_wr(p_wf," Severe"); break;
+ default: as_bomb("mess_let: Case defaulted.");
+ }
+ wf_wr(p_wf,"|.");
+ wf_wr(p_wf,dup('.',indent*INDENTQ));
+ wf_wr(p_wf,dup('.',column-1));
+ wf_wr(p_wf,"^");
+ wf_wr(p_wf,&p_mess->ms_text[0]);
+ wf_wr(p_wf,"\n");
+}
+
+/******************************************************************************/
+
+LOCAL void line_wri P_((p_wf_t,ln_t *));
+LOCAL void line_wri(p_wf,p_line)
+/* Writes the given line to the given output stream. */
+p_wf_t p_wf;
+ln_t *p_line;
+{
+ char buffer[100];
+
+ /* The last line of the line list is the EOF marker line and to indicate */
+ /* that it is not really part of the input file, we omit it's line number. */
+ if (p_line->ln_global==ls_len(line_list))
+ /*" 12345 12345| "*/
+ sprintf(buffer," | ");
+ else
+ sprintf(buffer," %5lu %5lu| ",
+ (unsigned long) p_line->ln_global,
+ (unsigned long) p_line->ln_local);
+ wf_wr(p_wf,buffer);
+ wf_blk(p_wf,p_line->ln_body.sc_first,(size_t)
+ (p_line->ln_body.sc_last-p_line->ln_body.sc_first+1));
+}
+
+/******************************************************************************/
+
+LOCAL void add_mess P_((ps_t *,mess_k_t,char *));
+LOCAL void add_mess(p_pos,messkind,p_string)
+/* Creates a message record and places the message information in the */
+/* argument into the record. Inserts the record into the message table. */
+ps_t *p_pos;
+mess_k_t messkind;
+char *p_string;
+{
+ mess_t tempmess;
+ unqpos_t unqpos;
+
+ tempmess.ms_kind=messkind;
+ as_cold(strlen(p_string)<=MESSMAXCH,
+ "lister.add_mess: Parameter message is too long.");
+ strcpy(tempmess.ms_text,p_string);
+ ASSIGN(unqpos.up_pos,*p_pos);
+ unqpos.up_serial=serial_next++;
+ tb_ins(p_msgtab,PV &unqpos,PV &tempmess);
+}
+
+/******************************************************************************/
+
+EXPORT void lr_ini P_((void))
+{
+ /* Create a brand new empty message table. */
+ p_msgtab=tb_cre(sizeof(unqpos_t),sizeof(mess_t),(p_kycm_t) cmpuqpos);
+
+ /* Start the serial numbers at zero again. */
+ serial_next=0;
+}
+
+/******************************************************************************/
+
+EXPORT void lr_mes(p_pos,s)
+ps_t *p_pos;
+char *s;
+{
+ add_mess(p_pos,MESS_MES,s);
+}
+
+/******************************************************************************/
+
+EXPORT void lr_war(p_pos,s)
+ps_t *p_pos;
+char *s;
+{
+ add_mess(p_pos,MESS_WAR,s);
+ num_war++;
+}
+
+/******************************************************************************/
+
+EXPORT void lr_err(p_pos,s)
+ps_t *p_pos;
+char *s;
+{
+ add_mess(p_pos,MESS_ERR,s);
+ num_err++;
+}
+
+/******************************************************************************/
+
+EXPORT void lr_sev(p_pos,s)
+ps_t *p_pos;
+char *s;
+{
+ add_mess(p_pos,MESS_SEV,s);
+ num_sev++;
+}
+
+/******************************************************************************/
+
+EXPORT void lr_gen(p_wf,ctx)
+p_wf_t p_wf;
+uword ctx;
+{
+ unqpos_t next_pos; /* Position of next message. */
+ mess_t next_mes; /* Content of next message. */
+ long prev_no; /* Global line number of previous message. */
+ long next_no; /* Global line number of next message. */
+ bool ingap; /* Controls issuance of gap markers in the listing. */
+ long context=ctx; /* Signed version of the parameter. */
+
+ /* A context of CTXINF signals an infinite context. */
+ if (context==CTXINF) context=MAXLINES;
+
+ /* Write listing header. */
+ wf_wr(p_wf,"\nGlobal Local| Input File\n");
+ wf_wr(p_wf,dup('-',12));wf_wr(p_wf,"+");
+ wf_wr(p_wf,dup('-',LISTWIDTH-13));wf_wr(p_wf,"\n");
+
+ /* Reset the line list and message table for reading. */
+ ls_fir(line_list);
+ tb_fir(p_msgtab);
+
+ /* Prime the variables ingap, prev_no, next_no, next_pos, and next_mes. */
+ ingap=FALSE; prev_no = -(context+1);
+ if (tb_rea(p_msgtab,PV &next_pos,PV &next_mes))
+ next_no=next_pos.up_pos.ps_line;
+ else
+ next_no=MAXLINES+context+1;
+
+ while (TRUE)
+ {/* Process a single line per iteration. */
+ ln_t *p_line;
+
+ /* Grab the next line from the line list. */
+ ls_nxt(line_list,PPV &p_line);
+ if (p_line==NULL) break;
+
+ /* List the line if it is within context range of prev or next message. */
+ if ((((long) p_line->ln_global) <= prev_no+context) ||
+ (((long) p_line->ln_global) >= next_no-context))
+ {line_wri(p_wf,p_line);ingap=FALSE;}
+ else
+ if (!ingap)
+ {wf_wr(p_wf,".................\n");ingap=TRUE;}
+
+ /* Issue any messages that are about this line. */
+ while (next_no == p_line->ln_global)
+ {
+ /* Write the current message. */
+ mess_wri(p_wf,&next_mes,(uword) 0,
+ (uword) next_pos.up_pos.ps_column);
+
+ /* Read the next message from the table. */
+ prev_no=next_no;
+ if (tb_rea(p_msgtab,PV &next_pos,PV &next_mes))
+ next_no=next_pos.up_pos.ps_line;
+ else
+ next_no=MAXLINES+context+1;
+ }
+ } /* End while */
+
+ /* Make sure that we have read to the end of the message table. */
+ {bool result;
+ result=tb_rea(p_msgtab,PV &next_pos,PV &next_mes);
+ as_cold(!result,
+ "lr_gen: Messages remaining in message table after listing.");
+ }
+
+ /* Write listing trailer. */
+ wf_wr(p_wf,dup('-',12));wf_wr(p_wf,"+");
+ wf_wr(p_wf,dup('-',LISTWIDTH-13));wf_wr(p_wf,"\n");
+ wf_wl(p_wf,"");
+}
+
+/******************************************************************************/
+/* End of LISTER.C */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/lister.h b/web/funnelAC/sources/lister.h
new file mode 100644
index 0000000000..829acce655
--- /dev/null
+++ b/web/funnelAC/sources/lister.h
@@ -0,0 +1,75 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* LISTER.H */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "data.h"
+
+/******************************************************************************/
+
+EXPORT void lr_ini P_((void));
+/* Initialize the lister. Calling this function destroys all the lister */
+/* package's old internal data structures and sets them to a well-defined */
+/* initial state (empty) and prepares the lister for the incoming messages. */
+/* This function may be called at any time and many times. */
+
+EXPORT void lr_mes P_((ps_t *,char *));
+EXPORT void lr_war P_((ps_t *,char *));
+EXPORT void lr_err P_((ps_t *,char *));
+EXPORT void lr_sev P_((ps_t *,char *));
+/* The functions above allow the user to record four different kinds of */
+/* messages and to specify exactly where in the listing each message is to */
+/* appear. */
+
+EXPORT void lr_gen P_((p_wf_t,uword));
+/* Merges the global structure line_list with the message table stored by the */
+/* lister package and writes the resultant listing to the p_wf_t stream. */
+/* The second parameter is the number of lines of context around each */
+/* diagnostic. The lister does not write the entire input file out. It only */
+/* writes input lines near a diagnostic. The context argument specifies the */
+/* number of lines that should be written around each diagnostic. */
+/* Note: A context of 100 is special and means that no lines should be */
+/* omitted in between diagnostics. */
+
+/******************************************************************************/
+/* End of LISTER.H */
+/******************************************************************************/
+
diff --git a/web/funnelAC/sources/machin.c b/web/funnelAC/sources/machin.c
new file mode 100644
index 0000000000..6058433121
--- /dev/null
+++ b/web/funnelAC/sources/machin.c
@@ -0,0 +1,345 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* MACHIN.C */
+/******************************************************************************/
+/* */
+/* WARNING: DO NOT ADD ANY PROGRAM DEPENDENT DEFINITIONS. */
+/* */
+/* This file contains machine-dependent, program-independent stuff that */
+/* implements the functionality promised in MACHIN.H. */
+/* */
+/* Note: As usual, the full definitions of functions in the .H file are not */
+/* repeated here. */
+/* */
+/******************************************************************************/
+
+#include <time.h>
+#include "style.h"
+
+#include "as.h"
+#include "machin.h"
+
+/* The Macintosh's doesn't have a command language, and so we have to prompt */
+/* for a command line. This requires a special package. */
+#if MAC
+#include <console.h>
+#endif
+
+/* Under VMS, we need RMS to get at stuff to do with filenames. */
+#if VMS
+#include RMS
+#endif
+
+/******************************************************************************/
+/* LOCAL FUNCTIONS */
+/******************************************************************************/
+
+LOCAL void mconcat P_((int,char **,char *));
+LOCAL void mconcat(argc,argv,result)
+/* Given argc and argv, as passed to main(), this function appends all the */
+/* arguments together (separated by spaces) into the string "result". */
+/* This function assists in reconstructing the command line. */
+/* This function is actually portable, so you shouldn't have to change it. */
+/* Note: "mconcat" stands for Multiple CONCATenation. */
+int argc;
+char **argv;
+char *result;
+{
+ uword i;
+ strcpy(&result[0],argv[0]);
+ for (i=1;i<argc;i++)
+ {
+ strcat(&result[0]," " );
+ strcat(&result[0],argv[i]);
+ }
+}
+
+/******************************************************************************/
+
+#if MAC | SUN | PC
+LOCAL void fn_split P_((p_fn_t,p_fn_t,p_fn_t,p_fn_t));
+LOCAL void fn_split(p_fn,p_path,p_name,p_ext)
+/* Accepts a filename in p_fn and writes the path, name, and extension */
+/* components of the filename to the strings p_path, p_name, and p_ext. */
+p_fn_t p_fn;
+p_fn_t p_path;
+p_fn_t p_name;
+p_fn_t p_ext;
+{
+ char *p,*q;
+
+ /* Make sure that the input filename is a sensible length. */
+ as_cold(strlen(p_fn)<=FILENAME_MAX,"fn_split: Filename is too long.");
+
+ /* Extract the path from the input string by searching for the last */
+ /* occurrance of the special character used for directories. */
+
+ /* Find the last directory/filename separator. */
+ p=strrchr(p_fn,FN_DELIM);
+ if (p==NULL)
+ {strcpy(p_path,""); p=p_fn;}
+ else
+ {
+ memcpy(p_path,p_fn,(size_t) (p-p_fn+1));
+ p_path[(size_t) (p-p_fn+1)]=EOS;
+ p++;
+ }
+
+ /* Assert: p now points to the first character of the name field. */
+
+ /* Now locate the file extension. */
+ q=strrchr(p_fn,'.');
+ if (q==NULL)
+ {strcpy(p_ext,""); q = &p_fn[strlen(p_fn)];}
+ else
+ {strcpy(p_ext,q);}
+
+ /* Assert: q now points to the '.' preceding the extension field. */
+
+ /* Now anything between p and q must be the filename proper. */
+ for (;p<q;p++)
+ *p_name++ = *p;
+ *p_name=EOS;
+}
+#endif
+
+/******************************************************************************/
+
+#if MAC | SUN | PC
+LOCAL void fn_join P_((p_fn_t,p_fn_t,p_fn_t,p_fn_t));
+LOCAL void fn_join(p_fn,p_path,p_name,p_ext)
+/* This function sets p_fn to the empty string and then successively appends */
+/* p_path, p_name, and p_ext. Before doing this, it checks to make sure that */
+/* there will be enough room and bombs the program if there isn't. */
+p_fn_t p_fn;
+p_fn_t p_path;
+p_fn_t p_name;
+p_fn_t p_ext;
+{
+ as_cold(strlen(p_path)+strlen(p_name)+strlen(p_ext) <= FILENAME_MAX,
+ "fn_join: Constructed filename is too long.");
+ strcpy(p_fn,p_path);
+ strcat(p_fn,p_name);
+ strcat(p_fn,p_ext);
+}
+#endif
+
+/******************************************************************************/
+/* EXPORTED FUNCTIONS */
+/******************************************************************************/
+
+#if MAC | SUN | PC
+EXPORT void fn_ins(p_cur,p_add)
+p_fn_t p_cur;
+p_fn_t p_add;
+{
+ fn_t cur_path, add_path;
+ fn_t cur_name, add_name;
+ fn_t cur_extn, add_extn;
+
+ /* Split the argument file names into their component parts. */
+ fn_split(p_cur,cur_path,cur_name,cur_extn);
+ fn_split(p_add,add_path,add_name,add_extn);
+
+ /* Perform the inheriting on a field by field basis. */
+ if (strlen(add_path) > 0) strcpy(cur_path,add_path);
+ if (strlen(add_name) > 0) strcpy(cur_name,add_name);
+ if (strlen(add_extn) > 0) strcpy(cur_extn,add_extn);
+
+ /* Put the fields back together again to yield the final result. */
+ fn_join(p_cur,cur_path,cur_name,cur_extn);
+}
+#endif
+
+#if VMS
+EXPORT void fn_ins(p_cur,p_add)
+/* This VMS version of fn_ins was written with the assistance of: */
+/* Jeremy Begg (jeremy@vsm.com.au) of VSM Software Services. Thanks! */
+/* The VMS version is messy because VMS has highly structured filenames and */
+/* highly ingrained rituals for manipulating them. */
+p_fn_t p_cur;
+p_fn_t p_add;
+{
+ struct FAB cur_fab; /* FAB for SYS$PARSE */
+ struct NAM cur_nam; /* NAM for SYS$PARSE */
+ fn_t expanded; /* Result of SYS$PARSE */
+ long rms_status; /* Status of SYS$PARSE */
+
+ /*
+ printf("\nTRACE: Call of fn_ins(...).\n");
+ printf(" Current spec = \"%s\".\n",p_cur);
+ printf(" Add spec = \"%s\".\n",p_add);
+ */
+
+ /* Initialize the FAB and NAM block to something sensible. */
+ cur_fab = cc$rms_fab;
+ cur_nam = cc$rms_nam;
+
+ /* (fna,fns) is address and size of input file spec in FAB block. */
+ cur_fab.fab$l_fna = p_add;
+ cur_fab.fab$b_fns = strlen(p_add);
+
+ /* (dna,dns) is address and size of default file spec in FAB block. */
+ cur_fab.fab$l_dna = p_cur;
+ cur_fab.fab$b_dns = strlen(p_cur);
+
+ /* Connect the NAM block to the FAB block. */
+ cur_fab.fab$l_nam = &cur_nam;
+
+ /* Point the NAM block's target name fields to the target namechar array. */
+ cur_nam.nam$l_esa = &expanded;
+ cur_nam.nam$b_ess = FILENAME_MAX; /* Reserve last char for NULL terminator */
+
+ /* PWD => put the password from a DECnet Access Control String in the filespec
+ * SYNCHK => check syntax only, don't search for the file on disk
+ */
+ cur_nam.nam$b_nop = NAM$M_PWD + NAM$M_SYNCHK;
+
+ /* Perform the parse. */
+ rms_status = sys$parse(&cur_fab);
+ if (rms_status & 1)
+ {
+ expanded[cur_nam.nam$b_esl]=EOS; /* Terminate VMS string. */
+ strcpy(p_cur,expanded);
+ }
+ else
+ {
+ printf("Note: RMS parse failed. Could be a syntax error, could be a bug!\n");
+ }
+
+ /* TRACE printf(" Result spec = \"%s\".",p_cur); */
+}
+#endif
+
+/******************************************************************************/
+
+EXPORT void getcline(argc,argv,p_comline)
+/* Given, argc and argv, writes a command line string in p_comline. */
+/* See machin.h for a thorough definition of this function. */
+int argc;
+char **argv;
+char *p_comline;
+{
+ int argc2;
+ char **argv2;
+
+#if MAC
+ /* On the Macintosh there is no command language and therefore no command */
+ /* line. Therefore we cannot trust the argc and argv handed to us by main() */
+ /* and have to obtain a command line from other sources. */
+ /* The "ccommand" function comes from <console.h> of the THINK C libraries. */
+ argc2=ccommand(&argv2);
+#endif
+
+/* The other systems work like Unix. */
+#if SUN | VMS | PC
+argc2=argc;
+argv2=argv;
+#endif
+
+ /* The command line is currently in pieces. Reassemble it. That's all! */
+ mconcat(argc2,argv2,p_comline);
+}
+
+/******************************************************************************/
+
+EXPORT float tim_real()
+{
+ STAVAR bool init=FALSE;
+ STAVAR time_t base;
+
+ /* The first time this routine is called, we establish a base real time */
+ /* from which real time differences are calculated. There are two reasons */
+ /* for doing this. The first is that difftime seems to be the only way to */
+ /* get ANSI C to hand over a calibrated arithmetic type holding the real */
+ /* time. The second is that we don't want to have to deal with large */
+ /* absolute times anyway. */
+ if (!init)
+ {
+ /* Returns -1 if the time is not available (ANSI 7.12.2.4). */
+ base=time(NULL);
+ init=TRUE;
+ }
+
+ /* Return the elapsed time since the base time. */
+
+/* Macintosh, VMS, and PC have difftime. */
+#if MAC | VMS | PC
+ if (base == -1)
+ return 0.0;
+ else
+ return (float) difftime(time(NULL),base);
+#endif
+
+/* Sun does not have difftime. */
+#if SUN
+ return 0.0;
+#endif
+
+/* The timing functions are only used to generate performance statistics and */
+/* are not critical to FunnelWeb. There is not much harm in returning 0.0. */
+}
+
+/******************************************************************************/
+
+EXPORT float tim_cpu()
+{
+ clock_t t=clock();
+
+/* Make sure that we have a definition for CLOCKS_PER_SEC. */
+#ifndef CLOCKS_PER_SEC
+#ifdef CLK_TCK
+#define CLOCKS_PER_SEC CLK_TCK
+#else
+/* Assume one million ticks per second. */
+#define CLOCKS_PER_SEC (1000000L)
+#endif
+#endif
+
+ /* The clock() function returns -1 if the CPU time is not available. */
+ /* Otherwise it returns the number of "clocks" since power-up. */
+ if (t == -1)
+ return 0.0;
+ else
+ return ((float) t) / ((float) CLOCKS_PER_SEC);
+}
+
+/******************************************************************************/
+/* End of MACHIN.C */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/machin.h b/web/funnelAC/sources/machin.h
new file mode 100644
index 0000000000..67253aa110
--- /dev/null
+++ b/web/funnelAC/sources/machin.h
@@ -0,0 +1,300 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* MACHIN.H */
+/******************************************************************************/
+/* */
+/* WARNING: DO NOT ADD ANY PROGRAM DEPENDENT DEFINITIONS. */
+/* */
+/* This module (machin.h and machin.c) contains definitions and objects */
+/* whose values depends directly on the compilation and execution */
+/* environment, but are otherwise independent from any particular computer */
+/* program. */
+/* */
+/* The only difference between the purpose of this module and the "environ" */
+/* module is that the "environ" module contains the "essentials" whereas this */
+/* module contains extra machine specific definitions and objects that will */
+/* not be required by most user modules. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_FWMACHIN
+#define DONE_FWMACHIN
+
+/******************************************************************************/
+
+#include <time.h>
+#include "style.h"
+
+/******************************************************************************/
+
+/* Machine Alignment Constraints */
+/* ----------------------------- */
+/* Some machines require that objects of particular lengths be aligned in */
+/* memory. For example, the 68000 will trap any attempt to access a word */
+/* (16 bits or an int in THINK C) at an odd address. It is important that C */
+/* programs that deal with memory at a low level be aware of such */
+/* constraints. As the constraints are always at a power of two, we defined */
+/* ALIGN_POWER to be the minimum power of two at which it is both safe and */
+/* efficient to operate. */
+
+/* The Macintosh requires words and longs to be aligned on word boundaries. */
+/* The PC is not fussy about alignment, but operates more efficiently at word */
+/* boundaries. */
+#if MAC | PC
+#define ALIGN_POWER (1L)
+#endif
+
+/* The Sun requires objects to be aligned on longword boundaries (=2^2). */
+/* The VMS VAX doesn't care about alignment, but operates more efficiently on */
+/* longword boundaries. */
+#if SUN | VMS
+#define ALIGN_POWER (2L)
+#endif
+
+/******************************************************************************/
+
+/* Filenames */
+/* --------- */
+/* The length and structure of filenames varies from machine to machine. The */
+/* differences addressed here are: */
+/* 1) The character used to separate directory specs from filenames. */
+/* 2) The maximum length of a filename. */
+
+/* FN_DELIM must contain the character that separates directory specs from */
+/* filenames. Notice that in the VMS case, it is "]", not "." */
+
+#if MAC
+#define FN_DELIM ':'
+#endif
+
+#if SUN
+#define FN_DELIM '/'
+#endif
+
+#if VAX
+#define FN_DELIM ']'
+#endif
+
+#if PC
+#define FN_DELIM '\\'
+#endif
+
+/* The rest of this section shouldn't have to be changed, unless you */
+/* encounter a funny with your system's definition of FILENAME_MAX. */
+
+/* FILENAME_MAX tells the maximum number of characters allowed in a filename */
+/* on the target machine. This symbol is supposed to be defined in stdio.h */
+/* (ANSI S7.9.1) so we don't want to override that. However, if it isn't, we */
+/* need to define a safe default length. */
+#ifndef FILENAME_MAX
+#define FILENAME_MAX 300
+#endif
+
+/* Some VAX compilers define FILENAME_MAX to be 39, which is the maximum */
+/* length of the NAME part of a VMS filename. This is not appropriate, so we */
+/* override it. */
+#if VMS
+#undef FILENAME_MAX
+#define FILENAME_MAX 255 /* Should really be NAM$C_MAXRSS */
+#endif
+
+/* Now we can use the constant to define a filename type. */
+/* Note: For a while I defined "typedef fn_t *p_fn_t". However, this is a */
+/* pointer to an array rather than (char *) and it caused no end of problems. */
+typedef char fn_t[FILENAME_MAX+1];
+typedef char *p_fn_t;
+
+/******************************************************************************/
+
+/* Command Lines */
+/* ------------- */
+/* The maximum length of command line varies from machine to machine and we */
+/* define symbols to reflect this. The reason why we don't just set this to a */
+/* high value and forget about it is that FunnelWeb sometimes places */
+/* command line variables on the stack, and some machines (e.g. MAC under */
+/* THINK-C don't provide much stack space. So we have to minimize this */
+/* variable on those machines. */
+
+/* We choose a small maximum command line on the Macintosh so as to avoid */
+/* chewing up stack space when command lines have to be pushed. */
+#if MAC
+#define COMLINE_MAX 300
+#endif
+
+/* On the Sun, 1024 is a normal command line and 2048 is safe. */
+#if SUN
+#define COMLINE_MAX 2048
+#endif
+
+/* On the VMS, 1024 is usually adequate. */
+#if VMS
+#define COMLINE_MAX 1024
+#endif
+
+/* On a PC, we assume this is enough. */
+#if PC
+#define COMLINE_MAX 300
+#endif
+
+/* Make sure that the value is not too low. */
+/* The value 300 is guaranteed by the command interpreter. */
+#if COMLINE_MAX < 300
+ #error COMLINE_MAX must be at least 300.
+#endif
+
+/* Now define a type for command lines. */
+/* Note: For a while I defined "typedef cl_t *p_cl_t". However, this is a */
+/* pointer to an array rather than (char *) and it caused no end of problems. */
+typedef char cl_t[COMLINE_MAX+1];
+typedef char *p_cl_t;
+
+/******************************************************************************/
+
+/* Line Termination */
+/* ---------------- */
+
+/* FunnelWeb has special-case code to make reading input files faster on */
+/* machines where the format of text files corresponds to the internal C */
+/* text stream model. The UNIX_EOL #define should be activated if and only */
+/* the host environment has text files consisting of a stream of bytes with */
+/* a single LF (ASCII,decimal-10,hex-0A) character being used to terminate */
+/* each line, and no special character to indicate end of file. */
+/* This is the same format as is used in the Unix operating system. */
+/* If you are in doubt about this, play it safe and define your environment */
+/* to be non-Unix, as non-Unix will work on ALL systems (including Unix). */
+
+#if MAC | VMS | PC
+/* These systems do NOT use Unix EOLs. */
+#define UNIX_EOL 0
+#endif
+
+#if SUN
+/* This should really be 1 on a SUN, but I haven't got around to debugging */
+/* FunnelWeb with UNIX_EOL==1. */
+#define UNIX_EOL 0
+#endif
+
+/******************************************************************************/
+
+/* MIssing Prototypes */
+/* ---------------- */
+/* Compilers that are fussy about prototypes sometimes complain about calls */
+/* to the standard libraries. These declarations solve this problem. */
+
+#if SUN
+int fclose P_((FILE *stream));
+int fputs P_((const char *s, FILE *stream));
+int fputc P_((int c, FILE *stream));
+int fflush P_((FILE *stream));
+int remove P_((const char *filename));
+int rename P_((const char *oldname, const char *newname));
+int toupper P_((int));
+int sscanf P_(());
+int fprintf P_(());
+int _filbuf P_(());
+void *memcpy P_((void *s1, void *s2, size_t n));
+void *memset P_((void *s, int c, size_t n));
+int memcmp P_((void *s1, void *s2, size_t n));
+size_t fread P_((void *ptr, size_t size, size_t nobj, FILE *stream));
+size_t fwrite P_((const void *ptr, size_t size, size_t nobj, FILE *stream));
+clock_t clock P_((void));
+time_t time P_((time_t *tp));
+int printf P_(());
+#endif
+
+/******************************************************************************/
+
+EXPORT void fn_ins P_((p_fn_t,char *));
+/* - The name stands for FileName INSert. */
+/* - The first argument must be a pointer to an object of type fn_t */
+/* (containing an ordinary C character string). */
+/* - The second argument must be a pointer to an ordinary C character string. */
+/* - Both arguments must contain a full, partial, or empty filename spec. */
+/* - We will refer to the arguments as f1 and f2. */
+/* - If there is a syntax error in either spec, fn_ins does nothing. */
+/* - Otherwise, it: */
+/* 1. Analyses the two filename specifications into filename field . */
+/* 2. Replaces each field in f1 by the corresponding field in f2, but */
+/* only if the corresponding field in f2 is non-empty. */
+/* 3. Optionally [concession to VMS] it may then replace blank fields */
+/* in the resulting file spec in f1 by fields from the current */
+/* global "default" directory spec. */
+/* The structure and fields of filenames will vary from machine to machine */
+/* and so this is not important. However, every implementation must structure */
+/* the filename so that it will at least RECOGNISE a file extension */
+/* (e.g. ".lis") field. */
+
+/******************************************************************************/
+
+EXPORT void getcline P_((int,char **,char *));
+/* Operating system environments vary a lot in the way in which their command */
+/* language interfaces are set up. The approach taken in FunnelWeb is to */
+/* define a "standard" Unix-like command line syntax and then insist that */
+/* other environments deliver such a command line as a single string. */
+/* This function getcline must extract such a standard command line from its */
+/* environment and copy it as a single string of not more than COMLINE_MAX */
+/* characters into its third argument. A description of the "standard" */
+/* command line can be found in the options package. */
+/* The first argument is given to getcline and is argc from main(). */
+/* The second argument is given to getcline and is argv from main(). */
+/* These two arguments are given in case getcline needs them to assemble the */
+/* command line (as opposed to calling e.g. VMS CLI routines). */
+/* The third argument is the string into which the result should be placed. */
+
+/******************************************************************************/
+
+EXPORT float tim_real P_((void));
+/* Returns the number of seconds between the present and an unspecified, but */
+/* statically fixed time in the past. */
+/* Returns 0.0 if this information is unavailable */
+
+EXPORT float tim_cpu P_((void));
+/* Returns the number of CPU seconds consumed between the present and an */
+/* unspecified, but statically fixed time in the past. */
+/* Returns 0.0 if this information is unavailable */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of MACHIN.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/main.c b/web/funnelAC/sources/main.c
new file mode 100644
index 0000000000..f5793cef8c
--- /dev/null
+++ b/web/funnelAC/sources/main.c
@@ -0,0 +1,109 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* MAIN.C */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "as.h"
+#include "command.h"
+#include "data.h"
+#include "machin.h"
+#include "memory.h"
+
+/******************************************************************************/
+
+/* The following variables should really be local to main. However, some */
+/* compilers have a problem with this and so it has been declared here. */
+LOCVAR char *p_comline;
+LOCVAR ulong sum_all;
+
+/******************************************************************************/
+
+LOCAL void minimain P_((int,char **));
+LOCAL void minimain(argc,argv)
+/* Some compilers generate buggy code for main() and so this minimain */
+/* function has been created to take the heat off main(). */
+int argc;
+char **argv;
+{
+ /* The principal concern of this main() function is to execute FunnelWeb and */
+ /* to ensure that the correct return status is returned to the OS. So it */
+ /* seems appropriate to zero all the global diagnostic counters here. */
+ sum_fat=sum_sev=sum_err=sum_war=0;
+
+ /* Some compilers place a low limit on the total amount of statics. So we */
+ /* have to allocate space for a command line. */
+ p_comline=(char *) mm_perm((size_t) COMLINE_FWMAX+1);
+
+ /* Obtaining the command line is highly machine specific and so it has been */
+ /* delegated to a function in the non-portable "machin". Just in case argc */
+ /* and argv are to be used, we hand them in too. The result of all this is a */
+ /* standard FunnelWeb command line string in the variable 'comline'. */
+ getcline(argc,argv,p_comline);
+
+ /* Execute the command line. */
+ command(p_comline);
+
+ /* Exit to the operating system with an appropriate status code. */
+ sum_all=sum_war+sum_err+sum_sev+sum_fat;
+ if (sum_all>0)
+ exit(EXIT_FAILURE);
+ else
+ exit(EXIT_SUCCESS);
+}
+
+/******************************************************************************/
+
+int main(argc,argv)
+int argc;
+char *argv[];
+{
+ /* We don't put anything into the function main() because some compilers */
+ /* generate incorrect code for main, especially with local variables. */
+ minimain(argc,argv);
+
+ /* Keep GCC warnings happy. */
+ as_bomb("Main program dropped through.");
+ return 0;
+}
+
+/******************************************************************************/
+/* End of MAIN.C */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/mapper.c b/web/funnelAC/sources/mapper.c
new file mode 100644
index 0000000000..9dbeb027df
--- /dev/null
+++ b/web/funnelAC/sources/mapper.c
@@ -0,0 +1,375 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* MAPPER.C */
+/******************************************************************************/
+
+#include <limits.h>
+#include "style.h"
+
+#include "as.h"
+#include "machin.h"
+#include "mapper.h"
+#include "memory.h"
+
+/******************************************************************************/
+
+/* When we allocate a block of memory for a mapped file, we have to allocate */
+/* a little more than the official length of the file. Here are some reasons: */
+/* */
+/* - We may wish to append an EOF character later on in the program. */
+/* - fgets, when requested to fetch n characters, fetches n characters and */
+/* then puts an EOS on the end of them. */
+/* - It is conceivable that fgets will insert a "\n" at the end of the */
+/* block if it doesn't see a "\n" just before the end of file. */
+/* */
+/* For all these reasons, we allocate a little more memory than we need. How */
+/* much more is determined by BLK_FUDGE which is set to be on the safe side. */
+#define BLK_FUDGE (20)
+
+/* The following fudge is useful for avoiding the limits of types. */
+#define LIM_FUDGE (10)
+
+/* On PCs, size_t is 16 bits and malloc cannot allocate contiguous chunks of */
+/* memory of more than about 64K. This really stuffs up FunnelWeb's capacity */
+/* map in files of length greater than 64K. I didn't think of this problem */
+/* when I designed FunnelWeb because I was thinking of the VOLUME of memory */
+/* available nowadays, rather than its organization on small computers. */
+/* Anyway, this problem should really be fixed by allowing files to be read */
+/* in in segments. Perhaps the mapper should hand over a linked list of */
+/* chunks rather than a single chunk. Unfortunately, I don't have the time to */
+/* do this now, so users of the PC version of FunnelWeb will have to be */
+/* content with an (approx) 64K limit to input files. This isn't as bad as it */
+/* sounds, as large input files can be split using the include facility. */
+/* 63K is chosen instead of 64K so as to be paranoid. */
+#define PCFILEMX (63L*1024L)
+
+/******************************************************************************/
+/* */
+/* Error Strings */
+/* ------------- */
+/* Routines in this package return pointers to error strings. These pointers */
+/* are subsequently bandied about by other packages. Therefore, they must be */
+/* pointers to constant strings. The trick of returning a pointer to a static */
+/* character array containing a specific sprintf message will backfire here */
+/* if there is an error opening more than one input file. Using mm_* to */
+/* create space for each error string would work though. */
+/* STOP PRESS: Now that the lister copies error messages, there may no longer */
+/* be a problem here. */
+/* */
+/******************************************************************************/
+
+/* Finding The Length of a File */
+/* ---------------------------- */
+/* We have to be able to find out the length of a file before reading it in */
+/* because, in this version of FunnelWeb, the entire file must be read into */
+/* one contiguous block of memory. */
+/* */
+/* As it turns out, finding the length of a file in portable C turns out to */
+/* be a very hard problem. Here are some possible solutions: */
+/* */
+/* 1. Read the entire file in and see how long it is. */
+/* 2. Use fseek to move to the end of the file and then use ftell. */
+/* 3. Use the Unix 'stat' call. */
+/* */
+/* Of these, only the first is portable. The second alternative is */
+/* non-portable because some environments do not support the SEEK_END symbol */
+/* required to perform a seek to the end of file. */
+/* Alternatives to needing the length are as follows: */
+/* */
+/* 4. Read the file/allocate memory in 64K blocks. */
+/* 5. Read the file in 64K blocks and then copy them to a contiguous one. */
+/* */
+/* Perhaps options 4 or 5 could be implemented later. However, right now I */
+/* haven't got the time to do anything except strive for portability, so */
+/* option 1 it is. */
+
+LOCAL char *file_len P_((char *,ulong *));
+LOCAL char *file_len (p_name,p_length)
+/* Given a filename (in 'p_name'), returns the length of the binary image of */
+/* the file in *p_length. Returns NULL upon success or a pointer to a string */
+/* describing an error upon failure. The length is measured in bytes. */
+char *p_name;
+ulong *p_length;
+{
+ FILE *infile;
+ STAVAR char *p_buf = NULL;
+
+/* The length of the buffer handed to fgets is non-critical. However, it */
+/* mustn't be bigger than 15 bits, as we are passing it as an int to fgets. */
+#define LENBUFLEN (1024L)
+#if LENBUFLEN > 30000L
+ #error "mapper.c: LENBUFLEN must be less than 15 bits."
+#endif
+
+ /* Allocate the buffer if it has not already been allocated. */
+ if (p_buf == NULL)
+ p_buf=mm_perm((size_t) LENBUFLEN);
+
+ /* Open for TEXT reading. Earlier, I tried this using a binary read, but */
+ /* I had problems with this on the VAX (I forget what the problems were) and */
+ /* so I have switched back to a text read which is slower, but more reliable.*/
+ infile=fopen(p_name,"r");
+ if (infile == FOPEN_F)
+ return "Error fopen()ing input file (to determine its length).";
+
+ /* Start with a zero length. */
+ *p_length=0;
+
+ /* Read the file as text and count the number of bytes it contains. */
+ while (!feof(infile))
+ {
+ /* Set the buffer to the empty string so it is valid even if fgets fails. */
+ p_buf[0]=EOS;
+
+ /* Read in a whole lot of bytes. */
+ fgets(p_buf,LENBUFLEN,infile);
+
+ /* If there is an error, abort. */
+ if (ferror(infile))
+ {
+ fclose(infile);
+ return "Error fgets()ing input file (as part of determining its length).";
+ }
+
+ /* Count the bytes that we have got. If EOF occurred above AND no bytes */
+ /* were read, the EOS we planted earlier saves us. */
+ (*p_length)+=strlen(p_buf);
+ }
+
+ if (fclose(infile) == FCLOSE_F)
+ return "Error fclose()ing input file (as part of determining its length).";
+
+ return NULL;
+}
+
+/******************************************************************************/
+
+#if PC & UNIX_EOL
+ #error Attempt to use unix_map function on a PC!
+#endif
+
+#if UNIX_EOL
+LOCAL char *unix_map P_((char *,char **,ulong *));
+LOCAL char *unix_map(p_name,pp_mem,p_length)
+/* If we know that the enclosing environment represents text files in UNIX */
+/* form, then there is no need to process the file on the way in. All we need */
+/* to do is map it directly into memory. This will be very fast. */
+char *p_name;
+char **pp_mem;
+ulong *p_length;
+{
+ ulong file_length; /* Number of bytes in the target input file. */
+ char *p_err; /* Temporary to store pointer to error message. */
+ FILE *infile; /* The file variable for the input file we are reading. */
+ ulong num_bytes; /* Number of bytes actually read in (may be different). */
+ char *p_bytes; /* Pointer to the memory block where all the action is. */
+
+ /* Obtain the length of the file we are about to map in. */
+ p_err=file_len(p_name,&file_length);
+ if (p_err != NULL)
+ return p_err;
+
+ /* Allocate memory to hold the mapped file. */
+ /* Note: The memory allocation package bombs if there is no more memory. */
+ p_bytes=(char *) mm_temp((size_t) file_length+BLK_FUDGE);
+
+ /* Open the file in BINARY mode. */
+ infile=fopen(p_name,"rb");
+ if (infile==FOPEN_F)
+ return "Error fopen()ing the input file (binary open).";
+
+ /* Read in the file and complain if we haven't read in enough bytes. */
+ num_bytes=fread(p_bytes,(size_t) 1L,(size_t) file_length,infile);
+ if (num_bytes != file_length)
+ return "Error fread()ing the input file.";
+
+ if (fclose(infile) == FCLOSE_F)
+ return "Error fclose()ing the input file.";
+
+ /* Success. We got through the IO calls. Now fill in the blanks and go home. */
+ *pp_mem =p_bytes;
+ *p_length =num_bytes;
+ return NULL;
+}
+#endif
+
+/******************************************************************************/
+
+#if !UNIX_EOL
+LOCAL char *stan_map P_((char *,char **,ulong *));
+LOCAL char *stan_map(p_name,pp_mem,p_length)
+/* Maps in a file using refined text stream IO calls. */
+char *p_name;
+char **pp_mem;
+ulong *p_length;
+{
+ ulong file_length; /* Number of bytes in the target input file. */
+ char *p_err; /* Temporary to store pointer to error message. */
+ FILE *infile; /* The file variable for the input file we are reading. */
+ ulong num_bytes; /* Number of bytes actually read in (may be different). */
+ char *p_bytes; /* Pointer to the memory block where all the action is. */
+ char *p_curr; /* Pointer to current position in memory block. */
+ long bytes_left; /* Number of bytes still left to read. */
+
+ /* Obtain the length of the file we are about to map in. */
+ p_err=file_len(p_name,&file_length);
+ if (p_err != NULL)
+ return p_err;
+
+ /* Complain on the PC if the file is too big to fit in one 64K segment. */
+#if PC
+ if (file_length+BLK_FUDGE > PCFILEMX)
+ return
+ "Error: Input file too big for PC FunnelWeb. Split using include files.";
+#endif
+
+ /* TRACE printf("MAPPER: LENGTH OF INPUT FILE=%lu\n",file_length); */
+
+ /* Allocate memory to hold the mapped file. */
+ /* Note: The memory allocation package bombs if there is no more memory. */
+ /* Note: As Unix stream format (the format to which we are converting) uses */
+ /* just one byte to mark the end of file, it seems highly unlikely */
+ /* that the file read in will be longer than the binary image. */
+ p_bytes=(char *) mm_temp((size_t) file_length+BLK_FUDGE);
+
+ /* If the file is of zero length, we already know its contents! */
+ /* This is probably not strictly necessary, but why pressure the code below? */
+ if (file_length==0)
+ {
+ *pp_mem = p_bytes;
+ *p_length = 0;
+ return NULL;
+ }
+
+ /* Open the file afresh in TEXT mode for portable reading. */
+ infile=fopen(p_name,"r");
+ if (infile==FOPEN_F)
+ return "Error fopen()ing input file (for reading).";
+
+ /* Read in as much of the file as we can without actually overflowing the */
+ /* buffer. If the file finished before the buffer, things have probably gone */
+ /* OK. If the buffer finishes before the file, we have a problem. */
+ /* Note: bytes_left = file_length+1 because in the following loop, we might */
+ /* read exactly up to the EOF and then be unable to actually trigger the EOF */
+ /* condition without another read. So we add one on to allow this extra read */
+ /* to take place. I don't know if this is necessary, but I certainly can't */
+ /* find anything in all my C books that will tell me. Anyway, it doesn't */
+ /* matter because we fudged in a few extra bytes earlier. */
+
+ p_curr = p_bytes; /* p_curr runs through the memory. */
+ bytes_left = file_length+1; /* Bytes left in memory allocated to hold file. */
+
+ while (!feof(infile))
+ {
+ int bytes_try;
+ int bytes_read;
+
+ /* Try to read as much as we possibly can, but not more than the integer */
+ /* limit (which can be as low as 15 bits). */
+ bytes_try = bytes_left >= ((ulong) (INT_MAX-LIM_FUDGE)) ?
+ (int) INT_MAX-LIM_FUDGE : (int) bytes_left;
+
+ /* Plan an EOS to cover the EOF case. */
+ *p_curr=EOS;
+
+ /* Attempt to read bytes_try bytes. +1 is because fgets reads n-1 bytes. */
+ fgets(p_curr,bytes_try+1,infile);
+ if (ferror(infile))
+ {
+ fclose(infile);
+ return "Error fgets()ing the input file.";
+ }
+
+ /* fgets doesn't return a length so we have to hobble behind with strlen. */
+ /* It's still probably better than using lots of fgetc calls. */
+ /* If we hit EOF and no bytes were read, the EOS we planted saves us. */
+ bytes_read = strlen(p_curr);
+ p_curr += bytes_read;
+ bytes_left -= bytes_read;
+
+ /* If we have run out of bytes in our allocated memory zone, then the */
+ /* file is longer than the length reported earlier. This is a bad thing. */
+ as_cold(bytes_left >=0,
+ "stan_map: Text representation was longer than binary rep.");
+ }
+
+ num_bytes=(file_length+1)-bytes_left; /* See earlier to undserstand +1. */
+
+ /* Note: We can't get fussy here and check the read in length with the */
+ /* official length, as the read-in length is the text representation which */
+ /* is allowed to be shorter than the physical (binary) length of the file. */
+
+ if (fclose(infile) == FCLOSE_F)
+ return "Error fclose()ing input file.";
+
+ /* Success. We got through the IO calls. Now fill in the blanks and go home. */
+ *pp_mem = p_bytes;
+ *p_length = num_bytes;
+ return NULL;
+}
+#endif
+
+/******************************************************************************/
+
+EXPORT char *map_file(p_name,pp_mem,p_length)
+char *p_name;
+char **pp_mem;
+ulong *p_length;
+{
+ /* We choose one of two mapper routines depending on where the operating */
+ /* system represents text files using EOL (\n) as end of line markers. */
+ /* The UNIX_EOL symbol is defined in the machin.h file. */
+ /* Note: I thought of using sprintf to test to see what "\n" translated into */
+ /* so I wouldn't need the UNIXEOL symbol. However, unlike printf (which it */
+ /* is supposed to be like), sprintf does not translate "\n" into its outside */
+ /* form. The only other alternative is writing a short text file and reading */
+ /* it back in binary - an action that would probably take longer than */
+ /* reading the original file to be read using fgetc()! */
+
+#if UNIX_EOL
+ return unix_map(p_name,pp_mem,p_length);
+#else
+ return stan_map(p_name,pp_mem,p_length);
+#endif
+}
+
+/******************************************************************************/
+/* End of MAPPER.C */
+/******************************************************************************/
+
diff --git a/web/funnelAC/sources/mapper.h b/web/funnelAC/sources/mapper.h
new file mode 100644
index 0000000000..6210206df6
--- /dev/null
+++ b/web/funnelAC/sources/mapper.h
@@ -0,0 +1,69 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* MAPPER.H */
+/******************************************************************************/
+/* */
+/* The mapper is the first of FunnelWeb's four front end processors: (mapper, */
+/* scanner, parser, analyser). The sole task of the mapper is, given the */
+/* name of a file, to create an image of that file in memory. This approach */
+/* is not wasteful of memory at all because FunnelWeb requires random access */
+/* to each input file at all times anyway so it can scramble the text around. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+EXPORT char *map_file P_((char *,char **,ulong *));
+/* Allocates a block of memory and places a Unix text stream representation */
+/* (with EOL marking end of line and no character marking end of file) of the */
+/* file 'p_name' in the block of memory. Returns a pointer to the address and */
+/* len of the file in the mem block in the parameters (pp_mem and p_length). */
+/* Returns NULL upon success or a pointer to an error message string upon */
+/* failure. Note: Parameters are: p_name, pp_mem, p_length. */
+/* Note: Allocates enough memory so that there is guaranteed to be at least */
+/* two extra bytes of spare memory at the end of the mapped file. The */
+/* scanner uses this space to put EOL and EOF characters. */
+/* Note: The mapper grabs its memory using mm_temp, so it can be recycled */
+/* as part of a call to mm_zapt. */
+
+/******************************************************************************/
+/* End of MAPPER.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/memory.c b/web/funnelAC/sources/memory.c
new file mode 100644
index 0000000000..8595ce4fd4
--- /dev/null
+++ b/web/funnelAC/sources/memory.c
@@ -0,0 +1,338 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* MEMORY.C */
+/******************************************************************************/
+/* */
+/* Implementation Overview */
+/* ----------------------- */
+/* One of the tasks of this Memory Management (MM) package is to keep track */
+/* of the memory that it has allocated so that it can all be deallocated */
+/* later, in one go. To do this, the package keeps a linked list whose */
+/* elements describe the blocks allocated. Two linked lists are kept, one for */
+/* temporary blocks and one for permanent blocks. Only the list for the */
+/* temporary blocks is used for deallocation. Permanent blocks are arranged */
+/* in a list so that the code for temporary blocks is also applicable. */
+/* */
+/* In order to avoid many calls to malloc() for small blocks of memory */
+/* (legend has it that some implementations of malloc() are very slow in this */
+/* case), the MM package keeps a spare temporary and permanent block of */
+/* length MM_BLOCK from which it allocates small blocks. Small is defined as */
+/* <=MM_BLOCK/16. A separate malloc call is made for "Large" blocks greater */
+/* than MM_BLOCK bytes. "Large" blocks less than MM_BLOCK bytes may or may */
+/* not be allocated from a buffer block, depending on how much space is */
+/* available. See the code for the full details. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "as.h"
+#include "machin.h"
+#include "memory.h"
+
+/******************************************************************************/
+
+/* The environ.h file contains a definition for ALIGN_POWER which is the */
+/* exponent of the power of two corresponding to the machine's alignment */
+/* requirements. The following two constants convert that constant to more */
+/* useful forms. These definitions should never need to be changed. */
+#define ALIGN_SIZE (1L<<ALIGN_POWER)
+#define ALIGN_MASK (ALIGN_SIZE-1)
+
+/* Because standard malloc() can be slow on some systems for large numbers of */
+/* calls requesting small blocks of memory, FunnelWeb's memory management */
+/* package MM_* allocates memory in sizeable blocks and then allocates */
+/* smaller blocks from these big blocks without reference to malloc(). The */
+/* following #define tells the MM package how big the sizeable allocated */
+/* blocks should be. The rule is then: if the requested block is greater than */
+/* MM_BLOCK/16, allocate it directly using malloc(), otherwise peel off some */
+/* memory from the latest sizeable block allocated. */
+/* In practice, MM_BLOCK should be chosen to be about 1/10 to 1/20 of the */
+/* memory available to FunnelWeb. The disadvantage of making it big is that */
+/* when memory is tight, MM will be unable to allocate a full block and about */
+/* half a block of memory will be unusable. The disadvantage of making it too */
+/* small is that the linked lists tracking memory allocations will grow long */
+/* and it will take a long time to free up memory between invocations of */
+/* FunnelWeb proper. The value is not critical. A value of 31K should work */
+/* well on most systems. 31K is chosen instead of 32K just to be on the safe */
+/* side of 16 bits (so who's paranoid?). */
+#define MM_BLOCK (31L*1024L)
+
+/* This definition provides the definition of the size of a "big" block; that */
+/* is, one that should possibly be treated differently from the others. */
+/* The rule we use is that a big block is 1/16 of the standard block size. */
+/* This results in a maximum memory wastage of 1/16 or about 7%. */
+#define MM_BIG (MM_BLOCK >> 4)
+
+/* Magic numbers help us to detect corruptions. */
+#define MAGIC_HEAD (83716343L)
+#define MAGIC_TAIL (11172363L)
+
+/* Set MEMTRACE to TRUE to trace all memory operations. */
+#define MEMTRACE FALSE
+
+/******************************************************************************/
+
+/* The following structures define a type for the linked lists that keep */
+/* track of the allocated blocks. */
+typedef struct mm_t_
+ {
+ ulong mm_mhead; /* Magic number protecting beginning of record. */
+ ubyte_ *mm_pblok; /* Pointer to the allocated block. */
+ ubyte_ *mm_pfree; /* Pointer to next free byte in block (ALIGNED). */
+ ulong mm_nfree; /* Number of unused bytes available in the block. */
+ struct mm_t_ *mm_pnext; /* Pointer to the header for the next block. */
+ ulong mm_mtail; /* Magic number protecting end of record. */
+ } mm_t;
+
+typedef mm_t *p_mm_t; /* Handy to have a pointer type too. */
+
+/* The following two local variables point to the head of the temporary and */
+/* permanent block lists. The first block in each list is that list's buffer. */
+LOCVAR p_mm_t p_perm = NULL;
+LOCVAR p_mm_t p_temp = NULL;
+
+/******************************************************************************/
+
+LOCAL void mm_check P_((p_mm_t));
+LOCAL void mm_check(p_mm)
+/* Checks the magic numbers in the specified block header object. */
+p_mm_t p_mm;
+{
+ as_cold(p_mm!=NULL,"mm_check: Null pointer.");
+ as_cold(p_mm->mm_mhead==MAGIC_HEAD,"mm_check: Corrupted header.");
+ as_cold(p_mm->mm_mtail==MAGIC_TAIL,"mm_check: Corrupted trailer.");
+}
+
+/******************************************************************************/
+
+LOCAL void mm_align P_((p_mm_t));
+LOCAL void mm_align(p_mm)
+/* Some machines are very fussy about the memory alignment of allocated */
+/* objects. To solve this problem, the mm_pfree pointer is always kept at an */
+/* "aligned" address. This function accepts a pointer to the header of a */
+/* block whose mm_pfree pointer is possibly unaligned and consumes bytes */
+/* until mm_pfree is aligned. */
+p_mm_t p_mm;
+{
+ ubyte bump;
+ ubyte consume;
+
+ mm_check(p_mm);
+
+ /* Work out how many bytes are sticking out over the alignment boundary. */
+ bump = ((ulong) p_mm->mm_pfree) & ALIGN_MASK;
+
+ /* Return if the block is already aligned. */
+ if (bump==0) return;
+
+ /* Otherwise work out how many bytes we have to consume to become realigned. */
+ consume=ALIGN_SIZE-bump;
+
+ /* If there are not enough bytes left in the block to allow the free pointer */
+ /* to be aligned, then simply set the available bytes to zero and return. It */
+ /* doesn't matter if we don't achieve alignment in this case as if */
+ /* mm_nfree==0, nothing can ever be allocated at the misaligned address. */
+ if (consume>p_mm->mm_nfree) {p_mm->mm_nfree=0; return;}
+
+ /* Consume the bytes required to align the free pointer. */
+ p_mm->mm_pfree += consume;
+ p_mm->mm_nfree -= consume;
+
+ /* Check that we have properly aligned the free pointer. */
+ as_cold((((ulong) p_mm->mm_pfree) & ALIGN_MASK)==0,
+ "mm_align: Failed to align.");
+}
+
+/******************************************************************************/
+
+LOCAL p_mm_t mm_newblk P_((size_t));
+LOCAL p_mm_t mm_newblk(blk_len)
+/* Creates a new block containing (after alignment) at least blk_len bytes. */
+/* Returns a pointer to the header for the block. */
+size_t blk_len;
+{
+ p_mm_t p_mm;
+ ubyte_ *p_bl;
+
+ /* Allocate the header and the block itself. Because we are guaranteeing */
+ /* that the resultant block will have at least blk_len bytes free, we have */
+ /* to take into account alignment and add in ALIGN_SIZE when requesting mem. */
+ p_mm=(p_mm_t ) malloc((size_t) sizeof(mm_t));
+ p_bl=(ubyte_ *) malloc((size_t) (blk_len+ALIGN_SIZE));
+ if (p_mm==NULL || p_bl==NULL)
+ {
+ fprintf(stderr,"mm_newblk: Out of memory!\n");
+ fprintf(stderr,"FunnelWeb doesn't cope well when it runs out of memory.\n");
+ fprintf(stderr,"It falls in a heap just as it is about to now.\n");
+ as_bomb("Stand by for an ungraceful termination!");
+ }
+
+ /* Fill in the fields of the block header. */
+ p_mm->mm_mhead = MAGIC_HEAD;
+ p_mm->mm_pblok = p_bl;
+ p_mm->mm_pfree = p_bl;
+ p_mm->mm_nfree = blk_len+ALIGN_SIZE;
+ p_mm->mm_pnext = NULL;
+ p_mm->mm_mtail = MAGIC_TAIL;
+
+ /* Align the free pointer in the header block. */
+ mm_align(p_mm);
+
+ /* Return a pointer to the header block we created. */
+ return p_mm;
+}
+
+/******************************************************************************/
+
+LOCAL p_void mm_alloc P_((p_mm_t *,size_t));
+LOCAL p_void mm_alloc(pp_mm,bytes)
+/* 'pp_mm' must be a pointer to either p_perm or p_temp. */
+/* 'bytes' is the number of bytes required. */
+/* Allocates the required memory and returns an aligned pointer to it. */
+/* Bombs the program if the memory is not available. */
+p_mm_t *pp_mm;
+size_t bytes;
+{
+ p_mm_t p_from; /* Pointer to header for block from which we finally alloc.*/
+ ubyte_ *p_result; /* The result pointer returned to the caller. */
+
+ /* If the list is empty, create a "buffer block" and put it in the list. */
+ if (*pp_mm==NULL) *pp_mm=mm_newblk((size_t) MM_BLOCK);
+
+ /* If there is room in the current buffer block, we can allocate directly. */
+ /* Note that we may be allocating a "big" block here, but as long as it fits */
+ /* into the free space of the current buffer block, we don't care. */
+ if ((*pp_mm)->mm_nfree >= bytes) {p_from = *pp_mm; goto dole_out;}
+
+ /* At this point we know that there is not enough space in the current */
+ /* buffer block. This could mean that we have an extra big allocation on our */
+ /* hands in which case, we should malloc up a block specially for this */
+ /* request. It could also mean that we are running out of space in our */
+ /* buffer block in which case a new one must be allocated. */
+ if (bytes >= MM_BIG)
+ {
+ /* If the request is BIG, allocate a special block for it and insert the */
+ /* block in the block list just after the buffer block, leaving the */
+ /* buffer block the first in the block list. */
+ p_mm_t p_tmp=mm_newblk(bytes);
+ p_tmp->mm_pnext=(*pp_mm)->mm_pnext;
+ (*pp_mm)->mm_pnext=p_tmp;
+ p_from=p_tmp;
+ }
+ else
+ {
+ /* If the request is not big, our buffer block is probably too empty and */
+ /* so it is time to create a new one. Allocate a new buffer block and */
+ /* make it the new head of this block list. Note that by giving up on the */
+ /* previous buffer, we waste at most 1/16 of the block we are giving up */
+ /* on. This cost is reasonable in exchange for all the speed this gives. */
+ p_mm_t p_tmp=mm_newblk((size_t) MM_BLOCK);
+ p_tmp->mm_pnext=(*pp_mm);
+ (*pp_mm)=p_tmp;
+ p_from=p_tmp;
+ }
+
+ dole_out:
+ /* Jump here to dole out 'bytes' bytes from block 'p_from'. */
+ p_result=p_from->mm_pfree;
+ p_from->mm_pfree += bytes;
+ p_from->mm_nfree -= bytes;
+ mm_align(p_from);
+
+ /* Ensure that the pointer being returned is properly aligned. */
+ as_cold((((ulong) p_result) & ALIGN_MASK)==0,
+ "mm_alloc: Result is misaligned.");
+
+ /* Return the result. */
+ return (p_void) p_result;
+}
+
+/******************************************************************************/
+
+EXPORT p_void mm_perm(bytes)
+size_t bytes;
+{
+#if MEMTRACE
+ printf("TRACE: mm_perm: Allocating %lu bytes of permanent memory.\n",
+(ulong) bytes);
+#endif
+ return mm_alloc(&p_perm,bytes);
+}
+
+/******************************************************************************/
+
+EXPORT p_void mm_temp(bytes)
+size_t bytes;
+{
+#if MEMTRACE
+ printf("TRACE: mm_temp: Allocating %lu bytes of temporary memory.\n",
+(ulong) bytes);
+#endif
+ return mm_alloc(&p_temp,bytes);
+}
+
+/******************************************************************************/
+
+EXPORT void mm_zapt()
+/* This function frees all the memory blocks recorded in the temporary */
+/* memory list. We choose to free them rather than merely re-using them */
+/* directly because they may not all be the same size, and we want to give */
+/* the built-in memory manager a chance to smooth out the heap. */
+{
+#if MEMTRACE
+ printf("TRACE: mm_zapt: Attempting to release all temporary memory.\n");
+#endif
+
+ while (p_temp != NULL)
+ {
+ p_mm_t p_mm=p_temp;
+ mm_check(p_temp);
+#if MEMTRACE
+ printf("TRACE: mm_zapt: Deallocating a big chunk of temporary memory.\n");
+#endif
+ free(p_temp->mm_pblok);
+ p_temp=p_temp->mm_pnext;
+ free(p_mm);
+ }
+}
+
+/******************************************************************************/
+/* End of MEMORY.C */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/memory.h b/web/funnelAC/sources/memory.h
new file mode 100644
index 0000000000..fe7889659f
--- /dev/null
+++ b/web/funnelAC/sources/memory.h
@@ -0,0 +1,113 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* MEMORY.H */
+/******************************************************************************/
+/* */
+/* Introduction */
+/* ------------ */
+/* This package provides a memory management facility for FunnelWeb. */
+/* The conventional MALLOC does not suit the needs of FunnelWeb. The */
+/* following notes give an idea of why: */
+/* */
+/* 1. At the times where FunnelWeb requires memory, it is nearly always */
+/* the case that failure to provide the memory should result in a bomb. */
+/* It therefore makes sense to wrap MALLOC up inside another function */
+/* that, at the very least, checks the status from malloc and bombs */
+/* the program if the requested memory is not available. */
+/* */
+/* 2. Because FunnelWeb proper can be invoked an indefinite number of */
+/* times from the FunnelWeb command interpreter, it is very important */
+/* to reclaim all the memory used by each invocation. This could be */
+/* done by explicitly tearing apart the data structures constructed */
+/* for each run. However, this is very messy, requiring detailed */
+/* knowledge of the data structures. A far simpler, safer scheme is to */
+/* arrange for a memory manager to keep track of all the memory that it */
+/* allocates and to provide a single call to free it all. This facility */
+/* is provided by this package. */
+/* */
+/* 3. In addition to the TEMPORARY memory allocations described in (2) above, */
+/* it should also be possible to make permanent allocations. */
+/* */
+/* 4. FunnelWeb uses linked lists a lot and hence will make many requests */
+/* for small chunks of memory (e.g 10 bytes). Legend has it that some */
+/* malloc libraries are very inefficient in this case, and that it is */
+/* better to use malloc to allocate a large chunk of memory and dole it */
+/* out yourself. This package does this too. */
+/* */
+/* For all these reasons, FunnelWeb memory management has been handed over to */
+/* this package which provides services that satisfy the conditions outlined */
+/* above. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_MEMORY
+#define DONE_MEMORY
+
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+EXPORT p_void mm_perm P_((size_t));
+/* Allocates a block of memory of the specified size (specified in bytes) and */
+/* returns a pointer to the new block of memory. Bombs the program if the */
+/* memory is not available. Memory allocated using mm_perm is permanently */
+/* allocated and cannot be freed. */
+
+EXPORT p_void mm_temp P_((size_t));
+/* Allocates a block of memory of the specified size (specified in bytes) and */
+/* returns a pointer to the new block of memory. Bombs the program if the */
+/* memory is not available. Memory allocated using this function can later be */
+/* freed in its entirely by making a call to mm_zapt. */
+
+EXPORT void mm_zapt P_((void));
+/* This function can be called at any time. Its effect is to free up all the */
+/* memory allocated using mm_temp since the last call to mm_zapt or the start */
+/* of the program, whichever is the more recent. */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of MEMORY.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/misc.c b/web/funnelAC/sources/misc.c
new file mode 100644
index 0000000000..183246be23
--- /dev/null
+++ b/web/funnelAC/sources/misc.c
@@ -0,0 +1,232 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* MISC.C */
+/******************************************************************************/
+
+#include <ctype.h>
+#include "style.h"
+
+#include "as.h"
+#include "data.h"
+#include "memory.h"
+#include "misc.h"
+#include "writfile.h"
+
+/******************************************************************************/
+
+EXPORT void wr_s (s) char *s; {wf_wr(&f_s,s);}
+EXPORT void wr_j (s) char *s; {wf_wr(&f_j,s);}
+EXPORT void wr_l (s) char *s; {wf_wr(&f_l,s);}
+
+EXPORT void wl_s (s) char *s; {wf_wr(&f_s,s); wf_wr(&f_s,"\n");}
+EXPORT void wl_j (s) char *s; {wf_wr(&f_j,s); wf_wr(&f_j,"\n");}
+EXPORT void wl_l (s) char *s; {wf_wr(&f_l,s); wf_wr(&f_l,"\n");}
+
+EXPORT void wr_sj (s) char *s; {wr_s(s); wr_j(s);}
+EXPORT void wl_sj (s) char *s; {wl_s(s); wl_j(s);}
+
+EXPORT void wr_sjl(s) char *s; {wr_s(s); wr_j(s); wr_l(s);}
+EXPORT void wl_sjl(s) char *s; {wl_s(s); wl_j(s); wl_l(s);}
+
+/******************************************************************************/
+
+EXPORT char *chabbrev(ch)
+int ch;
+{
+ switch (ch)
+ {
+ case 0: return "NUL";
+ case 1: return "SOH";
+ case 2: return "STX";
+ case 3: return "ETX";
+ case 4: return "EOT";
+ case 5: return "ENQ";
+ case 6: return "ACK";
+ case 7: return "BEL";
+ case 8: return "BS";
+ case 9: return "HT";
+ case 10: return "LF";
+ case 11: return "VT";
+ case 12: return "FF";
+ case 13: return "CR";
+ case 14: return "SO";
+ case 15: return "SI";
+ case 16: return "DLE";
+ case 17: return "DC1";
+ case 18: return "DC2";
+ case 19: return "DC3";
+ case 20: return "DC4";
+ case 21: return "NAK";
+ case 22: return "SYN";
+ case 23: return "ETB";
+ case 24: return "CAN";
+ case 25: return "EM";
+ case 26: return "SUB";
+ case 27: return "ESC";
+ case 28: return "FS";
+ case 29: return "GS";
+ case 30: return "RS";
+ case 31: return "US";
+ case 127:return "DEL";
+ default: return "";
+ }
+}
+
+/******************************************************************************/
+
+EXPORT sign signof(n)
+long n;
+{
+ if (n<0) return -1;
+ if (n>0) return 1;
+ return 0;
+}
+
+/******************************************************************************/
+
+EXPORT char * eq_files(name1,name2,p_result)
+char *name1;
+char *name2;
+bool *p_result;
+{
+ FILE *file1;
+ FILE *file2;
+
+ /* The following three lines define two comparison buffers. The next part of */
+ /* the two files being compared are read into these buffers and compared. */
+ /* Using the buffers allows bulk reads, which speeds things up considerably. */
+#define CMPBUFSIZ 16384
+ STAVAR ubyte_ *buf1 = NULL;
+ STAVAR ubyte_ *buf2 = NULL;
+
+ /* Set the default result to be FALSE (no match). */
+ *p_result=FALSE;
+
+ /* Allocate the comparison buffers if they are not already allocated. */
+ if (buf1 == NULL)
+ {
+ buf1=(ubyte_ *) mm_perm((size_t) CMPBUFSIZ);
+ buf2=(ubyte_ *) mm_perm((size_t) CMPBUFSIZ);
+ }
+
+ /* Open, for binary reading, the two files to be compared. */
+ file1=fopen(name1,"rb");
+ if (file1 == FOPEN_F)
+ return "Error opening the first file.";
+ file2=fopen(name2,"rb");
+ if (file2 == FOPEN_F)
+ {fclose(file1);return "Error opening the second file.";}
+
+ while (TRUE)
+ { /* Compare a chunk. */
+ size_t len1;
+ size_t len2;
+
+ /* Read a chunk from each file. */
+ len1=fread(buf1,(size_t) 1,(size_t) CMPBUFSIZ,file1);
+ len2=fread(buf2,(size_t) 1,(size_t) CMPBUFSIZ,file2);
+ if (ferror(file1))
+ return "Compare: Error reading the first file.";
+ if (ferror(file2))
+ return "Compare: Error reading the second file.";
+
+ /* Compare the two chunks. */
+ if (len1 != len2) break;
+ if (len1 == 0) {*p_result=TRUE; break;}
+ if (memcmp(buf1,buf2,(size_t) len1) != 0) break;
+ }
+
+ if (fclose(file1) == FCLOSE_F)
+ {*p_result=FALSE; return "Error closing the first file.";}
+ if (fclose(file2) == FCLOSE_F)
+ {*p_result=FALSE; return "Error closing the second file.";}
+
+ /* If we have reached this point, we can be sure that no errors occurred. */
+ return NULL;
+}
+
+/******************************************************************************/
+
+EXPORT bool fexists(fn)
+char *fn;
+{
+ FILE *file;
+ bool success;
+
+ file=fopen(fn,"rb");
+ if (file==NULL)
+ return FALSE;
+
+ success= (fclose(file) != FCLOSE_F);
+ as_cold(success,
+ "fexists: Error closing file whose existence is being tested!");
+
+ return TRUE;
+}
+
+/******************************************************************************/
+
+EXPORT char *fn_temp()
+{
+ STAVAR uword filnum=1;
+ STAVAR fn_t fn;
+ do
+ {
+ sprintf(fn,"fwtf%04lu.tmp",(ulong) filnum);
+ filnum++;
+ }
+ while (fexists(fn));
+ return fn;
+}
+
+/******************************************************************************/
+
+EXPORT void strupper(s)
+char *s;
+{
+ while (*s != EOS)
+ {
+ *s=toupper(*s);
+ s++;
+ }
+}
+
+/******************************************************************************/
+/* End of MISC.C */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/misc.h b/web/funnelAC/sources/misc.h
new file mode 100644
index 0000000000..aa98dbb2f0
--- /dev/null
+++ b/web/funnelAC/sources/misc.h
@@ -0,0 +1,126 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* MISC.H */
+/******************************************************************************/
+/* */
+/* This package contains a ragbag of FunnelWeb-specific functions that didn't */
+/* seem to have a home anywhere else. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "data.h"
+
+/******************************************************************************/
+
+/* The following functions each write a string to one or more output streams. */
+/* The code is as follows: */
+/* wr - means write the string only. */
+/* wl - means write the string followed by a '\n'. */
+/* s - The f_s output stream (the console/screen). */
+/* j - The f_j output stream (the journal file). */
+/* l - The f_l output stream (the listing file). */
+/* These functions are hard wired to the f_s, f_j, and f_l global variables. */
+
+EXPORT void wr_s P_((char *));
+EXPORT void wr_j P_((char *));
+EXPORT void wr_l P_((char *));
+
+EXPORT void wl_s P_((char *));
+EXPORT void wl_j P_((char *));
+EXPORT void wl_l P_((char *));
+
+EXPORT void wr_sj P_((char *));
+EXPORT void wl_sj P_((char *));
+
+EXPORT void wr_sjl P_((char *));
+EXPORT void wl_sjl P_((char *));
+
+/******************************************************************************/
+
+EXPORT char *chabbrev P_((int));
+/* If the argument is non-printable in the range [0,127], returns a pointer */
+/* to a constant string containing the mnemonic abbreviation for the */
+/* character (e.g. 10="LF"). Otherwise returns the empty string. */
+
+/******************************************************************************/
+
+EXPORT sign signof P_((long));
+/* Returns -1 if its argument is negative. */
+/* Returns 0 if its argument is zero. */
+/* Returns 1 if its argument is positive. */
+
+/******************************************************************************/
+
+EXPORT char * eq_files P_((char *,char *,bool *));
+/* Performs an exact binary comparison of the files named name1 and name2. */
+/* If there is no error during the comparison, returns NULL and the boolean */
+/* parameter carries the result of the comparison with TRUE=>Files identical. */
+/* If there is an error during the comparison, the boolean parameter is set */
+/* to FALSE and the function returns a pointer to a string describing the */
+/* error in terms of "the first file" and "the second file". */
+
+/******************************************************************************/
+
+EXPORT bool fexists P_((char *));
+/* Returns TRUE iff a file of the name given in the parameter exists. */
+/* (Does this by attempting to open the file. If it succeeds, it closes it */
+/* again). */
+
+/******************************************************************************/
+
+EXPORT char *fn_temp P_((void));
+/* Creates a filename (not containing a directory component) for which there */
+/* is no corresponding file in the current directory. */
+/* Returns a pointer to a static array containing the filename. */
+/* Each time this function is called, the new filename overwrites the old. */
+/* This function was created after it was discovered that, on some systems, */
+/* the standard library function "tmpnam" returns the name of a file in the */
+/* /tmp partition. This would not be a problem were it not for the fact that */
+/* generally, files cannot be renamed across partitions! */
+
+/******************************************************************************/
+
+EXPORT void strupper P_((char *));
+/* Converts all lower case letters in the argument string to upper case. */
+
+/******************************************************************************/
+/* End of MISC.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/option.c b/web/funnelAC/sources/option.c
new file mode 100644
index 0000000000..19d31b6123
--- /dev/null
+++ b/web/funnelAC/sources/option.c
@@ -0,0 +1,440 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* OPTION.C */
+/******************************************************************************/
+
+#include <ctype.h>
+#include "style.h"
+
+#include "as.h"
+#include "data.h"
+#include "machin.h"
+#include "misc.h"
+#include "option.h"
+
+/******************************************************************************/
+
+LOCAL void wl_caret P_((ulong,void (*)(char *)));
+LOCAL void wl_caret(n,p_outf)
+/* Writes a caret at position n of an otherwise blank line. */
+ulong n;
+void (*p_outf) P_((char *));
+{
+ as_cold(n<1000,"wl_caret: Argument is out of range.");
+ while (--n > 0)
+ (*p_outf)(" ");
+ (*p_outf)("^\n");
+}
+
+/******************************************************************************/
+
+EXPORT void op_ini(p_op)
+p_op_t p_op;
+{
+ p_op->op_f_b=FALSE;
+ strcpy(&p_op->op_f_s[0],"");
+
+ p_op->op_j_b=FALSE;
+ strcpy(&p_op->op_j_s[0],"");
+
+ strcpy(&p_op->op_i_s[0],"");
+
+ p_op->op_o_b=TRUE;
+ strcpy(&p_op->op_o_s[0],"");
+
+ p_op->op_t_b=FALSE;
+ strcpy(&p_op->op_t_s[0],"");
+
+ p_op->op_l_b=TRUE;
+ strcpy(&p_op->op_l_s[0],"");
+
+ p_op->op_d_b=FALSE;
+
+ p_op->op_c_i=2;
+
+ p_op->op_q_b=FALSE;
+
+ p_op->op_s_b=FALSE;
+ p_op->op_s_i=1;
+
+ p_op->op_w_b=FALSE;
+ p_op->op_w_i=80;
+
+ p_op->op_x_b=FALSE;
+ strcpy(&p_op->op_x_s[0],"");
+
+ p_op->op_k_b=FALSE;
+
+ p_op->op_b1_b=FALSE;
+ p_op->op_b2_b=FALSE;
+ p_op->op_b3_b=FALSE;
+ p_op->op_b4_b=FALSE;
+ p_op->op_b5_b=FALSE;
+ p_op->op_b6_b=FALSE;
+ p_op->op_b7_b=FALSE;
+
+ p_op->op_h_b=FALSE;
+ strcpy(&p_op->op_h_s[0],"menu");
+}
+
+/******************************************************************************/
+
+EXPORT bool op_add(p_op,p_cl,p_outf)
+p_op_t p_op;
+p_cl_t p_cl;
+void (*p_outf) P_((char *));
+{
+ op_t op_save; /* Saves *p_op so it can be restored later. */
+ char *comline = (char *) p_cl; /* Pointer to the command line to be parsed. */
+ char *p; /* Handy parsing pointer. */
+ bool seen_error = FALSE; /* TRUE iff one or more errors seen. */
+
+#define ECHO_CL {if (!seen_error)\
+ {(*p_outf)(comline);(*p_outf)("\n"); seen_error=TRUE;}}
+
+ /* Save the parameter option structure so that we can restore it */
+ /* if an error occurs later on. */
+ ASSIGN(op_save,*p_op);
+
+ /* Check to make sure that the command line is not too long. */
+ /* This error should really never occur. */
+ p=comline;
+ while (*p++ != EOS)
+ if ((p-comline) > COMLINE_FWMAX)
+ {
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("The entire command line is too long.\n");
+ sprintf(linet1,"The maximum command line length is %u characters.\n",
+ (unsigned) COMLINE_FWMAX);
+ (*p_outf)(linet1);
+ goto failure;
+ }
+
+ /* Check that the command line contains only printables. */
+ p=comline;
+ while (*p != EOS)
+ {
+ if (!isascprn(*p))
+ {
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Command line contains one or more non-printables.\n");
+ sprintf(linet1,"The first is at column %u.\n",(unsigned) (1+p-comline));
+ (*p_outf)(linet1);
+ goto failure;
+ }
+ p++;
+ }
+
+ /* Now parse each option. */
+ p=comline;
+ while (TRUE)
+ {/* This loop processes one command line parameter (option) per iteration. */
+ char *p_startopt; /* Points to the start of the parameter. */
+ bool opsign; /* The sign of the current option (+=TRUE). */
+ bool opsign_active; /* TRUE => (+ or -). FALSE => (=). */
+ char letter; /* Letter of current option. */
+ cl_t cl_temp; /* Parameter string of the current option. */
+ fn_t fn_temp; /* Parameter string of the current option. */
+ int i; /* Handy int used to feed sscanf. */
+
+ /* Skip first parameter or rest of previous parameter after syntax error. */
+ while ((*p!=' ') && (*p!=EOS)) p++;
+
+ /* Skip blanks between parameters. */
+ while (*p==' ') p++;
+
+ /* At this point we are either at the start of a parameter or at EOS. */
+ /* Finish if we are at the EOS. */
+ if (*p==EOS) break;
+
+ /* p now points to the next parameter (option). Make a note of its start. */
+ p_startopt=p;
+
+ /* This switch statement parses the sign and letter characters. */
+ switch (*p)
+ {
+ case '-': opsign=FALSE; opsign_active=TRUE; p++; goto parse_letter;
+ case '+': opsign=TRUE; opsign_active=TRUE; p++; goto parse_letter;
+ case '=': opsign_active=FALSE; p++; goto parse_letter;
+ parse_letter:
+ /* We have seen a sign. There should be a following letter. */
+ letter = *p;
+ if (!isalpha(letter))
+ {
+ ECHO_CL; wl_caret(p-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Option letter expected here.\n");
+ continue; /* Skip to the next parameter. */
+ }
+ p++;
+ break;
+ default: /* If no sign the option is a NAME option and defaults to +F. */
+ opsign=TRUE; opsign_active=TRUE; letter='F'; break;
+ } /* End switch */
+
+ /* Assert: p points to the parameter string of the option. */
+ /* Copy the parameter string into the holding variable cl_temp. */
+ {char *q;
+ q = &cl_temp[0];
+ while ((*p!=EOS) && (*p!=' '))
+ *q++ = *p++;
+ *q=EOS;
+ }
+
+ /* As COMLINE_FWMAX can be greater than FILENAME_FWMAX, we have to be carefu*/
+ /* that the user is not about to blow our filename buffer. */
+ if (strlen(cl_temp) > FILENAME_FWMAX)
+ {
+ ECHO_CL; wl_caret(p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Option parameter string is too long.\n");
+ sprintf(linet1,"The maximum option parameter length is %u characters.\n",
+ (unsigned) FILENAME_FWMAX);
+ (*p_outf)(linet1);
+ continue; /* Skip to next parameter. */
+ }
+
+ /* Now that we know that the parameter is not too big, we can copy it */
+ /* into a temporary variable of filename type. */
+ strcpy(&fn_temp[0],&cl_temp[0]);
+
+ /* At this point p points to the character following the option that */
+ /* we have just scanned. This is either a blank or an EOS. */
+ /* The current option is held in (opsign,opsign_active,letter,fn_temp). */
+ /* Now we apply the option to the option record. */
+ switch (toupper(letter))
+ {
+ case 'F':
+ if (opsign_active) p_op->op_f_b=opsign;
+ strcpy(&p_op->op_f_s[0],&fn_temp[0]);
+ break;
+ case 'J':
+ if (opsign_active) p_op->op_j_b=opsign;
+ strcpy(&p_op->op_j_s[0],&fn_temp[0]);
+ break;
+ case 'I':
+ strcpy(&p_op->op_i_s[0],&fn_temp[0]);
+ break;
+ case 'O':
+ if (opsign_active) p_op->op_o_b=opsign;
+ strcpy(&p_op->op_o_s[0],&fn_temp[0]);
+ break;
+ case 'T':
+ if (opsign_active) p_op->op_t_b=opsign;
+ strcpy(&p_op->op_t_s[0],&fn_temp[0]);
+ break;
+ case 'L':
+ if (opsign_active) p_op->op_l_b=opsign;
+ strcpy(&p_op->op_l_s[0],&fn_temp[0]);
+ break;
+ case 'D':
+ if (opsign_active) p_op->op_d_b=opsign;
+ if (strlen(fn_temp)>0)
+ {
+ ECHO_CL; wl_caret(3+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("The D option does not take an argument.\n");
+ }
+ break;
+ case 'C':
+ if ((sscanf(&fn_temp[0],"%d",&i) != 1) || (i<0) || (100<i))
+ {
+ ECHO_CL; wl_caret(3+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Numeric argument to C option invalid. It must\n");
+ (*p_outf)("be an unsigned decimal integer in the range [0,100].\n");
+ }
+ else
+ p_op->op_c_i=i;
+ break;
+ case 'Q':
+ if (opsign_active) p_op->op_q_b=opsign;
+ if (strlen(fn_temp)>0)
+ {
+ ECHO_CL; wl_caret(3+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("The Q option does not take an argument.\n");
+ }
+ break;
+ case 'S':
+ if (opsign_active) p_op->op_s_b=opsign;
+ if (strlen(fn_temp)==0) break;
+ if ((sscanf(&fn_temp[0],"%d",&i) != 1) || (i<0) || (100<i))
+ {
+ ECHO_CL; wl_caret(2+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Numeric argument to S option invalid. It must\n");
+ (*p_outf)("be an unsigned decimal integer in the range [0,100].\n");
+ }
+ else
+ p_op->op_s_i=i;
+ break;
+ case 'W':
+ if (opsign_active) p_op->op_w_b=opsign;
+ if (strlen(fn_temp)==0) break;
+ if ((sscanf(&fn_temp[0],"%d",&i) != 1) || (i<0) || (1000<i))
+ {
+ ECHO_CL; wl_caret(2+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Error: Numeric argument to W option invalid. It must\n");
+ (*p_outf)("be an unsigned decimal integer in the range [0,1000].\n");
+ }
+ else
+ p_op->op_w_i=i;
+ break;
+ case 'X':
+ if (opsign_active) p_op->op_x_b=opsign;
+ strcpy(&p_op->op_x_s[0],&fn_temp[0]);
+ break;
+ case 'K':
+ if (opsign_active) p_op->op_k_b=opsign;
+ if (strlen(fn_temp)>0)
+ {
+ ECHO_CL; wl_caret(3+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("The K option does not take an argument.\n");
+ }
+ break;
+ case 'H':
+ if (opsign_active) p_op->op_h_b=opsign;
+ if (strlen(&fn_temp[0])>0)
+ if (strlen(&fn_temp[0]) > HL_NMLEN)
+ {
+ ECHO_CL; wl_caret(3+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("The H option string argument is too long.\n");
+ (*p_outf)("Try +Hmenu for a list of help message names.\n");
+ }
+ else
+ if (hel_num(&fn_temp[0]) == HL_ERR)
+ {
+ ECHO_CL; wl_caret(3+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Unrecognised message name in argument to H option.\n");
+ (*p_outf)("Try +Hmenu for a list of help message names.\n");
+ }
+ else
+ strcpy(&p_op->op_h_s[0],&fn_temp[0]);
+ break;
+ case 'B':
+ {
+ uword i;
+ if (strlen(fn_temp)==0)
+ {
+ ECHO_CL; wl_caret(3+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("The B option must be followed by one or more digits.\n");
+ (*p_outf)("The digits must be in the range 1..7.\n");
+ break;
+ }
+ for (i=0;i<strlen(fn_temp);i++)
+ if (fn_temp[i]<'1' || fn_temp[i]>'7')
+ {
+
+ECHO_CL; wl_caret(2+p_startopt-comline+(1+i),p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Error: Characters in B argument must be '1'..'7'.\n");
+ goto endbop;
+ }
+ if (opsign_active)
+ for (i=0;i<strlen(fn_temp);i++)
+ switch (fn_temp[i])
+ {
+ case '1': p_op->op_b1_b=opsign; break;
+ case '2': p_op->op_b2_b=opsign; break;
+ case '3': p_op->op_b3_b=opsign; break;
+ case '4': p_op->op_b4_b=opsign; break;
+ case '5': p_op->op_b5_b=opsign; break;
+ case '6': p_op->op_b6_b=opsign; break;
+ case '7': p_op->op_b7_b=opsign; break;
+ default: as_bomb("op_add: b option case defaulted.");
+ }
+ endbop:
+ break;
+ }
+ default:
+ ECHO_CL; wl_caret(2+p_startopt-comline,p_outf);
+ (*p_outf)("FunnelWeb command line syntax error.\n");
+ (*p_outf)("Error: Unknown option letter.\n");
+ (*p_outf)("Legal option letters are FIOTLCSWPXZ.\n");
+ (*p_outf)("(Note: But P is not yet implemented!)\n");
+ break;
+ }
+ } /* End while. */
+ if (seen_error) goto failure;
+ return TRUE;
+
+ failure: ASSIGN(*p_op,op_save); return FALSE;
+}
+
+/******************************************************************************/
+
+EXPORT void op_wri(p_op,p_outf)
+p_op_t p_op;
+void (*p_outf) P_((char *));
+{
+#define STC(BOOLV) ((BOOLV)?'+':'-')
+ sprintf(linet1," %cB1 %cB2 %cB3 %cB4 %cB5 %cB6 %cB7\n",
+ STC(p_op->op_b1_b),
+ STC(p_op->op_b2_b),
+ STC(p_op->op_b3_b),
+ STC(p_op->op_b4_b),
+ STC(p_op->op_b5_b),
+ STC(p_op->op_b6_b),
+ STC(p_op->op_b7_b));(*p_outf)(linet1);
+ sprintf(linet1," +C%u\n" , (unsigned) p_op->op_c_i );(*p_outf)(linet1);
+ sprintf(linet1," %cD\n" , STC(p_op->op_d_b) );(*p_outf)(linet1);
+ sprintf(linet1," %cF%s\n", STC(p_op->op_f_b), p_op->op_f_s );(*p_outf)(linet1);
+ sprintf(linet1," %cH%s\n", STC(p_op->op_h_b), p_op->op_h_s );(*p_outf)(linet1);
+ sprintf(linet1," +I%s\n" , p_op->op_i_s );(*p_outf)(linet1);
+ sprintf(linet1," %cJ%s\n", STC(p_op->op_j_b), p_op->op_j_s );(*p_outf)(linet1);
+ sprintf(linet1," %cK\n" , STC(p_op->op_k_b) );(*p_outf)(linet1);
+ sprintf(linet1," %cL%s\n", STC(p_op->op_l_b), p_op->op_l_s );(*p_outf)(linet1);
+ sprintf(linet1," %cO%s\n", STC(p_op->op_o_b), p_op->op_o_s );(*p_outf)(linet1);
+ sprintf(linet1," %cQ\n" , STC(p_op->op_q_b) );(*p_outf)(linet1);
+ sprintf(linet1," %cS%u\n", STC(p_op->op_s_b), (unsigned) p_op->op_s_i );(*p_outf)(linet1);
+ sprintf(linet1," %cT%s\n", STC(p_op->op_t_b), p_op->op_t_s );(*p_outf)(linet1);
+ sprintf(linet1," %cW%u\n", STC(p_op->op_w_b), (unsigned) p_op->op_w_i );(*p_outf)(linet1);
+ sprintf(linet1," %cX%s\n", STC(p_op->op_x_b), p_op->op_x_s );(*p_outf)(linet1);
+}
+
+/******************************************************************************/
+/* End of OPTION.C */
+/******************************************************************************/
+
diff --git a/web/funnelAC/sources/option.h b/web/funnelAC/sources/option.h
new file mode 100644
index 0000000000..18974bf84c
--- /dev/null
+++ b/web/funnelAC/sources/option.h
@@ -0,0 +1,174 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* OPTION.H */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_OPTION
+#define DONE_OPTION
+
+/******************************************************************************/
+
+#include "style.h"
+
+#include "machin.h"
+#include "help.h"
+
+/******************************************************************************/
+
+/* THE B7 OPTION */
+/* ------------- */
+/* When FunnelWeb was first ported to different machines and the regression */
+/* testing was activated, a most irritating occurance was the failure of the */
+/* results of tests on different machines to compare, because of minor */
+/* differences in implementation. For example, error messages that contained */
+/* file names would differ because the directory name on different machines */
+/* was different. Another example was error messages that quoted */
+/* implementation limits. This problem was solved by creating the B7 option */
+/* which instructs FunnelWeb to suppress all output that is */
+/* non-deterministic, machine specific, or which in any other way would cause */
+/* an unncessary failure of the test suite. */
+
+/* The following symbol provides a simple replacement for filenames in error */
+/* messages. */
+#define SUPPNAME "<<Suppressed>>"
+#define SUPPVAL "<<Suppressed>>"
+
+/******************************************************************************/
+
+/* The following structure stores all the information that can be */
+/* communicated in one or more command lines. An important aspect of the */
+/* structure is that it is totally self contained; it does not contain any */
+/* pointers to outside structures such as command lines. */
+/* The rather strange field names are explained as follows: */
+/* 1) Local names must be distinct to 8 characters (for portability). */
+/* 2) All structure field names should be unique (for portability). */
+/* Some of the older compilers use a single field structure name space. */
+/* 3) The op_ is used as a prefix for entities in this whole package. */
+/* 4) The next letter is the option letter itself. It is not intended that */
+/* the command line option names be tightly bound to the internal */
+/* identifier names -- the command line names are just convenient. */
+/* 5) The next letter gives the type: [B]oolean, [S]tring, [I]nteger. */
+
+typedef struct
+ {
+ bool op_f_b; /* The input file. */
+ fn_t op_f_s;
+
+ bool op_j_b; /* The journal file. */
+ fn_t op_j_s;
+
+ fn_t op_i_s; /* Include file (default). */
+
+ bool op_o_b; /* Product files (default). */
+ fn_t op_o_s;
+
+ bool op_t_b; /* Typeset file (default). */
+ fn_t op_t_s;
+
+ bool op_l_b; /* Listing file (default). */
+ fn_t op_l_s;
+
+ bool op_d_b; /* Delete output files that have not changed? */
+
+ uword op_c_i; /* Lines of error context in listing file. */
+
+ bool op_q_b; /* Quiet mode. Console chatter suppressed if turned on. */
+
+ bool op_s_b; /* Send errors to the screen with specified context. */
+ uword op_s_i;
+
+ bool op_w_b; /* Set maximum line length of product files. */
+ uword op_w_i;
+
+ bool op_x_b; /* Execute specified file in FunnelWeb shell. */
+ fn_t op_x_s;
+
+ bool op_k_b; /* Interactive (keyboard) mode. */
+
+ /* Dump flags: */
+ bool op_b1_b; /* Dump input file image. */
+ bool op_b2_b; /* Dump line list. */
+ bool op_b3_b; /* Dump token list. */
+ bool op_b4_b; /* Dump macro table. */
+ bool op_b5_b; /* Dump document list. */
+ bool op_b6_b; /* Dump time summary. */
+ bool op_b7_b; /* Don't write anything non-deterministic or machine */
+ /* specific. This option is designed to assist in */
+ /* regression testing. */
+
+ bool op_h_b; /* Help messages. */
+ hn_t op_h_s;
+ } op_t;
+
+typedef op_t *p_op_t;
+
+/******************************************************************************/
+
+EXPORT void op_ini P_((p_op_t));
+/* Initializes the specified options structure with default values. */
+/* This includes ALL the fields of the structure. If, for example, the */
+/* default value of op_l_b is FALSE, op_l_s will be set to the empty string. */
+
+EXPORT bool op_add P_((p_op_t,p_cl_t,void (*)(char *)));
+/* Parses the specified command line and places the information given in the */
+/* command line into specific fields of the options structure. The options */
+/* structure should be entirely defined upon entry, as this parsing function */
+/* only ADDS information present in the command line. Call op_ini if you */
+/* don't want to initialize all the fields manually. */
+/* The comline string should start with the leading command (e.g. "fw"). */
+/* However, he leading command is ignored. */
+/* Returns FALSE: One or more syntax errors have been detected. One or error */
+/* messages have been written using the funtion argument. */
+/* *p_op unchanged. */
+/* Returns TRUE : No syntax errors. Comline information placed in *p_op. */
+
+EXPORT void op_wri P_((p_op_t,void (*)(char *)));
+/* Writes a text representation of the specified options record using the */
+/* function argument. */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of OPTION.H */
+/******************************************************************************/
+
diff --git a/web/funnelAC/sources/parser.c b/web/funnelAC/sources/parser.c
new file mode 100644
index 0000000000..4be989d18f
--- /dev/null
+++ b/web/funnelAC/sources/parser.c
@@ -0,0 +1,1289 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* PARSER.C */
+/******************************************************************************/
+
+#include <setjmp.h>
+#include "style.h"
+
+#include "as.h"
+#include "data.h"
+#include "lister.h"
+#include "machin.h"
+#include "mapper.h"
+#include "memory.h"
+#include "misc.h"
+#include "parser.h"
+#include "section.h"
+#include "table.h"
+
+/******************************************************************************/
+
+#define DUMMYINT 0 /* It doesn't matter what this value is!!! */
+#define TKPS &(p_tk->tk_ps) /* A commonly used construct. */
+
+/******************************************************************************/
+
+/* The following variables look after sections. */
+LOCVAR sn_t last_sn; /* Hierarchical section number of last section. */
+LOCVAR ps_t pssection; /* Position of last section. */
+LOCVAR p_dc_t p_secdc; /* Pointer to current section document component. */
+LOCVAR tk_t *p_tk; /* Pointer to the current token (a structure). */
+LOCVAR ulong sequence; /* Current sequence number. */
+LOCVAR jmp_buf jmp_pos; /* Setjmp() position of main parsing loop. */
+
+/******************************************************************************/
+/* Comparison Functions */
+/******************************************************************************/
+
+LOCAL sign cm_name P_((name_t *,name_t *));
+LOCAL sign cm_name(name1,name2)
+/* Compares two names and returns: */
+/* -1 if name1 < name2 */
+/* 0 if name1 = name2 */
+/* 1 if name1 > name2 */
+/* Provides a full ordering on the set of names. */
+name_t *name1;
+name_t *name2;
+{
+ return signof(strcmp(&(*name1)[0],&(*name2)[0]));
+}
+
+/******************************************************************************/
+
+LOCAL sign eq_txst P_((p_scls_t,char *));
+LOCAL sign eq_txst(p_scls,p_str)
+/* The first argument is a list of text scraps. */
+/* The second argument is an ordinary string. */
+/* Returns TRUE iff the two are identical. Otherwise FALSE. */
+p_scls_t p_scls;
+char *p_str;
+{
+ /* To compare the scrap list with the string, we run through the scrap list */
+ /* comparing the bytes its scraps yield progressively with the string. */
+ /* The two scanning groups are (p_scls,p_sc,p_ch) and p_str. */
+ sc_t *p_sc;
+
+ ls_fir(p_scls);
+ ls_nxt(p_scls,PPV &p_sc);
+ while (p_sc!=NULL)
+ {
+ /* The loop body compares a single scrap pointed to by p_sc. */
+ char *p_ch;
+ for (p_ch=p_sc->sc_first; p_ch<=p_sc->sc_last; p_ch++)
+ {
+ if (*p_str==EOS || *p_str != *p_ch) return FALSE;
+ p_str++;
+ }
+ ls_nxt(p_scls,PPV &p_sc);
+ }
+ return *p_str==EOS;
+}
+
+/******************************************************************************/
+/* Parsing Primitives */
+/******************************************************************************/
+/* The following functions provide the basic parsing primitives used by the */
+/* main parsing routines. */
+/******************************************************************************/
+
+LOCAL void next_tk P_((bool));
+LOCAL void next_tk(iseoferr)
+/* This function reads the next token from the token list and places a */
+/* pointer to the token (structure) in the global variable "token". */
+/* The "iseoferr" determines whether a fuss should be made if the next token */
+/* fetched is TK_EOF. If iseoferr==TRUE and the next token is TK_EOF, next_tk */
+/* jumps to the main parsing loop. */
+bool iseoferr;
+{
+ ls_nxt(token_list,PPV &p_tk);
+ as_cold(p_tk!=NULL,"next_tk: Attempted to read next token at EOF.");
+ if (iseoferr && p_tk->tk_kind==TK_EOF)
+ {
+ lr_err(TKPS,"Ouch! High velocity encounter with end of file.");
+ lr_mes(TKPS,"FunnelWeb expected something else when it hit the EOF.");
+ longjmp(jmp_pos,DUMMYINT); /* Jump up to the main parsing loop. */
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void recover P_((void));
+LOCAL void recover()
+/* Parsing functions call this function at points where a syntax error has */
+/* has occurred that it is unlikely that the particular parsing function will */
+/* be able to recover from on its own. In these situations, the parser */
+/* resorts to a course grained syntactic error-recovery implemented by this */
+/* function. The goal of the error recovery system is to skip tokens until */
+/* the next major outer-level-syntax structure is encountered. These are: */
+/* - A new section (@A etc.). */
+/* - A macro definition (@$ or @O). */
+/* - End of file. */
+/* Once one of these three is found, "recover" raises the syntax exception */
+/* which sends control to the main parsing loop which is the correct place */
+/* to deal with a new, major syntactic construct. */
+{
+ lr_mes(TKPS,"Skipping after error to the next major construct...");
+
+ /* Skip to one of TK_NSEC,... */
+ while (TRUE)
+ {
+ tk_k_t k = p_tk->tk_kind;
+ if (k==TK_NSEC || k==TK_MDEF || k==TK_FDEF || k==TK_EOF) break;
+ next_tk(FALSE);
+ }
+
+ /* Keep the user informed. */
+ lr_mes(TKPS,"...skipped to here after the error.");
+
+ /* Jump up to the main parsing loop. */
+ longjmp(jmp_pos,DUMMYINT);
+}
+
+/******************************************************************************/
+
+LOCAL void genexerr P_((tk_k_t));
+LOCAL void genexerr(tk_kind)
+/* Genexerr stands for GENerate EXpecting ERRor. */
+/* Given a token kind, genexerr issues an error saying that the specified */
+/* kind of token was expected. It then invokes recover() for error recovery. */
+tk_k_t tk_kind;
+{
+ switch (tk_kind)
+ {
+ /* Note: Not all token kinds are listed here. Only those token kinds that */
+ /* are passed to pr_token and check_tk by the main parsing routines are */
+ /* included here. There are some tokens that one never expects! */
+ case TK_NSEC: lr_err(TKPS,"Expecting '@*'."); break;
+ case TK_ONAM: lr_err(TKPS,"Expecting '@<'."); break;
+ case TK_ODEF: lr_err(TKPS,"Expecting '@{'."); break;
+ case TK_CDEF: lr_err(TKPS,"Expecting '@}'."); break;
+ case TK_EMPH: lr_err(TKPS,"Expecting '@/'."); break;
+ case TK_CPAR: lr_err(TKPS,"Expecting '@)'."); break;
+ case TK_QUOT: lr_err(TKPS,"Expecting '@\"'."); break;
+ case TK_PARM: lr_err(TKPS,"Expecting one of [@1..@9]." ); break;
+ case TK_TEXT: lr_err(TKPS,"Expecting a text character."); break;
+ default: as_bomb("genexerr: Case defaulted.");
+ }
+ recover();
+}
+
+/******************************************************************************/
+
+LOCAL void pr_token P_((tk_k_t));
+LOCAL void pr_token(tk_kind)
+/* Parses a single token of the specified kind. */
+/* If the token is of the specified kind, gets the next token. */
+/* If the token is not of the specified kind, generates an "expecting" error. */
+tk_k_t tk_kind;
+{
+ if (p_tk->tk_kind != tk_kind)
+ genexerr(tk_kind);
+ next_tk(TRUE);
+}
+
+/******************************************************************************/
+
+LOCAL void check_tk P_((tk_k_t));
+LOCAL void check_tk(tk_kind)
+/* Same as pr_token, but only checks that the token is OK. Does not move on. */
+tk_k_t tk_kind;
+{
+ if (p_tk->tk_kind != tk_kind)
+ genexerr(tk_kind);
+}
+
+/******************************************************************************/
+
+LOCAL void ass_tk P_((tk_k_t));
+LOCAL void ass_tk(tk_kind)
+/* Aborts the program if the current token is not of the specified kind. */
+/* This function is intended to perform internal consistency checks, and */
+/* should not be considered to be part of the parsing operation. */
+tk_k_t tk_kind;
+{
+ as_cold(p_tk->tk_kind==tk_kind,"Parser.ass_tk: Incorrect token.");
+}
+
+/******************************************************************************/
+
+LOCAL void ass_tks P_((tk_k_t,tk_k_t));
+LOCAL void ass_tks(tk_kind1,tk_kind2)
+/* Same as ass_tk except it allows a choice of two token kinds. */
+tk_k_t tk_kind1;
+tk_k_t tk_kind2;
+{
+ as_cold((p_tk->tk_kind == tk_kind1) || (p_tk->tk_kind == tk_kind2),
+ "Parser.ass_tks: Token is neither of two allowables.");
+}
+
+/******************************************************************************/
+/* Main Parsing Functions */
+/******************************************************************************/
+
+/* The parse expression procedure is the only procedure for which a forward */
+/* declaration is required. This is a product of the recursive definition of */
+/* a FunnelWeb expression. */
+LOCAL void pr_exp P_((p_ells_t *,p_ma_t));
+
+/******************************************************************************/
+
+LOCAL void pr_text P_((p_scls_t *,bool *));
+LOCAL void pr_text(pp_scls,p_white)
+/* This function parses a sequence of zero or more text tokens (until it runs */
+/* into a non-text token) and constructs a list of scraps containing the text */
+/* pointed to by the tokens. In addition the function writes TRUE to its */
+/* second argument iff all of the text scraps are whitespace. */
+p_scls_t *pp_scls;
+bool *p_white;
+{
+ *pp_scls=ls_cre(sizeof(sc_t));
+ *p_white=TRUE;
+
+ while (p_tk->tk_kind==TK_TEXT)
+ {
+ *p_white = *p_white && p_tk->tk_sc.sc_white;
+ ls_add(*pp_scls,PV &p_tk->tk_sc);
+ next_tk(FALSE);
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void pr_white P_((p_scls_t *));
+LOCAL void pr_white(pp_scls)
+/* Same as pr_text, but generates an error if the text is non-white. */
+p_scls_t *pp_scls;
+{
+ bool iswhite;
+ ps_t ps;
+ ASSIGN(ps,p_tk->tk_ps);
+ pr_text(pp_scls,&iswhite);
+ if (!iswhite)
+ lr_err(&ps,"Expecting whitespace text.");
+}
+
+/******************************************************************************/
+
+LOCAL void pr_name P_((char *));
+LOCAL void pr_name(p_name)
+/* Parses a single FunnelWeb name (e.g. "@<Sloth@>" and "@#K"). */
+char *p_name; /* Really should be of type p_name_t but this caused trouble. */
+{
+ uword namelen = 0;
+
+ /* Deal with the special case of a token name. */
+ if (p_tk->tk_kind==TK_NAME)
+ {
+ p_name[0]=p_tk->tk_gen;
+ p_name[1]=EOS;
+ next_tk(TRUE);
+ return;
+ }
+
+ ass_tk(TK_ONAM);
+ next_tk(TRUE);
+
+ while (TRUE)
+ switch (p_tk->tk_kind)
+ {
+ case TK_TEXT:
+ {
+ /* Copy the text token to the name array, checking all the time. */
+ char *p;
+ for (p=p_tk->tk_sc.sc_first; p<=p_tk->tk_sc.sc_last; p++)
+ {
+ if (*p==EOL)
+ {
+ lr_err(TKPS,"Names cannot cross lines.");
+ recover();
+ }
+ namelen++;
+ if (namelen>NAME_MAX)
+ {
+ lr_err(TKPS,"Name is too long.");
+ sprintf(linet1,
+ "The maximum length of a legal name is %lu characters.",
+ (unsigned long) NAME_MAX);
+ lr_mes(TKPS,linet1);
+ recover();
+ }
+ p_name[namelen-1] = *p;
+ }
+ next_tk(TRUE);
+ break;
+ }
+ case TK_CNAM:
+ /* We finish successfully if we hit a close name token "@>". */
+ p_name[namelen]=EOS;
+ next_tk(TRUE);
+ return;
+ default:
+ lr_err(TKPS,"Illegal character or symbol in name.");
+ recover();
+ } /* End switch */
+}
+
+/******************************************************************************/
+
+LOCAL void pr_dctxt P_((void));
+LOCAL void pr_dctxt()
+/* Parse a major text chunk. */
+{
+ dc_t dc;
+ bool dummybool;
+ ps_t pstext;
+
+ ass_tk(TK_TEXT);
+
+ ASSIGN(pstext,p_tk->tk_ps);
+ pr_text(&dc.dc_text,&dummybool);
+ ASSIGN(dc.dc_ps,pstext);
+ dc.dc_kind=DC_TEXT;
+ ls_add(document_list,PV &dc);
+}
+
+/******************************************************************************/
+
+LOCAL void sendtype P_((ty_k_t));
+LOCAL void sendtype(ty_kind)
+/* Send a document component of kind typesetter directive with no attributes. */
+ty_k_t ty_kind;
+{
+ dc_t dc;
+ ASSIGN(dc.dc_ps,p_tk->tk_ps);
+ dc.dc_kind = DC_TYPE;
+ dc.dc_ty.ty_kind=ty_kind;
+ ls_add(document_list,PV &dc);
+}
+
+/******************************************************************************/
+
+LOCAL void pr_lit P_((void));
+LOCAL void pr_lit()
+/* Parse a string delimited by literal typeset directives e.g. @{sloth@}. */
+{
+ /* Check and get past opening directive. */
+ ass_tk(TK_ODEF);
+ sendtype(TY_OLIT);
+
+ /* Move past the opening directive and parse the sandwich text. */
+ next_tk(TRUE);
+ if (p_tk->tk_kind!=TK_TEXT)
+ {
+ lr_err(TKPS,"Text expected after open literal token \"@{\".");
+ if (p_tk->tk_kind==TK_CDEF)
+ lr_mes(TKPS,"Sorry, empty literal strings are not allowed.");
+ recover();
+ }
+ pr_dctxt();
+
+ /* Check and parse the closing directive. */
+ pr_token(TK_CDEF);
+ sendtype(TY_CLIT);
+}
+
+/******************************************************************************/
+
+LOCAL void pr_emp P_((void));
+LOCAL void pr_emp()
+/* Parse a string delimited by emphasis typeset directives e.g. @/sloth@/. */
+{
+ /* Check and get past opening directive. */
+ ass_tk(TK_EMPH);
+ sendtype(TY_OEMP);
+
+ /* Move past the opening directive and parse the sandwich text. */
+ next_tk(TRUE);
+ if (p_tk->tk_kind!=TK_TEXT)
+ {
+ lr_err(TKPS,"Text expected after open emphasise token \"@/\".");
+ if (p_tk->tk_kind==TK_EMPH)
+ lr_mes(TKPS,"Sorry, empty emphasised strings are not allowed.");
+ recover();
+ }
+ pr_dctxt();
+
+ /* Check and parse the closing directive. */
+ pr_token(TK_EMPH);
+ sendtype(TY_CEMP);
+}
+
+/******************************************************************************/
+
+LOCAL void pr_npag P_((void));
+LOCAL void pr_npag()
+/* Parse a newpage token. */
+{
+ ass_tk(TK_NPAG);
+ sendtype(TY_NPAG);
+ pr_token(TK_NPAG);
+}
+
+/******************************************************************************/
+
+LOCAL void pr_tocs P_((void));
+LOCAL void pr_tocs()
+/* Parse a table of contents token. */
+{
+ ass_tk(TK_TOCS);
+ sendtype(TY_TOCS);
+ pr_token(TK_TOCS);
+}
+
+/******************************************************************************/
+
+LOCAL void pr_skip P_((void));
+LOCAL void pr_skip()
+/* Parse a skip token. */
+{
+ dc_t dc;
+ ass_tk(TK_SKIP);
+ ASSIGN(dc.dc_ps,p_tk->tk_ps);
+ dc.dc_kind = DC_TYPE;
+ dc.dc_ty.ty_kind=TY_SKIP;
+ dc.dc_ty.ty_mm=p_tk->tk_gen;
+ ls_add(document_list,PV &dc);
+ pr_token(TK_SKIP);
+}
+
+/******************************************************************************/
+
+LOCAL void pr_titl P_((void));
+LOCAL void pr_titl()
+/* Parse a title token. Bascially moving bones from one grave to another. */
+{
+ dc_t dc;
+ ass_tk(TK_TITL);
+ ASSIGN(dc.dc_ps,p_tk->tk_ps);
+ dc.dc_kind = DC_TYPE;
+ dc.dc_ty.ty_kind = TY_TITL;
+ dc.dc_ty.ty_font = p_tk->tk_gen / LRFT_PACK;
+ dc.dc_ty.ty_align = p_tk->tk_gen % LRFT_PACK;
+ ASSIGN(dc.dc_ty.ty_sc,p_tk->tk_sc);
+ ls_add(document_list,PV &dc);
+ pr_token(TK_TITL);
+}
+
+/******************************************************************************/
+
+LOCAL void pr_sec P_((void));
+LOCAL void pr_sec()
+/* Parse a new section marker ("@A.. and @*") and its optional name. */
+{
+ ps_t secps; /* Position of this new section. */
+ ubyte level; /* Level number of new section. */
+ bool has_name; /* Set to TRUE iff the section has a name. */
+ name_t name; /* Name of the section (if it has a name). */
+
+ /* If called, a new section marker must have been seen. */
+ ass_tk(TK_NSEC);
+
+ /* Grab a copy of the position of the start of the section. */
+ ASSIGN(secps,p_tk->tk_ps);
+
+ /* Grab the level number of the section marker. Move to the next token. */
+ level=p_tk->tk_gen;
+ next_tk(TRUE);
+
+ /* Check for a discontinuity in level. */
+ if (level>sn_lev(&last_sn)+1)
+ {
+ if (sn_lev(&last_sn)==0)
+ lr_err(&secps,"The first section in a document must be an @A section.");
+ else
+ {
+ sprintf(linet1,"The next section (at line %lu) is too deep.",
+ (unsigned long) secps.ps_line);
+ lr_mes(&pssection,linet1);
+ lr_err(&secps,"This section is more than one level deeper than the last");
+ sprintf(linet1,"section (at line %lu). Example: @B followed by @D is not allowed.",
+ (unsigned long) pssection.ps_line);
+ lr_mes(&secps,linet1);
+ }
+ /* At this point we know that the section structure of the document is */
+ /* faulty and that the weaver will never be invoked. As such the */
+ /* principal concern becomes that of error recovery. The best we can do */
+ /* there is to set to the specified level regardless of how silly it is. */
+ /* This ensures that we generate section errors only relative to the */
+ /* previous section. Thus, we avoid cascades of errors, if, for example */
+ /* the user mistypes an @A at the beginning of a FunnelWeb document. */
+ /* Once an error has occurred we don't care about the actual numbers. */
+ sn_set(&last_sn,level);
+ }
+
+ /* Actually increment the section number at the specified level. */
+ sn_inc(&last_sn,level);
+
+ /* Record the position. */
+ ASSIGN(pssection,secps);
+
+ /* Parse optional name (e.g. "@<Sloth@>"). */
+ if (p_tk->tk_kind==TK_ONAM || p_tk->tk_kind==TK_NAME)
+ {
+ pr_name(name);
+ has_name=TRUE;
+ }
+ else
+ {
+ strcpy(name,"No name given");
+ has_name=FALSE;
+ }
+
+ /* Place all the information we have into a document component structure */
+ /* and add it to the document list. */
+ {
+ dc_t dc;
+ ASSIGN(dc.dc_ps,secps);
+ dc.dc_kind = DC_TYPE;
+ dc.dc_ty.ty_kind=TY_NSEC;
+ ASSIGN(dc.dc_ty.ty_sn,last_sn);
+ dc.dc_ty.ty_isnam = has_name;
+ strcpy(&dc.dc_ty.ty_name[0],&name[0]);
+ ls_add(document_list,PV &dc);
+ ls_tai(document_list,PPV &p_secdc);
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void rem_name P_((char *));
+LOCAL void rem_name(p_name)
+/* rem_name stands for REMember NAME. rem_name accepts a pointer to a name. */
+/* It looks up the name in the global macro table, and if the name is in the */
+/* table performs no action. If the name isn't in the table, it creates a new */
+/* entry for the name, filling the entry's fields with "blank" values. */
+/* The rem_name function should not be seen as recording the definition of a */
+/* macro. This is handled by the md_isdef field. Instead the rem_name macro */
+/* should be viewed as just creating the space in the table for the info. */
+char * p_name; /* Really should be of type p_name_t but this caused trouble. */
+{
+ if (!tb_itb(macro_table,PV p_name))
+ {
+ p_ma_t p_macro=(p_ma_t) mm_temp(sizeof(ma_t));
+ strcpy(&p_macro->ma_name[0],&p_name[0]);
+ p_macro->ma_calls = ls_cre(sizeof(mc_t));
+ p_macro->ma_defn.md_isdef = FALSE;
+ p_macro->ma_actn = ls_cre(sizeof(p_elll_t));
+ tb_ins(macro_table,PV p_name,PV &p_macro);
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void chk_whex P_((p_ps_t,p_ells_t,p_scls_t *));
+LOCAL void chk_whex(p_ps,p_ex,pp_white)
+/* This function should really be a subfunction of pr_plist. However, C */
+/* doesn't allow nested functions so we have to put it here. This function is */
+/* called after pr_plist has just parsed an opening expression followed by */
+/* @". This means that the expression should consist of whitespace crud. Our */
+/* mission here is to check that it really does contain only whitespace crud */
+/* and return a text list containing the crud. If, on the other hand, it */
+/* contains meatier items, we have to call recover(). */
+p_ps_t p_ps; /* Position of the start of the expression. */
+p_ells_t p_ex; /* The expression that we have to check out. */
+p_scls_t *pp_white; /* The place to put the resultant whitespace list. */
+{
+ p_el_t p_el;
+
+ /* If the expression is empty, we can return an empty list. */
+ if (ls_len(p_ex)==0)
+ {
+ *pp_white=ls_cre(sizeof(sc_t));
+ return;
+ }
+
+ /* If there is more than one element, there is ...trouble. */
+ if (ls_len(p_ex) > 1) goto trouble;
+
+ /* Extract the first element of the list. */
+ ls_fir(p_ex); ls_nxt(p_ex,PPV &p_el);
+
+ /* If it's not text, there is ...trouble. */
+ if (p_el->el_kind != EL_TEXT) goto trouble;
+
+ /* If the text isn't lilly white, there is ...trouble. */
+ {
+ p_scls_t p_scls = p_el->el_text;
+ p_sc_t p_sc;
+ ls_fir(p_scls);
+ while (TRUE)
+ {
+ ls_nxt(p_scls,PPV &p_sc);
+ if (p_sc==NULL) break;
+ if (!p_sc->sc_white) goto trouble;
+ }
+ /* If we got this far, we know that the expression contains a single */
+ /* element and that that element is a text list and that that text */
+ /* list consists entirely of whitespace. We can now return it. */
+ *pp_white=p_scls;
+ return;
+ }
+
+ /* We COULD start dissecting the expression and issuing detailed specific */
+ /* error messages. However, the general approach is cleaner and so a general */
+ /* error message is used. */
+ trouble:
+ lr_err( p_ps,"Everything from here...");
+ lr_mes(TKPS,"...to here should be whitespace.");
+ lr_mes(TKPS,"Use of @\" to delimit macro parameters is optional, but");
+ lr_mes(TKPS,"if they are used, any surrounding text must be white.");
+ recover();
+}
+
+/******************************************************************************/
+
+LOCAL void pr_plist P_((p_elll_t *, p_scll_t *, p_scll_t *,p_ma_t));
+LOCAL void pr_plist(pp_plist,p_before,p_after,p_curmac)
+/* This function parses an optional parameter list. If the current token is */
+/* not TK_OPAR, then it is assumed that no list is present and no tokens are */
+/* consumed and empty lists are returned. */
+/* The three lists returned are: */
+/* A list of parameters each being a pointer to a list of elements. */
+/* A list of whitespace blocks being the space before each parameter. */
+/* A list of whitespace blocks being the space after each parameter. */
+/* The last parameter p_curmac should be supplied by the caller and should */
+/* contain a pointer to the macro currently being parsed. */
+p_elll_t *pp_plist;
+p_scll_t *p_before;
+p_scll_t *p_after;
+p_ma_t p_curmac;
+{
+ /* Initialize all the result lists to empty. */
+ *pp_plist = ls_cre(sizeof(p_ells_t));
+ *p_before = ls_cre(sizeof(p_scls_t));
+ *p_after = ls_cre(sizeof(p_scls_t));
+
+ /* The parameter list is optional. If it isn't there we assume a null one. */
+ if (p_tk->tk_kind!=TK_OPAR)
+ return;
+ next_tk(TRUE);
+
+ /* Now parse the parameter list, one parameter during each iteration. */
+ while (TRUE)
+ {
+ ps_t exp_ps;
+ p_ells_t p_ex;
+ p_scls_t p_white;
+
+ /* Things get a little tricky here because the double quotes around */
+ /* parameters are optional (per parameter). Thus the following calls are */
+ /* all legal (and functionally identical): */
+ /* @<Sloth@>@( @"walrus@" @, @"aardvark@" @) */
+ /* @<Sloth@>@(walrus@, @"aardvark@" @) */
+ /* @<Sloth@>@(walrus@,aardvark@) */
+
+ /* Note the position of the start of this parameter slot. */
+ ASSIGN(exp_ps,p_tk->tk_ps);
+
+ /* Because we face either crud text or an expression, we parse an exp. */
+ pr_exp(&p_ex,p_curmac);
+
+ /* Now take a look at the next token. If it is @" we know that we have */
+ /* been parsing whitespace crud. If it is @, or @) we know that we have */
+ /* been parsing the parameter expression itself. */
+ if (p_tk->tk_kind==TK_COMA || p_tk->tk_kind==TK_CPAR)
+ {
+ p_scls_t p_scls = ls_cre(sizeof(sc_t));
+ ls_add(*p_before,PV &p_scls); /* Add empty whitespace to crud list. */
+ ls_add(*pp_plist,PV &p_ex); /* Add expression to parameter list. */
+ ls_add(*p_after ,PV &p_scls); /* Add empty whitespace to crud list. */
+ }
+ else
+ if (p_tk->tk_kind==TK_QUOT)
+ {
+ /* After parsing the expression we hit a @". This means that the */
+ /* expression just parsed SHOULD turn out to contain a single */
+ /* element consisting of a white space text list. */
+ chk_whex(&exp_ps,p_ex,&p_white);
+ ls_add(*p_before,PV &p_white);
+
+ /* Get past the quote. */
+ next_tk(TRUE);
+
+ /* Parse the expression and add it to the parameter list. */
+ pr_exp(&p_ex,p_curmac); ls_add(*pp_plist,PV &p_ex);
+
+ /* Parse the quote to move onto the whitespace. */
+ pr_token(TK_QUOT);
+
+ /* Parse the whitespace after the parameter. */
+ {p_scls_t p_white; pr_white(&p_white); ls_add(*p_after,PV &p_white);}
+ }
+ else
+ {lr_err(TKPS,"Expecting @\" or @, or @)."); recover();}
+
+ /* The parameter list can now end (TK_CPAR) or continue (TK_COMA). */
+ if (p_tk->tk_kind==TK_COMA)
+ next_tk(TRUE);
+ else
+ if (p_tk->tk_kind==TK_CPAR)
+ {next_tk(TRUE);return;}
+ else
+ {lr_err(TKPS,"Expecting @, or @)."); recover();}
+ } /* End while */
+}
+
+/******************************************************************************/
+
+LOCAL void pr_invelt P_((p_el_t,p_ma_t));
+LOCAL void pr_invelt(p_el,p_curmac)
+/* Parses an "invocation element" which is just FunnelWebSpeak for "macro */
+/* call". Upon entry the current token must be TK_ONAM or TK_NAME which */
+/* presumably is the start of a macro call. Returns a pointer to an element */
+/* object describing the call. Does some other macro table stuff too. */
+/* p_curmac should be supplied by the caller and should be a pointer to the */
+/* macro currently being parsed. */
+p_el_t p_el;
+p_ma_t p_curmac;
+{
+ name_t name; /* Name of the macro being invoked. */
+ ps_t mc_ps; /* Position of the start of the macro invocation. */
+ mc_t mc; /* Macro call object that describes the invocation. */
+ p_ma_t p_callee; /* Pointer to the macro object of the target macro. */
+ p_elll_t parlist; /* The parameter list of the invocation. */
+ p_scll_t before; /* Whitespace before each parameter in the param list. */
+ p_scll_t after; /* Whitespace after each parameter in the param list. */
+
+ /* We shouldn't have been called unless we have seen the start of a name. */
+ ass_tks(TK_ONAM,TK_NAME);
+
+ /* Note the position of the start of the invocation. */
+ mc_ps=p_tk->tk_ps;
+
+ /* Parse the invocation (name and optional parameter list). */
+ pr_name(name); pr_plist(&parlist,&before,&after,p_curmac);
+
+ /* Ensure that there is an entry for this macro name in the macro table. */
+ rem_name(name);
+
+ /* Construct a macro call object describing the call and add it to the */
+ /* callee macro's call list. */
+ /* Note: The +1 in sequence+1 is because the sequence number is incremented */
+ /* at the end of each macro definition and we are only halfway here. */
+ mc.mc_seq = sequence+1;
+ mc.mc_ps = mc_ps;
+ mc.mc_npar = ls_len(parlist);
+ tb_loo(macro_table,PV name,PV &p_callee);
+ ls_add(p_callee->ma_calls,PV &mc);
+
+ /* Write an invocation element describing the call to the parameter. */
+ p_el->el_kind = EL_INVC;
+ p_el->el_p_mac = p_callee;
+ p_el->el_parls = parlist;
+ p_el->el_pretx = before;
+ p_el->el_postx = after;
+}
+
+/******************************************************************************/
+
+LOCAL void pr_txtelt P_((p_el_t));
+LOCAL void pr_txtelt(p_el)
+/* Parses a text element. Upon entry, the current token must be of type */
+/* TK_TEXT. Writes a text element into its parameter. */
+p_el_t p_el;
+{
+ p_scls_t p_scls;
+ bool dummy;
+ ass_tk(TK_TEXT);
+ pr_text(&p_scls,&dummy);
+ p_el->el_kind = EL_TEXT;
+ p_el->el_text = p_scls;
+}
+
+/******************************************************************************/
+
+LOCAL void pr_parelt P_((p_el_t,p_ma_t));
+LOCAL void pr_parelt(p_el,p_curmac)
+/* Parses a parameter element (e.g. @5). Writes the resultant parameter */
+/* element object to the first parameter. The second parameter should be */
+/* supplied by the caller and should be a pointer to the macro being parsed. */
+p_el_t p_el;
+p_ma_t p_curmac;
+{
+ /* We have to be sitting on a parameter token. */
+ ass_tk(TK_PARM);
+
+ /* Complain if the parameter does not exist. */
+ if (p_tk->tk_gen > p_curmac->ma_defn.md_npar)
+ {
+ sprintf(linet1,"Macro being defined has only %lu parameter%s.",
+ (unsigned long) p_curmac->ma_defn.md_npar,
+ p_curmac->ma_defn.md_npar==1 ? "" : "s");
+ lr_err(TKPS,linet1);
+ }
+
+ /* Write a parameter element to the function parameter. */
+ p_el->el_kind = EL_PARM;
+ p_el->el_parno = p_tk->tk_gen;
+ p_el->el_which = p_curmac;
+
+ /* Move on to the token following the parameter token. */
+ next_tk(TRUE);
+}
+
+/******************************************************************************/
+
+LOCAL void pr_exp(p_ex,p_curmac)
+/* Parses an expression and writes an expression list to the first parameter. */
+/* The second parameter should be supplied by the user and should be a */
+/* pointer to the macro currently being parsed. */
+p_ells_t *p_ex;
+p_ma_t p_curmac;
+{
+ p_ells_t ex = ls_cre(sizeof(el_t));
+
+ while (TRUE)
+ {
+ el_t el;
+ switch (p_tk->tk_kind)
+ {
+ case TK_TEXT: pr_txtelt(&el); break;
+ case TK_NAME:
+ case TK_ONAM: pr_invelt(&el,p_curmac); break;
+ case TK_PARM: pr_parelt(&el,p_curmac); break;
+ default : *p_ex=ex; return;
+ }
+ ls_add(ex,PV &el);
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void pr_formal P_((uword *,p_ps_t));
+LOCAL void pr_formal(p_numpar,p_ps)
+/* A FunnelWeb formal parameter list looks something like this: "@(@5@)". */
+/* This function parses a parameter list if present and returns the number of */
+/* parameters in the formal parameter list. The function also returns the */
+/* position the parameter list. */
+uword *p_numpar;
+p_ps_t p_ps;
+{
+ /* If the parameter list is absent, we default to having zero parameters and */
+ /* making the position of the parameter list the position of the next token. */
+ *p_numpar = 0;
+ *p_ps = p_tk->tk_ps;
+
+ /* Parse the parameter list only if one is present. */
+ if (p_tk->tk_kind==TK_OPAR)
+ {
+ /* Move to the parameter token and get its number and position. */
+ next_tk(TRUE);
+ check_tk(TK_PARM);
+ *p_numpar=p_tk->tk_gen;
+ *p_ps=p_tk->tk_ps;
+
+ /* Parse the end of the formal parameter list. */
+ next_tk(TRUE);
+ pr_token(TK_CPAR);
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void pr_number P_((bool *,bool *));
+LOCAL void pr_number(p_iszer,p_isman)
+/* Parses optional @Z@M after parameter list. */
+bool *p_iszer;
+bool *p_isman;
+{
+ *p_iszer=FALSE;
+ *p_isman=FALSE;
+
+ /* The following parse allows zero, one or both of @Z@M, but in order. */
+
+ /* Grab an @Z if it is there. */
+ if (p_tk->tk_kind==TK_ZERO)
+ {
+ next_tk(TRUE);
+ *p_iszer=TRUE;
+ }
+
+ /* Grab an @M too if it is there. */
+ if (p_tk->tk_kind==TK_MANY)
+ {
+ next_tk(TRUE);
+ *p_isman=TRUE;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void pr_equals P_((bool *,p_ps_t));
+LOCAL void pr_equals(isadd,p_ps)
+/* Parses optional "==" or "+=". Sets *isadd==TRUE iff "+=" parsed else FALSE.*/
+/* Sets *p_ps to the position of the equals. */
+bool *isadd;
+p_ps_t p_ps;
+{
+ p_scls_t p_scls;
+ bool dummy;
+
+ /* Grab a copy of the position of the equals (even if it is not there) . */
+ ASSIGN(*p_ps,p_tk->tk_ps);
+
+ /* If the equals isn't there, we default to FALSE. */
+ *isadd=FALSE;
+ if (p_tk->tk_kind!=TK_TEXT) return;
+
+ /* Parse text tokens producing a text list. */
+ pr_text(&p_scls,&dummy);
+
+ /* Compare the text list with the assignment constant strings. */
+ if (eq_txst(p_scls,"==")) {*isadd=FALSE; ls_des(p_scls); return;}
+ if (eq_txst(p_scls,"+=")) {*isadd=TRUE; ls_des(p_scls); return;}
+
+ lr_err(p_ps,"Expecting \"==@{\" or \"+=@{\" or just \"@{\".");
+ lr_mes(p_ps,"(or @Z or @M if they have not already appeared).");
+ lr_mes(p_ps,"Note: FunnelWeb is intolerant of spaces at this point.");
+ ls_des(p_scls);
+ recover();
+}
+
+/******************************************************************************/
+
+LOCAL bool checkdef P_((p_ma_t,bool,ulong,bool,bool,bool,
+ p_ps_t,p_ps_t,p_ps_t,p_ps_t));
+LOCAL bool checkdef (p_ma,is_file,numpar,iszer,isman,isadd,
+ p_psnam,p_psfor,p_pseql,p_psnum)
+/* This function performs all sorts of checks on a macro definition. */
+/* If there is anything wrong, it generates and error and calls recover(). */
+/* This would be best as a local function but because C doesn't have local */
+/* functions we have to use millions of parameters instead. */
+p_ma_t p_ma;
+bool is_file;
+ulong numpar;
+bool iszer;
+bool isman;
+bool isadd;
+p_ps_t p_psnam;
+p_ps_t p_psfor;
+p_ps_t p_pseql;
+p_ps_t p_psnum;
+{
+ bool semerr = FALSE;
+
+ /* CHECK INTERNAL INCONSISTENCIES */
+ /* ------------------------------ */
+ /* Complain if a file macro has a parameter list. */
+ if (is_file && numpar>0)
+ {
+ lr_err(p_psfor,"Macros attached to output files cannot be parameterized.");
+ lr_mes(p_psfor,"Reason: No actual parameters would be available during");
+ lr_mes(p_psfor," output file generation.");
+ semerr=TRUE;
+ }
+
+ /* Complain if a file macro is declared additive. */
+ if (is_file && isadd)
+ {
+ lr_err(p_pseql,"Macros attached to output files cannot be additive.");
+ lr_mes(p_pseql,"Reason: Preventing this makes it easy to find output");
+ lr_mes(p_pseql,"file macros later, because there will be exactly one");
+ lr_mes(p_pseql,"@O declaration in the input file for each output file.");
+ lr_mes(p_pseql,"To do what you are trying to do, just create an additive");
+ lr_mes(p_pseql,"bridging macro, like this:");
+ lr_mes(p_pseql," @O@<prog.c@>@{@<Bridge@>@}");
+ lr_mes(p_pseql," @$@<Bridge@>+=@{void stringhack()...@}");
+ lr_mes(p_pseql," @$@<Bridge@>+=@{main()...@}");
+ semerr=TRUE;
+ }
+
+ /* Complain if a file macro has a name that is too long. */
+ if (is_file && strlen(&p_ma->ma_name[0])>FILENAME_FWMAX)
+ {
+ lr_err(p_psnam,
+ "File macro's name is longer than the maximum permissible filename length.");
+ sprintf(linet1,"Maximum filename length is %lu characters.",
+ (unsigned long) FILENAME_FWMAX);
+ lr_mes(p_psnam,linet1);
+ semerr=TRUE;
+ }
+
+ /* Complain if a file macro has "zero" or "many" attributes. */
+ if (is_file && (iszer || isman))
+ {
+ lr_err(p_psnum,"Macros attached to output files cannot have @Z or @M.");
+ lr_mes(p_psnum,"Reason: They are always called once to generate their");
+ lr_mes(p_psnum,"output file and they cannot be called from other macros.");
+ lr_mes(p_psnum,"Hence they are always called exactly once and so there");
+ lr_mes(p_psnum,"can be no need for @Z or @M in their declarations.");
+ semerr=TRUE;
+ }
+
+ /* COMPARE WITH EARLIER DEFINITIONS */
+ /* -------------------------------- */
+ /* Don't do this section if no previous definition exists. */
+ if (!p_ma->ma_defn.md_isdef) goto finish;
+
+ /* Assert: An earlier definition of this macro exists. */
+
+ /* Old definition is a full definition, not admitting partial ones now. */
+ if (!p_ma->ma_defn.md_isadd)
+ {
+ if (isadd)
+ {
+ sprintf(linet1,"A full definition of this macro appears at line %lu.",
+ (ulong) p_ma->ma_defn.md_ps.ps_line);
+ lr_err(p_psnam,linet1);
+ lr_mes(p_psnam,"Full and additive definitions of the same macro cannot coexist.");
+ }
+ else
+ {
+ sprintf(linet1,"This macro is already fully defined (at line %lu).",
+ (ulong) p_ma->ma_defn.md_ps.ps_line);
+ lr_err(p_psnam,linet1);
+ }
+ semerr=TRUE;
+ }
+
+ /* Old definition is partial but new definition is full. */
+ if (p_ma->ma_defn.md_isadd && !isadd)
+ {
+ sprintf(linet1,"An additive definition of this macro appears at line %lu.",
+ (ulong) p_ma->ma_defn.md_ps.ps_line);
+ lr_err(p_psnam,linet1);
+ lr_mes(p_psnam,"Full and additive definitions of the same macro cannot coexist.");
+ semerr=TRUE;
+ }
+
+ /* Make sure that non-first body parts of additive macros do not have params.*/
+ if (isadd && (numpar>0))
+ {
+ lr_err(p_psfor,"The formal parameter list of an additive macro");
+ lr_mes(p_psfor,"must be placed only in the first definition part.");
+ sprintf(linet1,"The first part of this macro appears at line %lu.",
+ (ulong) p_ma->ma_defn.md_ps.ps_line);
+ lr_mes(p_psfor,linet1);
+ semerr=TRUE;
+ }
+
+ /* Complain if number attributes are being attached to an additive. */
+ if (isadd && (iszer || isman))
+ {
+ lr_err(p_psnum,"@Z and @M modifiers for additive macros must");
+ lr_mes(p_psnum,"be placed only in the first definition part.");
+ sprintf(linet1,"The first part of this macro appears at line %lu.",
+ (ulong) p_ma->ma_defn.md_ps.ps_line);
+ lr_mes(p_psnum,linet1);
+ semerr=TRUE;
+ }
+
+ finish:
+ if (semerr)
+ {
+ lr_mes(p_psnam,"Macro definition ignored.");
+ recover();
+ }
+ return TRUE;
+}
+
+/******************************************************************************/
+
+LOCAL void pr_macro P_((void));
+LOCAL void pr_macro()
+/* This function parses a single macro definition. Upon entry, the current */
+/* token must be either TK_MDEF or TK_FDEF. */
+{
+ ps_t ps_mac; /* Position of start of the macro definition. */
+ bool is_file; /* TRUE iff definition starts with @O instead of @$. */
+ name_t name; /* The macro name appearing in this definition. */
+ p_ma_t p_ma; /* Pointer to the macro record corresponding to 'name'. */
+ ps_t ps_name; /* Position of the macro name. */
+ ps_t ps_form; /* Position of the formal parameter list. */
+ ps_t ps_equal; /* Position of the equals. */
+ ps_t ps_num; /* Position of number attributes. */
+ uword numpar; /* Number of parameters in formal parameter list. */
+ bool iszer; /* TRUE iff macro is allowed to be called zero times. */
+ bool isman; /* TRUE iff macro is allowed to be called more than once. */
+ bool isadd; /* TRUE iff equals parsed here is "+=" not "==". */
+ p_ells_t ex; /* Expression constituting this macro body part. */
+ bool hasname; /* TRUE iff current section already has a name. */
+
+ /* We should not have got in here without seeing a definition token. */
+ ass_tks(TK_MDEF,TK_FDEF);
+
+ /* Grab a copy of the position of the start of the macro. */
+ ASSIGN(ps_mac,p_tk->tk_ps);
+
+ /* If we have seen a macro definition token then it means that the user is */
+ /* TRYING to define a macro. The macro may or may not provoke errors. In */
+ /* either case though we do not want to hassle the user with errors about */
+ /* nameless sections not containing macros if it is obvious that an attempt */
+ /* to define a macro has been made. So here we set the name flag after */
+ /* having a look at it so we can use its value later. */
+ if (sn_lev(&last_sn)>0)
+ {
+ as_cold(p_secdc->dc_kind==DC_TYPE,"pr_macro: section processing error (1).");
+ as_cold(p_secdc->dc_ty.ty_kind==TY_NSEC,"pr_macro: section processing error (2).");
+ hasname=p_secdc->dc_ty.ty_isnam;
+ p_secdc->dc_ty.ty_isnam=TRUE;
+ }
+
+ /* Record whether the macro is attached to an product file. */
+ is_file= (p_tk->tk_kind==TK_FDEF);
+
+ /* Parse the macro name. Record its position. Ensure that there is an entry */
+ /* in the macro table for this macro name (i.e. create one if not there). */
+ next_tk(TRUE);
+ if (p_tk->tk_kind!=TK_ONAM && p_tk->tk_kind!=TK_NAME)
+ {
+ lr_err(TKPS,"Macro name expected (@<...@> or @#c).");
+ recover();
+ }
+ ps_name=p_tk->tk_ps;
+ pr_name (name);
+ rem_name(name);
+ tb_loo(macro_table,PV name,PV &p_ma);
+
+ /* Parse the optional formal parameter list and the equals. */
+ /* Extract positioning and other information. */
+ pr_formal(&numpar,&ps_form );
+ ASSIGN(ps_num,p_tk->tk_ps);
+ pr_number(&iszer, &isman);
+ pr_equals(&isadd ,&ps_equal);
+
+ /* Perform semantic checks on whether this definition is valid. */
+ checkdef(p_ma,is_file,numpar,iszer,isman,isadd,
+ &ps_name,&ps_form,&ps_equal,&ps_num);
+
+ /* If we have got this far, we know that we have parsed a valid macro */
+ /* definition except possibly for the actual expression body. */
+ /* If this is the first definition of this macro, establish its definition. */
+ if (!p_ma->ma_defn.md_isdef)
+ {
+ p_ma->ma_defn.md_isdef = TRUE;
+ ASSIGN(p_ma->ma_defn.md_ps,ps_mac);
+ p_ma->ma_defn.md_npar = numpar;
+ p_ma->ma_defn.md_isadd = isadd;
+ p_ma->ma_defn.md_iszer = iszer;
+ p_ma->ma_defn.md_isman = isman;
+ p_ma->ma_defn.md_isfil = is_file;
+ p_ma->ma_defn.md_body = ls_cre(sizeof(bp_t));
+ if (is_file) tb_ins(file_table,PV name,PV &p_ma);
+ }
+
+ /* Parse the body of this macro definition. */
+ pr_token(TK_ODEF); pr_exp(&ex,p_ma); pr_token(TK_CDEF);
+
+ /* We are now clear to execute the effects of the macro on our tables. */
+ /* First we bump up the sequence number. */
+ sequence++;
+
+ {
+ /* Construct a body part object containing the information in this */
+ /* definition and append it to the list of body parts in the macro record. */
+ bp_t bp;
+ bp.bp_ex = ex;
+ bp.bp_seq = sequence;
+ bp.bp_ps = ps_name;
+ ls_add(p_ma->ma_defn.md_body,PV &bp);
+ }
+
+ {
+ /* Construct a document component object for this definition and append it */
+ /* to the global document component list. */
+ dc_t dc;
+ ASSIGN(dc.dc_ps,ps_mac);
+ dc.dc_kind = DC_MACR;
+ dc.dc_p_ma = p_ma;
+ dc.dc_part = ls_len(p_ma->ma_defn.md_body);
+ ls_add(document_list,PV &dc);
+ }
+
+ /* Sections without names inherit the name of their first macro. */
+ if (sn_lev(&last_sn)>0 && !hasname)
+ strcpy(&p_secdc->dc_ty.ty_name[0],name);
+}
+
+/******************************************************************************/
+
+EXPORT void parser()
+/* This is the main parser function. This function contains parser */
+/* initialization as well as the main parsing loop to which control is */
+/* returned (by recover()) when an error occurs. */
+{
+ /* Create the lists and tables generated by the parser. */
+ macro_table = tb_cre (sizeof(name_t),sizeof(p_ma_t),(p_kycm_t) cm_name);
+ file_table = tb_cre (sizeof(name_t),sizeof(p_ma_t),(p_kycm_t) cm_name);
+ document_list= ls_cre (sizeof(dc_t));
+
+ /* Initialize the section number counter. */
+ sequence = 0;
+ sn_ini(&last_sn);
+ p_secdc = NULL;
+
+ /* Prime the scanning of the token list. */
+ ls_fir(token_list);
+ next_tk(FALSE);
+
+ /* This is where we longjmp back to after hitting a nasty syntax error. */
+ /* We don't actually have to test dummyint, as our control state is no */
+ /* different after a syntax error has occurred. Example: We try to parse */
+ /* a macro but there is a syntax error. So we skip to the start of the */
+ /* next macro and then longjmp back to here ready to parse the next */
+ /* macro. Thus, there is no need to a fork test. */
+ (void) setjmp(jmp_pos);
+
+ /* This is the main parser loop which parses major syntactic chunks. */
+ while (p_tk->tk_kind != TK_EOF)
+ switch (p_tk->tk_kind)
+ {
+ case TK_NSEC: pr_sec (); break;
+ case TK_TEXT: pr_dctxt(); break;
+ case TK_MDEF: pr_macro(); break;
+ case TK_FDEF: pr_macro(); break;
+ case TK_ODEF: pr_lit (); break;
+ case TK_EMPH: pr_emp (); break;
+ case TK_NPAG: pr_npag (); break;
+ case TK_TOCS: pr_tocs (); break;
+ case TK_SKIP: pr_skip (); break;
+ case TK_TITL: pr_titl (); break;
+ default:
+ lr_err(TKPS,"The parser was at the top level and was expecting");
+ lr_mes(TKPS,"one of: {Directive, Text, Macro definition, EOF}.");
+ next_tk(FALSE);
+ break;
+ }
+
+}
+
+/******************************************************************************/
+/* End of PARSER.C */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/parser.h b/web/funnelAC/sources/parser.h
new file mode 100644
index 0000000000..687a5bbf23
--- /dev/null
+++ b/web/funnelAC/sources/parser.h
@@ -0,0 +1,65 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* PARSER.H */
+/******************************************************************************/
+/* */
+/* The FunnelWeb parser parses the tokens in the global token list and */
+/* constructs a macro table and a document list. These two data structures */
+/* give structured views of the input document which are used later by tangle */
+/* and weave. If the parser detects any errors it sends them to the lister */
+/* package. If any errors have occurred, the output of the parser should not */
+/* be used. */
+/* */
+/* IN : token_list - List of tokens to be parsed. */
+/* OUT: macro_table - Table of macros parsed. */
+/* file_table - Table indicating which macros are attached to files. */
+/* document_list - List giving a structured view of the document. */
+/* Also sends diagnostic messages to the lister. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+EXPORT void parser P_((void));
+
+/******************************************************************************/
+/* End of PARSER.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/scanner.c b/web/funnelAC/sources/scanner.c
new file mode 100644
index 0000000000..0bc057e57c
--- /dev/null
+++ b/web/funnelAC/sources/scanner.c
@@ -0,0 +1,1824 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* SCANNER.C */
+/******************************************************************************/
+/* */
+/* Introduction */
+/* ------------ */
+/* The FunnelWeb scanner is a little messy because it deals with two */
+/* structures at the same time while attempting to be efficient. On the one */
+/* hand it is busy constructing the line list. This means that it has to keep */
+/* an eye out for end of line characters ('\n'=EOL) so that it can add a line */
+/* record whenever it sees one. On the other hand, it has to scan the input */
+/* file into a token stream consisting of text tokens and special tokens */
+/* which usually have no regard for end of lines. It is tempting to divide */
+/* these two functions up (into perhaps a LINER and a TOKENIZER). However, */
+/* the presence of the include file facility would make this messy. Also, the */
+/* tokenizer has to count end of line markers so that it can generate */
+/* correctly positioned diagnostics. */
+/* */
+/* The long and short of it all is that the best way to do the scanning seems */
+/* to be to run a liner and a tokenizer as parallel layers. The liner */
+/* extracts characters from the input file and hands them to the tokenizer. */
+/* It also keeps an eye out for newline characters, sending a line record off */
+/* whenever it sees one, and counting lines. The tokenizer receives the */
+/* characters from the liner and performs the tokenize operation. */
+/* */
+/* Notes */
+/* ----- */
+/* - Currently FunnelWeb recognises only two characters as whitespace. */
+/* These are ' ' and EOL. */
+/* */
+/******************************************************************************/
+
+#include <ctype.h>
+#include <limits.h>
+#include "style.h"
+
+#include "as.h"
+#include "clock.h"
+#include "data.h"
+#include "dump.h"
+#include "list.h"
+#include "lister.h"
+#include "machin.h"
+#include "mapper.h"
+#include "memory.h"
+#include "misc.h"
+#include "option.h"
+#include "scanner.h"
+
+/******************************************************************************/
+
+/* The "special" character is the character that is used to introduce a */
+/* "special sequence". FunnelWeb allows the user to change this character so */
+/* as to cater for documents where the "default" character is common. This */
+/* definition defines what the default character is. */
+#define CH_DSPE ('@')
+
+/* FunnelWeb allows include files which are handled by the scanner by placing */
+/* recursive calls to scan_file. A maximum is placed on the level of nested */
+/* includes. This acts as a good sanity check as well as catching recursive */
+/* include files which are never a sensible construct in FunnelWeb as */
+/* FunnelWeb does not provide any conditional construct. */
+#define MAX_INCL (10)
+
+/* FunnelWeb is very conservative about what characters it will allow in its */
+/* input and output files. Currently the only characters allowed are */
+/* printables and end of lines. When FunnelWeb does spot an illegal character */
+/* it needs to be able to draw the user's attention to the character. The */
+/* best way to do this is to point to it in the listing file. However, if the */
+/* character is banned, it cannot appear in the listing file! The problem is */
+/* solved by having the scanner replace all illegal characters in each mapped */
+/* file by the following character. This eliminates further problems. */
+#define CENSORCH ('?')
+
+/* Following the Unix convention, mapped in files are not terminated with an */
+/* end-of-file character. However, the presence of such a character at the */
+/* end of the mapped file simplifies scanning and so we add one. This */
+/* definition defines what the character is to be. It doesn't matter what the */
+/* character is, so long as it cannot legally appear in the file. A control */
+/* character is a good choice as these are filtered out by the liner (see */
+/* above). */
+/* We undef EOF (from <stdio.h>) because it is too dangerously close to EOFCH.*/
+/* (EOF wasn't redefined as that might confuse readers used to <stdio.h>. */
+/* However, we still use EOF as an acronym for End Of File. */
+#define EOFCH (26)
+#undef EOF
+
+/* Tokens have a field for a general attribute which has meaning for some */
+/* token kinds. For other kinds, it has no meaning. This constant is used to */
+/* indicate a "don't care" value. */
+#define DONTCARE 0
+
+/* A nominal maximum value for the maximum length of an input line. */
+#define INMAXINF (ULONG_MAX)
+
+/******************************************************************************/
+
+/* The following type is used in the suite of pragma routines for parsing. */
+typedef
+ struct
+ {
+ ps_t pt_ps; /* Position of the start of this argument. */
+ char *pt_pstr; /* Pointer to a string containing the argument. */
+ char *pt_pinl; /* Pointer to first byte of the argument in commndline. */
+ } pt_t;
+typedef pt_t *p_pt_t;
+
+/******************************************************************************/
+
+ /* Variables Instantiated Over The Entire Scan */
+ /* ------------------------------------------- */
+LOCVAR p_ck_t p_mapp; /* Pointer to mapper's clock. */
+LOCVAR p_ck_t p_scan; /* Pointer to scanner's clock. */
+LOCVAR ulong globalno; /* Global line number of line being scanned. */
+LOCVAR ulong inclevel; /* Include level of current file. Top file is zero. */
+LOCVAR bool seenind; /* TRUE iff we have seen an indentation pragma. */
+LOCVAR ps_t ps_ind; /* seenind==TRUE => ps_ind is position of pragma. */
+LOCVAR bool seentyp; /* TRUE iff we have seen a typesetter pragma. */
+LOCVAR ps_t ps_typ; /* seentyp==TRUE => ps_typ is position of pragma. */
+LOCVAR bool seenlimo; /* TRUE iff we have seen an out lin len limit pragma. */
+LOCVAR ps_t ps_limo; /* seenlimo==TRUE => ps_limo is position of pragma. */
+
+ /* Variables Instantiated Over The Current File */
+ /* -------------------------------------------- */
+LOCVAR ulong inln_max; /* Maximum permitted length of an input line. */
+LOCVAR char specialch; /* Current special (escape) character. */
+LOCVAR char *p_eof; /* Pointer to EOFCH byte at the end of current file. */
+LOCVAR ulong localno; /* Local line number of line being scanned. */
+
+ /* Variables Instantiated Over The Current Line */
+ /* -------------------------------------------- */
+LOCVAR char *p_sol; /* Pointer to Start (first char) Of current Line. */
+LOCVAR char *p_ch; /* Pointer to current character in current line. */
+LOCVAR char ch; /* *p_ch. */
+
+/******************************************************************************/
+/* Line Processing Layer */
+/******************************************************************************/
+/* */
+/* This mini-section contains the two routines (prepline and NEXTCH) that */
+/* take care of the line based-scanning and feed characters to the */
+/* token-based scanner routines which have the top level of control. */
+/* After mapping in a file to be read, place a call to prepline passing the */
+/* address of the first byte of the mapped file as an argument. At that */
+/* point the current position will be the first byte on the first line and */
+/* the "variables instantiated over the current line" will be well defined. */
+/* Calls to NEXTCH then move the position through the mapped file one byte at */
+/* a time, stopping at the end of file at which point calls will not move the */
+/* marker which will point to the EOF character. */
+/* */
+/******************************************************************************/
+
+LOCAL void prepline P_((char *));
+LOCAL void prepline(p_line)
+/* This function should be called at the end of each line to prepare the next */
+/* line for scanning. The user of the liner mini-package should place a */
+/* single call to this function at the start of scanning a mapped file. */
+/* The user should then place calls to NEXTCH (which calls prepline when */
+/* necessary). */
+/* This function serves two purposes: */
+/* 1. It looks at the next line and converts all non-printables into */
+/* CENSORCH and issues errors for each non-printable. */
+/* 2. It initializes the line scanning variables for the next line. */
+/* The argument is a pointer to the first byte of the next line. */
+char *p_line;
+{
+ char *p; /* Scans through the line and winds up sitting on the EOL. */
+
+ /* Test to see if the "line" we have been given is the end of file marker. */
+ /* We have to be careful here because the byte we are using to mark the end */
+ /* of file could appear as an illegal unprintable. This is the reason for */
+ /* the test p_line==p_eof. */
+ if (*p_line==EOFCH && p_line==p_eof)
+ {
+ /* The line we have to process is in fact the end of file marker. */
+ p_sol = p_line;
+ p_ch = p_line;
+ ch = EOFCH;
+ return;
+ }
+
+ /* At this point we know that we are faced with a run of bytes terminated by */
+ /* an EOL character (we know this cos we put an EOL before EOF earlier on). */
+ /* We know that we have a line, so we can now bump up the line counters. */
+ globalno++;
+ localno++;
+
+ /* Run through the line checking for non-printables and issuing errors. */
+ p = p_line;
+ while (*p != EOL)
+ {
+ /* The following test tests to see if the character is a printable in */
+ /* seven bit ascii. FunnelWeb is not currently designed to work with */
+ /* any character set other than seven-bit ascii and so we flag and */
+ /* convert all out-of-range characters here before they are exposed to */
+ /* the rest of the scanner code which assumes that each line that it is */
+ /* handed consists entirely of printables except for the EOL char on the */
+ /* end and possibly an EOF char at the "Start" of a line. */
+ /* In particular, the NEXTCH macro will fail on machines with siged */
+ /* chars if non-printables are not removed. It goes into an infinite */
+ /* loop. */
+ /* Note: I don't use library function "isprint" here because on the vax */
+ /* it's definition is too loose (seems to accept characters with the top */
+ /* bit set as printable). */
+ if (!isascprn(*p)) /* If not a printable character. */
+ {
+ ps_t ps;
+ char c = *p;
+ ubyte_ uc = *((ubyte_ *) p);
+ ps.ps_line = globalno;
+ ps.ps_column = p-p_line+1;
+ if (strlen(chabbrev(c))==0)
+ sprintf(linet1,
+ "Non printable character (Sym=<none>, Dec=%03u, Hex=%02X, Oct=%03o).",
+ (unsigned) uc,(unsigned) uc,(unsigned) uc);
+ else
+ sprintf(linet1,
+ "Non printable character (Sym=%s, Dec=%03u, Hex=%02X, Oct=%03o).",
+ chabbrev(c),(unsigned) uc,(unsigned) uc,(unsigned) uc);
+ lr_err(&ps,linet1);
+ *p=CENSORCH;
+ }
+ p++;
+ }
+ /* Assert: p_line points to the start of the current line. */
+ /* Assert: p points to the EOL at the end of the current line. */
+
+ /* Check that the line is not too long. */
+ if ((p-p_line)>inln_max)
+ {
+ ps_t ps;
+ ps.ps_line = globalno;
+ ps.ps_column = inln_max+1;
+ lr_err(&ps,"Input line is too long (this character is the first offender).");
+ sprintf(linet1,"Currently, the maximum allowable input line length is %lu.",
+ (unsigned long) inln_max);
+ lr_mes(&ps,linet1);
+ lr_mes(&ps,"Note: You can change this using a pragma directive (@p).");
+ }
+
+ /* Now check for trailing spaces. */
+ if ((p != p_line) && (*(p-1) == ' '))
+ {
+ ps_t ps;
+ ps.ps_line = globalno;
+ ps.ps_column = p-p_line;
+ lr_war(&ps,"Line has trailing spaces up to and including this space.");
+ }
+
+ /* Construct a line record and append the record to the line list. */
+ /* Note that the line scrap encompasses the trailing EOL. */
+ {
+ ln_t line;
+ line.ln_global = globalno;
+ line.ln_local = localno;
+ line.ln_body.sc_first = p_line;
+ line.ln_body.sc_last = p;
+ /* Note: We do not set sc_white as it is not used in lines. */
+ ls_add(line_list,PV &line);
+ }
+
+ /* Finally, set the line scanning variables to the start of the line. */
+ /* We can't do this earlier in case the start of the line was a */
+ /* non-printable and got substituted (ch might pick it up). */
+ p_sol = p_line;
+ p_ch = p_line;
+ ch = *p_line;
+
+} /* End of prepline. */
+
+/* NEXTCH can be called continuously after an initializing call to prepline. */
+/* After a call to NEXTCH, p_sol, p_ch, ch are all well-defined. p_sol points */
+/* to the start of the current line, p_ch points to the current character, */
+/* and ch contains *p_ch. NEXTCH can be called repeatedly forever. When it */
+/* hits the EOF character, it sticks on it and returns it forever. */
+/* Note: The "ch<' '" is an optimized form of "(ch==EOL)||(ch=EOFCH)". Speed */
+/* is very important here as this macro is called in scanning tightloops. */
+/* This line of code is a little tricky so read it carefully. */
+/* WARNING: The ch<' ' will cause an infinite loop if a character appears */
+/* that satisfies this condition without being EOF or EOL (e.g. a control */
+/* char (meant to be filtered out earlier) or a top-bit-set character on */
+/* machines with signed character type. */
+#define NEXTCH {if (ch<' ') {if (ch==EOL) prepline(p_ch+1);} else ch= *++p_ch;}
+
+/******************************************************************************/
+/* Scanner Support Routines */
+/******************************************************************************/
+
+LOCAL ps_t *psofch P_((void));
+LOCAL ps_t *psofch()
+/* Returns a pointer to an internal static ps structure holding the line and */
+/* column number of the current character ch. */
+{
+ STAVAR ps_t chps;
+ chps.ps_line = globalno;
+ chps.ps_column = p_ch-p_sol+1;
+ return &chps;
+}
+
+/******************************************************************************/
+
+LOCAL void grabchps P_((p_ps_t));
+LOCAL void grabchps(p_ps)
+/* Writes the position of the current ch into the argument position struct. */
+p_ps_t p_ps;
+{
+ p_ps->ps_line = globalno;
+ p_ps->ps_column = p_ch-p_sol+1;
+}
+
+/******************************************************************************/
+
+LOCAL void sendspec P_((p_ps_t,tk_k_t,ubyte));
+LOCAL void sendspec(p_tkps,tk_kind,tk_gen)
+/* Appends a non-text token of kind tk_kind to the end of the token list. */
+/* p_ps is a pointer to a position structure giving the position of the */
+/* first character of the token. tk_gen is the general token attribute. */
+p_ps_t p_tkps;
+tk_k_t tk_kind;
+ubyte tk_gen;
+{
+ tk_t token;
+ token.tk_kind = tk_kind;
+ ASSIGN(token.tk_ps,*p_tkps);
+ token.tk_sc.sc_first = NULL;
+ token.tk_sc.sc_last = NULL;
+ token.tk_sc.sc_white = TRUE;
+ token.tk_gen = tk_gen;
+ ls_add(token_list,PV &token);
+}
+
+/******************************************************************************/
+
+LOCAL void sendtext P_((p_ps_t,char *,char *,bool));
+LOCAL void sendtext(p_tkps,p_first,p_last,is_white)
+/* Appends a text token to the end of the token list. */
+/* IN: p_ps is a pointer to a position structure giving the position of the */
+/* first character of the token. */
+/* IN: p_first and p_last point to the first and last byte of the text scrap. */
+/* IN: is_white should be set to TRUE iff scrap is entirely whitespace. */
+p_ps_t p_tkps;
+char *p_first;
+char *p_last;
+bool is_white;
+{
+ tk_t token;
+
+ /* Empty text scraps should never be generated. */
+ as_cold(p_first<=p_last,"sendtext: Text scrap bounds are bad.");
+
+ /* If ch=EOL then we should be scanning more text, not shipping it! */
+ as_cold(ch!=EOL,"senttext: Shipping text while still more to scan.");
+
+ /* Send the text token. */
+ token.tk_kind = TK_TEXT;
+ ASSIGN(token.tk_ps,*p_tkps);
+ token.tk_sc.sc_first = p_first;
+ token.tk_sc.sc_last = p_last;
+ token.tk_sc.sc_white = is_white;
+ token.tk_gen = DONTCARE;
+ ls_add(token_list,PV &token);
+}
+
+/******************************************************************************/
+
+LOCAL void add_eof P_((void));
+LOCAL void add_eof()
+/* This function adds terminators to the line and token list. */
+/* 1. It adds a TK_EOF token to the end of the token list. */
+/* 2. It adds a visible <eof> line to the end of the line list. */
+/* This assists the parser by allowing it to point diagnostic messages to a */
+/* visible EOF marker rather than pointing vaguely to the end of the last */
+/* line of the input file which (by the way) may not even exist! */
+{
+ STAVAR char *eofstr = "<End-Of-File>\n";
+ ln_t line;
+ ps_t ps;
+
+ /* When the liner mini package encounters an end of file marker, it stops */
+ /* dead on the marker and returns EOFCH forever. scan_file() eventually gets */
+ /* the message and drops out. However, in all of this, the line numbers are */
+ /* not incremented to indicate that we have moved to an EOF line. This is */
+ /* intended, as we do not want EOFs to appear in the listing for include */
+ /* files; only at the end of the main input file. Thus, here we effectively */
+ /* perform the liner function of moving from the last line of the input file */
+ /* to the imaginary line containing the EOF marker. This is done by */
+ /* incrementing the line numbers. Note that the fact that these line number */
+ /* variables are incorrect from the point of detection of the final EOF to */
+ /* here doesn't matter as no tokens or diagnostics are ever added after an */
+ /* EOF is detected. */
+ globalno++;
+ localno++;
+
+ /* Add a line to represent the EOF marker. */
+ line.ln_global = globalno;
+ line.ln_local = localno;
+ line.ln_body.sc_first = eofstr;
+ line.ln_body.sc_last = eofstr+strlen(eofstr)-1;
+ /* Note: We do not set sc_white as it is not used in lines. */
+ ls_add(line_list,PV &line);
+
+ /* Add a TK_EOF token to the end of the token list. */
+ ps.ps_line = globalno;
+ ps.ps_column = 1;
+ sendspec(&ps,TK_EOF,DONTCARE);
+}
+
+/******************************************************************************/
+/* The Scanner Proper */
+/******************************************************************************/
+
+LOCAL void skiptoeol P_((void));
+LOCAL void skiptoeol()
+{
+ while (ch != EOL)
+ NEXTCH;
+}
+
+/******************************************************************************/
+
+/* The incl_fil function calls this, so we have to declare it in advance. */
+LOCAL void scan_file P_((char *));
+
+LOCAL void incl_fil P_((p_ps_t));
+LOCAL void incl_fil(p_ps)
+/* Upon entry, the current character is the "i" of an "@i" sequence. Our task */
+/* is first to see if the sequence occurred at the start of a line (the only */
+/* point at which it is legal) and issue an error if it isn't. If it is legal,*/
+/* we have to read in the specified file and scan that. The included file */
+/* replaces exactly the line starting with the "@i" command and we return */
+/* to the "calling" file with the current position being the EOL character of */
+/* the include line. */
+p_ps_t p_ps;
+{
+ /* Complain if the include directive was not at the start of a line. */
+ if (p_ch-1 != p_sol)
+ {
+ lr_err(p_ps,"Include sequence must be at the beginning of a line.");
+ lr_mes(p_ps,"Include ignored.");
+ skiptoeol();
+ return;
+ }
+
+ /* The include command should be followed by a blank. Get the next char. */
+ NEXTCH;
+
+ /* Complain if the next character is not a blank. */
+ if (ch != ' ')
+ {
+ ps_t ps;
+ ASSIGN(ps,*p_ps);
+ ps.ps_column+=2;
+ lr_err(&ps,"Include sequence (@i) must be followed by a blank.");
+ lr_mes(&ps,"Example include: @i macros.fwi");
+ lr_mes(&ps,"Include ignored.");
+ skiptoeol();
+ return;
+ }
+
+ /* Complain if the include level is too high. */
+ if (inclevel == MAX_INCL)
+ {
+ lr_err(p_ps,"This include file is nested too deeply. It's probably recursive.");
+ sprintf(linet1,"The maximum level of nested includes is %u.",
+ (unsigned) MAX_INCL);
+ lr_mes(p_ps,linet1);
+ lr_mes(p_ps,"Include ignored.");
+ skiptoeol();
+ return;
+ }
+
+ {/* This construct does the work of the include. */
+ /* Warning: The following variables MUST be declared automatic. */
+ char *p_filename;
+ char *p_tempname;
+ ulong length;
+ char *p;
+ ulong xinln_max;
+ char xspecial;
+ char *xp_eof;
+ ulong xlocalno;
+ char *xp_sol;
+ char *xp_ch;
+ char xch;
+
+ /* We save stack space by sticking this filename in the heap. */
+ p_filename=mm_temp((size_t) FILENAME_FWMAX+1+10); /* 10 is for paranoia. */
+ p_tempname=mm_temp((size_t) FILENAME_FWMAX+1+10); /* 10 is for paranoia. */
+
+ /* The rest of the line is supposed to hold a filename. Copy it. */
+ NEXTCH;
+ p=p_tempname;
+ length=0;
+ while (ch!=EOL)
+ {
+ if (++length > FILENAME_FWMAX)
+ {
+ lr_err(p_ps,
+ "This include command's file specification is too long.");
+ if (option.op_b7_b)
+ sprintf(linet1,"The maximum file name length is %s characters.",
+ SUPPVAL);
+ else
+ sprintf(linet1,"The maximum file name length is %u characters.",
+ (unsigned) FILENAME_FWMAX);
+ lr_mes(p_ps,linet1);
+ lr_mes(p_ps,"Include ignored.");
+ skiptoeol();
+ return;
+ }
+ *p++=ch;
+ NEXTCH;
+ }
+ *p=EOS;
+ /* Note: Current position is now on the EOL at the end of the @i line. */
+
+ /* Complain if the user has not specified a filename. */
+ if (strlen(p_tempname) ==0)
+ {
+ lr_err(psofch(),"Expecting the name of a file to include.");
+ return;
+ }
+
+ /* Perform the necessary filename inheritance. */
+ strcpy(p_filename,"");
+ fn_ins(p_filename,option.op_f_s);
+ fn_ins(p_filename,".fwi");
+ fn_ins(p_filename,option.op_i_s);
+ fn_ins(p_filename,p_tempname);
+
+ /* Include the included file by calling scan_file recursively. */
+ /* Save and restore all variables in instantiation scope. */
+ xinln_max = inln_max;
+ xspecial = specialch;
+ xp_eof = p_eof;
+ xlocalno = localno;
+ xp_sol = p_sol;
+ xp_ch = p_ch;
+ xch = ch;
+ inclevel++;
+ scan_file(p_filename);
+ inclevel--;
+ ch = xch;
+ p_ch = xp_ch;
+ p_sol = xp_sol;
+ localno = xlocalno;
+ p_eof = xp_eof;
+ specialch = xspecial;
+ inln_max = xinln_max;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void do_ascii P_((p_ps_t));
+LOCAL void do_ascii(p_psspec)
+/* Upon entry, the current character is the '^' of a @^ sequence. The task is */
+/* to parse the following ascii code and generate a text token. */
+p_ps_t p_psspec;
+{
+ ubyte base; /* Base of the number we are scanning. */
+ ubyte digits; /* Number of digits expected. */
+ uword val; /* Value of target character. */
+ ubyte i; /* Looping variable. */
+ STAVAR char alphab[256]; /* Static alphabet array to which to point scraps. */
+ STAVAR bool init=FALSE; /* Tells if alphab has been initialized. */
+
+ /* Establish an array containing the ascii character set. Later on we can */
+ /* point the sc_first and sc_last pointers to particular characters. */
+ if (!init) {uword i; for (i=0;i<256;i++) alphab[i]=(char) i; init=TRUE;}
+
+ /* Make sure that the base character is legal. */
+ NEXTCH;
+ switch(toupper(ch))
+ {
+ case 'B': base= 2; digits=8; break;
+ case 'O':
+ case 'Q': base= 8; digits=3; break;
+ case 'D': base=10; digits=3; break;
+ case 'H':
+ case 'X': base=16; digits=2; break;
+ default : lr_err(psofch(),"Expecting one of 'B', 'Q', 'D', 'H'.");
+ lr_mes(psofch(),"(For Binary, Octal, Decimal, and Hexadecimal).");
+ base=10;
+ goto trouble;
+ }
+
+ /* Parse opening parenthesis. */
+ NEXTCH;
+ if (ch!='(')
+ {lr_err(psofch(),"Expecting '('.");goto trouble;}
+
+ val=0;
+ for (i=0;i<digits;i++)
+ {
+ char uch;
+ ubyte d;
+
+ NEXTCH;
+ uch=toupper(ch);
+ if (('0'<=uch) && (uch<='9'))
+ d=uch-'0';
+ else
+ if ('A'<=uch && uch<='F')
+ d=10+uch-'A';
+ else
+ d=100;
+ if (d>=base)
+ {lr_err(psofch(),"Illegal digit."); goto trouble;}
+ val = base*val + d;
+ }
+
+ /* Parse closing parenthesis. */
+ NEXTCH;
+ if (ch!=')')
+ {lr_err(psofch(),"Expecting ')'.");goto trouble;}
+
+ /* Make sure that the number is not too big (this is possible in decimal). */
+ if (val>255)
+ {
+ lr_err(psofch(),"Character number is too large.");
+ lr_mes(psofch(),"Character number must be in the range [0,255] (decimal).");
+ goto trouble;
+ }
+
+ /* Success! Now we can parcel it up into a scrap! */
+ sendtext(p_psspec,&alphab[val],&alphab[val],ch==' ' || ch==EOL);
+ return;
+
+ trouble:
+ /* Jump here after a specific diagnostic to give the user a reminder of */
+ /* how to specify an ascii character constant. */
+ switch (base)
+ {
+ case 2:
+ lr_mes(psofch(),
+ "A binary character representation takes the form \"@^B(dddddddd)\".");
+ lr_mes(psofch(),
+ "(exactly 8 digits) where each digit d is either 0 or 1.");
+ break;
+ case 8:
+ lr_mes(psofch(),
+ "An octal character representation takes the form \"@^Q(ddd)\" (or \"@^O(ddd)\").");
+ lr_mes(psofch(),
+ "(exactly 3 digits) where each digit d is in the range 0..7.");
+ break;
+ case 10:
+ lr_mes(psofch(),
+ "A decimal character representation takes the form \"@^D(ddd)\".");
+ lr_mes(psofch(),
+ "(exactly 3 digits) where each digit d is in the range 0..9.");
+ break;
+ case 16:
+ lr_mes(psofch(),
+ "A hexadecimal character representation takes the form \"@^X(dd)\" (or \"@^H(dd)\").");
+ lr_mes(psofch(),
+ "(exactly 2 digits) where each digit d is in the range 0..9,A..F.");
+ break;
+ default: as_bomb("do_ascii: trouble base switch defaulted.");
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void do_name P_((p_ps_t));
+LOCAL void do_name (p_psspec)
+/* Upon entry, the current character is the # of a @#. The task is to parse */
+/* it and transmit a name token. */
+p_ps_t p_psspec;
+{
+ as_cold(ch=='#',"do_name: character is wrong.");
+ NEXTCH;
+ if ((ch==EOL) || (ch==' '))
+ {lr_err(psofch(),"Expecting a printable character."); return;}
+
+ /* Transmit a name token. */
+ sendspec(p_psspec,TK_NAME,(ubyte) ch);
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgind P_((uword,p_pt_t));
+LOCAL void do_pgind(numarg,arg)
+/* Parse an indentation pragma. */
+uword numarg;
+p_pt_t arg;
+{
+ bool pragind;
+ ps_t psprag;
+
+ /* Make sure that there are exactly three arguments. */
+ if (numarg != 3) /* "indentation" "none|blank". */
+ {
+ lr_err(&arg[0].pt_ps,
+ "This indentation pragma has the wrong number of arguments.");
+ goto help;
+ }
+
+ /* Make sure that the second argument is an "=". */
+ if (0 != strcmp(arg[2].pt_pstr,"="))
+ {
+ lr_err(&arg[2].pt_ps,"Expecting \"=\".");
+ goto help;
+ }
+
+ /* Check the third argument. */
+ if (strcmp(arg[3].pt_pstr,"none" )==0) pragind=FALSE;
+ else if (strcmp(arg[3].pt_pstr,"blank")==0) pragind=TRUE;
+ else
+ {
+ lr_err(&arg[3].pt_ps,"Expecting either \"none\" or \"blank\".");
+ goto help;
+ }
+
+ /* Construct a shorthand for the start of the pragma. */
+ ASSIGN(psprag,arg[0].pt_ps);
+
+ /* Make sure that the pragma does not contradict an earlier pragma. */
+ if (seenind && (tgindent!=pragind))
+ {
+ sprintf(linet1,"This pragma is opposed by the pragma at line %lu.",
+ (unsigned long) psprag.ps_line);
+ lr_mes(&ps_ind,linet1);
+ sprintf(linet1,"This pragma opposes the pragma at line %lu.",
+ (unsigned long) ps_ind.ps_line);
+ lr_err(&psprag,linet1);
+ lr_mes(&psprag,"You can have as many indentation pragmas as you like,");
+ lr_mes(&psprag,"but they all have to be the same!");
+ lr_mes(&psprag,"Pragma ignored.");
+ return;
+ }
+
+ /* Success: Record the pragma information. */
+ seenind = TRUE; /* Record that we have seen a pragma. */
+ tgindent = pragind; /* Record what the pragma said. */
+ ASSIGN(ps_ind,psprag); /* Record where the pragma was. */
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: \"@p indentation = none|blank\".");
+ lr_mes(&arg[0].pt_ps,"Pragma ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pginl P_((uword,p_pt_t));
+LOCAL void do_pginl(numarg,arg)
+/* Parse a maximum input line length pragma. */
+uword numarg;
+p_pt_t arg;
+{
+ char *numstr;
+ uword spn;
+
+ /* Make sure that there are exactly three arguments. */
+ if (numarg != 3) /* "max..length = <num>". */
+ {
+ lr_err(&arg[0].pt_ps,"This pragma has the wrong number of arguments.");
+ goto help;
+ }
+
+ /* Make sure that the second argument is "=". */
+ if (0 != strcmp(arg[2].pt_pstr,"="))
+ {lr_err(&arg[2].pt_ps,"Expecting \"=\"."); goto help;}
+
+ /* Set up an abbreviation. */
+ numstr=arg[3].pt_pstr;
+
+ /* See if the value is "infinity". */
+ if (strcmp(numstr,"infinity")==0)
+ {inln_max=INMAXINF; return;}
+
+ /* Calculate length of longest prefix containing all decimal digits. */
+ /* Check that there are no illegal digits. */
+ spn=strspn(numstr,"0123456789");
+ if (spn != strlen(numstr))
+ {
+ ps_t ps;
+ ASSIGN(ps,arg[3].pt_ps);
+ ps.ps_column+=spn;
+ lr_err(&ps,"Illegal digit. Value must consist entirely of decimal digits.");
+ lr_mes(&ps,"You can also use the value \"infinity\".");
+ lr_mes(&ps,"Pragma ignored.");
+ return;
+ }
+
+ /* Check that the number is not too long. */
+ if (strlen(numstr)>8)
+ {
+ lr_err(&arg[3].pt_ps,"Too many digits. The maximum is eight.");
+ lr_mes(&arg[3].pt_ps,"Pragma ignored.");
+ return;
+ }
+
+ /* Convert the argument into an integer. */
+ {
+ ulong val;
+ int result;
+ /* Note: Should really be %lu, but the Vax doesn't know about the %u */
+ /* in sscanf and so we make do with %ld. */
+ result=sscanf(numstr,"%ld",&val);
+ as_cold(result==1,"do_pginl:sscanf failed.");
+ inln_max=val;
+ }
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: \"@p maximum_input_line_length = <num>|infinity\".");
+ lr_mes(&arg[0].pt_ps,"Pragma ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgotl P_((uword,p_pt_t));
+LOCAL void do_pgotl(numarg,arg)
+/* Parse a maximum product file line length pragma. */
+uword numarg;
+p_pt_t arg;
+{
+ char *numstr;
+ uword spn;
+ ulong val;
+ ps_t psprag;
+
+ /* Set up an abbreviation. */
+ ASSIGN(psprag,arg[0].pt_ps);
+
+ /* Make sure that there are exactly three arguments. */
+ if (numarg != 3) /* "max..length" "=" "value". */
+ {
+ lr_err(&arg[0].pt_ps,"This pragma has the wrong number of arguments.");
+ goto help;
+ }
+
+ /* Make sure that the second argument is an "=". */
+ if (0 != strcmp(arg[2].pt_pstr,"="))
+ {lr_err(&arg[2].pt_ps,"Expecting \"=\"."); goto help;}
+
+ /* Set up an abbreviation. */
+ numstr=arg[3].pt_pstr;
+
+ /* See if the value is "infinity". */
+ if (strcmp(numstr,"infinity")==0)
+ {val=TGMAXINF; goto gotvalue;}
+
+ /* Calculate length of longest prefix containing all decimal digits. */
+ /* Check that there are no illegal digits. */
+ spn=strspn(numstr,"0123456789");
+ if (spn != strlen(numstr))
+ {
+ ps_t ps;
+ ASSIGN(ps,arg[3].pt_ps);
+ ps.ps_column+=spn;
+ lr_err(&ps,"Illegal digit. Value must consist entirely of decimal digits.");
+ lr_mes(&ps,"You can also use the value \"infinity\".");
+ lr_mes(&ps,"Pragma ignored.");
+ return;
+ }
+
+ /* Check that the number is not too long. */
+ if (strlen(numstr)>8)
+ {
+ lr_err(&arg[3].pt_ps,"Too many digits. The maximum is eight.");
+ lr_mes(&arg[3].pt_ps,"Pragma ignored.");
+ return;
+ }
+
+ /* Convert the argument into an integer. */
+ {
+ int result=sscanf(numstr,"%ld",&val);
+ as_cold(result==1,"do_pgotl:sscanf failed.");
+ }
+
+ gotvalue:
+ /* Make sure that the pragma does not contradict an earlier pragma. */
+ if (seenlimo && (tglinmax!=val))
+ {
+ sprintf(linet1,"This pragma is opposed by the pragma at line %lu.",
+ (unsigned long) psprag.ps_line);
+ lr_mes(&ps_limo,linet1);
+ sprintf(linet1,"This pragma opposes the pragma at line %lu.",
+ (unsigned long) ps_limo.ps_line);
+ lr_err(&psprag,linet1);
+ lr_mes(&psprag,"You can have as many output line length pragmas");
+ lr_mes(&psprag,"as you like, but they all have to be the same!");
+ lr_mes(&psprag,"Pragma ignored.");
+ return;
+ }
+
+ /* If we got this far then the pragma is just the same as an earlier one. */
+ /* We don't want to set the pragma position to the later pragma so we */
+ /* return now. */
+ if (seenlimo) return;
+
+ /* Success. Set the variables. */
+ tglinmax=val;
+ seenlimo=TRUE;
+ ASSIGN(ps_limo,psprag);
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: \"@p maximum_output_line_length = <num>|infinity\".");
+ lr_mes(&arg[0].pt_ps,"Pragma ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgnpg P_((uword,p_pt_t));
+LOCAL void do_pgnpg(numarg,arg)
+/* Parse a newpage typesetter directive. */
+uword numarg;
+p_pt_t arg;
+{
+ /* Make sure that there is exactly one argument. */
+ if (numarg > 1) /* "new_page" */
+ {
+ lr_err(&arg[2].pt_ps,"The new_page directive does not take arguments.");
+ lr_mes(&arg[2].pt_ps,"Directive ignored.");
+ return;
+ }
+ sendspec(&arg[0].pt_ps,TK_NPAG,DONTCARE);
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgtoc P_((uword,p_pt_t));
+LOCAL void do_pgtoc(numarg,arg)
+/* Parse a table of contents typesetter directive. */
+uword numarg; /* Number of arguments to table of contents directive. */
+p_pt_t arg; /* Array describing arguments. */
+{
+ /* Make sure that there is exactly one argument. */
+ if (numarg > 1) /* "table_of_contents" */
+ {
+ lr_err(&arg[2].pt_ps,
+ "The table_of_contents directive does not take arguments.");
+ lr_mes(&arg[2].pt_ps,"Directive ignored.");
+ return;
+ }
+ sendspec(&arg[0].pt_ps,TK_TOCS,DONTCARE);
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgvsk P_((uword,p_pt_t));
+LOCAL void do_pgvsk(numarg,arg)
+/* Parse a vskip typesetter directive. */
+uword numarg; /* Number of arguments to indentation directive. */
+p_pt_t arg; /* Array describing arguments. */
+{
+ char *numstr;
+ uword spn;
+
+ /* Make sure that there are exactly three arguments. */
+ if (numarg != 3) /* "vskip" n "mm". */
+ {
+ lr_err(&arg[0].pt_ps,"This directive has the wrong number of arguments.");
+ goto help;
+ }
+
+ /* Make sure that the third argument is "mm". */
+ if (0 != strcmp(arg[3].pt_pstr,"mm"))
+ {lr_err(&arg[3].pt_ps,"Expecting \"mm\"."); goto help;}
+
+ /* Set up an abbreviation. */
+ numstr=arg[2].pt_pstr;
+
+ /* Calculate length of longest prefix containing all decimal digits. */
+ /* Check that there are no illegal digits. */
+ spn=strspn(numstr,"0123456789");
+ if (spn != strlen(numstr))
+ {
+ ps_t ps;
+ ASSIGN(ps,arg[2].pt_ps);
+ ps.ps_column+=spn;
+ lr_err(&ps,"Illegal digit.");
+ lr_mes(&ps,"Value must consist entirely of decimal digits.");
+ lr_mes(&ps,"Directive ignored.");
+ return;
+ }
+
+ /* Check that the number is not too long. */
+ if (strlen(numstr)>3)
+ {
+ lr_err(&arg[2].pt_ps,"Too many digits. The maximum is three.");
+ lr_mes(&arg[2].pt_ps,"Directive ignored.");
+ return;
+ }
+
+ /* Convert the argument into an integer. */
+ {
+ ulong val;
+ int result;
+ result=sscanf(numstr,"%ld",&val);
+ as_cold(result==1,"do_pginl:sscanf failed.");
+ if (val>255)
+ {
+ lr_err(&arg[2].pt_ps,"Value too large. Maximum is 255.");
+ lr_mes(&arg[2].pt_ps,"Directive ignored.");
+ return;
+ }
+ sendspec(&arg[0].pt_ps,TK_SKIP,(ubyte) val);
+ }
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,"The correct format is: \"@t vskip <num> mm\".");
+ lr_mes(&arg[0].pt_ps,"Directive ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgtit P_((uword,p_pt_t));
+LOCAL void do_pgtit(numarg,arg)
+/* Parse a title typesetter directive. */
+uword numarg; /* Number of arguments to title directive. */
+p_pt_t arg; /* Array describing arguments. */
+{
+ uword align;
+ uword font;
+ char *p_sot,*p_eot;
+
+ /* Make sure that there are at least three arguments. */
+ if (numarg < 4) /* "title <font> <align> <text>". */
+ {lr_err(&arg[0].pt_ps,"This directive has too few arguments."); goto help;}
+
+ /* Check the font argument. */
+ if (strcmp(arg[2].pt_pstr,"normalfont" )==0) font=FT_NORM;
+ else if (strcmp(arg[2].pt_pstr,"titlefont" )==0) font=FT_TITL;
+ else if (strcmp(arg[2].pt_pstr,"smalltitlefont")==0) font=FT_STIT;
+ else
+ {
+ lr_err(&arg[2].pt_ps,
+ "Expecting one of {titlefont,smalltitlefont,normalfont}.");
+ lr_mes(&arg[2].pt_ps,"Directive ignored.");
+ return;
+ }
+
+ /* Check the alignment argument. */
+ if (strcmp(arg[3].pt_pstr,"left" )==0) align=LR_LEFT;
+ else if (strcmp(arg[3].pt_pstr,"right" )==0) align=LR_RIGH;
+ else if (strcmp(arg[3].pt_pstr,"centre")==0) align=LR_CENT;
+ else
+ {
+ lr_err(&arg[3].pt_ps,"Expecting one of {left,right,centre}.");
+ if (strcmp(arg[3].pt_pstr,"center")==0)
+ {
+ lr_mes(&arg[3].pt_ps,"Note: Centre is spelt centRE, not centER.");
+ lr_mes(&arg[3].pt_ps," This is my revenge for years of getting error messages");
+ lr_mes(&arg[3].pt_ps," from TeX whenever I accidentally wrote \\centreline - Ross Williams.");
+ }
+ lr_mes(&arg[3].pt_ps,"Directive ignored.");
+ return;
+ }
+
+ /* Now make sure that the remainder of the line is delimited by quotes. */
+ p_sot=arg[4].pt_pinl;
+ p_eot=p_sot+strlen(p_sot)-1;
+ if (*p_sot!='"' || *p_eot!='"' || p_sot==p_eot)
+ {
+ lr_err(&arg[4].pt_ps,"Text argument must be delimited by double quotes.");
+ lr_mes(&arg[4].pt_ps,"Directive ignored.");
+ return;
+ }
+ p_sot++; p_eot--;
+
+ /* Ship out a token whose fields are all fully laden. */
+ {
+ tk_t token;
+ token.tk_kind = TK_TITL;
+ ASSIGN(token.tk_ps,arg[0].pt_ps);
+ token.tk_sc.sc_first = p_sol+ (3+(p_sot-arg[1].pt_pinl));
+ token.tk_sc.sc_last = p_sol+ (3+(p_eot-arg[1].pt_pinl));
+ token.tk_sc.sc_white = FALSE;
+ token.tk_gen = LRFT_PACK*font+align;
+ ls_add(token_list,PV &token);
+ }
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: \"@t title <font> <align> <text>\".");
+ lr_mes(&arg[0].pt_ps,
+ " where <font> = titlefont | smalltitlefont | normalfont.");
+ lr_mes(&arg[0].pt_ps,
+ " and <align> = left | centre | right.");
+ lr_mes(&arg[0].pt_ps,
+ " and <text> = text delimited by double quotes.");
+ lr_mes(&arg[0].pt_ps,"Directive ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pgtyp P_((uword,p_pt_t));
+LOCAL void do_pgtyp(numarg,arg)
+/* Parse a typesetter pragma. */
+uword numarg;
+p_pt_t arg;
+{
+ tr_k_t pragtyp;
+ ps_t psprag;
+
+ /* Make sure that there are exactly three arguments. */
+ if (numarg != 3) /* "typesetter" "=" "name". */
+ {
+ lr_err(&arg[0].pt_ps,
+ "This typesetter pragma has the wrong number of arguments.");
+ goto help;
+ }
+
+ /* Make sure that the second argument is "=". */
+ if (0 != strcmp(arg[2].pt_pstr,"="))
+ {
+ lr_err(&arg[2].pt_ps,"Expecting \"=\".");
+ goto help;
+ }
+
+ /* Check the third argument. */
+ if (strcmp(arg[3].pt_pstr,"none")==0) pragtyp=TR_NONE;
+ else if (strcmp(arg[3].pt_pstr,"tex" )==0) pragtyp=TR_TEX;
+ else
+ {
+ lr_err(&arg[3].pt_ps,"Expecting either \"none\" or \"tex\".");
+ goto help;
+ }
+
+ /* Construct a shorthand for the start of the pragma. */
+ ASSIGN(psprag,arg[0].pt_ps);
+
+ /* Make sure that the pragma does not contradict an earlier pragma. */
+ if (seentyp && (tr_codes != pragtyp))
+ {
+ sprintf(linet1,"This pragma is opposed by the pragma at line %lu.",
+ (unsigned long) psprag.ps_line);
+ lr_mes(&ps_typ,linet1);
+ sprintf(linet1,"This pragma opposes the pragma at line %lu.",
+ (unsigned long) ps_typ.ps_line);
+ lr_err(&psprag,linet1);
+ lr_mes(&psprag,"You can have as many typesetter pragmas as you like,");
+ lr_mes(&psprag,"but they all have to be the same!");
+ lr_mes(&psprag,"Pragma ignored.");
+ return;
+ }
+
+ /* Success: Record the pragma information. */
+ seentyp = TRUE; /* Record that we have seen a pragma. */
+ tr_codes = pragtyp; /* Record what the pragma said. */
+ ASSIGN(ps_typ,psprag); /* Record where the pragma was. */
+ return;
+
+ help:
+ lr_mes(&arg[0].pt_ps,
+ "The correct format is: \"@p typesetter = none|tex\".");
+ lr_mes(&arg[0].pt_ps,"Pragma ignored.");
+ return;
+}
+
+/******************************************************************************/
+
+LOCAL void do_pragma P_((p_ps_t,bool));
+LOCAL void do_pragma(p_ps,is_typ)
+/* Upon entry, the current character is: */
+/* is_typ=FALSE => The P of a @p. */
+/* is_typ=TRUE => The T of a @t. */
+/* This function processes these contructs. */
+p_ps_t p_ps;
+bool is_typ;
+{
+#define MAXPARG 10 /* Maximum recorded arguments to a pragma. */
+#define PRAGMA_MAX 100 /* Maximum length of a pragma. */
+ char praglin[PRAGMA_MAX+1]; /* Array to hold pragma as a complete line. */
+ char pragstr[PRAGMA_MAX+1]; /* Array to hold pragma as strings. */
+ pt_t pragarg[MAXPARG+1]; /* Array of pragma arguments. */
+ uword length; /* Helps prevent scanning overrun. */
+ char *p,*q; /* Temporary. */
+ uword numarg,na; /* Number of arguments seen so far. */
+
+ /* Complain if the pragma directive is not at the start of a line. */
+ if (p_ch-1 != p_sol)
+ {
+ if (is_typ)
+ {
+ lr_err(p_ps,"Typesetter directive @t must be at the start of a line.");
+ lr_mes(p_ps,"The rest of this line will be ignored.");
+ }
+ else
+ {
+ lr_err(p_ps,"Pragma sequence @p must be at the start of a line.");
+ lr_mes(p_ps,"The rest of this line will be ignored.");
+ }
+ skiptoeol();
+ goto help;
+ }
+
+ /* The include command should be followed by a blank. Get the next char. */
+ NEXTCH;
+
+ /* Complain if the next character is not a blank. */
+ if (ch != ' ')
+ {
+ /* Note: If we position this error correctly, it gets put after the */
+ /* help message! */
+ if (is_typ)
+ lr_err(p_ps,"Typesetter directive @t must be followed by a blank.");
+ else
+ lr_err(p_ps,"Pragma sequence @p must be followed by a blank.");
+ skiptoeol();
+ goto help;
+ }
+
+ /* Copy the rest of the line to the pragma arrays. */
+ NEXTCH;
+ p = &praglin[0];
+ q = &pragstr[0];
+ length=0;
+ while (ch!=EOL)
+ {
+ if (++length > PRAGMA_MAX-3) /* 3 is for "@p " or "@t " */
+ {
+ if (is_typ)
+ {
+ lr_err(p_ps,"This typestter directive line is too long.");
+ sprintf(linet1,"The maximum typesetter directive line length is %u characters.",
+ (unsigned) PRAGMA_MAX);
+ lr_mes(p_ps,linet1);
+ }
+ else
+ {
+ lr_err(p_ps,"This pragma line is too long.");
+ sprintf(linet1,"The maximum pragma line length is %u characters.",
+ (unsigned) PRAGMA_MAX);
+ lr_mes(p_ps,linet1);
+ }
+ skiptoeol();
+ goto help;
+ }
+ *p++=ch;
+ *q++=ch;
+ NEXTCH;
+ }
+ *p=EOS;
+ *q=EOS;
+ /* Note: Current position is now on the EOL at the end of the @p line. */
+ /* That is the way we want to leave it for the scanspec() routine. */
+
+ /* So far we have copied the body of the pragma line into two arrays. The */
+ /* next lump of code parses that line into a sequence of non-blank arguments.*/
+ /* The result is an array of pt_t objects each of which contains the */
+ /* position of each argument, a pointer to the first character of each */
+ /* argument in praglin, and also a pointer to a string containing the arg. */
+ /* The string resides in the array pragstr which is the same as praglin */
+ /* except that some blanks have been replaced by EOSs so as to allow us to */
+ /* point into it to form strings. All this probably seems rather overdone */
+ /* for the analysis of a "simple" pragma, but I have found that pulling the */
+ /* different kinds of pragma lines apart separately is very messy. Far */
+ /* better to suffer here in what is at least reasonably neat code than */
+ /* later in the specific pragma routines. */
+ numarg=0;
+ p= &praglin[0];
+ q= &pragstr[0];
+ while (TRUE)
+ {
+ /* Skip whitespace between arguments. */
+ while (*p==' ') {p++;q++;}
+
+ /* Exit if we have hit the end of the line. */
+ if ((numarg==MAXPARG) || (*p==EOS)) break;
+
+ /* We have found another argument! */
+ numarg++;
+
+ /* Record the argument. */
+ ASSIGN(pragarg[numarg].pt_ps,*p_ps);
+ pragarg[numarg].pt_ps.ps_column=4+(p-praglin);
+ pragarg[numarg].pt_pinl=p;
+ pragarg[numarg].pt_pstr=q;
+
+ /* Skip to the end of the argument. */
+ while (*p!=' ' && *p!=EOS) {p++;q++;}
+
+ /* Drop a null in the string array to complete string rep of argument. */
+ *q=EOS;
+ }
+
+ /* At this point numarg is MIN(arguments,MAXPARG), and pragargs contains an */
+ /* entry for each of the numarg arguments. */
+
+ /* It is handy to have the position of the pragma itself handy. */
+ ASSIGN(pragarg[0].pt_ps,*p_ps);
+
+ /* CHECK: Make sure that the line and string arrays square up. */
+ {
+ uword i;
+ for (i=1;i<=numarg;i++)
+ {
+ uword j;
+ uword t=strlen(pragarg[i].pt_pstr);
+ for (j=0;j<t;j++)
+ {
+ as_cold(pragarg[i].pt_pstr[j]==pragarg[i].pt_pinl[j],
+ "do_pragma: String and line arrays are not equal.");
+ as_cold((pragarg[i].pt_pstr-pragstr)==(pragarg[i].pt_pinl-praglin),
+ "do_pragma: String and line arrays are out of synch.");
+ }
+ }
+ }
+
+ /* Complain if there are no arguments at all. */
+ if (numarg==0)
+ {
+ if (is_typ)
+ lr_err(p_ps,"Typesetter directive @t must be followed by a keyword.");
+ else
+ lr_err(p_ps,"Pragma sequence @p must be followed by a keyword.");
+ skiptoeol();
+ goto help;
+ }
+
+ /* Branch off to specific routines based on the first argument. */
+ p=pragarg[1].pt_pstr; na=numarg;
+ if (is_typ)
+ {
+ if (0==strcmp(p,"new_page" )) {do_pgnpg(na,pragarg);return;}
+ if (0==strcmp(p,"table_of_contents" )) {do_pgtoc(na,pragarg);return;}
+ if (0==strcmp(p,"title" )) {do_pgtit(na,pragarg);return;}
+ if (0==strcmp(p,"vskip" )) {do_pgvsk(na,pragarg);return;}
+ }
+ else
+ {
+ if (0==strcmp(p,"indentation" )) {do_pgind(na,pragarg);return;}
+ if (0==strcmp(p,"maximum_input_line_length" )) {do_pginl(na,pragarg);return;}
+ if (0==strcmp(p,"maximum_output_line_length")) {do_pgotl(na,pragarg);return;}
+ if (0==strcmp(p,"typesetter" )) {do_pgtyp(na,pragarg);return;}
+ }
+
+ help:
+ if (is_typ)
+ {
+ lr_err(p_ps,"Unrecognised typesetter directive. Legal ones are:");
+ lr_mes(p_ps," @t new_page");
+ lr_mes(p_ps," @t table_of_contents");
+ lr_mes(p_ps," @t title <font> <align> <string>");
+ lr_mes(p_ps," @t vskip <num> mm");
+ lr_mes(p_ps,"The blanks between arguments are important.");
+ lr_mes(p_ps,"Typesetter directive ignored.");
+ }
+ else
+ {
+ lr_err(p_ps,"Unrecognised pragma. Possible legal pragmas are:");
+ lr_mes(p_ps," @p indentation = none | blank");
+ lr_mes(p_ps," @p maximum_input_line_length = <num>|infinity");
+ lr_mes(p_ps," @p maximum_output_line_length = <num>|infinity");
+ lr_mes(p_ps," @p typesetter = none | tex");
+ lr_mes(p_ps,"The blanks between arguments are important.");
+ lr_mes(p_ps,"Pragma ignored.");
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void chksol P_((void));
+LOCAL void chksol()
+/* This function is called when the current character is the character after */
+/* an @. The function checks to see if the @ was at the start of a line and */
+/* issues a error message if it isn't. */
+{
+ ps_t ps;
+ grabchps(&ps);
+ if (ps.ps_column != 2)
+ {
+ ps.ps_column--;
+ sprintf(linet1,"@%c is legal only at the start of a line.",ch);
+ lr_err(&ps,linet1);
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void scanspec P_((void));
+LOCAL void scanspec()
+/* Upon entry the current character is the special character (usually '@'). */
+/* The task is to scan the special sequence. Upon exit, the current character */
+/* is the character following the special sequence. */
+{
+ ps_t ps_spec; /* Position of start of special sequence. */
+
+ /* Make a note of where the special sequence starts. */
+ grabchps(&ps_spec);
+
+ /* Move onto the character following the special (escape) character. */
+ NEXTCH;
+
+ /* Now react to the character. In most cases, the special sequence is simply */
+ /* a marker in the input and we can simply transmit it. The nasty special */
+ /* case sequences are left until the end of the switch statement. */
+ /* Purists will complain about how all the case options are hardwired and */
+ /* say that symbols should have been used. They once were, but were taken */
+ /* out when it was discovered that the symbols had cryptic names (because of */
+ /* the portability eight-character rule) and were only used here anyway. */
+ switch (toupper(ch))
+ {
+ case '<': sendspec(&ps_spec,TK_ONAM,DONTCARE); break;
+ case '>': sendspec(&ps_spec,TK_CNAM,DONTCARE); break;
+ case '{': sendspec(&ps_spec,TK_ODEF,DONTCARE); break;
+ case '}': sendspec(&ps_spec,TK_CDEF,DONTCARE); break;
+ case '(': sendspec(&ps_spec,TK_OPAR,DONTCARE); break;
+ case ')': sendspec(&ps_spec,TK_CPAR,DONTCARE); break;
+ case ',': sendspec(&ps_spec,TK_COMA,DONTCARE); break;
+ case '"': sendspec(&ps_spec,TK_QUOT,DONTCARE); break;
+ case '/': sendspec(&ps_spec,TK_EMPH,DONTCARE); break;
+ case 'A': sendspec(&ps_spec,TK_NSEC,1); chksol(); break;
+ case 'B': sendspec(&ps_spec,TK_NSEC,2); chksol(); break;
+ case 'C': sendspec(&ps_spec,TK_NSEC,3); chksol(); break;
+ case 'D': sendspec(&ps_spec,TK_NSEC,4); chksol(); break;
+ case 'E': sendspec(&ps_spec,TK_NSEC,5); chksol(); break;
+ case '1': sendspec(&ps_spec,TK_PARM,1); break;
+ case '2': sendspec(&ps_spec,TK_PARM,2); break;
+ case '3': sendspec(&ps_spec,TK_PARM,3); break;
+ case '4': sendspec(&ps_spec,TK_PARM,4); break;
+ case '5': sendspec(&ps_spec,TK_PARM,5); break;
+ case '6': sendspec(&ps_spec,TK_PARM,6); break;
+ case '7': sendspec(&ps_spec,TK_PARM,7); break;
+ case '8': sendspec(&ps_spec,TK_PARM,8); break;
+ case '9': sendspec(&ps_spec,TK_PARM,9); break;
+ case 'M': sendspec(&ps_spec,TK_MANY,DONTCARE); break;
+ case 'Z': sendspec(&ps_spec,TK_ZERO,DONTCARE); break;
+ case 'O': sendspec(&ps_spec,TK_FDEF,DONTCARE); chksol(); break;
+ case '$': sendspec(&ps_spec,TK_MDEF,DONTCARE); chksol(); break;
+ case EOL:
+ lr_err(&ps_spec,"<special><endofline> is not a legal special sequence.");
+ break;
+ case ' ':
+ lr_err(&ps_spec,"<special><space> is not a legal special sequence.");
+ break;
+ case '@':
+ /* @ instructs FunnelWeb to replace the special construct with the */
+ /* special character. Luckily one appears just before the @ !! */
+ /* Note: FALSE is OK because space is not a legal specialch. */
+ sendtext(&ps_spec,p_ch-1,p_ch-1,FALSE);
+ break;
+ case '-':
+ /* - instructs FunnelWeb to suppress the following end of line. */
+ if (*(p_ch+1) == EOL)
+ NEXTCH
+ else
+ lr_err(&ps_spec,
+ "Suppress EOL sequence is legal only at the end of a line.");
+ break;
+ case '+':
+ /* + instructs FunnelWeb to insert an EOL. We can't look to the end of */
+ /* the previous line to find an EOL as this might be the first line. */
+ /* Running ahead to the end of the line is expensive, and having the */
+ /* liner mini-package maintain a variable for it would be extra */
+ /* housekeeping. Instead of all this, we just point to a static. */
+ {STAVAR char stateol = EOL;
+ sendtext(&ps_spec,&stateol,&stateol,TRUE);}
+ break;
+ case '=':
+ /* = instructs FunnelWeb to change the special character to the */
+ /* character following the <special>= sequence. */
+ NEXTCH;
+ if (ch == ' ')
+ {
+ lr_err(&ps_spec,"You cannot set the special character to <space>!");
+ lr_mes(&ps_spec,"Special sequence ignored.");
+ }
+ else if (ch == EOL)
+ {
+ lr_err(&ps_spec,
+ "You cannot set the special character to <endofline>!");
+ lr_mes(&ps_spec,"Special sequence ignored.");
+ }
+ else
+ specialch=ch;
+ break;
+ case '!':
+ /* ! instructs FunnelWeb to ignore the rest of the line (a comment). */
+ skiptoeol();
+ break;
+ case 'I':
+ /* i instructs FunnelWeb to include a file. */
+ incl_fil(&ps_spec);
+ break;
+ case '^':
+ /* ^ instructs FunnelWeb to insert a specific ascii character. */
+ do_ascii(&ps_spec);
+ break;
+ case '#':
+ /* # instructs FunnelWeb to transmit a two character name "#c". */
+ do_name(&ps_spec);
+ break;
+ case 'P':
+ /* P is used as a miscellaneous PRAGMA. */
+ do_pragma(&ps_spec,FALSE);
+ break;
+ case 'T':
+ /* T introduces a one-line typesetting directive. */
+ do_pragma(&ps_spec,TRUE);
+ break;
+ default:
+ lr_err(&ps_spec,"Unknown special sequence.");
+ break;
+ }
+
+ /* The switch statment absorbs the special sequence and its effects. */
+ /* This NEXTCH places us on the character following the special sequence. */
+ NEXTCH;
+}
+
+/******************************************************************************/
+
+LOCAL void scantext P_((void));
+LOCAL void scantext()
+/* Upon entry, we know that the current character is not EOF and that it is */
+/* not the special character. Our task is to parse as much text as we can and */
+/* ship it off as a text token. The scanner will probably spend most of its */
+/* time in the loops in this function so it is important that they be */
+/* efficient. That is why two loops are used to deal with detecting */
+/* whitespace rather than a flag. */
+/* Upon return, the current character is the character following the text */
+/* sequence. This is guaranteed to be the special character or an EOF. */
+{
+ ps_t ps_start; /* Position of first character of text sequence. */
+ char *p_first = p_ch; /* Pointer to first character of text sequence. */
+
+ /* Grab a copy of the position of this token. */
+ grabchps(&ps_start);
+
+ /* Scan whitespace. */
+ while (ch==' ' || ch==EOL)
+ NEXTCH;
+
+ /* If we hit something that ends a text token */
+ /* then we can transmit a white text token. */
+ if (ch==specialch || ch==EOFCH)
+ {sendtext(&ps_start,p_first,p_ch-1,TRUE); return;}
+
+ /* Otherwise we have some more (non-white) text to scan. */
+ /* We can then send a non-white text token. */
+ while (ch!=specialch && ch!=EOFCH)
+ NEXTCH;
+ sendtext(&ps_start,p_first,p_ch-1,FALSE);
+}
+
+/******************************************************************************/
+
+LOCAL void scan_file(p_fname)
+/* This function scans a single file. It's argument is the name of the file */
+/* to be scanned. scan_file calls the mapper to map in the file and then */
+/* scans the text of the mapped file using the liner mini-package. The result */
+/* of the scan is additions to the line and token list, and diagnostics sent */
+/* to the lister package. If an include directive is encountered, this */
+/* function is called recursively. */
+char *p_fname;
+{
+ char *p_mapped; /* Pointer to the mapped file. */
+ ulong length; /* Number of bytes in the mapped file. */
+ char *errstr; /* Error string returned by mapper. */
+ bool addedeol; /* Did we have to add an EOL to the end of the last line? */
+
+ /* Check to see if the file exists. */
+ if (!fexists(p_fname))
+ {
+ if (inclevel==0)
+ {
+ /* Failure to find the main file is a severe error. */
+ if (option.op_b7_b)
+ sprintf(linet1,"S: Error opening input file \"%s\".",SUPPNAME);
+ else
+ sprintf(linet1,"S: Error opening input file \"%s\".",p_fname);
+ wl_l(linet1);
+ /* Although strictly speaking we should suppress this error from the */
+ /* screen stream unless option.op_s_b is set, absence of an input file */
+ /* is such an important error, that we write it out anyway. */
+ /* if (option.op_s_b) */
+ wl_sj(linet1);
+ num_sev++;
+ return;
+ }
+ else
+ {
+ /* Failure to find an include file is an ordinary error. */
+ ps_t ps;
+ ps.ps_line = globalno;
+ ps.ps_column = 4;
+ lr_err(&ps,"Error opening include file.");
+ if (option.op_b7_b)
+ sprintf(linet1,
+ "The include file's expanded name was \"%s\".",SUPPNAME);
+ else
+ sprintf(linet1,
+ "The include file's expanded name was \"%s\".",p_fname);
+ lr_mes(&ps,linet1);
+ return;
+ }
+ }
+
+ /* Map the specified file into memory. We need to change from the scanner */
+ /* clock to the mapper clock to keep the time accounting correct here. */
+ ck_stop(p_scan);
+ ck_start(p_mapp);
+ errstr=map_file(p_fname,&p_mapped,&length);
+ ck_stop(p_mapp);
+ ck_start(p_scan);
+
+ /* Abort if the mapping was not possible. */
+ if (errstr != NULL)
+ if (inclevel==0)
+ {
+ /* Failure to map the main file is a severe error. */
+ if (option.op_b7_b)
+ sprintf(linet1,"S: Error reading input file \"%s\".",SUPPNAME);
+ else
+ sprintf(linet1,"S: Error reading input file \"%s\".",p_fname);
+ wl_l(linet1); if (option.op_s_b) wl_sj(linet1);
+ wl_l(errstr); if (option.op_s_b) wl_sj(errstr);
+ num_sev++;
+ return;
+ }
+ else
+ {
+ /* Failure to find an include file is an ordinary error. */
+ ps_t ps;
+ ps.ps_line = globalno;
+ ps.ps_column = 4;
+ lr_err(&ps,"Error reading include file.");
+ lr_mes(&ps,errstr);
+ if (option.op_b7_b)
+ sprintf(linet1,"The include file's expanded name was \"%s\".",
+ SUPPNAME);
+ else
+ sprintf(linet1,"The include file's expanded name was \"%s\".",
+ p_fname);
+ lr_mes(&ps,linet1);
+ return;
+ }
+
+ /* Dump the mapped file if requested. */
+ if (option.op_b1_b)
+ {
+ if (option.op_b7_b)
+ sprintf(linet1,"Dump of mapped file \"%s\".",SUPPNAME);
+ else
+ sprintf(linet1,"Dump of mapped file \"%s\".",p_fname);
+ wl_l(linet1);
+ dm_mem(&f_l,p_mapped,length);
+ }
+
+ /* If the file is absolutely empty, we have to warn the user. Also, this is */
+ /* a special case we can do without, and so we return here if file is empty. */
+ if (length==0)
+ {
+ ps_t ps;
+ /* The empty file could be the main file or an include file. */
+ /* If the empty file is the main file, we want the diagnostic to point to */
+ /* the EOF marker which will appear as line 1. */
+ /* If the empty file is an include file, we wish to point the diagnostic */
+ /* to the line containing the include command. This is globalno. */
+ /* In both cases, we want the diagnostic to point to column 1. */
+ ps.ps_column=1;
+ if (inclevel==0)
+ {
+ ps.ps_line=1;
+ lr_war(&ps,"Input file is empty (not a byte in syte)!");
+ }
+ else
+ {
+ ps.ps_line=globalno;
+ lr_war(&ps,"Include file is empty (not a byte in syte)!");
+ }
+ return;
+ }
+
+ /* Scanning is considerably simplified if we can guarantee that we will not */
+ /* run into an EOF without first hitting an EOL. The following code takes */
+ /* care of this by tacking one on the end if necessary and also adds an */
+ /* EOF character on the end, which also simplifies the scanning. We can get */
+ /* away with all this because the mapper purposefully leaves at least two */
+ /* bytes free for us at the end of the mapped file. */
+ addedeol=FALSE;
+ if (p_mapped[length-1] != EOL)
+ {p_mapped[length++]=EOL; addedeol=TRUE;}
+ p_mapped[length]=EOFCH;
+
+ /* Initialize the variables "instantiated over a single file". */
+ inln_max = 80;
+ specialch = CH_DSPE;
+ localno = 0;
+ p_eof = &p_mapped[length];
+
+ /* Crank up the line subscanner system with a call to prepline. */
+ /* Then enter the main scanning loop. */
+ /* All input consists of alternating special and text sequences */
+ /* terminated by EOF. */
+ prepline(p_mapped);
+ while (ch!=EOFCH)
+ if (ch==specialch)
+ scanspec();
+ else
+ scantext();
+
+ /* Now that we are at the end of the scanned file and the scanning markers */
+ /* are all sitting on the end of the file, it is a good time to issue */
+ /* diagnostics about problems at the end of the file. */
+ if (addedeol)
+ {
+ ps_t ps;
+ /* We want the diagnostic to point to the EOF line. Hence "global+1". */
+ ps.ps_line = globalno+1;
+ ps.ps_column = 1;
+ if (inclevel==0)
+ lr_war(&ps,"The last line of the input file was terminated by EOF.");
+ else
+ lr_war(&ps,"The last line of the include file was terminated by EOF.");
+ lr_mes(&ps,"An EOL was inserted at the end of the last line.");
+ }
+}
+
+/******************************************************************************/
+
+EXPORT void scanner(p_amapp,p_ascan)
+/* This is the scanner's main routine and the only exported function. */
+p_ck_t p_amapp; /* Mapper's clock (stopped). */
+p_ck_t p_ascan; /* Scanner's clock (running). */
+{
+ /* Copy the arguments into globals where we can get at them. */
+ p_mapp=p_amapp;
+ p_scan=p_ascan;
+
+ /* Apart from diagnostic messages sent to the lister, the only output of */
+ /* the scanner is two global lists holding a list of lines and a list of */
+ /* tokens. The scanner creates these lists simultaneously. */
+ /* We have to initialize them here before we get into 'scan_file' which */
+ /* calls itself recursively if an include file command is encountered. */
+ line_list =ls_cre(sizeof(ln_t));
+ token_list=ls_cre(sizeof(tk_t));
+
+ /* Initialize all the variables instantiated throughout the entire scan. */
+ globalno = 0;
+ inclevel = 0;
+ seenind = FALSE;
+ seentyp = FALSE;
+ seenlimo = FALSE;
+
+ /* We also have to initialize localno in case the input file is empty and */
+ /* it never gets initialized before being sucked into being used as the */
+ /* local number for the end of file marker. */
+ localno=0;
+
+ /* Initialize the global indentation flag to the default value. */
+ tgindent=TRUE;
+
+ /* Initialize the global product line length limit to the default value. */
+ tglinmax=80;
+
+ /* Initialize the global typesetter flag to the default value. */
+ tr_codes=TR_NONE;
+
+ /* Scan the top level file whose name is obtained from the command line. */
+ as_cold(option.op_f_b,"scanner: -F!!!!");
+
+ /* Work out what the input file name should be. */
+ {
+ fn_t fname;
+ strcpy(fname,""); /* Start with an empty string. */
+ fn_ins(fname,".fw");
+ fn_ins(fname,option.op_f_s);
+ scan_file(fname);
+ }
+
+ /* The scan_file function scans the main input file and all of its included */
+ /* files, but it does not append a TK_EOF token to the end. This call does */
+ /* this and also adds a line to the line list for EOF. */
+ add_eof();
+}
+
+/******************************************************************************/
+/* End of SCANNER.C */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/scanner.h b/web/funnelAC/sources/scanner.h
new file mode 100644
index 0000000000..859538db3c
--- /dev/null
+++ b/web/funnelAC/sources/scanner.h
@@ -0,0 +1,67 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* SCANNER.H */
+/******************************************************************************/
+/* */
+/* This package contains the scanner. When called (though the only exported */
+/* routine below), the scanner maps in the file whose filename is given in */
+/* the global option.op_f_s variable. The scanner scans the file, mapping in */
+/* any included files, and builds two lists in the global list variables */
+/* 'line_list' and 'token_list'. The line list contains a list of the lines */
+/* of the input. The token list contains a tokenized form of the input, which */
+/* is used by the parser. The scanner also sends diagnostics to the lister */
+/* package which has the effect of possibly incrementing the global error */
+/* counters num_*. See data.h for more information on data structures. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "clock.h"
+
+/******************************************************************************/
+
+EXPORT void scanner P_((p_ck_t,p_ck_t));
+/* The arguments are first a mapper clock, and second a scanner clock. The */
+/* scanner should turn off the scanner clock and turn on the mapper clock */
+/* when calling the mapper. */
+
+/******************************************************************************/
+/* End of SCANNER.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/section.c b/web/funnelAC/sources/section.c
new file mode 100644
index 0000000000..129c856018
--- /dev/null
+++ b/web/funnelAC/sources/section.c
@@ -0,0 +1,148 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* SECTION.C */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "as.h"
+#include "section.h"
+
+/******************************************************************************/
+
+#define MAGIC (89201129L) /* Magic number detects uninitialized sections. */
+#define SECMAX (30000L) /* Maximum value of a single level's section num. */
+
+/******************************************************************************/
+
+LOCAL void sn_chk P_((p_sn_t));
+LOCAL void sn_chk(p_sn)
+/* Checks that the given section object has a legal internal state. */
+p_sn_t p_sn;
+{
+ ubyte i;
+
+ as_cold(p_sn->sn_magic==MAGIC,"sn_chk: Section has bad magic number.");
+ as_cold(p_sn->sn_lev<=SECLEV_MAX,
+ "sn_chk: Section has bad level number.");
+ for (i=1;i<=p_sn->sn_lev;i++)
+ as_cold(p_sn->sn_num[i]>0,
+ "sn_chk: Section has zero hierarchical number.");
+}
+
+/******************************************************************************/
+
+EXPORT void sn_ini(p_sn)
+p_sn_t p_sn;
+{
+ p_sn->sn_magic = MAGIC;
+ p_sn->sn_lev = 0;
+}
+
+/******************************************************************************/
+
+EXPORT void sn_set(p_sn,level)
+p_sn_t p_sn;
+ubyte level;
+{
+ ubyte i;
+ sn_chk(p_sn);
+ as_cold(level>0 && level<=SECLEV_MAX,
+ "sn_set: Specified level is too high.");
+ p_sn->sn_lev=level;
+ for(i=1;i<=level;i++)
+ p_sn->sn_num[i]=1;
+}
+
+/******************************************************************************/
+
+EXPORT void sn_inc (p_sn,lev)
+p_sn_t p_sn;
+ubyte lev;
+{
+ sn_chk(p_sn);
+
+ /* Check the parameter level. */
+ as_cold(1<=lev && lev<=SECLEV_MAX,"sn_inc: Bad level number specified.");
+
+ /* Check that we are not skipping a hierarchical level. */
+ as_cold(lev<=p_sn->sn_lev+1,"sn_inc: Discountinuous level increment.");
+
+ /* Actually increment the section. */
+ if (lev==p_sn->sn_lev+1) p_sn->sn_num[lev]=0;
+ p_sn->sn_lev=lev;
+ p_sn->sn_num[lev]++;
+
+ /* Check that the section number hasn't got too big. */
+ as_cold(p_sn->sn_num[lev]<=SECMAX,"sn_inc: Section number is too large.");
+}
+
+/******************************************************************************/
+
+EXPORT ubyte sn_lev(p_sn)
+p_sn_t p_sn;
+{
+ sn_chk(p_sn);
+ return p_sn->sn_lev;
+}
+
+/******************************************************************************/
+
+EXPORT void sn_str(p_sn,s)
+p_sn_t p_sn;
+char *s;
+{
+ char t[20];
+ ubyte i;
+
+ sn_chk(p_sn);
+
+ s[0]=EOS;
+ for (i=1;i<=p_sn->sn_lev;i++)
+ {
+ if (i>1) strcat(s,".");
+ sprintf(t,"%u",(unsigned) p_sn->sn_num[i]);
+ strcat(s,t);
+ }
+}
+
+/******************************************************************************/
+/* End of SECTION.C */
+/******************************************************************************/
+
diff --git a/web/funnelAC/sources/section.h b/web/funnelAC/sources/section.h
new file mode 100644
index 0000000000..3bea8d18b4
--- /dev/null
+++ b/web/funnelAC/sources/section.h
@@ -0,0 +1,120 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* SECTION.H */
+/******************************************************************************/
+/* */
+/* This package provides a very simple, very small abstraction for a section */
+/* number. A section number is a hierarchical group of numbers such as is */
+/* used to number the sections in documents. For example: 4.5.1.3 is a */
+/* section number. This package provides an abstraction for these numbers */
+/* that assists in their incrementing at different levels and in writing them */
+/* out. The package also checks for hierarchical inconsistencies. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_SECTION
+#define DONE_SECTION
+
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+/* The following constant defines the maximum number of levels that a */
+/* FunnelWeb document can have. @A corresponds to level 1. */
+#define SECLEV_MAX 5
+
+/* The following constant defines the maximum length of a string representing */
+/* a section. This is calculated as the maximum number of levels multiplied */
+/* by 1 (for the separating dots) plus a safe size for a decimal number. */
+#define SECSTR_MAX (SECLEV_MAX*(1+10))
+
+/* The following structure stores a single section number. The sc_level */
+/* field is the level of this field and is in the range [1,SECLEV_MAX]. The */
+/* sc_num field is defined only for elements [1,level] and contains the */
+/* hierarchy number at each level. */
+/* Example: For SECLEVMAX=4 and "3.4.1", level=3 and num=[?,3,4,1,?]. */
+/* Note: The first question mark is for element zero which is always unknown. */
+typedef struct
+ {
+ ulong sn_magic; /* Used to detect uninitialized sn objects. */
+ ubyte_ sn_lev; /* Level number of section. */
+ uword_ sn_num[SECLEV_MAX+1]; /* Hierarchical level numbers. */
+ } sn_t;
+
+typedef sn_t *p_sn_t;
+
+/******************************************************************************/
+
+EXPORT void sn_ini P_((p_sn_t));
+/* Initializes the specified section object to the empty section at level 0. */
+/* All sections must be initialized before any other operations are performed.*/
+
+EXPORT void sn_set P_((p_sn_t,ubyte));
+/* Sets the specified section to 1.1.1.1.1.1... at the given level. */
+/* Example: sn_set(p_sn,3) yields a section set to 1.1.1. */
+/* Raises an error if the specified level is out of range. */
+
+EXPORT void sn_inc P_((p_sn_t,ubyte));
+/* Increments the number of the specified section object at the specified */
+/* level. This also has the effect of setting all lower levels to 0. For */
+/* example, 3.4.5.1 followed by sn_inc(&sn,2) would become 3.5. */
+/* Raises an error if the level is two or more lower than the current level */
+/* Example: You can't increment 2.4.1 at level 5. */
+/* Raises an error if the specified level is out of range. */
+/* Raises an error if a number at any level becomes too large (>60000). */
+
+EXPORT ubyte sn_lev P_((p_sn_t));
+/* Returns the level number of the specified section. */
+
+EXPORT void sn_str P_((p_sn_t,char *));
+/* Writes a textual representation of the specified section into the given */
+/* string. The string must be able to hold at least SECSTRMAX characters. */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of SECTION.H */
+/******************************************************************************/
+
diff --git a/web/funnelAC/sources/style.h b/web/funnelAC/sources/style.h
new file mode 100644
index 0000000000..f481e99bfa
--- /dev/null
+++ b/web/funnelAC/sources/style.h
@@ -0,0 +1,258 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* STYLE.H */
+/******************************************************************************/
+/* */
+/* WARNING: DO NOT ADD ANY MACHINE OR PROGRAM DEPENDENT DEFINITIONS. */
+/* */
+/* This style.h file contains program-independent, machine-independent */
+/* definitions that assist C programming in general. Nothing in this file */
+/* should require modification if this file is moved to a new machine or used */
+/* in a new computer program. However, it may use abstracted second-order */
+/* definitions from the machine-dependent, program independent module */
+/* "environ". */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_STYLE
+#define DONE_STYLE
+
+/******************************************************************************/
+
+/* System File Inclusions */
+/* ---------------------- */
+/* In order to support a readable programming style, symbols such as TRUE and */
+/* NULL are essential. However, environments differ as to whether and where */
+/* these symbols are defined. This can lead to multiple definition errors */
+/* where (say) this style.h file is included in a .C file before <stdlib.h>. */
+/* I did a quick survey of all the .C FunnelWeb modules and found the */
+/* following: */
+/* */
+/* Total files = 54 */
+/* Number .C files = 22 */
+/* Number .H files = 32 */
+/* Used <stdlib.h> = 19 */
+/* Used <stdio.h> = 16 */
+/* Used <string.h> = 12 */
+/* Used <ctype.h> = 6 */
+/* Used <stddef.h> = 4 */
+/* Used <limits.h> = 2 */
+/* Used <setjmp.h> = 1 */
+/* */
+/* Most of these inclusions were in the .C files. */
+/* It therefore seemed sensible to include some very commonly used system */
+/* header files here and header files that cause problems if not included */
+/* before style.h (<stddef.h>). */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+
+/******************************************************************************/
+
+/* Although this file is machine independent, it still needs some generic */
+/* definitions whose values vary from machine to machine (see above). */
+#include "environ.h"
+
+/******************************************************************************/
+
+/* The following types provide a clear and consistent collection of names for */
+/* C's arithmetic types. Each name describes only the portable range that the */
+/* underlying type supports. As in C, there are no guarantees about the */
+/* MAXIMUM size of each underlying type and these types can provide no */
+/* guarantees either. In the normal case, they translate to the most speed */
+/* efficient type that will support the specified range. However, to support */
+/* the situations where space efficiency is required, types ending in */
+/* underscores have been defined that strive to conserve memory. */
+/* Note: The signedness of a type does not change when an _ is added. */
+/* */
+/* The following terminology may be a touch vaxcentric, but it works for me. */
+/* A BYTE is an 8 bit quantity. */
+/* A WORD is a 16 bit quantity. */
+/* A LONG is a 32 bit quantity. */
+
+typedef unsigned ubyte ; /* Unsigned, [0,255]. */
+typedef unsigned char ubyte_ ; /* Unsigned, [0,255]. Space first. */
+typedef int word ; /* Signed , [-32767,+32767]. */
+typedef short word_ ; /* Signed , [-32767,+32767]. Space first. */
+typedef unsigned uword ; /* Unsigned, [0,65535]. */
+typedef unsigned short uword_ ; /* Unsigned, [0,+65535]. Space first. */
+typedef unsigned long ulong ; /* Unsigned, [0,(2^32)-1]. */
+
+typedef unsigned bool ; /* Unsigned, [0,1]. */
+typedef unsigned char bool_ ; /* Unsigned, [0,1]. Space first. */
+
+typedef int sign ; /* Signed , [-1,0,1]. */
+
+/******************************************************************************/
+
+/* C overloads the attribute keyword "static" horribly giving it meaning on */
+/* both the scoping and lifetime dimensions. This section gives definitions */
+/* that clarify its use. If these macros are used, there should be no need */
+/* for the keyword "static" in programs using this style file. */
+
+/* The following macros assist in making the scope of functions clearer. In */
+/* deciding on the names of these macros, I chose from the following lists: */
+/* file scope: PRIVATE, LOCAL, HIDDEN. */
+/* program scope: EXPORT, PUBLIC, GLOBAL. */
+/* In the end I chose LOCAL and EXPORT. Note: I didn't want to allow more */
+/* than one form as that would have created too much confusion. */
+#define LOCAL static
+#define EXPORT
+
+/* It is desirable to use separate keywords for variables. This makes it */
+/* easier to search for them without stopping at every function. There are */
+/* four classes of variable that we wish to tag, along the two dimensions */
+/* scope:(local,global) and lifetime:(permanent,temporary). In C, all */
+/* variables declared outside of functions have permanent lifetime and so */
+/* the following two names (which should be used only to tag variables not */
+/* declared within a function) have been designed to emphasise the scope */
+/* dimension which is the principal concern for these variables. */
+#define LOCVAR static
+#define GLOVAR
+
+/* Variables local to functions always have local scope and so the dimension */
+/* to emphasise is the lifetime. Automatic variables are the most common in */
+/* C and it would be messy to declare them all using a keyword. Far better */
+/* just to tag static local variables, emphasising their lifetime (STAtic). */
+#define STAVAR static
+
+/******************************************************************************/
+
+/* The following definitions are useful for dealing with void. */
+/* The typedefed definition "p_void" should always be used instead of */
+/* "void *" so as to improve portability. */
+/* The definition of "void" and "p_void" come from environ.h */
+typedef p_void *p_p_void;
+#define PV (p_void)
+#define PPV (p_p_void)
+
+/******************************************************************************/
+
+/* The following symbols are more mnemonic than character escape sequences. */
+#define EOS '\0'
+#define EOL '\n'
+
+/******************************************************************************/
+
+/* The ANSI library functions use many different techniques for returning */
+/* status information. For example, fopen returns NULL upon failure, but */
+/* fclose returns EOF upon failure. The result is that it is hard to */
+/* proofread calls to these routines without constantly referring to the */
+/* library manual. To avoid this problem, we define symbols with helpful */
+/* names for the different values returned. This makes the code obvious. */
+
+/* 07-Feb-1992: During porting I ran into a problem here with FPUTS_S. I had */
+/* defined it to be zero, as stated in the THINK C V4 ANSI library guide. */
+/* However, it turned out that fputs() returns EOF (-1) on failure and the */
+/* value that it returns on success is non negative! (See ANSI (7.9.7.4)). */
+/* Caught by an overspecification by the THINK C people! The lesson is that */
+/* it is very important to make sure that each function's status check symbol */
+/* is defined on the "right" side (success or failure) - that is, the side */
+/* for which a single value for that status is guaranteed portably. */
+/* The following values have all been checked for this. */
+
+/* Note: _F=Failure, _S=Success, _FE=Failure or End of File. */
+
+#define FOPEN_F (NULL)
+#define FSEEK_S (0)
+#define FTELL_F (-1L)
+#define FGETC_FE (EOF)
+#define FGETS_FE (NULL)
+#define FPUTC_F (EOF)
+#define FPUTS_F (EOF)
+#define FFLUSH_S (0)
+#define FCLOSE_F (EOF)
+#define REMOVE_S (0)
+#define RENAME_S (0)
+#define MALLOC_F (NULL)
+
+/******************************************************************************/
+
+/* The following macro functions are handy. However, be sure not to hand them */
+/* an argument with a non-idempotent side effect!!! (e.g. MAX(a++,b)). */
+#define MIN(A,B) ((A)<(B) ? (A) : (B))
+#define MAX(A,B) ((A)>(B) ? (A) : (B))
+
+/******************************************************************************/
+
+/* Some environments don't define some stuff we need so we do it here. */
+/* Cautiously! */
+
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE (-1)
+#endif
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS (0)
+#endif
+
+/******************************************************************************/
+
+/* The standard library macro/function "isprint" can be too loose in some */
+/* circumstances on some machines and it is convenient to define a macro */
+/* that provides a more strict 7-bit ASCII definition of "printable". */
+#define isascprn(ch) ((' '<=ch) && (ch<='~'))
+
+/******************************************************************************/
+
+/* Some compilers (GCC at least) complain about characters as a type in a */
+/* function argument. The following typedef is a quick hack that lets me say */
+/* that I really wanted the function argument to be a character, while */
+/* actually supplying an integer. */
+typedef int intchar;
+
+/******************************************************************************/
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of STYLE.H */
+/******************************************************************************/
+
diff --git a/web/funnelAC/sources/table.c b/web/funnelAC/sources/table.c
new file mode 100644
index 0000000000..b2a64cda7c
--- /dev/null
+++ b/web/funnelAC/sources/table.c
@@ -0,0 +1,429 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* TABLE.C */
+/******************************************************************************/
+/* */
+/* Notes */
+/* ----- */
+/* - There are few comments at the start of each function. As definitions */
+/* appear in the .H file, and it is dangerous to duplicate definitions, I */
+/* have simply omitted them here. */
+/* */
+/* About The Cache */
+/* --------------- */
+/* A typical usage sequence for tables is for the user to first call tb_itb */
+/* to see if a key is in the table and then call either tb_loo or tb_ins */
+/* to lookup the value or to add a new (key,value) pair to the table. */
+/* In order to avoid performing TWO searches down the binary tree in such */
+/* cases, a CACHE is maintained in the table data structure between calls. */
+/* */
+/* ca_valid stores whether the cache contents are valid. If TRUE then: */
+/* ca_p_key points to a key. */
+/* ca_p_node points to the node in the tree containing the key, or contains */
+/* NULL if no such node exists. */
+/* ca_p_parent points to the node in the tree that is the parent of the node */
+/* ca_p_node in the tree, or (if ca_p_node==NULL) WOULD BE the parent if a */
+/* node containing the key were inserted in the tree. If the tree is */
+/* currently empty, ca_p_parent will be NULL. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "as.h"
+#include "machin.h"
+#include "memory.h"
+
+/******************************************************************************/
+
+/* In order to catch uninitialized and corrupted tables, the first and last */
+/* fields of legitimate table objects contain magic numbers. The following */
+/* #defines give the values of these numbers. The first thing that each */
+/* function of this package does is to check the two magic number fields of */
+/* the table it has just been passed, and bomb the package if the fields have */
+/* the wrong values. This technique is likely to pick uninitialized tables, */
+/* as well as tables that have been partially overwritten. */
+#define MAGIC_HEAD_VALUE (53456839L)
+#define MAGIC_TAIL_VALUE (28434290L)
+
+/* Comparing keys is messy and so we define a macro to help us out. */
+#define key_compare(a,b) ((*(p_tb->p_kycm))((a),(b)))
+
+/******************************************************************************/
+
+/* The functions of the table abstraction pass keys and values exclusively */
+/* using pointers. These two definitions define types for these pointers. */
+/* Although the two types are both 'p_void', the different types are useful */
+/* to indicate what is expected in each position of the parameter lists. */
+typedef p_void p_tbky_t;
+typedef p_void p_tbvl_t;
+
+/* Define a type for a function to compare two keys. Such functions are */
+/* needed to organize the storage of (key,value) pairs inside the table. */
+/* Given the arguments are (a,b), the function should return: */
+/* -1 if a<b */
+/* 0 if a==b */
+/* 1 if a>b */
+/* The user must create such a function and hand it to the 'tb_create' */
+/* function when creating new a new table. */
+typedef sign (*p_kycm_t) P_((p_tbky_t,p_tbky_t));
+
+/* The (key,value) pairs in the table are stored in a binary tree. The tree */
+/* is ordered by the key ordering function passed in at table creation. */
+typedef struct node_t_
+ {
+ struct node_t_ *p_left;
+ struct node_t_ *p_right;
+ struct node_t_ *p_parent;
+ p_tbky_t p_key;
+ p_tbvl_t p_value;
+ }
+ node_t;
+typedef node_t *p_node_t;
+
+/* The type tb_t (table type) defines the root table data record. This */
+/* record stores attributes of the table along with the main binary tree of */
+/* (key,value) pairs. */
+typedef struct
+ {
+ ulong magic_head; /* Magic number to allow corruption checks. */
+ size_t key_bytes; /* Number of bytes in a key. */
+ size_t value_bytes; /* Number of bytes in a value. */
+ p_kycm_t p_kycm; /* Pointer to function to compare keys. */
+ p_node_t tree; /* Ptr to root of (key,value) binary tree. */
+ ulong num_keys; /* Number of (k,v) pairs in the table. */
+ bool ca_valid; /* Cache: TRUE iff cache contents are valid. */
+ p_tbky_t ca_p_key; /* Cache: Key value cache contents refer to. */
+ p_node_t ca_p_node; /* Cache: Pointer to node in binary tree. */
+ p_node_t ca_p_parent; /* Cache: Pointer to parent of ca_p_node. */
+ p_node_t p_read_next; /* Pointer to next node to be read. */
+ ulong magic_tail; /* Magic number to allow corruption checks. */
+ } tb_t;
+
+typedef tb_t *p_tb_t; /* Pointer to main table record. */
+
+/* Defining INTABLEC hides the abstract definition. */
+#define INTABLEC
+#include "table.h"
+
+/******************************************************************************/
+/* PRIVATE FUNCTIONS */
+/******************************************************************************/
+
+LOCAL p_node_t new_node P_((p_tb_t,p_tbky_t,p_tbvl_t));
+LOCAL p_node_t new_node(p_tb,p_tbky,p_tbvl)
+/* Creates a new tree node and returns a pointer to it. */
+/* p_tb is the table for which the new node is to be created. */
+/* p_tbky and p_tbvl point to the key and value to go in the new node. */
+/* Assumes that a tb_check(p_tb) has already been performed by the caller. */
+p_tb_t p_tb;
+p_tbky_t p_tbky;
+p_tbvl_t p_tbvl;
+{
+ p_node_t p_node;
+
+ p_node=(p_node_t) mm_temp(sizeof(node_t));
+
+ p_node->p_left = NULL;
+ p_node->p_right = NULL;
+ p_node->p_parent = NULL;
+ p_node->p_key = mm_temp(p_tb->key_bytes );
+ p_node->p_value = mm_temp(p_tb->value_bytes);
+
+ memcpy(p_node->p_key ,p_tbky,p_tb->key_bytes );
+ memcpy(p_node->p_value,p_tbvl,p_tb->value_bytes);
+
+ return p_node;
+}
+
+/******************************************************************************/
+
+LOCAL void tb_check P_((p_tb_t));
+LOCAL void tb_check(p_tb)
+/* Accepts a pointer to a table and performs a series of checks to make sure */
+/* that the table has not been corrupted in some way. */
+p_tb_t p_tb;
+{
+ as_cold(p_tb!=NULL,"tb_check: Table pointer is NULL.");
+ as_cold(p_tb->magic_head==MAGIC_HEAD_VALUE,
+ "tb_check: Magic number at head of record is incorrect.");
+ as_cold(p_tb->magic_tail==MAGIC_TAIL_VALUE,
+ "tb_check: Magic number at tail of record is incorrect.");
+}
+
+/******************************************************************************/
+
+LOCAL p_node_t min_leaf P_((p_node_t));
+LOCAL p_node_t min_leaf(p_node)
+/* Returns a pointer to the node that is leftmost (has the smallest value */
+/* according to the ordering function) in the specified node's subtree. */
+p_node_t p_node;
+{
+ if (p_node==NULL)
+ return NULL;
+ while (p_node->p_left != NULL)
+ p_node=p_node->p_left;
+ return p_node;
+}
+
+/******************************************************************************/
+
+LOCAL p_node_t next_node P_((p_node_t));
+LOCAL p_node_t next_node(p_node)
+/* Give a pointer to a node in the binary tree, returns a pointer to the next */
+/* node (in sequence defined by the order function) or NULL if the given node */
+/* is the last node in the ordered sequence. */
+p_node_t p_node;
+{
+ /* If there is a right subtree, we need the minimum node of that subtree. */
+ if (p_node->p_right != NULL)
+ return min_leaf(p_node->p_right);
+
+ /* Otherwise go up as far as possible through right arcs. */
+ while (p_node->p_parent!=NULL && p_node->p_parent->p_right==p_node)
+ p_node=p_node->p_parent;
+ return p_node->p_parent;
+}
+
+/******************************************************************************/
+
+LOCAL void tb_search P_((p_tb_t,p_tbky_t));
+LOCAL void tb_search(p_tb,p_tbky)
+/* Calling this function with a particular key value results in the cache */
+/* becoming valid and containing the specified key. */
+p_tb_t p_tb;
+p_tbky_t p_tbky;
+{
+ p_node_t p,p_parent;
+
+ tb_check(p_tb);
+
+ /* Return if the cache is already up to date. */
+ if (p_tb->ca_valid)
+ if (key_compare(p_tbky,p_tb->ca_p_key) == 0)
+ return;
+
+ p_parent=NULL;
+ p=p_tb->tree;
+ while (p != NULL)
+ switch(key_compare(p_tbky,p->p_key))
+ {
+ case -1: p_parent=p; p=p->p_left; break;
+ case 1: p_parent=p; p=p->p_right; break;
+ case 0: goto found;
+ default:
+ as_bomb("tb_search: Key comparison function returned bad value.");
+ }
+ found:
+ p_tb->ca_valid = TRUE;
+ memcpy(p_tb->ca_p_key,p_tbky,p_tb->key_bytes);
+ p_tb->ca_p_node = p;
+ p_tb->ca_p_parent = p_parent;
+}
+
+/******************************************************************************/
+
+LOCAL void des_tree P_((p_node_t));
+LOCAL void des_tree(p_root)
+p_node_t p_root;
+{
+ if (p_root==NULL)
+ return;
+ des_tree(p_root->p_left);
+ des_tree(p_root->p_right);
+
+ /* This is what we would need if it wasn't for the MM watermark system. */
+ /* DEALLOCATE(PV p_root); */
+}
+
+/******************************************************************************/
+/* EXPORTED FUNCTIONS */
+/******************************************************************************/
+
+EXPORT p_tb_t tb_cre(key_bytes,value_bytes,p_kycm)
+size_t key_bytes;
+size_t value_bytes;
+p_kycm_t p_kycm;
+{
+ p_tb_t p_tb;
+
+ p_tb = (p_tb_t) mm_temp(sizeof(tb_t));
+ p_tb->magic_head = MAGIC_HEAD_VALUE;
+ p_tb->key_bytes = key_bytes;
+ p_tb->value_bytes = value_bytes;
+ p_tb->p_kycm = p_kycm;
+ p_tb->tree = NULL;
+ p_tb->num_keys = 0;
+ p_tb->ca_valid = FALSE;
+ p_tb->ca_p_key = (p_tbky_t) mm_temp(key_bytes);
+ p_tb->ca_p_node = NULL; /* This initialization not strictly necessary. */
+ p_tb->ca_p_parent = NULL; /* This initialization not strictly necessary. */
+ p_tb->p_read_next = NULL;
+ p_tb->magic_tail = MAGIC_TAIL_VALUE;
+
+ return p_tb;
+}
+
+/******************************************************************************/
+
+EXPORT bool tb_itb(p_tb,p_tbky)
+p_tb_t p_tb;
+p_tbky_t p_tbky;
+{
+ tb_check(p_tb);
+
+ tb_search(p_tb,p_tbky);
+ return p_tb->ca_p_node != NULL;
+}
+
+/******************************************************************************/
+
+EXPORT void tb_loo(p_tb,p_tbky,p_tbvl)
+p_tb_t p_tb;
+p_tbky_t p_tbky;
+p_tbvl_t p_tbvl;
+{
+ tb_check(p_tb);
+
+ tb_search(p_tb,p_tbky);
+ as_cold(p_tb->ca_p_node!=NULL,"tb_loo: Requested key is absent.");
+ memcpy(p_tbvl,p_tb->ca_p_node->p_value,p_tb->value_bytes);
+}
+
+/******************************************************************************/
+
+EXPORT void tb_ins(p_tb,p_tbky,p_tbvl)
+p_tb_t p_tb;
+p_tbky_t p_tbky;
+p_tbvl_t p_tbvl;
+{
+ p_node_t p_new;
+
+ tb_check(p_tb);
+
+ /* Validate the cache. Note: tb_search does it's own cache check. */
+ tb_search(p_tb,p_tbky);
+
+ /* Ensure that the table does not already contain the key. */
+ as_cold(p_tb->ca_p_node==NULL,"tb_ins: Key is already present in the p_tb.");
+
+ /* Create the new node. */
+ p_new=new_node(p_tb,p_tbky,p_tbvl);
+
+ /* Insert the new node into the tree. */
+ if (p_tb->ca_p_parent==NULL)
+ p_tb->tree=p_new;
+ else
+ switch(key_compare(p_tbky,p_tb->ca_p_parent->p_key))
+ {
+ case -1: p_tb->ca_p_parent->p_left =p_new; break;
+ case 1: p_tb->ca_p_parent->p_right=p_new; break;
+ default: as_bomb("tb_ins: Key comparison function is inconsistent.");
+ }
+ p_new->p_parent=p_tb->ca_p_parent;
+
+ /* Need to fiddle cache to make it correct, and inc num_keys. */
+ p_tb->ca_p_node=p_new;
+ p_tb->num_keys++;
+}
+
+/******************************************************************************/
+
+EXPORT ulong tb_len(p_tb)
+p_tb_t p_tb;
+{
+ tb_check(p_tb);
+ return p_tb->num_keys;
+}
+
+/******************************************************************************/
+
+EXPORT void tb_fir(p_tb)
+p_tb_t p_tb;
+{
+ tb_check(p_tb);
+
+ p_tb->p_read_next=min_leaf(p_tb->tree);
+}
+
+/******************************************************************************/
+
+EXPORT bool tb_rea(p_tb,p_tbky,p_tbvl)
+p_tb_t p_tb;
+p_tbky_t p_tbky;
+p_tbvl_t p_tbvl;
+{
+ tb_check(p_tb);
+
+ if (p_tb->p_read_next == NULL)
+ return FALSE;
+
+ memcpy(p_tbky,p_tb->p_read_next->p_key ,p_tb->key_bytes );
+ memcpy(p_tbvl,p_tb->p_read_next->p_value,p_tb->value_bytes);
+
+ p_tb->p_read_next=next_node(p_tb->p_read_next);
+
+ return TRUE;
+}
+
+/******************************************************************************/
+
+#if FALSE
+EXPORT void tb_des(p_tb)
+p_tb_t p_tb;
+{
+ /* This routine now unused because of the watermark system. */
+ return;
+
+ /* tb_check(p_tb); */
+
+ /* Zap the magic numbers in case the memory is re-used in same alignment. */
+ /* p_tb->magic_head=0; */
+ /* p_tb->magic_tail=0; */
+
+ /* This is what we would need if it wasn't for the MM watermark system. */
+ /* des_tree(p_tb->tree); */ /* Zap the binary tree. */
+ /* DEALLOCATE(PV p_tb); */ /* Zap the node itself. */
+}
+#endif
+
+/******************************************************************************/
+/* TABLE.C */
+/******************************************************************************/
+
diff --git a/web/funnelAC/sources/table.h b/web/funnelAC/sources/table.h
new file mode 100644
index 0000000000..ba8ec90d6a
--- /dev/null
+++ b/web/funnelAC/sources/table.h
@@ -0,0 +1,189 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* TABLE.H */
+/******************************************************************************/
+/* */
+/* Introduction */
+/* ------------ */
+/* This table package (table.h and table.c) implements a table abstraction. */
+/* */
+/* Facts about Tables */
+/* ------------------ */
+/* - A TABLE stores zero or more (KEY,VALUE) PAIRS. */
+/* - The user decides the types of keys and values and provides a */
+/* COMPARISON FUNCTION providing a complete ordering of the set of keys. */
+/* - The comparison function must be consistent between calls. */
+/* - Tables store pairs in key order. */
+/* - A table cannot store more than one pair with the same key. */
+/* - Pairs can be added, but not deleted. */
+/* - A table can return the value corresponding to a given key. */
+/* - The pairs in a table can be read sequentially in key order. At all */
+/* times, the table has an imaginary MARKER positioned on one of its pairs */
+/* (or after the last pair). You can move the marker to the first pair and */
+/* you can move the marker to the next pair, reading the pair as you go. */
+/* Upon table creation, a table's marker is at the end-of-table position. */
+/* - If you try to perform an illegal operation on a table, the table package */
+/* will call "error" to write out an error message and bomb the program. */
+/* - Tables store copies of (key,value) pairs. They do not hold pointers to */
+/* outside data (unless your keys or values are pointers themselves). */
+/* - If the keys are pointers themselves and point to other data which is */
+/* used by the comparison function, then that data must not be modified */
+/* in a way that will change the order of pairs in the table. */
+/* - A table can hold from zero to about 2^31 pairs. */
+/* - The identifier "tb" is used as an abbreviation for "table". */
+/* - The identifier "ky" is used as an abbreviation for "key". */
+/* - The identifier "vl" is used as an abbreviation for "value". */
+/* - The author would like to use longer names, but has chosen to use the */
+/* abbreviations so as to enhance the portability of the code. */
+/* - IMPORTANT: Tables get all their memory using mm_temp calls. */
+/* */
+/* How To Use This Table Package */
+/* ----------------------------- */
+/* 1. Include this .H file in your program file. */
+/* 2. Identify the key and value types that you are going to use. */
+/* 3. Define a function (having two parameters being pointers to keys) */
+/* that compares two keys and returns [-1,0,1] accordingly. */
+/* 4. Define a variable of type p_tb as a view to a table. */
+/* 5. Use the tb_* functions to perform the desired operations. */
+/* Start with a call to tb_cre and (optionally) end with a call to tb_des. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_TABLE
+#define DONE_TABLE
+
+/******************************************************************************/
+
+#include <stddef.h>
+#include "style.h"
+
+/******************************************************************************/
+
+/* Hide the exported abstract definition of a table from the table.c package. */
+/* Table.c defines INTABLEC so as to prevent itself from seeing the following */
+/* definitions. It defines its own more concrete definitions. */
+#ifndef INTABLEC
+
+/* The functions of the table abstraction pass keys and values exclusively */
+/* using pointers. These two definitions define types for these pointers. */
+/* Although the two types are both 'p_void', the different types are useful */
+/* to indicate what is expected in each position of the parameter lists. */
+typedef p_void p_tbky_t;
+typedef p_void p_tbvl_t;
+
+/* Define a type for a function to compare two keys. Such functions are */
+/* needed to organize the storage of (key,value) pairs inside the table. */
+/* Given the arguments are (a,b), the function should return: */
+/* -1 if a<b */
+/* 0 if a==b */
+/* 1 if a>b */
+/* The user must create such a function and hand it to the 'tb_create' */
+/* function when creating new a new table. */
+typedef sign (*p_kycm_t) P_((p_tbky_t,p_tbky_t));
+
+/* Users manipulate tables through pointers to tables. Here the actual table */
+/* internals are hidden from the user. */
+typedef struct {word NEVER_USE_THIS_FIELD_UQJTKC;} tb_t;
+typedef tb_t *p_tb_t;
+
+#endif
+
+/******************************************************************************/
+
+/* General Notes About These Functions */
+/* ----------------------------------- */
+/* - All tables, keys, and values are passed by pointer. Whether a parameter */
+/* is read or written is determined by it's functions description. */
+/* - Each function (except tb_cre) accepts a single pointer to a table and */
+/* each function's description is assumed to be referring to the table. */
+/* - "Raising an error" means calling the external function "error" to */
+/* write out a message and bomb the program. */
+/* - You must create a table using tb_cre before performing any operations */
+/* upon it. The table operations will usually raise an error if they are */
+/* handed a pointer that does not point to a properly CREated table. */
+
+/* The Functions */
+/* ------------- */
+EXPORT p_tb_t tb_cre P_((size_t,size_t,p_kycm_t));
+/* CREate. This function creates a new table and returns a pointer to the */
+/* table. The user must supply 1) the size in bytes of keys, 2) the size in */
+/* bytes of values, 3) a pointer to a function that compares two keys. */
+
+EXPORT bool tb_itb P_((p_tb_t,p_tbky_t));
+/* InTaBle. Returns TRUE iff the given key is in the table. */
+
+EXPORT void tb_loo P_((p_tb_t,p_tbky_t,p_tbvl_t));
+/* LOOkup. Feed this function a table and a key and it will return (in the */
+/* p_tbvl_t parameter) the value corresponding to the key. The function */
+/* raises an error if the table does not contain the key. */
+
+EXPORT void tb_ins P_((p_tb_t,p_tbky_t,p_tbvl_t));
+/* INSert. Inserts the (key,value) pair into the table. Raises an error if */
+/* the key is already in the table. */
+
+EXPORT ulong tb_len P_((p_tb_t));
+/* LENgth. Returns the number of pairs in the table. */
+
+EXPORT void tb_fir P_((p_tb_t));
+/* FIRst. Set's the table's marker to the first pair in the table (or the end */
+/* of table position if the table is empty. */
+
+EXPORT bool tb_rea P_((p_tb_t,p_tbky_t,p_tbvl_t));
+/* REAd. Returns in (p_tbky_t,p_tbvl_t) the (key,value) pair corresponding to */
+/* the marker and them moves the marker onto the next pair. */
+/* Returns TRUE => Returned a pair. */
+/* Returns FALSE => Did not return a pair. No more pairs left. */
+/* of key) to be read from the table. Returns TRUE if it returns a pair */
+/* This function will not raise an error if it is called more than once with */
+/* the marker at the end of the table (it just keeps returning FALSE). */
+
+#if FALSE
+void tb_des P_((p_tb_t));
+/* DEStroy. Destroys a table, deallocating all its memory. */
+#endif
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of TABLE.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/tangle.c b/web/funnelAC/sources/tangle.c
new file mode 100644
index 0000000000..b40b7b0fe6
--- /dev/null
+++ b/web/funnelAC/sources/tangle.c
@@ -0,0 +1,539 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* TANGLE.C */
+/******************************************************************************/
+
+/* Note: In this module, "ex_" at the start of a function name means "expand" */
+/* rather than the standard meaning of "ex" of "expression. */
+
+/******************************************************************************/
+
+#include "style.h"
+
+#include "as.h"
+#include "data.h"
+#include "lister.h"
+#include "memory.h"
+#include "misc.h"
+#include "table.h"
+#include "tangle.h"
+#include "writfile.h"
+
+/******************************************************************************/
+
+/* The following variable keeps track of the output line number. This is */
+/* needed to report lines that are too long. */
+LOCVAR ulong lineno;
+
+/* Last line for which error message was generated. */
+LOCVAR ulong errlin;
+
+/* Number of too-long lines seen so far in this file. */
+LOCVAR ulong numlong;
+/* Number of long line error messages we can tolerate per product file. */
+#define LONGMESS 5
+
+/* Note: An indentation of n means n blanks before current material. */
+/* tgindent is a global variable set by the scanner. It is TRUE if blank */
+/* indenting is required and FALSE if no indenting is required. */
+LOCVAR ulong ind_base; /* Base indenting level of macro being expanded. */
+LOCVAR ulong ind_curr; /* Current indenting position. */
+
+LOCVAR char *fn_targ; /* Name of current (target) product file. */
+LOCVAR wf_t f_o; /* Current product file. */
+
+/******************************************************************************/
+
+/* The expression expansion function has to have a forward declaration. */
+LOCAL void ex_ex P_((p_ells_t));
+
+/******************************************************************************/
+
+LOCAL void eolblank P_((ulong));
+LOCAL void eolblank(n)
+/* Writes an EOL followed by n blanks to the product file. Efficiently! */
+ulong n;
+{
+ /* The whole aim of this routine is to write blanks EFFICIENTLY. In */
+ /* particular avoiding any per-char procedure call overhead (e.g. calls to */
+ /* wf_chr). The best way to avoid this is to create a static array of blanks */
+ /* and write out large blocks of blanks all at once. */
+#define BLANKLEN 100 /* Number of BLANKS in blank array. */
+ STAVAR bool notinit=TRUE; /* Has blank array been initialized? */
+ STAVAR char blanks[1+BLANKLEN]; /* EOL followed by BLANKLEN blanks. */
+
+ /* Set up the blank array. This only ever done once because of the static */
+ /* boolean. Note that use of an initialized static here does not make the */
+ /* code non-reentrant, as the state does not change after initialization. */
+ if (notinit)
+ {blanks[0]=EOL; memset(blanks+1,' ',(size_t) BLANKLEN); notinit=FALSE;}
+
+ /* The most common case will be a small indentation. Do this case fast. */
+ if (n<=BLANKLEN)
+ wf_blk(&f_o,&blanks[0],(size_t) n+1);
+ else
+ {
+ /* We now know that n>=BLANKLEN. Write out a long line with \n at front. */
+ wf_blk(&f_o,&blanks[0],BLANKLEN+1); n-=BLANKLEN;
+
+ /* Now get into large scale blank production! */
+ while (n>0)
+ {
+ ulong len=MIN(n,BLANKLEN);
+ wf_blk(&f_o,&blanks[1],(size_t) len); n-=len;
+ }
+ }
+}
+
+/******************************************************************************/
+
+#define SENDLINE {wl_l(linet1); if (option.op_s_b) wl_sj(linet1);}
+
+LOCAL void ex_sc P_((p_sc_t));
+LOCAL void ex_sc(p_sc)
+/* This function writes the specified scrap to the product file. It also */
+/* performs two other tasks: */
+/* If tgindent==TRUE, inserts indentation at the start of each line. */
+/* If tglinmax>0, checks for product file lines longer than tglinmax. */
+/* Note: The speed of this routine is fairly critical. */
+p_sc_t p_sc;
+{
+ /* Output of a scrap is straightforward if we are not inserting indentation */
+ /* or watching for lines that are too long. If neither of these tasks have */
+ /* to be performed, we can bang the scrap out directly with a wf_blk. */
+ if (!tgindent && tglinmax==TGMAXINF)
+ {
+ wf_blk(&f_o, p_sc->sc_first, (size_t) (p_sc->sc_last-p_sc->sc_first+1));
+ return;
+ }
+
+ /* Otherwise it gets rather messy. Basically, we have to watch for end of */
+ /* lines and perform special actions there. */
+ /* ind_curr is the number of characters already written to the current line. */
+ {
+ char *p = p_sc->sc_first;
+ char *p_post = p_sc->sc_last+1;
+ while (TRUE)
+ {
+ char *p_sot = p; /* SOT=Start of Text. */
+
+ /* Scan scrap until we hit either its end or an EOL. */
+ while (p!=p_post && *p!=EOL) p++;
+
+ /* Assert: p==p_post || (p_sot<=p<p_post && *p==EOL). */
+
+ /* If we scanned any non-EOL text, write out what we scanned. */
+ if (p>p_sot) {wf_blk(&f_o,p_sot,(size_t) (p-p_sot));ind_curr+=p-p_sot;}
+
+ /* Check that what we have written so far is not too long. */
+ /* Performing this check here rather than with the EOL processing */
+ /* means that we will detect overlong final non-EOL terminated lines. */
+ /* Use of errlin suppresses multiple errors on the same line. */
+ /* Note: We assume that TGMAXINF is very large. */
+ if (ind_curr>tglinmax && lineno!=errlin)
+ {
+ numlong++;
+ if (numlong <= LONGMESS)
+ {
+ if (option.op_b7_b)
+ sprintf(linet1,
+ "E: Product file line is too long (line %lu of \"%s\").",
+ (ulong) lineno,SUPPNAME);
+ else
+ sprintf(linet1,
+ "E: Product file line is too long (line %lu of \"%s\").",
+ (ulong) lineno,fn_targ);
+ SENDLINE;
+ if (numlong==1)
+ {
+ sprintf(linet1," Product file line length limit is %lu characters.",
+ (ulong) tglinmax);
+ SENDLINE;
+ sprintf(linet1," Note: You can change the limit by specifying.");
+ SENDLINE;
+ sprintf(linet1," @p maximum_output_line_length = <desired length>");
+ SENDLINE;
+ sprintf(linet1," somewhere in the input file.");
+ SENDLINE;
+ }
+ errlin=lineno;
+ num_err++;
+ }
+ if (numlong == LONGMESS+1)
+ {
+ sprintf(linet1,
+ "Further line-too-long warnings for file \"%s\" have been suppressed.",
+ fn_targ);
+ SENDLINE;
+ }
+ }
+
+ /* Exit if we hit the end of the scrap. */
+ if (p==p_post) break;
+
+ /* Move past the EOL and bump up the line counter. */
+ p++; lineno++;
+
+ /* Output an EOL with indentation if desired. */
+ if (tgindent)
+ eolblank(ind_base);
+ else
+ wf_chr(&f_o,EOL);
+ ind_curr=ind_base;
+ }
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void ex_eltx P_((p_el_t));
+LOCAL void ex_eltx(p_el)
+/* Writes the given text element to the product file. */
+p_el_t p_el;
+{
+ p_sc_t p_sc;
+
+ /* Make sure that we have actually been handed a text element. */
+ as_cold(p_el->el_kind==EL_TEXT,"ex_eltx: Not a text element!");
+
+ /* Write all the scraps in the text list to the product file. */
+ ls_fir(p_el->el_text);
+ while (TRUE)
+ {
+ ls_nxt(p_el->el_text,PPV &p_sc);
+ if (p_sc==NULL) break;
+ ex_sc(p_sc);
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void ex_elpr P_((p_el_t));
+LOCAL void ex_elpr(p_el)
+/* Write the expansion of the given parameter element to the product file. */
+p_el_t p_el;
+{
+ p_ell3_t actn = p_el->el_which->ma_actn;
+ p_elll_t *pp_parls;
+ p_ells_t *pp_exp;
+ ulong ind_save;
+
+ /* Make sure that we have been handed a parameter element. */
+ as_cold(p_el->el_kind==EL_PARM,"ex_elpr: Not a parameter element!");
+
+ /* Save the current indentation base and set it to the current level. */
+ ind_save=ind_base;
+ ind_base=ind_curr;
+
+ /* Get a pointer to the most recent parameter list of the target macro. */
+ ls_loo(actn,ls_len(actn),PPV &pp_parls);
+
+ /* Get the expression corresponding to the el_parno'th parameter. */
+ ls_loo(*pp_parls,p_el->el_parno,PPV &pp_exp);
+
+ /* Expand that expression. */
+ ex_ex(*pp_exp);
+
+ /* Restore the indentation base. */
+ ind_base=ind_save;
+}
+
+/******************************************************************************/
+
+LOCAL void ex_elin P_((p_el_t));
+LOCAL void ex_elin(p_el)
+/* Expand invocation element. */
+p_el_t p_el;
+{
+ p_ma_t p_ma;
+ p_bp_t p_bp;
+ ulong ind_save;
+ p_void p_mark;
+
+ /* Make sure that we have been handed an invocation element. */
+ as_cold(p_el->el_kind==EL_INVC,"ex_elin: Not an invocation element!");
+
+ /* Save the current indentation base and set it to the current level. */
+ ind_save=ind_base;
+ ind_base=ind_curr;
+
+ /* Grab a pointer to the macro being invoked. */
+ p_ma=p_el->el_p_mac;
+
+ /* Push the actual parameter list onto the invoked macro's activation list. */
+ ls_add(p_ma->ma_actn,PV &p_el->el_parls);
+
+ /* Expand each body part expression. */
+ ls_fir(p_ma->ma_defn.md_body);
+ while (TRUE)
+ {
+ ls_nxt(p_ma->ma_defn.md_body,PPV &p_bp);
+ if (p_bp==NULL) break;
+ p_mark=ls_mar(p_ma->ma_defn.md_body); /* Protect againt recursion. */
+ ex_ex(p_bp->bp_ex);
+ ls_set(p_ma->ma_defn.md_body,p_mark);
+ }
+
+ /* Pop the activated macro's parameter list. */
+ ls_lop(p_ma->ma_actn);
+
+ /* Restore the indentation base. */
+ ind_base=ind_save;
+}
+
+/******************************************************************************/
+
+LOCAL void ex_ex(p_exp)
+/* Expand the specified expression. */
+p_ells_t p_exp;
+{
+ p_void p_mark;
+
+ /* We need to save the current position in the expression list in case we */
+ /* are being recursively invoked (e.g. in @<X@>@(@"@<X@>@(@"sloth@"@)@"@). */
+ ls_fir(p_exp);
+ while (TRUE)
+ {
+ p_el_t p_el;
+ ls_nxt(p_exp,PPV &p_el);
+ if (p_el==NULL) break;
+ p_mark=ls_mar(p_exp);
+ switch (p_el->el_kind)
+ {
+ case EL_TEXT: ex_eltx(p_el); break;
+ case EL_INVC: ex_elin(p_el); break;
+ case EL_PARM: ex_elpr(p_el); break;
+ default : as_bomb("ex_ex: Case defaulted.");
+ }
+ ls_set(p_exp,p_mark);
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void ex_file P_((p_ma_t));
+LOCAL void ex_file(p_ma)
+/* This function accepts a pointer to a macro. It creates a product file */
+/* with the same name as the macro (inheriting any filename parts given in */
+/* the command line) and expands the macro, writing the expansion to the */
+/* product file. */
+p_ma_t p_ma;
+{
+ fn_t fn_tmp; /* Name of temporary file. */
+ bool renfil; /* Do we wish to rename product file? */
+ bool istarg; /* Does a target file already exist? */
+
+ /* Writing product files differs to the other output files. With non */
+ /* critical files such as the listing file that are really just logs, */
+ /* generation of half a listing file is acceptable if not desirable. However */
+ /* in the case of product files, it is very bad to generate half a product */
+ /* file; far better to generate none at all. For this reason, and also */
+ /* because of the presence of the D option (which prohibits the writing */
+ /* of product files identical to existing files (to prevent MAKE */
+ /* propagations)) it is best to write a temporary file and then rename it. */
+
+ /* Construct the target file name. */
+ strcpy(fn_targ,""); /* Start with an empty name. */
+ fn_ins(fn_targ,&option.op_o_s[0]);
+ fn_ins(fn_targ,&p_ma->ma_name[0]);
+
+ /* The temporary file has to inherit too, because the output directory may */
+ /* not be the default directory and some computers can't rename across */
+ /* directories (and we have to rename it later). */
+ strcpy(fn_tmp,fn_targ);
+ fn_ins(fn_tmp,fn_temp());
+
+ /* Expand the macro to the temporary file. */
+ wf_ini(&f_o,TRUE);
+ wf_ope(&f_o,fn_tmp);
+ if (wf_err(&f_o))
+ {
+ sprintf(linet1,"Error creating temporary product file \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ (void) remove(fn_tmp);
+ goto severe;
+ }
+
+ /* Now expand the target macro into the file. */
+ {
+ el_t el;
+ el.el_kind = EL_INVC;
+ el.el_p_mac = p_ma;
+ el.el_parls = ls_cre(sizeof(p_ells_t));
+ /* Note: We don't set el_pretx and el_postx as they are not used here. */
+ ind_base = 0;
+ ind_curr = 0;
+ lineno = 1;
+ errlin = 0;
+ numlong = 0;
+ ex_elin(&el);
+ }
+
+ /* Make sure that there weren't any errors writing to the product file. */
+ if (wf_err(&f_o))
+ {
+ sprintf(linet1,"S: Error writing to temporary product file \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ (void) remove(fn_tmp);
+ goto severe;
+ }
+
+ /* Close the product file. */
+ wf_clo(&f_o);
+ if (wf_err(&f_o))
+ {
+ sprintf(linet1,"S: Error closing temporary product file \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ (void) remove(fn_tmp);
+ goto severe;
+ }
+
+ /* The rest of the code in this function copes with the renaming. */
+
+ /* By default, we wish to rename the temporary file. */
+ renfil=TRUE;
+
+ /* Deal with any existing file of the target name. */
+ istarg=fexists(fn_targ);
+ if (istarg && option.op_d_b)
+ {
+ /* A target already exists, and the D option is on. If the target is */
+ /* identical to the temporary, we can simply delete the temporary! */
+ char *errstr;
+ bool same;
+ errstr=eq_files(fn_tmp,fn_targ,&same);
+ if (errstr != NULL)
+ {
+ wl_sjl("S: Error comparing temporary file with previous product file.");
+ wl_sjl("(A comparison was attempted because the D option was turned on.)");
+ wl_sjl("Error from comparison routine was as follows (first=temp):");
+ wr_sjl(" ");wl_sjl(errstr);
+ sprintf(linet1,"Temporary file name was \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ sprintf(linet1,"Product file name was \"%s\".",fn_targ);
+ wl_sjl(linet1);
+ wl_sjl("FunnelWeb will leave both files intact so you can look at them.");
+ goto severe;
+ }
+ /* If the two files are the same, we can simply delete the temporary. */
+ if (same)
+ {
+ int status;
+ status=remove(fn_tmp);
+ if (status != REMOVE_S)
+ {
+ sprintf(linet1,"S: Error deleting (under +D option) temporary file \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ goto severe;
+ }
+ sprintf(linet1,"Deleted identical product file \"%s\".",fn_targ);
+ wl_sjl(linet1);
+ renfil=FALSE;
+ }
+ }
+
+ if (renfil)
+ {
+ int status;
+ /* We need to delete any existing file of the target name. */
+ if (istarg)
+ {
+ status=remove(fn_targ);
+ if (status != REMOVE_S)
+ {
+ sprintf(linet1,"S: Error deleting existing product file \"%s\".",fn_targ);
+ wl_sjl(linet1);
+ goto severe;
+ }
+ }
+ /* Rename the temporary file to the product file. */
+ status=rename(fn_tmp,fn_targ);
+ if (status != RENAME_S)
+ {
+ wl_sjl("S: Error renaming temporary product file to product file.");
+ sprintf(linet1,"Temporary file name was \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ sprintf(linet1,"Product file name was \"%s\".",fn_targ);
+ wl_sjl(linet1);
+ wl_sjl("FunnelWeb will leave both files intact so you can look at them.");
+ goto severe;
+ }
+ }
+
+ /* Tell everyone that we have written a product file. */
+ /* Note that we use the macro name. The full name is usually too messy. */
+ sprintf(linet1,"Tangle: Completed %s.",&p_ma->ma_name[0]);
+ wl_sjl(linet1);
+ return;
+
+ /* Jump here is a nasty file error occurs. */
+ severe:
+ sprintf(linet1,"A problem occurred during the generation of product file \"%s\".",&fn_targ[0]);
+ wl_sjl(linet1);
+ wl_sjl("S: Aborting...");
+ num_sev++;
+ return;
+
+}
+
+/******************************************************************************/
+
+EXPORT void tangle()
+{
+ name_t dummyname;
+ p_ma_t p_ma;
+
+ /* Possibly decrease tglinmax if W option is turned on. */
+ if (option.op_w_b)
+ tglinmax=MIN(tglinmax,option.op_w_i);
+
+ /* Some compilers do not allow much space for statics so we allocate fn_targ */
+ /* dynamically to save static space. */
+ fn_targ=(char *) mm_temp(sizeof(fn_t));
+
+ /* Generate each file contained in the file table. */
+ tb_fir(file_table);
+ while (num_sev==0 && tb_rea(file_table,PV dummyname,PV &p_ma))
+ ex_file(p_ma);
+}
+
+/******************************************************************************/
+/* End of TANGLE.C */
+/******************************************************************************/
+
diff --git a/web/funnelAC/sources/tangle.h b/web/funnelAC/sources/tangle.h
new file mode 100644
index 0000000000..800a609cad
--- /dev/null
+++ b/web/funnelAC/sources/tangle.h
@@ -0,0 +1,56 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* TANGLE.H */
+/******************************************************************************/
+/* */
+/* This package exports a single function "tangle" that generates all the */
+/* product files for FunnelWeb. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+EXPORT void tangle P_((void));
+/* Generate product files. */
+
+/******************************************************************************/
+/* End of TANGLE.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/texhead.c b/web/funnelAC/sources/texhead.c
new file mode 100644
index 0000000000..8a94553471
--- /dev/null
+++ b/web/funnelAC/sources/texhead.c
@@ -0,0 +1,108 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* TEXHEAD.C */
+/******************************************************************************/
+/* */
+/* TEX HEADER PACKAGE */
+/* ================== */
+/* This package contains a single function that writes the TeX header */
+/* (containing all the Weave macros) to the specified stream. The package */
+/* consists of: */
+/* */
+/* texhead.tex - The header file ("source code" for texhead.ctx). */
+/* texhead.ctx - Automatically generated C code based on texhead.tex. */
+/* texhead.h - Exported header file containing function definition. */
+/* texhead.c - Contains the function body and the codified header file. */
+/* */
+/* WARNING: THE ONLY FILE THAT SHOULD EVER BE MODIFIED BY HAND IS TEXHEAD.TEX.*/
+/* From this can be generated a new version of texhead.ctx. Here's how: */
+/* 1. Edit texhead.tex as desired. */
+/* 2. Fire up the FunnelWeb shell and give the command: */
+/* codify texhead.tex texhead.ctx */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "texhead.h"
+#include "writfile.h"
+
+/******************************************************************************/
+
+EXPORT void tex_head(p_wf)
+p_wf_t p_wf;
+/* Writes the FunnelWeb TeX header block to the argument stream. */
+{
+
+ /*#############################################################################
+ IMPORTANT COPYRIGHT NOTICE
+ --------------------------
+ The set of FunnelWeb TeX definitions, embodied in C code in the file
+ included by the #include directive below, is a public domain work.
+
+ Notwithstanding the fact that the public domain set of FunnelWeb TeX
+ definitions is represented in the form of strings in C code #included by the
+ FunnelWeb literate-programming preprocessor program released under GNU General
+ Public License Version 2, the set of TeX definitions themselves do not fall
+ under GNU license. Instead, the set of FunnelWeb TeX definitions is classified
+ as a public domain work that is distributed with FunnelWeb as a "separate
+ work". The set of definitions is included as strings in the FunnelWeb code for
+ the sole reason that this organization avoids FunnelWeb having to locate the
+ file at run time. Thus, when FunnelWeb writes the set of TeX definitions to a
+ .TeX output file, it is not generating a work based on itself, but is merely
+ copying a public domain file (which it happened to represent in the form of
+ code rather than data) into the output file.
+
+ The motivation for rigorously clarifying the status of the set of
+ FunnelWeb TeX definitions is that it will appear in TeX output files
+ generated by FunnelWeb, and I do not want any output files generated by
+ FunnelWeb to be under any copyright restrictions.
+
+ -- Ross N. Williams, 5:42pm 07-May-1992, Adelaide, Australia.
+
+ #############################################################################*/
+
+#define WX(STR) wf_wl(p_wf,STR)
+
+#include "texhead.ctx"
+}
+
+/******************************************************************************/
+/* End of TEXHEAD.C */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/texhead.ctx b/web/funnelAC/sources/texhead.ctx
new file mode 100644
index 0000000000..b873bd70ba
--- /dev/null
+++ b/web/funnelAC/sources/texhead.ctx
@@ -0,0 +1,320 @@
+ WX("%===================== Start of FunnelWeb TeX Definitions ======================");
+ WX("");
+ WX("");
+ WX("% Version");
+ WX("% -------");
+ WX("% This is FunnelWeb TeX Macro Library Version 1.0.");
+ WX("");
+ WX("");
+ WX("% Copyright");
+ WX("% ---------");
+ WX("% This set of FunnelWeb TeX definitions was written by Ross Williams and was");
+ WX("% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,");
+ WX("% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions");
+ WX("% and hereby authorize that the set of TeX definitions pass into the public");
+ WX("% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.");
+ WX("");
+ WX("");
+ WX("% Modification");
+ WX("% ------------");
+ WX("% Please record all modifications to these TeX definitions here. Unless");
+ WX("% otherwise specified, all modified definitions fall in the public domain too.");
+ WX("%");
+ WX("% Programmers:");
+ WX("% RNW Ross N. Williams ross@spam.adelaide.edu.au");
+ WX("%");
+ WX("% Changes:");
+ WX("% 07-May-1992 RNW Prepared this work for public domain release.");
+ WX("%");
+ WX("");
+ WX("");
+ WX("% General Comments");
+ WX("% ----------------");
+ WX("% This set of TeX definitions exists for two reasons:");
+ WX("%");
+ WX("% 1. To shorten and neaten the FunnelWeb TeX output.");
+ WX("% 2. To allow users to fiddle with the output format in their input files");
+ WX("% (by inserting redefining \"\\def\"s) without having to resort to");
+ WX("% modifying the FunnelWeb code.");
+ WX("%");
+ WX("% The user is warned that these definitions may be changed from time to time");
+ WX("% (but probably not much). The user should not be too sneaky. In particular,");
+ WX("% users wishing to redefine some of these macros should do so in an explicitly");
+ WX("% defined section at the top of their input file. This will mean that in the");
+ WX("% event of problems, that section can simply be deleted or commented out to");
+ WX("% allow the document to at least be typeset in the default format. Users should");
+ WX("% limit themselves to redefining these macros in such a section and should");
+ WX("% refrain from using the macros throughout their documents.");
+ WX("");
+ WX("");
+ WX("% Environment Parameters");
+ WX("% ----------------------");
+ WX("% \\tolerance tells TeX how tolerant it should be about making bad line and");
+ WX("% page breaks. Here we set it to it's maximum, as");
+ WX("% 1) Computer programs are likely to cause lots of bad breaks.");
+ WX("% 2) In most cases the user would probably rather get the TeX file through");
+ WX("% TeX without any errors than fiddle with spacings for perfection.");
+ WX("\\tolerance=10000");
+ WX("");
+ WX("% I don't like indentation as it makes the page look more busy. Instead,");
+ WX("% paragraphs are separated by a little space (see next).");
+ WX("\\parindent=0pt");
+ WX("");
+ WX("% In many cases, users will produce documents with long runs of paragraphs.");
+ WX("% In order to space out these paragraphs, it is convenient to maintain a");
+ WX("% prevailing non-zero \\parskip (end-of-paragaph skip). The only trouble is");
+ WX("% that the skip becomes a problem in macro definitions which require no skip");
+ WX("% and so we have to turn the skip on and off. The following two macros");
+ WX("% simplify this process.");
+ WX("\\def\\fwparskipon{\\parskip=\\medskipamount}");
+ WX("\\def\\fwparskipoff{\\parskip=0pt}");
+ WX("\\fwparskipon");
+ WX("");
+ WX("% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the");
+ WX("% page in order to better vertically align the rest of the page (e.g. skips");
+ WX("% won't stretch as much). It also means that headings are less likely to be");
+ WX("% isolated at the bottom of the page without any following text.");
+ WX("\\raggedbottom");
+ WX("");
+ WX("");
+ WX("% Fonts");
+ WX("% -----");
+ WX("% Most of the typeset output is set in 10pt roman and 10pt tt font.");
+ WX("% The major extra font needs spring from titles and headings.");
+ WX("% For portability's sake we use only the following fonts:");
+ WX("% cmr10");
+ WX("% cmbx10");
+ WX("% cmtt10");
+ WX("% and some enlargements of them. These fonts are all \"standard\" fonts");
+ WX("% in Plain TeX. See The TeXbook p.350.");
+ WX("\\font\\fwfontnote=cmr7");
+ WX("");
+ WX("\\font\\fwfontnorm=cmr10");
+ WX("\\font\\fwfontnorma=cmr10 scaled \\magstep1");
+ WX("\\font\\fwfontnormb=cmr10 scaled \\magstep2");
+ WX("");
+ WX("\\font\\fwfontbold=cmbx10");
+ WX("\\font\\fwfontbolda=cmbx10 scaled \\magstep1");
+ WX("\\font\\fwfontboldb=cmbx10 scaled \\magstep2");
+ WX("\\font\\fwfontboldc=cmbx10 scaled \\magstep3");
+ WX("\\font\\fwfontboldd=cmbx10 scaled \\magstep4");
+ WX("");
+ WX("");
+ WX("% Macros for Stylistic Details");
+ WX("% ----------------------------");
+ WX("% This section contains all the fiddly little macros for setting the details");
+ WX("% of each macro definition.");
+ WX("");
+ WX("% Macro definitions are sandwiched by calls to these macros which can be used");
+ WX("% to sort out the spacing before and after the macro definition.");
+ WX("\\def\\fwbeginmacro{\\fwparskipoff\\bigskip}");
+ WX("\\def\\fwendmacro{\\fwparskipon\\par}");
+ WX("");
+ WX("% These macros deal with the macro name and definition line.");
+ WX("\\def\\fwmacroname#1#2{{\\sl #1\\/}$\\lbrack$#2$\\rbrack$}");
+ WX("\\def\\fwfilename#1#2{{\\bf #1}$\\lbrack$#2$\\rbrack$}");
+ WX("\\def\\fwzero#1{{\\bf Z}}");
+ WX("\\def\\fwmany#1{{\\bf M}}");
+ WX("\\def\\fwequals{ $\\equiv$}");
+ WX("\\def\\fwplusequals{ $+\\equiv$}");
+ WX("");
+ WX("% Now for the actual body of the definition. It looks nice to have the tt");
+ WX("% code indented a little. Again, we use macros instead of writing direct TeX,");
+ WX("% so as to allow the user to fiddle this stuff to taste without having to");
+ WX("% modify the FunnelWeb C code.");
+ WX("\\def\\fwodef{\\parindent=15pt\\vskip0pt$\\lbrace$\\parindent=20pt}");
+ WX("\\def\\fwcdef{$\\rbrace$\\vskip0pt\\parindent=0pt}");
+ WX("\\def\\fwoquote{`}");
+ WX("\\def\\fwcquote{'}");
+ WX("\\def\\fwoparen{$($}");
+ WX("\\def\\fwcomma{$,$}");
+ WX("\\def\\fwcparen{$)$}");
+ WX("\\def\\fwparam#1{$\\diamond #1$}");
+ WX("\\def\\fwparams#1{$(\\diamond #1)$}");
+ WX("");
+ WX("% These macros deal with the notes that are appended at the end of each");
+ WX("% macro definition. Note that even though \\fwisafile,\\fwusedin, and \\fwseealso");
+ WX("% have the same definition, they are given different names so as to allow the");
+ WX("% user to redefine these macros to typeset each kind of information differently");
+ WX("% if desired.");
+ WX("\\def\\fwbeginmacronotes{\\begingroup\\baselineskip=9pt\\smallskip}");
+ WX("\\def\\fwnote#1{{\\fwfontnote #1}\\par}");
+ WX("\\def\\fwisafile#1{\\fwnote{#1}}");
+ WX("\\def\\fwusedin#1{\\fwnote{#1}}");
+ WX("\\def\\fwseealso#1{\\fwnote{#1}}");
+ WX("\\def\\fwendmacronotes{\\endgroup}");
+ WX("");
+ WX("");
+ WX("% Macros to Typeset Program Code Verbatim");
+ WX("% ---------------------------------------");
+ WX("% This is by far the hairiest and most difficult part of the typesetting task");
+ WX("% because we have to turn off most of TeX's natural instincts in order to");
+ WX("% typeset the program text exactly as it appears in the input file.");
+ WX("% Two macros are defined to pull this off: \\fwbtx and \\fwverbatimgobble.");
+ WX("% Their code was inspired by the following sections of \"The TeXbook\":");
+ WX("% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.");
+ WX("% Appendix E: Example Formats, p.421.");
+ WX("% The \\fwbtx[ (for \"FunnelWeb Begin TeXt\") macro does most of the hard work.");
+ WX("% The liberal use of \"%\" is because I don't understand TeX well enough to");
+ WX("% understand when an end of line will cause trouble, and I am playing it safe.");
+ WX("");
+ WX("% Before defining the main \\fwbtx macro, we have to stash away some definitions");
+ WX("% in the hidden part of TeX's environment. Let's hope that these \"hidden\"");
+ WX("% definitions don't affect anything except what is desired to be affected.");
+ WX("");
+ WX("% The tt font in which we wish to set the text has two Latin lurking ligatures!");
+ WX("% These are ?` and !`. To disable them, we define the left quote when ACTIVE");
+ WX("% to be defined in such a way as to prevent ligatures. The main TeX text will");
+ WX("% normally not be exposed to this definition because normally the leftquote");
+ WX("% character is not active. The \\fwbtx macro temporarily makes the left quote");
+ WX("% character active thus activating the deactivation of left quote ligatures.");
+ WX("% See The TeXbook p.381.");
+ WX("{\\catcode`\\`=\\active \\gdef`{\\relax\\lq}}");
+ WX("");
+ WX("% TeX is fairly carefree about spaces and so we have to make it more serious.");
+ WX("% To do so we pull the same trick as above, setting up a definition for active");
+ WX("% space, but only making space active during the span of the verbatim text.");
+ WX("% In Plain TeX the active space is defined to be simply a space, but here we");
+ WX("% define it to be a control space. This ensures that the space cannot");
+ WX("% be gobbled up by one of TeX's mysterious mechanisms when activated.");
+ WX("% See The TeXbook, p.381 and p.352.");
+ WX("{\\obeyspaces\\global\\let =\\ }");
+ WX("");
+ WX("% Here is the main \\fwbtx verbatim text macro.");
+ WX("% Note: The order in which all these pieces of business have to be done is");
+ WX("% still a partial mystery to me. Don't fiddle with this stuff unless you");
+ WX("% think you know what you are doing.");
+ WX("\\def\\fwbtx[{%");
+ WX("%");
+ WX("% The funnies involved in getting verbatim output are safely housed inside");
+ WX("% this \\begingroup, and the \\endgroup in \\fwverbatimgobble. Groups are used");
+ WX("% instead of curly braces because we have to be able to signal the end of");
+ WX("% this macro with a curly brace.");
+ WX("\\begingroup%");
+ WX("%");
+ WX("% \\pars at the end of empty lines in the verbatim text won't come out normally");
+ WX("% because TeX is in vertical mode and they get gobbled up. To prevent this,");
+ WX("% we force \\par to exit vertical mode first. See The TeXbook p.381.");
+ WX("\\def\\par{\\leavevmode\\endgraf}%");
+ WX("%");
+ WX("% Activate the leftquote character so as to avoid ligatures (see above).");
+ WX("\\catcode`\\`=\\active%");
+ WX("%");
+ WX("% The \\obeylines macro simply defines end of line (^M) to be \\par. This ensures");
+ WX("% that TeX will treat each verbatim line as a new paragraph.");
+ WX("\\obeylines%");
+ WX("%");
+ WX("% To get verbatim output, we have to desex all the special characters. This");
+ WX("% is explained in detail in The TeXbook p.380.");
+ WX("\\def\\do##1{\\catcode`##1=12 }\\dospecials%");
+ WX("%");
+ WX("% Activate the space character so as to make TeX treat blanks seriously.");
+ WX("% This activation invokes an eralier definition (see above).");
+ WX("\\obeyspaces");
+ WX("%");
+ WX("% Interparagraph skips do not help the cause.");
+ WX("% Note: We have to preserve the indentation though, as the code is actually");
+ WX("% indented in the final output. See \\fwodef in an earlier section.");
+ WX("\\parskip=0pt%");
+ WX("%");
+ WX("% We typeset the verbatim text in tt font (courier on the Macintosh) for a");
+ WX("% number of reasons:");
+ WX("% - tt font has the same horizontal spacing for each character.");
+ WX("% - tt font covers the ASCII character set.");
+ WX("% - tt font doesn't have many surprises (e.g. ligatures).");
+ WX("% - tt font looks much what you might see on a computer terminal screen.");
+ WX("\\tt%");
+ WX("%");
+ WX("% Having set up an environment for verbatim, we are ready to use it.");
+ WX("% By invoking \\fwverbatimgobble, this \\fwbtx macro gobbles up text verbatim (as");
+ WX("% part of the parameter of \\fwverbatimgobble) until it sees the termination");
+ WX("% string \"]fwetx=\" (the \"=\" was thrown in to add obscurity as this sequence");
+ WX("% must never occur in the verbatim text).");
+ WX("\\fwverbatimgobble}");
+ WX("");
+ WX("% The \\fwverbatimgobble macro exists to allow \\fwbtx to bracket verbatim text.");
+ WX("\\def\\fwverbatimgobble#1]fwetx={#1\\endgroup}");
+ WX("");
+ WX("");
+ WX("% Table of Contents");
+ WX("% -----------------");
+ WX("% The five levels of table of contents that FunnelWeb supports are identified");
+ WX("% by the five letters [A..E]. These are used throughout the following macros.");
+ WX("");
+ WX("% The following macros are utilities to the TOC macros to follow.");
+ WX("\\def\\fwrule{\\medskip\\hrule\\medskip}");
+ WX("\\def\\fwqh{\\hskip1.5em\\relax}");
+ WX("\\def\\fwbeforesec{\\penalty-200\\bigskip\\medskip\\par}");
+ WX("");
+ WX("% The following macros are used to typeset the table of contents.");
+ WX("\\def\\fwtocstart#1{\\fwrule\\leftline{\\fwfontbolda Table of Contents}\\fwrule}");
+ WX("\\def\\fwtoca#1#2{\\leftline{{\\bf #1 #2}}}");
+ WX("\\def\\fwtocb#1#2{\\leftline{\\fwqh #1 #2}}");
+ WX("\\def\\fwtocc#1#2{\\leftline{\\fwqh\\fwqh #1 #2}}");
+ WX("\\def\\fwtocd#1#2{\\leftline{\\fwqh\\fwqh\\fwqh #1 #2}}");
+ WX("\\def\\fwtoce#1#2{\\leftline{\\fwqh\\fwqh\\fwqh\\fwqh #1 #2}}");
+ WX("\\def\\fwtocfinish#1{\\fwrule}");
+ WX("");
+ WX("% The following \"library\" macros define five different strengths of headings");
+ WX("% which can be used later in the section macros.");
+ WX("\\def\\fwliba#1#2{\\vfill\\eject{\\fwfontboldc #1 #2}\\penalty200\\smallskip}");
+ WX("\\def\\fwlibb#1#2{\\fwbeforesec{\\fwfontboldb #1 #2}\\penalty200\\smallskip}");
+ WX("\\def\\fwlibc#1#2{\\fwbeforesec{\\fwfontnormb #1 #2}\\penalty200\\smallskip}");
+ WX("\\def\\fwlibd#1#2{\\fwbeforesec{\\bf #1 #2}\\penalty200}");
+ WX("\\def\\fwlibe#1#2{\\fwbeforesec{\\bf #1 #2}}");
+ WX("");
+ WX("% Here are the macros that actually typeset the section headings throughout");
+ WX("% the document. The fwlib system has been employed so as to easily allow the");
+ WX("% user to redefine the strengths of headings to taste. For example, the");
+ WX("% user could insert in the input document a similar set of definitions to these");
+ WX("% but with the b..e headings set to \\fwlibc. This would tone down the output.");
+ WX("\\def\\fwseca#1#2{\\fwliba{#1}{#2}}");
+ WX("\\def\\fwsecb#1#2{\\fwlibb{#1}{#2}}");
+ WX("\\def\\fwsecc#1#2{\\fwlibc{#1}{#2}}");
+ WX("\\def\\fwsecd#1#2{\\fwlibd{#1}{#2}}");
+ WX("\\def\\fwsece#1#2{\\fwlibe{#1}{#2}}");
+ WX("");
+ WX("");
+ WX("% Support for Explicit Typesetting");
+ WX("% --------------------------------");
+ WX("% FunnelWeb supports pragmas and other constructs that allow");
+ WX("% typesetter-independent typesetting commands to be given. The");
+ WX("% following macros support these features.");
+ WX("");
+ WX("% The in-text literal @{sloth@} and emphasise @[walrus@] features.");
+ WX("\\def\\fwlit#1{{\\tt #1}}");
+ WX("\\def\\fwemp#1{{\\it #1}}");
+ WX("");
+ WX("% The \"@p new_page\" pragma.");
+ WX("\\def\\fwnewpage{\\vfill\\eject}");
+ WX("");
+ WX("% The \"@p vskip Nmm\" pragma.");
+ WX("\\def\\fwvskip#1{\\null\\vskip #1mm}");
+ WX("");
+ WX("% The \"@p title <font> <align> <text>\" pragma.");
+ WX("\\def\\fwfontnormal#1{{\\fwfontnorm {#1}}}");
+ WX("\\def\\fwfonttitle#1{{\\fwfontboldd {#1}}}");
+ WX("\\def\\fwfontsmalltitle#1{{\\fwfontboldb {#1}}}");
+ WX("\\def\\fwleftline#1{\\leftline{#1}}");
+ WX("\\def\\fwcenterline#1{\\centerline{#1}}");
+ WX("\\def\\fwrightline#1{\\rightline{#1}}");
+ WX("");
+ WX("");
+ WX("% Support for Old FunnelWeb");
+ WX("% -------------------------");
+ WX("% The following macros were used extensively in the first version of");
+ WX("% FunnelWeb and are retained so that these older input files will still");
+ WX("% typeset cleanly.");
+ WX("\\def\\p#1{{\\tt #1}} % P for Program text.");
+ WX("\\def\\flagpage#1#2{");
+ WX(" \\null");
+ WX(" \\vfill");
+ WX(" \\centerline{\\fwfontboldd #1}");
+ WX(" \\vskip 1cm");
+ WX(" \\centerline{\\fwfontboldd #2}");
+ WX(" \\vfill");
+ WX(" \\null");
+ WX(" \\vfill");
+ WX("}");
+ WX("");
+ WX("%====================== End of FunnelWeb TeX Definitions =======================");
diff --git a/web/funnelAC/sources/texhead.h b/web/funnelAC/sources/texhead.h
new file mode 100644
index 0000000000..d1bdbae151
--- /dev/null
+++ b/web/funnelAC/sources/texhead.h
@@ -0,0 +1,121 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* TEXHEAD.H */
+/******************************************************************************/
+/* */
+/* TEX HEADER PACKAGE */
+/* ================== */
+/* This package contains a single function that writes the TeX header */
+/* (containing all the Weave macros) to the specified stream. The package */
+/* consists of: */
+/* */
+/* texhead.tex - The header file ("source code" for texhead.ctx). */
+/* texhead.ctx - C code automatically generated by texhead.tex. */
+/* texhead.h - This file, containing a function definition. */
+/* texhead.c - Contains a function body. */
+/* */
+/* The first version of FunnelWeb (1986) generated TeX output files that used */
+/* a collection of macros to neaten and simplify the bulk of the TeX output */
+/* file. For example, the macro \fwbtx provided a simple way to specify */
+/* verbatim text. This system worked extremely well, the only inconvenience */
+/* being that each FunnelWeb TeX output file had to "\input" the TeX header */
+/* file containing all the macros. At the time, this seemed a sensible */
+/* factorization of the macros, and, within the limited environment in which */
+/* FunnelWeb was operating, worked well. */
+/* */
+/* In NEW, IMPROVED FunnelWeb, "\input"ing the header file has the potential */
+/* to cause lots of problems, the major ones being: */
+/* */
+/* - The header file would have to be installed as part of the FunnelWeb */
+/* system. Currently this means that it would be the ONLY other file */
+/* necessary apart from the FunnelWeb executable. It would be far more */
+/* desirable to avoid having to install the header file. */
+/* */
+/* - The header file would have to be referred to somehow by the TeX file. */
+/* As it makes sense to have only one copy of the header file on a machine, */
+/* TeX files would have to refer to that copy. This would require one of a */
+/* number of messy machine-specific mechanisms such as (VMS) logical name */
+/* translation or environment variable translation. */
+/* */
+/* - TeX files could not be easily moved to other machines (particularly */
+/* those not running FunnelWeb themselves) without also sending the header */
+/* file. */
+/* */
+/* - If FunnelWeb and the header file were ever jointly modified, the dynamic */
+/* binding of old TeX files would mean that they may no longer be printable.*/
+/* */
+/* For all these reasons, the decision was made to write the library of TeX */
+/* macros at the start of each TeX output file, thus making each TeX output */
+/* file entirely self-contained. To do this, the header file had to be */
+/* converted into a sequence of C output statments. To this end, a new */
+/* FunnelWeb shell command CODIFY was added that performs this transformation.*/
+/* CODIFY could have been a separate utility program, but if it was, it might */
+/* somehow be separated from the rest of FunnelWeb during distribution. By */
+/* building CODIFY into FunnelWeb itself, this possibility is eliminated. */
+/* */
+/* This package encapsulates the automatically generated C code. This header */
+/* file defines a function that writes it to a specified stream. The package */
+/* body texhead.c contains the body of the function which consists mainly of */
+/* a #include of the automatically generated C code in texhead.ctx. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_TEXH
+#define DONE_TEXH
+
+/******************************************************************************/
+
+#include "style.h"
+
+#include "writfile.h"
+
+/******************************************************************************/
+
+EXPORT void tex_head P_((p_wf_t));
+/* Writes the FunnelWeb TeX header block to the argument stream. */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of TEXHEAD.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/texhead.tex b/web/funnelAC/sources/texhead.tex
new file mode 100644
index 0000000000..0109a04fb0
--- /dev/null
+++ b/web/funnelAC/sources/texhead.tex
@@ -0,0 +1,320 @@
+%===================== Start of FunnelWeb TeX Definitions ======================
+
+
+% Version
+% -------
+% This is FunnelWeb TeX Macro Library Version 1.0.
+
+
+% Copyright
+% ---------
+% This set of FunnelWeb TeX definitions was written by Ross Williams and was
+% originally Copyright (C) 1992 Ross N. Williams. However, I, Ross Williams,
+% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
+% and hereby authorize that the set of TeX definitions pass into the public
+% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.
+
+
+% Modification
+% ------------
+% Please record all modifications to these TeX definitions here. Unless
+% otherwise specified, all modified definitions fall in the public domain too.
+%
+% Programmers:
+% RNW Ross N. Williams ross@spam.adelaide.edu.au
+%
+% Changes:
+% 07-May-1992 RNW Prepared this work for public domain release.
+%
+
+
+% General Comments
+% ----------------
+% This set of TeX definitions exists for two reasons:
+%
+% 1. To shorten and neaten the FunnelWeb TeX output.
+% 2. To allow users to fiddle with the output format in their input files
+% (by inserting redefining "\def"s) without having to resort to
+% modifying the FunnelWeb code.
+%
+% The user is warned that these definitions may be changed from time to time
+% (but probably not much). The user should not be too sneaky. In particular,
+% users wishing to redefine some of these macros should do so in an explicitly
+% defined section at the top of their input file. This will mean that in the
+% event of problems, that section can simply be deleted or commented out to
+% allow the document to at least be typeset in the default format. Users should
+% limit themselves to redefining these macros in such a section and should
+% refrain from using the macros throughout their documents.
+
+
+% Environment Parameters
+% ----------------------
+% \tolerance tells TeX how tolerant it should be about making bad line and
+% page breaks. Here we set it to it's maximum, as
+% 1) Computer programs are likely to cause lots of bad breaks.
+% 2) In most cases the user would probably rather get the TeX file through
+% TeX without any errors than fiddle with spacings for perfection.
+\tolerance=10000
+
+% I don't like indentation as it makes the page look more busy. Instead,
+% paragraphs are separated by a little space (see next).
+\parindent=0pt
+
+% In many cases, users will produce documents with long runs of paragraphs.
+% In order to space out these paragraphs, it is convenient to maintain a
+% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
+% that the skip becomes a problem in macro definitions which require no skip
+% and so we have to turn the skip on and off. The following two macros
+% simplify this process.
+\def\fwparskipon{\parskip=\medskipamount}
+\def\fwparskipoff{\parskip=0pt}
+\fwparskipon
+
+% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
+% page in order to better vertically align the rest of the page (e.g. skips
+% won't stretch as much). It also means that headings are less likely to be
+% isolated at the bottom of the page without any following text.
+\raggedbottom
+
+
+% Fonts
+% -----
+% Most of the typeset output is set in 10pt roman and 10pt tt font.
+% The major extra font needs spring from titles and headings.
+% For portability's sake we use only the following fonts:
+% cmr10
+% cmbx10
+% cmtt10
+% and some enlargements of them. These fonts are all "standard" fonts
+% in Plain TeX. See The TeXbook p.350.
+\font\fwfontnote=cmr7
+
+\font\fwfontnorm=cmr10
+\font\fwfontnorma=cmr10 scaled \magstep1
+\font\fwfontnormb=cmr10 scaled \magstep2
+
+\font\fwfontbold=cmbx10
+\font\fwfontbolda=cmbx10 scaled \magstep1
+\font\fwfontboldb=cmbx10 scaled \magstep2
+\font\fwfontboldc=cmbx10 scaled \magstep3
+\font\fwfontboldd=cmbx10 scaled \magstep4
+
+
+% Macros for Stylistic Details
+% ----------------------------
+% This section contains all the fiddly little macros for setting the details
+% of each macro definition.
+
+% Macro definitions are sandwiched by calls to these macros which can be used
+% to sort out the spacing before and after the macro definition.
+\def\fwbeginmacro{\fwparskipoff\bigskip}
+\def\fwendmacro{\fwparskipon\par}
+
+% These macros deal with the macro name and definition line.
+\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
+\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
+\def\fwzero#1{{\bf Z}}
+\def\fwmany#1{{\bf M}}
+\def\fwequals{ $\equiv$}
+\def\fwplusequals{ $+\equiv$}
+
+% Now for the actual body of the definition. It looks nice to have the tt
+% code indented a little. Again, we use macros instead of writing direct TeX,
+% so as to allow the user to fiddle this stuff to taste without having to
+% modify the FunnelWeb C code.
+\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
+\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
+\def\fwoquote{`}
+\def\fwcquote{'}
+\def\fwoparen{$($}
+\def\fwcomma{$,$}
+\def\fwcparen{$)$}
+\def\fwparam#1{$\diamond #1$}
+\def\fwparams#1{$(\diamond #1)$}
+
+% These macros deal with the notes that are appended at the end of each
+% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
+% have the same definition, they are given different names so as to allow the
+% user to redefine these macros to typeset each kind of information differently
+% if desired.
+\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
+\def\fwnote#1{{\fwfontnote #1}\par}
+\def\fwisafile#1{\fwnote{#1}}
+\def\fwusedin#1{\fwnote{#1}}
+\def\fwseealso#1{\fwnote{#1}}
+\def\fwendmacronotes{\endgroup}
+
+
+% Macros to Typeset Program Code Verbatim
+% ---------------------------------------
+% This is by far the hairiest and most difficult part of the typesetting task
+% because we have to turn off most of TeX's natural instincts in order to
+% typeset the program text exactly as it appears in the input file.
+% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
+% Their code was inspired by the following sections of "The TeXbook":
+% Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
+% Appendix E: Example Formats, p.421.
+% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
+% The liberal use of "%" is because I don't understand TeX well enough to
+% understand when an end of line will cause trouble, and I am playing it safe.
+
+% Before defining the main \fwbtx macro, we have to stash away some definitions
+% in the hidden part of TeX's environment. Let's hope that these "hidden"
+% definitions don't affect anything except what is desired to be affected.
+
+% The tt font in which we wish to set the text has two Latin lurking ligatures!
+% These are ?` and !`. To disable them, we define the left quote when ACTIVE
+% to be defined in such a way as to prevent ligatures. The main TeX text will
+% normally not be exposed to this definition because normally the leftquote
+% character is not active. The \fwbtx macro temporarily makes the left quote
+% character active thus activating the deactivation of left quote ligatures.
+% See The TeXbook p.381.
+{\catcode`\`=\active \gdef`{\relax\lq}}
+
+% TeX is fairly carefree about spaces and so we have to make it more serious.
+% To do so we pull the same trick as above, setting up a definition for active
+% space, but only making space active during the span of the verbatim text.
+% In Plain TeX the active space is defined to be simply a space, but here we
+% define it to be a control space. This ensures that the space cannot
+% be gobbled up by one of TeX's mysterious mechanisms when activated.
+% See The TeXbook, p.381 and p.352.
+{\obeyspaces\global\let =\ }
+
+% Here is the main \fwbtx verbatim text macro.
+% Note: The order in which all these pieces of business have to be done is
+% still a partial mystery to me. Don't fiddle with this stuff unless you
+% think you know what you are doing.
+\def\fwbtx[{%
+%
+% The funnies involved in getting verbatim output are safely housed inside
+% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
+% instead of curly braces because we have to be able to signal the end of
+% this macro with a curly brace.
+\begingroup%
+%
+% \pars at the end of empty lines in the verbatim text won't come out normally
+% because TeX is in vertical mode and they get gobbled up. To prevent this,
+% we force \par to exit vertical mode first. See The TeXbook p.381.
+\def\par{\leavevmode\endgraf}%
+%
+% Activate the leftquote character so as to avoid ligatures (see above).
+\catcode`\`=\active%
+%
+% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
+% that TeX will treat each verbatim line as a new paragraph.
+\obeylines%
+%
+% To get verbatim output, we have to desex all the special characters. This
+% is explained in detail in The TeXbook p.380.
+\def\do##1{\catcode`##1=12 }\dospecials%
+%
+% Activate the space character so as to make TeX treat blanks seriously.
+% This activation invokes an eralier definition (see above).
+\obeyspaces
+%
+% Interparagraph skips do not help the cause.
+% Note: We have to preserve the indentation though, as the code is actually
+% indented in the final output. See \fwodef in an earlier section.
+\parskip=0pt%
+%
+% We typeset the verbatim text in tt font (courier on the Macintosh) for a
+% number of reasons:
+% - tt font has the same horizontal spacing for each character.
+% - tt font covers the ASCII character set.
+% - tt font doesn't have many surprises (e.g. ligatures).
+% - tt font looks much what you might see on a computer terminal screen.
+\tt%
+%
+% Having set up an environment for verbatim, we are ready to use it.
+% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
+% part of the parameter of \fwverbatimgobble) until it sees the termination
+% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
+% must never occur in the verbatim text).
+\fwverbatimgobble}
+
+% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
+\def\fwverbatimgobble#1]fwetx={#1\endgroup}
+
+
+% Table of Contents
+% -----------------
+% The five levels of table of contents that FunnelWeb supports are identified
+% by the five letters [A..E]. These are used throughout the following macros.
+
+% The following macros are utilities to the TOC macros to follow.
+\def\fwrule{\medskip\hrule\medskip}
+\def\fwqh{\hskip1.5em\relax}
+\def\fwbeforesec{\penalty-200\bigskip\medskip\par}
+
+% The following macros are used to typeset the table of contents.
+\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
+\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
+\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
+\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
+\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
+\def\fwtocfinish#1{\fwrule}
+
+% The following "library" macros define five different strengths of headings
+% which can be used later in the section macros.
+\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
+\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
+\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
+\def\fwlibd#1#2{\fwbeforesec{\bf #1 #2}\penalty200}
+\def\fwlibe#1#2{\fwbeforesec{\bf #1 #2}}
+
+% Here are the macros that actually typeset the section headings throughout
+% the document. The fwlib system has been employed so as to easily allow the
+% user to redefine the strengths of headings to taste. For example, the
+% user could insert in the input document a similar set of definitions to these
+% but with the b..e headings set to \fwlibc. This would tone down the output.
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+
+
+% Support for Explicit Typesetting
+% --------------------------------
+% FunnelWeb supports pragmas and other constructs that allow
+% typesetter-independent typesetting commands to be given. The
+% following macros support these features.
+
+% The in-text literal @{sloth@} and emphasise @[walrus@] features.
+\def\fwlit#1{{\tt #1}}
+\def\fwemp#1{{\it #1}}
+
+% The "@p new_page" pragma.
+\def\fwnewpage{\vfill\eject}
+
+% The "@p vskip Nmm" pragma.
+\def\fwvskip#1{\null\vskip #1mm}
+
+% The "@p title <font> <align> <text>" pragma.
+\def\fwfontnormal#1{{\fwfontnorm {#1}}}
+\def\fwfonttitle#1{{\fwfontboldd {#1}}}
+\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
+\def\fwleftline#1{\leftline{#1}}
+\def\fwcenterline#1{\centerline{#1}}
+\def\fwrightline#1{\rightline{#1}}
+
+
+% Support for Old FunnelWeb
+% -------------------------
+% The following macros were used extensively in the first version of
+% FunnelWeb and are retained so that these older input files will still
+% typeset cleanly.
+\def\p#1{{\tt #1}} % P for Program text.
+\def\flagpage#1#2{
+ \null
+ \vfill
+ \centerline{\fwfontboldd #1}
+ \vskip 1cm
+ \centerline{\fwfontboldd #2}
+ \vfill
+ \null
+ \vfill
+}
+
+%====================== End of FunnelWeb TeX Definitions =======================
diff --git a/web/funnelAC/sources/weave.c b/web/funnelAC/sources/weave.c
new file mode 100644
index 0000000000..ad3ab27113
--- /dev/null
+++ b/web/funnelAC/sources/weave.c
@@ -0,0 +1,976 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* WEAVE.C */
+/******************************************************************************/
+
+#include <ctype.h>
+#include "style.h"
+
+#include "as.h"
+#include "data.h"
+#include "lister.h"
+#include "machin.h"
+#include "misc.h"
+#include "table.h"
+#include "texhead.h"
+#include "weave.h"
+
+/* IMPORTANT WARNING: The Macintosh THINK C compiler sets up strings that */
+/* start with \p or \P as PASCAL strings rather than C strings. So be very */
+/* careful not to start any strings with \p or \P. */
+
+/******************************************************************************/
+
+LOCVAR wf_t f_t; /* Variable representing documentation file. */
+LOCVAR bool literal; /* True if we are inside a literal @{. */
+
+/******************************************************************************/
+
+LOCAL void wv_ex P_((p_ells_t));
+
+/******************************************************************************/
+
+LOCAL char * fn_nodir P_((char *));
+LOCAL char * fn_nodir (p)
+/* Given a pointer to a string, returns a pointer to the character just past */
+/* the last occurrance of FN_DELIM, or a pointer to the start of the string */
+/* if it does not occur. In other words, given a filename, return a pointer */
+/* to the start of the name field. */
+char *p;
+{
+ char *q = strrchr(p,FN_DELIM);
+ if (q==NULL)
+ return p;
+ else
+ return q+1;
+}
+
+/******************************************************************************/
+
+LOCAL void wf_dec P_((p_wf_t,ulong));
+LOCAL void wf_dec(p_wf,n)
+/* Writes the unsigned number n to the specified output stream as a decimal. */
+/* This function has been named wf_dec so that it can be moved to the wf */
+/* package if it turns out to be popular. */
+p_wf_t p_wf;
+ulong n;
+{
+ char t[20];
+ sprintf(t,"%lu",n);
+ wf_wr(p_wf,t);
+}
+
+/******************************************************************************/
+
+LOCAL void wv_ugch P_((int));
+LOCAL void wv_ugch(ch)
+/* WeaVe UGly CHaracter. */
+/* Sometimes it is necessary to output text without causing the typesetting */
+/* program (TeX) to interpret it as control sequences and generate errors. */
+/* There are two ways of doing this. First, we can get the typesetter to do */
+/* the work by making it less sensitive. This has been done with the */
+/* typesetting of the main macro text. The other approach is to convert each */
+/* offending character into the typesetter control sequence that will simply */
+/* output the character. For example, in TeX, "$" becomes "\$". This function */
+/* accepts a single character and writes out its safe equivalent. */
+/* The term "ugly" is used to describe potentially harmful text/characters. */
+int ch;
+{
+ /* End of lines are the only non-printable allowed. */
+ if (ch==EOL) {wf_chr(&f_t,EOL); return;}
+
+ /* All other non-printables result in a bullet. In the absence of bugs, the */
+ /* only way a non-printable can get to us here is as a result of the user */
+ /* explicitly inserting one using the scanner's @^ control sequence. */
+ if (!isascprn(ch))
+ {
+ wf_wr(&f_t,"$\\bullet$");
+ return;
+ }
+ /* If it IS printable, then print it ... carefully! */
+ switch (ch)
+ {
+ /* Go through the printables in ASCII order. */
+ /* ' ': is an ordinary character. */
+ /* '!': is an ordinary character. */
+ case '\"': wf_wr(&f_t,"\\char`\\\""); break;
+ case '#': wf_wr(&f_t,"\\#"); break;
+ case '$': wf_wr(&f_t,"\\$"); break;
+ /* Note: The string "\\%" triggers a unknown sequence "\%" in GNUC. */
+ case '%': wf_chr(&f_t,'\\'); wf_chr(&f_t,'%'); break;
+ case '&': wf_wr(&f_t,"\\&"); break;
+ /* ''': is an ordinary character. */
+ /* '(': is an ordinary character. */
+ /* ')': is an ordinary character. */
+ /* '*': is an ordinary character. */
+ /* '+': is an ordinary character. */
+ /* ',': is an ordinary character. */
+ /* '-': is an ordinary character. */
+ /* '.': is an ordinary character. */
+ /* '/': is an ordinary character. */
+ /* '0-9': are ordinary characters.*/
+ /* ':': is an ordinary character. */
+ /* ';': is an ordinary character. */
+ /* Note: Some \chars work well in roman. Others don't. */
+ case '<': if (literal)
+ wf_wr(&f_t,"\\char`\\<");
+ else
+ wf_wr(&f_t,"$<$");
+ break;
+ /* '=': is an ordinary character. */
+ case '>': if (literal)
+ wf_wr(&f_t,"\\char`\\>");
+ else
+ wf_wr(&f_t,"$>$");
+ break;
+ /* '?': is an ordinary character. */
+ /* '@': is an ordinary character. */
+ /* 'A-Z': are ordinary characters.*/
+ /* '[': is an ordinary character. */
+ case '\\': if (literal)
+ wf_wr(&f_t,"\\char`\\\\");
+ else
+ wf_wr(&f_t,"$\\backslash$");
+ break;
+ /* ']': is an ordinary character. */
+ case '^': wf_wr(&f_t,"\\char`\\^"); break;
+ case '_': wf_wr(&f_t,"\\_"); break;
+ /* '`': is an ordinary character. */
+ /* 'a-z': are ordinary characters.*/
+ case '{': if (literal)
+ wf_wr(&f_t,"\\char`\\{");
+ else
+ wf_wr(&f_t,"$\\{$");
+ break;
+ case '|': if (literal)
+ wf_wr(&f_t,"\\char`\\|");
+ else
+ wf_wr(&f_t,"$|$");
+ break;
+ case '}': if (literal)
+ wf_wr(&f_t,"\\char`\\}");
+ else
+ wf_wr(&f_t,"$\\}$");
+ break;
+ case '~': wf_wr(&f_t,"\\char`\\~"); break;
+ default: wf_chr(&f_t,ch); break;
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void wv_ugstr P_((char *));
+LOCAL void wv_ugstr(s)
+/* Writes out a potentially ugly string. */
+char *s;
+{
+ while (*s != EOS)
+ wv_ugch(*s++);
+}
+
+/******************************************************************************/
+
+LOCAL void wv_ugsc P_((p_sc_t));
+LOCAL void wv_ugsc(p_sc)
+/* Writes out a potentially ugly text scrap. */
+p_sc_t p_sc;
+{
+ char *p = p_sc->sc_first;
+ char *p_last = p_sc->sc_last;
+
+ while (p<=p_last)
+ wv_ugch(*p++);
+}
+
+/******************************************************************************/
+
+LOCAL void wv_ugscls P_((p_scls_t));
+LOCAL void wv_ugscls(p_scls)
+/* This function writes the specified text list to the output stream. It */
+/* writes it cleaning up all ugly characters. */
+p_scls_t p_scls;
+{
+ ls_fir(p_scls);
+ while (TRUE)
+ {
+ p_sc_t p_sc;
+ ls_nxt(p_scls,PPV &p_sc);
+ if (p_sc==NULL) break;
+ wv_ugsc(p_sc);
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void wv_manm P_((p_ma_t,ulong));
+LOCAL void wv_manm(p_ma,part)
+/* This function writes the specified macro name and number. */
+/* The part number is the part to write out. */
+p_ma_t p_ma;
+ulong part;
+{
+ p_bp_t p_bp;
+
+ if (p_ma->ma_defn.md_isfil)
+ wf_wr(&f_t,"\\fwfilename{");
+ else
+ wf_wr(&f_t,"\\fwmacroname{");
+ wv_ugstr(p_ma->ma_name);
+ wf_wr(&f_t,"}{");
+ ls_loo(p_ma->ma_defn.md_body,part,PPV &p_bp);
+ wf_dec(&f_t,(ulong) p_bp->bp_seq);
+ wf_wr(&f_t,"}");
+}
+
+/******************************************************************************/
+
+LOCAL void wv_secnn P_((p_ty_t));
+LOCAL void wv_secnn(p_ty)
+/* Write out the section number and name, each in curly braces. */
+p_ty_t p_ty;
+{
+ /* Write as arguments the section number and name. */
+ wf_chr(&f_t,'{');
+ sn_str(&p_ty->ty_sn,linet1);
+ wf_wr(&f_t,linet1);
+ wf_wr(&f_t,"}{");
+ wv_ugstr(p_ty->ty_name);
+ wf_chr(&f_t,'}');
+}
+
+/******************************************************************************/
+
+LOCAL void wv_echo P_((p_scls_t));
+LOCAL void wv_echo(p_scls)
+/* This function writes the specified text list to the output stream. It */
+/* writes it just as it is, with no modifications whatsoever. */
+p_scls_t p_scls;
+{
+ ls_fir(p_scls);
+ while (TRUE)
+ {
+ p_sc_t p_sc;
+ ls_nxt(p_scls,PPV &p_sc);
+ if (p_sc==NULL) break;
+ wf_blk(&f_t,p_sc->sc_first,(size_t)
+ (p_sc->sc_last-p_sc->sc_first+1));
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void wv_verb P_((p_scls_t));
+LOCAL void wv_verb(p_scls)
+/* Writes a text list verbetim, but brackets it with sequences that instruct */
+/* the typesetter not to interpret the text in any special way. */
+p_scls_t p_scls;
+{
+ if (ls_len(p_scls) > 0)
+ {
+ wf_wr(&f_t,"\\fwbtx[");
+ wv_echo(p_scls);
+ wf_wl(&f_t,"]fwetx=%");
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void wv_head P_((void));
+LOCAL void wv_head()
+{
+ wf_wl(&f_t,"");
+ wf_wl(&f_t,"%*******************************************************************************");
+ wf_wl(&f_t,"%* START OF AUTOMATICALLY GENERATED TEX FILE *");
+ wf_wl(&f_t,"%*******************************************************************************");
+ wf_wl(&f_t,"%* *");
+ wf_wl(&f_t,"%* This TeX file was automatically generated by the FunnelWeb preprocessor. *");
+ wf_wl(&f_t,"%* You can typeset this file to produce printed documentation by running it *");
+ wf_wl(&f_t,"%* through the TeX typesetter using a command such as: *");
+ wf_wl(&f_t,"%* tex thisfilename *");
+ wf_wl(&f_t,"%* The resultant file thisfilename.dvi can be printed using a command such as: *");
+ wf_wl(&f_t,"%* lpr -Pcslw -d thisfilename.dvi *");
+ wf_wl(&f_t,"%* *");
+ wf_wl(&f_t,"%* FunnelWeb is a preprocessor that allows programmers to weave programs and *");
+ wf_wl(&f_t,"%* their documentation together in a single document. The FunnelWeb program *");
+ wf_wl(&f_t,"%* analyses such documents producing both program files and typeset *");
+ wf_wl(&f_t,"%* documentation such as this TeX file. *");
+ wf_wl(&f_t,"%* FunnelWeb was created by Ross Williams. *");
+ wf_wl(&f_t,"%* *");
+ wf_wl(&f_t,"%* For more information on FunnelWeb look in the following FTP archive: *");
+ wf_wl(&f_t,"%* Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3]. *");
+ wf_wl(&f_t,"%* Directory: ~pub/funnelweb/ *");
+ wf_wl(&f_t,"%* (or some other appropriately named directory). *");
+ wf_wl(&f_t,"%* or email Ross Williams at ross@spam.adelaide.edu.au *");
+ wf_wl(&f_t,"%* *");
+ wf_wl(&f_t,"%*******************************************************************************");
+ wf_wl(&f_t,"");
+ wf_wl(&f_t,"");
+}
+
+/******************************************************************************/
+
+LOCAL void wv_tail P_((void));
+LOCAL void wv_tail()
+{
+ wf_wl(&f_t,"");
+ wf_wl(&f_t,"");
+ wf_wl(&f_t,"%*******************************************************************************");
+ wf_wl(&f_t,"%* END OF AUTOMATICALLY GENERATED TEX FILE *");
+ wf_wl(&f_t,"%*******************************************************************************");
+ wf_wl(&f_t,"");
+}
+
+/******************************************************************************/
+
+LOCAL void wv_nsec P_((p_ty_t));
+LOCAL void wv_nsec(p_ty)
+/* Weaves the start of a new section. */
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_NSEC,"wv_nsec: Not a section!");
+
+ /* Work out what kind of section macro should be used. */
+ switch (sn_lev(&p_ty->ty_sn))
+ {
+ case 1: wf_wr(&f_t,"\\fwseca"); break;
+ case 2: wf_wr(&f_t,"\\fwsecb"); break;
+ case 3: wf_wr(&f_t,"\\fwsecc"); break;
+ case 4: wf_wr(&f_t,"\\fwsecd"); break;
+ case 5: wf_wr(&f_t,"\\fwsece"); break;
+ default: as_bomb("wv_nsec:case defaulted.");
+ }
+
+ /* Write out the section number and name. */
+ wv_secnn(p_ty);
+}
+
+/******************************************************************************/
+
+LOCAL void wv_olit P_((p_ty_t));
+LOCAL void wv_olit(p_ty)
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_OLIT,"wv_olit: Not an open literal!");
+ wf_wr(&f_t,"\\fwlit{");
+ literal=TRUE;
+}
+
+/******************************************************************************/
+
+LOCAL void wv_clit P_((p_ty_t));
+LOCAL void wv_clit(p_ty)
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_CLIT,"wv_clit: Not a close literal!");
+ wf_wr(&f_t,"}");
+ literal=FALSE;
+}
+
+/******************************************************************************/
+
+LOCAL void wv_oemp P_((p_ty_t));
+LOCAL void wv_oemp(p_ty)
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_OEMP,"wv_oemp: Not an open emphasize!");
+ wf_wr(&f_t,"\\fwemp{");
+}
+
+/******************************************************************************/
+
+LOCAL void wv_cemp P_((p_ty_t));
+LOCAL void wv_cemp(p_ty)
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_CEMP,"wv_cemp: Not a close emphasize!");
+ wf_wr(&f_t,"}");
+}
+
+/******************************************************************************/
+
+LOCAL void wv_npag P_((p_ty_t));
+LOCAL void wv_npag(p_ty)
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_NPAG,"wv_npag: Not a new page!");
+ wf_wl(&f_t,"");
+ wf_wl(&f_t,"\\fwnewpage");
+ wf_wl(&f_t,"");
+}
+
+/******************************************************************************/
+
+LOCAL void wv_tocs P_((p_ty_t));
+LOCAL void wv_tocs(p_ty)
+/* Writes a table of contents to the weave output file. */
+p_ty_t p_ty;
+{
+ /* We need to save the document list position as the rest of the weaver is */
+ /* in the process of traversing it!!! */
+ p_void p_mark = ls_mar(document_list);
+
+ as_cold(p_ty->ty_kind==TY_TOCS,"wv_tocs: Not a table of contents!");
+
+ wf_wl(&f_t,"");
+ wf_wl(&f_t,"\\fwtocstart{}");
+ ls_fir(document_list);
+ while (TRUE)
+ {
+ p_dc_t p_dc;
+ ls_nxt(document_list,PPV &p_dc);
+ if (p_dc == NULL) break;
+ if (p_dc->dc_kind==DC_TYPE && p_dc->dc_ty.ty_kind==TY_NSEC)
+ {
+ switch(sn_lev(&p_dc->dc_ty.ty_sn))
+ {
+ case 1: wf_wr(&f_t,"\\fwtoca"); break;
+ case 2: wf_wr(&f_t,"\\fwtocb"); break;
+ case 3: wf_wr(&f_t,"\\fwtocc"); break;
+ case 4: wf_wr(&f_t,"\\fwtocd"); break;
+ case 5: wf_wr(&f_t,"\\fwtoce"); break;
+ default: as_bomb("wv_toc: switch defaulted.");
+ }
+ wv_secnn(&p_dc->dc_ty);
+ wf_wl(&f_t,"");
+ }
+ }
+ wf_wl(&f_t,"\\fwtocfinish{}");
+ wf_wl(&f_t,"");
+
+ /* Restore the document list position. */
+ ls_set(document_list,p_mark);
+}
+
+/******************************************************************************/
+
+LOCAL void wv_skip P_((p_ty_t));
+LOCAL void wv_skip(p_ty)
+/* Writes a vertical space to the output file. */
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_SKIP,"wv_skip: Not a skip directive!");
+
+ sprintf(linet1,"\\fwvskip{%lu}",(ulong) p_ty->ty_mm);
+ wf_wl(&f_t,linet1);
+}
+
+/******************************************************************************/
+
+LOCAL void wv_titl P_((p_ty_t));
+LOCAL void wv_titl(p_ty)
+/* Writes a title line to the output file. */
+p_ty_t p_ty;
+{
+ as_cold(p_ty->ty_kind==TY_TITL,"wv_titl: Not a title!");
+
+ switch(p_ty->ty_align)
+ {
+ case LR_LEFT: wf_wr(&f_t,"\\fwleftline{"); break;
+ case LR_RIGH: wf_wr(&f_t,"\\fwrightline{"); break;
+ case LR_CENT: wf_wr(&f_t,"\\fwcenterline{"); break;
+ default: as_bomb("wv_title: Alignment switch defaulted.");
+ }
+ switch(p_ty->ty_font)
+ {
+ case FT_NORM: wf_wr(&f_t,"\\fwfontnormal{"); break;
+ case FT_TITL: wf_wr(&f_t,"\\fwfonttitle{"); break;
+ case FT_STIT: wf_wr(&f_t,"\\fwfontsmalltitle{"); break;
+ default: as_bomb("wv_title: Font switch defaulted.");
+ }
+ wv_ugsc(&p_ty->ty_sc);
+ wf_wl(&f_t,"}}");
+}
+
+/******************************************************************************/
+
+LOCAL void wv_dcty P_((p_dc_t));
+LOCAL void wv_dcty(p_dc)
+/* Weaves a document typesetter element. */
+p_dc_t p_dc;
+{
+ p_ty_t p_ty = &p_dc->dc_ty;
+
+ as_cold(p_dc->dc_kind==DC_TYPE,"wv_dcty: Not a typesetter component!");
+
+ switch (p_ty->ty_kind)
+ {
+ case TY_NSEC: wv_nsec(p_ty); break;
+ case TY_OLIT: wv_olit(p_ty); break;
+ case TY_CLIT: wv_clit(p_ty); break;
+ case TY_OEMP: wv_oemp(p_ty); break;
+ case TY_CEMP: wv_cemp(p_ty); break;
+ case TY_NPAG: wv_npag(p_ty); break;
+ case TY_TOCS: wv_tocs(p_ty); break;
+ case TY_SKIP: wv_skip(p_ty); break;
+ case TY_TITL: wv_titl(p_ty); break;
+ default : as_bomb("wv_dcty: Switch defaulted.");
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void wv_dctx P_((p_dc_t));
+LOCAL void wv_dctx(p_dc)
+/* Write out a document text item. */
+p_dc_t p_dc;
+{
+ as_cold(p_dc->dc_kind==DC_TEXT,"wv_dctx: Not text.");
+
+ if (literal || tr_codes==TR_NONE)
+ wv_ugscls(p_dc->dc_text);
+ else
+ wv_echo(p_dc->dc_text);
+}
+
+/******************************************************************************/
+
+LOCAL void wv_eltx P_((p_el_t));
+LOCAL void wv_eltx(p_el)
+/* Weaves a text element. */
+p_el_t p_el;
+{
+ as_cold(p_el->el_kind==EL_TEXT,"wv_eltx: Not text.");
+ wv_verb(p_el->el_text);
+}
+
+/******************************************************************************/
+
+LOCAL void wv_elin P_((p_el_t));
+LOCAL void wv_elin(p_el)
+/* Weaves a invocation element. */
+p_el_t p_el;
+{
+ as_cold(p_el->el_kind==EL_INVC,"wv_elin: Not an invocation.");
+
+ /* Write out the macro call proper. */
+ wv_manm(p_el->el_p_mac,1L);
+
+ /* Write out the actual parameter list, if any. */
+ if (ls_len(p_el->el_parls) > 0)
+ {
+ ulong parnum;
+ wf_wr(&f_t,"\\fwoparen ");
+ ls_fir(p_el->el_parls); /* List of actual parameter expressions. */
+ ls_fir(p_el->el_pretx); /* List of crud before each expression. */
+ ls_fir(p_el->el_postx); /* List of crud after each expression. */
+ parnum=1;
+ while (TRUE)
+ {
+ p_ells_t *pp_exp;
+ p_scls_t *pp_scls1;
+ p_scls_t *pp_scls2;
+ ls_nxt(p_el->el_parls,PPV &pp_exp);
+ ls_nxt(p_el->el_pretx,PPV &pp_scls1);
+ ls_nxt(p_el->el_postx,PPV &pp_scls2);
+ if (pp_exp==NULL) break;
+ if (parnum++>1) wf_wr(&f_t,"\\fwcomma ");
+ wv_verb(*pp_scls1);
+ wf_wr(&f_t,"\\fwoquote"); wv_ex(*pp_exp); wf_wr(&f_t,"\\fwcquote");
+ wv_verb(*pp_scls2);
+ }
+ wf_wr(&f_t,"\\fwcparen ");
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void wv_elpr P_((p_el_t));
+LOCAL void wv_elpr(p_el)
+/* Weaves a parameter element. */
+p_el_t p_el;
+{
+ as_cold(p_el->el_kind==EL_PARM,"wv_elpr: Not a parameter.");
+ wf_wr (&f_t,"\\fwparam{");
+ wf_dec(&f_t,(ulong) p_el->el_parno);
+ wf_wr (&f_t,"}");
+}
+
+
+/******************************************************************************/
+
+LOCAL void wv_ex(p_exp)
+/* Weaves a expression. */
+p_ells_t p_exp;
+{
+
+ ls_fir(p_exp);
+ while (TRUE)
+ {
+ p_el_t p_el;
+ ls_nxt(p_exp,PPV &p_el);
+ if (p_el==NULL) break;
+ switch (p_el->el_kind)
+ {
+ case EL_TEXT: wv_eltx(p_el); break;
+ case EL_INVC: wv_elin(p_el); break;
+ case EL_PARM: wv_elpr(p_el); break;
+ default: as_bomb("wv_ex: Case defaulted.");
+ }
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void wv_usage P_((p_ma_t));
+LOCAL void wv_usage(p_ma)
+/* Weaves a list of all the sections in which the specified macro is used. */
+p_ma_t p_ma;
+{
+ ulong no_calls = ls_len(p_ma->ma_calls);
+ ulong callno;
+
+ /* If it is a file macro then it is not allowed to be called. */
+ if (p_ma->ma_defn.md_isfil)
+ {
+ wf_wl(&f_t,"\\fwisafile{This macro is attached to an output file.}");
+ return;
+ }
+
+ if (no_calls==0)
+ {
+ wf_wl(&f_t,"\\fwusedin{This macro is NEVER invoked.}");
+ return;
+ }
+
+ wf_wr(&f_t,"\\fwusedin{This macro is invoked in definition");
+ if (no_calls>1) wf_chr(&f_t,'s');
+ wf_chr(&f_t,' ');
+ ls_fir(p_ma->ma_calls);
+ for (callno=1;callno<=no_calls;callno++)
+ {
+ p_mc_t p_mc;
+ ls_nxt(p_ma->ma_calls,PPV &p_mc); as_cold(p_mc!=NULL,"wv_usage: Awk!");
+ wf_dec(&f_t,(ulong) p_mc->mc_seq);
+ if (callno < no_calls-1)
+ wf_wr(&f_t,", ");
+ else
+ if (callno==no_calls-1)
+ if (no_calls>2)
+ wf_wr(&f_t,", and ");
+ else
+ wf_wr(&f_t," and ");
+ }
+ wf_wl(&f_t,".}");
+}
+
+/******************************************************************************/
+
+LOCAL void wv_defin P_((p_ma_t));
+LOCAL void wv_defin(p_ma)
+/* Just after each macro body part definition comes a note listing the */
+/* containing the macro's body parts. This function weaves that list. */
+p_ma_t p_ma;
+{
+ ulong no_parts = ls_len(p_ma->ma_defn.md_body);
+ ulong partno;
+
+ /* If it's not an additive macro, we don't write anything. */
+ if (!p_ma->ma_defn.md_isadd) return;
+
+ wf_wr(&f_t,"\\fwseealso{This macro is defined in definitions ");
+ ls_fir(p_ma->ma_defn.md_body);
+ for (partno=1;partno<=no_parts;partno++)
+ {
+ p_bp_t p_bp;
+ ls_nxt(p_ma->ma_defn.md_body,PPV &p_bp);
+ as_cold(p_bp!=NULL,"wv_defin: Awk!");
+ wf_dec(&f_t,(ulong) p_bp->bp_seq);
+ if (partno<no_parts-1)
+ wf_wr(&f_t,", ");
+ else
+ if (partno==no_parts-1)
+ if (no_parts>2)
+ wf_wr(&f_t,", and ");
+ else
+ wf_wr(&f_t," and ");
+ }
+ wf_wl(&f_t,".}");
+}
+
+/******************************************************************************/
+
+LOCAL void wv_dcma P_((p_dc_t));
+LOCAL void wv_dcma(p_dc)
+/* Weaves a macro definition. */
+p_dc_t p_dc;
+{
+ p_bp_t p_bp;
+
+ /* Macro calls sandwich the definition itsef. */
+ wf_wl(&f_t,"\\fwbeginmacro");
+
+ /* Write out the macro's name. */
+ wv_manm(p_dc->dc_p_ma,p_dc->dc_part);
+
+ /* Write the formal parameter list. */
+ if (p_dc->dc_p_ma->ma_defn.md_npar>0)
+ {
+ wf_wr(&f_t,"\\fwparams{");
+ wf_dec(&f_t,(ulong) p_dc->dc_p_ma->ma_defn.md_npar);
+ wf_wr(&f_t,"}");
+ }
+
+ /* Zero and many options are indicated by bold letters. */
+ if (p_dc->dc_p_ma->ma_defn.md_iszer) wf_wr(&f_t,"\\fwzero{}");
+ if (p_dc->dc_p_ma->ma_defn.md_isman) wf_wr(&f_t,"\\fwmany{}");
+
+ /* Write the "equals". */
+ if (p_dc->dc_p_ma->ma_defn.md_isadd)
+ wf_wr(&f_t,"\\fwplusequals ");
+ else
+ wf_wr(&f_t,"\\fwequals ");
+
+ /* Write out this particular body part. */
+ ls_loo(p_dc->dc_p_ma->ma_defn.md_body,p_dc->dc_part,PPV &p_bp);
+ wf_wr(&f_t,"\\fwodef ");
+ wv_ex(p_bp->bp_ex);
+ wf_wl(&f_t,"\\fwcdef ");
+
+ /* After the macro definition, write out notes on the macro. */
+ wf_wl(&f_t,"\\fwbeginmacronotes");
+ wv_defin(p_dc->dc_p_ma); /* A list of the macro's body parts. */
+ wv_usage(p_dc->dc_p_ma); /* A list of where the macro is used. */
+ wf_wl(&f_t,"\\fwendmacronotes");
+
+ /* The macro definition is sandwiched by macro calls. */
+ wf_wl(&f_t,"\\fwendmacro");
+}
+
+/******************************************************************************/
+
+LOCAL void wv_dc P_((p_dc_t));
+LOCAL void wv_dc(p_dc)
+/* Weaves a document component (p_dc). */
+p_dc_t p_dc;
+{
+ switch (p_dc->dc_kind)
+ {
+ case DC_TEXT: wv_dctx(p_dc); break;
+ case DC_TYPE: wv_dcty(p_dc); break;
+ case DC_MACR: wv_dcma(p_dc); break;
+ default : as_bomb("wv_dc: Case defaulted.");
+ }
+}
+
+/******************************************************************************/
+
+LOCAL void wv_docnt P_((void));
+LOCAL void wv_docnt()
+/* Weaves the entire document. This functions and most functions above assume */
+/* that the output stream f_t is prepared for writing. */
+{
+ /* Write the typeset header. */
+ wv_head();
+
+ /* Writes the library macros. */
+ tex_head(&f_t);
+
+ ls_fir(document_list);
+ literal=FALSE;
+ while (TRUE)
+ {
+ p_dc_t p_dc;
+ ls_nxt(document_list,PPV &p_dc);
+ if (p_dc == NULL) break;
+ wv_dc(p_dc);
+ }
+ wf_wl(&f_t,"\\bye");
+
+ /* Write the typeset trailer. */
+ wv_tail();
+}
+
+/******************************************************************************/
+
+EXPORT void weave()
+/* Writes out the documentation file. */
+{
+ fn_t fn_tmp; /* Name of temporary file. */
+ fn_t fn_targ; /* Name of documentation file. */
+ bool renfil; /* Do we wish to rename output file? */
+ bool istarg; /* Does a target file already exist? */
+
+ /* Writing the documentation file differs from some other output files. With */
+ /* non critical files such as the listing file that are really just logs, */
+ /* generation of half a listing file is acceptable if not desirable. However */
+ /* in the case of the documentation file, it is very bad to generate half an */
+ /* output file; far better to generate none at all. For this reason, and */
+ /* also because of the presence of the D option (which prevents the writing */
+ /* of output files identical to existing files (to prevent MAKE */
+ /* propagations)) it is best to write a temporary file and then rename it. */
+
+ /* We shouldn't be here if the weave option is off! */
+ as_cold(option.op_t_b,"weave: option.op_t_b==FALSE!");
+
+ /* Work out what the typeset file's name should be. */
+ strcpy(fn_targ,""); /* Start with an empty string. */
+ fn_ins(fn_targ,option.op_f_s);
+ fn_ins(fn_targ,".tex");
+ fn_ins(fn_targ,option.op_t_s);
+
+ /* The temporary file has to inherit too, because the output directory may */
+ /* not be the default directory and some computers can't rename across */
+ /* directories (and we have to rename it later). */
+ strcpy(fn_tmp,fn_targ);
+ fn_ins(fn_tmp,fn_temp());
+
+ /* Expand the macro to the temporary file. */
+ wf_ini(&f_t,TRUE);
+ wf_ope(&f_t,fn_tmp);
+ if (wf_err(&f_t))
+ {
+ sprintf(linet1,"Error creating temporary documentation file \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ (void) remove(fn_tmp);
+ goto severe;
+ }
+
+ wv_docnt();
+
+ /* Make sure that there weren't any errors writing to the temporary file. */
+ if (wf_err(&f_t))
+ {
+ sprintf(linet1,"Error writing to temporary documentation file \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ (void) remove(fn_tmp);
+ goto severe;
+ }
+
+ /* Close the temporary file. */
+ wf_clo(&f_t);
+ if (wf_err(&f_t))
+ {
+ sprintf(linet1,"Error closing temporary documentation file \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ remove(fn_tmp);
+ goto severe;
+ }
+
+ /* The rest of the code in this function copes with the renaming. */
+
+ /* By default, we wish to rename the temporary file. */
+ renfil=TRUE;
+
+ /* Deal with any existing file of the target name. */
+ istarg=fexists(fn_targ);
+ if (istarg && option.op_d_b)
+ {
+ /* A target already exists, and the D option is on. If the target is */
+ /* identical to the temporary, we can simply delete the temporary! */
+ char *errstr;
+ bool same;
+ errstr=eq_files(fn_tmp,fn_targ,&same);
+ if (errstr != NULL)
+ {
+ wl_sjl("Error comparing temporary file with previous documentation file.");
+ wl_sjl("(A comparison was attempted because the D option was turned on.)");
+ wl_sjl("Error from comparison routine was as follows (first=temp):");
+ wr_sjl(" ");wl_sjl(errstr);
+ sprintf(linet1,"Temporary file name was \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ sprintf(linet1,"Output file name was \"%s\".",&fn_targ[0]);
+ wl_sjl(linet1);
+ wl_sjl("FunnelWeb will leave both files intact so you can look at them.");
+ goto severe;
+ }
+ /* If the two files are the same, we can simply delete the temporary. */
+ if (same)
+ {
+ int status;
+ status=remove(fn_tmp);
+ if (status != REMOVE_S)
+ {
+ sprintf(linet1,"Error deleting (under +D option) temporary file \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ goto severe;
+ }
+ sprintf(linet1,"Deleted identical documentation file \"%s\".",&fn_targ[0]);
+ wl_sjl(linet1);
+ renfil=FALSE;
+ }
+ }
+
+ if (renfil)
+ {
+ int status;
+ /* We need to delete any existing file of the target name. */
+ if (istarg)
+ {
+ status=remove(fn_targ);
+ if (status != REMOVE_S)
+ {
+ sprintf(linet1,"Error deleting existing documentation file \"%s\".",&fn_targ[0]);
+ wl_sjl(linet1);
+ goto severe;
+ }
+ }
+ /* Rename the temporary file to the output file. */
+ status=rename(fn_tmp,fn_targ);
+ if (status != RENAME_S)
+ {
+ wl_sjl("Error renaming temporary documentation file to documentation file.");
+ sprintf(linet1,"Temporary file name was \"%s\".",&fn_tmp[0]);
+ wl_sjl(linet1);
+ sprintf(linet1,"Output file name was \"%s\".",&fn_targ[0]);
+ wl_sjl(linet1);
+ wl_sjl("FunnelWeb will leave both files intact so you can look at them.");
+ goto severe;
+ }
+ }
+
+ /* Tell everyone that we have written an output file. */
+ sprintf(linet1,"Weave : Completed %s.",fn_nodir(&fn_targ[0]));
+ wl_s(linet1);
+ if (option.op_b7_b)
+ sprintf(linet1,"Weave: Completed %s.",SUPPNAME);
+ wl_j(linet1);
+ wl_l(linet1);
+ return;
+
+ /* Jump here is a nasty file error occurs. */
+ severe:
+ sprintf(linet1,"A problem occurred during the generation of documentation file \"%s\".",&fn_targ[0]);
+ wl_sjl(linet1);
+ wl_sjl("S: Aborting...");
+ num_sev++;
+ return;
+}
+
+/******************************************************************************/
+
diff --git a/web/funnelAC/sources/weave.h b/web/funnelAC/sources/weave.h
new file mode 100644
index 0000000000..9ca3d4357a
--- /dev/null
+++ b/web/funnelAC/sources/weave.h
@@ -0,0 +1,55 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* WEAVE.H */
+/******************************************************************************/
+/* */
+/* This package exports a single function "weave" that generates the typeset */
+/* output file. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+EXPORT void weave P_((void));
+
+/******************************************************************************/
+/* End of WEAVE.H */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/writfile.c b/web/funnelAC/sources/writfile.c
new file mode 100644
index 0000000000..256ddbf22a
--- /dev/null
+++ b/web/funnelAC/sources/writfile.c
@@ -0,0 +1,299 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* WRITFILE.C */
+/******************************************************************************/
+/* */
+/* Implementation Notes */
+/* -------------------- */
+/* The .H file gives most of the details of what this package does. Here we */
+/* just give some notes on how it is implemented. */
+/* */
+/* MAGIC NUMBERS: These are placed at the head and tail of wf_t records so as */
+/* to assist in the detection of uninitialized or corrupted variables. */
+/* */
+/* TEXT VS BINARY: A big problem arises in choosing whether to write binary */
+/* or text files. Binary files are far faster because they allow us to write */
+/* out large slabs of text using fwrite. The only catch is that they do not */
+/* translate EOL characters in the end of line representation of the host */
+/* environment. Text files, on the other hand are slower (because we have */
+/* only fputc and fputs) but do provide the translation. The solution we */
+/* adopt is to use binary if the host environment's representation for end of */
+/* file is EOL (='\n'), but text otherwise. We can determine this by testing */
+/* the symbol UNIX_EOL defined in machin.h. If binary output is chosen, */
+/* only fwrite is called as we don't know if fwrite and fputc calls can be */
+/* mixed (it would seem not). */
+/* Note: We could test the preprocessor symbol in each function. However, */
+/* the wf_att function introduces a problem as we may be attaching to a text */
+/* file in a UNIX_EOL environment (e.g. stdout). So we make the text/binary */
+/* attribute and attribute of each file, rather than the environment which we */
+/* use only to direct us in how to create and tag (as binary or text) a file. */
+/* */
+/******************************************************************************/
+
+#include "style.h"
+
+#include "as.h"
+#include "machin.h"
+#include "writfile.h"
+
+/******************************************************************************/
+
+#define MGC_HEAD (4837295L)
+#define MGC_TAIL (1213839L)
+
+/* Set the following to TRUE to bomb the package upon the first error. */
+/* This is a good idea during debugging if no output appears. */
+#define BOMB_ON_ERROR FALSE
+
+/******************************************************************************/
+
+LOCAL void wf_check P_((p_wf_t));
+LOCAL void wf_check(p_wf)
+p_wf_t p_wf;
+{
+ as_cold(p_wf!=NULL,"wf_check: p_wf==NULL.");
+
+ as_cold(p_wf->wf_mhead==MGC_HEAD,
+ "wf_check: Magic header field has non-magic value.");
+
+ as_cold(p_wf->wf_mtail==MGC_TAIL,
+ "wf_check: Magic trailer field has non-magic value.");
+
+ as_cold(p_wf->wf_isope || p_wf->wf_pfile==NULL,
+ "wf_check: WF is closed but wf_pfile!=NULL.");
+}
+
+/******************************************************************************/
+
+LOCAL void wf_errlg P_((p_wf_t, char *));
+LOCAL void wf_errlg(p_wf,mess)
+/* This function is called whenever an error occurs on a stream. The main */
+/* responsibility of this function is to set the error flag in the stream. */
+/* However, it can do other stuff too such as log the error to the screen. */
+p_wf_t p_wf;
+char *mess;
+{
+ p_wf->wf_iserr=TRUE;
+#if BOMB_ON_ERROR
+ if (p_wf->wf_pfile == stdout)
+ fprintf(stderr,"The output file error occurred on STANDARD OUTPUT.\n");
+ else
+ fprintf(stderr,"The output file error occurred on an ordinary file.\n");
+ as_bomb(mess);
+#endif
+}
+
+/******************************************************************************/
+
+EXPORT void wf_ini(p_wf,normal)
+p_wf_t p_wf;
+bool normal;
+{
+ p_wf->wf_mhead = MGC_HEAD;
+ p_wf->wf_iserr = !normal;
+ p_wf->wf_isope = FALSE;
+ p_wf->wf_istxt = FALSE;
+ p_wf->wf_pfile = NULL;
+ p_wf->wf_mtail = MGC_TAIL;
+}
+
+/******************************************************************************/
+
+EXPORT void wf_att(p_wf,wf_pfile)
+p_wf_t p_wf;
+FILE *wf_pfile;
+{
+ wf_check(p_wf);
+ if (p_wf->wf_iserr) return;
+ as_cold(!p_wf->wf_isope,"wf_att: WF is already open.");
+
+ p_wf->wf_pfile = wf_pfile;
+ p_wf->wf_isope = TRUE;
+ p_wf->wf_istxt = TRUE; /* Play it safe with files we didn't open. */
+ wf_check(p_wf);
+}
+
+/******************************************************************************/
+
+EXPORT void wf_ope(p_wf,p_name)
+p_wf_t p_wf;
+char *p_name;
+{
+ FILE *result;
+
+ wf_check(p_wf);
+ if (p_wf->wf_iserr) return;
+ as_cold(!p_wf->wf_isope,"wf_ope: WF is already open.");
+
+/* Whether we open the file as text or binary depends on whether EOL maps */
+/* to an end of line in the current environment. */
+#if UNIX_EOL
+ result=fopen(p_name,"wb"); p_wf->wf_istxt=FALSE;
+#else
+ result=fopen(p_name,"w"); p_wf->wf_istxt=TRUE;
+#endif
+
+ if (result == FOPEN_F)
+ {
+ /* TRACE printf("Output file in error is \"%s\".\n",p_name); */
+ wf_errlg(p_wf,"wf_ope: Error opening output file.");
+ }
+ else
+ {p_wf->wf_isope=TRUE; p_wf->wf_pfile=result;}
+ wf_check(p_wf);
+}
+
+/******************************************************************************/
+
+EXPORT void wf_chr(p_wf,ch)
+p_wf_t p_wf;
+intchar ch;
+{
+ wf_check(p_wf);
+ if ( p_wf->wf_iserr) return;
+ as_cold(p_wf->wf_isope,"wf_chr: WF is closed.");
+
+ if (p_wf->wf_istxt)
+ {
+ if (fputc((int) ch,p_wf->wf_pfile) == FPUTC_F)
+ wf_errlg(p_wf,"wf_chr: Error fputc()ing to output file.");
+ }
+ else
+ {
+ if (fwrite(&ch,(size_t) 1,(size_t) 1,p_wf->wf_pfile) != 1)
+ wf_errlg(p_wf,"wf_chr: Error fwrite()ing to output file.");
+ }
+ wf_check(p_wf);
+}
+
+/******************************************************************************/
+
+EXPORT void wf_wr(p_wf,p_str)
+p_wf_t p_wf;
+char *p_str;
+{
+ wf_check(p_wf);
+ if ( p_wf->wf_iserr) return;
+ as_cold(p_wf->wf_isope,"wf_wr: WF is closed.");
+
+ if (p_wf->wf_istxt)
+ {
+ if (fputs(p_str,p_wf->wf_pfile) == FPUTS_F)
+ wf_errlg(p_wf,"wf_wr: Error fputs()ing to output file.");
+ }
+ else
+ {
+ size_t len = strlen(p_str);
+ if (fwrite(p_str,(size_t) 1,(size_t) len,p_wf->wf_pfile) != len)
+ wf_errlg(p_wf,"wf_wr: Error fwrite()ing to output file.");
+ }
+ wf_check(p_wf);
+}
+
+/******************************************************************************/
+
+EXPORT void wf_blk(p_wf,p_blk,blk_len)
+p_wf_t p_wf;
+char *p_blk;
+size_t blk_len;
+{
+ wf_check(p_wf);
+ if ( p_wf->wf_iserr) return;
+ as_cold(p_wf->wf_isope,"wf_blk: WF is closed.");
+
+ if (p_wf->wf_istxt)
+ {
+ /* Amazingly, fputc seems to be the only way to write out a block of */
+ /* bytes with end of line translation. Shocking, but true. */
+ /* See Section B1.4 (p.246-247) of Kernighan and Ritchie. */
+ /* Note: We can't use fputs because that requires a terminating nul. */
+ char *p;
+ char *p_post = p_blk+blk_len;
+ for (p=p_blk; p<p_post; p++)
+ if (fputc(*p,p_wf->wf_pfile) == FPUTC_F)
+ {
+ wf_errlg(p_wf,"wf_blk: Error fputc()ing to output file.");
+ break;
+ }
+ }
+ else
+ if (fwrite(p_blk,(size_t) 1,(size_t) blk_len,p_wf->wf_pfile) != blk_len)
+ wf_errlg(p_wf,"wf_blk: Error fwrite()ing to output file.");
+ wf_check(p_wf);
+}
+
+/******************************************************************************/
+
+EXPORT void wf_wl(p_wf,p_str)
+p_wf_t p_wf;
+char *p_str;
+{
+ wf_wr(p_wf,p_str);
+ wf_chr(p_wf,'\n');
+}
+
+/******************************************************************************/
+
+EXPORT void wf_clo(p_wf)
+p_wf_t p_wf;
+{
+ wf_check(p_wf);
+ if ( p_wf->wf_iserr) return;
+ as_cold(p_wf->wf_isope,"wf_clo: WF is not open.");
+ if (fflush(p_wf->wf_pfile) != FFLUSH_S)
+ wf_errlg(p_wf,"wf_clo: Error fflush()ing output file.");
+ if (fclose(p_wf->wf_pfile) == FCLOSE_F)
+ wf_errlg(p_wf,"wf_clo: Error fclose()ing output file.");
+ p_wf->wf_isope=FALSE;
+ p_wf->wf_pfile=NULL;
+ wf_check(p_wf);
+}
+
+/******************************************************************************/
+
+EXPORT bool wf_err(p_wf)
+p_wf_t p_wf;
+{
+ wf_check(p_wf);
+ return p_wf->wf_iserr;
+}
+
+/******************************************************************************/
+/* End of WRITFILE.C */
+/******************************************************************************/
diff --git a/web/funnelAC/sources/writfile.h b/web/funnelAC/sources/writfile.h
new file mode 100644
index 0000000000..a3a433dee4
--- /dev/null
+++ b/web/funnelAC/sources/writfile.h
@@ -0,0 +1,189 @@
+/*##############################################################################
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+##############################################################################*/
+
+
+/******************************************************************************/
+/* WRITFILE.H */
+/******************************************************************************/
+/* */
+/* Introduction */
+/* ------------ */
+/* This package performs all of FunnelWeb's file output. */
+/* FunnelWeb performs lots of output to lots of different files: */
+/* */
+/* - Standard output (to write to the screen). */
+/* - The journal file. */
+/* - The listing file. */
+/* - The tangle output files. */
+/* - The weave output file. */
+/* */
+/* Error Detection */
+/* --------------- */
+/* As we are serious about detecting errors, every call to every IO function */
+/* must have its status checked. Unfortunately this makes everything very */
+/* messy. Having to check result statuses and react to them can be very */
+/* awkward in deeply nested pieces of code, particularly as C does not have */
+/* exceptions. As a result, the policy adopted in FunnelWeb is to RECORD when */
+/* an error occurs on an output stream and silently shut down that stream. */
+/* Then later, at a convenient time, the error status of the stream can be */
+/* checked, and an error message issued. */
+/* */
+/* The C libraries make an effort to be helpful here by providing the ferror */
+/* function. However, it is not useful here for two reasons: */
+/* */
+/* 1. Some calls (e.g. fwrite) are not listed as setting the error status. */
+/* 2. It is not guaranteed that IO calls to a stream with error status */
+/* will not cause a crash. */
+/* 3. Even if ferror were used, it may not be supported by older compilers.*/
+/* */
+/* This package was created to take care of the vexing problems of IO errors */
+/* in output streams. It is a layer above the ANSI file library that provides */
+/* the elementary calls for writing. It differs in that if an error occurs, */
+/* the package records that fact and simply ignores all further operations */
+/* on the file. At any time, it is possible to find out whether a file is in */
+/* normal mode or error mode. All this means that a piece of code can use */
+/* this package to create and write to a file without worrying about errors. */
+/* Then later, when the dust settles, the package can check the status of */
+/* the file, and take appropriate action if an error has been detected. */
+/* */
+/* Text vs Binary */
+/* -------------- */
+/* This package translates all '\n' (contained in the data it has been given */
+/* to write) into the appropriate environment specific representation. */
+/* */
+/* Facts About WF Objects */
+/* ---------------------- */
+/* - A WF object is either in NORMAL or ERROR mode. */
+/* - A WF object in NORMAL mode is also either in OPEN or CLOSED mode. */
+/* - The term "raise an error" means bomb the program with a message. */
+/* - The comments attached to the functions given below are meant to be read */
+/* sequentially with each action or check being performed before the next. */
+/* - This package can not guarantee to detect uninitialized WF objects. The */
+/* reason is that policing is performed using magic number mechanism and it */
+/* is possible that a piece of random memory may contain just the right */
+/* numbers to fool the package. */
+/* */
+/******************************************************************************/
+
+/* Ensure that the body of this header file is included at most once. */
+#ifndef DONE_WRITFILE
+#define DONE_WRITFILE
+
+/******************************************************************************/
+
+#include "style.h"
+
+/******************************************************************************/
+
+/* We really don't want to show all the guts of this record here, but as */
+/* users of the package have to be able to declare objects of this type and */
+/* make them the right size, it seems as if we have no choice. */
+typedef struct
+ {
+ ulong wf_mhead; /* Helps detect uninitialized and corrupted records. */
+ bool wf_iserr; /* TRUE=>ERROR, FALSE=>NORMAL. */
+ bool wf_isope; /* TRUE=>OPEN, FALSE=>CLOSED. */
+ bool wf_istxt; /* TRUE=>TEXT, FALSE=>BINARY. */
+ FILE *wf_pfile; /* Pointer to the file object. */
+ ulong wf_mtail; /* Helps detect uninitialized and corrupted records. */
+ } wf_t;
+
+typedef wf_t *p_wf_t;
+
+/******************************************************************************/
+
+EXPORT void wf_ini P_((p_wf_t,bool));
+/* Initializes a WF to a well defined state in accordance with the boolean. */
+/* FALSE => State=(ERROR). */
+/* TRUE => State=(NORMAL,CLOSED). */
+/* wf_ini must be applied to a WF before any other operation. */
+/* It can be re-applied repeatedly. */
+
+EXPORT void wf_att P_((p_wf_t,FILE *));
+/* If WF is uninitialized, raises an error (probably). */
+/* If WF is in ERROR mode, returns with no effect. */
+/* If WF is OPEN, raises an error. */
+/* Attaches an already opened output file to the specified FW object. */
+/* Changes the WF to the OPEN state. */
+/* The memory that the second parameter points to must be stable. */
+
+EXPORT void wf_ope P_((p_wf_t,char *));
+/* If WF is uninitialized, raises an error (probably). */
+/* If WF is in ERROR mode, returns with no effect. */
+/* If WF is OPEN, raises an error. */
+/* Creates an output file of the specified name and prepares it for writing. */
+/* Changes the WF to the OPEN state. */
+/* Sets the WF to the ERROR state if the file cannot be opened for writing. */
+
+EXPORT void wf_chr P_((p_wf_t,intchar));
+/* If WF is uninitialized, raises an error (probably). */
+/* If WF is in ERROR mode, returns with no effect. */
+/* If WF is CLOSED, raises an error. */
+/* Writes the specified character to the output file associated with WF. */
+/* Sets WF to the ERROR state if an error occurs during the write. */
+
+EXPORT void wf_wr P_((p_wf_t,char *));
+/* Same as wf_chr except that it writes an entire string. */
+
+EXPORT void wf_wl P_((p_wf_t,char *));
+/* Same as wf_wr except that appends a '\n'. */
+
+EXPORT void wf_blk P_((p_wf_t,char *,size_t));
+/* Same as wf_wr but writes a block of bytes whose address is given by the */
+/* second parameter and whose length (in bytes) is given by the third */
+/* parameter. */
+
+EXPORT void wf_clo P_((p_wf_t));
+/* If WF is uninitialized, raises an error (probably). */
+/* If WF is in ERROR mode, returns with no effect. */
+/* If WF is CLOSED, raises an error. */
+/* Flushes and closes the output file attached to WF. */
+/* Sets WF to the CLOSED state. */
+/* Sets WF to the ERROR state if an error occurs during the close. */
+
+EXPORT bool wf_err P_((p_wf_t));
+/* If WF is uninitialized, raises an error (probably). */
+/* Returns TRUE iff WF is in the ERROR state, otherwise FALSE. */
+/* This function can be called at any time so long as the WF is initialized. */
+
+/******************************************************************************/
+
+/* For #ifndef preventing multiple inclusion of the body of this header file. */
+#endif
+
+/******************************************************************************/
+/* End of WRITFILE.H */
+/******************************************************************************/
diff --git a/web/funnelAC/tests/0license.txt b/web/funnelAC/tests/0license.txt
new file mode 100644
index 0000000000..8c2fba8bec
--- /dev/null
+++ b/web/funnelAC/tests/0license.txt
@@ -0,0 +1,37 @@
+
+FUNNNELWEB COPYRIGHT
+====================
+FunnelWeb is a literate-programming macro preprocessor.
+
+The files in this directory are:
+
+Copyright (C) 1992 Ross N. Williams.
+
+ Ross N. Williams
+ ross@spam.adelaide.edu.au
+ 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of Version 2 of the GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See Version 2 of the GNU General Public License for more details.
+
+You should have received a copy of Version 2 of the GNU General Public
+License along with this program. If not, you can FTP the license from
+prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Section 2a of the license requires that all changes to this file be
+recorded prominently in this file. Please record all changes here.
+
+Programmers:
+ RNW Ross N. Williams ross@spam.adelaide.edu.au
+
+Changes:
+ 07-May-1992 RNW Program prepared for release under GNU GPL V2.
+
+###############################################################################
+
diff --git a/web/funnelAC/tests/an01.fw b/web/funnelAC/tests/an01.fw
new file mode 100644
index 0000000000..a936932caa
--- /dev/null
+++ b/web/funnelAC/tests/an01.fw
@@ -0,0 +1,2 @@
+AN01: Test with no macros at all.
+
diff --git a/web/funnelAC/tests/an02.fw b/web/funnelAC/tests/an02.fw
new file mode 100644
index 0000000000..450ad5ceab
--- /dev/null
+++ b/web/funnelAC/tests/an02.fw
@@ -0,0 +1,3 @@
+AN02: Test with one macro but no output file.
+
+@$@<Sloth@>@Z@{@}
diff --git a/web/funnelAC/tests/an03.fw b/web/funnelAC/tests/an03.fw
new file mode 100644
index 0000000000..db1a06c7a1
--- /dev/null
+++ b/web/funnelAC/tests/an03.fw
@@ -0,0 +1,48 @@
+AN03: Test semantics checking of macros.
+
+First define some macros to call.
+@$@<Zero@>@Z@M@{@}
+@$@<One@>@(@1@)@Z@M@{@}
+@$@<Two@>@(@2@)@Z@M@{@}
+
+1. Test call to undefined macro.
+@$@<Sloth1@>@Z==@{@<Walrus@>@}
+
+2. Test calls with wrong number of parameters.
+@$@<Sloth2@>@Z==@{
+@<Zero@>
+@<Zero@>@(@)
+@<Zero@>@(@,@)
+@<One@>
+@<One@>@(@)
+@<One@>@(Walrus@,@)
+@<Two@>@(Sloth@)
+@}
+
+3. Test call to file macro.
+@O@<deleteme.txt@>@{@}
+@$@<Teapot@>@Z@{@<deleteme.txt@>@}
+
+4. Test macro never used and has <special>Z.
+@$@<Elephant@>@Z@{@}
+
+5. Test macro often used and has <special>M.
+@$@<Giraffe@>@M@{@}
+@$@<Use Giraffe@>@Z@{@<Giraffe@>@<Giraffe@>@}
+
+6. Test macro never used and no <special>Z
+@$@<Zebra@>@{@}
+
+7. Test multiply used and no <special>M.
+@$@<Monkey@>@{@}
+@$@<Use Monkey@>@Z@{@<Monkey@>@<Monkey@>@}
+
+8. Test directly recursive macro.
+@$@<Who do ya call?@>@{@<Who do ya call?@>@}
+
+9. Test indirectly recursive macro.
+@$@<X@>@M@{@<Y@>@}
+@$@<Y@>@{@<X@>@}
+
+10. Test callers of recursive macros.
+@$@<Z@>@Z@{@<X@>@}
diff --git a/web/funnelAC/tests/an04.fw b/web/funnelAC/tests/an04.fw
new file mode 100644
index 0000000000..3e46b9da55
--- /dev/null
+++ b/web/funnelAC/tests/an04.fw
@@ -0,0 +1,14 @@
+AN04: Test document list checks.
+
+1. Test for sections with no names.
+
+@A@<This section has both a name and a macro@>
+@$@<Sloth@>@Z@{@}
+
+@A@<This section has an explicit name but no macro@>
+
+@A
+@$@<This section has no explicit name but does have a macro@>@Z@{@}
+
+@A This section has no name and no macro to inherit one from.
+
diff --git a/web/funnelAC/tests/ex01.fw b/web/funnelAC/tests/ex01.fw
new file mode 100644
index 0000000000..72727d9295
--- /dev/null
+++ b/web/funnelAC/tests/ex01.fw
@@ -0,0 +1,3 @@
+EX01: A simple hello world program.
+
+@O@<ex01.out@>@{Hello World@+@}
diff --git a/web/funnelAC/tests/ex02.fw b/web/funnelAC/tests/ex02.fw
new file mode 100644
index 0000000000..a1e820e572
--- /dev/null
+++ b/web/funnelAC/tests/ex02.fw
@@ -0,0 +1,8 @@
+EX02: An example that demonstrates the use of simple macros.
+
+@O@<ex02.out@>@{@<Greetings@>@+@}
+
+@$@<H@>==@{Hello@}
+@$@<W@>==@{World@}
+
+@$@<Greetings@>==@{@<H@> @<W@>@}
diff --git a/web/funnelAC/tests/ex03.fw b/web/funnelAC/tests/ex03.fw
new file mode 100644
index 0000000000..6da784a71d
--- /dev/null
+++ b/web/funnelAC/tests/ex03.fw
@@ -0,0 +1,36 @@
+EX03: An example containing errors to do with the number of times
+ that macros are called.
+
+@O@<ex03.out@>==@{@-
+@<Include Files@>
+@<Include Files@>
+@<Main Program@>
+@}
+
+@$@<Main Program@>==@{@-
+main()
+{
+ doit();
+}
+@}
+
+@$@<Subroutine@>==@{@-
+void doit()
+{
+ int i;
+ for (i=0;i<10;i++)
+ {
+ @<Print@>
+ @<Print@>
+ }
+}@}
+
+@$@<Print@>==@{@-
+printf("Hello World!");
+printf("\n");@}
+
+@$@<Scan@>==@{scanf@}
+
+@$@<Include Files@>==@{@-
+#include <stdio.h>
+#include <stdlib.h>@}
diff --git a/web/funnelAC/tests/ex04.fw b/web/funnelAC/tests/ex04.fw
new file mode 100644
index 0000000000..07ced7f8ff
--- /dev/null
+++ b/web/funnelAC/tests/ex04.fw
@@ -0,0 +1,35 @@
+EX04: The same as EX03, but with the errors fixed.
+
+@O@<ex04.out@>==@{@-
+@<Include Files@>
+@<Function@>
+@<Main Program@>
+@}
+
+@$@<Main Program@>==@{@-
+main()
+{
+ doit();
+}
+@}
+
+@$@<Function@>==@{@-
+void doit()
+{
+ int i;
+ for (i=0;i<10;i++)
+ {
+ @<Print@>
+ @<Print@>
+ }
+}@}
+
+@$@<Print@>@M==@{@-
+printf("Hello World!");
+printf("\n");@}
+
+@$@<Scan@>@Z==@{scanf@}
+
+@$@<Include Files@>==@{@-
+#include <stdio.h>
+#include <stdlib.h>@}
diff --git a/web/funnelAC/tests/ex05.fw b/web/funnelAC/tests/ex05.fw
new file mode 100644
index 0000000000..97205705d8
--- /dev/null
+++ b/web/funnelAC/tests/ex05.fw
@@ -0,0 +1,50 @@
+EX05: An example in which Pascal program text is rearranged to form an ADT.
+ This example demonstrates the use of additive macros.
+
+@!******************************
+
+@O@<ex05.out@>==@{@-
+program adt(input,output);
+@<Types@>
+@<Variables@>
+@<Procedures@>
+begin startproc; end.
+@}
+
+@!******************************
+
+@$@<Types@>+=@{@-
+type buffer_type =
+ record
+ length : integer;
+ buf : array[1..100] of char;
+ end;
+@}
+
+@$@<Variables@>+=@{@-
+bigbuf : buffer_type;
+@}
+
+@$@<Procedures@>+=@{@-
+procedure buf_init (var b : buffer_type ) {Body of buf_init}
+procedure buf_add (var b : buffer_type; ch : char) {Body of buf_add}
+procedure buf_get (var b : buffer_type; var ch : char) {Body of buf_get}
+@}
+
+@!******************************
+
+@$@<Types@>+=@{@-
+type complex_type = record r,i : real; end;
+@}
+
+@$@<Procedures@>+=@{@-
+procedure cm_set (var c: complex_type; a,b: real) {Body of cm_set}
+procedure cm_add (a,b: complex_type; var c: complex_type) {Body of cm_add}
+{Other procedures and functions}
+@}
+
+@!******************************
+
+{...more pieces of program...}
+
+@!******************************
diff --git a/web/funnelAC/tests/ex06.fw b/web/funnelAC/tests/ex06.fw
new file mode 100644
index 0000000000..9391dc036d
--- /dev/null
+++ b/web/funnelAC/tests/ex06.fw
@@ -0,0 +1,57 @@
+EX06: An example in which Pascal program text is rearranged to form an ADT.
+ This example achieves what EX05 does, but without additive macros.
+
+@!******************************
+
+@O@<ex06.out@>==@{@-
+program adt(input,output);
+@<Types@>
+@<Variables@>
+@<Procedures@>
+begin startproc; end.
+@}
+
+@$@<Types@>==@{@-
+@<Buffer type@>
+@<Complex type@>
+@}
+
+@$@<Variables@>==@{@-
+@<Buffer variable@>
+@}
+
+@$@<Procedures@>==@{@-
+@<Buffer procedures@>
+@<Complex procedures@>
+@}
+
+@!******************************
+
+@$@<Buffer type@>==@{@-
+type buffer_type = record
+ length : integer;
+ buf : array[1..100] of char;
+ end;
+@}
+
+@$@<Buffer variable@>==@{@-
+bigbuf : buffer_type;
+@}
+
+@$@<Buffer procedures@>==@{@-
+procedure buf_init(var b : buffer_type) {Body of buf_init}
+procedure buf_add(var b : buffer_type; ch : char) {Body of buf_add}
+procedure buf_get(var b : buffer_type; var ch : char) {Body of buf_get}
+@}
+
+@!******************************
+
+@$@<Complex type@>==@{@-
+type complex_type = record r,i : real; end;
+@}
+
+@$@<Complex procedures@>+=@{@-
+procedure cm_set(var c: complex_type; a,b : real) {Body of cm_set}
+procedure cm_add(a,b : complex_type; var c: complex_type) {Body of cm_add}
+{Other procedures and functions}
+@}
diff --git a/web/funnelAC/tests/ex07.fw b/web/funnelAC/tests/ex07.fw
new file mode 100644
index 0000000000..0ac37e1899
--- /dev/null
+++ b/web/funnelAC/tests/ex07.fw
@@ -0,0 +1,30 @@
+EX07: This example demonstrates the use of macro parameters.
+
+@O@<ex07.out@>==@{@<While user code@>@+@}
+
+@$@<While loop@>@(@3@)@M==@{@-
+@1
+while (@2)
+ {
+ @3
+ }
+@}
+
+@$@<While user code@>==@{
+
+@! First form of actual parameters without whitespace and double quotes.
+@<While loop@>@(x=1;@,x<=10@,printf("X=%u\n",x);@)
+
+@! Second form of actual parameters. The double quotes allow non-active
+@! whitespace that helps to lay out the actual parameters neatly.
+@! This call is functionally identical to the one above.
+@<While loop@>@(
+ @"x:=1;@" @,
+ @"x<=10@" @,
+ @"printf("X=%u\n",x);@" @)
+
+@! The two forms can be mixed in a single call.
+@<While loop@>@(x=1;@,x<=10@,
+ @"printf("X=%u\n",x);@" @)
+
+@}
diff --git a/web/funnelAC/tests/ex08.fw b/web/funnelAC/tests/ex08.fw
new file mode 100644
index 0000000000..d4f5c5a9d2
--- /dev/null
+++ b/web/funnelAC/tests/ex08.fw
@@ -0,0 +1,39 @@
+EX08: This example demonstrates the use of parameterized macros.
+
+@O@<ex08.out@>==@{@-
+The Twelve Bugs of Christmas
+----------------------------
+@<Verse@>@(@"first@" @,@<1@>@)
+@<Verse@>@(@"second@" @,@<2@>@)
+@<Verse@>@(@"third@" @,@<3@>@)
+@<Verse@>@(@"fourth@" @,@<4@>@)
+@<Verse@>@(@"fifth@" @,@<5@>@)
+@<Verse@>@(@"sixth@" @,@<6@>@)
+@<Verse@>@(@"seventh@" @,@<7@>@)
+@<Verse@>@(@"eighth@" @,@<8@>@)
+@<Verse@>@(@"ninth@" @,@<9@>@)
+@<Verse@>@(@"tenth@" @,@<A@>@)
+@<Verse@>@(@"eleventh@" @,@<B@>@)
+@<Verse@>@(@"twelfth@" @,@<C@>@)
+
+This song appeared in the internet newsgroup rec.humor.funny on 24-Dec-1991.
+It was contributed by Pat Scannell (scannell@@darkstar.ma30.bull.com).
+@}
+
+@$@<Verse@>@(@2@)@M==@{@-
+For the @1 bug of Christmas, my manager said to me
+ @2
+@}
+
+@$@<1@>@M==@{See if they can do it again.@}
+@$@<2@>@M==@{Ask them how they did it and@+@<1@>@}
+@$@<3@>@M==@{Try to reproduce it@+@<2@>@}
+@$@<4@>@M==@{Run with the debugger@+@<3@>@}
+@$@<5@>@M==@{Ask for a dump@+@<4@>@}
+@$@<6@>@M==@{Reinstall the software@+@<5@>@}
+@$@<7@>@M==@{Say they need an upgrade@+@<6@>@}
+@$@<8@>@M==@{Find a way around it@+@<7@>@}
+@$@<9@>@M==@{Blame it on the hardware@+@<8@>@}
+@$@<A@>@M==@{Change the documentation@+@<9@>@}
+@$@<B@>@M==@{Say it's not supported@+@<A@>@}
+@$@<C@>@M==@{Tell them it's a feature@+@<B@>@}
diff --git a/web/funnelAC/tests/ex09.fw b/web/funnelAC/tests/ex09.fw
new file mode 100644
index 0000000000..a37a0c2582
--- /dev/null
+++ b/web/funnelAC/tests/ex09.fw
@@ -0,0 +1,8 @@
+EX09: This example demonstrates the use of include files.
+
+@O@<ex09.out@>==@{
+I like to go shooting, it's a whole lot of fun,
+@i ex09a.fwi
+Cos they know my camera isn't loaded with lead.
+- RNW, 04-Jan-1991.
+@}
diff --git a/web/funnelAC/tests/ex09a.fwi b/web/funnelAC/tests/ex09a.fwi
new file mode 100644
index 0000000000..949d45e14f
--- /dev/null
+++ b/web/funnelAC/tests/ex09a.fwi
@@ -0,0 +1,2 @@
+'Cos I shoot with a camera instead of a gun.
+The animals flock to be petted and fed,
diff --git a/web/funnelAC/tests/ex10.fw b/web/funnelAC/tests/ex10.fw
new file mode 100644
index 0000000000..09fd52043a
--- /dev/null
+++ b/web/funnelAC/tests/ex10.fw
@@ -0,0 +1,6 @@
+EX10: This example demonstrates the level at which include files are included.
+
+@O@<ex10.out@>==@{@-
+@i ex10a
+This is the text of the sloth macro.
+@}
diff --git a/web/funnelAC/tests/ex10a.fwi b/web/funnelAC/tests/ex10a.fwi
new file mode 100644
index 0000000000..8dc34aec9d
--- /dev/null
+++ b/web/funnelAC/tests/ex10a.fwi
@@ -0,0 +1,4 @@
+@<Sloth@>
+@}
+
+@$@<Sloth@>==@{@-
diff --git a/web/funnelAC/tests/ex11.fw b/web/funnelAC/tests/ex11.fw
new file mode 100644
index 0000000000..2652e48391
--- /dev/null
+++ b/web/funnelAC/tests/ex11.fw
@@ -0,0 +1,22 @@
+EX11: This example shows how FunnelWeb typesets macros, typesetter commands
+ and free text.
+
+You are reading some free text before the macro. Free text can consist
+of any text (not containing the FunnelWeb special character) including
+typesetter commands
+such as $, %, #, and \TeX{} which
+will be typeset to appear exactly as they do in the input file!
+Look out! Here comes a macro!
+
+@O@<ex11.out@>==@{@-
+This text is part of
+a macro definition.
+@}
+
+This is free text following the macro. This sentence contains
+two @{inline@} typesetter @/directives@/.
+Now here is a non-inline typesetting directive.
+
+@t new_page
+
+This sentence will appear on the next page.
diff --git a/web/funnelAC/tests/ex12.fw b/web/funnelAC/tests/ex12.fw
new file mode 100644
index 0000000000..0f90b77995
--- /dev/null
+++ b/web/funnelAC/tests/ex12.fw
@@ -0,0 +1,17 @@
+EX12: This example gives some simple headings and demonstrates heading name
+ inheritance.
+
+@O@<ex12.out@>==@{dummy text@}
+
+@A@<Feed the Penguins and Save the World@>
+@B@<Feed the Penguins@>
+@C@<Feed the little penguins@>
+@C@<Feed the big penguins@>
+@B@<Save the World@>
+@C@<Save Europe@>
+@C@<Save Africa@>
+
+@C This heading hasn't been given an explicit name, but will inherit the
+name \p{Save the rest of the world} from the macro definition below.
+
+@$@<Save the rest of the world@>@Z==@{...@}
diff --git a/web/funnelAC/tests/ex13.fw b/web/funnelAC/tests/ex13.fw
new file mode 100644
index 0000000000..db1bce2216
--- /dev/null
+++ b/web/funnelAC/tests/ex13.fw
@@ -0,0 +1,46 @@
+EX13: This example is used to generate typeset documentation which is
+ discussed in the tutorial in the FunnelWeb user's manual.
+
+
+@A@<Table of Contents@>
+
+@t table_of_contents
+
+@A@<Macros for Moral Support@>
+
+The following macro contain comments that provide moral support in the
+output code.
+
+@$@<Programmer's Cheer@>@M==@{
+-- Shift to the left!
+-- Shift to the right!
+-- Pop up, push down!
+-- Byte! Byte! Byte!
+-- (From "The New Hacker's Dictionary").
+@}
+
+The next macro is similar but is distributed throughout the program.
+@$@<Hacker's Cheer@>+=@{@+-- Pointer to the left@+@}
+
+@A@<An Extremely Imperative Stack Abstraction@>
+
+@B@<Define the Stack@>
+@$@<Hacker's Cheer@>+=@{-- Pointer to the right@+@}
+@$@<Stack Type@>@Z==@{type stack = record ... end;@}
+
+@B@<Push the Stack@>
+@$@<Hacker's Cheer@>+=@{-- Hack that code@+@}
+@$@<Push Procedure@>@Z==@{@-
+procedure push(var b:stack; v:value); @<Programmer's Cheer@> {...}@}
+
+@B@<Pop the Stack@>
+@$@<Hacker's Cheer@>+=@{-- Tight! Tight! Tight!@+@}
+@$@<Pop Procedure@>@Z==@{@-
+procedure pop(var b:stack); @<Programmer's Cheer@> {...}@}
+
+@B@<Rough the Stack Up a Bit@>
+@$@<Hacker's Cheer@>+=@{-- (RNW, 04-Jan-1991).@+@}
+@$@<Rough Procedure@>@Z==@{@-
+procedure rough(var b:stack); @<Hacker's Cheer@> {...}@}
+
+@O@<dummy.txt@>==@{dummy@+@}
diff --git a/web/funnelAC/tests/ex14.fw b/web/funnelAC/tests/ex14.fw
new file mode 100644
index 0000000000..517a79e758
--- /dev/null
+++ b/web/funnelAC/tests/ex14.fw
@@ -0,0 +1,7 @@
+EX14: This example demonstrates the literal and emphasis typesetting constructs.
+
+The following procedure @{put_sloth@} writes the @{sloth@} variable to
+the output file. Note: @/The output file must be opened for writing
+at this point or the program will crash!@/
+
+@O@<ex14.out@>==@{dummy@+@}
diff --git a/web/funnelAC/tests/ex15.fw b/web/funnelAC/tests/ex15.fw
new file mode 100644
index 0000000000..db9cd699c0
--- /dev/null
+++ b/web/funnelAC/tests/ex15.fw
@@ -0,0 +1,19 @@
+EX15: This example demonstrates some of FunnelWeb's generic typesetting
+ constructs.
+
+@t vskip 40 mm
+@t title titlefont centre "Hairy Wombat"
+@t title titlefont centre "Simulation"
+@t vskip 10 mm
+@t title smalltitlefont centre "A Program in Six Parts"
+@t title smalltitlefont centre "Simulating the Life of Some Hairy Wombats"
+@t vskip 20 mm
+@t title normalfont left "By Zqitzypbuswapzra Ypongtatoslrtzz"
+@t new_page
+@t table_of_contents
+@t new_page
+
+@A@<Section One@>
+@A@<Section Two@>
+
+@O@<ex15.out@>==@{Dummy@+@}
diff --git a/web/funnelAC/tests/ex16.fw b/web/funnelAC/tests/ex16.fw
new file mode 100644
index 0000000000..28fdeef366
--- /dev/null
+++ b/web/funnelAC/tests/ex16.fw
@@ -0,0 +1,66 @@
+@!---------------------------------------!
+@! Start of FunnelWeb Example .fw File !
+@!---------------------------------------!
+
+@t vskip 40 mm
+@t title titlefont centre "Powers:"
+@t title titlefont centre "An Example of"
+@t title titlefont centre "A Short"
+@t title titlefont centre "FunnelWeb .fw File"
+@t vskip 10 mm
+@t title smalltitlefont centre "by Ross Williams"
+@t title smalltitlefont centre "26 January 1992"
+@t vskip 20 mm
+@t table_of_contents
+
+@A@<FunnelWeb Example Program@>
+
+This program writes out each of the first @{p@} powers of the first @{n@}
+integers. These constant parameters are located here so that they are easy to
+change.
+
+@$@<Constants@>==@{@-
+n : constant natural := 10; -- How many numbers? (Ans: [1,n]).
+p : constant natural := 5; -- How many powers? (Ans: [1,p]).@}
+
+@B Here is the outline of the program. This FunnelWeb file generates a single
+Ada output file called @{Power.ada@}. The main program consists of a loop that
+iterates once for each number to be written out.
+
+@O@<ex16.out@>==@{@-
+@<Pull in packages@>
+
+procedure example is
+ @<Constants@>
+begin -- example
+ for i in 1..n loop
+ @<Write out the first p powers of i on a single line@>
+ end loop;
+end example;
+@}
+
+@B In this section, we pull in the packages that this program needs to run. In
+fact, all we need is the IO package so that we can write out the results. To use
+the IO package, we first of all need to haul it in (@{with text_io@}) and then
+we need to make all its identifiers visible at the top level (@{use text_io@}).
+
+@$@<Pull in packages@>==@{with text_io; use text_io;@}
+
+@B Here is the bit that writes out the first @{p@} powers of @{i@}. The power
+values are calculated incrementally in @{ip@} to avoid the use of the
+exponentiation operator.
+
+@$@<Write out the first p powers of i on a single line@>==@{@-
+declare
+ ip : natural := 1;
+begin
+ for power in 1..p loop
+ ip:=ip*i;
+ put(natural'image(ip) & " ");
+ end loop;
+ new_line;
+end;@}
+
+@!---------------------------------------!
+@! End of FunnelWeb Example .fw File !
+@!---------------------------------------!
diff --git a/web/funnelAC/tests/generate.fw b/web/funnelAC/tests/generate.fw
new file mode 100644
index 0000000000..6df5a66683
--- /dev/null
+++ b/web/funnelAC/tests/generate.fw
@@ -0,0 +1,61 @@
+Generate.Web
+============
+Some of the FunnelWeb tests require input files that contain control
+characters, improperly terminated lines, and other special constructs
+designed to test FunnelWeb's capacity to deal with anything that could
+arise in an input text file.
+
+Unfortunately, by their very nature, these constructs tend to be vulnerable
+to file transfer programs and other utilities (e.g. FIXEOLS!) that take it
+upon themselves to "fix up" various problems with text files.
+
+The solution adopted here is to totally avoid the problem by using FunnelWeb
+itself to generate these awkward test files. The following output file
+macro definitions achieve this.
+
+This FunnelWeb file should be fed into FunnelWeb before testing begins.
+
+@!------------------------------------------------------------------------------
+
+@O@<sc06.fw@>==@{@-
+SC06: Test FunnelWeb on a file whose last line is not terminated properly
+with an end of line marker.
+
+Here is the improper termination!---->@}
+
+@!------------------------------------------------------------------------------
+
+@O@<sc08.fw@>==@{@-
+SC08: Detection of trailing spaces.
+
+This line has zero trailing spaces |
+This line has one trailing space | @+@-
+This line has two trailing spaces | @+@-
+This line has three trailing spaces | @+@-
+@}
+
+@!------------------------------------------------------------------------------
+
+@O@<sc09.fw@>==@{@-
+SC09: Detection of control characters.
+
+SC09.1 Test that control characters are detected and replaced by "?".
+SC09.2 Test non printable that has a mnemonic.
+
+There is a tab between these two bars |@^D(009)| which should come out as "?".
+The above error message should contain the mnemonic "HT".
+
+SC09.3 Test non printable that has no mnemonic.
+
+There is a non-mnemonic control character between these bars |@^D(234)|.
+@}
+
+@!------------------------------------------------------------------------------
+
+@O@<sc13e.fwi@>==@{@-
+This is the include file for test SC13e. The test is to see how FunnelWeb
+copes with an include file that has an improperly terminated last line.
+
+Here is the improper termination!---->@}
+
+@!------------------------------------------------------------------------------
diff --git a/web/funnelAC/tests/hi01.fw b/web/funnelAC/tests/hi01.fw
new file mode 100644
index 0000000000..4c85c5949c
--- /dev/null
+++ b/web/funnelAC/tests/hi01.fw
@@ -0,0 +1,14 @@
+HI01: This example demonstrates a problem with managing end of line markers.
+
+@O@<hi01.out@>==@{
+while the_walrus_is_sleepy do
+ begin
+ writeln('zzzzzzz');
+ @<Wake up the walrus@>
+ writeln('Umpharumpha...');
+ end;
+@}
+
+@$@<Wake up the walrus@>==@{
+wake_up_the_walrus(the_walrus);
+@}
diff --git a/web/funnelAC/tests/hi02.fw b/web/funnelAC/tests/hi02.fw
new file mode 100644
index 0000000000..ea4d0c2ac7
--- /dev/null
+++ b/web/funnelAC/tests/hi02.fw
@@ -0,0 +1,25 @@
+HI02: This example shows how FunnelWeb's macro facility can be used to
+ fudge conditionals.
+
+@O@<hi02.out@>==@{
+@<Sloth incrementing loop@>
+@}
+
+@A@<Debug Macro@>
+
+The following macro determines whether debug code will be included in the
+program. All lines of debug code commence with a call to this macro and so
+we can turn all that code on or off here by defining this macro to be either
+empty or the single-line comment symbol (\p{--}). Note the use of a
+quick macro name.
+
+@$@#D@M==@{@} @! Turns the debug code ON.
+@! Use this definition to turn the debug code OFF: @$@#D==@{--@}
+
+
+@$@<Sloth incrementing loop@>==@{@-
+while sloth<walrus loop
+ @#D assert(sloth<walrus,"AWK! sloth>=walrus!!!!!!!");
+ @#D assert(timer<timermax,"AWK! timer>=timermax!!!");
+ inc(sloth);
+end loop@}
diff --git a/web/funnelAC/tests/hi03.fw b/web/funnelAC/tests/hi03.fw
new file mode 100644
index 0000000000..f7836346a3
--- /dev/null
+++ b/web/funnelAC/tests/hi03.fw
@@ -0,0 +1,25 @@
+HI03: This example shows how FunnelWeb's macro facility can be used to
+ fudge conditionals. This method is different to HI02.
+
+@O@<hi03.out@>==@{
+@<Sloth incrementing loop@>
+@}
+
+@A@<Debug Macro@>
+
+The following macro determines whether debug code will be included in the
+program. All debug code is wrapped by a call to this macro and so
+we can turn all the debug code on or off here by defining this macro to be
+either empty or its parameter.
+
+@$@#D@(@1@)@M==@{@1@} @! Turns the debug code ON.
+@! Use this definition to turn the debug code OFF: @$@#D@(@1@)==@{@}
+
+
+
+@$@<Sloth incrementing loop@>==@{@-
+while sloth<walrus loop
+ @#D@(assert(sloth<walrus,"AWK! sloth>=walrus!!!!!!!");
+ assert(timer<timermax,"AWK! timer>=timermax!!!");@)
+ inc(sloth);
+end loop@}
diff --git a/web/funnelAC/tests/hi04.fw b/web/funnelAC/tests/hi04.fw
new file mode 100644
index 0000000000..9dfb8c5fe4
--- /dev/null
+++ b/web/funnelAC/tests/hi04.fw
@@ -0,0 +1,23 @@
+HI04: This example shows how FunnelWeb's macro facility can be used to
+ fudge a multi-way conditional.
+
+@O@<hi04.out@>==@{@<Main code@>@}
+
+@A This module contains non-portable code that must execute on Hewlett
+Packard, Sun, and DEC workstations. The following FunnelWeb macro is
+defined to choose between these three. The first parameter is the HP code,
+the second is the Sun code, and the third is the DEC code. Whichever
+parameter constitutes the body of this macro determines which
+machine the code is being targetted for.
+
+@$@<Machine specific code@>@(@3@)@M==@{@1@} @! Configure for HP.
+
+@$@<Main code@>==@{@-
+-------
+@<Machine specific code@>@(
+@"get_command_line(comline)@" @, @! HP.
+@"scan_command_line(128,comline);@" @, @! Sun.
+@"dcl_get_command_line(comline,256);@" @) @! DEC.
+
+-------
+@}
diff --git a/web/funnelAC/tests/hi05.fw b/web/funnelAC/tests/hi05.fw
new file mode 100644
index 0000000000..8ae0ce8fd7
--- /dev/null
+++ b/web/funnelAC/tests/hi05.fw
@@ -0,0 +1,23 @@
+HI05: This example shows how FunnelWeb can be used to dissect a file.
+
+@O@<hi05.out@>==@{@-
+Unreadable Postscript code
+@<Print routine@>
+Unreadable Postscript code
+@<Zap routine@>
+Unreadable Postscript code
+@}
+
+@A This routine looks as if it does this, but really is does that,
+blah, blah blah.
+
+@$@<Print routine@>==@{@-
+/print { push pop pop push turn around and jump up and down and print it} def
+@}
+
+@A This routine zaps the...
+
+@$@<Zap routine@>==@{@-
+/zap { push pop pop push turn around and jump up and down and print it} def
+@}
+
diff --git a/web/funnelAC/tests/hi06.fw b/web/funnelAC/tests/hi06.fw
new file mode 100644
index 0000000000..1edcaa2471
--- /dev/null
+++ b/web/funnelAC/tests/hi06.fw
@@ -0,0 +1,22 @@
+HI06: This example shows how FunnelWeb can be used to allow compile
+time information sharing between two cooperating programs written in
+different programming languages.
+
+@A The following macro contains the temporary file name used to allow the
+two shellscripts to transfer each file to be printed.
+
+@$@<printfile@>@M==@{printme.txt@}
+
+@A Here are the scripts for the local VMS node and the remote UNIX node.
+
+@O@<hi06a.out@>==@{@-
+DCL commands
+copy @<printfile@> unixnode::
+DCL commands
+@}
+
+@O@<hi06b.out@>==@{@-
+unix commands
+print @<printfile@>
+unix commands
+@}
diff --git a/web/funnelAC/tests/hi07.fw b/web/funnelAC/tests/hi07.fw
new file mode 100644
index 0000000000..f3aa969f6a
--- /dev/null
+++ b/web/funnelAC/tests/hi07.fw
@@ -0,0 +1,16 @@
+HI07: This example demonstrates how FunnelWeb can be used to allow text
+sharing between documents.
+
+@O@<hi07a.out@>==@{@<M1@>@+@}
+@O@<hi07b.out@>==@{@<M2@>@+@}
+
+@$@<M1@>+=@{@<T1@>@}
+@$@<M2@>+=@{@<T1@>@}
+@$@<T1@>@M==@{First lump of text shared by both documents.@+@}
+
+@$@<M1@>+=@{Text for first document@+@}
+@$@<M2@>+=@{Text for second document@+@}
+
+@$@<M1@>+=@{@<T2@>@}
+@$@<M2@>+=@{@<T2@>@}
+@$@<T2@>@M==@{Second lump of text shared by both documents.@+@}
diff --git a/web/funnelAC/tests/hi08.fw b/web/funnelAC/tests/hi08.fw
new file mode 100644
index 0000000000..b10311e5a5
--- /dev/null
+++ b/web/funnelAC/tests/hi08.fw
@@ -0,0 +1,20 @@
+HI08: This example shows how parameterized macros can be used to choose
+ between alternative texts.
+
+@! Set the definition of @#D to
+@! @1 to create the shareholders report.
+@! @2 to create the customers report.
+@$@#D@(@2@)@M==@{@1@}
+
+@O@<hi08.out@>==@{@-
+1992 ANNUAL REPORT TO @#D@(Shareholders@,Customers@)
+======================@#D@(============@,=========@)
+This has been a very good year for The Very Big Corporation of America.
+With your help, we have been able to successfully
+@#D@(@"screw the customers for every cent they have@"@,
+ @"knock the shareholders into submission to bring you lower prices@"@).
+With gross earnings approaching six trillion dollars, we have been able to
+@#D@(@"increase dividends@"@,
+ @"lower prices@"@).
+We expect to have an even better year next year.
+@}
diff --git a/web/funnelAC/tests/hi09.fw b/web/funnelAC/tests/hi09.fw
new file mode 100644
index 0000000000..dadaf15971
--- /dev/null
+++ b/web/funnelAC/tests/hi09.fw
@@ -0,0 +1,111 @@
+HI09: This example demonstrates how FunnelWeb can be used to create generics
+ in languages that do not already provide them.
+
+@! We have to set the output line length limit up to cater for Barry Dwyer's
+@! rather horizontal coding style.
+@p maximum_output_line_length = 100
+
+@O@<hi09.out@>==@{
+@<Generic Set Module@>@(NaryTree@,NaryTreeSet@)
+@}
+
+@$@<Generic Set Module@>@(@2@)==@{@-
+@! @1 is the base type, @2 is the set type.
+[inherit ('@1'), environment ('@2')]
+
+module @2;
+
+type @2 = ^@2Record;
+ @2Record = record
+ Member: @1;
+ Next: @2;
+ end;
+
+procedure Null@2 (var Result: @2);
+begin new (Result);
+Result^.Member := (- MaxInt)::@1;
+Result^.Next := nil end;
+
+function IsNull@2 (S: @2): boolean;
+begin IsNull@2 := S^.Member::integer = - MaxInt end;
+
+procedure ForEach@1 (S: @2; procedure DoIt (i: @1));
+var ThisS, NextS: @2;
+begin ThisS := S;
+while ThisS^.Member::integer <> - MaxInt do
+ begin NextS := ThisS^.Next;
+ DoIt (ThisS^.Member);
+ ThisS := NextS end;
+end;
+
+function First@1 (S: @2): @1;
+begin First@1 := S^.Member end;
+
+function Is@1InSet (i: @1; S: @2): boolean;
+ procedure TestEquals (j: @1);
+ begin if Equal@1 (i, j) then Is@1InSet := true; end;
+begin Is@1InSet := false; ForEach@1 (S, TestEquals); end;
+
+function Includes@2 (S1, S2: @2): boolean;
+var Result: boolean;
+ procedure TestIfInS1 (i: @1);
+ begin if Result then if not Is@1InSet (i, S1) then Result := false; end;
+begin Result := true;
+ForEach@1 (S2, TestIfInS1);
+Includes@2 := Result end;
+
+function Disjoint@2s (S1, S2: @2): boolean;
+var Result: boolean;
+ procedure TestIfInS1 (i: @1);
+ begin if Result then if Is@1InSet (i, S1) then Result := false; end;
+begin Result := true;
+ForEach@1 (S2, TestIfInS1);
+Disjoint@2s := Result end;
+
+function Equal@2 (S1, S2: @2): boolean;
+begin
+Equal@2 := Includes@2 (S1, S2) and Includes@2 (S2, S1);
+end;
+
+procedure Insert@1 (i: @1; var S: @2);
+var This, Pred, Succ: @2;
+begin
+if not Is@1InSet (i, S) then
+ begin
+ Pred := nil; Succ := S;
+ while Succ^.Member::integer > i::integer do begin
+ Pred := Succ; Succ := Succ^.Next end;
+ if Succ^.Member::integer < i::integer then begin
+ new (This); This^.Next := Succ; This^.Member := i;
+ if Pred <> nil then Pred^.Next := This else S := This;
+ end;
+ end;
+end;
+
+procedure Insert@1s (S1: @2; var S2: @2);
+var This, Pred, Succ: @2;
+ procedure Add@1 (i: @1);
+ begin Insert@1 (i, S2) end;
+begin
+ForEach@1 (S1, Add@1);
+end;
+
+procedure Remove@1 (i: @1; var S: @2);
+var Pred, This: @2;
+begin
+Pred := nil; This := S;
+while not Equal@1 (This^.Member, i) do begin
+ Pred := This; This := This^.Next end;
+if Pred <> nil then Pred^.Next := This^.Next else S := This^.Next;
+Dispose (This);
+end;
+
+procedure Dispose@2 (var S: @2);
+var Old: @2;
+begin
+while S <> nil do begin Old := S; S := S^.Next; Dispose (Old) end;
+end;
+
+end.
+@}
+
diff --git a/web/funnelAC/tests/hi10.fw b/web/funnelAC/tests/hi10.fw
new file mode 100644
index 0000000000..4afd1e388a
--- /dev/null
+++ b/web/funnelAC/tests/hi10.fw
@@ -0,0 +1,83 @@
+HI10: This example gives examples of heavily and lightly documented pieces
+ of code.
+
+@O@<hi10.out@>==@{
+@<Set p to the length of the longest plateau in sorted array b[1..N]@>
+
+@<Function comp@>
+@}
+
+@A@<Calculation of the longest plateau in array b@>
+
+This section contains a solution to a problem outlined in section 16.3 of
+the book @/The Science of Programming@/ by David Gries[Gries81].
+
+@B Given a sorted array @{b[1..N]@} of integers, we wish to determine the
+@/length@/ of the longest run of identically valued elements in the array.
+This problem is defined by the following precondition and postcondition.
+
+@$@<Precondition@>==@{/* Pre: sorted(b). */@}
+@$@<Postcondition@>==@{@-
+/* Post: sorted(b) and p is the length of the longest run in b[1..N]. */@}
+
+@B We approach a solution to the problem by deciding to try the approach of
+scanning through the array one element at a time maintaining a useful
+invariant through each iteration. A loop variable
+array index @{i@} is created for this purpose. The bound function is
+@{N-i@}. Here is the invariant.
+
+@$@<Invariant@>==@{@-
+/* Invariant: sorted(b) and 1<=i<=N and */
+/* p is len of longest run in b[1..i]. */@}
+
+@B Establishing the invariant above in the initial, degenerate case is easy.
+
+@$@<Establish the plateau loop invariant initially@>==@{i=1; p=1;@}
+
+@B At this stage, we have the following loop structure. Note that when both
+the invariant and @{i != N@} are true, the postcondition holds and the loop
+can terminate.
+
+@$@<Set p to the length of the longest plateau in sorted array b[1..N]@>==@{@-
+@<Precondition@>
+@<Establish the plateau loop invariant initially@>
+while (i != N)
+ {
+ @<Invariant@>
+ @<Loop body@>
+ }
+@<Postcondition@>
+@}
+
+@B Now there remains only the loop body whose sole task is to increase @{i@}
+(and so decrease the value of the bound function) while maintaining the
+invariant. If @{p@} is the length of the longest run
+seen so far (i.e. in b[1..i]), then, because the array is sorted,
+the extension of our array range to
+@{b[1..i+1]@} can only result in an increase in @{p@} if the new element
+terminates a run of length @{p+1@}. The increase can be at most 1. Because
+the array is sorted, we need
+only compare the endpoints of this possible run to see if it exists. This
+is performed as shown below.
+
+@$@<Loop body@>==@{i++; if (b[i] != b[i-p]) p++;@}
+
+
+
+
+
+@A The following function compares two C~strings and returns TRUE iff they
+are identical.
+
+@$@<Function comp@>==@{@-
+bool comp(p,q)
+char *p,*q;
+{
+ while (TRUE)
+ {
+ if (*p != *q ) return FALSE;
+ if (*p == '\0') return TRUE;
+ p++; q++;
+ }
+}
+@}
diff --git a/web/funnelAC/tests/pr01.fw b/web/funnelAC/tests/pr01.fw
new file mode 100644
index 0000000000..652e2d313d
--- /dev/null
+++ b/web/funnelAC/tests/pr01.fw
@@ -0,0 +1,31 @@
+PR01: Test the inline typesetting features.
+
+1. First we test the legal use of the @{literal@} construct.
+
+2.Test @{@} (illegal).
+@A@<Error Recovery Point@>
+
+3. Test the construct @{across
+ more than one line@}.
+
+4. Now we test the construct with non-text following it.
+ @{@<sloth@>@}
+@A@<Error Recovery Point@>
+ @{ @> @}
+@A@<Error Recovery Point@>
+
+5. Test the legal use of the @/emphasis@/ construct.
+
+6.Test @/@/ (illegal).
+@A@<Error Recovery Point@>
+
+7. Test the construct @/across
+ more than one line@/.
+
+8. Now we test the construct with non-text following it.
+ @/@<sloth@>@/
+@A@<Error Recovery Point@>
+ @/ @< @/
+
+
+
diff --git a/web/funnelAC/tests/pr02.fw b/web/funnelAC/tests/pr02.fw
new file mode 100644
index 0000000000..a51890cdbb
--- /dev/null
+++ b/web/funnelAC/tests/pr02.fw
@@ -0,0 +1,14 @@
+PR02: Test the parsing of typesetter directives.
+
+1. Test parsing of new page directive.
+@t new_page
+
+2. Test parsing of table of contents directive.
+@t table_of_contents
+
+3. Test parsing of vskip directive.
+@t vskip 32 mm
+
+4. Test parsing of title directive.
+@t title titlefont left "Sloth"
+
diff --git a/web/funnelAC/tests/pr03.fw b/web/funnelAC/tests/pr03.fw
new file mode 100644
index 0000000000..8aadf4a1b9
--- /dev/null
+++ b/web/funnelAC/tests/pr03.fw
@@ -0,0 +1,27 @@
+PR03: Test the parsing and semantics of sections.
+
+4. Test first section of document is not <special>A.
+@B@<This section is out of order (and so is this test!)@>
+
+1. Test section with no name.
+@A This section has no name.
+@$@<The section name inherits the name of this macro@>@{Walrus@}
+
+2. Test section with a name
+@A@<This section has no name.@>
+
+3. Test the entire hierarchy.
+@A@<One@>
+@B@<Two@>
+@C@<Three@>
+@D@<Four@>
+@E@<Five@>
+
+5. Test detection of discontinuity in levels.
+@A@<One@>
+@C@<Three@>
+@E@<Five@>
+
+@A@<One@>
+@B@<Three@>
+@D@<Five@>
diff --git a/web/funnelAC/tests/pr04.fw b/web/funnelAC/tests/pr04.fw
new file mode 100644
index 0000000000..670d3ea6a5
--- /dev/null
+++ b/web/funnelAC/tests/pr04.fw
@@ -0,0 +1,33 @@
+PR04: Test the definition of ordinary macros.
+
+1. Test an ordinary macro definition.
+@$@<Ordinary@>@{The text of ordinary@}
+
+2. Test an ordinary definition using a quickname.
+@$@#|@{The text of ordinary@}
+
+3. Test a name that includes EOL.
+@$@<This name is illegal because
+it crosses a lion@>@{And people who cross lions tend to get eaten.@}
+@A@<Error Recovery Point@>
+
+4. Test the minimum length name (the empty name).
+@$@<@>@{The empty macro name is quite legal in FunnelWeb.@}
+
+5. Test a name at the maximum name length limit (80).
+ONly the second of the two macros should generate an error.
+@p maximum_input_line_length = 100
+@$@<12345678901234567890123456789012345678901234567890123456789012345678901234567890@>@{@}
+@$@<123456789012345678901234567890123456789012345678901234567890123456789012345678901@>@{@}
+@A@<Error Recovery Point@>
+
+6. Test names with all legal characters. There should be no errors.
+@$@< !"#$%'()*+,-./0123456789:;<=>?@>@{@}
+@$@<ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`@>@{@}
+@$@<abcdefghijklmnopqrstuvwxyz{|}~@>@{@}
+
+7. Test a name that has inserted text sequences.
+
+@$@<@^D(065)@@@>==@{@}
+
+
diff --git a/web/funnelAC/tests/pr05.fw b/web/funnelAC/tests/pr05.fw
new file mode 100644
index 0000000000..0a28168cbb
--- /dev/null
+++ b/web/funnelAC/tests/pr05.fw
@@ -0,0 +1,40 @@
+PR05: Test the parsing of formal parameter lists.
+
+First trip the parser so we don't get past the parser.
+@>
+
+1. Test macro definition with no formal parameters.
+@$@<Sloth@>@{Slothtext@}
+
+2. Test macro definition with one formal parameter.
+@$@<Sloth with one@>@(@1@)@{Slothtext@}
+
+3. Test macro definition with many formal parameters.
+@$@<Sloth with 2@>@(@2@)@{Slothtext@}
+@$@<Sloth with 3@>@(@3@)@{Slothtext@}
+@$@<Sloth with 4@>@(@4@)@{Slothtext@}
+@$@<Sloth with 5@>@(@5@)@{Slothtext@}
+@$@<Sloth with 6@>@(@6@)@{Slothtext@}
+@$@<Sloth with 7@>@(@7@)@{Slothtext@}
+@$@<Sloth with 8@>@(@8@)@{Slothtext@}
+@$@<Sloth with 9@>@(@9@)@{Slothtext@}
+
+4. Test with syntax errors in the parameter list.
+
+@$@<Sloth a@>@(@+@9@)@{Slothtext@}
+@A@<Error recovery point@>
+
+@$@<Sloth b@>@9@)@{Slothtext@}
+@A@<Error recovery point@>
+
+@$@<Sloth c@>@(9@)@{Slothtext@}
+@A@<Error recovery point@>
+
+@$@<Sloth d@>@9@)@{Slothtext@}
+@A@<Error recovery point@>
+
+@$@<Sloth e@>@(@9@)@)@{Slothtext@}
+@A@<Error recovery point@>
+
+
+
diff --git a/web/funnelAC/tests/pr06.fw b/web/funnelAC/tests/pr06.fw
new file mode 100644
index 0000000000..14b0c5e297
--- /dev/null
+++ b/web/funnelAC/tests/pr06.fw
@@ -0,0 +1,39 @@
+PR06: Test the parsing on invocation number constraints.
+
+Trip the parser so we don't get past it.
+@>
+
+1. Test with no zero and no many.
+@$@<Sloth@>@{No zero and no many in this macro@}
+
+2. Test with a zero.
+@$@<Sloth zero@>@Z@{Can be called from 0 to 1 times.@}
+
+3. Test with a many.
+@$@<Sloth many@>@M@{Can be called from 1 to infinity times.@}
+
+4. Test with a zero and a many.
+@$@<Sloth zeromany@>@Z@M@{Can be called from 0 to infinity times.@}
+
+5. Test with a zero and a many but out of order (should give error).
+@$@<Sloth manyzero@>@M@Z@{Oops.@}
+@A@<Error recovery point@>
+
+6. Test with syntactic errors.
+
+@$@<Sloth a@> @M @Z @{Oops.@}
+@A@<Error recovery point@>
+
+@$@<Sloth b@>@Z@Z@{Oops.@}
+@A@<Error recovery point@>
+
+@$@<Sloth c@Z@>@{Oops.@}
+@A@<Error recovery point@>
+
+@$@<Sloth d@>Z@{Oops.@}
+@A@<Error recovery point@>
+
+@$@<Sloth d@>@ZM@{Oops.@}
+@A@<Error recovery point@>
+
+
diff --git a/web/funnelAC/tests/pr07.fw b/web/funnelAC/tests/pr07.fw
new file mode 100644
index 0000000000..d0524f874d
--- /dev/null
+++ b/web/funnelAC/tests/pr07.fw
@@ -0,0 +1,36 @@
+PR07: Test the parsing of == and += in macro definitions.
+
+Trip the parser so we don't get any further.
+@>
+
+1. Test with no equals.
+@$@<Sloth@>@{No equals in this macro definition.@}
+
+2. Test with ==.
+@$@<Sloth with equals@>==@{No equals in this macro definition.@}
+
+3. Test with +=.
+@$@<Sloth with plus@>+=@{No equals in this macro definition.@}
+
+4. Test with syntax errors.
+
+@$@<Error1@>++@{No equals in this macro definition.@}
+@A@<Error recovery point@>
+
+@$@<Error2@>@+=@{No equals in this macro definition.@}
+@A@<Error recovery point@>
+
+@$@<Error3@>+==+@{No equals in this macro definition.@}
+@A@<Error recovery point@>
+
+@$@<Error4@>=+@{No equals in this macro definition.@}
+@A@<Error recovery point@>
+
+@$@<Error4@>@=@=@{No equals in this macro definition.@}
+@A@<Error recovery point@>
+
+@$@<Error4@>@+@=@{No equals in this macro definition.@}
+@A@<Error recovery point@>
+
+
+
diff --git a/web/funnelAC/tests/pr08.fw b/web/funnelAC/tests/pr08.fw
new file mode 100644
index 0000000000..b87164dba4
--- /dev/null
+++ b/web/funnelAC/tests/pr08.fw
@@ -0,0 +1,61 @@
+PR08: Test semantic checking of macro definitions.
+
+Trip parser to be sure that we won't get any output files!
+@>
+
+1. File macro has parameters. Error.
+@O@<Sloth 1@>@(@3@)@{Walrus@}
+@A@<Error recovery point@>
+
+2. File macro is additive. Error.
+@O@<Sloth 2@>+=@{Walrus@}
+@A@<Error recovery point@>
+
+3. File macro has too long a name. The test name has 1200 characters. Err.
+Note: This test can't test the error message if the maximum length of a
+macro name is less than the maximum length of a file name as the name
+error is caught first.
+@p maximum_input_line_length = infinity
+@O@<123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890@>@{@}
+@A@<Error recovery point@>
+
+4. File macro has zero or many attributes. Error.
+@O@<Sloth 3@>@Z@{Walrus@}
+@A@<Error recovery point@>
+
+@O@<Sloth 4@>@M@{Walrus@}
+@A@<Error recovery point@>
+
+@O@<Sloth 5@>@Z@M@{Walrus@}
+@A@<Error recovery point@>
+
+5. Previous definition is full, current is additive.
+@$@<Walrus 1@>==@{Sloth@}
+@$@<Walrus 1@>+=@{Aardvark@}
+@A@<Error recovery point@>
+
+6. Previous definition is additive, current is full.
+@$@<Walrus 2@>+=@{Sloth@}
+@$@<Walrus 2@>==@{Aardvark@}
+@A@<Error recovery point@>
+
+7. Non-first body part of partial has parameter.
+@$@<Unicorn@>@(@3@)+=@{Turkey@}
+@$@<Unicorn@>@(@3@)+=@{Turkey@}
+@A@<Error recovery point@>
+
+8. Zero or many attributes on non-first body part of additive.
+@$@<Elephant@>@Z@M+=@{Turkey@}
+@$@<Elephant@>@Z@M+=@{Turkey@}
+@A@<Error recovery point@>
+
+9. Check that non-existent formal parameters are caught.
+
+@$@<Zero@>@Z@{Sloth@1Walrus@}
+@A@<Error recovery point@>
+
+@$@<One@>@(@1@)@Z@{Sloth@2Walrus@}
+@A@<Error recovery point@>
+
+@$@<Many@>@(@7@)@Z@{Sloth@8Walrus@}
+@A@<Error recovery point@>
diff --git a/web/funnelAC/tests/pr09.fw b/web/funnelAC/tests/pr09.fw
new file mode 100644
index 0000000000..f8eb1bd5a5
--- /dev/null
+++ b/web/funnelAC/tests/pr09.fw
@@ -0,0 +1,92 @@
+PR09: Test calls and actual parameter lists.
+
+First trip up the parser so we don't get any further.
+@>
+
+Now define some macros to call. No error.
+
+@$@<Zero@>@{@}
+@$@<One@>@(@1@)@{@}
+@$@<Two@>@(@2@)@{@}
+@$@<Three@>@(@3@)@{@}
+@$@<Nine@>@(@9@)@{@}
+@$@#"@{@}
+
+The following test calls should NOT generate any errors.
+
+@$@<Macro containing the test macro calls.@>==@{
+1. Test macro call with no parameter list.
+@<Zero@>
+
+2. Test macro call with quick name.
+@#"
+
+3. Test macro call with one parameter.
+@<One@>@(Toucan@)
+
+4. Test macro call with many parameters.
+@<Two@>@(Toucan@,Teapot@)
+@<Three@>@(Toucan@,Teapot@,Walrus@)
+@<Nine@>@(Toucan@,Teapot@,Walrus@,
+ Toucan@,Teapot@,Walrus@,
+ Toucan@,Teapot@,Walrus@)
+
+5. Test macro calls with double quotes on parameters.
+@<One@>@( @"Toucan@"@)
+@<Two@>@(@"Toucan@" @, @"Teapot@"@)
+@<Three@>@(@"Toucan@" @,
+ @"Teapot@" @,
+ @"Walrus@" @)
+@<Nine@>@( @"Toucan@" @, @"Teapot@" @, @"Walrus@" @,
+ @"Toucan@" @, @"Teapot@" @, @"Walrus@" @,
+ @"Toucan@" @, @"Teapot@" @, @"Walrus@" @)
+
+7. Test macro calls with mixed double quotes on parameters.
+@<Two@>@(@"Toucan@" @,Teapot@)
+@<Three@>@(@"Toucan@" @,
+ @"Teapot@" @,Walrus@)
+@<Nine@>@( @"Toucan@" @, @"Teapot@" @, Walrus @,
+ @"Toucan@" @, Teapot @, @"Walrus@" @,
+ @"Toucan@" @, @"Teapot@" @, @"Walrus@" @)
+
+@} @! End of macro definition enclosing all these legal tests.
+
+8. Test macro calls with a variety of syntax errors in parameter list.
+@$@<Error1@>@{
+@<Zero@>@(
+@}
+@A@<Error recovery point@>
+
+@$@<Error2@>@{
+@<Zero@>@)
+@}
+@A@<Error recovery point@>
+
+@$@<Error3@>@{
+@<One@>@(@"Toucan@)
+@}
+@A@<Error recovery point@>
+
+@$@<Error4@>@{
+@<One@>@(@"Toucan@"@"Sloth@"@)
+@}
+@A@<Error recovery point@>
+
+@$@<Error5@>@{
+@<Two@>@(@"Toucan@"Teapot@)
+@}
+@A@<Error recovery point@>
+
+@$@<Error6@>@{
+@<Two@>@(@"Toucan@"Teapot
+@}
+@A@<Error recovery point@>
+
+@$@<Error7@>@{
+@<Two@>@(@"Toucan@"Teapot
+@<Three@>@(Toucan@,
+ @"Teapot@,Walrus
+
+@}
+@A@<Error recovery point@>
+
diff --git a/web/funnelAC/tests/pr10.fw b/web/funnelAC/tests/pr10.fw
new file mode 100644
index 0000000000..0e5bf191c8
--- /dev/null
+++ b/web/funnelAC/tests/pr10.fw
@@ -0,0 +1,28 @@
+PR10: Test syntactic error recovery.
+
+1. Test recovery at top parsing level.
+@<
+
+@A@<Error recovery point@>
+
+2. Test recovery inside macro definition.
+
+@$@<Sloth1@>@>==@{
+Walrus@}
+
+@$@<Sloth2@>==@{
+@<Walrus@<
+@}
+@A@<Error recovery point@>
+
+3. Test recovery inside actual parameter list in macro definition.
+@$@<Sloth3@>==@{
+@<Walrus@>@(@"aardvark@>
+@}
+@A@<Error recovery point@>
+
+4. Test EOF in the middle of a complicated construct.
+The following makes the end of the file looked chopped off, but it is
+actually intentional.
+@$@<Sloth4@>==@{
+@<Walrus@>@(@"aardva
diff --git a/web/funnelAC/tests/sc01_note.fw b/web/funnelAC/tests/sc01_note.fw
new file mode 100644
index 0000000000..a1cc7220f3
--- /dev/null
+++ b/web/funnelAC/tests/sc01_note.fw
@@ -0,0 +1,2 @@
+SC01: The first test tests what happens when FunnelWeb cannot find the
+specified input file. And so the file cannot exist!
diff --git a/web/funnelAC/tests/sc02.fw b/web/funnelAC/tests/sc02.fw
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/web/funnelAC/tests/sc02.fw
diff --git a/web/funnelAC/tests/sc03.fw b/web/funnelAC/tests/sc03.fw
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/web/funnelAC/tests/sc03.fw
@@ -0,0 +1 @@
+
diff --git a/web/funnelAC/tests/sc04.fw b/web/funnelAC/tests/sc04.fw
new file mode 100644
index 0000000000..139597f9cb
--- /dev/null
+++ b/web/funnelAC/tests/sc04.fw
@@ -0,0 +1,2 @@
+
+
diff --git a/web/funnelAC/tests/sc05.fw b/web/funnelAC/tests/sc05.fw
new file mode 100644
index 0000000000..83c91741b2
--- /dev/null
+++ b/web/funnelAC/tests/sc05.fw
@@ -0,0 +1 @@
+SC05: This input file contains a single line containing this text!
diff --git a/web/funnelAC/tests/sc06.fw b/web/funnelAC/tests/sc06.fw
new file mode 100644
index 0000000000..0ca81ee46d
--- /dev/null
+++ b/web/funnelAC/tests/sc06.fw
@@ -0,0 +1,4 @@
+SC06: Test FunnelWeb on a file whose last line is not terminated properly
+with an end of line marker.
+
+Here is the improper termination!----> \ No newline at end of file
diff --git a/web/funnelAC/tests/sc07.fw b/web/funnelAC/tests/sc07.fw
new file mode 100644
index 0000000000..ef0b2c31e7
--- /dev/null
+++ b/web/funnelAC/tests/sc07.fw
@@ -0,0 +1,25 @@
+SC07: Processing of long lines.
+
+SC07.1: Detection of a line longer than the default limit.
+
+The default limit is 80 characters so we will test on either side of
+that:
+ 1 2 3 4 5 6 7 8
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+The above should not trigger a "line too long error". But this line should!------
+
+SC07.3: Test the limit set at infinity.
+
+@p maximum_input_line_length = infinity
+
+ 1 2 3 4 5 6 7 8
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+The above should not trigger a "line too long error". Nor should this one!-------
+
+SC07.3: Test the limit set lower.
+
+@p maximum_input_line_length = 50
+
+ 1 2 3 4 5
+12345678901234567890123456789012345678901234567890
+No error for the above but this line will!---------
diff --git a/web/funnelAC/tests/sc08.fw b/web/funnelAC/tests/sc08.fw
new file mode 100644
index 0000000000..2e59304d8f
--- /dev/null
+++ b/web/funnelAC/tests/sc08.fw
@@ -0,0 +1,6 @@
+SC08: Detection of trailing spaces.
+
+This line has zero trailing spaces |
+This line has one trailing space |
+This line has two trailing spaces |
+This line has three trailing spaces |
diff --git a/web/funnelAC/tests/sc09.fw b/web/funnelAC/tests/sc09.fw
new file mode 100644
index 0000000000..7b6520ed68
--- /dev/null
+++ b/web/funnelAC/tests/sc09.fw
@@ -0,0 +1,11 @@
+SC09: Detection of control characters.
+
+SC09.1 Test that control characters are detected and replaced by "?".
+SC09.2 Test non printable that has a mnemonic.
+
+There is a tab between these two bars | | which should come out as "?".
+The above error message should contain the mnemonic "HT".
+
+SC09.3 Test non printable that has no mnemonic.
+
+There is a non-mnemonic control character between these bars |ê|.
diff --git a/web/funnelAC/tests/sc10.fw b/web/funnelAC/tests/sc10.fw
new file mode 100644
index 0000000000..0a221e9630
--- /dev/null
+++ b/web/funnelAC/tests/sc10.fw
@@ -0,0 +1,116 @@
+Scanner Test: Special Sequence Recognition
+==========================================
+This test tests to see that FunnelWeb is recognising the full set of special
+sequences.
+
+Turn Off the Parser
+-------------------
+First we cause a deliberate scanner error so as to prevent the parser from
+generating lots of errors over the syntactic rubbish presented here.
+
+ @
+
+List of All Possible Special Sequences
+--------------------------------------
+The following is a list of the default special character followed by each of
+the ASCII printables.
+000 to 031 are unprintable control characters.
+
+032 @ - ILLEGAL. (Note: Hyphen is needed to avoid trailing blanks error.)
+033 @! - Comment.
+034 @" - Parameter delimeter.
+035 @#X - Short name sequence.
+@$ 036 - Define macro. Has to be at start of line.
+037 @% - ILLEGAL.
+038 @& - ILLEGAL.
+039 @' - ILLEGAL.
+040 @( - Open parameter list.
+041 @) - Close parameter list.
+042
+@* - Old fashioned section marker (has to be at start of a line.).
+043 @+ - Insert newline.
+044 @, - Parameter separator.
+045 @-
+ - Ignore end of line marker (has to be at end of line).
+046 @. - ILLEGAL.
+047 @/ - Emphasised text.
+048 @0 - ILLEGAL.
+049 @1 - Formal parameter 1.
+050 @2 - Formal parameter 2.
+051 @3 - Formal parameter 3.
+052 @4 - Formal parameter 4.
+053 @5 - Formal parameter 5.
+054 @6 - Formal parameter 6.
+055 @7 - Formal parameter 7.
+056 @8 - Formal parameter 8.
+057 @9 - Formal parameter 9.
+058 @: - ILLEGAL.
+059 @; - ILLEGAL.
+060 @< - Open macro name.
+061 @=@ - Set special character.
+062 @> - Close macro name.
+063 @? - ILLEGAL.
+064 @@ - Insert special character into text.
+@A 065 - New section (level 1). Must be at start of a line.
+@B 066 - New section (level 2). Must be at start of a line.
+@C 067 - New section (level 3). Must be at start of a line.
+@D 068 - New section (level 4). Must be at start of a line.
+@E 069 - New section (level 5). Must be at start of a line.
+070 @F - ILLEGAL.
+071 @G - ILLEGAL.
+072 @H - ILLEGAL.
+073 @I - Include file. Will provoke an error here though.
+074 @J - ILLEGAL.
+075 @K - ILLEGAL.
+076 @L - ILLEGAL.
+077 @M - Tags macro as being allowed to be called many times.
+078 @N - ILLEGAL.
+@O 079 - New macro attached to output file. Has to be at start of line.
+080 @P - Pragma. Will cause error here though.
+081 @Q - ILLEGAL.
+082 @R - ILLEGAL.
+083 @S - ILLEGAL.
+084 @T - Typesetter directive. Will cause an error here though.
+085 @U - ILLEGAL.
+086 @V - ILLEGAL.
+087 @W - ILLEGAL.
+088 @X - ILLEGAL.
+089 @Y - ILLEGAL.
+090 @Z - Tags macro as being allowed to be called zero times.
+091 @[ - ILLEGAL.
+092 @\ - ILLEGAL.
+093 @] - ILLEGAL.
+094 @^D(065) - Insert control character into text
+095 @_ - ILLEGAL.
+096 @` - ILLEGAL.
+@a 097 - New section (level 1). Must be at start of a line.
+@b 098 - New section (level 1). Must be at start of a line.
+@c 099 - New section (level 1). Must be at start of a line.
+@d 100 - New section (level 1). Must be at start of a line.
+@e 101 - New section (level 1). Must be at start of a line.
+102 @f - ILLEGAL.
+103 @g - ILLEGAL.
+104 @h - ILLEGAL.
+105 @i - Include file. Will provoke an error here though.
+106 @j - ILLEGAL.
+107 @k - ILLEGAL.
+108 @l - ILLEGAL.
+109 @m - Tags macro as being allowed to be called many times.
+110 @n - ILLEGAL.
+@O 111 - New macro attached to output file. Has to be at start of line.
+112 @p - Pragma. Will cause error here though.
+113 @q - ILLEGAL.
+114 @r - ILLEGAL.
+115 @s - ILLEGAL.
+116 @t - Typesetter directive. Will cause an error here though.
+117 @u - ILLEGAL.
+118 @v - ILLEGAL.
+119 @w - ILLEGAL.
+120 @x - ILLEGAL.
+121 @y - ILLEGAL.
+122 @z - Tags macro as being allowed to be called zero times.
+123 @{ - Open macro body.
+124 @| - ILLEGAL.
+125 @} - Close macro body.
+126 @~ - ILLEGAL.
+127 to 255 are not standard printable ASCII characters.
diff --git a/web/funnelAC/tests/sc11.fw b/web/funnelAC/tests/sc11.fw
new file mode 100644
index 0000000000..4ee39f35c3
--- /dev/null
+++ b/web/funnelAC/tests/sc11.fw
@@ -0,0 +1,24 @@
+SC11: Syntax of the include pragma.
+
+1. Test include pragma not at start of line.
+
+ @i
+
+2. Test ATi not followed by a blank.
+
+@ix
+
+3. Test include filename is too long. The maximum on the Macintosh is
+ 255 but we will use a filename of over 1024 characters so as to make
+ the test portable. The actual length used is 1100 characters in the
+ filename.
+
+ 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
+@i 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
+
+4. Include pragma has an empty filename. Note: Because the ATi has to be
+ followed by a blank, we have to incur a trailing blank error here in
+ order to provoke the error we really want to see.
+
+@i
+
diff --git a/web/funnelAC/tests/sc12.fw b/web/funnelAC/tests/sc12.fw
new file mode 100644
index 0000000000..d33d26b680
--- /dev/null
+++ b/web/funnelAC/tests/sc12.fw
@@ -0,0 +1,6 @@
+SC12: Include file cannot be found.
+Test person: DONT create sc12a.inc. It is not supposed to exist!
+The following include should yield a "file not found error."
+
+@i sc12a.inc
+
diff --git a/web/funnelAC/tests/sc13.fw b/web/funnelAC/tests/sc13.fw
new file mode 100644
index 0000000000..3052630cd6
--- /dev/null
+++ b/web/funnelAC/tests/sc13.fw
@@ -0,0 +1,38 @@
+SC13: Various kinds of include file.
+
+1. Include file is empty.
+Before include
+@i sc13a
+After include
+
+2. Include file contains a single blank line.
+Before include
+@i sc13b
+After include
+
+3. Include file contains two blank lines.
+Before include
+@i sc13c
+After include
+
+4. Include file contains a single line with text on it.
+Before include
+@i sc13d
+After include
+
+5. Include file's last line is not properly terminated.
+Before include
+@i sc13e
+After include
+
+6. Include file is ordinary.
+Before include
+@i sc13f
+After include
+
+7. Test upper case I and file extension inheritance.
+Before include
+@I sc13f
+After include
+
+End of test File.
diff --git a/web/funnelAC/tests/sc13a.fwi b/web/funnelAC/tests/sc13a.fwi
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/web/funnelAC/tests/sc13a.fwi
diff --git a/web/funnelAC/tests/sc13b.fwi b/web/funnelAC/tests/sc13b.fwi
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/web/funnelAC/tests/sc13b.fwi
@@ -0,0 +1 @@
+
diff --git a/web/funnelAC/tests/sc13c.fwi b/web/funnelAC/tests/sc13c.fwi
new file mode 100644
index 0000000000..139597f9cb
--- /dev/null
+++ b/web/funnelAC/tests/sc13c.fwi
@@ -0,0 +1,2 @@
+
+
diff --git a/web/funnelAC/tests/sc13d.fwi b/web/funnelAC/tests/sc13d.fwi
new file mode 100644
index 0000000000..bb6cb827b1
--- /dev/null
+++ b/web/funnelAC/tests/sc13d.fwi
@@ -0,0 +1 @@
+This is the include file for test SC13d. Just a file containing one line.
diff --git a/web/funnelAC/tests/sc13e.fwi b/web/funnelAC/tests/sc13e.fwi
new file mode 100644
index 0000000000..91444064d4
--- /dev/null
+++ b/web/funnelAC/tests/sc13e.fwi
@@ -0,0 +1,4 @@
+This is the include file for test SC13e. The test is to see how FunnelWeb
+copes with an include file that has an improperly terminated last line.
+
+Here is the improper termination!----> \ No newline at end of file
diff --git a/web/funnelAC/tests/sc13f.fwi b/web/funnelAC/tests/sc13f.fwi
new file mode 100644
index 0000000000..5c786ee679
--- /dev/null
+++ b/web/funnelAC/tests/sc13f.fwi
@@ -0,0 +1,2 @@
+This is the include file for tests SC13.6 and SC13.7.
+There are only two lines, and this is the second one.
diff --git a/web/funnelAC/tests/sc14.fw b/web/funnelAC/tests/sc14.fw
new file mode 100644
index 0000000000..e7bbf6ae3e
--- /dev/null
+++ b/web/funnelAC/tests/sc14.fw
@@ -0,0 +1,6 @@
+SC14: Test that the maximum number of levels of include file is 10.
+This is most easily done with a recursive inclusion.
+
+Before the include
+@i sc14.fw
+After the include
diff --git a/web/funnelAC/tests/sc15.fw b/web/funnelAC/tests/sc15.fw
new file mode 100644
index 0000000000..68e4fadae9
--- /dev/null
+++ b/web/funnelAC/tests/sc15.fw
@@ -0,0 +1,30 @@
+SC15: Test that certain attributes are saved across inclusions.
+
+1. Maximum input line length.
+2. Special character.
+3. Local line number.
+
+To test this, we first set the first two attributes away from the
+default. This will enable us to be sure that when they are restored that
+they are being restored to their former values and not just set to the
+default.
+
+@=* *! Change the special character.
+*p maximum_input_line_length = 75
+
+Before include.
+*i sc15a
+After include.
+
+If the maximum input line length has been correctly restored then the
+second of the following two lines should give an error, but not the first.
+123456789012345678901234567890123456789012345678901234567890123456789012345
+1234567890123456789012345678901234567890123456789012345678901234567890123456
+
+If the special character has been preserved, then the following should
+generate an error.
+
+* - This should generate an error if all is well.
+
+Preservation of the local line number can be checked by looking at the
+listing file.
diff --git a/web/funnelAC/tests/sc15a.fwi b/web/funnelAC/tests/sc15a.fwi
new file mode 100644
index 0000000000..6a1c43c563
--- /dev/null
+++ b/web/funnelAC/tests/sc15a.fwi
@@ -0,0 +1,25 @@
+This is the include file for test SC15. The SC15 test checks to make
+sure that FunnelWeb is saving and restoring three scanning
+attributes across include files. We also want to make sure
+that the scanner is initializing these attributes correctly within
+the include file.
+
+SC15.4: Make sure that the special character is AT at the start of
+include files.
+
+@ - This should yield an error.
+
+SC15.5 Ensure that the maximum input line length is 80 at the start
+of an include file. If all is well, only the second of the following two
+lines will provoke a "line too long" error.
+
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+123456789012345678901234567890123456789012345678901234567890123456789012345678901
+
+Now that we have checked the default attributes on entering an include file,
+we want to stuff them up so as to make sure that the attributes
+prevailing when the include was hit are restored.
+
+@p maximum_input_line_length = 65
+@=+
+
diff --git a/web/funnelAC/tests/sc16.fw b/web/funnelAC/tests/sc16.fw
new file mode 100644
index 0000000000..6f88a89a96
--- /dev/null
+++ b/web/funnelAC/tests/sc16.fw
@@ -0,0 +1,62 @@
+SC16: Test <special>^ sequence.
+
+1. Test that all base characters work (in both cases).
+ These should provoke no errors.
+
+ @^B(00000000) @^b(00000000)
+ @^O(000) @^o(000)
+ @^Q(000) @^q(000)
+ @^D(000) @^d(000)
+ @^H(00) @^h(00)
+ @^X(00) @^x(00)
+
+2. Test that some other base characters generate an error.
+
+ @^u(0)
+ @^y
+ @^#
+ @^(
+
+3. Test that an error is generated if parenthesis is missing.
+
+ @^D34)
+
+4. Test legal digits in each base.
+
+ @^B(00001111)
+ @^O(012) @^O(034) @^O(056) @^O(077)
+ @^D(012) @^D(034) @^D(056) @^D(078) @^D(099)
+ @^H(01) @^H(23) @^H(45) @^H(67)
+ @^H(89) @^H(AB) @^X(CD) @^X(EF) @^x(af)
+
+5. Test illegal digits in each base.
+
+ @^B(00000002)
+ @^O(008)
+ @^D(00A)
+ @^H(0G)
+
+6. Test what happens if there are the wrong number of digits
+ (too few, too many).
+
+ @^B(1)
+ @^O(1)
+ @^D(1)
+ @^H(1)
+
+ @^B(000000001)
+ @^O(0004)
+ @^D(0001)
+ @^H(005)
+
+7. Test that an error is generated for a missing closing parenthesis.
+
+ @^B(00000000
+ @^D(045(
+
+8. Test what happens in number is out of the range [0,255].
+
+ @^D(255)
+ @^D(256)
+ @^D(999)
+
diff --git a/web/funnelAC/tests/sc17.fw b/web/funnelAC/tests/sc17.fw
new file mode 100644
index 0000000000..396bce5f31
--- /dev/null
+++ b/web/funnelAC/tests/sc17.fw
@@ -0,0 +1,24 @@
+SC17: Test <special>#.
+
+First we trip up the scanner so no further passes take place.
+
+@
+
+1. Test with all possible printable characters.
+
+@#! @#" @## @#$ @#% @#& @#' @#( @#) @#* @#+ @#, @#- @#. @#/
+@#0 @#1 @#2 @#3 @#4 @#5 @#6 @#7 @#8 @#9 @#: @#; @#< @#= @#>
+@#? @#@ @#A @#B @#C @#D @#E @#F @#G @#H @#I @#J @#K @#L @#M
+@#N @#O @#P @#Q @#R @#S @#T @#U @#V @#W @#X @#Y @#Z @#[ @#\
+@#] @#^ @#_ @#` @#a @#b @#c @#d @#e @#f @#g @#h @#i @#j @#k
+@#l @#m @#n @#o @#p @#q @#r @#s @#t @#u @#v @#w @#x @#y @#z
+@#{ @#| @#} @#~
+
+2. Test that <special>#<space> is flagged as an error.
+
+ @# @! Should be flagged as an error.
+
+3. Test that <special>#EOL is flagged as an error.
+
+ @#
+
diff --git a/web/funnelAC/tests/sc18.fw b/web/funnelAC/tests/sc18.fw
new file mode 100644
index 0000000000..027972586c
--- /dev/null
+++ b/web/funnelAC/tests/sc18.fw
@@ -0,0 +1,24 @@
+SC18: Test <special>#=
+
+First we trip up the scanner so no further passes take place.
+
+@
+
+1. Test with all possible printable characters.
+
+@=! !=" "=# #=$ $=% %=& &=' '=( (=) )=* *=+ +=, ,=- -=. .=/
+/=0 0=1 1=2 2=3 3=4 4=5 5=6 6=7 7=8 8=9 9=: :=; ;=< <== ==>
+>=? ?=@ @=A A=B B=C C=D D=E E=F F=G G=H H=I I=J J=K K=L L=M
+M=N N=O O=P P=Q Q=R R=S S=T T=U U=V V=W W=X X=Y Y=Z Z=[ [=\
+\=] ]=^ ^=_ _=` `=a a=b b=c c=d d=e e=f f=g g=h h=i i=j j=k
+k=l l=m m=n n=o o=p p=q q=r r=s s=t t=u u=v v=w w=x x=y y=z
+z={ {=| |=} }=~ ~=@
+
+2. Test that <special>=<space> is flagged as an error.
+
+ @= @! Should be flagged as an error.
+
+3. Test that <special>=EOL is flagged as an error.
+
+ @=
+
diff --git a/web/funnelAC/tests/sc19.fw b/web/funnelAC/tests/sc19.fw
new file mode 100644
index 0000000000..49be9e487c
--- /dev/null
+++ b/web/funnelAC/tests/sc19.fw
@@ -0,0 +1,10 @@
+SC19: Test <special>-
+
+1. Test that error is flagged if sequence is not at the end of a line.
+
+This is a line containing @- the end of line suppressor.
+
+2. Test the sequence followed by trailing blanks.
+
+ @-
+
diff --git a/web/funnelAC/tests/sc20.fw b/web/funnelAC/tests/sc20.fw
new file mode 100644
index 0000000000..53d44f262b
--- /dev/null
+++ b/web/funnelAC/tests/sc20.fw
@@ -0,0 +1,11 @@
+SC20: Test @!
+
+1. Test at the start of a line.
+
+@! This is a comment and we can stick any sort of rubbish in it.
+@! @# @i @^ds;af;lsdmf;land other @ rubbish.
+
+2. Test halfway through a line.
+
+This is a line @! whose second half never sees the daylight. @i @<
+
diff --git a/web/funnelAC/tests/sc21.fw b/web/funnelAC/tests/sc21.fw
new file mode 100644
index 0000000000..bf66604166
--- /dev/null
+++ b/web/funnelAC/tests/sc21.fw
@@ -0,0 +1,31 @@
+SC21: Test generic syntax checking of pragmas and typesetter directives.
+
+1. Test pragma not at the start of line.
+ @p
+ @t
+
+2. Test character following <special>p is not a blank.
+@px
+@tx
+@p
+@t
+
+3. Test pragma line is too long (limit is 100)
+ 1 2 3 4 5 6 7 8 9 1
+@p 4567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
+@p 45678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901
+@t 4567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
+@t 45678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901
+
+4. Test various different pragma lines.
+@p $#%@ 2525 sloth
+@t $#%@ 2525 sloth
+
+5. Test pragma with no arguments. (Will get a trailing blanks error.).
+@p
+@t
+
+6. Test pragma with too many arguments.
+@p a b c d e f g h i j k l m n o p q r s t u v w x y z
+@t a b c d e f g h i j k l m n o p q r s t u v w x y z
+
diff --git a/web/funnelAC/tests/sc22.fw b/web/funnelAC/tests/sc22.fw
new file mode 100644
index 0000000000..2ad1cbcb40
--- /dev/null
+++ b/web/funnelAC/tests/sc22.fw
@@ -0,0 +1,23 @@
+SC22: Test syntax checking of input line length pragma.
+
+1. Test not three arguments.
+@p maximum_input_line_length
+@p maximum_input_line_length =
+@p maximum_input_line_length = xxx yyy
+
+2. Test second argument not "=".
+@p maximum_input_line_length x sloth
+
+3. Test value of infinity.
+@p maximum_input_line_length = infinity
+
+4. Test non-decimal digit in number.
+@p maximum_input_line_length = 2ef
+
+5. Test number is more than eight digits long.
+@p maximum_input_line_length = 123456789
+
+6. Test number is exactly eight digits long.
+@p maximum_input_line_length = 12345678
+
+
diff --git a/web/funnelAC/tests/sc23.fw b/web/funnelAC/tests/sc23.fw
new file mode 100644
index 0000000000..7ec5ffcb3a
--- /dev/null
+++ b/web/funnelAC/tests/sc23.fw
@@ -0,0 +1,26 @@
+SC23: Test syntax checking of output line length pragma.
+
+1. Test not three arguments.
+@p maximum_output_line_length
+@p maximum_output_line_length =
+@p maximum_output_line_length = xxx yyy
+
+2. Test second argument not "=".
+@p maximum_output_line_length x sloth
+
+3. Test value of infinity.
+@p maximum_output_line_length = infinity
+
+4. Test non-decimal digit in number.
+@p maximum_output_line_length = 2ef
+
+5. Test number is more than eight digits long.
+@p maximum_output_line_length = 123456789
+
+6. Test number is exactly eight digits long.
+7. Test pragma opposing earlier pragma.
+@p maximum_output_line_length = 12345678
+
+8. Test pragma not opposing earlier pragma.
+@p maximum_output_line_length = infinity
+
diff --git a/web/funnelAC/tests/sc24.fw b/web/funnelAC/tests/sc24.fw
new file mode 100644
index 0000000000..37db6f9200
--- /dev/null
+++ b/web/funnelAC/tests/sc24.fw
@@ -0,0 +1,23 @@
+SC23: Test syntax checking of indentation pragma.
+
+1. Test not three arguments.
+@p indentation
+@p indentation =
+@p indentation = xxx yyy
+
+2. Test second argument not "=".
+@p indentation x sloth
+
+3. Test third argument is not legal.
+@p indentation = sloth
+
+4. Test third argument is none.
+@p indentation = none
+
+5. Test third argument is blank.
+6. Test pragma opposes earlier pragma.
+@p indentation = blank
+
+7. Test pragma does not oppose earlier pragma.
+@p indentation = none
+
diff --git a/web/funnelAC/tests/sc25.fw b/web/funnelAC/tests/sc25.fw
new file mode 100644
index 0000000000..c622789bf3
--- /dev/null
+++ b/web/funnelAC/tests/sc25.fw
@@ -0,0 +1,8 @@
+SC25: Test syntax checking of new page typesetter directive.
+
+1. Make sure that a legal new page directive is OK.
+@t new_page
+
+2. Check that it doesn't stand for any nonsense.
+@t new_page nonsense
+
diff --git a/web/funnelAC/tests/sc26.fw b/web/funnelAC/tests/sc26.fw
new file mode 100644
index 0000000000..bbae8b02ac
--- /dev/null
+++ b/web/funnelAC/tests/sc26.fw
@@ -0,0 +1,8 @@
+SC26: Test syntax checking of table of contents typesetting pragma.
+
+1. Make sure that a legal table of contents directive is OK.
+@t table_of_contents
+
+2. Check that it doesn't stand for any nonsense.
+@t table_of_contents nonsense
+
diff --git a/web/funnelAC/tests/sc27.fw b/web/funnelAC/tests/sc27.fw
new file mode 100644
index 0000000000..6b554e0c76
--- /dev/null
+++ b/web/funnelAC/tests/sc27.fw
@@ -0,0 +1,20 @@
+SC27: Test syntax checking of vskip typesetting directive.
+
+1. Test not exactly three arguments (includes vskip).
+@t vskip
+@t vskip one
+@t vskip one two three four
+
+2. Test third argument not "mm".
+@t vskip 32 xx
+
+3. Test second argument has bad digit.
+@t vskip 3f mm
+
+4. Test number has more than three digits
+
+@t vskip 4355 mm
+
+5. Test a legal one too.
+@t vskip 20 mm
+
diff --git a/web/funnelAC/tests/sc28.fw b/web/funnelAC/tests/sc28.fw
new file mode 100644
index 0000000000..d936bfbe37
--- /dev/null
+++ b/web/funnelAC/tests/sc28.fw
@@ -0,0 +1,34 @@
+SC28: Test syntax checking of title typesetting directive.
+
+1. Test less than four arguments (includes title).
+Note: The title command pulls a hack treating the rest of the line after
+two arguments as the string. So it can't detect an EXCESS of arguments!
+@t title
+@t title two
+@t title two three
+
+2. Test out bad font.
+@t title slothfont left "Sloth"
+
+3. Test out bad alignment.
+@t title titlefont westward "Sloth"
+
+4. Test out funny strings.
+@t title titlefont left "
+@t title titlefont left ""
+@! Note: The following, believe it or not, is actually LEGAL!
+@t title titlefont left "sloth"sloth"
+
+5. Test out all combinations of font and alignment.
+@t title titlefont left "Sloth"
+@t title titlefont centre "Sloth"
+@t title titlefont right "Sloth"
+@t title smalltitlefont left "Sloth"
+@t title smalltitlefont centre "Sloth"
+@t title smalltitlefont right "Sloth"
+@t title normalfont left "Sloth"
+@t title normalfont centre "Sloth"
+@t title normalfont right "Sloth"
+
+6. Test misspelling of centre (Ross's revenge).
+@t title normalfont center "Sloth"
diff --git a/web/funnelAC/tests/sc29.fw b/web/funnelAC/tests/sc29.fw
new file mode 100644
index 0000000000..f62a2af5ad
--- /dev/null
+++ b/web/funnelAC/tests/sc29.fw
@@ -0,0 +1,23 @@
+SC29: Test syntax checking of typesetter pragma.
+
+1. Test not three arguments.
+@p typesetter
+@p typesetter =
+@p typesetter = xxx yyy
+
+2. Test second argument not "=".
+@p typesetter x sloth
+
+3. Test third argument is not legal.
+@p typesetter = sloth
+
+4. Test third argument is none.
+@p typesetter = none
+
+5. Test third argument is tex.
+6. Test pragma opposes earlier pragma.
+@p typesetter = tex
+
+7. Test pragma does not oppose earlier pragma.
+@p typesetter = none
+
diff --git a/web/funnelAC/tests/tg01.fw b/web/funnelAC/tests/tg01.fw
new file mode 100644
index 0000000000..bc9c64707d
--- /dev/null
+++ b/web/funnelAC/tests/tg01.fw
@@ -0,0 +1,8 @@
+TG01: Test basic output file mechanism and filename inheritance.
+
+The file written will be directory:tg01.out
+@O@<.out@>==@{@-
+Patterson's prayer:
+ "There is nothing I would rather be, than chairman of the ABC."
+ - Les Patterson
+@}
diff --git a/web/funnelAC/tests/tg02.fw b/web/funnelAC/tests/tg02.fw
new file mode 100644
index 0000000000..bd02b664d5
--- /dev/null
+++ b/web/funnelAC/tests/tg02.fw
@@ -0,0 +1,71 @@
+TG02: Test expansions with no indentation.
+
+@p indentation = none
+
+@O@<tg02.out@>@{@-
+@<Poem@>
+
+@<Indentation test@>
+@}
+
+@!******************************************************************************
+
+@A@<Poem Section@>
+
+@$@<Poem@>@{@-
+The other day upon the stair,
+@<Middle@>
+I think he's from the CIA.@}
+
+@$@<Middle@>@{@-
+I met a man who wasn't there.
+@<Second line of middle@>@}
+
+@$@<Second line of middle@>@{He wasn't there @<again@> today,@}
+
+@$@<again@>@{again@}
+
+@!******************************************************************************
+
+@A@<Program Section@>
+
+@$@<Indentation test@>@{@-
+In the output begin0 should be at the left margin, then begin1 to begin wayout
+should be indented by three spaces. Then the "It's scary" should be
+positioned over the "a" ofd margin. The rest should be at the left margin.
+
+begin0
+ @<A@>
+end0@}
+
+
+@$@<A@>@{@-
+begin1
+ @<B@>
+end1@}
+
+@$@<B@>@{@-
+begin2
+ @<C@>
+end2@}
+
+@$@<C@>@{@-
+begin3
+ @<D@>
+end3@}
+
+@$@<D@>@{@-
+begin4
+ @<E@>
+end4@}
+
+@$@<E@>@{@-
+begin wayout----------V
+ @<wayout@>
+end wayout----------^@}
+
+@$@<wayout@>@{@-
+It's scary out here
+So far from the left margin.@}
+
+@!******************************************************************************
diff --git a/web/funnelAC/tests/tg03.fw b/web/funnelAC/tests/tg03.fw
new file mode 100644
index 0000000000..6d7ca462d5
--- /dev/null
+++ b/web/funnelAC/tests/tg03.fw
@@ -0,0 +1,69 @@
+TG03: Test expansions with indentation.
+
+@p indentation = blank
+
+@O@<tg03.out@>@{@-
+@<Poem@>
+
+@<Indentation test@>
+@}
+
+@!******************************************************************************
+
+@A@<Poem Section@>
+
+@$@<Poem@>@{@-
+The other day upon the stair,
+@<Middle@>
+I think he's from the CIA.@}
+
+@$@<Middle@>@{@-
+I met a man who wasn't there.
+@<Second line of middle@>@}
+
+@$@<Second line of middle@>@{He wasn't there @<again@> today,@}
+
+@$@<again@>@{again@}
+
+@!******************************************************************************
+
+@A@<Program Section@>
+
+@$@<Indentation test@>@{@-
+The following nest of begin and ends should be indented in a nest.
+
+begin0
+ @<A@>
+end0@}
+
+
+@$@<A@>@{@-
+begin1
+ @<B@>
+end1@}
+
+@$@<B@>@{@-
+begin2
+ @<C@>
+end2@}
+
+@$@<C@>@{@-
+begin3
+ @<D@>
+end3@}
+
+@$@<D@>@{@-
+begin4
+ @<E@>
+end4@}
+
+@$@<E@>@{@-
+begin wayout----------V
+ @<wayout@>
+end wayout----------^@}
+
+@$@<wayout@>@{@-
+It's scary out here
+So far from the left margin.@}
+
+@!******************************************************************************
diff --git a/web/funnelAC/tests/tg04.fw b/web/funnelAC/tests/tg04.fw
new file mode 100644
index 0000000000..9fc4a9defb
--- /dev/null
+++ b/web/funnelAC/tests/tg04.fw
@@ -0,0 +1,30 @@
+TG04: Test macro expansions.
+
+@$@<Teapot@>@{Teapot@}
+@$@<One@>@(@1@)@M@{Left @1 Right@}
+@$@<Two@>@(@2@)@M@{Left @1 Middle @2 Right@}
+@$@<A@>@(@1@)@M@{[@1]@}
+
+@O@<tg04.out@>@{
+
+1. Test macro call with no parameters.
+"Teapot" =
+"@<Teapot@>"
+
+2. Test macro call with one parameter.
+"Left Testing Right" =
+"@<One@>@(@"Testing@"@)"
+
+3. Test macro call with many parameters.
+"Left x Middle y Right" =
+"@<Two@>@(x@,y@)"
+
+4. Test macro call as a parameter of another macro call.
+"Left Ostrich Middle Left Wombat Right Right" =
+"@<Two@>@(Ostrich@,@<One@>@(Wombat@)@)"
+
+5. Test expression recursive macro call.
+"[X[[Walrus]]Y]" =
+"@<A@>@(X@<A@>@(@<A@>@(Walrus@)@)Y@)"
+
+@}
diff --git a/web/funnelAC/tests/tg05.fw b/web/funnelAC/tests/tg05.fw
new file mode 100644
index 0000000000..968019e2d4
--- /dev/null
+++ b/web/funnelAC/tests/tg05.fw
@@ -0,0 +1,10 @@
+TG05: Checking of the output line length.
+
+@$@<Ten@>@M@{1234567890@}
+
+@O@<tg05.out@>@{@-
+We test the default limit of 80 characters.
+Only the second of the following two lines should provoke an error.
+@<Ten@>@<Ten@>@<Ten@>@<Ten@>@<Ten@>@<Ten@>@<Ten@>@<Ten@>
+@<Ten@>@<Ten@>@<Ten@>@<Ten@>@<Ten@>@<Ten@>@<Ten@>@<Ten@>1
+@}
diff --git a/web/funnelAC/tests/tg06.fw b/web/funnelAC/tests/tg06.fw
new file mode 100644
index 0000000000..45e169b977
--- /dev/null
+++ b/web/funnelAC/tests/tg06.fw
@@ -0,0 +1,11 @@
+TG06: Test the setting of the line length limit.
+
+@p maximum_output_line_length = 60
+@O@<tg06.out@>@{@-
+We test the user-set limit of 60 characters.
+Only the third of the following three lines
+should provoke an error.
+ 1 2 3 4 5 6
+123456789012345678901234567890123456789012345678901234567890
+1234567890123456789012345678901234567890123456789012345678901
+@}
diff --git a/web/funnelAC/tests/tg07.fw b/web/funnelAC/tests/tg07.fw
new file mode 100644
index 0000000000..cb8e11eba0
--- /dev/null
+++ b/web/funnelAC/tests/tg07.fw
@@ -0,0 +1,10 @@
+TG07: Checking the setting of the maximum line length to infinity.
+
+@p maximum_output_line_length = infinity
+
+@$@<A@>@M@{1234567890123456789012345678901234567890@}
+
+@O@<tg07.out@>@{@-
+The following long line should not blow the line length limit.
+@<A@>@<A@>@<A@>@<A@>@<A@>@<A@>@<A@>@<A@>@<A@>@<A@>@<A@>@<A@>@<A@>@<A@>
+@}
diff --git a/web/funnelAC/tests/tg08.fw b/web/funnelAC/tests/tg08.fw
new file mode 100644
index 0000000000..b26e2c9406
--- /dev/null
+++ b/web/funnelAC/tests/tg08.fw
@@ -0,0 +1,14 @@
+TG08: Test include files and output generation.
+
+@O@<tg08.out@>@{@-
+@<Macbeth ripoff@>
+
+@<Hamlet ripoff@>
+@}
+
+@$@<Hamlet ripoff@>@{@-
+Now might I drink hot jolt cola
+@i tg08a
+Its contours moulded for my hand?
+Come, let me clutch thee!@}
+
diff --git a/web/funnelAC/tests/tg08a.fwi b/web/funnelAC/tests/tg08a.fwi
new file mode 100644
index 0000000000..36f91ec77c
--- /dev/null
+++ b/web/funnelAC/tests/tg08a.fwi
@@ -0,0 +1,5 @@
+And create hacks in C
+That would not bear witness of the Sun.@}
+
+@$@<Macbeth ripoff@>@{@-
+Is this a mouse I see before me?
diff --git a/web/funnelAC/tests/tg09.fw b/web/funnelAC/tests/tg09.fw
new file mode 100644
index 0000000000..185ed2a38c
--- /dev/null
+++ b/web/funnelAC/tests/tg09.fw
@@ -0,0 +1,37 @@
+TG09: Test some special sequences.
+1. <special>^
+2. <special>-
+3. <special>!
+
+@O@<tg09.out@>@{@-
+@! This line and the next line should not come out in the output file.
+@! This line is a comment line.
+A Megastar's Mantras
+--------------------
+(Things that Mean a Lot to Me)
+
+@^D(065) is for Austr@-
+alia
+The land I adore;
+It's so spot@-
+less and clean
+You can eat off the floor.
+
+@^X(42) is for Boomerang,
+Which our qua@-
+int Abos launch
+In the hope it will bring back
+A roast quok@-
+ka's haunch.
+
+@^B(01000011) is for Culture
+Which blossoms unch@-
+ecked,
+You can't move in my homeland
+for Beckett and Brecht.
+
+...more...
+
+- Dame Edna Everage,
+"Neglected Poems and Other Creatures" by Barry Humphries, 1991.
+@}
diff --git a/web/funnelAC/tests/wv01.fw b/web/funnelAC/tests/wv01.fw
new file mode 100644
index 0000000000..440b934a72
--- /dev/null
+++ b/web/funnelAC/tests/wv01.fw
@@ -0,0 +1,7 @@
+WV01: Test basic typeset file output mechanism.
+
+@A@<A section for no particular reason@>
+
+@O@<wv01.out@>@{@-
+Some text for no particular reason.
+@}
diff --git a/web/funnelAC/tests/wv02.fw b/web/funnelAC/tests/wv02.fw
new file mode 100644
index 0000000000..87efad52f9
--- /dev/null
+++ b/web/funnelAC/tests/wv02.fw
@@ -0,0 +1,43 @@
+WV05: Test typesetting features.
+
+@O@<wv05.out@>@{
+@}
+
+1. Test all five levels of headings with explicit titles.
+
+@A@<One@>
+@B@<Two@>
+@C@<Three@>
+@D@<Four@>
+@E@<Five@>
+
+2. Test all five levels of headings with implicit titles.
+
+@A
+@$@<Macro at level one@>@Z@{Sloth@}
+
+@B
+@$@<Macro at level two@>@Z@{Walrus@}
+
+@C
+@$@<Macro at level three@>@Z@{Aardvark@}
+
+@D
+@$@<Macro at level four@>@Z@{Teapot@}
+
+@E
+@$@<Macro at level five@>@Z@{Emu@}
+
+3. Test the table of contents directive.
+@t table_of_contents
+
+4. Test the newpage directive.
+@t new_page
+
+5. Test the vskip directive.
+@t vskip 50 mm
+
+6. Test the title directive.
+@t title titlefont centre "This is a test Title"
+
+
diff --git a/web/funnelAC/tests/wv03.fw b/web/funnelAC/tests/wv03.fw
new file mode 100644
index 0000000000..8735cf2cd1
--- /dev/null
+++ b/web/funnelAC/tests/wv03.fw
@@ -0,0 +1,64 @@
+WV03: Test the typesetting of various kinds of macros.
+
+First create an output file to keep the analyser happy.
+@O@<wv03.out@>@{@}
+
+1. Test macro never used.
+@$@<Never Used@>@Z@{@}
+
+2. Test a macro used once.
+@$@<Used Once@>@{@}
+
+3. Test a macro used twice.
+@$@<Used Twice@>@M@{@}
+
+4. Test a macro used three times.
+@$@<Used Thrice@>@M@{@}
+
+5. Test a macro used five times.
+@$@<Used Quice@>@M@{@}
+
+Here is the macro that does all the calling for the above.
+@$@<Dummy1@>@Z@{@-
+@<Used Once@>
+@<Used Twice@>
+@<Used Thrice@>
+@<Used Quice@>
+@}
+
+@$@<Dummy2@>@Z@{@-
+@<Used Twice@>
+@<Used Thrice@>
+@<Used Quice@>
+@}
+
+@$@<Dummy3@>@Z@{@-
+@<Used Thrice@>
+@<Used Quice@>
+@}
+
+@$@<Dummy4@>@Z@{@-
+@<Used Quice@>
+@}
+
+@$@<Dummy5@>@Z@{@-
+@<Used Quice@>
+@}
+
+6. Test a macro with two body parts.
+@$@<Two body parts@>@Z+=@{Sloth@}
+@$@<Two body parts@>+=@{Walrus@}
+
+7. Test a macro with three body parts.
+@$@<Three body parts@>@Z+=@{Sloth@}
+@$@<Three body parts@>+=@{Walrus@}
+@$@<Three body parts@>+=@{Aardvaark@}
+
+8. Test a macro with five body parts.
+@$@<Five body parts@>@Z+=@{Sloth@}
+@$@<Five body parts@>+=@{Walrus@}
+@$@<Five body parts@>+=@{@<Three body parts@>@}
+@$@<Five body parts@>+=@{Aardvaark@}
+@$@<Five body parts@>+=@{@<Two body parts@>@}
+
+
diff --git a/web/funnelAC/tests/wv04.fw b/web/funnelAC/tests/wv04.fw
new file mode 100644
index 0000000000..200e0bf39d
--- /dev/null
+++ b/web/funnelAC/tests/wv04.fw
@@ -0,0 +1,20 @@
+WV04: Test ugly string processing.
+
+@! We need this to keep the analyser happy.
+@O@<wv04.out@>@{@}
+
+1. Test ugly string in section name.
+@A@< !"#$%'()*+,-./0123456789:;<=>?@>
+@A@<ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`@>
+@A@<abcdefghijklmnopqrstuvwxyz{|}~@>
+
+2. Test ugly string in macro name.
+@$@< !"#$%'()*+,-./0123456789:;<=>?@>@Z@{@}
+@$@<ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`@>@Z@{@}
+@$@<abcdefghijklmnopqrstuvwxyz{|}~@>@Z@{@}
+
+3. Test ugly string in literal section.
+@{ !"#$%'()*+,-./0123456789:;<=>?@}
+@{ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`@}
+@{abcdefghijklmnopqrstuvwxyz{|}~@}
+
diff --git a/web/funnelAC/tests/wv05.fw b/web/funnelAC/tests/wv05.fw
new file mode 100644
index 0000000000..c236ba044b
--- /dev/null
+++ b/web/funnelAC/tests/wv05.fw
@@ -0,0 +1,83 @@
+WV05: Test processing of ugly strings as ordinary and protected text
+with no typesetter set.
+
+@! We need this to keep the analyser happy.
+@O@<wv05.out@>@{@}
+
+A paragraph in ordinary mode.
+
+33 con!text
+34 con"text
+35 con#text
+36 con$text
+37 con%text
+38 con&text
+39 con'text
+40 con(text
+41 con)text
+42 con*text
+43 con+text
+44 con,text
+45 con-text
+46 con.text
+47 con/text
+48-57 con0123456789text
+58 con:text
+59 con;text
+60 con<text
+61 con=text
+62 con>text
+63 con?text
+64 con@@text
+65-90 conABCDEFGHIJKLMNOPQRSTUVWXYZtext
+91 con[text
+92 con\text
+93 con]text
+94 con^text
+95 con_text
+96 con`text
+97-122 conabcdefghijklmnopqrstuvwxyztext
+123 con{text
+124 con|text
+125 con}text
+126 con~text
+
+Now again, but this time inside protective braces.
+
+@{
+33 con!text
+34 con"text
+35 con#text
+36 con$text
+37 con%text
+38 con&text
+39 con'text
+40 con(text
+41 con)text
+42 con*text
+43 con+text
+44 con,text
+45 con-text
+46 con.text
+47 con/text
+48-57 con0123456789text
+58 con:text
+59 con;text
+60 con<text
+61 con=text
+62 con>text
+63 con?text
+64 con@@text
+65-90 conABCDEFGHIJKLMNOPQRSTUVWXYZtext
+91 con[text
+92 con\text
+93 con]text
+94 con^text
+95 con_text
+96 con`text
+97-122 conabcdefghijklmnopqrstuvwxyztext
+123 con{text
+124 con|text
+125 con}text
+126 con~text
+@}
diff --git a/web/funnelAC/tests/wv06.fw b/web/funnelAC/tests/wv06.fw
new file mode 100644
index 0000000000..99bb7b67bd
--- /dev/null
+++ b/web/funnelAC/tests/wv06.fw
@@ -0,0 +1,85 @@
+WV06: Test processing of ugly strings as ordinary and protected text
+with typesetter = tex.
+
+@p typesetter = tex
+
+@! We need this to keep the analyser happy.
+@O@<wv06.out@>@{@}
+
+A paragraph in ordinary mode.
+
+33 con!text
+34 con"text
+35 con#text
+36 con$text
+37 con%text
+38 con&text
+39 con'text
+40 con(text
+41 con)text
+42 con*text
+43 con+text
+44 con,text
+45 con-text
+46 con.text
+47 con/text
+48-57 con0123456789text
+58 con:text
+59 con;text
+60 con<text
+61 con=text
+62 con>text
+63 con?text
+64 con@@text
+65-90 conABCDEFGHIJKLMNOPQRSTUVWXYZtext
+91 con[text
+92 con\text
+93 con]text
+94 con^text
+95 con_text
+96 con`text
+97-122 conabcdefghijklmnopqrstuvwxyztext
+123 con{text
+124 con|text
+125 con}text
+126 con~text
+
+Now again, but this time inside protective braces.
+
+@{
+33 con!text
+34 con"text
+35 con#text
+36 con$text
+37 con%text
+38 con&text
+39 con'text
+40 con(text
+41 con)text
+42 con*text
+43 con+text
+44 con,text
+45 con-text
+46 con.text
+47 con/text
+48-57 con0123456789text
+58 con:text
+59 con;text
+60 con<text
+61 con=text
+62 con>text
+63 con?text
+64 con@@text
+65-90 conABCDEFGHIJKLMNOPQRSTUVWXYZtext
+91 con[text
+92 con\text
+93 con]text
+94 con^text
+95 con_text
+96 con`text
+97-122 conabcdefghijklmnopqrstuvwxyztext
+123 con{text
+124 con|text
+125 con}text
+126 con~text
+@}
diff --git a/web/funnelAC/userman/u_ch0.tex b/web/funnelAC/userman/u_ch0.tex
new file mode 100644
index 0000000000..ff8b3cca58
--- /dev/null
+++ b/web/funnelAC/userman/u_ch0.tex
@@ -0,0 +1,197 @@
+%==============================================================================%
+% Start of Ch0.tex %
+%==============================================================================%
+%
+% Copyright
+% ---------
+% Copyright (C) 1992 Ross N. Williams.
+% This file contains a chapter of the FunnelWeb User's Manual.
+% See the main TeX file for this manual for further information.
+%
+%==============================================================================%
+
+\vbox{\relax}
+\vfill
+
+\hrule
+
+\medskip
+
+Copyright \copyright{} 1992 Ross~N.~Williams.
+\xn{Ross}{Williams}\xx{copyright}{notice}
+
+Permission is granted to make and distribute verbatim copies of this manual
+provided that the copyright notice and this permission notice are preserved
+on all copies.\note{This paragraph was copied from the GNU Emacs manual to
+avoid my having to get a legal opinion on something I could cook up.}
+
+\medskip
+
+\hrule
+
+\newpage
+
+%==============================================================================
+
+\tableofcontents
+
+\newpage
+
+%==============================================================================
+
+%I am not using LaTeX's figures and tables numbering so these are commented out.
+%\pseudochapter{List of Figures}
+%\pseudochapter{List of Tables}
+
+%==============================================================================
+
+% No forward.
+%\pseudochapter{Foreword}
+%\x{foreword}
+
+%==============================================================================
+
+\pseudochapter{Preface}
+\x{preface}
+
+When, in 1986, I first read Donald Knuth's\xn{Donald}{Knuth}
+technical report on Web\paper{Knuth83},\x{Web} and
+tried Web out, I was simultaneously excited by Knuth's idea of literate
+programming, and disappointed by his implementation of it. I was excited
+because I could sense the potential for
+the literate style to transform the state of mind of the programmer, but was
+disappointed by Web's rigidity
+and lack of practicality, which seemed to betray this potential.
+The Web I used was Pascal-specific, \TeX{}-specific, and applied too
+many constraints to the programming process.
+In particular, it insisted on taking control of the
+program text, mangling the code in the Pascal output files,
+and imposing its own rather rigid ideas about indenting in the \TeX{} output.
+All this, combined with the complexity of the tool, led me
+to come to perceive Web as problem rather than solution.
+
+Despite all this, I was well and truly hooked on the idea of literate
+programming. The inevitable result was that I designed and implemented
+my own version of Web --- FunnelWeb!
+
+FunnelWeb is not the most sophisticated literate programming tool available,
+but it is an extremely \i{practical} tool, striving for simplicity
+and portability in all areas. Not only is FunnelWeb language-independent,
+and to some extent typesetter independent, but its implementation also
+stresses portability, being written in~C, and currently operating on four
+major platforms (Sun, Vax, PC, Mac). FunnelWeb allows the
+programmer total control over the output file, making it suitable
+for use with all sorts of format-sensitive languages. It also allows
+control over its own source code, which has been released under a
+GNU license.\xx{GNU}{license}
+FunnelWeb is quite solid, having to pass
+a regression testing suite of over 200 tests
+before being released. Finally, FunnelWeb is well documented by this manual
+which provides a tutorial, advanced hints, and a language definition.
+
+I would like to dedicate FunnelWeb and this manual to Donald Knuth
+and his literate programming tool Web.
+Although this manual is somewhat critical of some aspects of
+Web, this criticism is really a product of differing design goals.
+Knuth designed a paradigm (literate programming) and a tool
+(Web) aimed at the highest pitch of program presentation and typesetting.
+FunnelWeb aims lower, relaxing constraints, and making compromises
+in order to achieve simplicity, flexibility, and portability.
+The result is a practical tool which I hope will attract more people to
+the literate style.
+
+\bigskip
+
+\leftline{\b{Ross~N.~Williams}}
+\leftline{\b{Adelaide, Australia}}
+\leftline{\b{May~1992}}
+
+%==============================================================================
+
+\pseudochapter{Acknowledgements}
+\x{acknowledgements}
+
+Many thanks to \b{David Hulse}\xn{David}{Hulse}
+(\p{dave@cs.adelaide.edu.au}) for
+translating the original version of FunnelWeb
+(FunnelWeb~V1) from Ada\x{Ada} into~C
+and getting it to work on Unix and a PC.
+The C code written by David (FunnelWeb~V2) formed
+the basis of FunnelWeb~V3, but was
+entirely rewritten during the intensive refinement and feature-injection
+period leading up to this release (FunnelWeb~V3 is about three times
+the size of FunnelWeb~V2).
+Nevertheless, without this important first translation step,
+I would probably not have found the motivation to develop FunnelWeb to its
+present state.
+
+Thanks go to \b{Simon Hackett}\xn{Simon}{Hackett}
+(\p{simon@internode.com.au}) of Internode Systems
+Pty Ltd for the use of his Sun, Mac, and PC, for assistance in porting
+FunnelWeb to the Sun and PC, and for helpful discussions.
+
+Thanks go to \b{Jeremy Begg}\xn{Jeremy}{Begg}
+(\p{jeremy@vsm.com.au}) of VSM Software Services
+for the use of his VAX, and for assistance with the VMS-specific code.
+
+Thanks to \b{Barry Dwyer}\xn{Barry}{Dwyer} (\p{dwyer@cs.adelaide.edu.au})
+and \b{Roger Brissenden}\xn{Roger}{Brissenden} (\p{rjb@koala.harvard.edu})
+for trying out FunnelWeb Version~1 in 1987 and providing valuable feedback.
+
+Thanks to Donald Knuth\xn{Donald}{Knuth}
+for establishing the idea of literate programming in the first place.
+
+\bigskip
+
+\leftline{\b{Ross~N.~Williams}}
+\leftline{\b{Adelaide, Australia}}
+\leftline{\b{May~1992}}
+
+%==============================================================================
+
+\pseudochapter{Presentation Notes}
+\x{presentation notes}
+
+\thing{References:} All references are set in bold and are
+cited in square brackets in the form
+\b{[}$<$\i{firstauthor}$><$\i{year}$>$\b{]}.
+All references cited in the text appear in the reference list and the index.
+
+\thing{Special terms:} New or important terminology has been set in bold
+face and appears in the index. A glossary appears as an appendix.
+
+\thing{Typesetting:} This\x{typesetting}
+document was prepared by the author using Andrew
+Trevorrow's\xn{Andrew}{Trevorrow} (\p{akt150@cscgpo.anu.edu.au})\checked{}
+implementation (OzTeX\x{OzTeX}) of the
+\TeX{}/\LaTeX{}\paper{Knuth84}\paper{Lamport86}\x{TeX}\x{LaTeX}
+typesetting system running on a Macintosh-SE.\x{Macintosh}
+
+\thing{Graphics:} All diagrams have been constructed out of text using
+the \LaTeX{} \p{verbatim} environment so as to allow this document to
+be disseminated electronically and printed using \LaTeX{} without access
+to the author's drawing tools.
+
+%%%%Put this paragraph back again if I insert any \fix footnotes again.
+%\thing{Correction footnotes:} Footnotes\x{footnotes}
+%commencing with dots ($\bullet$) are
+%notes to remind the author about something in the document that must be
+%attended to.\fix{This is an example of such a footnote.} These footnotes
+%will be attended to and eliminated in later versions.
+
+\thing{Known typesetting problems:} While every attempt has been made
+to give a good presentation within the
+time available, some shortcuts have had to be taken. In particular, the author
+has
+been unable to work out how to get \LaTeX{} to suppress blank pages at the
+start of chapters.
+
+%==============================================================================
+
+% No abstract.
+%\pseudochapter{Abstract}
+%\x{abstract}
+
+%==============================================================================%
+% End of Ch0.tex %
+%==============================================================================%
diff --git a/web/funnelAC/userman/u_ch1.tex b/web/funnelAC/userman/u_ch1.tex
new file mode 100644
index 0000000000..947fd2326b
--- /dev/null
+++ b/web/funnelAC/userman/u_ch1.tex
@@ -0,0 +1,1800 @@
+%==============================================================================%
+% Start of Ch1.tex %
+%==============================================================================%
+%
+% Copyright
+% ---------
+% Copyright (C) 1992 Ross N. Williams.
+% This file contains a chapter of the FunnelWeb User's Manual.
+% See the main TeX file for this manual for further information.
+%
+%==============================================================================%
+
+\chapter{A Tutorial Introduction}
+\label{chapintroduction}
+\x{tutorial}
+
+\section{What is Literate Programming?}
+\x{literate programming}
+
+A traditional computer program consists of a text file containing program
+code. Scattered in amongst the program code are comments which describe the
+various parts of the code.
+
+In \newterm{literate programming} the emphasis is reversed. Instead of
+writing code containing documentation, the literate programmer writes
+documentation containing code. No longer does the English commentary
+injected into a program have to be hidden in
+comment delimiters at the top of the
+file, or under procedure headings, or at the end of lines.
+Instead, it is wrenched into the daylight and made the main focus.
+The \dq{program} then becomes primarily a document directed at humans,
+with the code being herded between \dq{code delimiters} from where it
+can be extracted and shuffled out sideways to the language system
+by literate programming tools.
+
+The effect of this simple shift of emphasis can be so
+profound as to change one's whole approach to programming. Under the
+literate programming paradigm, the central activity of programming becomes
+that of conveying meaning to other intelligent beings rather than merely
+convincing the computer to behave in a particular way. It is the difference
+between performing and exposing a magic trick.\x{magic trick}
+
+In order to program in a literate style, particular tools are
+required.\xx{tools}{literate programming}
+The traditional approach (used in the FunnelWeb system) is to have
+some sort of text-file-in/text-file-out utility that reads a
+literate program (containing a program commentary peppered with scraps
+of program text) and writes out a file containing all the program code and
+a file containing typesetter commands representing the entire input document,
+documentation, code, and all (\figarchitecture{}).
+
+\begin{figure}[htbp]
+\begin{verbatim}
+
+ +-----------------------------------------+
+ | File containing the program description |
+ | peppered with scraps of program code. |
+ | This is what the programmer works on. |
+ | (e.g. sloth.web) |
+ +-----------------------------------------+
+ |
+ v
+ o---------------------------o
+ | Literate Programming Tool |
+ o---------------------------o
+ |
+ +-------------------+-------------------+
+ | |
+ v v
+ +------------------+ +----------------------------------+
+ | Traditional | | Documentation file suitable for |
+ | Computer Program | | input into a typesetting program |
+ | (e.g. sloth.c) | | (e.g. sloth.tex) |
+ +------------------+ +----------------------------------+
+
+\end{verbatim}
+\mylabel{\figarchitecture{}: Traditional architecture of literate programming tools.}{%
+%
+Literate programming tools could be organized in a number of ways. However,
+to fit in with current file and command line based environments, most tools
+conform to the traditional architecture shown here in which the user feeds
+in a file containing a literate program, and the literate programming
+utility generates program files and a documentation file.
+%
+}
+\end{figure}
+
+Given the coming age of hypertext\x{hypertext} systems,
+this is probably not the best approach.
+However, it does mesh beautifully with current text
+files and command line interfaces, the expectation of linear presentations in
+the documents we read, and the particular requirements of current programming
+languages and typesetting systems. It is certainly not a bad approach.
+
+With this structure in place, the literate programming system can provide
+far more than just a reversal of the priority of comments and code.
+In its full blown form, a good literate programming facility can provide
+total support for the essential thrust of literate programming, which is that
+computer programs should be written more for the human reader
+than for the compiler. In particular, a literate programming system can
+provide:\xs{literate programming}{facilities}
+
+\narrowthing{Re-ordering of code:}{Programming languages often force the
+programmer to give the various parts of a computer program in a particular
+order.\xx{program}{ordering}
+For example, the Pascal\x{Pascal} programming language\paper{BSI82}
+imposes the ordering:
+constants, types, variables, procedures, code. Pascal also requires that
+procedures appear in an order consistent with the partial ordering
+imposed by the static call graph (but forward
+declarations allow this to be bypassed). In contrast, the literate style
+requires that the programmer be free to present the computer program in
+any order whatsoever. The facility to do this is implemented in literate
+programming tools by providing text \i{macros} that can be defined
+and used in any order.}
+
+\narrowthing{Typeset code and documentation:}{Traditionally program
+listings are
+dull affairs consisting of pages of fan-form paper imprinted with meandering
+coastlines of structured text in a boring font. In contrast, literate
+programming systems are capable of producing documentation that is
+superior in two ways. First, because most of the documentation text is
+fed straight to the typesetter, the programmer can make use of all the
+power of the underlying typesetter, resulting in documentation that has the
+same presentation as an ordinary typeset document. Second, because the
+literate programming utility sees all the code, it can use its knowledge
+of the programming language and the features of the typesetting language
+to typeset the program code as if it were appearing in a
+technical journal. It is the difference
+between:}
+
+\begin{verbatim}
+ while sloth<walrus loop
+ sloth:=sloth+1;
+ end loop
+\end{verbatim}
+
+\narrowtext{and}
+
+\begin{verse}
+\b{while} \i{sloth}$<$\i{walrus} \b{loop}\\
+\qquad\qquad \i{sloth}$\leftarrow$\i{sloth}$+1$;\\
+\b{end} \b{loop}
+\end{verse}
+
+\narrowtext{Unfortunately, while FunnelWeb provides full typesetting
+of the
+documentation, it typesets all of its code in the style of the first of these
+two examples. To typeset in the style of the second requires knowledge of
+the programming language, and the current version of FunnelWeb is
+programming language independent. At a later stage, it is possible that
+FunnelWeb will be modified to read in a file containing information
+about the target programming language to be used to assist in
+typesetting the code properly.}
+
+\narrowthing{Cross referencing:}{Because\x{cross referencing}
+the literate tool sees all the
+code and documentation, it is able to generate extensive cross referencing
+information in the typeset documentation. This makes the printed program
+document more easy to navigate and partially compensates for the lack of
+an automatic searching facility when reading printed documentation.}
+
+In the end, the details don't matter. The most significant
+benefit that literate programming offers
+is \i{its capacity to transform the state of mind of the
+programmer}.\xs{literate programming}{most significant benefit}
+It is now legend that the act of explaining something can transform
+one's understanding of it. This is one of the justifications behind the
+powerful combination of research and teaching in
+universities\paper{Rosovsky90}.\x{universities}
+Similarly, by constantly explaining the unfolding program code in English to an
+imaginary reader, the programmer transforms his perception of the code,
+laying it open, prone, to the critical eye.\xx{explaining}{code}
+
+The result of this exposure is a higher quality of programming.
+When exposed to the harsh light of the literate eye,
+bugs crawl out, special cases vanish, and sloppy code evaporates.
+As a rule literate programs
+take longer to write than ordinary programs, but the total
+development time\xx{development}{time}
+is the same or less because the time taken to write and
+document the program carefully is compensated for by a reduced debugging
+and maintenance time.
+Thus literate programming does not merely assist in the preparation of
+documentation, but also makes significant contributes to the process of
+programming itself. In practice this has turned out to be a contribution
+far more important than the mere capacity to produce typeset documentation.
+
+For more information on literate programming, the reader is directed
+to Knuth's early founding work \paper{Knuth83} and \paper{Knuth84}.
+For more recent information refer to \paper{Smith91},
+which provides a comprehensive bibliography up to 1990.
+
+\section{What is FunnelWeb?}
+\xx{FunnelWeb}{overview}
+
+FunnelWeb is a particular literate programming system that is implemented
+by a single C program. FunnelWeb takes as input a single \p{.fw}
+\newterm{input file}
+and writes one or more \newterm{product files}
+and a \newterm{documentation file} (\figfunarch{}).
+
+\begin{figure}[htbp]
+\begin{verbatim}
+ +-----------+
+ | sloth.fw |
+ +-----------+
+ |
+ v
+ o-------------------o
+ | FUNNELWEB Program |
+ o-------------------o
+ |
+ +-------------------+----------------+
+ | |
+ v v
+ +-----------------------------+ +--------------------------------+
+ | Product File (e.g. sloth.c) | | Documentation File (sloth.tex) |
+ +-----------------------------+ +--------------------------------+
+\end{verbatim}
+\mylabel{\figfunarch{}: Architecture of FunnelWeb.}{%
+%
+FunnelWeb follows the traditional architecture of literate programming
+tools.
+%
+}
+\end{figure}
+
+In literate programming systems, it is usual to refer to the product
+file as a \dq{program file}. However, as FunnelWeb is a general tool that
+can be used to prepare all sorts of text files that are not computer programs,
+the more generic term \dq{product file} was chosen. Product files should
+be carefully distinguished from the term \newterm{output files} which refers
+to all of the output files produced by FunnelWeb.
+
+FunnelWeb is distinguished by the following characteristics:
+
+\narrowthing{Simplicity:}{A\x{simplicity}
+governing design goal of FunnelWeb is to provide
+a \i{simple} tool that could be easily learnt and completely mastered.
+This manual is thick because it is comprehensive and lingers on the
+ways in which FunnelWeb can be used. The tool itself is quite simple.}
+
+\narrowthing{Reliability:}{Another\x{reliability}
+design goal is to provide a tool that will
+protect the user as much as possible from silly errors. Macro preprocessors
+are notorious for causing obscure errors. Every attempt has been made in
+FunnelWeb to keep the syntax robust.
+For example, in FunnelWeb the syntax of
+macro calls has been purposely designed to be highly visible so that the
+reader is always aware when the macro facility is being invoked.}
+
+\narrowthing{Language and Typesetter Independence:}{Unlike
+Knuth's original\xx{language}{independence}\xx{typesetter}{independence}
+Web system which was specific to the Pascal programming language\paper{BSI82}
+and the \TeX{} typesetting language\paper{Knuth84}, FunnelWeb strives to
+be language and typesetter independent. The current version of FunnelWeb
+is completely language independent, but is still somewhat dependent on the
+\TeX{}\x{TeX} typesetter language.}
+
+\narrowthing{Portability:}{FunnelWeb\x{portability} has been written in
+the~C programming language with great emphasis on portability.
+FunnelWeb currently runs on the Sun, VAX, IBM PC, and Mac.}
+
+\narrowthing{Controllable:}{FunnelWeb\x{controllability}
+is an extremely controllable tool.
+To protect users' investment in source files constructed in the FunnelWeb
+macro language, the C source code to FunnelWeb has been released under GNU
+license.\xx{GNU}{license}
+This means that it will always be available to everyone. Furthermore,
+license has been granted for the FunnelWeb User's Manual and FunnelWeb
+Hacker's Manual to be copied freely so long as they are not modified. All
+this means that FunnelWeb is not going to disappear suddenly.}
+
+\narrowthing{A Production Tool:}{Above\x{production tool}
+all, FunnelWeb has been designed to be
+a production tool and every effort has been made to ensure that it will
+operate effectively in a professional environment. FunnelWeb is \dq{open}
+and portable. There is a comprehensive user manual. Its error messages
+are comprehensive. It is fast. Finally, it has been designed with the
+experience of three years of using FunnelWeb~V1.}
+
+For more information on the history and design of FunnelWeb, see
+the \i{FunnelWeb Hacker's Manual}.
+
+\section{The Name FunnelWeb}
+\xx{FunnelWeb}{name}
+
+The name \dq{FunnelWeb} was chosen because it contains the name \dq{WEB},
+which is the name of Knuth's system. It was also chosen because it
+has a distinctly Australian flavour.
+
+Funnel-web spiders\xx{Funnel-web}{spider}
+are found in Northern and Eastern Australia. They are
+about three to four centimetres long and are very poisonous. The
+Sydney\x{Sydney}
+Funnel-web spider (\i{Atrax robustus}\x{Atrax robustus}),
+common in Sydney,
+has caused the most trouble and has been responsible for several deaths.
+Funnel-web spiders love to crawl into temporarily discarded shoes where they
+later react in a hostile manner to an unsuspecting foot. They are known
+to hang on once they sink their fangs in. Funnel-web spiders derive
+their name from the shape of their webs which are horizontally-aligned
+narrowing tubes, open at one end\paper{ANZE}.
+
+The Funnel-web spider, like the tiger snake\xx{tiger}{snake}
+and the white pointer shark,\xx{white pointer}{shark}
+is secretly regarded by Australians as a kind of national
+treasure.\xn{Edna}{Everage}\xn{Barry}{Humphries}
+
+\begin{verse}
+\b{F} is for Funnel-web\\
+Our furry-legged foe.\\
+He sleeps in your slipper\\
+And breakfasts on toe.\\
+--- One verse from \i{A Megastar's Mantras: Things that Mean a Lot to Me},\\
+\qquad{} by Dame Edna Everage\paper{Humphries91}.\\
+\end{verse}
+
+\section{A FunnelWeb Tutorial}
+\x{tutorial}\xx{tutorial}{introduction}
+
+The remainder of this chapter consists of an introductory tutorial on
+FunnelWeb. Ideally you should have a working version of FunnelWeb in front
+of you when reading this chapter so that you can try out the examples
+yourself. There is no need to try all the examples so long as you
+type in enough to feel comfortable with what you are reading. There
+is no harm in reading this chapter offline too, so long as you get to the
+computer within a couple of days to reinforce what you have read.
+
+For best effect, you should create a new, temporary, empty directory in
+which to experiment with FunnelWeb. That way, it will be more obvious
+when FunnelWeb creates an output file. You can either type in the
+examples in this chapter directly, or copy and paste them from the \LaTeX{}
+source file for this chapter or the FunnelWeb
+test suite. The source file for this chapter should be available
+in a file such as \p{/fwdir/userman/ch1.tex}. The test suite should be
+available in a directory such as \p{/fwdir/tests/}. The
+test files called \p{ex01.fw} through \p{ex16.fw} contain the examples in this
+chapter. The test files called \p{hi01.fw} through \p{hi10.fw} contain the
+examples in the next chapter.
+
+If you do not yet have an installed copy of FunnelWeb, refer to
+Chapter~\ref{chapinstall} for full details on how to obtain and install
+a copy of FunnelWeb. If you are not sure if you have an installed copy,
+try invoking FunnelWeb by giving the command \dqp{fw}. If this yields an error
+such as \dq{command not found} then you do not have a properly
+installed version of FunnelWeb.
+
+\section{A Hello World Document}
+\x{hello world document}
+
+Just as one starts the process of learning a new programming language with a
+\dq{Hello World} program, when learning FunnelWeb, you can start with a
+\dq{Hello World} document! And here it is! Edit a text file
+called \p{hello.fw} and put the following text in it. (Note: The second
+character is the letter \dq{Oh}, not the digit \dq{Zero}).
+
+\begin{verbatim}
+@O@<hello.txt@>@{Hello World@+@}
+\end{verbatim}
+
+To \dq{run} this \dq{program}, invoke FunnelWeb using the \dqp{fw}
+command as follows.\x{invoking FunnelWeb}
+
+\begin{verbatim}
+fw hello
+\end{verbatim}
+
+\i{If this command doesn't work, then chances are that
+FunnelWeb has not been installed on your machine. Refer to
+Chapter~\ref{chapinstall} for full details on how to obtain and install
+a copy of FunnelWeb.}
+
+There should be no errors. If there are, have a look
+at the listing file \p{hello.lis}, which should contain an explanation of the
+error, and compare the area in the file where the error occurred with the
+text above. If there are no errors, you will find that the following
+two files have been created.
+
+\begin{verbatim}
+hello.lis - The LISTING file.
+hello.txt - The PRODUCT file.
+\end{verbatim}
+
+Take a look at \p{hello.txt}. It should contain a single line with the
+text \p{Hello World}. Let's take another look at the input file.
+
+\begin{verbatim}
+@O@<hello.txt@>@{Hello World@+@}
+\end{verbatim}
+
+The whole structure of the input file is controlled by \dqp{@},
+called the \newterm{special character}, which
+introduces \newterm{special sequence}s. A scanner's-eye view of the command
+line looks like this:
+
+\begin{verbatim}
+@O @< "hello.txt" @> @{ "Hello World" @+ @}
+\end{verbatim}
+
+The \p{@} character controls everything. In this file we have six different
+special sequences that together
+form a single macro definition. The \p{@<}\x{@<} and \p{@>}\x{@>}
+delimit the name of
+the macro. The \p{@O}\x{@O} signals the start of the macro
+definition and indicates that the macro is to be connected to a product
+file with the same name as the macro (This is is why we got a product file when
+we ran FunnelWeb). The \p{@\{} and \p{@\}}\x{@braces}
+delimit the body of the macro.
+Finally, the \p{@+}\x{@+} instructs that an end of line sequence should be
+inserted at that point in the product file.
+
+If you think this syntax looks messy, then you're right.
+It \i{is}
+messy. FunnelWeb \i{could} have employed a \dq{simpler} notation
+in which more of the \p{@} sequences were eliminated. For example:
+
+
+\begin{verbatim}
+Warning: This example is NOT legal FunnelWeb.
+
+#hello.txt{Hello World+}
+\end{verbatim}
+
+However, if such a syntax were used, the user (you!) would have to remember
+that \p{\#} starts a new macro. You would also have to remember that
+the characters \p{\}} and \p{+} cannot be used in a macro body without a fuss.
+And so on. FunnelWeb is messier, but provides one simple
+rule:\xx{simple}{rule} \i{Nothing special happens
+unless the special character \p{@} appears.}
+
+This means that in FunnelWeb, you can look at large blocks of text in the
+confidence that (unlike for the C
+pre-processor\xx{C}{preprocessor}) there are no macro calls
+hidden in there. If there were, there would be an \p{@}
+character!\footnote{The only
+exception to this rule occurs where the user has explicitly changed the
+special character using the \p{@=}\x{@=} special sequence.}
+
+Let's take another look at the hello world program.
+
+\begin{verbatim}
+@O@<hello.txt@>@{Hello World@+@}
+\end{verbatim}
+
+In its current form, it consists of a single macro definition. This definition,
+while completely valid on its own, only represents half the power of
+FunnelWeb. In fact you could say that it is a \dq{Hello
+Northern Hemisphere Program}.\x{Hello Northern Hemisphere Program}
+To turn it into a proper FunnelWeb \dq{Hello
+World} program, we need to add some documentation!
+
+A FunnelWeb input file consists of a sequence of macro definitions surrounded
+by a sea of documentation which is just ordinary text. Modify your hello
+world document so that it looks like this:
+
+\begin{verbatim}
+This hello world document was created by -insert your name here-.
+
+@O@<hello.txt@>@{Hello World@+@}
+
+It writes out a file called hello.txt containing the string ``Hello World''.
+\end{verbatim}
+
+Now run it through FunnelWeb, but this time, add a \p{+t} to the command line.
+
+\begin{verbatim}
+fw hello +t
+\end{verbatim}
+
+If all goes well, you should find that you now have
+
+\begin{verbatim}
+hello.lis - A LISTING file.
+hello.tex - A DOCUMENTATION file (in TeX format).
+hello.txt - A PRODUCT file.
+\end{verbatim}
+
+Take a look at \p{hello.txt}. You will find that it is identical to the
+\p{hello.txt} of the previous run. Only macro
+definitions affect the product files that FunnelWeb produces (as a result
+of \p{@O} macro definitions). The surrounding documentation has \i{no}
+effect. In contrast, the new file, \p{hello.tex} (have a look at it now)
+which was created as
+a result of your adding the \p{+t} option contains a fairly full
+representation of the input file. Whereas \p{hello.txt} is the
+\i{product file} of FunnelWeb, \p{hello.tex} is the \i{documentation file}.
+Try typesetting the documentation file now using
+the \TeX{} typesetting program. Then print it.
+The following commands are an example of the
+sort of commands you will have to give to do this.
+
+\begin{verbatim}
+tex hello ! Typeset the documentation.
+lpr -Pcslw -d hello.dvi ! Print the typeset documentation.
+\end{verbatim}
+
+The result should be a single page containing the two lines of documentation
+along with a typeset representation of the macro.
+At this point, you have exercised the two main aspects of
+FunnelWeb.\xx{FunnelWeb}{two main aspects}
+Starting
+with an input file containing macros (or in this case macro) and documentation,
+you have successfully generated a product file based on the macros, and
+a documentation file, based on the entire document. Congratulations!
+
+The remainder of this tutorial is divided into two parts, which focus on
+FunnelWeb's macro facilities and its typesetting facilities. By tradition,
+the generation of program files from a literate text is called
+\newterm{Tangling}, and the generation of typeset documentation is
+called \newterm{Weaving}.\footnote{In FunnelWeb, these two functions
+are aspects of a single computer program. However, in Knuth's WEB\x{WEB}
+system,
+the two functions are embodied in two separate computer programs called
+Tangle and Weave, presumably because, as everyone knows, \dq{it takes
+two to Tangle}.}
+
+\section{Macro Facilities}
+\xx{tutorial}{macro facilities}
+
+The hello world program of the previous section exercised both the macro
+expansion (product-file) aspect of FunnelWeb, and the typesetting
+(documentation file) aspect
+of FunnelWeb. This section contains an exposition of the macro facilities,
+and totally ignores the documentation side. This is partly to increase the
+focus of the tutorial, and partly because documentation is usually bulky and
+would take too long for the reader to type in to make the tutorial effective.
+
+\subsection{Simple Macros}
+\xx{tutorial}{simple macros}\xx{tutorial}{macros simple}
+
+The original \dq{Hello World} program consisted of a single macro definition.
+
+\begin{verbatim}
+@O@<hello.txt@>@{Hello World@+@}
+\end{verbatim}
+
+In fact, this is a rather exceptional macro, as it causes its expansion to
+be written to a
+product file. The \p{@O}\x{@O} (for \b{O}utput) signals this.
+In FunnelWeb, most macros are
+defined using \p{@\$}.\x{@dollar}
+This results in a macro that does not generate a product
+file, but which can be called in other macros (including \p{@O} macros).
+Let us expand the hello world program to include some other macros.
+
+\begin{verbatim}
+@O@<hello.txt@>@{@<Greetings@>@+@}
+
+@$@<H@>==@{Hello@}
+@$@<W@>==@{World@}
+
+@$@<Greetings@>==@{@<H@> @<W@>@}
+\end{verbatim}
+
+Type in the file and run it through FunnelWeb using the command:
+
+\begin{verbatim}
+fw hello
+\end{verbatim}
+
+The product file (result.out) should look like this:
+
+\begin{verbatim}
+Hello World
+\end{verbatim}
+
+This short program illustrates some of the features of ordinary macros in
+FunnelWeb. Consider the \p{@O} macro. Instead of containing
+straight text (\dq{Hello World}), it now contains the macro call
+\p{@<Greetings@>}. A FunnelWeb macro can be called from within the body of
+another macro just by giving the macro
+name delimited in \p{@<} and \p{@>}.
+
+At the bottom of the file is the
+definition of the \p{@<Greetings@>}
+macro. The definition is similar to the definition of \p{hello.txt} except
+that it starts with \p{@\$} to indicate that no product file
+is desired from this macro (directly). It also employs the optional
+\p{==} syntax which has no semantic impact, but
+can be used to make definitions clearer.
+The body of the \p{@<Greetings@>} macro consists of
+calls to the \p{H} and \p{W} macros which are defined immediately above.
+
+Note that the macros are not constrained to be
+defined in any particular order. One of the main
+features of literate programming tools is that
+they allow the different parts of the text document being developed (usually
+a computer program) to be layed out in any
+order.\xx{order}{program}\xx{program}{layout} So long as there is a
+definition somewhere in the input file for every macro call, FunnelWeb
+will sort it all out.
+
+In fact, FunnelWeb's macro facility is very simple.\xx{macro}{bindings}
+Unlike many macro preprocessors which allow macros to define other macros,
+FunnelWeb completely
+finishes parsing and analysing the macros in the input file before it
+starts expanding them into product files. Other preprocessors allow
+macros to
+be redefined like variables (as in, say, \TeX{}\x{TeX}) taking on
+many different values as the macro pre-processor travels through the input
+file. In contrast,
+FunnelWeb has no concept of \dq{different times} and
+treats the input as one huge static orderless, timeless,
+collection of definitions.
+In FunnelWeb, there is only ever one time, and so there can only ever be
+one value/definition for each macro.
+
+
+\subsection{Number of Times Called}
+\x{number of times called}\xx{calls}{number}\xx{invocation}{number}
+
+So far we have seen only tiny, degenerate input files. The next example
+moves up to the level of \dq{trivial}, but starts to convey the flavour of
+the way FunnelWeb can be used in practice. Normally, there would be
+documentation text appearing between the macros, but this has been omitted
+so as to keep the focus on the macros themselves. Although the next
+example is
+much longer than the previous example, the only new construct is \p{@-}
+which can appear only at the end of a line,
+and suppresses it,\xx{EOL}{suppression}
+preventing it from appearing in the text. The \p{@-}\x{@-} construct allows
+the text of a macro to be aligned at the left margin, rather than
+having the first line hanging at the end of the
+\p{@\{}. FunnelWeb could have been set up so that this end of
+line marker was suppressed. However, it would have been a special case that
+would have broken the very memorable rule \dq{the text of a macro is the
+text appearing between the \p{@\{} and \p{@\}}}.
+
+Type the following text into the file \p{hello.fw}
+and run it through FunnelWeb. The file contains some intentional errors so
+be sure to type it in exactly and worry only if FunnelWeb \i{doesn't}
+generate some errors.
+
+\begin{verbatim}
+@O@<hello.c@>==@{@-
+@<Include Files@>
+@<Include Files@>
+@<Main Program@>
+@}
+
+@$@<Main Program@>==@{@-
+main()
+{
+ doit();
+}
+@}
+
+@$@<Subroutine@>==@{@-
+void doit()
+{
+ int i;
+ for (i=0;i<10;i++)
+ {
+ @<Print@>
+ @<Print@>
+ }
+}@}
+
+@$@<Print@>==@{@-
+printf("Hello World!");
+printf("\n");@}
+
+@$@<Scan@>==@{scanf@}
+
+@$@<Include Files@>==@{@-
+#include <stdio.h>
+#include <stdlib.h>@}
+\end{verbatim}
+
+What happened? Well, if you haven't typed the file in properly, you may
+get some miscellaneous syntax errors. Fix these before continuing.
+If the file has been correctly typed, you should be faced with some error
+messages to do with the number of times some of the macros are called.
+
+By default, FunnelWeb insists that each macro defined is invoked
+exactly once. However, the file above defines macros that are used
+more than once and a macro that is not used at all. Let us examine the
+errors.
+
+First, we see that FunnelWeb has alerted us to the fact that
+the \p{Include Files} macro has been called twice. Once alerted to this,
+a quick look at the program convinces us that calling the macro twice is
+a mistake, and that one of the calls should be eliminated.
+
+Second, we note that FunnelWeb has alerted us to the fact that the
+\p{@<subroutine@>}
+macro is never called. Again, a quick look at the program tells us that this
+is a mistake (and a very common one in the use of FunnelWeb), and that
+a call to the \p{@<subroutine@>} macro should be inserted just above
+the call to the \p{@<Main Program@>} macro
+in the definition of \p{@<hello.c@>}.
+
+These two cases demonstrate why these checks have been placed in
+FunnelWeb. It is nearly always acceptable for a macro to be called once.
+However, if a macro is not called at all, or called more than once,
+this is often a sign
+that the user has made a mistake.
+
+These checks have a dark side too. In addition to the
+errors mentioned above, FunnelWeb has generated two similar
+errors that do not help us.
+
+First, we are alerted to the fact that the
+\p{@<print@>} macro has been called twice. Clearly, in this case, this is not
+a problem, and so here FunnelWeb's fussiness is a nuisance.
+
+Second, we are alerted to the fact that the \p{@<scan@>} macro has never
+been called. Like the \p{@<print@>} macro,
+this macro was defined as a notational
+convenience, and clearly it does not matter here if it is not used. Again,
+FunnelWeb is being a nuisance.
+
+The four cases above demonstrate the light and dark side of
+FunnelWeb's insistence that each macro be called exactly once. To resolve
+the conflict without reducing the strength of the checking, FunnelWeb
+provides two special sequences \p{@Z} (for \b{Z}ero) and \p{@M} (for \b{M}any)
+that can be attached to macro definitions. Presence of the
+\p{@Z}\xx{@Z}{tutorial}
+tag allows the designated macro to be called zero times.
+Presence of the
+\p{@M}\xx{@M}{tutorial}
+tag allows the designated macro to be called more than once.
+A single macro may carry both tags.
+It is always true that all macros are allowed to be called exactly once.
+
+Here is the revised program with the errors fixed,
+by eliminating or adding macro calls, or by adding tags.
+Try processing the file now. There should be no errors.
+
+\begin{verbatim}
+@O@<hello.c@>==@{@-
+@<Include Files@>
+@<Function@>
+@<Main Program@>
+@}
+
+@$@<Main Program@>==@{@-
+main()
+{
+ doit();
+}
+@}
+
+@$@<Function@>==@{@-
+void doit()
+{
+ int i;
+ for (i=0;i<10;i++)
+ {
+ @<Print@>
+ @<Print@>
+ }
+}@}
+
+@$@<Print@>@M==@{@-
+printf("Hello World!");
+printf("\n");@}
+
+@$@<Scan@>@Z==@{scanf@}
+
+@$@<Include Files@>==@{@-
+#include <stdio.h>
+#include <stdlib.h>@}
+\end{verbatim}
+
+\subsection{Indentation}
+\xx{indentation}{macro calls}
+
+The body of the \p{print} macro of the previous example
+contains two lines of text.
+A literal substitution of this macro's body in its context would result in:
+
+\begin{verbatim}
+ {
+ printf("Hello World!");
+printf("\n");
+ printf("Hello World!");
+printf("\n");
+ }
+\end{verbatim}
+
+But instead, it comes out as (have a look at this part of \p{hello.c} now):
+
+\begin{verbatim}
+ {
+ printf("Hello World!");
+ printf("\n");
+ printf("Hello World!");
+ printf("\n");
+ }
+\end{verbatim}
+
+The explanation is that FunnelWeb indents each line of multiline macros
+by the level of indentation at the point of call.
+This means that, as in the case above, program texts, which are usually
+highly indented, come out looking \dq{right}.
+
+In other circumstances, where the model of the text is one dimensional,
+FunnelWeb's indentation could become an impediment or even a danger.
+In these cases, it
+can be switched off by including the FunnelWeb \newterm{pragma} line
+
+\begin{verbatim}
+@p indentation = none
+\end{verbatim}
+
+anywhere in the input file.
+
+One of the design goals of FunnelWeb is to allow the user total control over
+the product files. This contrasts with the approach of Knuth's WEB\x{WEB}
+system
+\paper{Knuth83} (upon which FunnelWeb is based), which mangles the input
+text at the Pascal\x{Pascal} program syntax level, truncating identifiers,
+converting
+the text to upper case, and paragraphing text. Here is an example of part of
+a Pascal program produced by WEB\xx{output}{WEB}
+(from page~14 of \paper{Knuth83}):
+
+\begin{verbatim}
+IF R=0 THEN XREF[P]:=XREFPTR ELSE XMEM[R].XLINKFIELD:=XREFPTR;END;{:51}
+{58:}FUNCTION IDLOOKUP(T:EIGHTBITS):NAMEPOINTER;LABEL 31;
+VAR I:0..LONGBUFSIZE;H:0..HASHSIZE;K:0..MAXBYTES;W:0..1;
+L:0..LONGBUFSIZE;P:NAMEPOINTER;BEGIN L:=IDLOC-IDFIRST;{59:}
+H:=BUFFER[IDFIRST];I=IDFIRST+1;
+WHILE I<IDLOC DO BEGIN H:=(H+H+BUFFER[I])MOD HASHSIZE;I=I+1;END{:59};
+\end{verbatim}\checked{I can't believe I actually typed this mess in.}
+
+Knuth's theory is that the program generated by a literate programming
+system should be
+treated as object code and hence should look like object code
+too.\x{object code} While this
+may be an admirable approach in the long run, the present programming
+environment is one of faulty compilers and buggy tools.
+The FunnelWeb view is that, in this environment,
+the programmer needs all the help he can get
+and that therefore he should be allowed total control over
+the product file. Another reason for FunnelWeb's providing total
+control over the product file, is that FunnelWeb is intended to be
+target language independent, and so even if Knuth's view were adopted, it
+would not be clear what a legitimate transformation of the text could be.
+
+\subsection{Additive Macros}
+\xx{additive}{macros}
+
+Sometimes it is convenient to build up the definition of a macro in
+stages throughout the input file. In FunnelWeb, this can be done using
+an \newterm{additive macro}.
+An additive macro is identical to an ordinary macro except
+that\xx{tutorial}{==}\xx{tutorial}{+=}
+
+\begin{enumerate}
+\item It has \p{+=} instead of \p{==}.
+\item It can be defined in one or more parts throughout the input file.
+The definition of the macro is the concatenation of all the parts in the
+order in which they appear.
+\end{enumerate}
+
+The following example shows how additive macros
+can be used to scatter and regroup information, in this
+case assisting in the lucid construction of a
+data abstraction\xx{data}{abstraction} in a language (Pascal\x{Pascal})
+that does not support them explicitly.
+
+\begin{verbatim}
+@!******************************
+
+@O@<prog.pas@>==@{@-
+program adt(input,output);
+@<Types@>
+@<Variables@>
+@<Procedures@>
+begin startproc; end.
+@}
+
+@!******************************
+
+@$@<Types@>+=@{@-
+type buffer_type =
+ record
+ length : integer;
+ buf : array[1..100] of char;
+ end;
+@}
+
+@$@<Variables@>+=@{@-
+bigbuf : buffer_type;
+@}
+
+@$@<Procedures@>+=@{@-
+procedure buf_init (var b : buffer_type ) {Body of buf_init}
+procedure buf_add (var b : buffer_type; ch : char) {Body of buf_add}
+procedure buf_get (var b : buffer_type; var ch : char) {Body of buf_get}
+@}
+
+@!******************************
+
+@$@<Types@>+=@{@-
+type complex_type = record r,i : real; end;
+@}
+
+@$@<Procedures@>+=@{@-
+procedure cm_set (var c: complex_type; a,b: real) {Body of cm_set}
+procedure cm_add (a,b: complex_type; var c: complex_type) {Body of cm_add}
+{Other procedures and functions}
+@}
+
+@!******************************
+
+{...more pieces of program...}
+
+@!******************************
+\end{verbatim}
+
+It is important to remember that the definition of each macro does not change
+throughout the input file. FunnelWeb parses the entire input file and
+assembles all the macro definitions before it even starts to expand macros.
+As a result, each additive macro can only have one definition, and that
+definition is the concatenation of all its parts.
+
+The example above shows how additive macros can be used to rearrange the
+presentation of a computer program in the order in which the user wishes
+to discuss it rather than the order in which the compiler requires that it
+be consumed. It is easy, however, to abuse the feature of additive macros.
+In many cases, the same effect can be obtained more clearly by replacing
+each part of an additive macro in-situ using uniquely named non-additive
+macros, and then collect them together as a group at the point where the
+additive macro is called. Doing this is more work, and is more error
+prone, but can result in a clearer exposition.
+The following program illustrates this alternative approach.
+
+\begin{verbatim}
+@!******************************
+
+@O@<prog.pas@>==@{@-
+program adt(input,output);
+@<Types@>
+@<Variables@>
+@<Procedures@>
+begin startproc; end.
+@}
+
+@$@<Types@>==@{@-
+@<Buffer type@>
+@<Complex type@>
+@}
+
+@$@<Variables@>==@{@-
+@<Buffer variable@>
+@}
+
+@$@<Procedures@>==@{@-
+@<Buffer procedures@>
+@<Complex procedures@>
+@}
+
+@!******************************
+
+@$@<Buffer type@>==@{@-
+type buffer_type = record
+ length : integer;
+ buf : array[1..100] of char;
+ end;
+@}
+
+@$@<Buffer variable@>==@{@-
+bigbuf : buffer_type;
+@}
+
+@$@<Buffer procedures@>==@{@-
+procedure buf_init(var b : buffer_type) {Body of buf_init}
+procedure buf_add(var b : buffer_type; ch : char) {Body of buf_add}
+procedure buf_get(var b : buffer_type; var ch : char) {Body of buf_get}
+@}
+
+@!******************************
+
+@$@<Complex type@>==@{@-
+type complex_type = record r,i : real; end;
+@}
+
+@$@<Complex procedures@>+=@{@-
+procedure cm_set(var c: complex_type; a,b : real) {Body of cm_set}
+procedure cm_add(a,b : complex_type; var c: complex_type) {Body of cm_add}
+{Other procedures and functions}
+@}
+
+@!******************************
+
+{...more pieces of program...}
+
+@!******************************
+\end{verbatim}
+
+One of advantages of FunnelWeb (and literate programming in general) is that
+(as shown above) it allows the user to lay out the program in whatever order is
+desired\xx{program}{layout}
+with near total independence from the ordering requirements of the
+target programming language.
+
+Additive macros are allowed to be tagged with \p{@Z} and \p{@M} just as other
+macros can, but the tags must appear only on the first definition of the
+macro. Additive macros cannot be connected directly to product files.
+
+\subsection{Parameterized Macros}
+\xx{parameterized}{macros}
+
+No self-respecting macro preprocessor would be complete without some form
+of macro parameterization, and FunnelWeb is no exception. FunnelWeb allows
+each macro to have from zero to nine formal parameters\xx{formal}{parameters}
+named \p{@1}\x{@1...}, \p{@2},
+\p{@3}, \p{@4}, \p{@5}, \p{@6}, \p{@7}, \p{@8}, and \p{@9}.
+
+To define a macro with one or more parameters, insert a formal parameter
+list\xx{formal}{parameters}
+just after the macro name in the macro definition. Because macro
+parameters have fixed names (\p{@1}$\ldots$\p{@9}), there is no need to
+specify the names of formal parameters in the formal parameter list.
+All that need be conveyed is how many parameters the macro has.
+Here is an example of the definition of a macro having three parameters:
+
+\begin{verbatim}
+@$@<While loop@>@(@3@)@M==@{@-
+@1
+while (@2)
+ {
+ @3
+ }
+@}
+\end{verbatim}
+
+To call a parameterized macro, an actual
+parameter\xx{actual}{parameters} list must be supplied
+that contains exactly the same number of actual parameters as there are
+formal parameters in the definition of the macro being called. An actual
+parameter list is delimited by \p{@(}\x{@(}
+and \p{@)},\x{@)} and parameters are
+\i{separated} by \dqp{@,}.\x{@,} The actual parameters themselves are general
+FunnelWeb expressions (see Chapter~\ref{chapdefinition}
+for the exact syntax) and can
+be inserted into the list directly or can be delimited by \p{@"}\x{@"} so as to
+allow some white space to assist in formatting the actual parameters.
+Here are some examples of calls of the \p{While loop} macro defined above.
+
+\begin{verbatim}
+@! First form of actual parameters without whitespace and double quotes.
+@<While loop@>@(x=1;@,x<=10@,printf("X=%u\n",x);@)
+
+@! Second form of actual parameters. The double quotes allow non-active
+@! whitespace that helps to lay out the actual parameters neatly.
+@! This call is functionally identical to the one above.
+@<While loop@>@(
+ @"x:=1;@" @,
+ @"x<=10@" @,
+ @"printf("X=%u\n",x);@" @)
+
+@! The two forms can be mixed in a single call.
+@<While loop@>@(x=1;@,x<=10@,
+ @"printf("X=%u\n",x);@" @)
+\end{verbatim}
+
+A few rules about parameterized macros are worth mentioning.
+Macros that do not have any parameters must have no formal or
+actual parameter lists.\xs{parameter list}{absent}
+Additive macros can have parameters, but the formal parameter list
+must appear in the first definition part only.
+
+Here is another example of the use of parameterized macros. This time,
+parameters and macro calls are used in a FunnelWeb input file
+that constructs an $O(n)$ representation
+of a song\x{song}\x{twelve bugs of christmas} whose full size is
+$O(n^2)$ in the number $n$ of unique
+lines.\x{rec.humor.funny}\xn{Pat}{Scannel}
+
+\begin{verbatim}
+
+@O@<Twelve_bugs.txt@>==@{@-
+The Twelve Bugs of Christmas
+----------------------------
+@<Verse@>@(@"first@" @,@<1@>@)
+@<Verse@>@(@"second@" @,@<2@>@)
+@<Verse@>@(@"third@" @,@<3@>@)
+@<Verse@>@(@"fourth@" @,@<4@>@)
+@<Verse@>@(@"fifth@" @,@<5@>@)
+@<Verse@>@(@"sixth@" @,@<6@>@)
+@<Verse@>@(@"seventh@" @,@<7@>@)
+@<Verse@>@(@"eighth@" @,@<8@>@)
+@<Verse@>@(@"ninth@" @,@<9@>@)
+@<Verse@>@(@"tenth@" @,@<A@>@)
+@<Verse@>@(@"eleventh@" @,@<B@>@)
+@<Verse@>@(@"twelfth@" @,@<C@>@)
+
+This song appeared in the internet newsgroup rec.humor.funny on 24-Dec-1991.
+It was contributed by Pat Scannell (scannell@@darkstar.ma30.bull.com).
+@}
+
+@$@<Verse@>@(@2@)@M==@{@-
+For the @1 bug of Christmas, my manager said to me
+ @2
+@}
+
+@$@<1@>@M==@{See if they can do it again.@}
+@$@<2@>@M==@{Ask them how they did it and@+@<1@>@}
+@$@<3@>@M==@{Try to reproduce it@+@<2@>@}
+@$@<4@>@M==@{Run with the debugger@+@<3@>@}
+@$@<5@>@M==@{Ask for a dump@+@<4@>@}
+@$@<6@>@M==@{Reinstall the software@+@<5@>@}
+@$@<7@>@M==@{Say they need an upgrade@+@<6@>@}
+@$@<8@>@M==@{Find a way around it@+@<7@>@}
+@$@<9@>@M==@{Blame it on the hardware@+@<8@>@}
+@$@<A@>@M==@{Change the documentation@+@<9@>@}
+@$@<B@>@M==@{Say it's not supported@+@<A@>@}
+@$@<C@>@M==@{Tell them it's a feature@+@<B@>@}
+\end{verbatim}
+
+\subsection{Macro Expansion}
+\xx{macro}{expansion}
+
+One of the strengths of FunnelWeb is that, when writing product files, it
+does not attempt to evaluate any text expression (\eg{}text block, parameter,
+macro call) in memory\xx{memory}{use of}
+and then write the result out. Instead, it always
+writes out what it is expanding dynamically and directly. This means that
+the user need not fear defining macros that expand to huge amounts of text
+and then calling those macros in other macros, or passing those huge macros
+as parameters to other macros. In all cases, FunnelWeb expands directly to
+the product file, and there can be no danger in running out of memory during
+expansion (except for running out of stack space and other
+marginally used resources in pathological cases).
+
+The only thing to remember in this regard is that FunnelWeb always stores
+the entire \i{input} file and all included files, in their entirety in
+memory, for the duration of the run.
+
+Here is an example, that illustrates how robust FunnelWeb is:
+
+\begin{verbatim}
+@! FunnelWeb copes well with the following macro definitions.
+@! (Providing that it has a little over ten megabytes of memory).
+
+@O@<woppa.txt@>==@{@<Quote@>@(@<Humungeous@>@)@+@}
+
+@$@<Quote@>@(@1@)==@{"@1"@}
+
+@$@<Humungeous@>==@{@-
+...Ten Megabytes of Text...
+@}
+\end{verbatim}
+
+\subsection{Include Files}
+\xx{include}{files}
+
+FunnelWeb provides a nested include file facility that can be used for a
+number of purposes. When FunnelWeb runs into a single line containing the
+special sequence \p{@i}\x{@i} followed by a blank, followed by a file name,
+it reads in the designated
+file and replaces the line containing the command (including the end of
+line marker at the end of the line) with the entire contents
+of the designated file. For example, if there was a file called
+\p{camera.txt} containing the two lines:\xx{poem}{camera}\xx{animal}{poem}
+
+\begin{verbatim}
+'Cos I shoot with a camera instead of a gun.
+The animals flock to be petted and fed,
+\end{verbatim}
+
+and another file called \p{poem.fw}
+containing the following four lines\x{shooting}
+
+\begin{verbatim}
+I like to go shooting, it's a whole lot of fun,
+@i camera.txt
+Cos they know my camera isn't loaded with lead.
+- RNW, 04-Jan-1991.
+\end{verbatim}
+
+Then, if FunnelWeb were to process \p{poem.fw}, the result would be
+as if FunnelWeb had read in:
+
+\begin{verbatim}
+I like to go shooting, it's a whole lot of fun,
+'Cos I shoot with a camera instead of a gun.
+The animals flock to be petted and fed,
+'Cos they know my camera isn't loaded with lead.
+- RNW, 04-Jan-1991.
+\end{verbatim}
+
+FunnelWeb expands include files before it starts scanning and parsing the
+included text. The result is that include files can contain anything that
+can be found in a FunnelWeb file. The following example illustrates
+the level at which the include mechanism operates. If \p{main.fw} contains
+
+\begin{verbatim}
+@O@<output.dat@>==@{@-
+@i inc.fw
+This is the text of the sloth macro.
+@}
+\end{verbatim}
+
+and inc.fw contains
+
+\begin{verbatim}
+@<Sloth@>
+@}
+
+@$@<Sloth@>==@{@-
+\end{verbatim}
+
+Then if FunnelWeb were applied to \p{main.fw}, it would see:
+
+\begin{verbatim}
+@O@<output.dat@>==@{@-
+@<Sloth@>
+@}
+
+@$@<Sloth@>==@{@-
+This is the text of the sloth macro.
+@}
+\end{verbatim}
+
+which it would process in the normal manner. The only special
+sequence processing that takes place at a level lower
+than include files is the processing of the \p{<special>=<newspecial>}
+sequence which changes the special character.\xx{special character}{changing}
+
+A few other facts about include files are worth mentioning here. Include
+files inherit the directory specification supplied using the \p{+I} command
+line option. The special character is saved at the start of each include
+file and restored to its previous value at the end of each include file.
+Include files can be nested up to ten levels.
+Recursive included files\xx{include files}{recursive}
+will always cause an infinite recursion as there
+is no bottoming out mechanism available.
+Include files
+must contain an integer number of lines (\ie{}the last line must be
+terminated with an end of line marker). Once FunnelWeb has seen
+\dqp{@i\ } at the start of a line, it will grab the rest of the
+line raw and treat it as a file name. There is no place on the
+line for things like FunnelWeb comments (see later) or extraneous text.
+
+Include files can be used for many purposes, but are particularly useful for
+hauling in macro libraries.\xx{macro}{libraries}
+
+\section{Typesetting Facilities}
+\xx{tutorial}{typesetting}
+
+The first half of this tutorial focuses solely on the macro facilities
+of FunnelWeb (which it more or less covers completely). As a result,
+the example documents you have seen so far have been gross
+distortions of \dq{normal} FunnelWeb documents which often contain as much
+documentation as
+code.\x{documentation vs code}\x{code vs documentation}\footnote{As
+an example, the author used
+FunnelWeb to develop a largish computer program and found that on average
+his style of using FunnelWeb resulted in about 30\% documentation and
+70\% macros (code) (measured by numbers of lines).}
+While there are applications where FunnelWeb can be used solely
+as a macro preprocessor, most applications will use its
+typesetting facilities as well.
+
+This section restores the balance in this tutorial
+by presenting FunnelWeb's typesetting facilities.
+
+\subsection{Overview}
+\xx{overview}{typesetting}
+
+The macro definitions discussed in the macro tutorial completely define
+the contents of the product files that FunnelWeb will generate. These macro
+definitions can be arranged in any order and nothing external to them
+can affect the contents of the product files. The macros
+can be thought of as a group of self-contained islands.
+
+Although FunnelWeb will can process the macros all on their own,
+the full power of FunnelWeb
+is realized only when the macros are surrounded by a sea of documentation.
+This sea can take two forms: directives and free text.
+Some of the directives control things such as the maximum input line
+length. However, most of them are typesetting directives that affect
+the printed documentation.
+Thus a FunnelWeb document can be viewed as a sequence
+of \newterm{macro definitions},
+\newterm{directives}, and \newterm{free text}.
+
+Unlike the product files which consist of unscrambled macro calls,
+the documentation file is more or less a
+direct representation of the input file. Each part of the input file
+appears in the documentation file in the order in which it appears in the
+input file. However, each different kind of part is
+typeset\footnote{Here the term \dq{typeset} is used loosely to refer to
+FunnelWeb's generation of typesetter commands for each construct in the
+input file. Strictly, the term should be used only to describe the actions
+of a typesetter program (\eg{}\TeX{}).} in a different
+manner. Macros are typeset in a particular style, with the macro body
+appearing in \p{tt font} (see some FunnelWeb printed documentation for
+an example). Typesetter directives have specific defined
+effects (more later).
+Free text is typeset exactly as it is, except that each block of text
+between blank lines is filled and justified as a paragraph.
+
+The following example demonstrates how all this works. Type in the following
+as \p{example.fw} and run it through FunnelWeb with the
+command \dqp{fw~example~+t}. The \dqp{+t} instructs FunnelWeb to generate
+a documentation file called \p{example.tex}.
+Run the file through \TeX{} and print it.
+Examine the files \p{example.out} and \p{example.tex}.
+
+\begin{verbatim}
+You are reading some free text before the macro. Free text can consist
+of any text (not containing the FunnelWeb special character) including
+typesetter commands
+such as $, %, #, and \TeX{} which
+will be typeset to appear exactly as they do in the input file!
+Look out! Here comes a macro!
+
+@O@<example.out@>==@{@-
+This text is part of
+a macro definition.
+@}
+
+This is free text following the macro. This sentence contains
+two @{inline@} typesetter @/directives@/.
+Now here is a non-inline typesetting directive.
+
+@t new_page
+
+This sentence will appear on the next page.
+\end{verbatim}
+
+At the top of the \p{example.tex} documentation file will be a set of \TeX{}
+macro definitions. The \TeX{} code corresponding to the input above
+appears at the end of the file. It should look something like this.
+
+\begin{verbatim}
+You are reading some free text before the macro. Free text can consist
+of any text (not containing the FunnelWeb special character) including
+typesetter commands
+such as \$, \%, \#, and $\backslash$TeX$\{$$\}$ which
+will be typeset to appear exactly as they do in the input file!
+Look out! Here comes a macro!
+
+\fwbeginmacro
+\fwfilename{example.out}{1}\fwequals \fwodef \fwbtx[This text is part of
+a macro definition.
+]fwetx=%
+\fwcdef
+\fwbeginmacronotes
+\fwisafile{This macro is attached to an output file.}
+\fwendmacronotes
+\fwendmacro
+
+This is free text following the macro. This sentence contains
+two \fwlit{inline} typesetter \fwemp{directives}.
+Now here is a non-inline typesetting directive.
+
+\fwnewpage
+
+This sentence will appear on the next page.
+\end{verbatim}
+
+The following points explain the \p{example.tex} file.
+
+\narrowthing{You don't have to know TeX:}{If you don't know
+\TeX{}, don't pay too much
+attention to this section. You don't need to know \TeX{} to use FunnelWeb.}
+
+\narrowthing{In order:}{FunnelWeb has merely transformed the
+input. It hasn't rearranged it.}
+
+\narrowthing{Free text:}{Most of the free text has been simply copied over.
+The \TeX{} typesetter justifies and fills all paragraphs fed to it by
+default, so most of the text has just been copied verbatim.}
+
+\narrowthing{TeX codes:}{The characters and sequences which
+\TeX{} treats as special have been neutralized in the documentation
+file. For example, \dqp{\$} has become \dqp{\bs\$}. By
+default, FunnelWeb allows the user to write any text as free text and not
+have to worry about accidentally invoking typesetter features.}
+
+\narrowthing{fw sequences:}{The \p{fw} sequences (\eg{}\p{\bs{}fwbeginmacro})
+invoke \TeX{} macros defined
+earlier in the documentation file (and not shown here).}
+
+\narrowthing{The macro:}{The macro is typeset using a set of predefined
+\TeX{} macros. See the printed documentation to see what this looks like
+on paper.}
+
+\narrowthing{Typesetter directives:}{Unlike the \TeX{}
+command sequences (which
+were neutralized), the FunnelWeb typesetter directives turn into \TeX{} macro
+calls. For example, \dqp{@\{inline@\}} became \dqp{\bs{}fwlit\{inline\}}.}
+
+In summary, FunnelWeb produces typeset documentation that transforms,
+but does not reorder, the input file. Macros are typeset in a specific
+style. FunnelWeb typesetter directives have particular well-defined effects.
+Free text is filled and justified, but will otherwise appear in the
+printed documentation exactly as it appears in the input file.
+
+\subsection{Typesetter Independence}
+\xx{typesetter}{independence}
+
+Although the current version of FunnelWeb can only generate documentation
+files in \TeX{} form,
+it encourages typesetter independence
+by neutralizing all \TeX{} control sequences before writing them out. The
+result is that you don't have worry about upsetting or depending on \TeX{}
+by accidentally including some special character or sequence. By default your
+input file is \newterm{typesetter independent}.
+
+This scheme differs from other literate programming tools, including
+all earlier versions of FunnelWeb, which copy their free text directly
+to the documentation file, the justification being that the programmer
+can use the full power of the typesetter language to describe the program.
+The disadvantages of doing this are first that the
+programmer is required to know the typesetting language and second that
+the input file becomes typesetter dependent. FunnelWeb avoids these problems
+by knobbling the free text be default.
+
+However, FunnelWeb does provide a trapdoor for those who want their
+free text to be fed directly to \TeX{}. To open the trapdoor,
+simply include the following pragma somewhere in your input file.
+
+\begin{verbatim}
+@p typesetter = tex
+\end{verbatim}
+
+See Section~\ref{typesetterpragma} for more information.
+
+FunnelWeb leaves the degree to which
+the user wishes to bind a particular document to a particular typesetter
+up to the user. In some cases, the extra typesetting power may compensate
+for the lack of portability. However, as a rule, it is best to
+avoid typesetter-specific commands, so as to allow your input files to
+be formatted at a later date for different typesetters.
+FunnelWeb includes a number of its own typesetter commands so as to
+support typesetter-independent input files.
+The following sections describe some of these commands. In particular,
+the next section describes the most powerful FunnelWeb typesetting directives
+which allow the user to structure the document hierarchically.
+
+\subsection{Hierarchical Structure}
+\xx{hierarchical}{structure}
+
+The tree structure is one of the most effective structuring tools that
+exists, deriving its power from the principal of divide and conquor.
+So effective is it that the internal organization of
+most technical books are tree
+structures which are concisely summarized in the table of contents.
+In contrast, computer programs
+are usually presented as flat sequences of text to be consumed by an
+anonymous compiler.
+
+In order to bring program documentation up to the structural
+sophistication commonplace in technical books, FunnelWeb provides five levels
+of section headings\xx{section}{headings}
+implemented by the five special sequences \p{@A},\x{@A...} \p{@B},
+\p{@C}, \p{@D}, and \p{@E}. These must always appear at the start of a line.
+\p{@A} is the highest level section
+(\eg{}like \LaTeX{}'s \p{\bs{}chapter}) and \p{@E} is the lowest level
+section (\eg{}like \LaTeX{}'s \p{\bs{}subsubsubsection}).
+Section headings can appear anywhere in
+the free text of a FunnelWeb input file (\ie{}anywhere except inside a
+macro definition).
+
+Each section heading\xx{name}{section} in a FunnelWeb document
+has an associated name.
+The name of a section can be provided explicitly by supplying it
+delimited by \p{@<} and \p{@>} immediately after the section sequence
+(\eg{}\p{@A}), or implicitly by not providing an explicit name, in which
+case the section takes the name of the first macro defined between the
+section header in question and the following section header. An error is
+generated if a section has not been given an explicit name and does not
+contain any macro definitions. Here are some example headings:
+
+\begin{verbatim}
+@A@<Feed the Penguins and Save the World@>
+@B@<Feed the Penguins@>
+@C@<Feed the little penguins@>
+@C@<Feed the big penguins@>
+@B@<Save the World@>
+@C@<Save Europe@>
+@C@<Save Africa@>
+
+@C This heading hasn't been given an explicit name, but will inherit the
+name \p{Save the rest of the world} from the macro definition below.
+
+@$@<Save the rest of the world@>@Z==@{...@}
+\end{verbatim}
+
+The feature of having unnamed sections inherit the name of the first
+macro defined within their scope is present because a common style of
+writing in FunnelWeb is to have one section per macro definition. Because,
+under this style,
+each section describes a single macro, it usually turns out that the
+macro name makes a good name for the section too. The inheritance mechanism
+prevents duplication of the name.\xx{section name}{inheritance}
+
+Apart from the requirement that each section have an explicit or implicit
+name and that its special sequence appear at the start of a line, the only
+other restriction on section headings is that a section heading at level
+$n$ cannot appear immediately after a section heading at level $n-1$ or less.
+In other words, the hierarchy cannot be broken. For
+example, an \p{@C} cannot appear after an \p{@A} heading unless there
+is an intervening \p{@B} heading.
+
+\begin{verbatim}
+@A@<The Top Heading@>
+@C@<Level C here is not allowed after an A and will cause an error@>
+\end{verbatim}
+
+This rule extends to the start of the
+file; if there are any headings at all, the first one must be an \p{@A}
+heading. The following file, while short, is in error.
+
+\begin{verbatim}
+This FunnelWeb input file is in error because its first section heading
+is at level C rather than level A.
+@C@<2@>
+\end{verbatim}
+
+\subsection{Understanding the Printed Documentation}
+
+Type in the following file, and use FunnelWeb and \TeX{} to generate the
+corresponding printed
+documentation.\xx{programmer's}{cheer}\xx{hacker's}{cheer}
+\xx{hacker's}{dictionary}
+
+\begin{verbatim}
+@A@<Table of Contents@>
+
+@t table_of_contents
+
+@A@<Macros for Moral Support@>
+
+The following macro contain comments that provide moral support in the
+output code.
+
+@$@<Programmer's Cheer@>@M==@{
+-- Shift to the left!
+-- Shift to the right!
+-- Pop up, push down!
+-- Byte! Byte! Byte!
+-- (From "The New Hacker's Dictionary").
+@}
+
+The next macro is similar but is distributed throughout the program.
+@$@<Hacker's Cheer@>+=@{@+-- Pointer to the left@+@}
+
+@A@<An Extremely Imperative Stack Abstraction@>
+
+@B@<Define the Stack@>
+@$@<Hacker's Cheer@>+=@{-- Pointer to the right@+@}
+@$@<Stack Type@>@Z==@{type stack = record ... end;@}
+
+@B@<Push the Stack@>
+@$@<Hacker's Cheer@>+=@{-- Hack that code@+@}
+@$@<Push Procedure@>@Z==@{@-
+procedure push(var b:stack; v:value); @<Programmer's Cheer@> {...}@}
+
+@B@<Pop the Stack@>
+@$@<Hacker's Cheer@>+=@{-- Tight! Tight! Tight!@+@}
+@$@<Pop Procedure@>@Z==@{@-
+procedure pop(var b:stack); @<Programmer's Cheer@> {...}@}
+
+@B@<Rough the Stack Up a Bit@>
+@$@<Hacker's Cheer@>+=@{-- (RNW, 04-Jan-1991).@+@}
+@$@<Rough Procedure@>@Z==@{@-
+procedure rough(var b:stack); @<Hacker's Cheer@> {...}@}
+
+@O@<dummy.txt@>==@{dummy@+@}
+\end{verbatim}
+
+An examination of the printed documentation reveals a lot about how
+FunnelWeb's presentation works.
+
+First, notice how the \p{@t} typesetter directive
+at the top of the file has caused a table of contents to appear.
+This is one of FunnelWeb's typesetting features and is discussed in a later
+section. The table of contents shows that the sections have been
+numbered hierarchically.
+
+Now take a look at the typeset macro definitions. Most important are the
+numbers in square brackets that follow each macro name. As well as
+numbering the headings \i{hierarchically}, FunnelWeb \i{independently}
+numbers
+the macro definitions \i{sequentially}. The first macro definition
+(for \dq{Programmer's Cheer}) is numbered 1.
+The second (for \dq{Hacker's Cheer}) is numbered 2 and so on.
+Note that it is not macros that are numbered, but macro definitions.
+The distinction is necessary because some macros (such as the
+\dq{Hacker's Cheer} macro) are additive.
+It is important to
+realize that there is no relationship between the numbers of the headings
+and the numbers of the macro definitions.
+
+Now take a look at the notes beneath the body of each macro definition.
+All macro definitions are followed by a note indicating the definitions in
+which the macro is called. Additive macros have an additional list, listing
+the definitions in which they are defined.
+
+Finally, take a look at the macro \i{call} of \dq{Programmer's Cheer}
+in section~3.2 of the printed documentation.
+Macro calls are set in slanted roman (so that they can
+be distinguished from the \p{tt font} code) and are followed by
+the number of the defining macro definition. In this case, the macro
+was defined in definition~1. Further down, the call to
+the \dq{Hacker's Cheer} macro
+indicates that the macro was defined in definition~2. In fact the macro is
+additive and definition~2 is just the first of many definitions. To list
+all definitions in a call to an additive macro would be unnecessarily messy.
+
+\subsection{Literals and Emphasis}
+\x{literal construct}\x{emphasis construct}
+
+When writing about program code, it is often desirable to be able to indicate
+that a particular word or phrase be typeset in the same manner as the code
+being discussed. For example, one might talk about the variable \p{topval}
+or the procedure \p{stack\_pop} and wish for them to be typeset
+as they are in this sentence. This, of course,
+is simple to do using \TeX{} macros, but use of the
+(more general) FunnelWeb typesetting directives to do the same work has the
+added benefit of keeping the document portable to other typesetters.
+
+FunnelWeb provides two in-text type modification constructs: \p{@\{...@\}}
+and \p{@/...@/}\x{@slash}\x{@braces}
+where $\ldots$ is raw text. The \p{@\{...@\}}
+construct sets the enclosed
+text in the same manner as the text of macro definitions is set. The
+\p{@/...@/} construct emphasises its enclosed text in some
+typesetter-dependent fashion. Typically the emphasised text is set in
+italics.
+
+Here is an example of how these constructs might be used:
+
+\begin{verbatim}
+The following procedure @{put_sloth@} writes the @{sloth@} variable to
+the output file. Note: @/The output file must be opened for writing
+at this point or the program will crash!@/
+\end{verbatim}
+
+\subsection{Adding a Header Page}
+\x{header page}
+
+FunnelWeb provides a few typesetter-independent typesetting constructs
+which are specifically designed for the construction of header pages.
+These constructs are usually best placed at the top
+of your input file, but can be placed anywhere the document if desired to
+create header pages right through. The two main restrictions on these
+constructs is that the \p{@t} must start at the start of a line (which
+cannot contain comments), and that the constructs cannot appear inside
+a macro definition. Here is what the top of an input file might look like:
+
+\begin{verbatim}
+@t vskip 40 mm
+@t title titlefont centre "Hairy Wombat"
+@t title titlefont centre "Simulation"
+@t vskip 10 mm
+@t title smalltitlefont centre "A Program in Six Parts"
+@t title smalltitlefont centre "Simulating the Life of Some Hairy Wombats"
+@t vskip 20 mm
+@t title normalfont left "By Zqitzypbuswapzra Ypongtatoslrtzz"
+@t new_page
+@t table_of_contents
+@t new_page
+\end{verbatim}
+
+The \p{@t} at the start of each line indicates that each entire line is
+a typesetter directive.
+The \p{vskip}\xx{vskip}{directive}
+directive instructs FunnelWeb to skip some vertical space
+(measured in millimetres). The \p{title} directive\xx{title}{directive}
+instructs FunnelWeb to
+position a string of text on a single line of its own. Options are
+provided for font and alignment. The first word after \p{title} is the font
+which can be one of (in decreasing order of size) \p{titlefont},
+\p{smalltitlefont}, and \p{normalfont}. The second word after \p{title} is
+the desired alignment of the text. The options here are \p{left}, \p{right},
+and \p{centre}. The \p{new\_page}
+directive\xx{newpage}{directive}
+instructs FunnelWeb to skip to a new page. Finally, the
+\p{table\_of\_contents} directive\xx{table of contents}{directive}
+instructs FunnelWeb to insert a table of
+contents at that point in the text.
+
+\subsection{Comments}
+\x{comments}
+
+A FunnelWeb comment commences with the \p{@!}\x{@!} sequence and continues up to,
+but not including, the end of line marker at the end of the line that the
+comment sequence is on. Comments can be placed on any line except
+\p{@i} include, \p{@p} pragma, and \p{@t} typesetter directive lines.
+
+The text following the FunnelWeb comment sequence \p{@!} will not appear
+in the product files or the documentation file. It is
+only for the eyes of those who bother to look at the original \p{.fw}
+input file. Typically FunnelWeb comments are used to describe the way in
+which particular FunnelWeb constructs are being used. Example:
+
+\begin{verbatim}
+@! This macro is really revolting. Please forgive me. I had to do it!
+@$@<Revolt Me@>==@{@-
+@#X@(@#Y@(@#Z@,@"@#Z@"@)=6@,Teapot@,@"@#Q@(45@)@"@,Tiger@)@}
+\end{verbatim}
+
+\section{A Complete Example}
+\xx{complete}{example}\xx{FunnelWeb}{Example}
+
+To finish off the chapter, a complete example of a FunnelWeb input file
+is presented. Although unrealistically short, it gives a better
+idea of what a typical FunnelWeb \p{.fw} file looks like.
+
+\begin{verbatim}
+@!---------------------------------------!
+@! Start of FunnelWeb Example .fw File !
+@!---------------------------------------!
+
+@t vskip 40 mm
+@t title titlefont centre "Powers:"
+@t title titlefont centre "An Example of"
+@t title titlefont centre "A Short"
+@t title titlefont centre "FunnelWeb .fw File"
+@t vskip 10 mm
+@t title smalltitlefont centre "by Ross Williams"
+@t title smalltitlefont centre "26 January 1992"
+@t vskip 20 mm
+@t table_of_contents
+
+@A@<FunnelWeb Example Program@>
+
+This program writes out each of the first @{p@} powers of the first @{n@}
+integers. These constant parameters are located here so that they are easy to
+change.
+
+@$@<Constants@>==@{@-
+n : constant natural := 10; -- How many numbers? (Ans: [1,n]).
+p : constant natural := 5; -- How many powers? (Ans: [1,p]).@}
+
+@B Here is the outline of the program. This FunnelWeb file generates a single
+Ada output file called @{Power.ada@}. The main program consists of a loop that
+iterates once for each number to be written out.
+
+@O@<Power.ada@>==@{@-
+@<Pull in packages@>
+
+procedure example is
+ @<Constants@>
+begin -- example
+ for i in 1..n loop
+ @<Write out the first p powers of i on a single line@>
+ end loop;
+end example;
+@}
+
+@B In this section, we pull in the packages that this program needs to run. In
+fact, all we need is the IO package so that we can write out the results. To use
+the IO package, we first of all need to haul it in (@{with text_io@}) and then
+we need to make all its identifiers visible at the top level (@{use text_io@}).
+
+@$@<Pull in packages@>==@{with text_io; use text_io;@}
+
+@B Here is the bit that writes out the first @{p@} powers of @{i@}. The power
+values are calculated incrementally in @{ip@} to avoid the use of the
+exponentiation operator.
+
+@$@<Write out the first p powers of i on a single line@>==@{@-
+declare
+ ip : natural := 1;
+begin
+ for power in 1..p loop
+ ip:=ip*i;
+ put(natural'image(ip) & " ");
+ end loop;
+ new_line;
+end;@}
+
+@!---------------------------------------!
+@! End of FunnelWeb Example .fw File !
+@!---------------------------------------!
+\end{verbatim}
+
+\section{Summary}
+
+This chapter has provided an introduction to FunnelWeb and a tutorial
+that covers most of its features. FunnelWeb's functionality can be split into
+two parts: a macro preprocessor, and support for typesetting.
+The reader should be aware that
+the examples in this chapter, constructed as they were to demonstrate
+particular features of FunnelWeb, do not present a realistic picture
+of the best use of the tool. Only the final example of this chapter
+comes close.
+The reader should study this last example carefully
+and then write some real
+programs using FunnelWeb before proceeding to Chapter~\ref{chapadvanced}
+which provides more advanced information. At this stage it does not
+particularly matter exactly how you use Funnelweb, as everyone develops
+their own style anyway. The important thing is to try it.
+
+%==============================================================================%
+% End of Ch1.tex %
+%==============================================================================%
diff --git a/web/funnelAC/userman/u_ch2.tex b/web/funnelAC/userman/u_ch2.tex
new file mode 100644
index 0000000000..f1abe0773b
--- /dev/null
+++ b/web/funnelAC/userman/u_ch2.tex
@@ -0,0 +1,1586 @@
+%==============================================================================%
+% Start of Ch2.tex %
+%==============================================================================%
+%
+% Copyright
+% ---------
+% Copyright (C) 1992 Ross N. Williams.
+% This file contains a chapter of the FunnelWeb User's Manual.
+% See the main TeX file for this manual for further information.
+%
+%==============================================================================%
+
+\chapter{FunnelWeb Hints}
+\label{chapadvanced}\xx{FunnelWeb}{hints}
+
+Whereas Chapter~\ref{chapintroduction} provides an introduction to
+FunnelWeb and Chapter~\ref{chapdefinition} a definition, \i{this} chapter
+contains hints about how
+FunnelWeb can be used. This chapter probably should not be read until
+the reader has already commenced using FunnelWeb, or at the very least,
+tried out some of the examples in Chapter~\ref{chapintroduction}.
+Those who find themselves using FunnelWeb frequently
+should read this chapter at some stage
+so as to ensure that they are getting the most out of it.
+
+Most of the examples in this chapter have been
+placed in the FunnelWeb regression test suite which should be
+available in a directory called \p{/fwdir/tests/}.
+The files to examine are \p{hi01.fw} through \p{hi10.fw}.
+
+\section{Macro Names}
+\xx{macro}{names}\xx{macro}{identifiers}
+
+When using FunnelWeb, the choice of macro names can be as
+important to the readability of a program as the choice of program
+identifiers,
+and it is important that the user know the range of options available.
+
+\narrowthing{Names are case sensitive and exact matching:}{Macro names are case
+sensitive and are matched exactly. The strings used as a macro name
+at the point of definition and call must be
+\i{identical} for the connection to be made.}
+
+\narrowthing{Names can contain any printable character:}{FunnelWeb is less
+restrictive about its macro names than most programming languages are
+about their identifiers. A FunnelWeb macro name can contain any
+sequence of printable characters, including blanks and punctuation. Names
+can start and end with any character. Names cannot cross line boundaries. The
+following are all legal macro names:}
+
+\begin{verbatim}
+ @<This macro expands to some really bad code@>
+ @<@>
+ @<453 #$ %&# --===~~1">>>@>
+ @<<@>
+ @<<>@>
+ @<a b c d e f g@>
+ @< ! @>
+ @<?? ...@>
+ @<"Who's been hacking MY program" said Father Bear.@>
+ @<Update the maximum and return for more data@>
+\end{verbatim}
+
+\narrowthing{Names must be no more than a maximum limit in length:}{Names
+can be
+no longer than a predefined maximum length. Currently this length cannot
+be modified.}
+
+Typically, macro names will consist of a short English phrase or sentence
+that describes the contents of the macro.
+
+\section{Quick Names}
+\xx{quick}{names}
+
+Sometimes a particular macro must be used extremely often. When this happens
+it is desirable to make the macro's name as short as possible.
+The shortest ordinary FunnelWeb macro name is the empty name\xx{empty}{name}
+\dqp{@<@>}, which is four characters long. Single-character names are
+five characters long.
+
+To cater for the cases where really short names are needed, FunnelWeb provides
+a \newterm{quick name} syntax that allows one-character macro names to be
+specified in two less characters. Quick names take the form of the special
+character, followed by a hash (\p{\#}) followed by a single character.
+Examples:
+
+\begin{verbatim}
+@#A @#| @#& @#m
+\end{verbatim}
+
+This form of macro name has the same syntactic functionality as an ordinary
+name and can be substituted wherever an ordinary name can be. In fact
+quick names live in the same namespace as ordinary macro names. For example
+the quickname \p{@\#A} is the \i{same name} (refers to the same macro)
+as the ordinary name \p{@<A@>}.
+
+Because quick names look syntactically \dq{open} (\ie{}they do not have
+a closing\p{@>} as ordinary names do), it is best to avoid them except
+where a macro must be called very often.
+
+\section{FunnelWeb the Martinet}
+\xx{FunnelWeb}{rules}\xx{FunnelWeb}{martinet}
+
+There are many ways in which a macro preprocessor can cause unexpected
+difficulties. FunnelWeb seeks to avoid many of these problems by performing
+a number of checks. This section describes some of the checks that
+FunnelWeb performs.
+
+\narrowthing{Trailing blanks in the input file:}{Trailing
+blanks\xx{trailing}{blanks} are usually
+not dangerous, but
+FunnelWeb disallows them anyway. All trailing blanks in the
+\i{input} (\p{.fw} file) are flagged as errors by FunnelWeb.
+FunnelWeb does not flag trailing blanks in any of its output files.}
+
+\narrowthing{Input line length:}{FunnelWeb has a maximum input line
+length.\xx{input line}{length}
+If FunnelWeb reads an input line longer than this length, it flags the
+line with an error message. The maximum length can be changed using a
+pragma (see Chapter~\ref{chapdefinition}).}
+
+\narrowthing{Product file line length:}{FunnelWeb
+watches the length of output lines\xx{output line}{length}
+and all output lines longer than the limit are flagged with error
+messages.
+The maximum length can be changed using a
+pragma (see Chapter~\ref{chapdefinition}).
+That FunnelWeb polices output lines is very important. Some programs
+can behave very strangely if they get an input line that is too long
+(\eg{}Fortran compilers\xx{Fortran}{compilers}
+can simply ignore text past a certain column!)
+and once FunnelWeb starts expanding macros using indentation, it is sometimes
+not obvious how wide the product file will be.}
+
+\narrowthing{Control characters:}{The presence of control
+characters\xx{control}{characters} in a text file
+can result in some confusing behaviour downstream when the file is
+presented to various programs. Unfortunately, some text
+editors\xx{text}{editors} allow
+control characters to be inserted into the text rather too easily, and it is
+all too easy to be tripped up. FunnelWeb prevents these problems by flagging
+with diagnostics all non-end-of-line control characters detected
+in the input (\p{.fw}) file (even TABs\x{tabs}).
+The result is that the user is
+guaranteed that product files generated from FunnelWeb contain no
+unintentional control characters. This said, FunnelWeb does allow the
+insertion of control characters in the output file by explicitly
+specifying
+them in the text using a \p{@\circumflex{}} control sequence.}
+
+\narrowthing{Number of invocations:}{FunnelWeb
+checks the number of times that\xx{invocations}{number}
+each macro is called and issues an error if the total is not one. The
+\p{@Z} (for zero) and \p{@M} (for many) macro attributes can be used
+to bypass these checks.}
+
+\narrowthing{Recursion:}{Because\xx{recursion}{macro}
+FunnelWeb does not provide any conditional
+constructs, all recursively defined macros must, by
+definition, expand infinitely,\footnote{A special case exists where
+there is recursion but no content. In this case, the expansion is finite
+(the empty string) even though the operation of expanding is infinite.
+FunnelWeb does not treat this case specially.} and are therefore
+unacceptable. FunnelWeb performs \i{static} checks to detect recursion,
+detecting it before macro expansion commences. The user need not fear that
+FunnelWeb will lock up or spew forth
+if a recursive macro is accidentally specified.}
+
+\section{Fiddling With End of Lines}
+\xx{EOL}{fiddling with}\xx{end-of-line}{fiddling with}\x{spacing}
+
+One of the fiddly aspects of programming with FunnelWeb is coping with end of
+lines. If you want your product file to be well indented without
+multiple blank lines or code run-ons, you have to spend a little time working
+out how the end of line markers get moved around.
+
+The rule to remember is that,
+disregarding the effects of special sequences
+within a macro body, \i{the body of a macro consists of exactly the text
+between the opening \p{@\{} and the closing \p{@\}}}. This text includes end of
+line markers.
+
+If for example you call a macro in a sequence of code$\ldots$
+
+\begin{verbatim}
+while the_walrus_is_sleepy do
+ begin
+ writeln('zzzzzzz');
+ @<Wake up the walrus@>
+ writeln('Umpharumpha...');
+ end;
+\end{verbatim}
+
+where \p{<wake up the walrus>} is defined as follows
+
+\begin{verbatim}
+@$@<Wake up the walrus@>==@{
+wake_up_the_walrus(the_walrus);
+@}
+\end{verbatim}
+
+then when \p{<Wake up the walrus>} is expanded you will get
+
+\begin{verbatim}
+while the_walrus_is_sleepy do
+ begin
+ writeln("zzzzzzz");
+
+ wake_up_the_walrus(the_walrus);
+
+ writeln("Umpharumpha...");
+ end;
+\end{verbatim}
+
+The blank lines were introduced by the end on line markers included in the
+definition of \p{<Wake up the walrus>}. A good solution to this problem is to
+suppress the end of line markers by defining the macro as follows
+
+\begin{verbatim}
+@$@<Wake up the walrus@>==@{@-
+wake_up_the_walrus(the_walrus);@}
+\end{verbatim}
+
+This is the usual form of macro definitions in FunnelWeb files.
+
+In additive macros, this format does not
+work properly because the end of line that is suppressed by the trailing \p{@\}}
+does not get replaced by the end of line at the end of the macro invocation. For
+example the definition
+
+\begin{verbatim}
+@$@<Wake up the walrus@>+=@{@-
+wake_up_the_walrus_once(the_walrus);@}
+\end{verbatim}
+
+later followed by
+
+\begin{verbatim}
+@$@<Wake up the walrus@>+=@{@-
+wake_up_the_walrus_again(the_walrus);@}
+\end{verbatim}
+
+is equivalent to the single definition
+
+\begin{verbatim}
+@$@<Wake up the walrus@>==@{@-
+wake_up_the_walrus_once(the_walrus);wake_up_the_walrus_again(the_walrus);@}
+\end{verbatim}
+
+Putting the trailing \p{@\}} on a new line at the end of the macro (except for
+the last definition part) solves the problem.
+
+\begin{verbatim}
+@$@<Wake up the walrus@>+=@{@-
+wake_up_the_walrus_once(the_walrus);
+@}
+\end{verbatim}
+
+later followed by
+
+\begin{verbatim}
+@$@<Wake up the walrus@>+=@{@-
+wake_up_the_walrus_again(the_walrus);@}
+\end{verbatim}
+
+is equivalent to the single definition
+
+\begin{verbatim}
+@$@<Wake up the walrus@>==@{@-
+wake_up_the_walrus_once(the_walrus);
+wake_up_the_walrus_again(the_walrus);@}
+\end{verbatim}
+
+Managing end of line markers is tricky,
+but once you establish a convention for coping
+with them, the problem disappears into the background.
+
+\section{Fudging Conditionals}
+\xx{fudging}{conditionals}
+
+As a macro preprocessor, the facility that FunnelWeb most obviously lacks
+is a conditional facility (such as C's \p{\#ifdef}). It might, therefore,
+come as a surprise to know that the first version of FunnelWeb
+actually had a built in conditional facility. The facility allowed
+the programmer to specify a construct that would select from one of a number
+of macro expressions depending on the value of a controlling macro expression.
+
+In three years the construct was never used.
+
+The reason was that conditional constructs could be fudged nearly
+as easily as they could be used. Because of this, the inbuilt conditional
+feature was removed in the current version of FunnelWeb. Not only did this
+simplify the program, but is also allowed recursive macros to be detected
+through static analysis rather than during macro expansion.
+
+There are two basic ways to fudge a conditional. First, the comment
+facility of the target programming language may be employed. For example,
+in Ada,\x{Ada}
+comments commence with \dqp{--} and terminate at the end of the line.
+Using this fact, it is easy to construct macros that can be called at the
+start of each target line and which turn on and off the lines so
+marked by defining the macro to be the empty string (ON) or the comment
+symbol (\p{--}) (OFF). For example:
+
+\begin{verbatim}
+@A@<Debug Macro@>
+
+The following macro determines whether debug code will be included in the
+program. All lines of debug code commence with a call to this macro and so
+we can turn all that code on or off here by defining this macro to be either
+empty or the single-line comment symbol (\p{--}). Note the use of a
+quick macro name.
+
+@$@#D@M==@{@} @! Turns the debug code ON.
+@! Use this definition to turn the debug code OFF: @$@#D==@{--@}
+
+... then later in the file...
+
+@$@<Sloth incrementing loop@>==@{@-
+while sloth<walrus loop
+ @#D assert(sloth<walrus,"AWK! sloth>=walrus!!!!!!!");
+ @#D assert(timer<timermax,"AWK! timer>=timermax!!!");
+ inc(sloth);
+end loop@}
+\end{verbatim}
+
+The other way to fudge a conditional is to define a macro with a
+single parameter. A call to the macro is then wrapped around all the
+conditional code in the program. The macro can then be defined to
+present or ignore the code of its argument. For example:
+
+\begin{verbatim}
+@A@<Debug Macro@>
+
+The following macro determines whether debug code will be included in the
+program. All debug code is wrapped by a call to this macro and so
+we can turn all the debug code on or off here by defining this macro to be
+either empty or its parameter.
+
+@$@#D@(@1@)@M==@{@1@} @! Turns the debug code ON.
+@! Use this definition to turn the debug code OFF: @$@#D@(@1@)==@{@}
+
+... then later in the file...
+
+@$@<Sloth incrementing loop@>==@{@-
+while sloth<walrus loop
+ @#D@(assert(sloth<walrus,"AWK! sloth>=walrus!!!!!!!");
+ assert(timer<timermax,"AWK! timer>=timermax!!!");@)
+ inc(sloth);
+end loop@}
+\end{verbatim}
+
+In languages that allow multi-line comments (\eg{}C with \p{/*} and \p{*/}),
+comments can be used to eliminate the conditioned code rather than
+absence. For example:
+
+\begin{verbatim}
+@$@#D@(@1@)@M==@{/* @1 */@} @! Comments out the debug code
+\end{verbatim}
+
+(Note: If this example were ever actually used,
+the programmer would have to be careful not to place comments in
+the argument code. Nested comments in~C are non-portable.)
+
+The parameterized macro idea can be generalized to support the choice of
+more than one mutually exclusive alternative. For example:
+
+\begin{verbatim}
+@A This module contains non-portable code that must execute on Hewlett
+Packard, Sun, and DEC workstations. The following FunnelWeb macro is
+defined to choose between these three. The first parameter is the HP code,
+the second is the Sun code, and the third is the DEC code. Whichever
+parameter constitutes the body of this macro determines which
+machine the code is being targeted\note{Dictionary says only one t
+in targeted.} for.
+
+@$@<Machine specific code@>@(@3@)@M==@{@1@} @! Configure for HP.
+
+...then later in the file...
+
+@<Machine specific code@>@(
+@"get_command_line(comline)@" @, @! HP.
+@"scan_command_line(128,comline);@" @, @! Sun.
+@"dcl_get_command_line(comline,256);@" @) @! DEC.
+\end{verbatim}
+
+Of course, this could also be performed using three separate macros. The
+main advantage of using a single macro is that the mutual exclusivity is
+enforced. Also, because FunnelWeb ensures that the number of formal and
+actual parameters are the same, this method lessens the chance that a
+machine will be forgotten in some places.
+
+
+\section{Changing the Strength of Headings}
+\xx{headings}{strength}\xx{typesetting}{strength}%
+\xx{section}{strength}\xx{font}{size}
+
+FunnelWeb provides five heading levels:
+\p{@A}, \p{@B}, \p{@C}, \p{@D}, and \p{@E} to which it binds five different
+typographical strengths. These bindings are static; a level
+\p{@A} heading will always be typeset in a particular font size regardless
+of the size of the document. The font
+sizes have been preset to be \dq{reasonable} for a range of document sizes,
+but may be inappropriate for very small or large documents.
+
+FunnelWeb does not currently provide an \dq{official}
+way (\eg{}a pragma) to change the typesetting
+strength of headings. This feature might be added in later versions.
+Meanwhile, a hack is available that will do the job, providing that you
+do not mind the hack being \TeX{}-specific and probably FunnelWeb-version
+specific.
+
+Inside the set of \TeX{} macro definitions
+that FunnelWeb writes at the top of every documentation
+file are five \dq{library}
+definitions \p{fwliba}$\ldots$\p{fwlibe} which
+provide five different typesetting strengths for headings. Near the
+end of the set of definitions, FunnelWeb binds these macros to five
+other macros \p{fwseca}$\ldots$\p{fwsece} which are invoked directly in the
+generated \TeX{} code to typeset the headings.
+
+\begin{verbatim}
+\def\fwseca#1#2{\fwliba{#1}{#2}}
+\def\fwsecb#1#2{\fwlibb{#1}{#2}}
+\def\fwsecc#1#2{\fwlibc{#1}{#2}}
+\def\fwsecd#1#2{\fwlibd{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+\end{verbatim}
+
+This means that the typesetting strength of the headings in a FunnelWeb
+document can be changed by redefining these macros at the top of a FunnelWeb
+document. For example:
+
+\begin{verbatim}
+@p typesetter = tex
+\def\fwseca#1#2{\fwlibc{#1}{#2}}
+\end{verbatim}
+
+would set \p{@A} headings at the same strength as the default strength of
+\p{@C} headings. The \p{typesetter} directive is necessary to ensure that the
+\TeX{} control sequences get through to the documentation file unfiltered.
+
+The following will tone down all headings by two levels (with the
+\p{@D} and \p{@E} levels being allocated the default \p{@E} typesetting
+strength because there is nothing weaker).
+
+\begin{verbatim}
+@p typesetter = tex
+\def\fwseca#1#2{\fwlibc{#1}{#2}}
+\def\fwsecb#1#2{\fwlibd{#1}{#2}}
+\def\fwsecc#1#2{\fwlibe{#1}{#2}}
+\def\fwsecd#1#2{\fwlibe{#1}{#2}}
+\def\fwsece#1#2{\fwlibe{#1}{#2}}
+\end{verbatim}
+
+These definitions affect only the headings that follow them, and so they
+should be placed at the top of the FunnelWeb input file.
+
+\section{Efficiency Notes}
+\xx{FunnelWeb}{efficiency}\xx{efficiency}{notes}
+
+The following notes are worth keeping in mind when using FunnelWeb.
+
+\narrowthing{Memory:}{When\x{memory}\xx{input}{files}
+FunnelWeb processes an input file, it reads
+the entire input file, and all the included files into memory.\footnote{If a
+file is included $n$ times, FunnelWeb keeps $n$ copies in memory.} This
+organization does not pose a constraint on machines with large memories,
+but could
+present a problem on the smaller machines such as the PC.}
+
+\narrowthing{Speed:}{FunnelWeb\x{speed} is not a slow program. However, it is
+not particularly fast either. If the speed at which FunnelWeb runs is
+important to you, then the thing to keep in mind is that FunnelWeb has been
+optimized to deal efficiently with large slabs of text. FunnelWeb treats
+input files as a sequence of text slabs and special sequences (\eg{}\p{@+})
+and whenever it hits a special sequence, it has to stop and think.
+Thus, while a ten megabyte text slab would be manipulated as a single token,
+in a few milliseconds, a similar ten megabyte chunk filled with special
+sequences would take a lot longer.
+If FunnelWeb is running slowly, look to see if the input contains
+a high density of special sequences. This can sometimes happen if FunnelWeb
+is being used as a backend macro processor and its input is being
+generated automatically by some other program.}
+
+\narrowthing{Macro expansion:}{When\xx{macro}{expansion}
+tangling (expanding macros), FunnelWeb never
+expands a macro expression into memory; it always writes it to the
+product file
+as it goes. This is a powerful fact, because it means that you can
+write macros containing an unlimited amount of text, and pass such macros
+as parameters to other macros without becoming concerned about overflowing
+some kind of buffer memory. In short, FunnelWeb does not impose any
+limits on the size of macro bodies or their expansions.}
+
+\section{Interactive Mode}
+\x{interactive mode}\x{keyboard mode}
+
+As well as having a command line interface with lots of options, FunnelWeb
+also provides a command language and a mode (\dq{interactive mode})
+in which commands in the language can be typed interactively. The
+FunnelWeb command interpreter was created primarily
+to support regression testing,\xx{regression}{testing}
+but can also be useful to FunnelWeb users.
+
+FunnelWeb's command interpreter\xx{command}{interpreter}
+reads one command per line and can read
+a stream of commands either from a text file, or from the console. The
+interpreter can understand over twenty commands. See
+Chapter~\ref{chapdefinition} for a full list. However, most of them
+were designed to support regression testing and will not be of use to the
+casual user.
+
+The commands that are of greatest use to the casual user
+are:\xx{useful}{commands}
+
+\begin{verbatim}
+ ! - Comment. Ignores the whole line.
+ EXECUTE fn - Execute the specified file.
+ FW options - Invoke FunnelWeb-proper once.
+ SET options - Sets options.
+ SHOW - Displays currently active options.
+ TRACE ON - Turns command tracing ON.
+ QUIT - Quits FunnelWeb.
+\end{verbatim}
+
+To distinguish here between invocations of the FunnelWeb program
+and FunnelWeb runs inside the shell, we call the latter \newterm{FunnelWeb
+proper}. The \dqp{FW} command invokes FunnelWeb proper with the specified
+options which take the same syntax as they do on the command line. The only
+restriction is that none of the action options can be turned on except
+\dqp{+F} which must be turned on.
+
+The \dqp{SET} command\xx{set}{command}
+has the same syntax as the \dqp{FW} command except that it
+does not allow \i{any} action options to be
+specified. It's sole effect is to set default option values for the
+rest of the run.
+
+The \dqp{SHOW}\xx{show}{command}
+command displays the current default options.
+
+By default, FunnelWeb does not echo the commands that it processes in a
+script. The \dqp{TRACE ON}\xx{trace on}{command}
+command turns on such tracing.
+
+These commands can be combined to streamline the use of FunnelWeb.
+For example, you might wish to create a script called \p{typeset.fws}
+to process a whole group of files.
+
+\begin{verbatim}
+trace on
+!This script typesets the whole program.
+! Set no listing file, no product files, but specify a documentation file
+! and specify the directory into which it should be placed.
+set -L -O +T/usr/ross/typeset/
+fw prog1
+fw prog2
+fw prog3
+fw prog4
+\end{verbatim}
+
+There are a few ways in which this script can be run. The simplest is
+simply to specify it in the \dqp{+X} option of a FunnelWeb invocation.
+FunnelWeb shellscripts default to \dqp{<current\_directory>} and \dqp{.fws}.
+
+\begin{verbatim}
+fw +xtypeset
+\end{verbatim}
+
+The second alternative is to enter interactive mode.
+
+\begin{verbatim}
+fw +k
+\end{verbatim}
+
+From there, you can execute the script using:
+
+\begin{verbatim}
+execute typeset
+\end{verbatim}
+
+Interactive mode could be very useful to those with multiple-window
+workstations.\x{workstations}
+The user could create a window containing an interactive
+session of FunnelWeb, and then switch between windows, editing, and executing
+FunnelWeb proper and other programs.
+
+If you find yourself using the command interpreter a lot, be sure to
+read about the other commands that are available in
+Chapter~\ref{chapdefinition}.
+
+\section{Setting Up Default Options}
+\xx{options}{setting defaults}\xx{default}{options}
+
+If you do not like FunnelWeb's default settings for its command line
+options, there are a number of ways in which you can change them.
+
+\narrowthing{Define an \dq{alias}:}{Use your operating system
+\dqp{alias}\x{alias}
+facility to create an alias for FunnelWeb containing the desired options.
+FunnelWeb processes options from left to right, so you can override
+these defaults later if you wish.}
+
+\narrowthing{Create a script called \dqp{fwinit.fws}:}{When FunnelWeb
+starts up, it executes a script called \dqp{fwinit.fws}\x{fwinit.fws}
+if\xx{startup}{script}\xx{initialization}{script} such a
+script exists in the current directory. You can use this fact to set options
+before the run of FunnelWeb proper by creating such a script and placing
+a single \dqp{set} command in it containing the desired options. The main
+trouble with this approach is that the options in the \p{set} command will
+be processed \i{after} the command line options, which means that you won't
+be able to override them on the command line.}
+
+For example, you might be involved more with presenting programs than with
+running them, and want FunnelWeb to generate a documentation
+file by default, but not to produce
+listing or product files by default. In Unix you could do this with:
+
+\begin{verbatim}
+alias fw fw -L -O +T
+\end{verbatim}
+
+\section{FunnelWeb and Make}
+\x{make utility}\xx{file}{dependencies}
+
+The Unix \p{Make} program allows a set of dependencies between a set of
+files to be described, and then uses these dependencies to control the way in
+which the files are created and updated. Typically,
+\p{Make} is used to control the process of transforming a collection of
+source code files to one or more executable files.
+As the use of FunnelWeb implies an extra stage to this process, it is
+natural to include the transformation of \p{.fw} files to source code
+files as part of the \p{Make} process. This is easy to do, but the user
+should be aware of one aspect of FunnelWeb which can cause problems.
+
+It is often useful, when using FunnelWeb, to create a FunnelWeb \p{.fw}
+file that generates more than one product file.
+That is, a single \p{.fw} file may have many macro definitions connected
+to product files so that when the FunnelWeb \p{.fw} file is processed by
+FunnelWeb, several files are created. For example, this facility has been
+used to great effect to place the description of an Ada\x{Ada} package's
+package specification file and package body file in the same FunnelWeb
+\p{.fw} file.
+
+The use of multiple product files, however, provokes a problem
+with dependencies. Suppose for example that a FunnelWeb \p{prog.fw}
+produces two product files \p{proc.spec} (a package specification)
+and \p{prog.body} (a package body). If the package is accessed in the way
+that packages normally are, it will be quite common for the programmer
+to want to modify the package body without modifying the program specification.
+So the programmer will edit the \p{prog.fw} file to change the package
+body. The result of running this through FunnelWeb will be the desired
+new package body file. However, FunnelWeb will also produce a new package
+specification product file \i{even though it may be identical to the
+previous version!} The result is that the newly created (with a recent
+file date) specification package file could provoke a huge remake of much
+of the program in which it resides.
+
+To solve the problem, FunnelWeb includes a command line option
+(\p{D} for Delete),\xx{D}{option}\xx{delete}{output files}
+which when turned on (using \dqp{+D}) causes
+FunnelWeb to suppress\xx{suppression}{file}
+product and documentation files that are identical
+to the previously existing versions of the same files. For example,
+if, during a FunnelWeb run, a macro was connected to a product file called
+\p{x.dat}, and the macro expanded to \i{exactly} the same text as is
+contained in \p{x.dat} then FunnelWeb would simply \i{never write the product
+file}, the file \p{x.dat} would be untouched and, as a result, no further
+\p{Make} propagations would take place.
+
+FunnelWeb implements this feature by writing each product file to
+a temporary file with a temporary file name. It then compares the temporary
+file with the target file. If the two are identical, it deletes the
+temporary file. If the two are different it deletes the target file and
+renames the temporary file to the target file.
+
+Use of the \p{D} facility means that the programmer need not be punished
+(by extra \p{Make} propagations) for describing more than one product file
+in the same FunnelWeb file.
+
+
+\section{The Dangers of FunnelWeb}
+\xx{FunnelWeb}{dangers}\xx{FunnelWeb}{pitfalls}
+
+Like many tools that are general and flexible, FunnelWeb can be used in a
+variety of ways, both good and bad. One of the original appeals of the
+literate approach to programming for Knuth,\xn{Donald}{Knuth}
+the inventor of literate
+programming,\xx{literate}{programming}
+was that it allows the programmer to describe the target
+program bottom up, top down, size to side, or chaotically if desired.
+The flexibility that this style of programming leaves much
+room for bad documentation as well as good documentation. Years of
+experience with FunnelWeb has revealed the following stylistic pitfalls
+which the experienced FunnelWeb user should take care to
+avoid.\footnote{The fact that these faults are listed here does not mean
+that the author has eliminated them in his own work. Rather,
+it is mainly the author's own mistakes that have resulted in this list
+being compiled. The author immediately
+confesses to several of the faults listed here, most notably that of
+Pavlov documentation.}
+
+\narrowthing{Spaghetti organization:}{By\xx{spaghetti}{organization}
+far the worst problem that arises
+in connection with the literate style occurs where the programmer has
+used the literate tool to completely scramble the program so that the
+program is described and layed out in an unordered, undisciplined
+\dq{stream of consciousness}.\x{stream of consciousness}
+In such cases the programmer may be using
+the literate style as a crutch to avoid having to
+think about structuring the presentation.}
+
+\narrowthing{Boring organization:}{At\xx{boring}{organization}
+the other extreme, a program may be
+organized in such a strict way that it is essentially laid out in the
+order most \dq{desired} by the target programming language. For example,
+each macro might contain a single procedure, with all the macros being
+called by a macro connected to a file at the top. In many cases a boring
+structure may be entirely appropriate, but the programmer should be warned
+that it is easy to slip into such a normative style, largely forgetting the
+descriptive structural power that FunnelWeb provides.}
+
+\narrowthing{Poor random access:}{Using\xx{random}{access}
+FunnelWeb, it is quite possible to write
+programs like novels\x{novels}
+--- to be read from cover to cover. Sometimes the
+story is very exciting, with data structures making dashing triumphs and
+optimized code bringing the story to a satisfying conclusion. These programs
+can be works of art.
+Unfortunately, without careful construction,
+such \dq{novel-programs} can become very hard to access randomly by (say)
+a maintenance programmer\xx{maintenance}{programmer}
+who wishes only to dive in and fix a specific
+problem. If the entire program is scrambled for sequential exposition, it
+can be hard to find the parts relating to a single function.
+Somehow a balance must be struck in the document between the
+needs of the sequential and of the random-access reader.
+This balance will depend on the intended use of the program.}
+
+\narrowthing{Too-interdependent documentation:}{Sometimes,
+when\xx{documentation}{interdependent} editing a
+program written using FunnelWeb, one knows how to modify the program,
+but one is unsure of how to update the surrounding documentation!
+The documentation may be woven into such a network of facts that it seems that
+changing a small piece of code could invalidate many
+pieces of documentation scattered throughout the document. The documentation
+becomes a big tar pit in which movement is impossible.
+For example,
+if you have talked about a particular data structure invariant throughout
+a document, changing that invariant in
+a small way could mean having to update all the documentation without
+touching much
+code. In such cases, the documentation is too interdependent. This could be
+symptomatic of an excessibly interconnected program, or of an
+excessively verbose or redundant documenting style. In any case, a balance
+must be struck between the conversational style that encourages redundancy
+(by mentioning things many times) and the normalized database approach where
+each fact is given at only one point, and the reader is left to figure
+out the implications throughout the document.}
+
+\narrowthing{Pavlov documentation:}{By\xx{pavlov}{documentation}
+placing so much emphasis on the documentation,
+FunnelWeb naturally provides slots where documentation \dq{should} go. For
+example, a FunnelWeb user may feel that there may be a rather unpleasant
+gap between a \p{@C} marker and the following macro. In many cases \i{no}
+commentary is needed and the zone is better left blank rather than being
+filled with the kind of uninformative waffle one often finds filling the slots
+of structured documentation written according to a military standards
+(\eg{}MIL-STD-2167A).\x{MIL-STD-2167A}\x{2167A}\footnote{Note:
+This is not a criticism of 2167A,
+only of the way it is sometimes used.} The lesson is to add documentation
+only when it adds something. The lesson in Strunk and White\paper{Strunk79}
+(p.~23)
+holds for
+program documentation as it does for other writing: \dq{Vigorous writing is
+concise. A sentence should contain no unnecessary words, a paragraph no
+unnecessary sentences, for the same reason that a drawing should have
+no unnecessary lines and a machine no unnecessary parts. This
+requires not that the writer make all his sentences short, or that he avoid
+all detail and treat his subjects only in outline, but that every word
+tell.}.\checked{}}
+
+\narrowthing{Duplicate documentation:}{Where\xx{duplicate}{documentation}
+the programmer is generating
+product files that must exist on their own within the entire programming
+environment (\eg{}the case of a programmer in a team who is using FunnelWeb
+for his own benefit but must generate (say) commented Ada\x{Ada}
+specification
+package files) there is a tendency for the comments in the
+target code to duplicate the commentary in the FunnelWeb text. This may or
+may not be a problem, depending on the exact situation. However, if this is
+happening, it is certainly worth the programmer spending some time deciding
+if one or other of the FunnelWeb or inline-comment documentation should be
+discarded.
+In many cases, a mixture can be used, with the FunnelWeb documentation
+referring the reader to the inline comments where they are present.
+For example:}
+
+\begin{verbatim}
+@A Here is the header comment for the list package specification.
+The reader should read these comments carefully as they define a list.
+There is no need to duplicate the comments in this text.
+
+@$@<Specification package header comments@>==@{@-
+-- LIST PACKAGE
+-- ============
+-- * A LIST consists of zero or more ITEMS.
+-- * The items are numbered 1 to N where N is the number of items in the list.
+-- * If the list is non-empty, item 1 is called the HEAD of the list.
+-- * If the list is non-empty, item N is called the TAIL of the list.
+-- ...
+@}
+\end{verbatim}
+
+\narrowthing{Overdocumenting:}{Another\xx{over}{documentation}
+evil that can arise when using FunnelWeb is
+to over-document the target program. In some of Knuth's earlier (\eg{}1984)
+examples of literate programming, each variable is given its own description
+and each piece of code has a detailed explanation. This level of analysis,
+while justified for tricky tracts of code, is probably not warranted
+for most of the code that constitutes most programs. Such over-commenting
+can even have the detrimental affect of obscuring the code, making it hard
+to understand because it is so scattered (see \dq{spaghetti organization}
+earlier). It is up to the user to decide when a stretch of just a few lines of
+code should be pulled to bits and analysed and when it is clearer to leave it
+alone.}
+
+\narrowtext{In the case where there
+are a few rather tricky lines of code, a detailed
+explanation may be appropriate. The following example
+contains a solution to a problem outlined in section 16.3 of
+the book \dq{The Science of Programming} by David Gries\paper{Gries81}.}
+
+\begin{verbatim}
+@C@<Calculation of the longest plateau in array b@>
+
+This section contains a solution to a problem outlined in section 16.3 of
+the book @/The Science of Programming@/ by David Gries[Gries81].
+
+@D Given a sorted array @{b[1..N]@} of integers, we wish to determine the
+@/length@/ of the longest run of identically valued elements in the array.
+This problem is defined by the following precondition and postcondition.
+
+@$@<Precondition@>==@{/* Pre: sorted(b). */@}
+@$@<Postcondition@>==@{@-
+/* Post: sorted(b) and p is the length of the longest run in b[1..N]. */@}
+
+@D We approach a solution to the problem by deciding to try the approach of
+scanning through the array one element at a time maintaining a useful
+invariant through each iteration. A loop variable
+array index @{i@} is created for this purpose. The bound function is
+@{N-i@}. Here is the invariant.
+
+@$@<Invariant@>==@{@-
+/* Invariant: sorted(b) and 1<=i<=N and */
+/* p is len of longest run in b[1..i]. */@}
+
+@D Establishing the invariant above in the initial, degenerate case is easy.
+
+@$@<Establish the plateau loop invariant initially@>==@{i=1; p=1;@}
+
+@D At this stage, we have the following loop structure. Note that when both
+the invariant and @{i != N@} are true, the postcondition holds and the loop
+can terminate.
+
+@$@<Set p to the length of the longest plateau in sorted array b[1..N]@>==@{@-
+@<Precondition@>
+@<Establish the plateau loop invariant initially@>
+while (i != N)
+ {
+ @<Invariant@>
+ @<Loop body@>
+ }
+@<Postcondition@>
+@}
+
+@D Now there remains only the loop body whose sole task is to increase @{i@}
+(and so decrease the value of the bound function) while maintaining the
+invariant. If @{p@} is the length of the longest run
+seen so far (i.e. in b[1..i]), then, because the array is sorted,
+the extension of our array range to
+@{b[1..i+1]@} can only result in an increase in @{p@} if the new element
+terminates a run of length @{p+1@}. The increase can be at most 1. Because
+the array is sorted, we need
+only compare the endpoints of this possible run to see if it exists. This
+is performed as shown below.
+
+@$@<Loop body@>==@{i++; if (b[i] != b[i-p]) p++;@}
+\end{verbatim}
+
+\narrowtext{Where the code is more obvious,
+it is often better to let the code speak for itself.}
+
+\begin{verbatim}
+@C The following function compares two C~strings and returns TRUE iff they
+are identical.
+
+@$@<Function comp@>==@{@-
+bool comp(p,q)
+char *p,*q;
+{
+ while (TRUE)
+ {
+ if (*p != *q ) return FALSE;
+ if (*p == '\0') return TRUE;
+ p++; q++;
+ }
+}
+@}
+\end{verbatim}
+
+\section{Wholistic Debugging}
+\xx{wholistic}{debugging}
+
+Surprising though it may be, FunnelWeb has a key role to play in the
+\i{debugging} of programs. Long experience in programming has led me to the
+concept of \newterm{wholistic debugging}. When most programmers detect a
+bug, their first reaction seems to be to jump into the debugger\x{debugger}
+where they
+often spend many hours stepping through endless stretches of code and
+generally wasting a lot of time.
+
+In contrast, my first reaction when I detect a bug is to realize that
+\i{the code must not be in good enough shape if such a bug can arise.}
+The presence of the bug is taken as symptomatic of the lack of general
+health of the code. If that bug occurred, why not another?
+In response to this realization, my reaction is not to enter the debugger,
+but rather to return to the original code and tend it like a
+garden,\xx{code}{gardening}
+adding more comments, reworking the grotty bits, adding assertions,
+and looking for faults. In many cases, the search for faults does not
+even centre on the specific bug that arose, but does tend to focus on
+the area of code where the bug is likely to be.
+
+The result is often that the original bug is located more quickly than it
+would have been had the debugger been involved. But even if it isn't, there
+are other benefits. A programmer who enters the debugger may
+stay there for hours and still not find the bug. The result is
+frustration and no positive gain at all. In contrast, by tending to the
+code, the programmer is making forward progress at all times (the code
+is constantly improving) even if the bug is not immediately found.
+At the end of ten hours, the programmer can at least feel that the code
+is \dq{ten hours better}, whereas the debugger freak will likely feel
+defeated.
+All this makes code tending better psychologically as well as a more
+efficient approach to debugging.
+
+I call this technique wholistic debugging, for it is like the
+difference between conventional and wholistic medicine.\xx{wholistic}{medicine}
+Go to a
+conventional doctor with a headache and he might send off for head X-rays,
+perform allergy tests and perform many other
+debugging activities. Go to a wholistic doctor with the same problem and
+he might look to see if you are fit, assess your mental health, and ask you
+if your marriage is working. Both approaches are appropriate at different
+times. In programming, the wholistic approach is not used enough.
+
+\section{Examples of FunnelWeb Applications}
+\xx{FunnelWeb}{example applications}\xx{FunnelWeb}{applications}
+
+Despite (or perhaps because of) its flexibility and simplicity,
+FunnelWeb can be applied to quite a number of different
+text processing and documenting problems. This section describes some of
+the more interesting real problems that FunnelWeb has solved.
+
+\subsection{Analyzing the Monster Postscript Header File}
+\xx{monster file}{postscript}
+
+During my Ph.D. candidature, I determined at one point that it would be
+very desirable to automatically insert diagrams from the \i{MacDraw}\x{MacDraw}
+program on my Macintosh into
+\TeX{}\x{TeX}
+\p{insert}ions in my thesis.\xx{PhD}{thesis} This would allow diagrams to float
+around with the text and be printed automatically rather than having to be
+printed separately and stuck in with real glue. On the face of it, the
+problem seemed inherently solvable as the Macintosh\x{Macintosh}
+could generate PostScript\x{PostScript}
+for each diagram and this PostScript could presumably be inserted into the
+PostScript generated using \TeX{}.
+
+The only trouble was that the Macintosh PostScript code for the diagrams
+relied on an Apple PostScript header file.\xx{postscript}{header file}
+This meant that the header file
+had to be included at the start of the \TeX{} PostScript if the inserted
+PostScript for the diagrams was to work.
+Unfortunately, merely including the header file at the top didn't work, and
+it turned out that a rather detailed analysis of some parts of the Apple
+header file was required in order to perform the necessary surgery on the
+header file to make it work. This analysis was severely aggravated by the
+fact that the PostScript header file was virtually unreadable. Basically
+it was about 50K of interwoven
+definitions, that looked as if it had been run through a word processor.
+There was no way that the code could be understood clearly without some
+kind of reformatting. Two other aspects of the problem further complicated
+the analysis:
+
+\begin{itemize}
+
+\item The definitions of interest (\ie{}the ones causing the problems)
+were scattered throughout the file.
+
+\item Many definitions could not be moved. For one or more reasons
+(\eg{}to keep a definition within the activation of a particular
+dictionary \p{begin} and \p{end}) it would have been unwise to move the
+definitions of interest to the same point in the file.
+
+\end{itemize}
+
+In fact the file was so messy and complicated that, as a rule, it had to
+be handled with kid gloves. It would have been unwise to re-arrange
+the definitions or to insert comments.
+
+To my surprise, FunnelWeb provided an unexpected solution to
+the problem. First I replaced all occurrences of the \p{@} in the
+header file with \p{@@}. Second, I placed the entire header file
+in a FunnelWeb macro definition connected to a product file. I then
+processed the file and checked to make sure that the product file
+was identical to the original file.
+By doing all this I had placed the
+header file under FunnelWeb control. I then left the
+macro definition largely untouched, but replaced the PostScript
+definitions of
+interest with FunnelWeb macro calls, moving the actual PostScript
+definitions into FunnelWeb macro definitions at the end of the FunnelWeb
+file.
+
+\begin{verbatim}
+@O@<LaserHeader.ps@>==@{@-
+Unreadable Postscript code
+@<Print routine@>
+Unreadable Postscript code
+@<Zap routine@>
+Unreadable Postscript code
+@}
+
+@A This routine looks as if it does this, but really is does that,
+blah, blah blah.
+
+@$@<Print routine@>==@{@-
+/print { push pop pop push turn around and jump up and down and print it} def
+@}
+
+@A This routine zaps the...
+
+@$@<Zap routine@>==@{@-
+/zap { push pop pop push turn around and jump up and down and print it} def
+@}
+\end{verbatim}
+
+Use of FunnelWeb meant that I was able to pluck out the definitions of interest
+(a very small part of the whole file) and collect them as a group at the end
+of the file where they could be studied.
+Because each definition was safely contained in a macro, it was possible to
+write a detailed commentary of each routine without fear of affecting the
+final PostScript code in any way at all. Once this analysis was completed,
+it was possible to perform surgery on the offending PostScript definitions
+in an extremely controlled way. In particular, the FunnelWeb input file
+served as a repository for all the different versions of particular routines
+that were tried in order to get the definitions to work. A new (\b{Z}ero)
+macro was created for each version of each definition, and a commentary of how
+it performed added above it.
+
+This case demonstrates that
+FunnelWeb is an extremely powerful tool for dissecting and
+documenting cryptic text files.\xx{cryptic}{text files}
+Through the use of macros, particular
+parts of the file can be isolated and discussed without affecting the
+final product file in any way. In the example above, only a small part of the
+file was analysed, the rest being left as a blob, but in the general case,
+a cryptic text file could be inserted into FunnelWeb and then incrementally
+dissected (and possibly modified) until the result is a fully documented
+literate program. That this can be done without affecting the actual
+product file demonstrates the high degree of descriptive control that
+FunnelWeb provides.
+
+\subsection{Making Ada ADTs more A}
+\x{Ada}\x{abstract data type}\x{ADT}
+
+Like many modern programming languages, Ada provides mechanisms for hiding
+information and structure. In particular, Ada provides a \newterm{package}
+facility that allows the programmer to declare objects in a
+package definition and define them in a corresponding package body.
+This works well
+for functions and procedures. However, in the case of types, implementation
+issues (in particular, the need to know the size of exported types) have
+led the designers of Ada to force the placement of
+private type definitions in the definition package rather than the
+implementation package. This means that some implementation details
+are present in the package definition for all to see. While not actually
+dangerous (the user of the package cannot make use of the information
+without recourse to \dq{Chapter~13} of the Ada Language Reference
+Manual\paper{DOD83}), this aspect of Ada is certainly unpleasant.
+
+During the development of some Ada programs, FunnelWeb was used to solve
+this problem. Instead of creating a separate file for the package
+specification and package body, a single FunnelWeb file was created containing
+two sections, one for the each package part. The \dq{private} part of the
+package specification was then moved (using a FunnelWeb macro definition)
+to the section describing the package body. Readers who wished only to read
+the package specification could read only the first part, which contained
+a fully documented description not containing the private definition.
+
+\subsection{Multiple Language Systems}
+\xx{multiple}{languages}
+
+With the prevalence of open systems\x{open systems}
+and multi-vendor computing, it is
+often necessary to construct systems consisting of programs written in
+a number of different programming languages for a number of different
+systems. For example, a particular functionality might be implemented by a
+shellscript
+(invoked by the user) that calls a C~program that makes a network connection
+to a Pascal program that queries a database. Quite often all these programs
+must conspire closely to execute their function. In the normal case, they
+must be written separately. FunnelWeb allows them to be written as a
+whole.
+
+By creating a single FunnelWeb file that creates many product files in
+different languages, the programmer can describe the interaction between
+the different programs in any manner desired. Furthermore, because
+the different product files are all created in the same \dq{text space}
+(\ie{}in a single FunnelWeb file), it is easy for them to share information.
+
+For example, in one real application FunnelWeb was used to create a
+system for printing files\xx{printing}{system}
+on a laser printer\xx{laser}{printer}
+connected to a remote Vax
+Unix machine from a local Vax VMS
+machine. The system consisted of two files: a VMS DCL command procedure
+to run on the local node, and a Unix shellscript to run on the remote
+node. The user, by giving the print command, invoked the local VMS
+command procedure, which in turn fired up the remote Unix shellscript. The
+two scripts then cooperated to transfer the files to be printed and print
+them.
+
+In addition to its usual documentation powers, FunnelWeb assisted in the
+creation of this system in two special ways. First, it allowed pieces of
+code from the two different command procedures to be partially interwoven in a
+description of their interaction. This is just not possible with comments.
+Second, it facilitated the use of shared information. For example, under
+some conditions, each file to be printed would be renamed and copied to the
+remote system using a particular constant filename (\eg{}\dqp{printfile.tmp}).
+FunnelWeb allowed this constant filename to be included in a single macro
+definition which was invoked in the definition of each of the scripts. This
+ensured that the two scripts used the same name.
+
+\begin{verbatim}
+@A The following macro contains the temporary file name used to allow the
+two shellscripts to transfer each file to be printed.
+
+@$@<printfile@>@M==@{printme.txt@}
+
+@A Here are the scripts for the local VMS node and the remote UNIX node.
+
+@O@<vmscommandprocedure.com@>==@{@-
+DCL commands
+copy @<printfile@> unixnode::
+DCL commands
+@}
+
+@O@<unixshellscript@>==@{@-
+unix commands
+print @<printfile@>
+unix commands
+@}
+\end{verbatim}
+
+In the case of the printing system, the entire system was described and
+defined in a single FunnelWeb \p{.fw} file. In larger systems containing
+many FunnelWeb \p{.fw} files for many different modules in many different
+languages, the same trick can be pulled by placing FunnelWeb macro
+definitions for shared values into FunnelWeb include files. For example,
+a suite of implementations of network nodes, with each implementation being
+in a different programming language for a different target machine, could
+all share a table of configuration constants defined in macros in a
+FunnelWeb include file.
+
+In summary, FunnelWeb's macro and include file mechanisms provide
+a simple way for programs written in different languages to share
+information. This reduces redundancy between the systems and hence the
+chance of inconsistencies arising.\x{sharing information}
+
+\subsection{The Case of the Small Function}
+\xx{small}{functions}
+
+Often, when programming, there is a need for a
+code abstraction\xx{code}{abstraction} facility
+that operates at the text level. If the statement \dqp{a:=3;} occurs often,
+it may be best simply to repeat it verbatim. If a sequence of one hundred
+statements is repeated often, it is normal to remove the code to a function
+and replace the occurrences by a function call.
+However, in between these two extremes are cases where a particular sequence
+of code is long enough and appears often enough to be troublesome, but which
+is bound so messily to its environment as to make a function call
+cumbersome.
+
+For example, the following line of statements (referring to five variables
+declared \i{local} to a function) might appear ten times in
+a function:
+
+\begin{verbatim}
+a=b*3.14159; c=d % 256; e=e+1;
+\end{verbatim}
+
+Now the \dq{normal} rule of programming says that these statements should be
+placed in a procedure (also called a \dq{function} in the C programming language
+used in this example),
+but here five local variables are used. Use of a procedure
+(function) would result in a procedure definition looking something like:
+
+\begin{verbatim}
+void frobit(a,b,c,d,e)
+float *a,b;
+int *c,d;
+unsigned *e;
+{*a=b << 8; *c=d % 256; *e=*e+1;}
+\end{verbatim}
+
+and a procedure call something like
+
+\begin{verbatim}
+frobit(&a,b,&c,d,&e);
+\end{verbatim}
+
+This might be workable in a language that allowed formal parameters to be
+specified to be bound only to particular variables. Similarly, it might
+be possible to avoid the parameter list in languages that support
+local procedures that can access non-local variables (such as
+Pascal\x{Pascal}).
+However, in our example here, in the C programming language, these options
+are not available, and so we must either create a function with five
+parameters,
+or use the C macro preprocessor\xx{preprocessor}{C}
+(the best solution). FunnelWeb provides the
+same macro facility for languages that do not have a built-in
+preprocessor.
+
+In particularly speed-stressed applications, the programmer may be
+reluctant to remove code to a procedure because of the procedure-call
+overhead.\xx{procedure call}{overhead}
+FunnelWeb macros can help there too.
+
+In summary, there sometimes arises in programming situations where the
+cost of defining a procedure is higher than the benefits it will bestow.
+Common reasons for this are the run-time procedure overhead and
+the messy binding problems\xx{binding}{problems}
+caused by removing target code from its target context. FunnelWeb
+can help in these situations by allowing the programmer to define a text
+macro. This avoids all the problems and provides an additional incentive
+for the programmer to describe the piece of code so isolated.
+
+\subsection{When Comments are Bad}
+\xx{comments}{abuse}\xx{eliminating}{comments}
+
+In the \dq{good old days}\x{good old days}
+of small machine memories and interpreted BASIC,\x{BASIC}
+programmers would eliminate the \dqp{REM} statements\xx{REM}{statement}
+(comments) from their
+BASIC programs so as to save space and increase execution speed. Whilst
+this was obviously an appalling programming practice, the small memories
+and slow microprocessors often made this tempting, if not necessary.
+
+Thankfully, times have changed since then,
+and most code is now compiled
+rather than interpreted. However, from time to time one still runs into
+an environment or situation, or special-purpose language, where comments
+are either unavailable (no comment feature) or undesirable. Here
+FunnelWeb can be used to fully document the code without resulting in any
+comments in the final code at all. For example:\xx{header}{files}
+
+\begin{itemize}
+
+\item Comments in frequently used \p{.h} header files in C
+programs\xx{C}{header} can
+have a significant impact on compilation speed. Often such header files
+are fairly cryptic and really ought to be well commented, but their authors
+are reluctant to.
+
+\item Comments are undesirable in PostScript\x{postscript}
+header files that must be
+transferred repeatedly along communications channels (\eg{}the Apple
+Macintosh LaserWriter header file).
+
+\item Interpreted programs in embedded systems.
+
+\item Hand written machine code in hex dump form could be commented.
+
+\item A programmer may wish to annotate a text data file containing lists
+of numbers that is to be fed into a statistical program that does not
+provide any comment facility for its input file.
+
+\end{itemize}
+
+In all these situations, FunnelWeb allows full integrated documentation
+without any impact on the final code.
+
+\subsection{Documents That Share Text}
+\xx{sharing}{text}
+
+FunnelWeb is very useful when preparing multiple documents that must
+share large slabs of identical text that are being constantly modified.
+
+For example someone preparing two slightly different user manuals for two
+slightly different audiences might want the manuals to share
+large slabs of text, while still allowing differences between them.
+The following example shows how this can be done. The code is cluttered,
+but this clutter would not be a problem if the lumps of text were moderately
+large.
+
+\begin{verbatim}
+@O@<manual1.txt@>==@{@<M1@>@+@}
+@O@<manual2.txt@>==@{@<M2@>@+@}
+
+@$@<M1@>+=@{@<T1@>@}
+@$@<M2@>+=@{@<T1@>@}
+@$@<T1@>@M==@{First lump of text shared by both documents.@+@}
+
+@$@<M1@>+=@{Text for first document@+@}
+@$@<M2@>+=@{Text for second document@+@}
+
+@$@<M1@>+=@{@<T2@>@}
+@$@<M2@>+=@{@<T2@>@}
+@$@<T2@>@M==@{Second lump of text shared by both documents.@+@}
+\end{verbatim}
+
+An alternative approach, which might work better in situations where there
+are many small differences between the two documents rather than a few large
+ones, is to define a macro with two arguments, one for each product
+file document.
+Write the document from top to bottom, but place all stretches that
+differ between the two documents in a macro call.\xx{annual}{report}
+
+\begin{verbatim}
+@! Set the definition of @#D to
+@! @1 to create the shareholders report.
+@! @2 to create the customers report.
+@$@#D@(@2@)@M==@{@1@}
+
+@O@<report.txt@>==@{@-
+1992 ANNUAL REPORT TO @#D@(Shareholders@,Customers@)
+======================@#D@(============@,=========@)
+This has been a very good year for The Very Big Corporation of America.
+With your help, we have been able to successfully
+@#D@(@"screw the customers for every cent they have@"@,
+ @"knock the shareholders into submission to bring you lower prices@"@).
+With gross earnings approaching six trillion dollars, we have been able to
+@#D@(@"increase dividends@"@,
+ @"lower prices@"@).
+We expect to have an even better year next year.
+@}
+\end{verbatim}
+
+One application where text sharing can be particularly useful is in the
+preparation of computer documentation\xx{examples}{documentation}
+containing examples. For example,
+a book describing a new programming language might be full of examples
+of small programs written in the language which the user might want to try
+without having to type them all in. The \dq{default} approach of keeping
+a copy of the examples in the text of the book and another copy in
+separate files is cumbersome and error prone, because both files have to
+be updated whenever an example is changed. A more sophisticated approach is
+to store each example in a separate file, and then use the \dq{include file}
+facility of the word processor to include each example in the text.
+This is a better solution, but suffers from a few drawbacks. First, when
+editing the book in a word processor, the
+examples in the book will not be directly accessible or visible. To see an
+example, the writer would have to open the file containing the example in
+a separate window. This could become tedious if the text contained many
+examples, as many texts do. Furthermore, there is a risk that some example
+files will be included in the wrong place. Second, because the book is
+dependent on the included files, the book will end up consisting of a
+directory of a hundred or more files instead of just a few.
+
+An alternative solution is to construct a single FunnelWeb \p{.fw}
+file that, when processed, produces both the book file and the example files.
+This solution assumes that the book consists of a text file containing
+commands for a typesetter such as \TeX{}.
+
+\begin{verbatim}
+@O@<Book.tex@>==@{@#B@}
+
+@$@#B+=@{@-
+The first step to learning the object oriented AdaCgol++ language is to examine
+a hello world program.
+
+\start{verbatim}
+@<Ex1@>
+\finish{verbatim}
+@}
+
+@$@<Ex1@>==@{read iopack@+Enter !World~! !Hello~! ex pr flu X[1]@}
+@O@<Ex1.c@>==@{@<Ex1@>@}
+
+@$@#B+=@{@-
+To understand the program, think of the execution state as a plate of cheese...
+@}
+\end{verbatim}
+
+Most of the file will consist of part definitions of the additive
+macro \p{@\#B}. The definition is \dq{broken} to allow a macro definition,
+wherever an example appears.
+
+The example above is a little messy because FunnelWeb does not allow
+macros connected to product files to be called, and it does not have
+text expressions that write to an product file as well as evaluating to text.
+Nevertheless, it presents a fairly clean solution to the problem of keeping
+the example programs in a computing text up to date.
+
+\subsection{Generics}
+\xx{generics}{fudging}
+
+It is well known that generics in programming languages are closely aligned
+with textual substitution. In fact, a good way to understand the generic
+facility of a new programming language is to ask oneself the question
+\dq{In what way does this generic facility differ from simple text
+substitution?} The differences, if any, typically have to do with
+the difference in scoping between textual and intelligent substitution
+and whether the generic code is shared or copied by the implementation.
+In most cases the differences are quite minor.
+
+Because generic facilities are so closely aligned with text substitution,
+it is possible to use FunnelWeb's parameterized macros to provide generics
+in programming languages that do not support generics. Simply write a
+FunnelWeb macro whose parameters are the parameters of the generic and
+whose body is the generic object.
+
+The following FunnelWeb file gives an example of a fully worked Vax
+Pascal\x{Pascal}
+generic set package implemented using FunnelWeb parameterized macros.
+The package was written by Barry Dwyer\xn{Barry}{Dwyer}
+of the Computer Science Department
+of the University of Adelaide\xx{University}{Adelaide}
+in 1987 and was emailed to me on
+11~November 1987. The generic package provides a set
+abstraction\xx{set}{abstraction} implemented
+using linked lists. Note the clever use of the instantiation parameters in
+type, function, and procedure names.
+
+\begin{verbatim}
+@$@<Generic Set Module@>@(@2@)==@{@-
+@! @1 is the base type, @2 is the set type.
+[inherit ('@1'), environment ('@2')]
+
+module @2;
+
+type @2 = ^@2Record;
+ @2Record = record
+ Member: @1;
+ Next: @2;
+ end;
+
+procedure Null@2 (var Result: @2);
+begin new (Result);
+Result^.Member := (- MaxInt)::@1;
+Result^.Next := nil end;
+
+function IsNull@2 (S: @2): boolean;
+begin IsNull@2 := S^.Member::integer = - MaxInt end;
+
+procedure ForEach@1 (S: @2; procedure DoIt (i: @1));
+var ThisS, NextS: @2;
+begin ThisS := S;
+while ThisS^.Member::integer <> - MaxInt do
+ begin NextS := ThisS^.Next;
+ DoIt (ThisS^.Member);
+ ThisS := NextS end;
+end;
+
+function First@1 (S: @2): @1;
+begin First@1 := S^.Member end;
+
+function Is@1InSet (i: @1; S: @2): boolean;
+ procedure TestEquals (j: @1);
+ begin if Equal@1 (i, j) then Is@1InSet := true; end;
+begin Is@1InSet := false; ForEach@1 (S, TestEquals); end;
+
+function Includes@2 (S1, S2: @2): boolean;
+var Result: boolean;
+ procedure TestIfInS1 (i: @1);
+ begin if Result then if not Is@1InSet (i, S1) then Result := false; end;
+begin Result := true;
+ForEach@1 (S2, TestIfInS1);
+Includes@2 := Result end;
+
+function Disjoint@2s (S1, S2: @2): boolean;
+var Result: boolean;
+ procedure TestIfInS1 (i: @1);
+ begin if Result then if Is@1InSet (i, S1) then Result := false; end;
+begin Result := true;
+ForEach@1 (S2, TestIfInS1);
+Disjoint@2s := Result end;
+
+function Equal@2 (S1, S2: @2): boolean;
+begin
+Equal@2 := Includes@2 (S1, S2) and Includes@2 (S2, S1);
+end;
+
+procedure Insert@1 (i: @1; var S: @2);
+var This, Pred, Succ: @2;
+begin
+if not Is@1InSet (i, S) then
+ begin
+ Pred := nil; Succ := S;
+ while Succ^.Member::integer > i::integer do begin
+ Pred := Succ; Succ := Succ^.Next end;
+ if Succ^.Member::integer < i::integer then begin
+ new (This); This^.Next := Succ; This^.Member := i;
+ if Pred <> nil then Pred^.Next := This else S := This;
+ end;
+ end;
+end;
+
+procedure Insert@1s (S1: @2; var S2: @2);
+var This, Pred, Succ: @2;
+ procedure Add@1 (i: @1);
+ begin Insert@1 (i, S2) end;
+begin
+ForEach@1 (S1, Add@1);
+end;
+
+procedure Remove@1 (i: @1; var S: @2);
+var Pred, This: @2;
+begin
+Pred := nil; This := S;
+while not Equal@1 (This^.Member, i) do begin
+ Pred := This; This := This^.Next end;
+if Pred <> nil then Pred^.Next := This^.Next else S := This^.Next;
+Dispose (This);
+end;
+
+procedure Dispose@2 (var S: @2);
+var Old: @2;
+begin
+while S <> nil do begin Old := S; S := S^.Next; Dispose (Old) end;
+end;
+
+end.
+@}
+
+@O@<NaryTreeSet.pas@>==@{@-
+ @<Generic Set Module@>@(@"NaryTree@"@,@"NaryTreeSet@"@)@}
+@O@<NaryTreeSetSet.pas@>==@{@-
+ @<Generic Set Module@>@(@"NaryTreeSet@"@,@"NaryTreeSetSet@"@)@}
+\end{verbatim}
+
+A great advantage of the approach reflected in the above example is that
+it allows the programmer to construct a generic object in a language that
+does not supply generics, \i{with complete typesafety.}\xx{typesafe}{generics}
+This contrasts to the
+approach that might be used in a language such as C where the programmer
+might choose to construct a \dq{generic} package by parameterizing a
+package with pointers to \p{void}. The resulting package is
+powerful but extremely untypesafe. Such a generic list package is used in the
+code of FunnelWeb itself and caused no end of problems, as the compiler had
+no way of telling if pointers to the correctly typed object were being
+handed to the correct list-object/function combination.
+
+The major disadvantage of the text generic approach is that it causes the
+code of the generic object to be duplicated once for each instantiation.
+Depending on the number and size of the instantiations, this may or may not
+be acceptable.
+
+Where the duplication of code is unacceptable, a hybrid approach may be
+taken. As in the C~example, the programmer could write
+a single generic package
+using pointers to \p{void} or some other untypesafe mechanism.
+Then the programmer
+creates a FunnelWeb generic package whose functions do nothing
+more than call the functions of the untypesafe package, and whose types do
+nothing more than contain the types of the untypesafe package. This solution
+involves the use of untypesafe programming, but this is a one-off
+and if done carefully and correctly, the result can be
+a typesafe generic package involving minimal code duplication.
+
+\section{Summary}
+
+This chapter has described some of the finer aspects of the use of FunnelWeb.
+Throughout, the power and danger of FunnelWeb as a general text-rearranging
+preprocessor has been emphasised. FunnelWeb can be used both to make programs
+more readable or more obscure. It is up to the programmer to ensure that
+FunnelWeb is used properly.
+
+%==============================================================================%
+% End of Ch2.tex %
+%==============================================================================%
diff --git a/web/funnelAC/userman/u_ch3.tex b/web/funnelAC/userman/u_ch3.tex
new file mode 100644
index 0000000000..7669732fc8
--- /dev/null
+++ b/web/funnelAC/userman/u_ch3.tex
@@ -0,0 +1,2986 @@
+%==============================================================================%
+% Start of Ch3.tex %
+%==============================================================================%
+%
+% Copyright
+% ---------
+% Copyright (C) 1992 Ross N. Williams.
+% This file contains a chapter of the FunnelWeb User's Manual.
+% See the main TeX file for this manual for further information.
+%
+%==============================================================================%
+
+\chapter{FunnelWeb Definition}
+\label{chapdefinition}\xx{FunnelWeb}{definition}
+
+\section{Introduction}
+
+This purpose of this chapter is to provide a complete and consistent
+definition of the FunnelWeb input language and the behaviour of the
+FunnelWeb program. Usually, a chapter such as this is called a
+\dq{reference manual}, but this chapter is intended to go further
+by actually defining the language and program. This chapter takes
+precedence over all other chapters and all implementations of FunnelWeb.
+If an implementation contradicts this chapter, then the implementation
+is wrong.
+
+This is the chapter that you should turn if you find yourself asking a
+specific question about a specific aspect of FunnelWeb. In many
+cases it will be convenient to access this chapter through the index.
+
+\section{Notation}
+\x{notation}
+
+A particular variant of EBNF\xx{EBNF}{syntax}
+(Extended Bachus Naur Form) will be used to
+describe the FunnelWeb syntax. In this variant, literal strings are
+delimited by double quotes (\eg{}\p{"string"}), optional constructs by
+square brackets (\eg{}\p{[optional]}), and constructs repeated zero or
+more times by braces (\eg{}\p{\{zeroormore\}}). Constructs to be repeated
+a fixed number of times are enclosed in braces followed by a decimal
+number indicating the number of times to be repeated
+(\eg{}\p{\{sixtimes\}6}). Constructs to be
+repeated one or more times are
+enclosed in braces and followed by a \p{+} (\eg{}\p{\{oneormore\}+}).
+The traditional BNF \dqp{::=}
+is replaced by the visually simpler \dqp{=}. The traditional BNF angle
+brackets are abandoned.
+
+Although FunnelWeb allows the special character to be changed using the
+construct \dq{$<$special$>$=}, use of \dq{$<$special$>$} to refer to
+FunnelWeb's special character is cumbersome and abstract. To simplify
+the presentation, the default special character \dqp{@} is used throughout
+this chapter to represent the special character.
+
+\section{Terminology}
+\x{terminology}
+
+A specific terminology has arisen for dealing with FunnelWeb. Some
+particularly useful examples are:
+
+\narrowthing{Journal file:}{An output file containing
+a copy of the output sent to
+the user's console during an invocation of FunnelWeb. In other systems,
+this file is sometimes called a \dq{log file}.}
+
+\narrowthing{Product file:}{An output file, generated by the Tangle
+component of
+FunnelWeb, that contains the expansion of the macros in the input
+file.\footnote{Other names considered for this were:
+generated file, expanded file, result file, program file, and tangle file.}}
+
+A complete list of all the special FunnelWeb terminology appears in the
+glossary. Be sure to refer to it if any of the terms used are unclear.
+
+\section{An Architectural Overview}
+\xx{semantic}{architecture}\xx{FunnelWeb}{overview}
+
+An understanding of the internals of FunnelWeb assists with understanding
+its operation (\figphases{}).\xx{execution}{phases}
+
+During a single run, FunnelWeb reads and
+processes a single input file called the \newterm{input file} or
+the \newterm{FunnelWeb file}. The file is processed by passing it through
+a series of stages called \newterm{phases}. The result is that some
+\newterm{output files} are generated.
+A \newterm{journal file} is generated containing a copy of the messages that
+appear on the console during the FunnelWeb run. A \newterm{listing file}
+is created containing a summary of the run, including any error messages.
+A \newterm{documentation} file is generated containing typesetter commands
+that when fed into a typesetter program will result in
+printed documentation. Finally, one or more \newterm{product files}
+are generated containing the result of unscrambling the macro definitions
+of the input file.
+
+These files need not all be generated on any particular FunnelWeb run.
+Whether each output file appears is controlled by command line options.
+
+\begin{figure}[htbp]
+\begin{verbatim}
+
+ .fw Input File (FunnelWeb file)
+ V
+ +---------+ \
+ | Scanner | |
+ +---------+ |
+ V |
+ +--------+ |
+ | Parser | |
+ +--------+ |
+ V |
+ +----------+ >-------+------------+
+ | Analyser | | | |
+ +----------+ | | |
+ V | | |
+ +-----------+------------+ | V V
+ V V | | |
+ +--------+ +-------+ | | |
+ | Tangle | | Weave | | | |
+ +--------+ +-------+ / | |
+ | | | |
+ V V V V
+ Product Files Documentation File Listing File Journal File
+
+\end{verbatim}
+\mylabel{\figphases{}: FunnelWeb's processing phases.}{%
+%
+FunnelWeb processes each input file in a sequence of phases.
+If an error occurs during a phase, no subsequent phases are executed.
+%
+}
+\end{figure}
+
+The phases are briefly described below.
+
+\narrowthing{The Scanner}{reads\x{scanner} the input file, expands
+and reads in include files,
+scans the input stream, processes pragmas and typesetter directives,
+and parses all the
+FunnelWeb special sequences. The result is a list of tokens that
+is handed to the parser.}
+
+\narrowthing{The Parser}{reads\x{parser}
+the scanner's token list and parses it, constructing a
+document list\xx{document}{list} and a macro
+table.\xx{macro}{table} which are passed to later phases.}
+
+\narrowthing{The Analyser}{examines\x{analyser}
+the macro table generated by the parser
+and performs a number of checks of the macro structures
+that the parser could not make on its single pass.
+For example, the
+analyser detects and flags unused macros and recursive macros. The
+analyser forms the final stage of FunnelWeb's front-end processing.}
+
+\narrowthing{Tangle}{expands certain macros in the macro table
+to generate\x{tangle} one or more product files.}
+
+\narrowthing{Weave}{uses the document list to generate\x{weave}
+a documentation file.}
+
+A single run through these phases constitutes a single invocation of
+\newterm{FunnelWeb proper}. Most invocations of the
+\newterm{FunnelWeb program}
+will consist only of a single execution of FunnelWeb proper. However,
+FunnelWeb also provides a command shell that provides many useful commands,
+including a command to invoke FunnelWeb proper. Discussion of the command
+shell is deferred until Section~\ref{commandshell}.
+
+\section{Diagnostics}
+\label{diagnostics}\x{diagnostics}
+
+During execution, FunnelWeb proceeds cautiously with each of its phases,
+only proceeding with the next phase if the previous phase has been
+successful. This means that, when debugging
+a FunnelWeb file, you may find that the number of errors \i{increases}
+after you fix some of them, as you will be exposing yourself to the
+next FunnelWeb phase.
+
+FunnelWeb employs five levels of diagnostics\xx{diagnostics}{levels of}
+at different levels of
+severity.\x{severity}
+Severity is defined in terms of the level of activity at which the
+diagnostic causes FunnelWeb to abort.
+
+\narrowthing{Warning:}{A warning\xx{warning}{severity}
+does not cause FunnelWeb to terminate or
+curtail its operation in any way, but serves merely to warn the user of
+particular conditions that might be symptomatic of deeper problems.}
+
+\narrowthing{Error:}{An\xx{error}{severity} error causes
+FunnelWeb to terminate processing of the
+current input file at the end of the current phase. For example, if an
+error occurs during scanning, FunnelWeb will continue scanning (and possibly
+generate further scanning diagnostics), but will not invoke the parser.}
+
+\narrowthing{Severe Error:}{A\xx{severe}{severity} severe error
+(or \dq{severe} for short) is the same
+as an error except that FunnelWeb terminates the current phase immediately.}
+
+\narrowthing{Fatal Error:}{A\xx{fatal}{severity} fatal error
+causes FunnelWeb not only to terminate
+the current phase and run immediately, but also to terminate total
+FunnelWeb processing immediately. A severe error will not cause a
+FunnelWeb script to terminate, but a fatal error will. A fatal error
+causes FunnelWeb to return control to the operating system.}
+
+\narrowthing{Assertion Error:}{An\xx{assertion}{severity}
+assertion error occurs if FunnelWeb detects
+an internal inconsistency, in which case FunnelWeb terminates immediately
+and ungracefully. Such
+an error can occur only if there are bugs in FunnelWeb. With luck, such
+errors will be extremely rare.}
+
+FunnelWeb indicates the level of severity of each diagnostic that it issues
+by starting each diagnostic either with the full name of the severity level
+or with just the first letter of the severity level followed by a colon.
+
+FunnelWeb conveys the presence or absence of diagnostics at the operating
+system level by returning \p{EXIT\_SUCCESS}\xx{return}{status}
+status if no
+diagnostics occurred during the run and \p{EXIT\_FAILURE} status
+if one or more
+diagnostics (including warnings)
+occurred during the run.\footnote{From
+the symbols of the ANSI standard C library \p{stdlib.h}.
+See \paper{Kernighan88}, p.252.}
+
+
+\section{Typesetter Independence}
+\xx{typesetter}{independence}
+
+One of the design goals of FunnelWeb was to provide a \i{target-language}
+independent literate programming system. This goal has been achieved
+simply by treating the text written to the product file
+as homogeneous and typesetting
+it in \p{tt font}. A secondary goal was to provide
+a \i{typesetter} independent literate programming
+system. By this is meant that it be possible to create FunnelWeb input files
+that do not contain typesetter-specific commands.
+To a lesser extent this goal has also been achieved.
+
+The difficulty with providing typesetter-independent typesetting is that
+each desired typesetting feature must be recreated in a
+typesetter-independent FunnelWeb typesetting construct that FunnelWeb can
+translate into whatever typesetting language is being targeted by Weave.
+Taken to the extreme, this would result in FunnelWeb providing the full
+syntactic and semantic power of \TeX{}, but with a more generic,
+FunnelWeb-specific syntax. This was unfeasible in the time available, and
+undesirable as well.
+
+The compromise struck in the FunnelWeb design is to provide a set of
+primitive typesetter-independent typesetting features that are implemented
+by FunnelWeb. These are the \newterm{typesetter directives}.
+If the user is prepared to restrict to these directives,
+then the user's
+FunnelWeb document will be both target-language and typesetter independent.
+However, if the user wishes to use the more sophisticated features of the
+target typesetting system, the user can specify the typesetter
+in a \dqp{typesetter} pragma and then place typesetter commands
+in the free text
+of the FunnelWeb document where they will be passed verbatim to the
+documentation file. The choice of the trade-off between typesetter
+independence and typesetting power is left to the user.
+
+This said, experience with FunnelWeb V1 over a three year period,
+indicates that the typesetting facilities provided by FunnelWeb are
+sufficient for most documentation.
+
+\section{Command Line Interface}
+\xx{command line}{interface}
+
+\subsection{Invoking FunnelWeb}
+\xx{FunnelWeb}{invoking}\xx{FunnelWeb}{running}
+
+When a user invokes FunnelWeb at the operating system command level, the
+user must provide a command line instructing FunnelWeb what to do. Typically
+an operating system command line consists of a \i{verb} indicating that a
+particular program should be run, followed by a list of options. For example:
+
+\begin{verbatim}
+$ rename file1 file2
+\end{verbatim}
+
+In this case, the verb is \p{rename} and the command line options are
+\p{file1 file2}. The entire command line begins with the \p{\$} and ends with
+the \p{2}.
+
+Operating systems differ greatly in the depth with which
+they process their command\xx{command line}{processing}
+lines, ranging from systems that simply pass the entire command line string
+to the invoked program (\eg{}MSDOS) through to systems that perform complete
+command line parsing (\eg{}VMS). Syntax conventions vary considerably.
+
+So as to achieve maximum portability and consistency of invocation across
+different platforms, FunnelWeb reads its command line as a raw string and
+performs all its own parsing.\xx{command line}{parsing}
+This is portable because, at the very least, all
+operating systems allow invoked programs access to the raw command line.
+
+The command verb used to invoke FunnelWeb should be
+\dqp{fw}.\xx{fw}{command verb}
+
+\begin{verbatim}
+FunnelWeb_verb = "fw"
+\end{verbatim}
+
+If this verb is not available, some alternatives are
+\dqp{funweb}, \dqp{fun}, and \dqp{funnelweb}.
+The verbs \p{web} or \p{fweb} should be avoided
+as they are the names of other literate programming systems.
+
+\subsection{Command Line Arguments}
+\xx{command line}{argument}\xx{syntax}{command line}
+
+Following the verb is the body of the command line which
+FunnelWeb parses into
+zero or more \newterm{arguments} separated by runs
+of one or more blanks.
+
+\begin{verbatim}
+FunnelWeb_command_line = FunnelWeb_verb {{" "}+ argument}
+\end{verbatim}
+
+Because some operating systems convert
+their command line to upper case before handing it to the invoked program,
+FunnelWeb has been constructed so as to be \i{insensitive} to the case
+of its command line arguments.\xx{case}{dependence} However, when
+dealing internally with arguments, FunnelWeb \i{preserves} the case of
+its command line arguments so that it will be able to operate with
+operating systems (such as Unix\x{Unix})
+whose file names are case dependent.
+
+A valid FunnelWeb argument consists of a
+\newterm{sign}, an identifying \newterm{letter}, and an
+optional
+\newterm{string} with no spaces separating
+them.\xx{command line options}{syntax}\xx{options}{syntax}
+
+\begin{verbatim}
+argument = sign id_letter [non_blank_string]
+sign = "+" | "-" | "="
+id_letter = "B" | "C" | "D" | "F" | "H" |"I" | "J" | "K" |
+ "L" | "O" | "Q" | "S" | "T" | "W" | "X"
+\end{verbatim}
+
+In addition there is a special form of argument that does not begin with
+a sign.
+
+\begin{verbatim}
+argument = non_blank_string_not_beginning_with_+_=_or_-
+\end{verbatim}
+
+This form is exactly equivalent to the same string with \dqp{+F}
+prepended to it.
+
+The semantic effect of these arguments is
+defined in terms of \newterm{options} which are the
+internal parameters of FunnelWeb
+and which correspond closely with the set of legal command line arguments.
+FunnelWeb has a predefined set of options each identified
+by an identifying letter having two attributes: a \i{string}, and a
+\i{boolean}. The boolean determines whether an option is turned
+\i{on} or \i{off}. The string contains additional information
+depending on the option.
+
+When FunnelWeb starts up, its options have predefined default values.
+FunnelWeb then parses its command line sequentially from
+left to right
+executing the effect of each argument on the argument's corresponding
+option. The sign and the
+string components of the argument are processed \i{independently}.
+A sign of \p{+} turns the option on. A sign of \p{-} turns the option off.
+A sign of \p{=} leaves the option's boolean attribute unchanged. The argument
+string replaces the string of the corresponding
+option, unless the argument string is empty, in which case the
+option string is not changed.
+
+Because FunnelWeb processes its command line arguments from left to right,
+a later argument can cancel the effect of an earlier one.
+For example \p{fw +t -t} will result in the \p{t} option
+ending up \i{off}. This allows users to set up their own default arguments
+by defining a symbol in their operating system's command language. For
+example, a Unix user who wants FunnelWeb to delete all identical output
+files and create a documentation file on each run
+with a default \p{.typ} extension could simply place the following definition
+in their \dqp{.login} file.
+
+\begin{verbatim}
+alias fw fw +d +t.typ
+\end{verbatim}
+
+These default options can then later be easily overridden on the command line.
+
+\subsection{Options}
+\label{commandlineoptions}\x{options}\xx{list}{options}
+
+FunnelWeb's options are internal parameters which can be modified by
+corresponding arguments on FunnelWeb's command line. A description of each
+argument and option follows.
+
+\narrowthing{B1$\ldots$B6: Tracedumps:}{These\xx{B}{option}
+six\xx{tracedump}{options}\xx{dump}{option} options have been provided to
+assist in the debugging and testing
+of FunnelWeb. They determine which of six possible trace dumps are
+to be written to the listing file. Only the boolean attributes
+of these options are ever used. The six dumps are identified by the
+digits \p{1..6} as
+follows:\xx{dump}{mapped file}
+\xx{dump}{global line list}\xx{dump}{token list}
+\xx{dump}{macro table}\xx{dump}{document list}\xx{dump}{times}}
+
+\begin{enumerate}
+\item Dump a hexdump of each mapped input and include file.
+\item Dump the global line list created by the scanner.
+\item Dump the token list created by the scanner.
+\item Dump the macro table created by the parser.
+\item Dump the document list created by the parser.
+\item Dump a table summarizing CPU and real time usage.
+\end{enumerate}
+
+\narrowtext{Because these options are so closely related, a hack has been
+pulled to enable them to all to be controlled by the \p{B} argument.
+The
+string argument to the \p{B} argument determines which of the six options
+are to be affected by the sign. Examples: \p{+B134} turns on options \p{B1},
+\p{B3}, and \p{B4}. \p{-B1} turns off option \p{B1}.
+\p{Default:~-B123456}.}
+
+\narrowthing{B7: Determinism:}{If the \p{B7} option is turned on,
+FunnelWeb suppresses the output of anything
+non-deterministic,\x{non-determinism}
+or machine dependent. This assists in regression testing.
+Only the boolean attribute is used in this option.
+This option is controlled by the \p{B7} argument which falls under the
+same argument syntax as the other \p{B} options. Examples: \p{+B7}, \p{-B7}.
+\p{Default:~-B7}.}
+
+\narrowthing{C: Listing File Context:}{The\xx{C}{option}
+\p{C}\xx{listing file}{context}
+option is always turned on and
+cannot be turned off. Its only attribute is a number which determines the
+number of lines of context that the lister will place around lines flagged
+with diagnostics in the listing file (if a listing file is written).
+A value of 100 indicates infinite context\xx{infinite}{context}
+which means that the entire
+listing file will be written out if a single diagnostic occurs.
+The value of this number can be specified by specifying it as a string of
+decimal digits to the \p{+C} argument. Examples: \p{+C100}, \p{+C10}.
+\p{Default:~+C2}.}
+
+\narrowthing{D: Delete Identical Output Files:}{Only the boolean
+attribute of this option is used.\xx{D}{option}\xx{delete output}{option}
+When turned on, the option causes the suppression (deletion)
+of product files and documentation files
+(but not listing or journal files) that
+are identical to the currently existing files of the same name. For example,
+if FunnelWeb is instructed to generate \p{stack.h} as an product file, and
+the text to be written to \p{stack.h} is identical to the currently existing
+\p{stack.h}, then FunnelWeb will simply not write any product file, leaving the
+currently existing \p{stack.h} as it is (and in particular leaving the
+file's date attribute the same).
+This prevents unnecessary \p{make} propagations. For example, in a C program,
+if \p{stack.fw} is a
+FunnelWeb input file that generates \p{stack.h} and \p{stack.c},
+a modification to \p{stack.fw} that affects \p{stack.c} but does not
+affect \p{stack.h} will not provoke the recompilation of modules
+that \p{\#include stack.h}, so long as the intervening FunnelWeb run has
+\p{+D} set. Examples: \p{-D}, \p{+D}. \p{Default:~-D}.}
+
+\narrowthing{F: FunnelWeb Input File:}{If\xx{F}{option}
+this option is turned on, FunnelWeb\xx{input file}{option}
+processes the input file whose name is specified by the option string.
+Examples: \p{+Fsloth.fw}, \p{+Fwalrus}, \p{-F}.
+\p{Default:~-F}.}
+
+\narrowthing{H: Display Help Message:}{If\xx{H}{option}
+this option\xx{help}{option} is turned on, FunnelWeb
+displays the message specified by the argument string.
+Each message has a name. The main help message is called \dqp{menu}
+and contains a list of the other help messages. Examples: \p{+Hregistration},
+\p{+Hoptions}. \p{Default:~-Hmenu}.}
+
+\narrowthing{I: Include default file specification:}{This\xx{I}{option}
+option\xx{include file}{option}\xx{include}{file} is always turned
+on and cannot be turned off. Its string attribute is used as the default file
+specification for include files. Usually this option is used to specify
+a directory from which include files should be obtained.
+Examples: \p{=I/usr/dave/includes/}. \p{Default:~+I}.}
+
+\narrowthing{J: Journal File:}{If\xx{J}{option} this option is turned on,
+FunnelWeb generates a\xx{journal file}{option}\xx{journal}{file}
+journal file. A journal file contains a log of
+all the console input and output to FunnelWeb during a single invocation of
+the FunnelWeb program (Note: The \p{Q} option does not affect this.).
+The journal file is particularly useful for examining what happened during
+a FunnelWeb shell run. The string attribute is the name of the journal
+file. Examples: \p{+Jjournfile}, \p{-J}. \p{Default:~-J}.}
+
+\narrowthing{K: Keyboard:}{If\xx{K}{option}
+this option\xx{keyboard}{option}\xx{interactive}{option}
+is turned on, FunnelWeb enters an
+interactive mode in which the user can enter FunnelWeb shell commands
+interactively. The string attribute is unused.
+Examples: \p{+K}, \p{-K}. \p{Default:~-K}.}
+
+\narrowthing{L: Listing File:}{If\xx{L}{option}
+this option is turned on, FunnelWeb
+generates a\xx{listing file}{option}\xx{listing}{file}
+listing file containing a summary of a run on FunnelWeb proper.
+The string argument is the name of the listing file to be created.
+Examples: \p{+L}, \p{-L}, \p{+Llisting.lis}.
+\p{Default:~-L}.}
+
+\narrowthing{O: Product Files:}{If this option is turned on,
+FunnelWeb generates a product file for each macro in the input file
+that is bound to an output file. The string attribute contributes to the
+name of the product files. This option is controlled
+by the \p{O} argument
+because product files used to be called \dq{\b{O}utput files}).
+Examples: \p{-O}, \p{+O/usr/dave/product/}. \p{Default:~+O}.}
+
+\narrowthing{Q: Quiet:}{If\xx{Q}{option} this option is turned on,
+FunnelWeb suppresses all\xx{quiet}{option}\xx{suppress}{console output}
+output to the screen (standard output) unless one or more errors occur,
+in which case a single line summarizing the errors is sent to standard
+output at the end of the run. If this option is turned off, FunnelWeb
+writes to the console in its normal garrulous way. The string
+attribute is unused in this option. Examples: \p{-Q}, \p{+Q}. \p{Default:~-Q}.}
+
+\narrowthing{S: Screen:}{If\xx{S}{option} this option is turned on,
+FunnelWeb writes all\xx{screen}{option}
+diagnostics to the screen (standard output)
+as well as to the listing file.
+By default, they are sent only to the listing file.
+This option has a single numerical attribute
+that can be specified as a decimal string in the string component of the
+\p{S} argument. The number is the number of lines of context that should
+surround each diagnostic sent to the screen.\x{context}
+Examples: \p{-S}, \p{+S6}, \p{+S0}. \p{Default:~-S}.}
+
+\narrowthing{T: Documentation file:}{If\xx{T}{option} this
+option\footnote{This option is controlled by the \p{T} command line
+argument because documentation files used to be called typesetter files.} is
+turned on, FunnelWeb\xx{typeset}{option}\xx{typeset}{file}
+generates a documentation file in \TeX{} format.
+The string argument contributes to the
+name of the documentation file to be created.
+By default this option is turned off, as experience has
+shown that most FunnelWeb runs are made during program development;
+documentation runs occur far more rarely. Examples: \p{-T},
+\p{+Tsloth.tex}. \p{Default:~-T}.}
+
+\narrowthing{W: Width of Product Files:}{If\xx{W}{option}
+this option\xx{width}{option}\xx{product file}{width}
+is turned on, a limit is
+placed on the length of lines in product files generated during the
+run. Lines that breach the limit are flagged with error messages.
+This option has a single numerical attribute
+that can be specified as a decimal string in the string component of the
+\p{W} argument. The number is the specified maximum width.
+This option is one of two limits that are placed on the width of
+product files. The other limit is an attribute of the input file that
+defaults to 80 characters,
+but can be raised or lowered using an output line length
+pragma. The width that is enforced is the lower of this value and the
+value of the \p{W} option (if turned on).
+Examples: \p{-W}, \p{+W100}. \p{Default:~-W80}.}
+
+\narrowthing{X: Execute:}{If\xx{X}{option}
+this option\xx{execute script}{option}
+is turned on, FunnelWeb executes the FunnelWeb shell
+script file specified by the string attribute.
+Examples: \p{+Xmaster}, \p{-X}.
+\p{Default:~-X}.}
+
+\section{File Name Inheritance}
+\xx{filename}{inheritance}
+
+During a single run of FunnelWeb, FunnelWeb can produce many different
+output files. As it would be very tedious to have to specify the name
+of each of these files explicitly each time FunnelWeb is run, FunnelWeb
+provides a system of defaults that allows the user to specify the minimum
+required to successfully complete the run. To do this FunnelWeb allows
+file specifications to inherit fields from one another.
+
+FunnelWeb structures filenames into three fields\xx{filename}{fields}
+which are inherited
+independently. The fields are: \newterm{directory}, \newterm{name},
+and \newterm{extension}.
+On systems having other fields (\eg{}\i{network node}, \i{device name}),
+the extra fields are considered to be part of the directory field.
+Version numbers are
+ignored. A field can inherit a value if its current value is
+the empty string.
+
+The following table gives the full inheritance scheme used in FunnelWeb.
+
+\begin{center}
+\begin{tabular}{|l|l|l|l|l|l|l|} \hline
+Script & Input & Include & Journal & List & Document & Product \\ \hline
+ & & \p{@i} & & & & \p{@o} \\
+\p{+x} & \p{+f} & \p{+i} & \p{+j} & \p{+l} & \p{+t} & \p{+o} \\
+\dqp{.fws} & \dqp{.fw} & \dqp{.fwi} & \dqp{.jrn} & \dqp{.lis} & \dqp{.tex} & \\
+ & & \p{+f} & \p{+f} & \p{+f} & \p{+f} & \\
+DefDir & Defdir & Defdir & Defdir & Defdir & Defdir & Defdir \\ \hline
+\end{tabular}
+\end{center}
+
+The table is arranged with items of highest priority at the top.
+The \dqp{+<letter>} cells refer to the file
+specification supplied in the given command line argument.
+\dqp{+F} is the name of the input file.
+\dq{Defdir} refers to the default directory
+specification provided by the operating system. Empty cells
+do not contribute.
+
+The following example shows how the table is used.
+Suppose that the user invoked FunnelWeb as
+follows:\xx{filename inheritance}{example}
+
+\begin{verbatim}
+fw /usr/ross/work/sloth.fw +twalrus
+\end{verbatim}
+
+To work out what the documentation file should be called, FunnelWeb starts
+with the empty string and then works down the Document column of the table.
+The top entry is empty
+so we ignore it and proceed to the second entry which consists of \dqp{+T}.
+The user specified the string \dqp{walrus} as the value of this option, and
+as our current (empty)
+string does not have a name field, we insert the string
+\dqp{walrus} into the name field, resulting in the string \dqp{walrus}.
+Moving down to the next row, we encounter the constant string \dqp{.tex}.
+This string consists of an empty directory and name field, but a \dqp{.tex}
+file extension. As our current string \dqp{walrus}, does not already
+have a file extension (\ie{}the file extension field of our current string
+is empty), we add in \dqp{.tex},
+resulting in the string \dqp{walrus.tex}. Next we encounter the \dqp{+F} field
+which is the input filename \dqp{/usr/ross/work/sloth.fw} consisting of
+a directory field \dqp{/usr/ross/work/}, a name field \dqp{sloth}, and a
+file extension field \dqp{.fw}. Our \dqp{walrus.tex} string already has
+name and file extension fields, but its directory field is empty, and
+so we add in the directory field from the input file specification,
+resulting in the string \dqp{/usr/ross/work/walrus.tex}. Finally, we hit
+the default directory specification, which is (say)
+\dqp{/usr/ross/play/}. However, as the directory field of our walrus
+string is already full, it has no effect.
+
+In general, there is no need to remember the exact details of FunnelWeb's
+filename inheritance. The important thing is to know that it exists, and to
+use it.
+
+\section{FunnelWeb Startup}
+\xx{FunnelWeb}{startup}\xx{FunnelWeb}{initialization}
+
+FunnelWeb's command line options can be divided into two groups.
+\newterm{Action options} instruct FunnelWeb to performs some sort of
+independent action such as processing a file. \newterm{Ordinary options}
+merely modify the way in which FunnelWeb executes the actions.
+
+The four action options are: \p{+F}, \p{+K}, \p{+X}, and \p{+H}. For
+FunnelWeb to be successfully invoked, at least one action option must be
+specified. If zero action options are specified, FunnelWeb terminates
+with failure status.
+If more than one action option is specified, FunnelWeb performs
+the specified actions in a predefined order.
+
+Assuming that the user has specified at least one action, the order in which
+actions are executed is as follows:\xx{action execution}{order}
+
+\narrowthing{Initialization script:}{FunnelWeb\xx{initialization}{script}
+starts by
+looking in the current
+directory for a file called \dqp{fwinit.fws}.\x{fwinit.fws}
+If it doesn't find one, it
+doesn't raise any error. If it does find one, it executes it as a FunnelWeb
+shellscript. Initialization scripts are useful for setting up FunnelWeb
+options (\eg{}using the \dqp{set}
+command without having to type them each time).}
+
+\narrowthing{Execute argument script:}{If a shellscript has been specified
+using the \dqp{+X} option, FunnelWeb executes it.}
+
+\narrowthing{Process input file:}{If the user has specified an input file
+using the \dqp{+F} option, then this is processed next (by FunnelWeb proper).}
+
+\narrowthing{Display help message:}{If the user requested,
+using the \dqp{+H} option, that a help message be displayed,
+the message is displayed at this time.}
+
+\narrowthing{Interactive mode:}{If the user specified the
+\dqp{+K} option, FunnelWeb enters interactive (keyboard) mode.}
+
+FunnelWeb processes these actions in the above order regardless of the
+order in which they appear on the command line.
+
+It may be hard to see how some of these actions might be combined.
+Nevertheless, FunnelWeb allows this. For example, a user might wish
+to process a batch of files as specified in a script (\dqp{+Xscript.fws}),
+be reminded of the interactive commands available (\dqp{+Hcommand}), and
+then enter interactive mode so as to be able to
+reprocess files for which FunnelWeb
+reported errors (after correcting the errors in a different
+workstation window).
+
+
+\section{Scanner}
+\x{scanner}
+
+The scanner reads in the input file and produces a list of tokens
+which it hands onto the parser. In addition, some input constructs may cause
+the scanner to modify some of FunnelWeb's options.
+
+\subsection{Basic Input File Processing}
+
+In order to read in an input file or include file, the scanner calls a
+submodule called the \newterm{mapper}
+that reads a file in and creates a contiguous copy of
+it in memory. The scanner then performs three checks on the file, the first
+(file termination) of
+which is performed before scanning commences, and the other two of which take
+place during scanning before each line is scanned.
+
+\narrowthing{File Termination:}{The\xx{file}{termination}
+first check the scanner makes\xx{line}{termination}
+is whether
+the file is terminated properly. A file is considered to be properly
+terminated if it either contains no lines, or if the last line in the file
+is terminated by an end-of-line marker. If the scanner detects that an
+input file is not properly terminated, it adds an end-of-line marker
+itself (to the copy in memory only).}
+
+\narrowthing{Unprintable Characters:}{The second check the
+scanner makes is for\xx{unprintable}{characters}
+unprintable characters (ASCII 0--31 and 127--255
+(except for EOL(10))) which it flags
+as errors and replaces by question marks.}
+
+\narrowthing{Line Lengths:}{The third check
+the scanner makes is input line length.\xx{line}{length}
+When FunnelWeb starts up, a default maximum
+input line length of 80 is set. This can be changed dynamically during scanning
+using a \p{@p maximum\_input\_line\_length} pragma.
+If the number of characters on a line (not including the end of line marker)
+exceeds this limit, FunnelWeb generates an error.\checked{}}
+
+\subsection{Special Sequences}
+\xx{special}{sequences}
+
+The scanner scans the input file from top to bottom, left to right, treating
+the input as ordinary text (to be handed directly to the parser as a text
+token) unless it encounters the \newterm{special character}\footnote{This sort
+of character is often referred to as the \dq{escape character} or the
+\dq{control character} in other
+systems. However, as there is great potential to confuse these names
+with the \dq{escape} character (ASCII 27) and ASCII \dq{control} characters,
+the term \dq{special} has been chosen instead. This results in the terms
+\i{special character} and \i{special sequence}.} which introduces
+a \newterm{special sequence}. Thus, the
+scanner partitions the input file into ordinary text and special sequences.
+
+\begin{verbatim}
+input_file = {ordinary_text | special_sequence}
+\end{verbatim}
+
+Upon startup, the special character\xx{default}{special character}
+is \p{@}, but it can
+be changed using the $<$special$>$\p{=}$<$new\_special$>$ special sequence.
+Rather than using $<$special$>$ whenever the special character appears,
+this document uses the default special character \dqp{@} to represent the
+current special character.
+More importantly, FunnelWeb's
+error messages all use the default special character in their error messages
+even if the special character has been changed.
+
+An occurrence of the special character in the input file introduces a
+special sequence. The kind of special sequence is determined by the
+character following the special character. Only printable characters can
+follow the special character.
+
+The following list gives all the possible characters that can follow the
+special character, and the legality of each sequence.
+The first column gives the ASCII number of each ASCII character. The second
+column gives the special sequence for that character. The next column contains
+one of three characters: \dqp{-} means that the sequence is illegal. \dqp{S}
+indicates that the sequence is a \newterm{simple sequence} (with no attributes
+or side effects) that appears exactly as shown and is
+converted directly into a token and fed to the parser. Finally, \dqp{C}
+indicates that the special sequence is complex, possibly having a following
+syntax or producing funny side effects.
+
+\begin{verbatim}
+ASC SEQ COMMENT
+-----------------
+000 \
+016 | Unprintable characters and hence illegal specials.
+031 /
+032 @ - Illegal (space).
+033 @! C Comment.
+034 @" S Parameter delimeter.
+035 @# C Short name sequence.
+036 @$ S Start of macro definition.
+037 @% - Illegal.
+038 @& - Illegal.
+039 @' - Illegal.
+040 @( S Open parameter list.
+041 @) S Close parameter list.
+042 @* - Illegal.
+043 @+ C Insert newline.
+044 @, S Parameter separator.
+045 @- C Suppress end of line marker.
+046 @. - Illegal.
+047 @/ S Open or close emphasised text.
+048 @0 - Illegal.
+049 @1 S Formal parameter 1.
+050 @2 S Formal parameter 2.
+051 @3 S Formal parameter 3.
+052 @4 S Formal parameter 4.
+053 @5 S Formal parameter 5.
+054 @6 S Formal parameter 6.
+055 @7 S Formal parameter 7.
+056 @8 S Formal parameter 8.
+057 @9 S Formal parameter 9.
+058 @: - Illegal.
+059 @; - Illegal.
+060 @< S Open macro name.
+061 @= C Set special character.
+062 @> S Close macro name.
+063 @? - Illegal. Reserved for future use.
+064 @@ C Insert special character into text.
+065 @A S New section (level 1).
+066 @B S New section (level 2).
+067 @C S New section (level 3).
+068 @D S New section (level 4).
+069 @E S New section (level 5).
+070 @F - Illegal.
+071 @G - Illegal.
+072 @H - Illegal.
+073 @I C Include file.
+074 @J - Illegal.
+075 @K - Illegal.
+076 @L - Illegal.
+077 @M S Tag macro as being allowed to be called many times.
+078 @N - Illegal.
+079 @O S New macro attached to product file. Has to be at start of line.
+080 @P C Pragma.
+081 @Q - Illegal.
+082 @R - Illegal.
+083 @S - Illegal.
+084 @T C Typesetter directive.
+085 @U - Illegal.
+086 @V - Illegal.
+087 @W - Illegal.
+088 @X - Illegal.
+089 @Y - Illegal.
+090 @Z S Tags macro as being allowed to be called zero times.
+091 @[ - Illegal. Reserved for future use.
+092 @\ - Illegal.
+093 @] - Illegal. Reserved for future use.
+094 @^ C Insert control character into text
+095 @_ - Illegal.
+096 @` - Illegal.
+097 @a \
+109 @m | Identical to @A..@Z.
+122 @z /
+123 @{ S Open macro body/Open literal directive.
+124 @| - Illegal.
+125 @} S Close macro body/Close literal directive.
+126 @~ - Illegal.
+127 to 255 are not standard printable ASCII characters and are illegal.
+\end{verbatim}
+
+The most important thing to remember about the scanner is that \i{nothing
+happens unless the special character is seen.} There are no funny sequences
+that will cause strange things to happen. The best way to view a FunnelWeb
+document at the scanner level is as a body of text punctuated by special
+sequences that serve to structure the text at a higher level.
+
+The remaining description of the scanner consists of a detailed description
+of the effect of each complex special sequence.
+
+\subsection{Setting the Special Character}
+\xx{setting}{special character}
+
+The special character can be set using the sequence
+$<$special$>$\p{=}$<$newspecialchar$>$. For example, \p{@=\#} would change the
+special character to a hash (\p{\#}) character. The special character may
+be set to any printable ASCII character except the blank character
+(\ie{}any character in the ASCII range $[33,126]$). In normal use, it
+should not be necessary to change the special character of FunnelWeb, and it
+is probably best to avoid changing the special character so as not to
+confuse FunnelWeb readers conditioned to the \p{@} character.
+However, the feature is very useful where the text being prepared contains
+many \p{@} characters (\eg{}a list of internet electronic mail addresses).
+
+\subsection{Inserting the Special Character into the Text}
+\xx{special character}{inserting into text}
+
+The special sequence $<$special$>$\p{@} inserts the special character
+into the text as if it were not special at all. The \p{@} of this
+sequence has nothing to do with the current special character. If the
+current special character is \p{P} then the sequence \p{P@} will insert
+a \p{P} into the text. Example: \p{@@\#@=\#@\#@\#=@@@} translates
+to \p{@\#@\#@}.
+
+\subsection{Inserting Arbitrary Characters into the Text}
+\xx{arbitrary characters}{inserting into text}
+\xx{control characters}{inserting into text}\x{@circumflex}
+
+While FunnelWeb does not tolerate unprintable characters in the input file
+(except for the end of line character),
+it does allow the user to specify that unprintable characters appear in the
+product file. The \p{@\circumflex{}} sequence inserts a single character
+of the user's choosing into the text.
+The character can be specified by giving its
+ASCII number in one of four bases:
+binary, octal, decimal, and hexadecimal. Here is the syntax:
+
+\begin{verbatim}
+control_sequence = "@^" char_spec
+char_spec = binary | octal | decimal | hexadecimal
+binary = ("b" | "B") "(" {binary_digit}8 ")"
+octal = ("o" | "O" | "q" | "Q") "(" {octal_digit}3 ")"
+decimal = ("d" | "D") "(" {decimal_digit}3 ")"
+hexadecimal = ("h" | "H" | "x" | "X") "(" {hex_digit}2 ")"
+binary_digit = "0" | "1"
+octal_digit = binary_digit | "2" | "3" | "4" | "5" | "6" | "7"
+decimal_digit = octal_digit | "8" | "9"
+hex_digit = decimal_digit | "A" | "B" | "C" | "D" | "E" | "F"
+ | "a" | "b" | "c" | "d" | "e" | "f"
+\end{verbatim}
+
+Example:
+
+\begin{verbatim}
+@! Unix Make requires that productions commence with tab characters.
+@^D(009)prog.o <- prog.c
+\end{verbatim}
+
+Note that the decimal \dqp{9} is expressed with leading zeros
+as \dqp{009}. FunnelWeb requires
+a fixed number of digits for each base. Eight digits for base two, three
+digits for base ten, three digits for base eight and two digits for base
+sixteen.
+
+FunnelWeb treats the character resulting from a
+\p{@\circumflex{}} sequence as ordinary text in every sense.
+If your input file contains many instances of a particular control
+character,
+you can package it up in a macro like any other text. In particular,
+quick names can be used to great effect:
+
+\begin{verbatim}
+@! Unix "Make" requires that productions commence with tab characters.
+@! So we define a macro with a quick name as a tab character.
+$@#T@{@^D(009)@}
+@! And use it in our productions.
+@#Tprog.o <- prog.c
+@#Ta.out <- prog.o
+\end{verbatim}
+
+Warning: If you insert a Unix\x{Unix newline}
+newline character (decimal 10) into the text,
+FunnelWeb will treat this as an end of line sequence regardless of what
+the character sequence for end of line is on the machine upon which it is
+running. Unix EOL is FunnelWeb's internal representation for end of line.
+Thus, in the current version of FunnelWeb, inserting character 10 into the
+text is impossible unless this also happens to be
+the character used by the operating system to mark the end of line.
+
+\subsection{Comments}
+\xx{comments}{FunnelWeb}
+
+When FunnelWeb encounters the \p{@!}\x{@!}
+sequence during its left-to-right scan
+of the line, it throws away the rest of the line (including the EOL)
+without analysing it further.
+Comments can appear in any line except \dqp{@i},
+\dqp{@t}, and \dqp{@p} lines.
+
+FunnelWeb comments can be used to insert
+comments into your input file that will
+neither appear in the product files nor in the documentation file,
+but will be
+solely for the benefit of those reading and editing the input
+file directly. Example:
+
+\begin{verbatim}
+@! I have used a quick macro for this definition as it will be used often.
+@$@#C@{--@}
+\end{verbatim}
+
+Because comments are defined to include the end-of-line marker,
+care must be taken when they are being added or removed within the text
+of macro bodies. For example
+the text fragment
+
+\begin{verbatim}
+for (i=0;i<MAXVAL;i++) @! Print out a[0..MAXVAL-1].
+ printf("%u\n",a[i]);
+\end{verbatim}
+
+will expand to
+
+\begin{verbatim}
+for (i=0;i<MAXVAL;i++) printf("%u\n",a[i]);
+\end{verbatim}
+
+This problem really has no solution; if FunnelWeb comments were defined to
+omit the end of line marker, the expanded text would contain trailing blanks!
+As it is, FunnelWeb comments are designed to support single line comments
+which can be inserted and removed as a line without causing trouble.
+For example:
+
+\begin{verbatim}
+@! Print out a[0..MAXVAL-1].
+for (i=0;i<MAXVAL;i++)
+ printf("%u\n",a[i]);
+\end{verbatim}
+
+If you want a comment construct that does not enclose the end of line
+marker, combine the insert end of line construct \p{@+} with the comment
+construct \p{@!} as in
+
+\begin{verbatim}
+for (i=0;i<MAXVAL;i++) @+@! Print out a[0..MAXVAL-1].
+ printf("%u\n",a[i]);
+\end{verbatim}
+
+FunnelWeb comments should really only be used to comment the FunnelWeb
+constructs being used in the input file. Comments on the target code are
+best placed in comments in the target language or in the documenting text
+surrounding the macro definitions. In the example above, a C
+comment would have been more appropriate.
+
+\subsection{Quick Names}
+\xx{quick}{names}
+
+FunnelWeb provides a \newterm{quick name} syntax as an alternative,
+for macros whose name consists of a single character, to the
+angle bracket syntax usually used (\eg{}\p{@<Sloth@>}).
+A quick name sequence consists of \p{@\#}$x$\x{@hash}
+where $x$, the name of the macro,
+can be any printable character except space.
+
+\begin{verbatim}
+quick_name = "@#" non_space_printable
+\end{verbatim}
+
+The result is identical to the
+equivalent ordinary name syntax, but is
+shorter. For example, \p{@\#X} is equivalent to \p{@<X@>}.
+This shorter way of writing one-character macro names is more convenient where
+a macro must be used very often. For example, the macro calls in the
+following fragment of an Ada program are a little clumsy.
+
+\begin{verbatim}
+@! Define @<D@> as "" to turn on debug code and "--" to turn it off.
+@$@<D@>@{--@}
+@<D@>assert(b>3);
+@<D@>if x>7 then write("error") end if
+\end{verbatim}
+
+The calls can be shortened using the alternative syntax.
+
+\begin{verbatim}
+@! Define @#| as "" to turn on debug code and "--" to turn it off.
+@$@#|@{--@}
+@#|assert(b>3);
+@#|if x>7 then write("error") end if
+\end{verbatim}
+
+\subsection{Inserting End of Line Markers}
+\xx{EOL markers}{inserting}
+
+An end of line marker/character can be inserted into the text
+using the \p{@+}\x{@+} sequence. This is
+exactly equivalent to a real end of line in the text at the point where
+it occurs.
+While this feature may sound rather useless,
+it is very useful for laying out the input file. For
+example, the following input data for a database program
+
+\begin{verbatim}
+Animal = Kangaroo
+Size = Medium
+Speed = Fast
+
+Animal = Sloth
+Size = Medium
+Speed = Slow
+
+Animal = Walrus
+Size = Big
+Speed = Medium
+\end{verbatim}
+
+can be converted into
+
+\begin{verbatim}
+Animal = Kangaroo @+Size = Medium @+Speed = Fast @+
+Animal = Sloth @+Size = Medium @+Speed = Slow @+
+Animal = Walrus @+Size = Big @+Speed = Medium @+
+\end{verbatim}
+
+which is easier to read, and more easily allows comparisons between
+records.
+
+\subsection{Suppressing End of Line Markers}
+\xx{EOL markers}{suppressing}
+
+End of line markers can be suppressed by the \p{@-}\x{@-}
+sequence.
+A single occurrence of a \p{@-} sequence serves to suppress only the end of line
+marker following it and must appear \i{exactly} before the end of line marker to
+be suppressed. No trailing spaces, \p{@!} comments, or any other characters
+are permitted between a \p{@-} sequence and the end of line that it is
+supposed to suppress. The \p{@-} sequence is useful for constructing
+long output lines without them having to appear in the input.
+It can also be used in the same way as the \p{@+}
+was used in the previous section to assist in exposing the structure of output
+text without affecting the output text itself. Finally, it is invaluable for
+suppressing the EOL after the opening macro text \p{@\{} construct.
+For example:
+
+\begin{verbatim}
+@$@<Walrus@>@{@-
+I am the walrus!@}
+\end{verbatim}
+
+is equivalent to
+
+\begin{verbatim}
+@$@<Walrus@>@{I am the walrus!@}
+\end{verbatim}
+
+The comment construct (\p{@!}) can also be used to suppress end of lines.
+However, the \p{@-} construct should be preferred for this purpose as it
+makes explicit the programmer's intent to suppress the end of line.
+
+\subsection{Include Files}
+\xx{include}{files}
+
+FunnelWeb provides an include file facility with a maximum depth of 10.
+When FunnelWeb sees a line of the form \p{@i <filename>},\x{@i}
+it replaces the entire line (including the EOL) with the
+contents of the specified include file. FunnelWeb's include file
+facility is intended to operate at the line level. If the last line of the
+include file is not terminated by an EOL, FunnelWeb issues a warning
+and interts one (in the copy in memory).
+
+The
+\p{@i} construct is illegal if it appears anywhere except
+at the start of a line.
+The construct must be followed by a single blank. The file
+name is defined to be everything
+between the blank and the end of the line (no
+comments (\p{@!}) please!). Example: If the input file is
+
+\begin{verbatim}
+"Uh Oh, It's the Fuzz. We're busted!" said Baby Bear.
+@i mr_plod.txt
+"Quick! Flush the stash down the dunny and let's split." said Father Bear.
+\end{verbatim}
+
+and there is a file called \p{mr\_plod.txt} containing
+
+\begin{verbatim}
+"'Ello, 'Ello, 'Ello! What's all this 'ere then?" Mr Plod exclaimed.
+\end{verbatim}
+
+then the scanner translates the input file into
+
+\begin{verbatim}
+"Uh Oh, It's the Fuzz. We're busted!" said Baby Bear.
+"'Ello, 'Ello, 'Ello! What's all this 'ere then?" Mr Plod exclaimed.
+"Quick! Flush the stash down the dunny and let's split." said Father Bear.
+\end{verbatim}
+
+As a point of terminology, FunnelWeb calls the original input file the
+\newterm{input file} and calls include files and their included files
+\newterm{include files}.
+
+The include file construct operates at a very low level. An include
+line can appear anywhere in the input file regardless of the context
+of the surrounding lines.
+
+FunnelWeb sets the special character to the default (\p{@}) at the
+start of each include file and restores it to its previous value at the end
+of the include file. This allows macro libraries to be constructed and
+included that are independent of the prevailing special character
+at the point of inclusion.
+The same goes for the input line length limit
+which is reset to the default
+value at the start of each include file and
+restored to its previous value afterwards.
+
+\subsection{Pragmas}
+\x{pragmas}\xx{pragmas}{visible}\xx{pragmas}{invisible}
+
+Most tools have to support some essential, but rather inelegant features.
+In FunnelWeb these messy bits have all been stuffed into the
+scanner's \newterm{pragma} (for \i{pragma}tic) construct.
+
+A pragma consists of a single line of input (including the EOL)
+commencing with \p{@p}. This
+must be followed by a single space, and then the pragma verb.
+This must
+be followed by a sequence of zero or more arguments separated by one or
+more spaces. Four pragmas are available
+
+\begin{verbatim}
+pragma = pragma_ident | pragma_mill | pragma_moll | pragma_typesetter
+\end{verbatim}
+The following syntax definitions assist in defining the pragmas.
+
+\begin{verbatim}
+s = {" "}+
+ps = ("@p" | "@P") " "
+number = { decimal_digit }+
+numorinf = number | "infinity"
+\end{verbatim}
+
+The arguments to pragmas are case-sensitive and must be specified in
+lower case.
+
+Pragmas are processed and consumed entirely by the scanner. The parser
+never sees them and so they can play
+no part in the parser level syntax. As a result, pragma lines
+can appear anywhere in the entire input file regardless of the surrounding
+context (\eg{}even in the middle of a macro definition).
+The sole effect of a pragma is to modify some internal parameter of
+FunnelWeb.
+
+The following sections describe the four FunnelWeb pragmas.
+
+\subsubsection{Indentation}
+\label{indentationpragma}\xx{indentation}{macro expansion}
+
+When FunnelWeb expands a macro, it can do so in two ways. First it can treat
+the text it is processing as a one-dimensional stream of text, and merely
+insert the body of the macro in place of the macro call. Second, it can
+treat the text of the macro as a two dimensional object and
+indent each line of the macro body by the amount that the macro
+call itself was indented. Consider the following macros.
+
+\begin{verbatim}
+@$@<Loop Structure@>@{@-
+i=1;
+while (i<=N)
+ @<Loop body@>
+endwhile
+@}
+
+@$@<Loop body@>@{@-
+a[i]:=0;
+i:=i+1;@}
+\end{verbatim}
+
+Under the regime of \newterm{no indentation}\xx{indentation}{none}
+the loop structure
+macro expands to:
+
+\begin{verbatim}
+i=1;
+while (i<=N)
+ a[i]:=0;
+i:=i+1;
+endwhile
+\end{verbatim}
+
+Under the regime of \newterm{blank indentation}\xx{indentation}{blank}
+the loop structure macro expands to:
+
+\begin{verbatim}
+i=1;
+while (i<=N)
+ a[i]:=0;
+ i:=i+1;
+endwhile
+\end{verbatim}
+
+The \p{indentation} pragma determines which of these two regimes will be used
+to expand the macros when constructing the product files. The syntax of the
+pragma is:
+
+\begin{verbatim}
+pragma_ident = ps "indentation" s "=" s ("blank" | "none")
+\end{verbatim}
+
+Its two forms look like this:
+
+\begin{verbatim}
+@p indentation = blank
+@p indentation = none
+\end{verbatim}
+
+In the current version of FunnelWeb, the indentation regime is an attribute
+that is attached to an entire run of Tangle; it is not possible to bind it
+to particular product files or to particular macros. As a result, it doesn't
+matter where indentation pragmas occur in the input file or how many
+there are so long as they are all the same. By default FunnelWeb uses
+blank indentation.
+
+\subsubsection{Maximum Input Line Length}
+\label{millpragma}\xx{input}{line length}\xx{maximum}{input line length}
+
+FunnelWeb generates an error for each input line
+that exceeds a certain maximum number of characters. At the start of the
+processing of each input
+file and each include file, this maximum is set to a default value of 80.
+However,
+the maximum can be changed using a maximum input line length
+pragma.\xx{pragma}{input line length}
+
+\begin{verbatim}
+pragma_mill = ps "maximum_input_line_length" s "=" s numorinf
+\end{verbatim}
+
+The maximum input line length can be varied
+\i{dynamically} throughout the input file. Each maximum input line length
+pragma's scope covers the line following the pragma through to and including
+the next maximum input line length pragma, but not covering any intervening
+include files. At the start of an include file, FunnelWeb resets
+the maximum input line length to the default value. It restores it to
+its previous value at the end of the include file.
+
+This pragma is useful for detecting text that has strayed off the
+right side of the screen when editing. If you use FunnelWeb, and set the
+maximum input line length to be the width of your editing window, you will
+never be caught by, for example, off-screen opening comment symbols.
+You can also be sure that your source text can be printed raw, if necessary,
+without lines wrapping around.
+
+\subsubsection{Maximum Output File Line Length}
+\label{mollpragma}%
+\xx{maximum}{product file line length}%
+\xx{pragma}{maximum product file line length}%
+\xx{maximum}{output file line length}%
+\xx{pragma}{maximum output file line length}
+
+As well as keeping an eye on input line lengths, FunnelWeb also keeps an
+eye on the line lengths of product files and flags all lines longer
+than a certain limit with error messages.
+Unlike the
+maximum input line length, which can vary dynamically throughout the input
+file, the maximum product file line length remains fixed throughout the
+generation
+of all the product files. The maximum product file
+line length pragma allows this
+value to be set. If there is more than one such pragma in an input file, the
+pragmas must all specify the same value.
+
+\begin{verbatim}
+pragma_moll = ps "maximum_output_line_length" s "=" s numorinf
+\end{verbatim}
+
+The default value is 80 characters.
+
+This pragma is only one of two constraints on the length of the lines of the
+product files. The \p{+W} command line option also contributes.
+The actual value that FunnelWeb uses is the minimum of the limits
+specified in the command line and pragmas.
+
+FunnelWeb does not monitor the length of the lines of its other output files
+(journal file, listing file, documentation file).
+
+\subsubsection{Typesetter}
+\xx{typesetter}{pragma}\xx{typesetter}{independence}
+
+The \p{typesetter} pragma allows the user to specify whether the input
+file is supposed to be typesetter-independent, or whether it contains
+commands in a particular typesetter language. The pragma has the
+following syntax.
+
+\begin{verbatim}
+pragma_typesetter = ps "typesetter" s "=" s ("none" | "tex")
+\end{verbatim}
+
+The two forms of the pragma look like this.
+
+\begin{verbatim}
+@ typesetter = none
+@ typesetter = tex
+\end{verbatim}
+
+A source file can contain more than one typesetter pragma, but they must
+all specify the same value. The default is \p{none}.
+The typesetter setting affects two things:
+
+\narrowthing{Handling of free text:}{If the typesetter is not \p{none},
+Weave writes the free text \i{directly}
+to the documentation file without changing it whatsoever. This means that
+if (say) \p{\char`\\ centerline} appears in the input file, it will copied
+directly to the documentation file. If the typesetter is \p{none}, Weave
+intercepts any characters or sequences that might have a special
+meaning to the target typesetter and replaces them
+with typesetter commands to typeset the sequences so that they will appear
+as they do in the input. For example, if the typesetter is \p{none} and
+the target typesetter is \TeX{}, then if
+\p{\$} (the \TeX{} \dq{mathematics mode} character)
+appears in the input file, it will be
+be written to the documentation file as \p{\char`\\ \$}.}
+
+\narrowthing{Restrictions on the target typesetter:}{At a later date,
+different weave modules might be incorporated into FunnelWeb to cater
+for a variety
+of different typesetters. If this happens, it will be important to ensure
+that typesetter-specific source files
+(\ie{}\p{typesetter} $\ne$ \p{none}) are not processed with different
+target typesetters. For example, a user might innocently attempt to generate
+a \p{troff} documentation file from a
+FunnelWeb source file containing a \p{typesetter = tex} (and by
+implication \TeX{} control sequences). The pragma could also be useful
+for catching typesetter clashes in source and include files. The setting
+\p{none} is special because it is guaranteed to work with any
+future target typesetter.}
+
+The aim of all this is
+to ensure that any typesetter dependency is correctly proclaimed.
+Because \p{none} is the default typesetter,
+a user who creates a source file without a \p{typesetter = x} pragma
+will soon find that the control sequences they are inserting into
+the source document are appearing verbatim in the printed documentation!
+In order to activate these sequences, they will be forced to add a
+\p{typesetter} pragma, thus making the dependency explicit.
+
+It may seem strange to place the \p{typesetter} setting facility within
+a pragma (\p{@p}) when there is a separate typesetting construct (\p{@t}).
+This has been done to sustain the rule of thumb that says that
+pragmas do not participate in the parser-level syntax, but typesetter
+directives do.
+
+\subsection{Freestanding Typesetter Directives}
+\xx{typesetter}{directives}
+
+FunnelWeb provides two kinds of typesetter directive to assist the user
+to produce documentation. These are \newterm{inline} and
+\newterm{freestanding}. Unlike pragmas,
+each of these categories of directive participates in the parser-level
+syntax and can appear only in certain contexts (see the parser section).
+Inline directives are
+designed to be used within paragraphs to alter the look of the enclosed
+text. Freestanding typesetter directives are designed to
+appear on lines of their own and have a bigger typographical impact.
+
+The syntax of freestanding typesetter directives is almost identical to that
+of pragmas. All the same syntax rules apply (except that the actual
+keywords are different).
+The following subsections describe the four typesetter directives
+available.
+
+\begin{verbatim}
+ftd = ftd_newpage | ftd_toc | ftd_vskip | ftd_title
+ts = "@t "
+\end{verbatim}
+
+\subsubsection{New Page}
+\x{new page}\xx{pragma}{new page}
+
+The new page pragma is a typesetting pragma with the following syntax.
+
+\begin{verbatim}
+ftd_newpage = ts "new_page"
+\end{verbatim}
+
+It only form looks like this.
+
+\begin{verbatim}
+@t new_page
+\end{verbatim}
+
+Its sole effect is to cause a \dq{skip to a new page} command to be inserted
+into the documentation file.
+The new page command is such that if the typesetter is already at
+the top of a page, it will skip to the top of the next page.
+
+\subsubsection{Table of Contents}
+\xx{table of}{contents}\xx{pragma}{table of contents}
+
+The new page pragma is a typesetting pragma with the following syntax.
+
+\begin{verbatim}
+ftd_toc = ts "table_of_contents"
+\end{verbatim}
+
+It only form looks like this.
+
+\begin{verbatim}
+@t table_of_contents
+\end{verbatim}
+
+Its sole effect is to instruct Weave to insert a table of contents at
+this point in the printed documentation.
+This pragma does not skip to a top of a new page first.
+
+\subsubsection{Vertical Skip}
+\xx{vertical}{skip}\xx{pragma}{vskip}
+
+The vertical skip pragma is a typesetting pragma that
+instructs Weave to insert a specified amount of
+vertical space into the documentation. The pragma has the following syntax.
+
+\begin{verbatim}
+ftd_vskip = ts "vskip" s number s "mm"
+\end{verbatim}
+
+For example:
+
+\begin{verbatim}
+@t vskip 26 mm
+\end{verbatim}
+
+\subsubsection{Title}
+\x{title}\xx{pragma}{title}
+
+The title pragma is a typesetting pragma with the following syntax.
+
+\begin{verbatim}
+ftd_title = ts "title" s font s alignment text
+font = "normalfont" | "titlefont" | "smalltitlefont"
+alignment = "left" | "centre" | "right"
+text = """" {printable_char} """"
+\end{verbatim}
+
+It's effect is to instruct Weave to insert a single line
+into the printed documentation
+containing the specified text set in the specified font
+and aligned in the specified manner. The double quotes delimiting
+the text are for show only; if you want to put a double quote in the string,
+you don't need to double them.
+
+Here is an example of the pragma.
+
+\begin{verbatim}
+@t title smalltitlefont centre "How to Flip a Bit"
+\end{verbatim}
+
+\subsection{Scanner/Parser Interface}
+
+If the scanner terminates without any errors, control
+is passed to the parser. The parser parses the token list generated by
+the scanner. The token list consists of text scraps, freestanding
+typesetter directives,
+and special sequence tokens.
+
+The user should bear in mind that
+\i{the scanner finishes running before the
+parser starts running.} This means that the scanner cannot be influenced
+in any way by higher order structures such as the parser might parse.
+For example,
+it is impossible to write a FunnelWeb macro to include a file, or insert
+a \p{vskip} pragma into the input text.
+
+\section{Parser}
+\x{parser}
+
+By the time the parser starts, the scanner has completely terminated.
+At this point, it
+is not possible for any more files to be included, and special characters are
+no longer present to confuse things. All that remains is a list of
+\newterm{text tokens},
+\newterm{special tokens}, and \newterm{typesetter directive tokens}.
+Text tokens consist entirely of
+sequences of printable characters and end of line markers. Special tokens
+represent the special sequences that the scanner found in the input file.
+Typesetter directive tokens represent the freestanding typesetter directives
+that the scanner encountered.
+The parser consumes the token list and builds a macro table that is
+later used to generate product files. It also constructs
+a document list that is used to generate the documentation file.
+
+The syntax rules appearing in the following sections refer to the
+token list.
+
+\subsection{High Level Structure}
+\xx{syntax}{high level}
+
+At the highest level, the FunnelWeb parser parses the input file (token
+list) into a sequence of text scraps, macro definitions,
+and typesetter directives.
+
+\begin{verbatim}
+input_file = {text | macro | directive}
+\end{verbatim}
+
+All three of these kinds of components contribute to the documentation file,
+but only macro definitions
+contribute to the product files. If all the free text
+and directives were removed from a FunnelWeb input file, the
+product files would not be affected.
+
+\subsection{Free Text}
+\xx{free}{text}
+
+\newterm{Free text} is any text that is not part of a macro definition or a
+directive. A scrap of free text consists of a sequence of items drawn
+from the following list:
+non-special printable characters, insert-eol special
+sequences, insert special character special sequences, insert arbitrary
+character special sequence.
+
+\begin{verbatim}
+free_text = ordinary_text
+ordinary_text = {ordinary_char | eol | text_special}+
+text_special = "@+" | "@@" | "@^" char_spec
+ordinary_char = " ".."~"-special
+\end{verbatim}
+
+An example of some rather messy free text is as follows:
+
+\begin{verbatim}
+This@@ is a very@+ messy
+@^D(009)chunk of text indeed.
+But FunnelWeb still views it as
+a single chunk of text.
+\end{verbatim}
+
+FunnelWeb never sees two text chunks next to each other in the input;
+they are always merged into a single text token.
+
+The free text in an input file
+does not affect the product files. However, by default, it appears in the
+printed documentation exactly as it is given in the input file, except
+that it is filled and justified into paragraphs.
+
+Any printable character
+or particular sequence of characters
+may appear in the free text of a document. FunnelWeb ensures that they
+will appear exactly as given in the input file, even if they happen to be
+escape characters or commands in the target typesetter.
+However, FunnelWeb also provides a special mode that allows
+this censoring to be
+overridden. See Section~\label{typesetterpragma} for more information.
+
+\subsection{Typesetter Directives}
+\x{directives}
+
+FunnelWeb provides a variety of typesetter directives to assist the
+user to typeset the document in a typesetter-independent way. These are
+divided into \newterm{freestanding typesetter directives} (ftd) and
+\newterm{inline typesetter directives} (itd). The internal syntax of the
+freestanding typesetter directives has already been discussed
+in the scanner section. The following syntax rule defines
+the context in which these constructs can appear.
+
+\begin{verbatim}
+directive = ftd | itd
+itd = section | literal | emphasis
+\end{verbatim}
+
+The remainder of this section describes the inline typesetter directives.
+
+\subsubsection{Section}
+\xx{section}{constructs}
+
+The section directive
+provides a way for the user to structure the program and documentation into
+a hierarchical tree structure,\xx{tree}{structure}
+just as in most large documents.
+A section construct consists of a case-insensitive
+identifying letter, which determines the
+absolute level of the section in the document, and an optional section
+name, which has exactly the same syntax as a macro name.
+
+\begin{verbatim}
+section = "@" levelchar [name]
+levelchar = "A" | "B" | "C" | "D" | "E" |
+ "a" | "b" | "c" | "d" | "e"
+\end{verbatim}
+
+The section construct is not quite \dq{inline} as it must appear only
+at the start of a line. However, unlike the \dqp{@i}, \dqp{@p}, and
+\dqp{@t} constructs, it does not consume the remainder of the line
+(although it would be silly to place anything on the same line anyway).
+
+FunnelWeb provides five levels of sections, ranging from the highest level
+of \p{A} (like a \LaTeX{}\x{LaTeX}
+chapter) to the lowest level of \p{E} (like a \LaTeX{}
+subsubsubsection). FunnelWeb input files need not contain
+any sections at all, but if they do, the first section must be at level \p{A},
+and following sections must not skip hierarchical levels (\eg{}an \p{@D} cannot
+follow an \p{@C}). FunnelWeb generates an error if a level is skipped.
+
+All section \i{must} have names associated with them, but for convenience,
+the section name is optional if the section contains one or more
+macro definitions
+(\ie{}at least one macro definition appears between the section construct
+in question and the
+next section construct in the input file.). In this case, the section
+\i{inherits} the name of the first macro defined in the section. This
+feature streamlines the input file, avoiding duplicate name inconsistencies.
+
+Any sequence of printable characters can be used in the
+section name,\xx{section}{name}
+even the target typesetter's escape sequence (\eg{}in \TeX{},
+\dqp{\bs{}}).
+
+The following example demonstrates the section construct.
+
+\begin{verbatim}
+@A@<Life Simulation@>
+
+This is the main simulation module for planet earth, simulated down to the
+molecular level. This is a REALLY big program. I mean really big. I mean,
+if you thought the X-Windows source code was big, you're in for a shock...
+
+@B We start by looking at the code for six legged stick insects as they
+form a good example of a typical object-oriented animal implementation.
+
+@$@<Six Legged Stick Insects@>@{@-
+slsi.creep; slsi.crawl; slsi.creep;@}
+\end{verbatim}
+
+In the above example, the name for the level A section is provided
+explicitly, while the name for the level B section will be inherited from the
+macro name.
+
+\subsubsection{Literal Directive}
+\xx{literal}{directive}
+
+Experience has shown that one of the most common typesetting requirement
+is that of being able to typeset small program fragments
+in the middle of the documenting free text. Typically
+there is a frequent need to refer to program identifiers, and it
+assists the reader to have such identifiers typeset in the same manner
+as the program text in the macro definition.
+FunnelWeb~V1
+defined a \TeX{} macro for this (called \p{p}) that simply typeset its
+argument in \p{tt font}. This proved so
+useful, that the facility has been made typesetter-independent in
+FunnelWeb~V3.
+
+To specify that some text be typeset in \p{tt font},
+enclose the text in curly brace special sequences as follows.
+
+\begin{verbatim}
+literal = "@{" ordinary_text "@}"
+\end{verbatim}
+
+As in macro names, section names, and macro bodies, the text contained
+within the literal
+construct is protected by FunnelWeb from any non-literal interpretation by
+the typesetter and the user is
+free to enclose \i{any} text covered by the definition \p{ordinary\_text}.
+FunnelWeb guarantees that, no matter what the text is, it will
+be typeset in \p{tt font} exactly as it appears. However, the text will be
+filled and justified into a paragraph as usual.
+
+Here is an example of the use of the construct:
+
+\begin{verbatim}
+@C The @{WOMBAT@} (Waste Of Money, Brains, And Time) function
+calls the @{kangaroo@} input function which has been
+known to cause keybounce.
+This keybounce can be dampened using the @{wet_sloth@} subsystem.
+\end{verbatim}
+
+\subsubsection{Emphasis Directive}
+\xx{emphasis}{directive}
+
+The emphasis directive is very similar to the literal directive except that
+it causes its argument to be typeset in an emphasised manner
+(\eg{}italics). Like the literal directive,
+the emphasis directive protects its text argument.
+
+\begin{verbatim}
+emphasise = "@/" ordinary_text "@/"
+\end{verbatim}
+
+Example:
+
+\begin{verbatim}
+@C What you @/really@/ need, of course, is a @/great@/, @/big@/,
+network with packets just flying @/everywhere@/.
+This section implements an interface
+to such a @/humungeous@/ network.
+\end{verbatim}
+
+\subsection{Macros}
+\xx{macro}{definition}
+
+The third category of
+construct appearing at the highest syntactic level in a FunnelWeb
+input file is the macro definition.
+A macro definition binds a unique
+\newterm{macro name} to a \newterm{macro body} containing an
+\newterm{expression} consisting of text, calls to
+other macros, and formal parameters. The syntax for a macro definition is as
+follows:
+
+\begin{verbatim}
+macro = ("@O" | "@$") name [formal_parameter_list]
+ ["@Z"] ["@M"] ["==" | "+="] "@{" expression "@}"
+\end{verbatim}
+
+The complexity of the macro definition syntax is mostly to enable the user
+to attach various attributes to the macro.\xx{macro}{attributes}
+If the user chooses \p{@O},
+then the macro cannot be called, but is instead
+attached to a product file. If the user chooses \p{@\$}, then the macro is
+an ordinary macro definition that is not attached to a file.
+
+By default, a non-file macro must be invoked exactly once by one other
+macro. Macros that
+aren't are flagged with errors by the FunnelWeb analyser. However, if the
+user uses the \p{@Z}\x{@Z} sequence in the macro definition, the macro is then
+permitted to be invoked zero times, as well as once. Similarly, if the
+user uses the \p{@M}\x{@M}
+sequence in the macro definition, the macro is
+permitted to be called many times as well as once. If both \p{@Z} and
+\p{@M} are present then the macro is permitted to be invoked zero, one,
+or many times.
+
+The purpose of enforcing the default \dq{exactly one call} rule is to
+flag pieces of code that the user may have defined in a macro but not
+hooked into the rest of the program. Experience shows that this is a
+common error. Similarly, it can be dangerous to multiply invoke a
+macro intended to be invoked only once. For example, it may be dangerous
+to invoke a scrap of non-idempotent initialization code in two different
+parts of the main function of a program! However, FunnelWeb will not
+generate an error if a macro without \p{@M} is called by another
+macro that is called more than once.
+
+If the text string \p{==}\x{==} (or nothing) follows the macro name,
+the expression that follows
+is the entire text of the macro body. If the text string \p{+=}\x{+=}
+follows
+the macro name, then more than one such definition is allowed
+(but not required) in the document
+and the body of
+the macro consists of the concatenation of all such expressions in the order
+in which they occur in the input file. Such a macro is said to be
+additive and is
+\newterm{additively defined}. Thus a macro body can either be defined
+in one place using one definition (using \p{==}) or it can be \i{distributed}
+throughout the input file in a sequence of one or more macro definitions (using
+\p{+=}). If neither \p{==} and \p{+=} are present, FunnelWeb assumes a
+default of \p{==}.
+
+Macros attached to product files cannot be additively defined.
+Additively defined macros can have parameter lists and \p{@Z} and \p{@M}
+attributes, but these must be specified only in the first definition of the
+macro. However, \p{+=} must appear in each definition.
+
+\subsubsection{Names}
+\x{names}\xx{macro}{names}\xx{section}{names}
+
+Names are used to identify macros and sections.
+A name consists of a sequence of from zero to 80 printable characters,
+including the blank
+character. End of line characters are not permitted in names.
+Names are case sensitive; two different macros are permitted to have names
+that differ in case only. Like free text, names are typeset by FunnelWeb and
+are safe from misinterpretation by the target typesetter. For example, it
+is quite acceptable to use the macro name \p{@<\bs{}medskip@>}
+even if the target typesetter is \TeX{}.
+
+\begin{verbatim}
+name = "@<" name_text "@>"
+name_text = {ordinary_char | text_special}
+\end{verbatim}
+
+\subsubsection{Formal Parameter Lists}
+\xx{parameter lists}{formal}
+
+FunnelWeb allows macros to have up to nine macro parameters, named
+\p{@1},\x{@1...}
+\p{@2}, $\ldots$, \p{@9}. If a macro does not have a formal
+parameter list,
+it is defined to have no parameters, and an actual parameter list must not
+appear at the point of call. If a macro has a formal parameter list, it
+is defined to have one or more parameters, and a corresponding actual
+parameter must be supplied for each formal parameter, at the point of call.
+
+Because FunnelWeb parameters have predictable names, the only information
+that a formal parameter list need convey is \i{how many} parameters a macro
+has. For this reason a formal parameter list takes the form of the highest
+numbered formal parameter desired, enclosed in parentheses sequences.
+
+\begin{verbatim}
+formal_parameter_list = "@(" formal_parameter "@)".
+formal_parameter = "@1" | "@2" | "@3" | "@4" | "@5" |
+ "@6" | "@7" | "@8" | "@9"
+\end{verbatim}
+
+\subsection{Expressions}
+\xx{macro}{expressions}
+
+Expressions are FunnelWeb's most powerful form of expressing a text
+string.
+Macro bodies are defined as expressions. Actual parameters consist of
+expressions.
+
+An expression consists of a sequence of zero or more expression elements.
+An expression element can be ordinary text, a macro call, or a formal
+parameter of the macro \i{definition} in which the formal parameter occurs.
+
+\begin{verbatim}
+expression = {ordinary_text | macro_call | formal_parameter}
+\end{verbatim}
+
+\subsection{Macro Calls}
+\xx{macro}{calls}
+
+A macro call consists of a name optionally followed by an actual parameter
+list. The
+number of parameters in the actual parameter list must be the same as
+the number of formal parameters specified in the definition of the
+macro. If the macro has no formal parameter list, its call must have no
+actual parameter list.
+
+\begin{verbatim}
+macro_call = name [actual_parameter_list]
+actual_parameter_list = "@(" actpar { "@," actpar } "@)"
+actpar = expression |
+ ( whitespace "@""" expression "@""" whitespace )
+whitespace = {" " | eol}
+\end{verbatim}
+
+FunnelWeb allows parameters to be passed directly, or delimited by
+special double
+quotes.\xx{macro parameter}{delimiting}
+Each form is useful under different circumstances. Direct specification
+is useful where the parameters are short and can be all placed on one line.
+Double quoted parameters allow whitespace on either side
+(that is not considered part of the parameter) and are useful for laying out
+rather messy parameters. Here are examples of the two forms.
+
+\begin{verbatim}
+@<Generic Loop@>@(
+ @"x:=1;@" @,
+ @"x<=10;@" @,
+ @"print "x=%u, x^2=%u",x,x*x;
+ x:=x+1;@+@"
+@)
+
+@<Colours@>@(red@,green@,blue@,yellow@)
+\end{verbatim}
+
+As shown, the two forms may be mixed within the same parameter list.
+
+Experience has shown that the vast majority of macros have no parameters.
+
+\subsection{Formal Parameters}
+\xx{formal}{parameters}
+
+Formal parameters can appear in the expressions forming macro bodies
+in accordance with the syntax rules defined above. A formal parameter
+expands to the text of the expansion of its corresponding
+actual parameter. There is nothing preventing a formal
+parameter being provided as part of an expression that forms an actual
+parameter.
+In that happens, the formal parameter is bound to the actual parameter of the
+calling macro, not the called macro.
+After the following definitions,
+
+\begin{verbatim}
+@$@<One@>@(@1@)=@{A walrus in @1 is a walrus in vain.@}
+@$@<Two@>@(@1@)=@{@<One@>@(S@1n@)@}
+\end{verbatim}
+
+the call
+
+\begin{verbatim}
+@<Two@>@(pai@)
+\end{verbatim}
+
+will result in the expansion
+
+\begin{verbatim}
+A walrus in Spain is a walrus in vain.
+\end{verbatim}
+
+\subsection{Macros are Static}
+\xx{macro}{definition}\xx{macro}{expansion}\xx{macros}{static}
+
+In FunnelWeb, the actions of \i{macro definition} and \i{macro
+expansion} occur during two separate phases (parser and tangle)
+and cannot be interleaved. As a result, the FunnelWeb macro facility is
+completely static.
+It is not possible for one macro to
+define another while the first macro is being
+expanded; each must be defined statically. It is not possible to define a
+macro to even assist in the definition of other macros. Because the scanner,
+parser, analyser, and tangler phases are all invoked sequentially, there is
+no room for feedback of definitions between different levels (\eg{}the user
+cannot define a macro for the \p{vskip} pragma).
+
+This lack of power is fully intentional. By totally excluding the more
+incomprehensible ways in which a general purpose macro preprocessor can be
+used, FunnelWeb provides definite guarantees to the reader of its input files:
+
+\begin{itemize}
+\item FunnelWeb guarantees that a piece of text does not contain a macro call
+unless it contains the special character followed by \p{$<$} or \p{\#}.
+\item FunnelWeb allows calls to be made to macros that are defined later
+in the input file.
+\end{itemize}
+
+\section{Analyser}
+\x{analyser}\xx{checks}{macro}
+
+The effect of the parser is to construct a macro table containing a
+representation of all the macros defined within the document, and a document
+list which contains a complete representation of the entire document.
+If there are no error diagnostics (or worse) at the end of the parser
+run, FunnelWeb invokes the analyser which tests for the following conditions
+and flags them with errors if they arise.
+
+\begin{itemize}
+\item No macros defined in the input file.
+\item No macros connected to output files.
+\item Call of an undefined macro.
+\item Call having the wrong number of parameters.
+\item Call of a macro that is connected to an output file.
+\item No calls made to a macro without the \p{@Z} option.
+\item More than one call made to a macro without the \p{@M} option.
+\item Directly or indirectly recursively defined macros.
+\item Unnamed sections that contain no macro definitions.
+\end{itemize}
+
+FunnelWeb performs a static analysis\xx{static}{analysis} to detect
+recursion.\xx{macro}{recursion}
+Unfortunately, the recursion detection algorithm
+flags all macros that have an infinite expansion
+rather than just all macros
+with a recursive definition. If A calls B, and B calls
+C, and C calls B, then FunnelWeb will flag A as well
+as B and C. It is hoped that this problem will be fixed in a later version.
+
+Because FunnelWeb does not provide any kind of conditional feature, the
+prevention of recursion does not represent a curtailment of expressive power.
+
+Macros may be invoked recursively, but may not be recursive. Thus:
+
+\begin{verbatim}
+@<Sloth@>@(@<Sloth@>@(Walrus@)@) @! LEGAL recursive invocation.
+
+@$@<Teapot@>==@{@<Teapot@>@} @! ILLEGAL recursive definition.
+\end{verbatim}
+
+\section{Tangle}
+\x{tangle}
+
+If the scanner, parser, and analyser have successfully (\ie{}with no
+errors, severe errors, or fatal errors) completed, and the Tangle option
+(\p{+O}) is turned on (it is by default), then the Tangle component of
+FunnelWeb is invoked to generate the product files specified in the \p{@O}
+macros of the input file.
+
+The operation of Tangle is very simple. Each \p{@O} macro is expanded and
+written to a file of the same name. As there are a finite number of macros,
+and the analyser guarantees that the
+macro structure is non-recursive, Tangle is guaranteed to terminate.
+
+Three remaining points are worth discussing.
+
+\begin{enumerate}
+
+\item Tangle expands macros using blank indentation unless the
+user has specified otherwise in an indentation pragma in the
+input file (see Section~\ref{indentationpragma}).
+
+\item Tangle keeps track of the
+length of the lines that it is writing
+and issues an error if any line of any product file that it generates is
+longer than the maximum. The maximum is the minimum of a value defaulted
+or specified in the input file (Section~\ref{mollpragma}),
+and the value (if any) provided by the
+\p{+w} command line argument (Section~\ref{commandlineoptions}).
+
+\item It is worth the user obtaining
+some understanding of the resources
+that FunnelWeb requires to perform its task.
+
+\end{enumerate}
+
+When FunnelWeb's scanner
+executes, it reads each file into memory where it is kept for the duration
+of the run. Thus, there must be room in memory for the entire
+input file, including all include files. While this approach may seem
+expensive in memory, it is almost necessary in order to support
+forward references. To merely scan the input file, recording the macro
+names, but leaving the text on disk, would require many random
+access disk seeks.
+
+In contrast, FunnelWeb never builds an internal representation
+of the product file.
+Instead, each piece of output is written immediately to the
+product file. This means that as long as the input file fits in memory,
+the product file can be arbitrarily large. It also means that users need
+not fear to define or call macros that they know will expand to megabytes
+of text. Nor need they fear placing a call to such a macro as part of
+an actual parameter. FunnelWeb does not ever expand actual parameters
+internally. In fact, it does not expand them until it hits the corresponding
+formal parameter during its expansion of the called macro. At that point, it
+looks up the \i{expression} (not the expansion of the expression) for the
+corresponding actual parameter, and starts expanding it.
+
+\section{Weave}
+\x{weave}\x{typesetting}
+
+If the scanner, parser, and analyser have successfully (\ie{}with no
+errors, severe errors, or fatal errors) completed, and the Weave option
+(\p{+T}) is turned on (it is \i{off} by default), then the Weave component of
+FunnelWeb is invoked to generate a text file in the format of a particular
+typesetter. The result, when fed through the particular typesetter and printed,
+is a fully typeset representation of the entire input file complete with
+cross referencing information.
+
+\subsection{Target Typesetter}
+\xx{target}{typesetter}
+
+Currently, FunnelWeb produces documentation files
+in the format of only one typesetter ---
+\TeX{}. However, the Weave package of FunnelWeb is fairly small, and it
+is hoped that it can be rewritten so as to provide
+a collection of typesetter modules from which
+the user will be able to choose using a command line argument.
+
+\subsection{Cross Reference Numbering}
+\xx{cross}{referencing}\xx{cross reference}{numbering}
+\xx{section}{numbering}
+
+When FunnelWeb produces its typeset documentation, it \i{numbers} each
+section and each macro definition and cross references the macro definitions.
+The exact scheme used has been carefully thought out. However, as it can
+be a little confusing to the beginner, it is explained here in full.
+
+The most important thing is that there is \i{no relation} between the
+macro numbering and the section numbering. In Knuth's Web there are only
+section numbers. In FunnelWeb, the numbering of sections and macros
+is separated.
+
+In FunnelWeb, \i{sections} are numbered
+hierarchically in ascending order. For example, the second level-C section
+of the third level-B section of the first level-A section is
+numbered \dq{1.3.2}. In contrast, \i{macro definitions} are numbered
+sequentially in ascending order. For example, the first macro definition is
+number 1, the second is number 2, and so on. Note that it is \i{macro
+definitions} that are numbered, not \i{macros}. This distinction is necessary
+because additive macros (\ie{}the ones with \p{+=})
+can be defined by a collection
+of partial definitions scattered throughout the input file. A single additive
+macro may be defined in definitions 5, 67, 128, and 153.
+
+\section{FunnelWeb Shell}
+\label{commandshell}%
+\xx{FunnelWeb}{command shell}\xx{commands}{FunnelWeb}\xx{FunnelWeb}{shell}
+
+\subsection{Introduction}
+
+One of the goals of FunnelWeb is
+that it must be extremely portable. Huge efforts, desperate actions,
+and great sacrifices were made in the name of portability.
+For example, FunnelWeb is written in~C.
+
+An equally important goal was that of correctness and reliability. To this
+end, it was determined that a large automated suite of test programs be
+prepared to assist in regression testing. Preparing the test suite was
+tedious, but achievable. Automating it portably was more difficult.
+
+The difficulty faced was that if FunnelWeb was implemented in the form of
+a utility that could be
+invoked from the operating system command language, the only way to set up
+regression testing was in the command language of the operating system
+of the target machine (shellscripts for UNIX, DCL for VMS, batch files
+for MSDOS, and \i{nothing} on the Macintosh). The huge variation in these
+command languages led to the conclusion that either the automation of
+regression testing would have to be rewritten on each target machine, or
+a small command language would have to be created within FunnelWeb. In the
+end, the twin goals of portability and regression testing were considered so
+important that a small command
+shell was constructed inside FunnelWeb. This is called the
+\newterm{FunnelWeb command shell}, or just \dq{the shell} for short.
+
+By default, when FunnelWeb is invoked, it does not enter its shell. If
+just given the name of an input file, it will simple process the input file
+in the normal manner and then terminate. To instruct FunnelWeb to
+invoke its shell, the \p{+K} or \p{+X} command line option must be specified
+when FunnelWeb is invoked from the operating system. It is also
+invoked upon startup if the file \p{fwinit.fws} exists.
+
+Most FunnelWeb users will never need to use the shell and need not even
+know about it. There are four main uses of the shell:\xx{uses}{shell}
+
+\begin{enumerate}
+
+\item As a tool to support automated regression testing.
+
+\item As a development tool on machines that do not have a built in shell
+(\eg{}the Macintosh). The shell can be used to process whole groups of
+files automatically.
+
+\item As a convenience. A user working on a multi-tasking, multi-window
+workstation\x{workstation}
+may wish to keep an interactive session of FunnelWeb going in
+one window rather than having to run up the utility each time it is required.
+
+\item As a convenient
+vehicle for enclosing utilities. The FunnelWeb shell contains
+useful general purpose commands such as the
+differences command \p{diff}.
+
+\end{enumerate}
+
+\subsection{Return Statuses}
+\xx{errors}{shell}\xx{status}{success}%
+\xx{status}{warning}\xx{status}{error}\xx{status}{severe}\xx{status}{fatal}%
+\xx{status}{assertion}
+
+The hierarchy of diagnostics described in Section~\ref{diagnostics}
+is also used in the
+shell commands. Each shell command returns a status which can affect
+further processing.
+
+\narrowthing{Success}{status is the normal command return status.}
+
+\narrowthing{Warning}{status is returned if some minor problem
+arose with the execution of the command.}
+
+\narrowthing{Error}{status is returned if a significant problem
+arises during the execution of the command.
+However, unlike a severe error,
+it does \i{not} cause termination of the enclosing shellscript.}
+
+\narrowthing{Severe error}{status is returned if a problem arises
+during the execution of the command that prevents the command from
+delivering on its \dq{promise}. A severe error causes FunnelWeb
+to abort the script (and any stacked scripts) to the interactive level.
+(However, the \p{tolerate} command allows this to be temporarily
+overridden).}
+
+\narrowthing{Fatal error}{status is returned if a problem arises
+that is so serious that execution of FunnelWeb cannot continue.
+A fatal error causes FunnelWeb to abort to the operating system level.}
+
+\narrowthing{Assertion error}{status is never returned. If an assertion
+error occurs, FunnelWeb bombs out ungracefully to the operating system.
+Assertion errors should never happen. If they do, then there is a bug
+in FunnelWeb.}
+
+To be precise, the status returned by each command
+is a vector of numbers being the number of each of the different kinds of
+diagnostic generated by the command. Usually only one kind
+of diagnostic is generated. However, the \p{fw} command and a few of the other
+commands can generate more than one kind of diagnostic.
+These status vectors are summed internally where they may later be accessed
+using the \p{status} command. However, the current diagnostic state
+evaporates as soon as the next command is encountered.
+
+\subsection{Command Line Length}
+\xx{command}{length}
+
+The maximum length of a shell command line is guaranteed to be
+at least 300 characters.
+
+\subsection{String Substitution}
+\label{stringsubstitution}\xx{string}{substitution}
+
+Most command shells provide some form of string substitution so
+as to provide some degree of parameterization.
+The FunnelWeb shell provides 36 different string variables named
+\p{\$0..\$9} and \p{\$A..\$Z} (case insensitive).
+Each variable can hold a string containing
+any sequence of printable characters and can be as long as a command line.
+
+The \p{define} command\xx{define}{command}
+allows the user to assign a value to these variables.
+The \p{define} command takes two arguments. The first is the digit or letter
+of the
+variable to be defined. The second is a double quote delimited string being the
+string value to be assigned to the variable. If you want to include a
+double quote character within the string, you don't need to double it.
+
+Examples:
+
+\begin{verbatim}
+define 3 "/root/usr/usrs/users/users5/thisuser/workdir/fwdir/testdir"
+define M "/user/local/rubbish/bin/fw"
+define Q "You don't need to double" double quotes"
+\end{verbatim}
+
+Only the identifying character of the variable being assigned
+is used in the definition. This syntax is a simple way of preventing
+the variable from being substituted before it has a chance to be
+defined!
+
+The following points clean up the remaining semantic details:
+
+\begin{itemize}
+
+\item There is only one set of variables and they are global to all
+shellscripts. There are \i{no local variables}.
+
+\item When a shellscript is invoked using the \p{execute} command, the
+substitution variables \p{0} through \p{9} are affected. See
+Section~\ref{executecommand} for more details.
+
+\item If you want to include a dollar sign character in a command
+use \dqp{\$\$}.
+
+\item FunnelWeb also defines \dqp{\$/} which translates to the character
+that separates directory and file name fields in file names on the host
+machine. For example: Sun=\dqp{/}, Vax=\dqp{]}, Mac=\dqp{:},
+PC=\dqp{\bs{}}.
+
+\item Substitution is not performed recursively.
+
+\end{itemize}
+
+\subsection{How a Command Line is Processed}
+\xx{command line}{processing}
+
+When FunnelWeb reads in a command line (from the console or a script file),
+it processes it in the following sequence:
+
+\begin{enumerate}
+
+\item The command line is checked for non-printable characters. If there
+are any, they are flagged with a severe error.
+
+\item All dollar string substitution variables in the command line are
+replaced by their corresponding string.
+The command line is processed from left to right. Substitutions are
+performed non recursively.
+
+\item At this point, if the line is empty, or consists entirely of
+blanks, it is ignored and the interpreter moves to the next line.
+
+\item A severe error is generated if the line at this stage begins with
+a blank.
+
+\item If the first character of the line is \dqp{!}, the line is a
+comment line and is ignored.
+
+\item The run of non-blanks commencing at the start of the line is
+compared case-insensitively to each of the legal command verbs. If the
+command is illegal, a severe error is generated, otherwise the command
+is processed.
+
+\end{enumerate}
+
+\subsection{Options}
+\xx{command}{options}\xx{default}{options}
+
+The FunnelWeb shell maintains three sets of command line options.
+
+\begin{enumerate}
+
+\item The set of options resulting from applying the operating system
+level command line
+arguments to the default option settings.
+
+\item A set of shell options that prevail during the shell invocation.
+
+\item The set of option values active during a particular invocation
+of FunnelWeb proper.
+
+\end{enumerate}
+
+When FunnelWeb is invoked from the operating system with just \p{+F},
+only the first of these three sets comes into existence. If the user
+invokes the FunnelWeb shell, the shell options come into existence and are
+initialized with the value of the first set. These shell options are
+used as the default for all subsequent \p{fw} commands. However,
+they can be altered using the script command \p{set}. If a
+\p{fw} command executed in a shell contains additional command line options,
+these override the shell options for that run, but do not change the
+shell options. An example follows:
+
+\begin{verbatim}
+$ fw +k +t ! Original invocation of FunnelWeb from OS.
+ ! Shell options are now default with "+t".
+FunnelWeb>fw sloth ! Equivalent to fw sloth +t.
+FunnelWeb>set -l ! Change the l shell option.
+FunnelWeb>fw sloth +q ! Equivalent to fw sloth +t -l +q.
+FunnelWeb>fw sloth ! Equivalent to fw sloth +t -l.
+\end{verbatim}
+
+The existence of the shell option set means that the user can set up
+a set of defaults to be applied to all \p{fw} commands issued within
+the shell.
+
+\subsection{Shell Commands}
+\xx{shell commands}{list}\xx{commands}{shell}
+
+This section describes each of the FunnelWeb shell commands. The syntax
+is:
+
+\begin{verbatim}
+shell_command = absent | codify | compare | define | diff | diffsummary |
+ diffzero | eneo | execute | exists | fixeols | help |
+ here | quit | set | show | skipto | status |
+ tolerate | trace | write | writeu
+s = {" "}+
+\end{verbatim}
+
+As a rule, FunnelWeb shell commands return severe status if their
+arguments are syntactically incorrect or if they are
+unable to successfully operate on argument files.
+
+\subsubsection{Absent}
+\xx{command}{absent}
+
+The \p{absent} command performs no action except to return a status. If the
+file specified in its argument doesn't exist
+it returns success status, otherwise it returns severe status.
+
+\begin{verbatim}
+Syntax : absent = "absent" s filename
+Example: absent result.out
+\end{verbatim}
+
+This command is useful in regression testing
+for making sure that
+FunnelWeb \i{hasn't} produced a particular output file.
+
+\subsubsection{Codify}
+\xx{command}{codify}
+
+The \p{codify} command takes two arguments: an input file and an output file.
+It reads each line of the input file and writes a corresponding line to the
+output file. The corresponding line consists of a C macro call containing
+a string containing the input line. The command converts all backslashes in
+input lines to double backslashes so as to avoid unwanted interpretations by
+the C compiler. It also converts double quotes in the line to backslashed
+double quotes.
+
+\begin{verbatim}
+Syntax : codify = "codify" s filename s filename
+Example: codify header.tex header.c
+\end{verbatim}
+
+The following example demonstrates the transformation.
+
+\begin{verbatim}
+Input Line: \def\par{\leavevmode\endgraf}% A "jolly good hack".
+Output Line: WX("\\def\\par{\\leavevmode\\endgraf}% A \"jolly good hack\".");
+\end{verbatim}
+
+The \p{codify} command was introduced to assist in the
+development of FunnelWeb.
+It is used to convert longish text files
+into C code to write them out. The C code is then included within
+the FunnelWeb C program. For example,
+the set of \TeX{} definitions that appears at the top of every
+documentation file was \p{codif}ied and inserted into the
+FunnelWeb code so that FunnelWeb would not have to look for a file containing
+the definitions at run time.
+
+\subsubsection{Compare}
+\xx{command}{compare}
+
+The \p{compare} command takes two filename arguments and performs a binary
+comparison of the two files. If the files are identical, success status
+is returned. If they are different, severe status is returned. No information
+about the manner in which the files differ is conveyed.
+
+\begin{verbatim}
+Syntax : compare = "compare" s filename s filename
+Example: compare result.txt answer.txt
+\end{verbatim}
+
+The \p{compare} command was created as the main checking mechanism for
+regression testing. However, its binary output was soon found to be
+unworkable and the more sophisticated \p{diff} command was added so
+that the actual differences between the files could be examined.
+
+\subsubsection{Define}
+\xx{command}{define}\xx{string}{substitution}
+
+The \p{define} command
+assigns a value to a shell string substitution variable.
+The \p{define} command takes two arguments. The first is the digit or letter
+of the
+variable to be defined. The second is a double quote delimited string being the
+string value to be assigned to the variable. If you want to include a
+double quote character within the string, you don't need to double it.
+
+\begin{verbatim}
+Syntax : define = "define" s letter s """" text """"
+Examples: define 3 "/usr/usrs/thisuser/workdir/fwdir/testdir"
+ define M "/user/local/rubbish/bin/fw"
+ define Q "You don't need to double" double quotes"
+\end{verbatim}
+
+The command interpreter expands the command line before it executes the
+\p{define} command. This means that you can define string substitution
+variables in terms of each other with static binding.
+
+The \p{define} command was introduced to allow the parameterization
+of the directories involved in regression testing.
+
+See Section~\ref{stringsubstitution} for more details.
+
+\subsubsection{Diff}
+\xx{command}{diff}\xx{file}{differences}
+
+The \p{diff} command reads in two text files and \i{appends} a report to a log
+file containing a list of the differences between the two input
+files. If the log file does not already exist, an empty one is created first.
+
+\begin{verbatim}
+Syntax : diff = "diff" s filename s filename s filename s ["ABORT"]
+Examples: diff result.tex answer.tex diff.log
+ diff $Otest23.out $Atest23.out $Ldiff.log ABORT
+\end{verbatim}
+
+The \p{diff} command performs a full line-based differences operation.
+It will identify different sections in a file, even if they are of differing
+length.
+
+The implementation of the \p{diff} command is quite complicated. To be
+sure that it is at least getting its same/different proclamation right,
+the \p{diff} command performs a binary comparison as an extra check.
+
+The following points describe the rules for determining the result status.
+
+\begin{enumerate}
+
+\item \p{diff} aborts with a
+severe error if the log file cannot be opened or
+created for appending.
+
+\item An ordinary error is generated if either or both of the input files
+cannot be opened.
+
+\item If, at the end of the run, the two input files have not
+been proven to be identical, and the \p{ABORT} keyword is present, \p{diff}
+returns severe status.
+
+\item \p{diff} returns success status if none of the above conditions
+(or similar conditions) occur, even if the two files are different.
+
+\end{enumerate}
+
+The \p{diff} command \i{appends} its differences report rather than
+merely writing it. This allows a regression test script to perform
+a series of regression tests and produce a report for the user.
+
+The \p{diff} command was added to the shell after it had become apparent
+that the simpler \p{compare} command was not yielding enough information.
+Whereas early on, regression testing was treated
+mainly as a tool to ensure that FunnelWeb was being ported to other machines
+correctly, it began to place an increasing role during development in
+identifying the effects of changes made to the code. The \p{diff} command
+supports this application of regression testing by pinpointing the
+differences between nearly-identical text files.
+
+\subsubsection{Diffsummary}
+\xx{command}{diffsummary}
+
+The \p{diffsummary} command writes a short report to the
+console giving the number of
+difference operations that have taken place and how many of the pairs
+of files compared were identical. Counting starts at the most recent
+execution of a \p{diffzero} command, or if there has been none, when
+FunnelWeb started up.
+
+\begin{verbatim}
+Syntax : diffsummary = "diffsummary"
+Examples: diffsummary
+\end{verbatim}
+
+The \p{diffsummary} command was added so as to allow regression testing
+scripts to display a summary of the results of the test. If the summary
+indicates that no pair of files differed, then there is no need to look
+in the \p{diff} log file.
+
+\subsubsection{Diffzero}
+\xx{command}{diffzero}
+
+The \p{diffzero} command zeros the different summary counters used by the
+\p{diff} and \p{diffsummary} commands.
+
+\begin{verbatim}
+Syntax : diffzero = "diffzero"
+Examples: diffzero
+\end{verbatim}
+
+The \p{diffzero} command was added so as to allow regression testing
+shellscripts to zero their differences counters at the start of a run.
+This allows testers to invoke the same regression testing script
+twice in one interactive session without receiving an inflated
+differences summary.
+
+\subsubsection{Eneo}
+\xx{command}{eneo}
+
+The \p{eneo} command takes one filename argument. If the file does
+not exist, no action is taken. If the file does exist, it is deleted.
+In both cases success status is returned. However, if the file exists
+and cannot be deleted, \p{eneo} returns severe status.
+
+\begin{verbatim}
+Syntax : eneo = "eneo" s filename
+Examples: eneo result.out
+\end{verbatim}
+
+The \p{eneo} command was added so as to allow regression testing scripts
+to ensure that existing output files were not present before proceeding
+with a test run. If FunnelWeb were to fail to generate an output file, it
+would be
+extremely undesirable for the old version to be used.
+
+ENEO stands for \b{E}stablish the \b{N}on \b{E}xistence \b{O}f.
+Most operating systems provide a command to delete files. Typically
+these commands are verbs such as \dq{delete}, \dq{remove}, and \dq{kill}.
+As a consequence, the designers of delete commands usually
+consider the command to have failed if it fails to find the file to be
+deleted. However, in my experience, the most common use
+for the delete command
+is to \i{establish the non-existence of} one or more files. Typically, a
+script is starting up and needs to clear the air before getting started.
+If the files are there, they should be deleted; if they are not, then that's
+OK too.\footnote{As far as I know, the \p{eneo} command is original.}
+
+\subsubsection{Execute}
+\label{executecommand}\xx{command}{execute}
+
+The \p{execute} command causes a specified text file to be
+executed as a FunnelWeb shellscript. The first argument is the
+name of the script file.
+The remaining arguments are assigned to the substitution
+variables \p{\$1}, \p{\$2}, $\ldots$, \p{\$9}.
+Substitution variables in the range
+\p{\$1} to \p{\$9} that do not correspond to an argument are set to
+the empty string \p{""}. \p{\$0} is set to the empty string regardless.
+The execute command can be used recursively, allowing shell scripts to
+invoke each other. A file extension default of \dqp{.fws}
+(FunnelWeb Script) applies to script files.
+
+\begin{verbatim}
+Syntax : execute = "execute" s filename {argument_string}
+Examples: execute megatest.fws /usr/users/ross/fwtest !
+ execute sloth
+\end{verbatim}
+
+The first example above will result in the following substitution variable
+assignments.
+
+\begin{verbatim}
+$0 = ""
+$1 = "/usr/users/ross/fwtest"
+$2 = "!"
+$3 = ""
+...
+$9 = ""
+\end{verbatim}
+
+It should be stressed that there are no local variables in the FunnelWeb
+command language; the variables above are globally modified.
+
+The \p{execute} command was added to allow the creation of sub-scripts
+to test FunnelWeb in particular ways.
+
+\subsubsection{Exists}
+\xx{command}{exists}
+
+The \p{exists} command performs no action except to return a status. If the
+file specified in its argument exists
+it returns success status, otherwise it returns severe status.
+
+\begin{verbatim}
+Syntax : exists = "exists" s filename
+Example: exists test6.fw
+\end{verbatim}
+
+This command is useful in regression testing
+for ensuring that
+FunnelWeb has produced a particular output file.
+
+\subsubsection{Fixeols}
+\xx{command}{fixeols}
+
+The \p{fixeols} command takes two filename arguments: an input file and
+an output file. It reads in the input file and writes it to the output file
+changing all the end of line control character
+sequences to the local format. It can also take one filename argument, in
+which case it replaces the target file with its transformation.
+
+\begin{verbatim}
+Syntax : fixeols = "fixeols" s filename [s filename]
+Examples: fixeols imported.hak result.kln
+ fixeols sloth.dat
+\end{verbatim}
+
+The \p{fixeols} command works by parsing the input file into alternating
+runs of
+printable characters (ASCII 20 to ASCII 126) and runs of non-printable
+characters (all the others).
+It then\xx{non-printable}{characters}
+parses each run of non-printable characters from left to right into
+subruns of non-printables not containing the same character twice.
+It then replaces each subrun with a native EOL.\footnote{Note: A native
+EOL can be inserted into a text file in a portable manner
+simply by writing \dqp{\bs{}n} to the text output stream.}
+For example,
+if a native EOL is \p{X}, and \p{ABCD} are non-printable characters, and
+the file to be converted is
+
+\begin{verbatim}
+thisABisABCDanABABexampleABCCCof the conversion.
+\end{verbatim}
+
+then \p{fixeols} would produce
+
+\begin{verbatim}
+thisXisXanXXexampleXXXof the conversion.
+\end{verbatim}
+
+The \p{fixeols} command was devised to solve the problem created sometimes
+when text files are moved from one machine to another
+(\eg{}with the kermit program)
+using a binary transfer mode rather than a text transfer mode.
+If such a transfer is made, and the text file line termination conventions
+differ on the two machines, one can wind up with a set of
+text files with improperly terminated lines. This can cause problems
+on a number of fronts, but in particular affects regression testing
+which relies heavily on exact comparisons between files. The \p{fixeols}
+command provides a solution to this problem by providing a portable way
+to \dq{purify} text files whose end of lines have become incorrect.
+The regression testing scripts all apply \p{fixeols} to their input and
+output files before each test.
+
+\subsubsection{Fw}
+\xx{command}{fw}
+
+The \p{fw} command allows FunnelWeb proper to be invoked from a shell
+script. The syntax is almost identical to the syntax with which FunnelWeb is
+invoked from the operating system.
+
+\begin{verbatim}
+Syntax : fw = "fw" s ordinary_funnelweb_command_line
+Examples: fw sloth +t +d
+ fw -l walrus
+\end{verbatim}
+
+Some important points about this \p{fw} command are:
+
+\begin{itemize}
+\item Options are inherited from the default shell options.
+\item The \p{F} (input file option) must be turned on.
+\item The \p{K}, \p{H}, and \p{X} options must be turned off.
+\item The \p{J} option must be turned off.
+\item The options specified in a \p{fw} command do not affect the default
+shell options.
+\item This command performs no action in the VAX VMS version of FunnelWeb.
+\end{itemize}
+
+\subsubsection{Help}
+\xx{command}{help}
+
+The \p{help} command provides online help from within the FunnelWeb shell.
+It provides access to all of the same messages that the \p{+H} command
+line option does.
+
+\begin{verbatim}
+Syntax : help = "help" [s help_message_name]
+Examples: help
+ help commands
+\end{verbatim}
+
+If no message name is given, the default message is displayed. It contains
+a list of the other help messages and their names. The actual messages
+themselves are not listed here.
+
+\subsubsection{Here}
+\xx{command}{here}
+
+The \p{here} command acts as a target for the \p{skipto} command. When
+the shell interpreter encounters a \p{skipto} command, it ignores all
+the following commands until it encounters a \p{here} command.
+
+\begin{verbatim}
+Syntax : here = "here"
+Example: here
+\end{verbatim}
+
+The \p{skipto}/\p{here} mechanism was created to allow groups of
+regression tests to be skipped during debugging without having to comment
+them out. For more information, see Section~\ref{skiptocommand}.
+
+\subsubsection{Quit}
+\xx{command}{quit}
+
+The \p{quit} command terminates FunnelWeb immediately and returns
+control to the operating system. This applies regardless of the depth
+of the script being executed.
+
+\begin{verbatim}
+Syntax : quit = "quit"
+Example: quit
+\end{verbatim}
+
+\subsubsection{Set}
+\xx{command}{set}
+
+The \p{set} command modifies the default shell options.
+For example, \p{set +t} sets the \p{+t} option for all subsequent
+FunnelWeb runs within the shell until another set command
+sets \p{-t}.
+
+\begin{verbatim}
+Syntax : set = "set" s ordinary_funnelweb_command_line
+Examples: set sloth +t +d
+ set -lwalrus
+\end{verbatim}
+
+The restrictions on the \p{set} command are identical to those on the
+\p{fw} command except that, in addition,
+the \p{+F} option cannot be turned on in the \p{set} command.
+
+The set command is useful for setting option defaults before a long run
+of regression tests. It could also be useful to set default options in
+a FunnelWeb shell kept by a user in a workstation window.
+
+\subsubsection{Show}
+\xx{command}{show}
+
+The \p{show} command displays the current default shell options.
+These options are the options that subsequent \p{fw} commands will
+inherit.
+
+\begin{verbatim}
+Syntax : show = "show"
+Example: show
+\end{verbatim}
+
+\subsubsection{Skipto}
+\label{skiptocommand}\xx{command}{skipto}
+
+The \p{skipto} command causes the shell to ignore all subsequent commands
+until a \p{here} command is encountered.
+
+\begin{verbatim}
+Syntax : skipto = "skipto"
+Examples: skipto
+\end{verbatim}
+
+The \p{skipto}/\p{here} mechanism was created to allow groups of
+regression tests to be skipped during debugging without having to comment
+them out. It is like a cut price \p{goto}.
+For example, supposing that there were eight tests and that
+you had debugged the first five. You might want to skip the first five
+tests so that you can concentrate on the next three. The following
+code shows how this can be done.
+
+\begin{verbatim}
+skipto
+execute test infile1
+execute test infile2
+execute test infile3
+execute test infile4
+execute test infile5
+here
+execute test infile6
+execute test infile7
+execute test infile8
+\end{verbatim}
+
+It should be stressed that FunnelWeb performs full command line processing
+including the dollar substitutions before testing the line to see if
+it is \p{here}. This can lead to non-obvious problems. For example.
+
+\begin{verbatim}
+skipto
+! Test the Parser
+! ---------------
+define X "execute parsertest.fws"
+$X infile1
+$X infile2
+$X infile3
+$X infile4
+$X infile5
+here
+\end{verbatim}
+
+The above looks correct, but, because the \p{define} command isn't executed
+(and \p{\$X} is not defined) the subsequent \p{\$X} lines result in a
+leading blanks error. The problem can be corrected by defining \p{\$X}
+before the \p{skipto} command.
+
+\subsubsection{Status}
+\xx{command}{status}
+
+The \p{status} command takes two forms. In its first form in which
+no arguments are given, it writes out the number of warnings, errors
+and severe errors that 1) were generated by the previous command
+and 2) have been generated during the entire shell invocation.
+In its second form it takes from one to three arguments each of which
+specifies a diagnostic severity and a number. The \p{status} command
+compares each of these numbers with the number of that diagnostic
+generated by the previous command and generates a severe error if
+they differ.
+
+\begin{verbatim}
+Syntax : status = "status" {s ("w"|"e"|"s") num}0..3
+Examples: status
+ status w1 e5 s1
+ status w4
+ status s1 e2
+\end{verbatim}
+
+The \p{status} command was introduced to test the status results of
+commands during their debugging. It is also useful for checking to see that
+the right number of diagnostics have been generated at particular points
+in test scripts.
+
+\subsubsection{Tolerate}
+\xx{command}{tolerate}
+
+The \p{tolerate} command instructs the shell not to abort processing
+of the script if the next command generates one or more warnings, errors,
+or severe errors. For the purposes of this command, a blank line counts
+as a command, so be sure to place the \p{tolerate} command immediately
+above the command about which you wish to be tolerant.
+
+\begin{verbatim}
+Syntax : tolerate = "tolerate"
+Example: tolerate
+\end{verbatim}
+
+The tolerate command was introduced to allow FunnelWeb (\ie{}the
+\p{fw} command) to be tested
+in a script under conditions which would normally cause it to abort the
+script.
+
+\subsubsection{Trace}
+\xx{command}{trace}
+
+The \p{trace} command turns on or off command tracing during script
+execution. By default, tracing is turned off.
+
+\begin{verbatim}
+Syntax : trace = "trace" [s ("on" | "off")]
+Examples: trace on
+ trace off
+\end{verbatim}
+
+The \p{trace} command was introduced to assist in the debugging of
+regression test scripts.
+
+\subsubsection{Write}
+\xx{command}{write}
+
+The \p{write} command accepts a double-quoted argument and writes it followed
+by an EOL to the console (standard output).
+There is no need to double any double quotes
+occurring within the string.
+
+\begin{verbatim}
+Syntax : write = "write" s string
+Examples: write "Now about to start the next test."
+ write "You don't need to " double enclosed double quotes."
+\end{verbatim}
+
+The \p{write} command was added so as to allow regression testing scripts
+to inform the user of their progress.
+
+\subsubsection{Writeu}
+\xx{command}{writeu}
+
+The \p{writeu} command is identical to the \p{write} command except that it
+underlines the text on an additional following output line.
+
+\begin{verbatim}
+Syntax : writeu = "writeu" s string
+Examples: writeu "Test 6"
+\end{verbatim}
+
+\section{Concluding Remarks}
+
+This chapter defines the semantics of the FunnelWeb program. As stated
+at the start of this chapter, this document takes precedence over the
+FunnelWeb program. While the
+definition of FunnelWeb in this chapter is reasonably solid, it is far
+from watertight, and it is hoped that it can be tightened further in
+future versions. All constructive criticism will be gratefully received
+by the author Ross Williams (\p{ross@spam.adelaide.edu.au}).
+
+%==============================================================================%
+% End of Ch3.tex %
+%==============================================================================%
diff --git a/web/funnelAC/userman/u_ch4.tex b/web/funnelAC/userman/u_ch4.tex
new file mode 100644
index 0000000000..82a9be4010
--- /dev/null
+++ b/web/funnelAC/userman/u_ch4.tex
@@ -0,0 +1,468 @@
+%==============================================================================%
+% Start of Ch4.tex %
+%==============================================================================%
+%
+% Copyright
+% ---------
+% Copyright (C) 1992 Ross N. Williams.
+% This file contains a chapter of the FunnelWeb User's Manual.
+% See the main TeX file for this manual for further information.
+%
+%==============================================================================%
+
+\chapter{FunnelWeb Installation}
+\label{chapinstall}\xx{FunnelWeb}{installation}
+
+This chapter describes how to obtain, compile, and install FunnelWeb.
+You will need:
+
+\begin{itemize}
+
+\item FTP access to the internet \i{or} a FunnelWeb distribution kit on disk.
+
+\item A Sun, VMS VAX, Macintosh, or PC \i{or} lots of extra time to port
+FunnelWeb to a new platform.
+
+\item About four megabytes of free disk space. You might be able to
+install it with less, but four megabytes is safe. The distribution kit itself
+is about two and a half megabytes.
+If you are short on space, you can throw away everything after installation
+except the binary executable which will consume about half a megabyte.
+
+\item A C compiler.
+
+\item An acquaintance with the C programming language and the ability to
+compile and link C programs on your machine.
+
+\item Elementary systems programming knowledege for your machine.
+
+\item About an hour.
+
+\end{itemize}
+
+You will \i{not} need any sort of system privileges to install FunnelWeb,
+unless you want the FunnelWeb command \p{fw} to be automatically available
+to everyone on your machine as well as yourself.
+
+\section{Obtaining a Copy of FunnelWeb}
+\xx{FunnelWeb}{obtaining}\xx{ftp}{anonymous}
+
+The simplest way to obtain a copy of FunnelWeb is by anonymous FTP from:
+
+\begin{verbatim}
+ Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3].
+ Directory : ~pub/funnelweb/ (or a directory of similar name).
+\end{verbatim}
+
+It is not clear at the time of writing whether FunnelWeb will be presented
+as a \dqp{.tar} file, or as a directory tree,
+or both. Just sniff around and use
+your common sense. Two points deserve attention however:
+
+\begin{enumerate}
+
+\item Be sure to use the \i{text} transfer mode whenever you transfer
+raw FunnelWeb files. However, you should use \i{binary} mode for TAR files
+and other conglomerate representations.
+
+\item If you have to transfer the files individually,
+don't lump all the FunnelWeb files into a single directory. Refer to
+the sections that follow for information on the directory tree you should
+create to receive the FunnelWeb files.
+
+\end{enumerate}
+
+If anonymous FTP is not available to you, contact the author
+for up-to-date information on other channels of distribution.
+
+\begin{verbatim}
+ Name: Dr Ross N. Williams
+ Email: ross@spam.adelaide.edu.au
+ Snail: 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+\end{verbatim}
+
+\section{Establishing The Directory Tree}
+\xx{directory}{tree}
+
+At this stage,
+we will assume that you have somehow obtained a set of files that
+are supposed to be FunnelWeb, and that they are sitting on a disk
+on the machine on which you wish to compile and install
+FunnelWeb.
+
+The first thing you have to do is to make sure that
+the FunnelWeb directory tree has been correctly unpacked. The directory
+tree should look like this.
+
+\begin{verbatim}
+ fwdir - Root FunnelWeb directory.
+ admin - Administrative files.
+ answers - Answers to test suite.
+ hackman - FunnelWeb Hacker's Manual.
+ results - For test results.
+ scripts - Test scripts.
+ sources - Source code.
+ tests - Test suite.
+ userman - FunnelWeb User's Manual.
+\end{verbatim}
+
+The following sections describe the contents of each directory in
+alphabetical order. Check the
+contents to make sure that you have everything. Do not become fussed if
+your configuration is not quite as specified as
+it is very easy for
+installation guides such as this one to go out
+of date as minor last minute changes and updates
+are made to the distribution kit. Check the source from which you obtained
+the kit, and if it is different too, proceed.
+
+\subsection{Admin Directory}
+\xx{admin}{directory}
+
+The \p{admin} directory contains administrative files to do with licensing
+and such. It is also a catch-all directory for files that don't belong
+anywhere else. At the time of writing, it is not clear
+exactly what will be in the \p{admin} directory. Why not take a look?
+
+\subsection{Answers Directory}
+\xx{answers}{directory}
+
+The \p{answers} directory contains the
+\dq{correct answers}\xx{correct}{answers}
+to all the regression testing input files. The regression test scripts
+compare these files to the files generated in the \p{results} directory.
+
+\begin{verbatim}
+an01.lis ... an04.lis
+ex01.lis ... ex16.lis
+ex01.out ... ex10.out
+ex11.tex ... ex16.tex
+generate.lis
+hi01.lis ... hi10.lis
+hi01.out ... hi05.out
+hi06a.out
+hi06b.out
+hi07a.out
+hi07b.out
+hi08.out ... hi10.out
+pr01.lis ... pr10.lis
+sc01.lis ... sc29.lis
+tg01.lis ... tg09.lis
+tg01.out ... tg09.out
+wv01.lis ... wv06.lis
+wv01.tex ... wv06.tex
+\end{verbatim}
+
+\subsection{Hackman Directory}
+\xx{hackman}{directory}
+
+The \p{hackman} directory contains the \p{.tex} files that make up the
+\i{FunnelWeb Hacker's Manual}.
+
+\begin{verbatim}
+h_ch0.tex - Preface, etc.
+h_ch1.tex - Design.
+h_ch2.tex - Implementation.
+h_ch3.tex - Modification.
+h_ch4.tex - Future.
+h_cha.tex - Appendices.
+h_manual.tex - Main TeX file.
+\end{verbatim}
+
+See the comment at the top of \p{h\_manual.tex} file for
+instructions on how to typeset and print the \i{FunnelWeb Hacker's Manual}.
+
+There is no need to read or print the \i{FunnelWeb Hacker's Manual} unless you
+intend to modify FunnelWeb.
+
+\subsection{Results Directory}
+\xx{results}{directory}
+
+The \p{results} directory exists as a target directory for
+the output files generated by FunnelWeb during regression testing.
+This directory is distributed empty and
+should be empty at the start of regression testing.
+However, it is permissible for the \p{results} directory to
+contain files generated
+during a previous test run, as the regression testing scripts
+delete specific unwanted files before each test anyway.
+
+\subsection{Scripts Directory}
+\xx{scripts}{directory}
+
+The \p{scripts} directory stores the FunnelWeb command shell scripts that
+are used to perform regression testing.\xx{regression}{testing}
+
+\begin{verbatim}
+master.fws - The master test script. This is the one you run.
+test_gen.fws - Script to generate certain tricky input files.
+test_l.fws - Test FunnelWeb with +L.
+test_ld.fws - Test FunnelWeb with +L +B...
+test_lo.fws - Test FunnelWeb with +L +O.
+test_lo2.fws - Test FunnelWeb with +L +O (two output files).
+test_lot.fws - Test FunnelWeb with +L +O +T.
+test_lt.fws - Test FunnelWeb with +L +T.
+\end{verbatim}
+
+\subsection{Sources Directory}
+\xx{sources}{directory}
+
+The \p{sources} directory contains \i{all} of the C source files
+required to build a FunnelWeb binary executable. In the following list,
+files given without an extension represent both \p{.c} and \p{.h} files.
+
+\begin{verbatim}
+analyse - The analyser.
+as - Assertions.
+clock - A clock abstraction.
+command - The shell command interpreter.
+data - Shared data structures and global variables.
+dump - Functions to dump internal data structures.
+environ.h - Lightweight machine-dependent, program-independent header.
+help - Module to write out help messages.
+help_gnu - Function to write out the GNU license.
+help_gnu.txt - The GNU license in text form.
+help_gnu.ctx - The GNU license in C code form.
+list - A list abstraction.
+lister - Module to manage the listing file.
+machin - Module to hold machine-dependent, program-dependent stuff.
+main.c - The main() program.
+mapper - Module to read files into memory.
+memory - Memory management.
+misc - Miscellaneous functions.
+option - Command line option processing.
+parser - The parser.
+scanner - The scanner.
+section - A section number abstraction.
+style.h - A machine-independent, program-independent header file.
+table - A table abstraction.
+tangle - The tangler.
+texhead - Module to write out TeX header in documentation files.
+texhead.ctx - The TeX header in C code form.
+texhead.tex - The TeX header in TeX form.
+weave - The weaver.
+writfile - Output abstraction.
+\end{verbatim}
+
+The \dqp{.txt}, and \dqp{.tex} files do not participate in the compilation,
+but are considered part of the source code as they
+were used to generate the \dqp{.ctx} files. The \dqp{.ctx} files
+are included by \p{.c} files of the same name. They do not need to be
+compiled themselves.
+
+\subsection{Tests Directory}
+\xx{tests}{directory}
+
+The \p{tests} directory stores all the input files of the
+regression test suite. These come in two kinds: FunnelWeb input
+files with extensions of \dqp{.fw}, and FunnelWeb include files with
+extensions of \dqp{.fwi}.
+
+\begin{verbatim}
+FunnelWeb Input Files:
+ an01.fw ... an04.fw - Analyser tests.
+ ex01.fw ... ex16.fw - Examples from the tutorial in user manual.
+ generate.fw - Generates a few other tricky input files.
+ hi01.fw ... hi10.fw - Examples from the hints chapter in user manual.
+ pr01.fw ... pr10.fw - Parser tests.
+ sc01_note.fw - A note explaining absence of sc01.fw
+ sc02.fw ... sc29.fw - Scanner tests.
+ tg01.fw ... tg09.fw - Tangler tests.
+ wv01.fw ... wv06.fw - Weaver tests.
+
+FunnelWeb Include Files:
+ ex09a.fwi
+ sc13a.fwi ... sc13f.fwi
+ sc15a.fwi
+ tg08a.fwi
+\end{verbatim}
+
+\subsection{Userman Directory}
+\xx{userman}{directory}
+
+The \p{userman} directory contains the \p{.tex} files that make up the
+\i{FunnelWeb User's Manual}.
+
+\begin{verbatim}
+u_ch0.tex - Preface, etc.
+u_ch1.tex - Tutorial.
+u_ch2.tex - Hints.
+u_ch3.tex - Definition.
+u_ch4.tex - Installation.
+u_ch5.tex - Administration.
+u_cha.tex - Appendices.
+u_manual.tex - Main TeX file.
+\end{verbatim}
+
+See the comment at the top of \p{u\_manual.tex} file for
+instructions on how to typeset and print the \i{FunnelWeb User's Manual}.
+
+\section{Compiling FunnelWeb}
+\xx{compiling}{FunnelWeb}
+
+The FunnelWeb source code is entirely contained within the \p{sources}
+directory. However, some simple
+script files and makefiles can be found in the \p{admin} directory.
+
+FunnelWeb contains some machine-dependent components, so before compiling
+FunnelWeb, you need to specify your machine in the source file \p{environ.h}.
+To do this,
+edit the \p{environ.h} file and set exactly one of the machine name
+\p{\#define}s to \p{1}. For example, on the Sun you should set:
+
+\begin{verbatim}
+#define MAC 0
+#define SUN 1
+#define VMS 0
+#define PC 0
+\end{verbatim}
+
+There should be little difficulty compiling FunnelWeb for any of these
+platforms.
+If the machine on which you are compiling FunnelWeb is not one of the ones
+listed in the \p{environ.h} file, then choose the closest one you can.
+Try the \p{SUN} if you are running a non-Sun Unix.
+If you run into serious difficulties, you will have to
+customize \p{machin.h} and \p{machin.c} for your machine.
+See the comments in these files
+for instructions on how to do this.
+
+Once you have specified a target machine, compile FunnelWeb by pointing
+your C compiler at all the
+\dqp{.c} files in the \p{sources} directory.
+The \dqp{.txt}, and \dqp{.tex} files do not participate in the compilation,
+but appear in the \p{sources} directory because they
+were used to generate the \dqp{.ctx} files. The \dqp{.ctx} files
+are included by \p{.c} files of the same name and do not need to be
+compiled separately.
+Link the results.
+
+The result of all this should be a binary executable called
+\p{fw}, or \p{fw.exe},
+or \p{fw.xxx} where \p{.xxx} is whatever file extension is
+appropriate on the target machine. Clean up the
+\p{sources} directory by deleting all the listing and object files.
+
+\section{Testing FunnelWeb}
+\label{testingfunnelweb}\xx{testing}{FunnelWeb}
+
+Once you have obtained a binary executable, you should test FunnelWeb
+before making it available to users. To do this:
+
+\begin{enumerate}
+
+\item Set the default directory to be the \p{scripts} directory.
+
+\item Copy the FunnelWeb executable into the scripts directory (or
+be able to invoke it from the scripts directory).
+
+\item Edit the script \p{master.fws}. Locate the section called
+\dq{Define Symbol For the Root Test Directory} and define the \p{R}
+symbol to point to the FunnelWeb root directory \p{fwdir}. The examples
+in the comments in the script should make it clear what is required.
+
+\item Invoke FunnelWeb to execute the master test script
+with the command line \p{fw +xmaster}
+
+\end{enumerate}
+
+The \p{master.fws} script should run for a few minutes. If all goes
+well, you will find a differences report on your screen reporting
+zero differences. If this happens, then FunnelWeb has been
+fully tested and is ready to be made available to users. You should
+delete all the files in the \p{results} directory and proceed to the next
+section on installing FunnelWeb for users.
+
+If there were
+one or more differences, you can either give up and contact the author,
+or attempt to fix the code yourself. If you decide to fix the code
+yourself, start
+with the differences log file and follow your nose. Good luck!
+
+\section{Installing FunnelWeb}
+\xx{installing}{FunnelWeb}
+
+At this stage you should have a \p{fwdir} directory tree somewhere in your
+file system. Its contents should be almost identical to the directory
+contents specified earlier in this chapter except there should now be
+an additional binary executable file sitting in the \p{scripts}
+directory.
+
+To make FunnelWeb available to users, you should:
+
+\begin{enumerate}
+
+\item Make the entire directory tree readable to all users.
+
+\item Move the binary executable from the scripts directory to the
+\p{admin} directory \i{or} copy it to somewhere convenient such as
+a \p{/bin} directory.
+
+\item Set up a symbol, path, or command of some kind by the name of \p{fw}
+that \dq{points} to the binary executable. If possible, set this up so
+that the \p{fw} symbol is available to all users. Alternatively,
+you can inform interested users of how they can add a command to their
+\p{login} command file to make the command available to them.
+
+\end{enumerate}
+
+If you are short of disk space or have a system that is stressed in some other
+way, it may be of assistance to you to know that
+FunnelWeb has been constructed so that its
+binary executable\xx{FunnelWeb}{executable} is
+\i{totally self contained}. The binary executable does not rely on any
+other files to operate. Nor does it care about its position in the file system.
+In fact, all that is really required to use FunnelWeb is the binary
+executable and the \i{FunnelWeb User's Manual}. Thus, if you are short
+of disk space, you can move the binary executable to your \dqp{/bin}
+directory and delete the entire FunnelWeb tree. However, making the
+tree available to users is encouraged because:
+
+\begin{itemize}
+
+\item It allows users to copy the tree and install it on another machine
+without bothering you.
+
+\item It allows users access to the \TeX{} code for the \i{FunnelWeb
+User's Manual} and the \i{FunnelWeb Hacker's Manual}.
+
+\item It allows users access to the regression test suite. This may not
+seem important, but it could be very convenient for the user as the
+\p{ex*} and \p{hi*} files of the regression test suite contain most
+of the examples from the \i{FunnelWeb User's Manual}. By making them available
+you will save users the trouble of typing them in.
+
+\end{itemize}
+
+Finally, you should fill in and send off a FunnelWeb registration form.
+This allows me to get a handle on the size and needs of the user base, and you
+to be kept informed of new FunnelWeb releases (optional).
+See Section~\ref{registration} for more information.
+
+\section{Printing Manuals}
+\xx{printing}{manuals}
+
+FunnelWeb comes with two manuals, a \i{FunnelWeb User's Manual} and a
+\i{FunnelWeb Hacker's Manual}. Instructions for how to
+typeset and print these manuals appear at the top of
+the main \TeX{} files for these manuals
+\p{u\_manual.tex} and \p{h\_manual.tex}.
+
+There is no need to print the \i{FunnelWeb Hacker's Manual} unless you
+intend to modify FunnelWeb. However, you should make a few copies of the
+\i{FunnelWeb User's Manual} available for users, or at least
+let them know where the \TeX{} source for the \i{FunnelWeb User's Manual}
+is kept so that they can typeset and print it themselves.
+
+\section{Installation Problems?}
+\xx{problems}{installation}
+
+If you run into any problems installing FunnelWeb, please write a short
+report describing the problem and mail it to the author Ross Williams
+(\p{ross@spam.adelaide.edu.au}). I may not be able to help you with it
+immediately, but I certainly want to know that a problem exists so that
+it can be corrected in future releases of FunnelWeb.
+
+%==============================================================================%
+% End of Ch4.tex %
+%==============================================================================%
diff --git a/web/funnelAC/userman/u_ch5.tex b/web/funnelAC/userman/u_ch5.tex
new file mode 100644
index 0000000000..ab676074f8
--- /dev/null
+++ b/web/funnelAC/userman/u_ch5.tex
@@ -0,0 +1,387 @@
+%==============================================================================%
+% Start of Ch5.tex %
+%==============================================================================%
+%
+% Copyright
+% ---------
+% Copyright (C) 1992 Ross N. Williams.
+% This file contains a chapter of the FunnelWeb User's Manual.
+% See the main TeX file for this manual for further information.
+%
+%==============================================================================%
+
+\chapter{FunnelWeb Administration}
+\label{chapadministration}\xx{FunnelWeb}{administration}
+
+\section{Introduction}
+
+Whether a computer program is useful depends not just on the functionality
+provided by the program, but also on the totality of the culture
+and services surrounding it such as license costs, the
+quality of
+documentation, presence of a standard and so on.
+This chapter addresses these issues from a user perspective.
+
+\section{The User's Commitment To FunnelWeb}
+\xx{commitment}{FunnelWeb}
+
+One of the problems that might prevent potential users from using FunnelWeb
+is the level of commitment that it requires. As soon as the user starts
+creating FunnelWeb \p{.fw} files, the user becomes dependent on the
+FunnelWeb program, as the files so created will become unmanageable if
+the FunnelWeb program were to become unavailable for some reason.
+There are a number of ways in which computer programs can become unavailable,
+including operating system upgrades, copyright problems, inability to
+fix bugs, or just the inability of the program to be ported to a new target
+platform.
+
+The fact
+is that FunnelWeb defines an input language and that currently there is
+only one implementation of the language. Users will only write programs
+using that language if they feel comfortable about the availability of its
+implementation.
+
+I have been critically
+aware of these issues throughout the development of FunnelWeb and have
+taken every possible step to make FunnelWeb a solid base onto which to
+build programs. The following points describe the actions I have taken.
+
+\narrowthing{GNU license:}{FunnelWeb's C source code
+has been released under GNU General Public
+License Version 2. This means that the source code to FunnelWeb will always
+be available to anyone who wants it. The FunnelWeb program can never be
+taken away from you.}
+
+\narrowthing{Portability:}{FunnelWeb has been designed and written to be
+extremely portable. First, all FunnelWeb really does is read and write
+text files. This makes it easy to make portable. Second,
+FunnelWeb is written in the C programming language\paper{ANSI}
+with portability as
+a major design goal. Third, FunnelWeb has already been ported to four
+popular platforms: SunOS, VAX VMS, PC, and Macintosh and it should not prove
+hard to move it to others. Fourth, FunnelWeb comes with a huge automated
+regression test suite. This makes it easy to pinpoint problems when it
+is moved to a new platform. Portability is important because, even if \i{you}
+are not using FunnelWeb on some funny platform, you may want to send
+a computer program written using FunnelWeb to someone who does.}
+
+\narrowthing{Quality:}{The FunnelWeb source code is high quality code.
+Although it has not been formally developed under any particular coding
+standard, it is well designed and documented. Design decisions have
+not been taken lightly.}
+
+\narrowthing{Documentation:}{FunnelWeb is well documented by this manual
+and by the \i{FunnelWeb Hacker's Manual}. This is important because it
+means that if you want to send someone a program written using FunnelWeb,
+you can simply point them to this manual rather than having to explain
+it all yourself. It is also comforting for managers who are controlling
+source code to know that the format in which the source code is written
+is well-documented.}
+
+\narrowthing{Standardization:}{Users who create source files using FunnelWeb
+are not only committing to the FunnelWeb program; they are also investing
+in the FunnelWeb language. If FunnelWeb's language changes radically for
+some reason, then this investment by users will be undermined. To protect
+this investment, I intend to maintain an \dq{official} version of FunnelWeb
+whose language will not change radically, at least not
+in a non backward compatible manner.}
+
+It is my hope that the combination of these factors will alleviate any
+fears that users may have about committing their source files
+to FunnelWeb.
+
+\section{Documentation}
+\xx{FunnelWeb}{documentation}
+
+The following FunnelWeb documentation is available:
+
+\begin{verbatim}
+ "FunnelWeb User's Manual": Tutorial, Hints, Reference Manual.
+ "FunnelWeb Hacker's Manual": Notes on Design and Implementation.
+\end{verbatim}
+
+Everyone involved with FunnelWeb should read the \i{FunnelWeb User's Manual}.
+It contains everything you need to know about how to use FunnelWeb. In fact,
+you are reading it now!
+
+The \i{FunnelWeb Hacker's Manual}
+is for those who want to install, modify, fix,
+fiddle with, and generally hack the FunnelWeb C source code.
+
+Both of these manuals are shipped with the FunnelWeb distribution
+kit, and should be available on your machine in the form of LaTeX text
+files. If you cannot find them, you can obtain them from the
+FunnelWeb FTP archive (see Section~\ref{ftparchive}).
+
+\section{Registration}
+\label{registration}\xx{FunnelWeb}{registration}
+
+If you install or use FunnelWeb, please register by filling in and
+returning the registration form in \figregform{}.
+Feel free to expand the form if there is not enough room.
+
+
+\begin{figure}[htbp]
+\begin{verbatim}
+ +----------------------FunnelWeb Registration Form----------------------+
+ | 1. Date: |
+ | |
+ | 2. Title and name: |
+ | |
+ | 3. Internet email address: |
+ | |
+ | 4. Snail mail address: |
+ | |
+ | 5. Work phone number (country,area,number): |
+ | |
+ | 6. Which category of FunnelWeb user best describes you? |
+ | Latent - Installed FunnelWeb, but don't intend to use it. |
+ | Beginner - Haven't used FunnelWeb much yet; have an open mind. |
+ | Casual - Use FunnelWeb occasionally. |
+ | Convert - Use FunnelWeb to do most programming. |
+ | Fanatic - FunnelWeb has become a way of life. |
+ | |
+ | 7. What changes or new features would you like to see in FunnelWeb? |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | 8. Do you want to be kept informed of new FunnelWeb developments? |
+ | |
+ +-----------------------------------------------------------------------+
+\end{verbatim}
+\mylabel{\figregform{}: The FunnelWeb registration form.}{%
+%
+To register as a FunnelWeb user, please fill in this form and email it to
+\p{ross@spam.adelaide.edu.au}, or snail mail it to
+Ross Williams, 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+You may wish to make a contribution when you register.
+See Section~\ref{support} for more information.
+%
+}
+\end{figure}
+
+Email the form to \p{ross@spam.adelaide.edu.au}, or snail mail it to
+Ross Williams, 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+You may wish to make a contribution when you register.
+See Section~\ref{support} for more information.
+
+\section{Support}
+\xx{FunnelWeb}{support}\label{support}
+
+FunnelWeb is released \dq{as is} under a GNU license, and
+no formal support is available.
+You have the right to make changes to FunnelWeb
+and to use the modified versions created by random programmers.
+However, this is discouraged (see Section~\ref{modification}).
+
+In fact the support that is most needed is your financial
+support for the
+FunnelWeb developers! It has taken \i{months} of full-time \i{unpaid}
+work to bring FunnelWeb to you in its current form.
+I don't want to inconvenience users who install
+FunnelWeb, play with it, and then hardly ever use it.
+If you are in this category,
+please register, but don't bother contributing. However, if you find that
+FunnelWeb has become a useful programming tool, a
+contribution of some positive multiple of US\$50 would be appreciated.
+
+To make a contribution, send payment with a completed registration form
+(see Section~\ref{registration}) to:
+
+\begin{verbatim}
+ Renaissance Software Pty Ltd
+ Email: ross@spam.adelaide.edu.au
+ Snail: 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+\end{verbatim}
+
+Payment can be by personal or bank cheque to any bank in the world or by
+Visa or Mastercard. Please give the card name, number, expiry date, and
+the amount to be paid in US dollars. All contributions will be appreciated
+and will encourage further FunnelWeb development. However, no undertaking
+is made whatsoever about how the money will be used.
+
+\section{Copyright}
+\xx{copyright}{FunnelWeb}\xx{FunnelWeb}{license}\xx{GNU}{license}%
+\label{copyright}
+
+The FunnelWeb program is Copyright $\copyright$ 1992 Ross Williams.
+
+However, FunnelWeb has been released by the author and copyright owner Ross
+Williams (\p{ross@spam.adelaide.edu.au}) under Version 2 of the GNU General
+Public
+License published by the Free Software Foundation. Here are some ways
+that you can obtain a copy of this license.
+
+\begin{itemize}
+
+\item The license appears as an appendix in the \i{FunnelWeb Hacker's
+Manual}.
+
+\item If you have a working version of FunnelWeb, invoke it with
+\p{fw +hlicense +jlicense.txt}.
+
+\item Look in the \p{help} module of the FunnelWeb source code.
+
+\item FTP the license from \p{prep.ai.mit.edu} in \p{/pub/gnu/COPYING-2}.
+
+\item Write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+\end{itemize}
+
+The license allows you to
+redistribute FunnelWeb and/or modify it under certain conditions.
+The license does not cover the \i{FunnelWeb User's Manual} and
+\i{FunnelWeb Hacker's Manual} which are distributed under a simpler
+license that prohibits changes.
+
+Note: FunnelWeb is distributed WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+\section{Nowarranty}
+\x{warranty}
+
+Users of FunnelWeb should be aware that FunnelWeb comes with no
+warranty. Here is an extract from the GNU General Public License Version 2,
+under which
+FunnelWeb is distributed. For more information see Section~\ref{copyright}.
+
+\begin{verbatim}
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+ REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGES.
+\end{verbatim}
+
+\section{Distribution}
+\xx{FunnelWeb}{Distribution}
+
+Users of FunnelWeb should be aware that they can distribute the program
+freely.
+The following is an extract from the GNU General Public License Version 2,
+under which FunnelWeb is distributed.
+
+\begin{verbatim}
+ 1. You may copy and distribute verbatim copies of the Program's
+ source code as you receive it, in any medium, provided that you
+ conspicuously and appropriately publish on each copy an appropriate
+ copyright notice and disclaimer of warranty; keep intact all the
+ notices that refer to this License and to the absence of any warranty;
+ and give any other recipients of the Program a copy of this License
+ along with the Program.
+
+ You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a fee.
+\end{verbatim}
+
+The license also allows you other freedoms.
+For more information see Section~\ref{copyright}.
+
+\section{Modification}
+\label{modification}
+
+FunnelWeb is distributed under a GNU license, and you are free to modify the
+source code and distribute modified copies (see Section~\ref{copyright}).
+However, there are good reasons why you should avoid doing this.
+
+\begin{enumerate}
+
+\item If you distribute modified versions of FunnelWeb, you run the risk of
+creating a version that will diverge from the \dq{official} version of
+FunnelWeb that I intend to maintain.
+
+\item If you release a version of FunnelWeb with a changed input language,
+users of your modified version will create source files that will no
+longer work on other versions of FunnelWeb. The result would be chaos.
+
+\end{enumerate}
+
+For these reasons I request that you do not distribute modified versions of
+FunnelWeb, particularly versions with a modified language. However, if you must
+distribute a version with a modified language, \i{please change its name}
+(\ie{}from \dq{FunnelWeb} to something else). Please also allocate a new
+file extension
+to replace \dqp{.fw} as the extension for source files written in the modified
+language.
+
+For more information, refer to the \i{FunnelWeb Hacker's Manual}.
+
+\section{Versions}
+\xx{FunnelWeb}{versions}
+
+FunnelWeb was created in 1986 and was used extensively by Ross Williams
+(\p{ross@spam.adelaide.edu.au}) for three years. However,
+Version~1.0 was written
+in Ada and was not very portable (it was fairly VAX/VMS specific).
+David Hulse
+(\p{dave@cs.adelaide.edu.au}) took the first step towards a
+release by translating
+the Ada code into C. Ross Williams then extensively reworked the C code, making
+it robust and portable, adding new features, and polishing it to its
+current form.
+
+\begin{verbatim}
+ Vers Lang Created Released Author Copyright Licensing
+ ---- ---- ------- -------- -------------- ------------- ---------
+ V1.0 Ada 1986 Never Ross Williams Ross Williams
+ V2.0 C 1989 Never David Hulse Public domain No restriction.
+ V3.0 C 1992 May-1992 Ross Williams Ross Williams GNU release.
+\end{verbatim}
+
+This manual was released for:
+
+\begin{verbatim}
+ * FunnelWeb V3.0.
+ * User's Manual V1.0.
+ * Hacker's Manual V1.0.
+ * TeX Definitions V1.0.
+\end{verbatim}
+
+\section{FTP Archive and Author}
+\label{ftparchive}%
+\xx{author}{contacting}\xx{ftp}{archive}\xx{FunnelWeb}{archive}
+
+The FunnelWeb FTP archive is:
+
+\begin{verbatim}
+ Machine : sirius.itd.adelaide.edu.au [IP=129.127.40.3].
+ Directory : ~pub/funnelweb/ (or a directory of similar name).
+\end{verbatim}
+
+The author of FunnelWeb and this manual is:
+
+\begin{verbatim}
+ Name: Dr Ross N. Williams
+ Email: ross@spam.adelaide.edu.au
+ Snail: 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+\end{verbatim}
+
+I intend to maintain an \dq{official} version of FunnelWeb which I will
+release under GNU license from time to time. I am happy to receive
+constructive criticism
+about FunnelWeb and its documentation.
+
+I will always be happy to receive mail about FunnelWeb, but cannot
+guarantee that I will be able to reply to it immediately.
+
+%==============================================================================%
+% End of Ch5.tex %
+%==============================================================================%
diff --git a/web/funnelAC/userman/u_cha.tex b/web/funnelAC/userman/u_cha.tex
new file mode 100644
index 0000000000..f1ddd2b776
--- /dev/null
+++ b/web/funnelAC/userman/u_cha.tex
@@ -0,0 +1,228 @@
+%==============================================================================%
+% Start of Cha.tex %
+%==============================================================================%
+%
+% Copyright
+% ---------
+% Copyright (C) 1992 Ross N. Williams.
+% This file contains a chapter of the FunnelWeb User's Manual.
+% See the main TeX file for this manual for further information.
+%
+%==============================================================================%
+
+\appendix
+
+%==============================================================================
+
+\chapter{Glossary}
+\x{glossary}
+
+\gloss{Analyser} A component of the FunnelWeb program
+that checks the macro table created by the parser for errors.
+For example, the analyser checks to see if any macro without a \p{@Z} has
+not been called.
+
+\gloss{Argument} A string delimited by blanks appearing on the FunnelWeb
+command line. Arguments are used to control options.
+
+\gloss{Directive} A FunnelWeb special sequence or
+cooperating group of special sequences that do not form part of
+a macro definition. A directive can take the form of a pragma.
+
+\gloss{Documentation} Descriptive text.
+
+\gloss{Documentation file} An output file, produced by the Weave
+component of FunnelWeb, that
+contains typesetter commands. When fed into the appropriate typesetter
+program, the result is a typeset image of the input file.
+
+\gloss{Free text} The text in an input file that remains
+if one were to remove macro definitions and directives.
+
+\gloss{FunnelWeb} This word has a number of different meanings all
+pertaining to the FunnelWeb system of programming. 1) The
+entire system of programming as in \dq{Maybe FunnelWeb can help.}
+2) The computer program that implements the
+system as in \dq{Run it through FunnelWeb and see what comes out.}
+3) The language implemented by the FunnelWeb program as in \dq{I wrote the
+program in FunnelWeb.} or \dq{I wrote the program in Ada using FunnelWeb.}.
+
+\gloss{FunnelWeb file} A file whose contents are written in the FunnelWeb
+language.
+
+\gloss{FunnelWeb language} The language in which FunnelWeb input files are
+written.
+
+\gloss{FunnelWeb proper} Usually, when FunnelWeb is invoked, it processes
+a single input file and then terminates. However, it also has a command
+language mode in which it is possible to invoke \dq{FunnelWeb} many times.
+This leads to confusion between \dq{FunnelWeb} the outer program and
+\dq{FunnelWeb} the inner program. To avoid this confusion, the inner
+FunnelWeb is sometimes referred to as \dq{FunnelWeb proper}.
+
+\gloss{FW} An abbreviation for \dq{FunnelWeb} that is
+used wherever appropriate.
+
+\gloss{Include file} A file read in by FunnelWeb as the result of an
+include pragma (\p{@i filename}).
+
+\gloss{Input file} Any file read in by FunnelWeb. The phrase
+\dq{the input file} refers to the root input file
+(specified using the \p{+F} option).
+
+\gloss{Journal file} An output file containing a copy of the output sent to
+the user's console during an invocation of FunnelWeb. In other systems,
+this file is sometimes called a \dq{log file}.
+
+\gloss{Listing file} An output file summarizing the result of processing
+an input file.
+
+\gloss{Macro} A binding of a name to a string.
+
+\gloss{Macro definition} A construct appearing in a FunnelWeb file that
+binds a name to a text string.
+A FunnelWeb file consists of a series of macro definitions surrounded by
+documentary text.
+
+\gloss{Mapper} A component of the FunnelWeb program
+that reads in the input file and creates a copy of it in memory.
+
+\gloss{Option} An parameter internal to the FunnelWeb program which can be
+controlled by command line arguments or pragmas.
+
+\gloss{Output file} Any file written by FunnelWeb. This includes
+listing, journal, product, and documentation files. (Warning: During most
+of FunnelWeb's development the term \dq{output file} was also used to
+refer to what are now called \dq{product files}. This turned out to be
+extremely confusing and so the term \dq{product file} was invented to
+distinguish the generic from the specific.
+However, as this was a late modification,
+you may find some occurrences of the old
+use of \dq{output file}.).
+
+\gloss{Parser} A component of the FunnelWeb program
+that processes the token list generated by the scanner and produces a
+macro table and a document list. The parser mainly
+analyses the input file at the syntactic level, but also does some lightweight
+semantic checking too.
+
+\gloss{Pragma} Single-line directives that appears in
+FunnelWeb files. Pragmas control everything from maximum input line length
+to typesetter dependence. A pragma line starts with \dqp{@p}.
+
+\gloss{Printed documentation} Sheets of paper
+resulting from actually typesetting and printing a documentation file.
+
+\gloss{Product file} An output file, generated by the Tangle component of
+FunnelWeb, that contains the expansion of the macros in the input
+file. Note: Other names considered for this were:
+generated file, expanded file, result file, program file, and tangle file.
+
+\gloss{Scanner} A component of the FunnelWeb program
+that scans a copy of the input file in memory and generates a line list
+and a token list to be fed to the parser. The scanner processes the input
+at the lexical level.
+
+\gloss{Script} A file containing FunnelWeb shell commands.
+
+\gloss{Shell} A command language interpreter built into the FunnelWeb
+program. The interpreter allows the user to invoke FunnelWeb proper
+many times during a single invocation of the FunnelWeb program.
+
+\gloss{Special character} A distinguished character
+in a FunnelWeb input file that introduces a special sequence.
+By default the special
+character is \dqp{@}. However, it can be changed using the \dqp{@=} special
+sequence.
+
+\gloss{Special sequence} A special sequence is a construct introduced by the
+special character. Special sequences are used to define a structure in a
+FunnelWeb input file that exists at a higher level to the surrounding text.
+A FunnelWeb input file may be considered to be a sequence of text and
+special sequences.
+
+\gloss{Tangle} This is the name for the component of FunnelWeb that
+generates one or more product files containing the expansion of macros
+in the input file.
+
+\gloss{Typesetting directive} A FunnelWeb directive whose
+sole effect is to modify the way in which the input file is represented
+in the documentation file.
+
+\gloss{Weave} This is the name for the component of FunnelWeb that
+generates a documentation file containing typesetting commands representing
+the input file.
+
+%==============================================================================
+
+\chapter{References}
+\x{references}
+
+\paper{ANSI} Australian Standard AS~3955-1991, \dq{Programming Languages --- C},
+(ISBN: 0-7262-6970-0), 12~July~1991. Identical to:
+International Standard ISO/IEC 9899:
+1990 Programming Languages --- C.\checked{}
+
+\paper{ANZE} \dq{Australia, New Zealand Encyclopedia},
+Entry: \dq{Funnel-web spiders}, Vol~7, pp.~564--565, Bay Books,
+Sydney, (ISBN: 85835--127--7), 1975.\checked{}
+
+
+\paper{BSI82} British Standards Institute, \dq{Specification for
+Computer Programming Language Pascal}, Publication BS6192:1982,
+British Standards Institute, P.O. Box 372, Milton Keynes, MK146LO,
+1982.\checked{}
+
+\paper{Gries81} Gries~D., \dq{The Science of Programming},
+Springer-Verlag, (ISBN: 0-387-90641-X), 1981.
+
+\paper{Humphries91} Humphries~B, \dq{Neglected Poems and Other Creatures},
+Angus and Robertson, Sydney, (ISBN: 0-207-17212-9), 1991.\checked{}
+
+\paper{Kernighan88} Kernighan~B.W., Ritchie~D.M., \dq{The~C Programming
+Language}, (second edition,\dq{ANSI~C}), Prentice Hall,
+(ISBN: 0-13-110362-8), 1988.\checked{}
+
+\paper{Knuth83} Knuth~D.E., \dq{The WEB System of Structured
+Documentation}, (Web User Manual, Version~2.5, November, 1983),
+Stanford University, 1983.
+
+\paper{Knuth84} Knuth~D.E., \dq{The \TeX{}book}, Addison-Wesley,
+(ISBN: 0-201-13448-9), 1984.
+
+\paper{Knuth84} Knuth~D.E., \dq{Literate Programming}, \i{The Computer
+Journal}, Vol.~27, No.~2, pp.~97-111, 1984.\checked{Reference copied from
+SIGPLAN 26(1) p.16} Note: The author of this manual has not yet obtained
+this paper.
+
+\paper{Lamport86} Lamport~L., \dq{\LaTeX{}: A Document Preparation System},
+Addison-Wesley, (ISBN: 0-201-15790-X),
+1986.\checked{}
+
+\paper{Rosovsky90} Rosovsky~H., \dq{The University: An Owner's Manual},
+W.W.Norton \& Company, Inc., (ISBN: 0-393-02782-1), 1990.\checked{}
+
+\paper{Smith91} Smith~L.M.C., \dq{An Annotated Bibliography
+of Literate Programming}, ACM SIGPLAN Notices, Vol.~26, No.~1,
+January 1991.\checked{}
+
+\paper{Strunk79} Strunk~W., White~E.B., \dq{The Elements of
+Style}, Third Edition, MacMillan Publishing Company, New York,
+(ISBN: 0-02-418200-1),
+1979.\checked{}
+
+\paper{USDOD83} \dq{The Programming Language Ada Reference Manual},
+American National Standards Institute Inc,
+ANSI/MIL-STD-1815A-1983, 1983.\checked{}
+
+%==============================================================================
+
+\addcontentsline{toc}{chapter}{Index}
+\def\indexentry#1#2{\item #1~#2}
+\begin{theindex}
+\input u_manual.sin
+\end{theindex}
+
+%==============================================================================%
+% End of Cha.tex %
+%==============================================================================%
diff --git a/web/funnelAC/userman/u_manual.aux b/web/funnelAC/userman/u_manual.aux
new file mode 100644
index 0000000000..ca824ce14d
--- /dev/null
+++ b/web/funnelAC/userman/u_manual.aux
@@ -0,0 +1,202 @@
+\relax
+\@writefile{toc}{\string\contentsline\space {chapter}{Preface}{9}}
+\@writefile{toc}{\string\contentsline\space {chapter}{Acknowledgements}{11}}
+\@writefile{toc}{\string\contentsline\space {chapter}{Presentation Notes}{13}}
+\@writefile{toc}{\string\contentsline\space {chapter}{\string\numberline\space {1}A Tutorial Introduction}{15}}
+\@writefile{lof}{\string\addvspace\space {10\p@ }}
+\@writefile{lot}{\string\addvspace\space {10\p@ }}
+\newlabel{chapintroduction}{{1}{15}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.1}What is Literate Programming?}{15}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.2}What is FunnelWeb?}{18}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.3}The Name FunnelWeb}{19}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.4}A FunnelWeb Tutorial}{19}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.5}A Hello World Document}{20}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.6}Macro Facilities}{22}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.6.1}Simple Macros}{22}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.6.2}Number of Times Called}{23}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.6.3}Indentation}{25}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.6.4}Additive Macros}{26}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.6.5}Parameterized Macros}{28}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.6.6}Macro Expansion}{30}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.6.7}Include Files}{30}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.7}Typesetting Facilities}{32}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.7.1}Overview}{32}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.7.2}Typesetter Independence}{34}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.7.3}Hierarchical Structure}{34}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.7.4}Understanding the Printed Documentation}{35}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.7.5}Literals and Emphasis}{37}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.7.6}Adding a Header Page}{37}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {1.7.7}Comments}{37}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.8}A Complete Example}{38}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.9}Summary}{39}}
+\@writefile{toc}{\string\contentsline\space {chapter}{\string\numberline\space {2}FunnelWeb Hints}{41}}
+\@writefile{lof}{\string\addvspace\space {10\p@ }}
+\@writefile{lot}{\string\addvspace\space {10\p@ }}
+\newlabel{chapadvanced}{{2}{41}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.1}Macro Names}{41}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.2}Quick Names}{42}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.3}FunnelWeb the Martinet}{42}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.4}Fiddling With End of Lines}{43}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.5}Fudging Conditionals}{44}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.6}Changing the Strength of Headings}{46}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.7}Efficiency Notes}{47}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.8}Interactive Mode}{47}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.9}Setting Up Default Options}{49}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.10}FunnelWeb and Make}{49}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.11}The Dangers of FunnelWeb}{50}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.12}Wholistic Debugging}{53}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.13}Examples of FunnelWeb Applications}{53}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {2.13.1}Analyzing the Monster Postscript Header File}{54}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {2.13.2}Making Ada ADTs more A}{55}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {2.13.3}Multiple Language Systems}{55}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {2.13.4}The Case of the Small Function}{56}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {2.13.5}When Comments are Bad}{57}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {2.13.6}Documents That Share Text}{58}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {2.13.7}Generics}{59}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.14}Summary}{62}}
+\@writefile{toc}{\string\contentsline\space {chapter}{\string\numberline\space {3}FunnelWeb Definition}{63}}
+\@writefile{lof}{\string\addvspace\space {10\p@ }}
+\@writefile{lot}{\string\addvspace\space {10\p@ }}
+\newlabel{chapdefinition}{{3}{63}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.1}Introduction}{63}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.2}Notation}{63}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.3}Terminology}{63}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.4}An Architectural Overview}{64}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.5}Diagnostics}{65}}
+\newlabel{diagnostics}{{3.5}{65}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.6}Typesetter Independence}{65}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.7}Command Line Interface}{66}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.7.1}Invoking FunnelWeb}{66}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.7.2}Command Line Arguments}{67}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.7.3}Options}{68}}
+\newlabel{commandlineoptions}{{3.7.3}{68}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.8}File Name Inheritance}{70}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.9}FunnelWeb Startup}{70}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.10}Scanner}{71}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.10.1}Basic Input File Processing}{71}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.10.2}Special Sequences}{72}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.10.3}Setting the Special Character}{74}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.10.4}Inserting the Special Character into the Text}{74}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.10.5}Inserting Arbitrary Characters into the Text}{74}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.10.6}Comments}{75}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.10.7}Quick Names}{76}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.10.8}Inserting End of Line Markers}{76}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.10.9}Suppressing End of Line Markers}{77}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.10.10}Include Files}{77}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.10.11}Pragmas}{78}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.10.11.1}Indentation}{78}}
+\newlabel{indentationpragma}{{3.10.11.1}{78}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.10.11.2}Maximum Input Line Length}{79}}
+\newlabel{millpragma}{{3.10.11.2}{79}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.10.11.3}Maximum Output File Line Length}{79}}
+\newlabel{mollpragma}{{3.10.11.3}{79}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.10.11.4}Typesetter}{80}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.10.12}Freestanding Typesetter Directives}{81}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.10.12.1}New Page}{81}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.10.12.2}Table of Contents}{81}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.10.12.3}Vertical Skip}{81}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.10.12.4}Title}{82}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.10.13}Scanner/Parser Interface}{82}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.11}Parser}{82}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.11.1}High Level Structure}{82}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.11.2}Free Text}{83}}
+\newlabel{typesetterpragma}{{3.11.2}{83}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.11.3}Typesetter Directives}{83}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.11.3.1}Section}{83}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.11.3.2}Literal Directive}{84}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.11.3.3}Emphasis Directive}{85}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.11.4}Macros}{85}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.11.4.1}Names}{86}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.11.4.2}Formal Parameter Lists}{86}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.11.5}Expressions}{86}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.11.6}Macro Calls}{86}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.11.7}Formal Parameters}{87}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.11.8}Macros are Static}{87}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.12}Analyser}{88}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.13}Tangle}{88}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.14}Weave}{89}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.14.1}Target Typesetter}{89}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.14.2}Cross Reference Numbering}{89}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.15}FunnelWeb Shell}{90}}
+\newlabel{commandshell}{{3.15}{90}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.15.1}Introduction}{90}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.15.2}Return Statuses}{90}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.15.3}Command Line Length}{91}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.15.4}String Substitution}{91}}
+\newlabel{stringsubstitution}{{3.15.4}{91}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.15.5}How a Command Line is Processed}{92}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.15.6}Options}{92}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {3.15.7}Shell Commands}{93}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.1}Absent}{93}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.2}Codify}{93}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.3}Compare}{93}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.4}Define}{94}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.5}Diff}{94}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.6}Diffsummary}{95}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.7}Diffzero}{95}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.8}Eneo}{95}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.9}Execute}{96}}
+\newlabel{executecommand}{{3.15.7.9}{96}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.10}Exists}{96}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.11}Fixeols}{96}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.12}Fw}{97}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.13}Help}{97}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.14}Here}{98}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.15}Quit}{98}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.16}Set}{98}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.17}Show}{98}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.18}Skipto}{98}}
+\newlabel{skiptocommand}{{3.15.7.18}{98}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.19}Status}{99}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.20}Tolerate}{100}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.21}Trace}{100}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.22}Write}{100}}
+\@writefile{toc}{\string\contentsline\space {subsubsection}{\string\numberline\space {3.15.7.23}Writeu}{100}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.16}Concluding Remarks}{100}}
+\@writefile{toc}{\string\contentsline\space {chapter}{\string\numberline\space {4}FunnelWeb Installation}{101}}
+\@writefile{lof}{\string\addvspace\space {10\p@ }}
+\@writefile{lot}{\string\addvspace\space {10\p@ }}
+\newlabel{chapinstall}{{4}{101}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.1}Obtaining a Copy of FunnelWeb}{101}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.2}Establishing The Directory Tree}{102}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {4.2.1}Admin Directory}{102}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {4.2.2}Answers Directory}{102}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {4.2.3}Hackman Directory}{103}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {4.2.4}Results Directory}{103}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {4.2.5}Scripts Directory}{103}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {4.2.6}Sources Directory}{103}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {4.2.7}Tests Directory}{104}}
+\@writefile{toc}{\string\contentsline\space {subsection}{\string\numberline\space {4.2.8}Userman Directory}{105}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.3}Compiling FunnelWeb}{105}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.4}Testing FunnelWeb}{105}}
+\newlabel{testingfunnelweb}{{4.4}{105}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.5}Installing FunnelWeb}{106}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.6}Printing Manuals}{107}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.7}Installation Problems?}{107}}
+\@writefile{toc}{\string\contentsline\space {chapter}{\string\numberline\space {5}FunnelWeb Administration}{109}}
+\@writefile{lof}{\string\addvspace\space {10\p@ }}
+\@writefile{lot}{\string\addvspace\space {10\p@ }}
+\newlabel{chapadministration}{{5}{109}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {5.1}Introduction}{109}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {5.2}The User's Commitment To FunnelWeb}{109}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {5.3}Documentation}{110}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {5.4}Registration}{110}}
+\newlabel{registration}{{5.4}{110}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {5.5}Support}{110}}
+\newlabel{support}{{5.5}{110}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {5.6}Copyright}{112}}
+\newlabel{copyright}{{5.6}{112}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {5.7}Nowarranty}{112}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {5.8}Distribution}{113}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {5.9}Modification}{113}}
+\newlabel{modification}{{5.9}{113}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {5.10}Versions}{114}}
+\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {5.11}FTP Archive and Author}{114}}
+\newlabel{ftparchive}{{5.11}{114}}
+\@writefile{toc}{\string\contentsline\space {chapter}{\string\numberline\space {A}Glossary}{115}}
+\@writefile{lof}{\string\addvspace\space {10\p@ }}
+\@writefile{lot}{\string\addvspace\space {10\p@ }}
+\@writefile{toc}{\string\contentsline\space {chapter}{\string\numberline\space {B}References}{117}}
+\@writefile{lof}{\string\addvspace\space {10\p@ }}
+\@writefile{lot}{\string\addvspace\space {10\p@ }}
+\@writefile{toc}{\string\contentsline\space {chapter}{Index}{117}}
diff --git a/web/funnelAC/userman/u_manual.dvi b/web/funnelAC/userman/u_manual.dvi
new file mode 100644
index 0000000000..36d149f69b
--- /dev/null
+++ b/web/funnelAC/userman/u_manual.dvi
Binary files differ
diff --git a/web/funnelAC/userman/u_manual.idx b/web/funnelAC/userman/u_manual.idx
new file mode 100644
index 0000000000..5935623e5c
--- /dev/null
+++ b/web/funnelAC/userman/u_manual.idx
@@ -0,0 +1,1020 @@
+\indexentry{Ross Williams}{1}
+\indexentry{Williams Ross}{1}
+\indexentry{copyright notice}{1}
+\indexentry{notice copyright}{1}
+\indexentry{preface}{9}
+\indexentry{Donald Knuth}{9}
+\indexentry{Knuth Donald}{9}
+\indexentry{Knuth83}{9}
+\indexentry{Web}{9}
+\indexentry{GNU license}{9}
+\indexentry{license GNU}{9}
+\indexentry{acknowledgements}{11}
+\indexentry{David Hulse}{11}
+\indexentry{Hulse David}{11}
+\indexentry{Ada}{11}
+\indexentry{Simon Hackett}{11}
+\indexentry{Hackett Simon}{11}
+\indexentry{Jeremy Begg}{11}
+\indexentry{Begg Jeremy}{11}
+\indexentry{Barry Dwyer}{11}
+\indexentry{Dwyer Barry}{11}
+\indexentry{Roger Brissenden}{11}
+\indexentry{Brissenden Roger}{11}
+\indexentry{Donald Knuth}{11}
+\indexentry{Knuth Donald}{11}
+\indexentry{presentation notes}{13}
+\indexentry{typesetting}{13}
+\indexentry{Andrew Trevorrow}{13}
+\indexentry{Trevorrow Andrew}{13}
+\indexentry{OzTeX}{13}
+\indexentry{Knuth84}{13}
+\indexentry{Lamport86}{13}
+\indexentry{TeX}{13}
+\indexentry{LaTeX}{13}
+\indexentry{Macintosh}{13}
+\indexentry{tutorial}{15}
+\indexentry{literate programming}{15}
+\indexentry{literate programming}{15}
+\indexentry{magic trick}{15}
+\indexentry{tools literate programming}{15}
+\indexentry{literate programming tools}{15}
+\indexentry{hypertext}{15}
+\indexentry{literate programming, facilities}{15}
+\indexentry{program ordering}{15}
+\indexentry{ordering program}{15}
+\indexentry{Pascal}{15}
+\indexentry{BSI82}{15}
+\indexentry{cross referencing}{17}
+\indexentry{literate programming, most significant benefit}{17}
+\indexentry{Rosovsky90}{17}
+\indexentry{universities}{17}
+\indexentry{explaining code}{17}
+\indexentry{code explaining}{17}
+\indexentry{development time}{17}
+\indexentry{time development}{17}
+\indexentry{Knuth83}{17}
+\indexentry{Knuth84}{17}
+\indexentry{Smith91}{17}
+\indexentry{FunnelWeb overview}{18}
+\indexentry{overview FunnelWeb}{18}
+\indexentry{input file}{18}
+\indexentry{product files}{18}
+\indexentry{documentation file}{18}
+\indexentry{output files}{18}
+\indexentry{simplicity}{18}
+\indexentry{reliability}{18}
+\indexentry{language independence}{18}
+\indexentry{independence language}{18}
+\indexentry{typesetter independence}{18}
+\indexentry{independence typesetter}{18}
+\indexentry{BSI82}{18}
+\indexentry{Knuth84}{18}
+\indexentry{TeX}{18}
+\indexentry{portability}{18}
+\indexentry{controllability}{18}
+\indexentry{GNU license}{18}
+\indexentry{license GNU}{18}
+\indexentry{production tool}{19}
+\indexentry{FunnelWeb name}{19}
+\indexentry{name FunnelWeb}{19}
+\indexentry{Funnel-web spider}{19}
+\indexentry{spider Funnel-web}{19}
+\indexentry{Sydney}{19}
+\indexentry{Atrax robustus}{19}
+\indexentry{ANZE}{19}
+\indexentry{tiger snake}{19}
+\indexentry{snake tiger}{19}
+\indexentry{white pointer shark}{19}
+\indexentry{shark white pointer}{19}
+\indexentry{Edna Everage}{19}
+\indexentry{Everage Edna}{19}
+\indexentry{Barry Humphries}{19}
+\indexentry{Humphries Barry}{19}
+\indexentry{Humphries91}{19}
+\indexentry{tutorial}{19}
+\indexentry{tutorial introduction}{19}
+\indexentry{introduction tutorial}{19}
+\indexentry{hello world document}{20}
+\indexentry{invoking FunnelWeb}{20}
+\indexentry{special character}{20}
+\indexentry{special sequence}{20}
+\indexentry{@<}{20}
+\indexentry{@>}{20}
+\indexentry{@O}{20}
+\indexentry{@braces}{20}
+\indexentry{@+}{20}
+\indexentry{simple rule}{20}
+\indexentry{rule simple}{20}
+\indexentry{C preprocessor}{20}
+\indexentry{preprocessor C}{20}
+\indexentry{@=}{20}
+\indexentry{Hello Northern Hemisphere Program}{21}
+\indexentry{FunnelWeb two main aspects}{21}
+\indexentry{two main aspects FunnelWeb}{21}
+\indexentry{Tangling}{21}
+\indexentry{Weaving}{21}
+\indexentry{WEB}{21}
+\indexentry{tutorial macro facilities}{22}
+\indexentry{macro facilities tutorial}{22}
+\indexentry{tutorial simple macros}{22}
+\indexentry{simple macros tutorial}{22}
+\indexentry{tutorial macros simple}{22}
+\indexentry{macros simple tutorial}{22}
+\indexentry{@O}{22}
+\indexentry{@dollar}{22}
+\indexentry{order program}{22}
+\indexentry{program order}{22}
+\indexentry{program layout}{22}
+\indexentry{layout program}{22}
+\indexentry{macro bindings}{22}
+\indexentry{bindings macro}{22}
+\indexentry{TeX}{22}
+\indexentry{number of times called}{23}
+\indexentry{calls number}{23}
+\indexentry{number calls}{23}
+\indexentry{invocation number}{23}
+\indexentry{number invocation}{23}
+\indexentry{EOL suppression}{23}
+\indexentry{suppression EOL}{23}
+\indexentry{@-}{23}
+\indexentry{@Z tutorial}{24}
+\indexentry{tutorial @Z}{24}
+\indexentry{@M tutorial}{24}
+\indexentry{tutorial @M}{24}
+\indexentry{indentation macro calls}{25}
+\indexentry{macro calls indentation}{25}
+\indexentry{pragma}{25}
+\indexentry{WEB}{25}
+\indexentry{Knuth83}{25}
+\indexentry{Pascal}{25}
+\indexentry{output WEB}{25}
+\indexentry{WEB output}{25}
+\indexentry{Knuth83}{25}
+\indexentry{object code}{26}
+\indexentry{additive macros}{26}
+\indexentry{macros additive}{26}
+\indexentry{additive macro}{26}
+\indexentry{tutorial ==}{26}
+\indexentry{== tutorial}{26}
+\indexentry{tutorial +=}{26}
+\indexentry{+= tutorial}{26}
+\indexentry{data abstraction}{26}
+\indexentry{abstraction data}{26}
+\indexentry{Pascal}{26}
+\indexentry{program layout}{28}
+\indexentry{layout program}{28}
+\indexentry{parameterized macros}{28}
+\indexentry{macros parameterized}{28}
+\indexentry{formal parameters}{28}
+\indexentry{parameters formal}{28}
+\indexentry{@1...}{28}
+\indexentry{formal parameters}{28}
+\indexentry{parameters formal}{28}
+\indexentry{actual parameters}{29}
+\indexentry{parameters actual}{29}
+\indexentry{@(}{29}
+\indexentry{@)}{29}
+\indexentry{@,}{29}
+\indexentry{@"}{29}
+\indexentry{parameter list, absent}{29}
+\indexentry{song}{29}
+\indexentry{twelve bugs of christmas}{29}
+\indexentry{rec.humor.funny}{29}
+\indexentry{Pat Scannel}{29}
+\indexentry{Scannel Pat}{29}
+\indexentry{macro expansion}{30}
+\indexentry{expansion macro}{30}
+\indexentry{memory use of}{30}
+\indexentry{use of memory}{30}
+\indexentry{include files}{30}
+\indexentry{files include}{30}
+\indexentry{@i}{30}
+\indexentry{poem camera}{30}
+\indexentry{camera poem}{30}
+\indexentry{animal poem}{30}
+\indexentry{poem animal}{30}
+\indexentry{shooting}{31}
+\indexentry{special character changing}{31}
+\indexentry{changing special character}{31}
+\indexentry{include files recursive}{31}
+\indexentry{recursive include files}{31}
+\indexentry{macro libraries}{31}
+\indexentry{libraries macro}{31}
+\indexentry{tutorial typesetting}{32}
+\indexentry{typesetting tutorial}{32}
+\indexentry{documentation vs code}{32}
+\indexentry{code vs documentation}{32}
+\indexentry{overview typesetting}{32}
+\indexentry{typesetting overview}{32}
+\indexentry{macro definitions}{32}
+\indexentry{directives}{32}
+\indexentry{free text}{32}
+\indexentry{typesetter independence}{34}
+\indexentry{independence typesetter}{34}
+\indexentry{typesetter independent}{34}
+\indexentry{hierarchical structure}{34}
+\indexentry{structure hierarchical}{34}
+\indexentry{section headings}{34}
+\indexentry{headings section}{34}
+\indexentry{@A...}{34}
+\indexentry{name section}{34}
+\indexentry{section name}{34}
+\indexentry{section name inheritance}{35}
+\indexentry{inheritance section name}{35}
+\indexentry{programmer's cheer}{35}
+\indexentry{cheer programmer's}{35}
+\indexentry{hacker's cheer}{35}
+\indexentry{cheer hacker's}{35}
+\indexentry{hacker's dictionary}{35}
+\indexentry{dictionary hacker's}{35}
+\indexentry{literal construct}{37}
+\indexentry{emphasis construct}{37}
+\indexentry{@slash}{37}
+\indexentry{@braces}{37}
+\indexentry{header page}{37}
+\indexentry{vskip directive}{37}
+\indexentry{directive vskip}{37}
+\indexentry{title directive}{37}
+\indexentry{directive title}{37}
+\indexentry{newpage directive}{37}
+\indexentry{directive newpage}{37}
+\indexentry{table of contents directive}{37}
+\indexentry{directive table of contents}{37}
+\indexentry{comments}{37}
+\indexentry{@!}{37}
+\indexentry{complete example}{38}
+\indexentry{example complete}{38}
+\indexentry{FunnelWeb Example}{38}
+\indexentry{Example FunnelWeb}{38}
+\indexentry{FunnelWeb hints}{41}
+\indexentry{hints FunnelWeb}{41}
+\indexentry{macro names}{41}
+\indexentry{names macro}{41}
+\indexentry{macro identifiers}{41}
+\indexentry{identifiers macro}{41}
+\indexentry{quick names}{42}
+\indexentry{names quick}{42}
+\indexentry{empty name}{42}
+\indexentry{name empty}{42}
+\indexentry{quick name}{42}
+\indexentry{FunnelWeb rules}{42}
+\indexentry{rules FunnelWeb}{42}
+\indexentry{FunnelWeb martinet}{42}
+\indexentry{martinet FunnelWeb}{42}
+\indexentry{trailing blanks}{42}
+\indexentry{blanks trailing}{42}
+\indexentry{input line length}{42}
+\indexentry{length input line}{42}
+\indexentry{output line length}{42}
+\indexentry{length output line}{42}
+\indexentry{Fortran compilers}{42}
+\indexentry{compilers Fortran}{42}
+\indexentry{control characters}{42}
+\indexentry{characters control}{42}
+\indexentry{text editors}{42}
+\indexentry{editors text}{42}
+\indexentry{tabs}{42}
+\indexentry{invocations number}{42}
+\indexentry{number invocations}{42}
+\indexentry{recursion macro}{43}
+\indexentry{macro recursion}{43}
+\indexentry{EOL fiddling with}{43}
+\indexentry{fiddling with EOL}{43}
+\indexentry{end-of-line fiddling with}{43}
+\indexentry{fiddling with end-of-line}{43}
+\indexentry{spacing}{43}
+\indexentry{fudging conditionals}{44}
+\indexentry{conditionals fudging}{44}
+\indexentry{Ada}{44}
+\indexentry{headings strength}{46}
+\indexentry{strength headings}{46}
+\indexentry{typesetting strength}{46}
+\indexentry{strength typesetting}{46}
+\indexentry{section strength}{46}
+\indexentry{strength section}{46}
+\indexentry{font size}{46}
+\indexentry{size font}{46}
+\indexentry{FunnelWeb efficiency}{47}
+\indexentry{efficiency FunnelWeb}{47}
+\indexentry{efficiency notes}{47}
+\indexentry{notes efficiency}{47}
+\indexentry{memory}{47}
+\indexentry{input files}{47}
+\indexentry{files input}{47}
+\indexentry{speed}{47}
+\indexentry{macro expansion}{47}
+\indexentry{expansion macro}{47}
+\indexentry{interactive mode}{47}
+\indexentry{keyboard mode}{47}
+\indexentry{regression testing}{47}
+\indexentry{testing regression}{47}
+\indexentry{command interpreter}{47}
+\indexentry{interpreter command}{47}
+\indexentry{useful commands}{47}
+\indexentry{commands useful}{47}
+\indexentry{FunnelWeb proper}{48}
+\indexentry{set command}{48}
+\indexentry{command set}{48}
+\indexentry{show command}{48}
+\indexentry{command show}{48}
+\indexentry{trace on command}{48}
+\indexentry{command trace on}{48}
+\indexentry{workstations}{48}
+\indexentry{options setting defaults}{49}
+\indexentry{setting defaults options}{49}
+\indexentry{default options}{49}
+\indexentry{options default}{49}
+\indexentry{alias}{49}
+\indexentry{fwinit.fws}{49}
+\indexentry{startup script}{49}
+\indexentry{script startup}{49}
+\indexentry{initialization script}{49}
+\indexentry{script initialization}{49}
+\indexentry{make utility}{49}
+\indexentry{file dependencies}{49}
+\indexentry{dependencies file}{49}
+\indexentry{Ada}{49}
+\indexentry{D option}{49}
+\indexentry{option D}{49}
+\indexentry{delete output files}{49}
+\indexentry{output files delete}{49}
+\indexentry{suppression file}{49}
+\indexentry{file suppression}{49}
+\indexentry{FunnelWeb dangers}{50}
+\indexentry{dangers FunnelWeb}{50}
+\indexentry{FunnelWeb pitfalls}{50}
+\indexentry{pitfalls FunnelWeb}{50}
+\indexentry{Donald Knuth}{50}
+\indexentry{Knuth Donald}{50}
+\indexentry{literate programming}{50}
+\indexentry{programming literate}{50}
+\indexentry{spaghetti organization}{50}
+\indexentry{organization spaghetti}{50}
+\indexentry{stream of consciousness}{50}
+\indexentry{boring organization}{50}
+\indexentry{organization boring}{50}
+\indexentry{random access}{50}
+\indexentry{access random}{50}
+\indexentry{novels}{50}
+\indexentry{maintenance programmer}{50}
+\indexentry{programmer maintenance}{50}
+\indexentry{documentation interdependent}{50}
+\indexentry{interdependent documentation}{50}
+\indexentry{pavlov documentation}{51}
+\indexentry{documentation pavlov}{51}
+\indexentry{MIL-STD-2167A}{51}
+\indexentry{2167A}{51}
+\indexentry{Strunk79}{51}
+\indexentry{duplicate documentation}{51}
+\indexentry{documentation duplicate}{51}
+\indexentry{Ada}{51}
+\indexentry{over documentation}{51}
+\indexentry{documentation over}{51}
+\indexentry{Gries81}{51}
+\indexentry{wholistic debugging}{53}
+\indexentry{debugging wholistic}{53}
+\indexentry{wholistic debugging}{53}
+\indexentry{debugger}{53}
+\indexentry{code gardening}{53}
+\indexentry{gardening code}{53}
+\indexentry{wholistic medicine}{53}
+\indexentry{medicine wholistic}{53}
+\indexentry{FunnelWeb example applications}{53}
+\indexentry{example applications FunnelWeb}{53}
+\indexentry{FunnelWeb applications}{53}
+\indexentry{applications FunnelWeb}{53}
+\indexentry{monster file postscript}{54}
+\indexentry{postscript monster file}{54}
+\indexentry{MacDraw}{54}
+\indexentry{TeX}{54}
+\indexentry{PhD thesis}{54}
+\indexentry{thesis PhD}{54}
+\indexentry{Macintosh}{54}
+\indexentry{PostScript}{54}
+\indexentry{postscript header file}{54}
+\indexentry{header file postscript}{54}
+\indexentry{cryptic text files}{55}
+\indexentry{text files cryptic}{55}
+\indexentry{Ada}{55}
+\indexentry{abstract data type}{55}
+\indexentry{ADT}{55}
+\indexentry{package}{55}
+\indexentry{DOD83}{55}
+\indexentry{multiple languages}{55}
+\indexentry{languages multiple}{55}
+\indexentry{open systems}{55}
+\indexentry{printing system}{55}
+\indexentry{system printing}{55}
+\indexentry{laser printer}{55}
+\indexentry{printer laser}{55}
+\indexentry{sharing information}{56}
+\indexentry{small functions}{56}
+\indexentry{functions small}{56}
+\indexentry{code abstraction}{56}
+\indexentry{abstraction code}{56}
+\indexentry{Pascal}{57}
+\indexentry{preprocessor C}{57}
+\indexentry{C preprocessor}{57}
+\indexentry{procedure call overhead}{57}
+\indexentry{overhead procedure call}{57}
+\indexentry{binding problems}{57}
+\indexentry{problems binding}{57}
+\indexentry{comments abuse}{57}
+\indexentry{abuse comments}{57}
+\indexentry{eliminating comments}{57}
+\indexentry{comments eliminating}{57}
+\indexentry{good old days}{57}
+\indexentry{BASIC}{57}
+\indexentry{REM statement}{57}
+\indexentry{statement REM}{57}
+\indexentry{header files}{57}
+\indexentry{files header}{57}
+\indexentry{C header}{57}
+\indexentry{header C}{57}
+\indexentry{postscript}{57}
+\indexentry{sharing text}{58}
+\indexentry{text sharing}{58}
+\indexentry{annual report}{58}
+\indexentry{report annual}{58}
+\indexentry{examples documentation}{58}
+\indexentry{documentation examples}{58}
+\indexentry{generics fudging}{59}
+\indexentry{fudging generics}{59}
+\indexentry{Pascal}{59}
+\indexentry{Barry Dwyer}{59}
+\indexentry{Dwyer Barry}{59}
+\indexentry{University Adelaide}{59}
+\indexentry{Adelaide University}{59}
+\indexentry{set abstraction}{59}
+\indexentry{abstraction set}{59}
+\indexentry{typesafe generics}{61}
+\indexentry{generics typesafe}{61}
+\indexentry{FunnelWeb definition}{63}
+\indexentry{definition FunnelWeb}{63}
+\indexentry{notation}{63}
+\indexentry{EBNF syntax}{63}
+\indexentry{syntax EBNF}{63}
+\indexentry{terminology}{63}
+\indexentry{semantic architecture}{64}
+\indexentry{architecture semantic}{64}
+\indexentry{FunnelWeb overview}{64}
+\indexentry{overview FunnelWeb}{64}
+\indexentry{execution phases}{64}
+\indexentry{phases execution}{64}
+\indexentry{input file}{64}
+\indexentry{FunnelWeb file}{64}
+\indexentry{phases}{64}
+\indexentry{output files}{64}
+\indexentry{journal file}{64}
+\indexentry{listing file}{64}
+\indexentry{documentation}{64}
+\indexentry{product files}{64}
+\indexentry{scanner}{64}
+\indexentry{parser}{64}
+\indexentry{document list}{64}
+\indexentry{list document}{64}
+\indexentry{macro table}{64}
+\indexentry{table macro}{64}
+\indexentry{analyser}{65}
+\indexentry{tangle}{65}
+\indexentry{weave}{65}
+\indexentry{FunnelWeb proper}{65}
+\indexentry{FunnelWeb program}{65}
+\indexentry{diagnostics}{65}
+\indexentry{diagnostics levels of}{65}
+\indexentry{levels of diagnostics}{65}
+\indexentry{severity}{65}
+\indexentry{warning severity}{65}
+\indexentry{severity warning}{65}
+\indexentry{error severity}{65}
+\indexentry{severity error}{65}
+\indexentry{severe severity}{65}
+\indexentry{severity severe}{65}
+\indexentry{fatal severity}{65}
+\indexentry{severity fatal}{65}
+\indexentry{assertion severity}{65}
+\indexentry{severity assertion}{65}
+\indexentry{return status}{65}
+\indexentry{status return}{65}
+\indexentry{typesetter independence}{65}
+\indexentry{independence typesetter}{65}
+\indexentry{Kernighan88}{65}
+\indexentry{typesetter directives}{66}
+\indexentry{command line interface}{66}
+\indexentry{interface command line}{66}
+\indexentry{FunnelWeb invoking}{66}
+\indexentry{invoking FunnelWeb}{66}
+\indexentry{FunnelWeb running}{66}
+\indexentry{running FunnelWeb}{66}
+\indexentry{command line processing}{66}
+\indexentry{processing command line}{66}
+\indexentry{command line parsing}{66}
+\indexentry{parsing command line}{66}
+\indexentry{fw command verb}{66}
+\indexentry{command verb fw}{66}
+\indexentry{command line argument}{67}
+\indexentry{argument command line}{67}
+\indexentry{syntax command line}{67}
+\indexentry{command line syntax}{67}
+\indexentry{arguments}{67}
+\indexentry{case dependence}{67}
+\indexentry{dependence case}{67}
+\indexentry{Unix}{67}
+\indexentry{sign}{67}
+\indexentry{letter}{67}
+\indexentry{string}{67}
+\indexentry{command line options syntax}{67}
+\indexentry{syntax command line options}{67}
+\indexentry{options syntax}{67}
+\indexentry{syntax options}{67}
+\indexentry{options}{67}
+\indexentry{options}{68}
+\indexentry{list options}{68}
+\indexentry{options list}{68}
+\indexentry{B option}{68}
+\indexentry{option B}{68}
+\indexentry{tracedump options}{68}
+\indexentry{options tracedump}{68}
+\indexentry{dump option}{68}
+\indexentry{option dump}{68}
+\indexentry{dump mapped file}{68}
+\indexentry{mapped file dump}{68}
+\indexentry{dump global line list}{68}
+\indexentry{global line list dump}{68}
+\indexentry{dump token list}{68}
+\indexentry{token list dump}{68}
+\indexentry{dump macro table}{68}
+\indexentry{macro table dump}{68}
+\indexentry{dump document list}{68}
+\indexentry{document list dump}{68}
+\indexentry{dump times}{68}
+\indexentry{times dump}{68}
+\indexentry{non-determinism}{68}
+\indexentry{C option}{68}
+\indexentry{option C}{68}
+\indexentry{listing file context}{68}
+\indexentry{context listing file}{68}
+\indexentry{infinite context}{68}
+\indexentry{context infinite}{68}
+\indexentry{D option}{68}
+\indexentry{option D}{68}
+\indexentry{delete output option}{68}
+\indexentry{option delete output}{68}
+\indexentry{F option}{68}
+\indexentry{option F}{68}
+\indexentry{input file option}{68}
+\indexentry{option input file}{68}
+\indexentry{H option}{68}
+\indexentry{option H}{68}
+\indexentry{help option}{68}
+\indexentry{option help}{68}
+\indexentry{I option}{69}
+\indexentry{option I}{69}
+\indexentry{include file option}{69}
+\indexentry{option include file}{69}
+\indexentry{include file}{69}
+\indexentry{file include}{69}
+\indexentry{J option}{69}
+\indexentry{option J}{69}
+\indexentry{journal file option}{69}
+\indexentry{option journal file}{69}
+\indexentry{journal file}{69}
+\indexentry{file journal}{69}
+\indexentry{K option}{69}
+\indexentry{option K}{69}
+\indexentry{keyboard option}{69}
+\indexentry{option keyboard}{69}
+\indexentry{interactive option}{69}
+\indexentry{option interactive}{69}
+\indexentry{L option}{69}
+\indexentry{option L}{69}
+\indexentry{listing file option}{69}
+\indexentry{option listing file}{69}
+\indexentry{listing file}{69}
+\indexentry{file listing}{69}
+\indexentry{Q option}{69}
+\indexentry{option Q}{69}
+\indexentry{quiet option}{69}
+\indexentry{option quiet}{69}
+\indexentry{suppress console output}{69}
+\indexentry{console output suppress}{69}
+\indexentry{S option}{69}
+\indexentry{option S}{69}
+\indexentry{screen option}{69}
+\indexentry{option screen}{69}
+\indexentry{context}{69}
+\indexentry{T option}{69}
+\indexentry{option T}{69}
+\indexentry{typeset option}{69}
+\indexentry{option typeset}{69}
+\indexentry{typeset file}{69}
+\indexentry{file typeset}{69}
+\indexentry{W option}{69}
+\indexentry{option W}{69}
+\indexentry{width option}{69}
+\indexentry{option width}{69}
+\indexentry{product file width}{69}
+\indexentry{width product file}{69}
+\indexentry{X option}{69}
+\indexentry{option X}{69}
+\indexentry{execute script option}{69}
+\indexentry{option execute script}{69}
+\indexentry{filename inheritance}{70}
+\indexentry{inheritance filename}{70}
+\indexentry{filename fields}{70}
+\indexentry{fields filename}{70}
+\indexentry{directory}{70}
+\indexentry{name}{70}
+\indexentry{extension}{70}
+\indexentry{filename inheritance example}{70}
+\indexentry{example filename inheritance}{70}
+\indexentry{FunnelWeb startup}{70}
+\indexentry{startup FunnelWeb}{70}
+\indexentry{FunnelWeb initialization}{70}
+\indexentry{initialization FunnelWeb}{70}
+\indexentry{Action options}{70}
+\indexentry{Ordinary options}{70}
+\indexentry{action execution order}{71}
+\indexentry{order action execution}{71}
+\indexentry{initialization script}{71}
+\indexentry{script initialization}{71}
+\indexentry{fwinit.fws}{71}
+\indexentry{scanner}{71}
+\indexentry{mapper}{71}
+\indexentry{file termination}{71}
+\indexentry{termination file}{71}
+\indexentry{line termination}{71}
+\indexentry{termination line}{71}
+\indexentry{unprintable characters}{71}
+\indexentry{characters unprintable}{71}
+\indexentry{line length}{71}
+\indexentry{length line}{71}
+\indexentry{special sequences}{72}
+\indexentry{sequences special}{72}
+\indexentry{special character}{72}
+\indexentry{special sequence}{72}
+\indexentry{default special character}{72}
+\indexentry{special character default}{72}
+\indexentry{simple sequence}{72}
+\indexentry{setting special character}{74}
+\indexentry{special character setting}{74}
+\indexentry{special character inserting into text}{74}
+\indexentry{inserting into text special character}{74}
+\indexentry{arbitrary characters inserting into text}{74}
+\indexentry{inserting into text arbitrary characters}{74}
+\indexentry{control characters inserting into text}{74}
+\indexentry{inserting into text control characters}{74}
+\indexentry{@circumflex}{74}
+\indexentry{Unix newline}{75}
+\indexentry{comments FunnelWeb}{75}
+\indexentry{FunnelWeb comments}{75}
+\indexentry{@!}{75}
+\indexentry{quick names}{76}
+\indexentry{names quick}{76}
+\indexentry{quick name}{76}
+\indexentry{@hash}{76}
+\indexentry{EOL markers inserting}{76}
+\indexentry{inserting EOL markers}{76}
+\indexentry{@+}{76}
+\indexentry{EOL markers suppressing}{77}
+\indexentry{suppressing EOL markers}{77}
+\indexentry{@-}{77}
+\indexentry{include files}{77}
+\indexentry{files include}{77}
+\indexentry{@i}{77}
+\indexentry{input file}{77}
+\indexentry{include files}{77}
+\indexentry{pragmas}{78}
+\indexentry{pragmas visible}{78}
+\indexentry{visible pragmas}{78}
+\indexentry{pragmas invisible}{78}
+\indexentry{invisible pragmas}{78}
+\indexentry{pragma}{78}
+\indexentry{indentation macro expansion}{78}
+\indexentry{macro expansion indentation}{78}
+\indexentry{no indentation}{78}
+\indexentry{indentation none}{78}
+\indexentry{none indentation}{78}
+\indexentry{blank indentation}{78}
+\indexentry{indentation blank}{78}
+\indexentry{blank indentation}{78}
+\indexentry{input line length}{79}
+\indexentry{line length input}{79}
+\indexentry{maximum input line length}{79}
+\indexentry{input line length maximum}{79}
+\indexentry{pragma input line length}{79}
+\indexentry{input line length pragma}{79}
+\indexentry{maximum product file line length}{79}
+\indexentry{product file line length maximum}{79}
+\indexentry{pragma maximum product file line length}{79}
+\indexentry{maximum product file line length pragma}{79}
+\indexentry{maximum output file line length}{79}
+\indexentry{output file line length maximum}{79}
+\indexentry{pragma maximum output file line length}{79}
+\indexentry{maximum output file line length pragma}{79}
+\indexentry{typesetter pragma}{80}
+\indexentry{pragma typesetter}{80}
+\indexentry{typesetter independence}{80}
+\indexentry{independence typesetter}{80}
+\indexentry{typesetter directives}{81}
+\indexentry{directives typesetter}{81}
+\indexentry{inline}{81}
+\indexentry{freestanding}{81}
+\indexentry{new page}{81}
+\indexentry{pragma new page}{81}
+\indexentry{new page pragma}{81}
+\indexentry{table of contents}{81}
+\indexentry{contents table of}{81}
+\indexentry{pragma table of contents}{81}
+\indexentry{table of contents pragma}{81}
+\indexentry{vertical skip}{81}
+\indexentry{skip vertical}{81}
+\indexentry{pragma vskip}{81}
+\indexentry{vskip pragma}{81}
+\indexentry{title}{82}
+\indexentry{pragma title}{82}
+\indexentry{title pragma}{82}
+\indexentry{parser}{82}
+\indexentry{text tokens}{82}
+\indexentry{special tokens}{82}
+\indexentry{typesetter directive tokens}{82}
+\indexentry{syntax high level}{82}
+\indexentry{high level syntax}{82}
+\indexentry{free text}{83}
+\indexentry{text free}{83}
+\indexentry{Free text}{83}
+\indexentry{directives}{83}
+\indexentry{freestanding typesetter directives}{83}
+\indexentry{inline typesetter directives}{83}
+\indexentry{section constructs}{83}
+\indexentry{constructs section}{83}
+\indexentry{tree structure}{83}
+\indexentry{structure tree}{83}
+\indexentry{LaTeX}{84}
+\indexentry{section name}{84}
+\indexentry{name section}{84}
+\indexentry{literal directive}{84}
+\indexentry{directive literal}{84}
+\indexentry{emphasis directive}{85}
+\indexentry{directive emphasis}{85}
+\indexentry{macro definition}{85}
+\indexentry{definition macro}{85}
+\indexentry{macro name}{85}
+\indexentry{macro body}{85}
+\indexentry{expression}{85}
+\indexentry{macro attributes}{85}
+\indexentry{attributes macro}{85}
+\indexentry{@Z}{85}
+\indexentry{@M}{85}
+\indexentry{==}{85}
+\indexentry{+=}{85}
+\indexentry{additively defined}{85}
+\indexentry{names}{86}
+\indexentry{macro names}{86}
+\indexentry{names macro}{86}
+\indexentry{section names}{86}
+\indexentry{names section}{86}
+\indexentry{parameter lists formal}{86}
+\indexentry{formal parameter lists}{86}
+\indexentry{@1...}{86}
+\indexentry{macro expressions}{86}
+\indexentry{expressions macro}{86}
+\indexentry{macro calls}{86}
+\indexentry{calls macro}{86}
+\indexentry{macro parameter delimiting}{87}
+\indexentry{delimiting macro parameter}{87}
+\indexentry{formal parameters}{87}
+\indexentry{parameters formal}{87}
+\indexentry{macro definition}{87}
+\indexentry{definition macro}{87}
+\indexentry{macro expansion}{87}
+\indexentry{expansion macro}{87}
+\indexentry{macros static}{87}
+\indexentry{static macros}{87}
+\indexentry{analyser}{88}
+\indexentry{checks macro}{88}
+\indexentry{macro checks}{88}
+\indexentry{static analysis}{88}
+\indexentry{analysis static}{88}
+\indexentry{macro recursion}{88}
+\indexentry{recursion macro}{88}
+\indexentry{tangle}{88}
+\indexentry{weave}{89}
+\indexentry{typesetting}{89}
+\indexentry{target typesetter}{89}
+\indexentry{typesetter target}{89}
+\indexentry{cross referencing}{89}
+\indexentry{referencing cross}{89}
+\indexentry{cross reference numbering}{89}
+\indexentry{numbering cross reference}{89}
+\indexentry{section numbering}{89}
+\indexentry{numbering section}{89}
+\indexentry{FunnelWeb command shell}{90}
+\indexentry{command shell FunnelWeb}{90}
+\indexentry{commands FunnelWeb}{90}
+\indexentry{FunnelWeb commands}{90}
+\indexentry{FunnelWeb shell}{90}
+\indexentry{shell FunnelWeb}{90}
+\indexentry{FunnelWeb command shell}{90}
+\indexentry{uses shell}{90}
+\indexentry{shell uses}{90}
+\indexentry{workstation}{90}
+\indexentry{errors shell}{90}
+\indexentry{shell errors}{90}
+\indexentry{status success}{90}
+\indexentry{success status}{90}
+\indexentry{status warning}{90}
+\indexentry{warning status}{90}
+\indexentry{status error}{90}
+\indexentry{error status}{90}
+\indexentry{status severe}{90}
+\indexentry{severe status}{90}
+\indexentry{status fatal}{90}
+\indexentry{fatal status}{90}
+\indexentry{status assertion}{90}
+\indexentry{assertion status}{90}
+\indexentry{command length}{91}
+\indexentry{length command}{91}
+\indexentry{string substitution}{91}
+\indexentry{substitution string}{91}
+\indexentry{define command}{91}
+\indexentry{command define}{91}
+\indexentry{command line processing}{92}
+\indexentry{processing command line}{92}
+\indexentry{command options}{92}
+\indexentry{options command}{92}
+\indexentry{default options}{92}
+\indexentry{options default}{92}
+\indexentry{shell commands list}{93}
+\indexentry{list shell commands}{93}
+\indexentry{commands shell}{93}
+\indexentry{shell commands}{93}
+\indexentry{command absent}{93}
+\indexentry{absent command}{93}
+\indexentry{command codify}{93}
+\indexentry{codify command}{93}
+\indexentry{command compare}{93}
+\indexentry{compare command}{93}
+\indexentry{command define}{94}
+\indexentry{define command}{94}
+\indexentry{string substitution}{94}
+\indexentry{substitution string}{94}
+\indexentry{command diff}{94}
+\indexentry{diff command}{94}
+\indexentry{file differences}{94}
+\indexentry{differences file}{94}
+\indexentry{command diffsummary}{95}
+\indexentry{diffsummary command}{95}
+\indexentry{command diffzero}{95}
+\indexentry{diffzero command}{95}
+\indexentry{command eneo}{95}
+\indexentry{eneo command}{95}
+\indexentry{command execute}{96}
+\indexentry{execute command}{96}
+\indexentry{command exists}{96}
+\indexentry{exists command}{96}
+\indexentry{command fixeols}{96}
+\indexentry{fixeols command}{96}
+\indexentry{non-printable characters}{96}
+\indexentry{characters non-printable}{96}
+\indexentry{command fw}{97}
+\indexentry{fw command}{97}
+\indexentry{command help}{97}
+\indexentry{help command}{97}
+\indexentry{command here}{98}
+\indexentry{here command}{98}
+\indexentry{command quit}{98}
+\indexentry{quit command}{98}
+\indexentry{command set}{98}
+\indexentry{set command}{98}
+\indexentry{command show}{98}
+\indexentry{show command}{98}
+\indexentry{command skipto}{98}
+\indexentry{skipto command}{98}
+\indexentry{command status}{99}
+\indexentry{status command}{99}
+\indexentry{command tolerate}{100}
+\indexentry{tolerate command}{100}
+\indexentry{command trace}{100}
+\indexentry{trace command}{100}
+\indexentry{command write}{100}
+\indexentry{write command}{100}
+\indexentry{command writeu}{100}
+\indexentry{writeu command}{100}
+\indexentry{FunnelWeb installation}{101}
+\indexentry{installation FunnelWeb}{101}
+\indexentry{FunnelWeb obtaining}{101}
+\indexentry{obtaining FunnelWeb}{101}
+\indexentry{ftp anonymous}{101}
+\indexentry{anonymous ftp}{101}
+\indexentry{directory tree}{102}
+\indexentry{tree directory}{102}
+\indexentry{admin directory}{102}
+\indexentry{directory admin}{102}
+\indexentry{answers directory}{102}
+\indexentry{directory answers}{102}
+\indexentry{correct answers}{102}
+\indexentry{answers correct}{102}
+\indexentry{hackman directory}{103}
+\indexentry{directory hackman}{103}
+\indexentry{results directory}{103}
+\indexentry{directory results}{103}
+\indexentry{scripts directory}{103}
+\indexentry{directory scripts}{103}
+\indexentry{regression testing}{103}
+\indexentry{testing regression}{103}
+\indexentry{sources directory}{103}
+\indexentry{directory sources}{103}
+\indexentry{tests directory}{104}
+\indexentry{directory tests}{104}
+\indexentry{userman directory}{105}
+\indexentry{directory userman}{105}
+\indexentry{compiling FunnelWeb}{105}
+\indexentry{FunnelWeb compiling}{105}
+\indexentry{testing FunnelWeb}{105}
+\indexentry{FunnelWeb testing}{105}
+\indexentry{installing FunnelWeb}{106}
+\indexentry{FunnelWeb installing}{106}
+\indexentry{FunnelWeb executable}{106}
+\indexentry{executable FunnelWeb}{106}
+\indexentry{printing manuals}{107}
+\indexentry{manuals printing}{107}
+\indexentry{problems installation}{107}
+\indexentry{installation problems}{107}
+\indexentry{FunnelWeb administration}{109}
+\indexentry{administration FunnelWeb}{109}
+\indexentry{commitment FunnelWeb}{109}
+\indexentry{FunnelWeb commitment}{109}
+\indexentry{ANSI}{109}
+\indexentry{FunnelWeb documentation}{110}
+\indexentry{documentation FunnelWeb}{110}
+\indexentry{FunnelWeb registration}{110}
+\indexentry{registration FunnelWeb}{110}
+\indexentry{FunnelWeb support}{110}
+\indexentry{support FunnelWeb}{110}
+\indexentry{copyright FunnelWeb}{112}
+\indexentry{FunnelWeb copyright}{112}
+\indexentry{FunnelWeb license}{112}
+\indexentry{license FunnelWeb}{112}
+\indexentry{GNU license}{112}
+\indexentry{license GNU}{112}
+\indexentry{warranty}{112}
+\indexentry{FunnelWeb Distribution}{113}
+\indexentry{Distribution FunnelWeb}{113}
+\indexentry{FunnelWeb versions}{114}
+\indexentry{versions FunnelWeb}{114}
+\indexentry{author contacting}{114}
+\indexentry{contacting author}{114}
+\indexentry{ftp archive}{114}
+\indexentry{archive ftp}{114}
+\indexentry{FunnelWeb archive}{114}
+\indexentry{archive FunnelWeb}{114}
+\indexentry{glossary}{115}
+\indexentry{Analyser}{115}
+\indexentry{Argument}{115}
+\indexentry{Directive}{115}
+\indexentry{Documentation}{115}
+\indexentry{Documentation file}{115}
+\indexentry{Free text}{115}
+\indexentry{FunnelWeb}{115}
+\indexentry{FunnelWeb file}{115}
+\indexentry{FunnelWeb language}{115}
+\indexentry{FunnelWeb proper}{115}
+\indexentry{FW}{115}
+\indexentry{Include file}{115}
+\indexentry{Input file}{115}
+\indexentry{Journal file}{115}
+\indexentry{Listing file}{115}
+\indexentry{Macro}{115}
+\indexentry{Macro definition}{116}
+\indexentry{Mapper}{116}
+\indexentry{Option}{116}
+\indexentry{Output file}{116}
+\indexentry{Parser}{116}
+\indexentry{Pragma}{116}
+\indexentry{Printed documentation}{116}
+\indexentry{Product file}{116}
+\indexentry{Scanner}{116}
+\indexentry{Script}{116}
+\indexentry{Shell}{116}
+\indexentry{Special character}{116}
+\indexentry{Special sequence}{116}
+\indexentry{Tangle}{116}
+\indexentry{Typesetting directive}{116}
+\indexentry{Weave}{116}
+\indexentry{references}{117}
+\indexentry{ANSI}{117}
+\indexentry{ANZE}{117}
+\indexentry{BSI82}{117}
+\indexentry{Gries81}{117}
+\indexentry{Humphries91}{117}
+\indexentry{Kernighan88}{117}
+\indexentry{Knuth83}{117}
+\indexentry{Knuth84}{117}
+\indexentry{Knuth84}{117}
+\indexentry{Lamport86}{117}
+\indexentry{Rosovsky90}{117}
+\indexentry{Smith91}{117}
+\indexentry{Strunk79}{117}
+\indexentry{USDOD83}{117}
diff --git a/web/funnelAC/userman/u_manual.log b/web/funnelAC/userman/u_manual.log
new file mode 100644
index 0000000000..309de749d7
--- /dev/null
+++ b/web/funnelAC/userman/u_manual.log
@@ -0,0 +1,188 @@
+This is emTeX (tex386), Version 3.1415 [3c-beta9] (preloaded format=lplain 93.12.31) 15 APR 1994 15:04
+**&lplain u_manual
+(u_manual.tex
+LaTeX Version 2.09 <25 March 1992>
+(d:/emtex/texinput/book.sty
+Standard Document Style `book' <14 Jan 92>.
+(d:/emtex/texinput/bk10.sty)
+\descriptionmargin=\dimen99
+\c@part=\count79
+\c@chapter=\count80
+\c@section=\count81
+\c@subsection=\count82
+\c@subsubsection=\count83
+\c@paragraph=\count84
+\c@subparagraph=\count85
+\c@figure=\count86
+\c@table=\count87
+) (d:/emtex/texinput/titlepag.sty
+Document Style Option `titlepage' -- Released 16 June 1991.
+)
+\@indexfile=\write3
+
+Writing index file u_manual.idx
+(u_manual.aux) [0
+
+
+]
+(u_ch0.tex [1] [2
+
+] (u_manual.toc [3] [4] [5] [6])
+\tf@toc=\write4
+ [7] [8
+
+] [9] [10
+
+]
+Underfull \hbox (badness 10000) in paragraph at lines 137--140
+[]\tenrm Thanks to \tenbf Barry Dwyer[][] \tenrm (\tentt dwyer@cs.adelaide.edu.
+au\tenrm ) and \tenbf Roger Bris-senden[][]
+
+\hbox(7.5+2.5)x426.79134, glue set 5.25278
+.\hbox(0.0+0.0)x0.0
+.\tenrm T
+.\tenrm h
+.\tenrm a
+.\tenrm n
+.etc.
+
+[11] [12
+
+]
+Underfull \hbox (badness 5652) in paragraph at lines 163--169
+[]\tenbf Typesetting: \tenrm This[] doc-u-ment was pre-pared by the au-thor us-
+ing An-drew Trevor-
+
+\hbox(6.94444+1.94444)x426.79134, glue set 3.83969
+.\hbox(0.0+0.0)x0.0
+.\tenbf T
+.\kern-0.31944
+.\tenbf y
+.\tenbf p
+.etc.
+
+
+Underfull \hbox (badness 1117) in paragraph at lines 163--169
+\tenrm row's[][] (\tentt akt150@cscgpo.anu.edu.au\tenrm ) im-ple-men-ta-tion (O
+z-TeX[]) of the T[]X/L[]T[]X\tenbf [Knuth84][]
+
+\hbox(7.5+3.01385)x426.79134, glue set 2.23746
+.\tenrm r
+.\tenrm o
+.\kern-0.27779
+.\tenrm w
+.\tenrm '
+.etc.
+
+) (u_ch1.tex [13] [14
+
+]
+Chapter 1.
+[15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29]
+[30] [31] [32] [33] [34] [35]
+Underfull \vbox (badness 4108) has occurred while \output is active
+\vbox(682.86613+0.0)x426.79134, glue set 3.45125
+.\glue(\topskip) 3.05556
+.\hbox(6.94444+0.8333)x426.79134, glue set 416.29143fil
+..\hbox(0.0+0.0)x0.0
+..\tentt @
+..\tentt }
+..\hbox(0.0+0.0)x0.0
+..\penalty 10000
+..etc.
+.\penalty 0
+.\glue(\baselineskip) 11.1667
+.\hbox(0.0+0.0)x0.0
+.etc.
+
+ [36]
+[37] [38]) (u_ch2.tex [39] [40
+
+]
+Chapter 2.
+[41] [42] [43] [44] [45] [46] [47] [48] [49] [50] [51] [52] [53] [54] [55]
+[56] [57] [58] [59]
+Underfull \vbox (badness 10000) has occurred while \output is active
+\vbox(682.86613+0.0)x426.79134
+.\glue(\topskip) 3.88889
+.\hbox(6.11111+2.22223)x426.79134, glue set 201.0433fil
+..\hbox(0.0+0.0)x0.0
+..\tentt @
+..\tentt !
+..\penalty 10000
+..\glue 5.24995
+..etc.
+.\penalty 0
+.\glue(\parskip) 0.0
+.\glue(\baselineskip) 2.83333
+.etc.
+
+ [60]
+[61]) (u_ch3.tex [62]
+Chapter 3.
+[63
+
+] [64] [65] [66] [67] [68] [69] [70] [71] [72] [73] [74] [75] [76] [77]
+[78] [79] [80] [81] [82] [83] [84] [85] [86] [87] [88] [89] [90] [91] [92]
+[93] [94] [95] [96] [97] [98] [99]) (u_ch4.tex [100]
+Chapter 4.
+[101
+
+] [102] [103] [104] [105] [106]) (u_ch5.tex [107] [108
+
+]
+Chapter 5.
+[109]
+Underfull \hbox (badness 10000) in paragraph at lines 163--163
+[] []\egtrm To reg-is-ter as a
+
+\hbox(5.46666+1.55556)x376.79134, glue set 71.60066
+.\hbox(0.0+0.0)x15.00002
+.\glue -15.00002
+.\hbox(0.0+0.0)x15.00002
+..\glue 15.00002
+..\glue -20.0
+..\glue -5.0
+..\hbox(0.0+0.0)x20.0, glue set 20.0fil
+...\glue 0.0 plus 1.0fil
+..\glue 5.0
+.\penalty 0
+.\egtrm T
+.etc.
+
+[110] [111] [112]
+Underfull \hbox (badness 10000) in paragraph at lines 330--340
+\tenrm FunnelWeb was
+
+\hbox(6.94444+0.0)x426.79134, glue set 215.12605
+.\tenrm F
+.\kern-0.83334
+.\tenrm u
+.\tenrm n
+.\tenrm n
+.etc.
+
+[113]) (u_cha.tex [114]
+Appendix A.
+[115
+
+] [116]
+Appendix B.
+[117
+
+] (u_manual.sin [118
+
+] [119] [120] [121] [122] [123] [124] [125] [126])
+[127
+
+]) (u_manual.aux) )
+Here is how much of TeX's memory you used:
+ 253 strings out of 56972
+ 2338 string characters out of 225268
+ 43716 words of memory out of 262143
+ 2191 multiletter control sequences out of 10000
+ 20390 words of font info for 77 fonts, out of 81920 for 254
+ 14 hyphenation exceptions out of 607
+ 16i,8n,15p,187b,243s stack positions out of 300i,100n,60p,5000b,1000s
+
+Output written on u_manual.dvi (128 pages, 442412 bytes).
diff --git a/web/funnelAC/userman/u_manual.ps b/web/funnelAC/userman/u_manual.ps
new file mode 100644
index 0000000000..e8b54fd616
--- /dev/null
+++ b/web/funnelAC/userman/u_manual.ps
@@ -0,0 +1,9876 @@
+%!PS-Adobe-2.0
+%%Creator: dvips 5.493 Copyright 1986, 1992 Radical Eye Software
+%%Title: u_manual.dvi
+%%CreationDate: Sat Feb 6 19:08:15 1993
+%%Pages: 128
+%%PageOrder: Ascend
+%%BoundingBox: 0 0 612 792
+%%EndComments
+%DVIPSCommandLine: dvips u_manual
+%DVIPSSource: TeX output 1993.02.06:1904
+%%BeginProcSet: tex.pro
+%!
+/TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}
+B /TR{translate}N /isls false N /vsize 11 72 mul N /@rigin{isls{[0 -1 1 0 0 0]
+concat}if 72 Resolution div 72 VResolution div neg scale isls{Resolution hsize
+-72 div mul 0 TR}if Resolution VResolution vsize -72 div 1 add mul TR matrix
+currentmatrix dup dup 4 get round 4 exch put dup dup 5 get round 5 exch put
+setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed
+true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N
+/IE 0 N /ctr 0 N /df-tail{/nn 8 dict N nn begin /FontType 3 N /FontMatrix
+fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{
+CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn
+put /ctr 0 N[}B /df{/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0
+0 sf neg 0 0]N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data
+dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{128
+ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127
+sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type
+/stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N
+/cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get
+S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height
+sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0
+-1 -.1 ch-xoff sub ch-yoff .1 add]{ch-image}imagemask restore}B /D{/cc X dup
+type /stringtype ne{]}if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1
+ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}
+B /I{cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin
+0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add
+.99 lt{/FV}{/RV}ifelse load def pop pop}N /eop{SI restore showpage userdict
+/eop-hook known{eop-hook}if}N /@start{userdict /start-hook known{start-hook}
+if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255
+{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76
+div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N
+/ruley 0 N /v{/ruley X /rulex X V}B /V{}B /RV statusdict begin /product where{
+pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4
+getinterval(NeXT)eq or}{pop false}ifelse}{false}ifelse end{{gsave TR -.1 -.1
+TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1
+-.1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /FV{
+gsave transform round exch round exch itransform moveto rulex 0 rlineto 0
+ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N
+/tail{dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M}
+B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{4 M}B
+/w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{p 1 w}B /r{
+p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save
+N}B /eos{SS restore}B end
+%%EndProcSet
+TeXDict begin 40258437 52099154 1000 300 300
+(/users/onl2/coates/startup/tmp/funnelweb/userman/u_manual.dvi)
+@start /Fa 13 118 df<072008E018E0306030C060C060C060C0C180C188C1884388659038E0
+0D0E7C8D12>97 D<03C00C6018E030E030006000600060004000C0004020604021801E000B0E7C
+8D10>99 D<07001880304060404080FF00C000C000C0008000C040C08043003C000A0E7B8D10>
+101 D<1F0006000600060006000C000C000C000C0019C01A601C201830306030603060306060C0
+60C461846188C098C0E00E177D9612>104 D<030706000000000000384C4C4C8C181818303262
+62243808177D960B>I<3E0C0C0C0C181818183030303060606060C0D0D0D0D06007177C9609>
+108 D<387044984708460C8C180C180C180C18183018311861186230263038100E7D8D14>110
+D<1C702288230C230C460C060C060C060C0C180C180C100C301A601B8018001800300030003000
+FC000E147E8D12>112 D<072008A018E0306030C060C060C060C0C180C180C180438067003B00
+030003000600060006003F800B147C8D10>I<38F04518463846308C000C000C000C0018001800
+18001800300030000D0E7D8D0F>I<07800C4018E018E038001E001F8007C000C060C0E0C0C180
+C3003E000B0E7D8D0F>I<030003000600060006000600FF800C000C000C001800180018001800
+300031003100310032001C0009147D930C>I<1C0826184618461886300C300C300C3018601862
+1862186208E407380F0E7D8D13>I E /Fb 11 115 df<07E01FF03838701C701C781C7E1C7FB8
+3FF01FF00FF83BFC70FEE03EE01EE00EE00EF00C78183FF00FE00F157E9414>56
+D<FFF83FE0FFF83FE00F800E000F801C000F8030000F8060000F81C0000F8380000F8700000F8F
+00000F9F00000FBF80000FE7C0000FC7C0000F83E0000F81F0000F81F8000F80F8000F807C000F
+803E000F803F00FFF8FFE0FFF8FFE01B177E9620>75 D<FEFEFEE0E0E0E0E0E0E0E0E0E0E0E0E0
+E0E0E0E0E0E0E0E0E0E0E0E0E0E0FEFEFE07217D980B>91 D<FEFEFE0E0E0E0E0E0E0E0E0E0E0E
+0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0EFEFEFE072180980B>93 D<0FE0003838003C1C003C1E00
+181E00001E0000FE000F9E003C1E00781E00F01E00F01E00F01E00786FC01F87C0120F7F8E14>
+97 D<07F01C18380C78067007F007F007FFFFF000F0007000780038031E0603FC100F7F8E13>
+101 D<0FCF001873803033807038007038007038007038003030001860002FC000200000300000
+3FF8003FFE003FFF00700780E00380E00380E00380700700380E000FF80011167F8E14>103
+D<FC0000FC00003C00003C00003C00003C00003C00003C00003C7C003D8E003E0F003E0F003C0F
+003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F00FF3FC0FF3FC012177E9617>I<38
+7C7C7C3800000000FCFC3C3C3C3C3C3C3C3C3C3C3CFFFF08187F970B>I<FC7C00FD8E003E0F00
+3E0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F00FF3FC0FF3FC0120F7E
+8E17>110 D<F8E0F9383A783A783C303C003C003C003C003C003C003C003C00FF80FF800D0F7E
+8E11>114 D E /Fc 1 111 df<383C0044C6004702004602008E06000C06000C06000C0C00180C
+00180C40181840181880300880300F00120E7F8D15>110 D E /Fd 57 123
+df<387CFEFEFE7C3807077C8610>46 D<0000180000380000380000700000700000E00000E000
+00E00001C00001C0000380000380000380000700000700000700000E00000E00001C00001C0000
+1C0000380000380000700000700000700000E00000E00001C00001C00001C00003800003800007
+00000700000700000E00000E00000E00001C00001C0000380000380000380000700000700000E0
+0000E00000C0000015317DA41C>I<00FE0007FFC00F83E01F01F03E00F83E00F87C007C7C007C
+7C007CFC007CFC007EFC007EFC007EFC007EFC007EFC007EFC007EFC007EFC007EFC007EFC007E
+FC007EFC007E7C007C7C007C7C007C3E00F83E00F81F01F00F83E007FFC000FE0017207E9F1C>
+I<00180000780001F800FFF800FFF80001F80001F80001F80001F80001F80001F80001F80001F8
+0001F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001F8
+0001F80001F80001F80001F8007FFFE07FFFE013207C9F1C>I<03FC000FFF003C1FC07007E07C
+07F0FE03F0FE03F8FE03F8FE01F87C01F83803F80003F80003F00003F00007E00007C0000F8000
+1F00003E0000380000700000E01801C0180380180700180E00380FFFF01FFFF03FFFF07FFFF0FF
+FFF0FFFFF015207D9F1C>I<00FE0007FFC00F07E01E03F03F03F03F81F83F81F83F81F81F03F8
+1F03F00003F00003E00007C0001F8001FE0001FF000007C00001F00001F80000FC0000FC3C00FE
+7E00FEFF00FEFF00FEFF00FEFF00FC7E01FC7801F81E07F00FFFC001FE0017207E9F1C>I<0000
+E00001E00003E00003E00007E0000FE0001FE0001FE00037E00077E000E7E001C7E00187E00307
+E00707E00E07E00C07E01807E03807E07007E0E007E0FFFFFEFFFFFE0007E00007E00007E00007
+E00007E00007E00007E000FFFE00FFFE17207E9F1C>I<1000201E01E01FFFC01FFF801FFF001F
+FE001FF8001BC00018000018000018000018000019FC001FFF001E0FC01807E01803E00003F000
+03F00003F80003F83803F87C03F8FE03F8FE03F8FC03F0FC03F07007E03007C01C1F800FFF0003
+F80015207D9F1C>I<001F8000FFE003F07007C0F00F01F81F01F83E01F83E01F87E00F07C0000
+7C0000FC0800FC7FC0FCFFE0FD80F0FF00F8FE007CFE007CFC007EFC007EFC007EFC007E7C007E
+7C007E7C007E3C007C3E007C1E00F80F00F00783E003FFC000FF0017207E9F1C>I<6000007800
+007FFFFE7FFFFE7FFFFC7FFFF87FFFF87FFFF0E00060E000C0C00180C00300C00300000600000C
+00001C0000180000380000780000780000F00000F00000F00001F00001F00001F00003F00003F0
+0003F00003F00003F00003F00003F00001E00017227DA11C>I<00FE0003FFC00703E00E00F01C
+00F01C00783C00783E00783F00783F80783FE0F01FF9E01FFFC00FFF8007FFC003FFE007FFF01E
+7FF83C1FFC7807FC7801FEF000FEF0003EF0001EF0001EF0001CF8001C7800383C00381F01F00F
+FFC001FF0017207E9F1C>I<01FE0007FF800F83E01E01F03E00F07C00F87C0078FC007CFC007C
+FC007CFC007EFC007EFC007EFC007E7C00FE7C00FE3E01FE1E037E0FFE7E07FC7E00207E00007C
+00007C1E007C3F00F83F00F83F00F03F01E01E03C01C0F800FFE0003F80017207E9F1C>I<0000
+70000000007000000000F800000000F800000000F800000001FC00000001FC00000003FE000000
+03FE00000003FE00000006FF000000067F0000000E7F8000000C3F8000000C3F800000183FC000
+00181FC00000381FE00000300FE00000300FE00000600FF000006007F00000E007F80000FFFFF8
+0000FFFFF800018001FC00018001FC00038001FE00030000FE00030000FE000600007F00060000
+7F00FFE00FFFF8FFE00FFFF825227EA12A>65 D<FFFFFF8000FFFFFFE00007F001F80007F000FC
+0007F0007E0007F0007E0007F0007F0007F0007F0007F0007F0007F0007F0007F0007F0007F000
+7E0007F000FE0007F000FC0007F003F80007FFFFF00007FFFFF00007F001FC0007F0007E0007F0
+003F0007F0003F8007F0001F8007F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007
+F0001FC007F0003F8007F0003F8007F0007F0007F001FE00FFFFFFF800FFFFFFC00022227EA128
+>I<0003FE0080001FFF818000FF01E38001F8003F8003E0001F8007C0000F800F800007801F80
+0007803F000003803F000003807F000001807E000001807E00000180FE00000000FE00000000FE
+00000000FE00000000FE00000000FE00000000FE00000000FE000000007E000000007E00000180
+7F000001803F000001803F000003801F800003000F8000030007C000060003F0000C0001F80038
+0000FF00F000001FFFC0000003FE000021227DA128>I<FFFFFF8000FFFFFFF00007F003FC0007
+F0007E0007F0003F0007F0001F8007F0000FC007F00007E007F00007E007F00007F007F00003F0
+07F00003F007F00003F007F00003F807F00003F807F00003F807F00003F807F00003F807F00003
+F807F00003F807F00003F807F00003F807F00003F007F00003F007F00003F007F00007E007F000
+07E007F0000FC007F0001F8007F0003F0007F0007E0007F003FC00FFFFFFF000FFFFFF80002522
+7EA12B>I<FFFFFFFCFFFFFFFC07F000FC07F0003C07F0001C07F0000C07F0000E07F0000E07F0
+000607F0180607F0180607F0180607F0180007F0380007F0780007FFF80007FFF80007F0780007
+F0380007F0180007F0180007F0180307F0180307F0000307F0000607F0000607F0000607F0000E
+07F0000E07F0001E07F0003E07F001FCFFFFFFFCFFFFFFFC20227EA125>I<FFFFFFF8FFFFFFF8
+07F001F807F0007807F0003807F0001807F0001C07F0001C07F0000C07F0000C07F0180C07F018
+0C07F0180007F0180007F0380007F0780007FFF80007FFF80007F0780007F0380007F0180007F0
+180007F0180007F0180007F0000007F0000007F0000007F0000007F0000007F0000007F0000007
+F00000FFFFE000FFFFE0001E227EA123>I<0003FE0040001FFFC0C0007F00F1C001F8003FC003
+F0000FC007C00007C00FC00003C01F800003C03F000001C03F000001C07F000000C07E000000C0
+7E000000C0FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE000000
+00FE000FFFFC7E000FFFFC7F00001FC07F00001FC03F00001FC03F00001FC01F80001FC00FC000
+1FC007E0001FC003F0001FC001FC003FC0007F80E7C0001FFFC3C00003FF00C026227DA12C>I<
+FFFF83FFFEFFFF83FFFE07F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007F0001F
+C007F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007FFFF
+FFC007FFFFFFC007F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007F0
+001FC007F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007
+F0001FC0FFFF83FFFEFFFF83FFFE27227EA12C>I<FFFFE0FFFFE003F80003F80003F80003F800
+03F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F800
+03F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F800
+FFFFE0FFFFE013227FA115>I<FFFFE000FFFFE00007F0000007F0000007F0000007F0000007F0
+000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007
+F0000007F0000007F0000007F0000007F0000007F0001807F0001807F0001807F0001807F00038
+07F0003807F0007007F0007007F000F007F001F007F007F0FFFFFFF0FFFFFFF01D227EA122>76
+D<FFF000000FFFFFF800001FFF07F800001FE006FC000037E006FC000037E006FC000037E0067E
+000067E0067E000067E0063F0000C7E0063F0000C7E0061F800187E0061F800187E0060FC00307
+E0060FC00307E0060FC00307E00607E00607E00607E00607E00603F00C07E00603F00C07E00601
+F81807E00601F81807E00601F81807E00600FC3007E00600FC3007E006007E6007E006007E6007
+E006003FC007E006003FC007E006001F8007E006001F8007E006001F8007E006000F0007E0FFF0
+0F00FFFFFFF00600FFFF30227EA135>I<FFF8001FFEFFFC001FFE07FC0000C007FE0000C006FF
+0000C0067F8000C0063FC000C0061FE000C0060FE000C0060FF000C00607F800C00603FC00C006
+01FE00C00600FE00C00600FF00C006007F80C006003FC0C006001FE0C006000FF0C0060007F0C0
+060007F8C0060003FCC0060001FEC0060000FFC00600007FC00600007FC00600003FC00600001F
+C00600000FC006000007C006000003C006000003C0FFF00001C0FFF00000C027227EA12C>I<00
+07FC0000003FFF800000FC07E00003F001F80007E000FC000FC0007E001F80003F001F80003F00
+3F00001F803F00001F807F00001FC07E00000FC07E00000FC0FE00000FE0FE00000FE0FE00000F
+E0FE00000FE0FE00000FE0FE00000FE0FE00000FE0FE00000FE0FE00000FE07E00000FC07F0000
+1FC07F00001FC03F00001F803F80003F801F80003F000FC0007E0007E000FC0003F001F80000FC
+07E000003FFF80000007FC000023227DA12A>I<FFFFFF00FFFFFFE007F007F007F001FC07F000
+FC07F0007E07F0007E07F0007F07F0007F07F0007F07F0007F07F0007F07F0007E07F0007E07F0
+00FC07F001FC07F007F007FFFFE007FFFF0007F0000007F0000007F0000007F0000007F0000007
+F0000007F0000007F0000007F0000007F0000007F0000007F0000007F00000FFFF8000FFFF8000
+20227EA126>I<0007FC0000003FFF800000FC07E00003F001F80007E000FC000FC0007E001F80
+003F001F80003F003F00001F803F00001F807F00001FC07E00000FC07E00000FC0FE00000FE0FE
+00000FE0FE00000FE0FE00000FE0FE00000FE0FE00000FE0FE00000FE0FE00000FE0FE00000FE0
+7E00000FC07F00001FC07F00001FC03F00001F803F81F03F801F83F83F000FC70C7E0007E606FC
+0003F607F80000FF07E000003FFF80000007FF80200000038020000003C020000003E0E0000003
+FFE0000001FFC0000001FFC0000000FFC0000000FF800000007F000000001E00232C7DA12A>I<
+FFFFFE0000FFFFFFC00007F007F00007F001F80007F000FC0007F0007E0007F0007F0007F0007F
+0007F0007F0007F0007F0007F0007F0007F0007F0007F0007E0007F000FC0007F001F80007F007
+F00007FFFFC00007FFFF800007F00FE00007F007F00007F003F80007F001FC0007F001FC0007F0
+01FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC0607F000FE0607
+F000FF0CFFFF803FF8FFFF800FF027227EA12A>I<01FC0407FF8C1F03FC3C007C7C003C78001C
+78001CF8000CF8000CFC000CFC0000FF0000FFE0007FFF007FFFC03FFFF01FFFF80FFFFC03FFFE
+003FFE0003FF00007F00003F00003FC0001FC0001FC0001FE0001EE0001EF0003CFC003CFF00F8
+C7FFE080FF8018227DA11F>I<7FFFFFFF807FFFFFFF807E03F80F807803F807807003F8038060
+03F80180E003F801C0E003F801C0C003F800C0C003F800C0C003F800C0C003F800C00003F80000
+0003F800000003F800000003F800000003F800000003F800000003F800000003F800000003F800
+000003F800000003F800000003F800000003F800000003F800000003F800000003F800000003F8
+00000003F800000003F800000003F8000003FFFFF80003FFFFF80022227EA127>I<FFFF803FFC
+FFFF803FFC07F000018007F000018007F000018007F000018007F000018007F000018007F00001
+8007F000018007F000018007F000018007F000018007F000018007F000018007F000018007F000
+018007F000018007F000018007F000018007F000018007F000018007F000018007F000018007F0
+00018007F000018003F000030003F800030001F800060000FC000E00007E001C00003F80F80000
+0FFFE0000001FF000026227EA12B>I<FFFF0FFFF01FFEFFFF0FFFF01FFE0FF000FF0000E007F0
+007F0000C007F0007F0000C003F8007F80018003F8003F80018003FC003F80038001FC003FC003
+0001FC003FC0030000FE007FE0060000FE006FE0060000FF006FE00600007F00C7F00C00007F00
+C7F00C00007F80C7F81C00003F8183F81800003F8183F81800001FC383FC3000001FC301FC3000
+001FE301FC3000000FE600FE6000000FE600FE6000000FF600FFE0000007FC007FC0000007FC00
+7FC0000003FC007F80000003F8003F80000003F8003F80000001F0001F00000001F0001F000000
+00F0001E00000000E0000E00000000E0000E000037227FA13A>87 D<07FC001FFF803F07C03F03
+E03F01E03F01F01E01F00001F00001F0003FF003FDF01FC1F03F01F07E01F0FC01F0FC01F0FC01
+F0FC01F07E02F07E0CF81FF87F07E03F18167E951B>97 D<FF000000FF0000001F0000001F0000
+001F0000001F0000001F0000001F0000001F0000001F0000001F0000001F0000001F0000001F0F
+E0001F3FF8001FF07C001F801E001F001F001F000F801F000F801F000FC01F000FC01F000FC01F
+000FC01F000FC01F000FC01F000FC01F000FC01F000F801F001F801F801F001FC03E001EE07C00
+1C3FF800180FC0001A237EA21F>I<00FF8007FFE00F83F01F03F03E03F07E03F07C01E07C0000
+FC0000FC0000FC0000FC0000FC0000FC00007C00007E00007E00003E00301F00600FC0E007FF80
+00FE0014167E9519>I<0001FE000001FE0000003E0000003E0000003E0000003E0000003E0000
+003E0000003E0000003E0000003E0000003E0000003E0001FC3E0007FFBE000F81FE001F007E00
+3E003E007E003E007C003E00FC003E00FC003E00FC003E00FC003E00FC003E00FC003E00FC003E
+00FC003E007C003E007C003E003E007E001E00FE000F83BE0007FF3FC001FC3FC01A237EA21F>
+I<00FE0007FF800F87C01E01E03E01F07C00F07C00F8FC00F8FC00F8FFFFF8FFFFF8FC0000FC00
+00FC00007C00007C00007E00003E00181F00300FC07003FFC000FF0015167E951A>I<003F8000
+FFC001E3E003C7E007C7E00F87E00F83C00F80000F80000F80000F80000F80000F8000FFFC00FF
+FC000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F
+80000F80000F80000F80000F80000F80007FF8007FF80013237FA211>I<03FC1E0FFF7F1F0F8F
+3E07CF3C03C07C03E07C03E07C03E07C03E07C03E03C03C03E07C01F0F801FFF0013FC00300000
+3000003800003FFF801FFFF00FFFF81FFFFC3800FC70003EF0001EF0001EF0001EF0001E78003C
+7C007C3F01F80FFFE001FF0018217E951C>I<FF000000FF0000001F0000001F0000001F000000
+1F0000001F0000001F0000001F0000001F0000001F0000001F0000001F0000001F07E0001F1FF8
+001F307C001F403C001F803E001F803E001F003E001F003E001F003E001F003E001F003E001F00
+3E001F003E001F003E001F003E001F003E001F003E001F003E001F003E001F003E00FFE1FFC0FF
+E1FFC01A237EA21F>I<1C003E007F007F007F003E001C000000000000000000000000000000FF
+00FF001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F00
+FFE0FFE00B247EA310>I<FF000000FF0000001F0000001F0000001F0000001F0000001F000000
+1F0000001F0000001F0000001F0000001F0000001F0000001F00FF801F00FF801F0038001F0060
+001F01C0001F0380001F0700001F0E00001F1C00001F7E00001FFF00001FCF00001F0F80001F07
+C0001F03E0001F01E0001F01F0001F00F8001F007C001F003C00FFE0FFC0FFE0FFC01A237EA21E
+>107 D<FF00FF001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F
+001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F00FFE0FFE00B237EA2
+10>I<FF07F007F000FF1FFC1FFC001F303E303E001F403E403E001F801F801F001F801F801F00
+1F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F
+001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F00
+1F001F001F00FFE0FFE0FFE0FFE0FFE0FFE02B167E9530>I<FF07E000FF1FF8001F307C001F40
+3C001F803E001F803E001F003E001F003E001F003E001F003E001F003E001F003E001F003E001F
+003E001F003E001F003E001F003E001F003E001F003E001F003E00FFE1FFC0FFE1FFC01A167E95
+1F>I<00FE0007FFC00F83E01E00F03E00F87C007C7C007C7C007CFC007EFC007EFC007EFC007E
+FC007EFC007EFC007E7C007C7C007C3E00F81F01F00F83E007FFC000FE0017167E951C>I<FF0F
+E000FF3FF8001FF07C001F803E001F001F001F001F801F001F801F000FC01F000FC01F000FC01F
+000FC01F000FC01F000FC01F000FC01F000FC01F001F801F001F801F803F001FC03E001FE0FC00
+1F3FF8001F0FC0001F0000001F0000001F0000001F0000001F0000001F0000001F0000001F0000
+00FFE00000FFE000001A207E951F>I<00FE030007FF87000FC1C7001F006F003F003F007E003F
+007E001F007C001F00FC001F00FC001F00FC001F00FC001F00FC001F00FC001F00FC001F007E00
+1F007E001F003E003F001F007F000FC1DF0007FF9F0001FC1F0000001F0000001F0000001F0000
+001F0000001F0000001F0000001F0000001F000000FFE00000FFE01B207E951E>I<FE1F00FE3F
+C01E67E01EC7E01E87E01E87E01F83C01F00001F00001F00001F00001F00001F00001F00001F00
+001F00001F00001F00001F00001F0000FFF000FFF00013167E9517>I<0FF3003FFF00781F0060
+0700E00300E00300F00300FC00007FE0007FF8003FFE000FFF0001FF00000F80C00780C00380E0
+0380E00380F00700FC0E00EFFC00C7F00011167E9516>I<018000018000018000018000038000
+0380000780000780000F80003F8000FFFF00FFFF000F80000F80000F80000F80000F80000F8000
+0F80000F80000F80000F80000F80000F81800F81800F81800F81800F81800F830007C30003FE00
+00F80011207F9F16>I<FF01FE00FF01FE001F003E001F003E001F003E001F003E001F003E001F
+003E001F003E001F003E001F003E001F003E001F003E001F003E001F003E001F003E001F003E00
+1F007E001F00FE000F81BE0007FF3FC001FC3FC01A167E951F>I<FFE01FE0FFE01FE00F800600
+0F8006000FC00E0007C00C0007E01C0003E0180003E0180001F0300001F0300000F8600000F860
+00007CC000007CC000007FC000003F8000003F8000001F0000001F0000000E0000000E00001B16
+7F951E>I<FFE7FF07F8FFE7FF07F81F007800C00F807801800F807C01800F807C018007C07E03
+0007C0DE030007E0DE070003E0DF060003E18F060001F18F0C0001F38F8C0001FB079C0000FB07
+D80000FE03D800007E03F000007E03F000007C01F000003C01E000003800E000001800C0002516
+7F9528>I<FFE07FC0FFE07FC00F801C0007C0380003E0700003F0600001F8C00000F98000007F
+8000003F0000001F0000001F8000003FC0000037C0000063E00000C1F00001C0F8000380FC0007
+007E000E003E00FF80FFE0FF80FFE01B167F951E>I<FFE01FE0FFE01FE00F8006000F8006000F
+C00E0007C00C0007E01C0003E0180003E0180001F0300001F0300000F8600000F86000007CC000
+007CC000007FC000003F8000003F8000001F0000001F0000000E0000000E0000000C0000000C00
+000018000078180000FC380000FC300000FC60000069C000007F8000001F0000001B207F951E>
+I<7FFFF07FFFF07C03E07007C0600FC0E01F80C01F00C03E00C07E0000FC0000F80001F00003F0
+3007E03007C0300F80701F80703F00603E00E07C03E0FFFFE0FFFFE014167E9519>I
+E /Fe 20 118 df<60F0F0600404798312>46 D<FFFEFFFE7FFE0000000000007FFEFFFEFFFE0F
+097F8E12>61 D<03E007F01E18381C30FC71FE739EE30EE70EE70EE70EE70EE30C739C71F830F0
+38001E0E07FE03F80F147F9312>64 D<7FFEFFFEE38EE38EE38E03800380038003800380038003
+800380038003800380038003801FF01FF00F147F9312>84 D<C000E000E0007000700038003800
+1C001C001C000E000E00070007000380038001C001C001C000E000E0007000700038003800180D
+1A7E9612>92 D<3F807FC070E0207000700FF03FF07870E070E070E07070F03FFE1F3E0F0E7E8D
+12>97 D<F800F80038003800380038003BE03FF03C38381C380C380E380E380E380E380C381C3C
+383FF01BC00F147F9312>I<00F800F8003800380038003807B81FF8387870386038E038E038E0
+38E0386038707838781FFE0FBE0F147F9312>100 D<07801FE0387070706038E038FFF8FFF8E0
+006000703838381FF007C00D0E7E8D12>I<F800F800380038003800380039E03FF03E383C3838
+383838383838383838383838383838FE3EFE3E0F147F9312>104 D<06000F000F000600000000
+000000FF00FF000700070007000700070007000700070007000700FFF0FFF00C157D9412>I<FF
+00FF000700070007000700070007000700070007000700070007000700070007000700FFF8FFF8
+0D147E9312>108 D<F71C00FFBE0079E70079E70071C70071C70071C70071C70071C70071C700
+71C70071C700F9E780F8E380110E808D12>I<F9E0FFF03E383C38383838383838383838383838
+38383838FE3EFE3E0F0E7F8D12>I<0F803FE038E07070E038E038E038E038E038F078707038E0
+3FE00F800D0E7E8D12>I<FBE0FFF03C38381C380C380E380E380E380E380C381C3C383FF03BC0
+38003800380038003800FE00FE000F157F8D12>I<FCF8FDFC1F1C1E081E001C001C001C001C00
+1C001C001C00FFC0FFC00E0E7E8D12>114 D<1FF03FF06070C070E0007F003FE00FF000786018
+E018F030FFE0DFC00D0E7E8D12>I<06000E000E000E007FF8FFF80E000E000E000E000E000E00
+0E000E380E380E3807F003C00D127F9112>I<F8F8F8F838383838383838383838383838383838
+383838781FFE0FBE0F0E7F8D12>I E /Ff 6 55 df<0C003C00CC000C000C000C000C000C000C
+000C000C000C000C000C000C00FF8009107E8F0F>49 D<1F00618040C08060C0600060006000C0
+0180030006000C00102020207FC0FFC00B107F8F0F>I<1F00218060C060C000C0008001800F00
+008000400060C060C060804060801F000B107F8F0F>I<0300030007000F000B00130033002300
+4300C300FFE003000300030003001FE00B107F8F0F>I<20803F002C002000200020002F003080
+2040006000600060C06080C061801F000B107F8F0F>I<0780184030C060C06000C000CF00F080
+E040C060C060C060406060C030801F000B107F8F0F>I E /Fg 6 55 df<0C001C00EC000C000C
+000C000C000C000C000C000C000C000C000C000C000C000C000C00FFC00A137D9211>49
+D<1F0060C06060F070F030603000700070006000C001C00180020004000810101020207FE0FFE0
+0C137E9211>I<0FC030707038703870380038003000E00FC0007000380018001C601CF01CF018
+E03860701FC00E137F9211>I<006000E000E00160026006600C600860106020606060C060FFFC
+0060006000600060006003FC0E137F9211>I<60607FC07F8044004000400040004F0070C040E0
+006000700070E070E070E06040E021C01F000C137E9211>I<07C00C201070207060006000C000
+CF00D0C0E060C020C030C030C03040306020206010C00F000C137E9211>I
+E /Fh 60 123 df<00FC000782000E07001C07001C02001C00001C00001C00001C0000FFFF001C
+07001C07001C07001C07001C07001C07001C07001C07001C07001C07001C07001C0700FF1FE013
+17809614>12 D<60C0F1E0F1E070E01020102020402040408040800B0A7F9612>34
+D<1C00183200186180706161E0E09E60E080C0E08180E08180E08300E08300610600610C00320C
+001C18380030640030C20060C200C1C100C1C10181C10181C10301C10601C10600C20C00C21800
+64080038181B7E981D>37 D<60F0F070101020204040040A7D960A>39 D<0102040C1818303070
+606060E0E0E0E0E0E0E0E0E0E060606070303018180C04020108227D980E>I<8040203018180C
+0C0E060606070707070707070707070606060E0C0C18183020408008227E980E>I<60F0F07010
+1020204040040A7D830A>44 D<60F0F06004047D830A>46 D<07C018303018701C600C600CE00E
+E00EE00EE00EE00EE00EE00EE00EE00E600C600C701C30181C7007C00F157F9412>48
+D<03000700FF000700070007000700070007000700070007000700070007000700070007000700
+07007FF00C157E9412>I<0F8030E040708030C038E0384038003800700070006000C001800300
+06000C08080810183FF07FF0FFF00D157E9412>I<0FE030306018701C701C001C001800380060
+07E000300018000C000E000EE00EE00EC00C401830300FE00F157F9412>I<20303FE03FC02400
+20002000200020002F8030E020700030003800384038E038E0388030406020C01F000D157E9412
+>53 D<01F00608080C181C301C70006000E000E3E0EC30F018F00CE00EE00EE00E600E600E300C
+3018183007C00F157F9412>I<40007FFE7FFC7FF8C00880108020004000800080010001000300
+0200060006000E000E000E000E000E0004000F167E9512>I<60F0F06000000000000060F0F060
+040E7D8D0A>58 D<001000003800003800003800005C00005C00005C00008E00008E00008E0001
+070001070003078002038002038007FFC00401C00401C00800E00800E01800E03800F0FE03FE17
+177F961A>65 D<FFFE001C03801C00E01C00601C00701C00701C00701C00701C00E01C01C01FFF
+801FFFC01C00E01C00701C00301C00381C00381C00381C00381C00701C00E01C01C0FFFF001517
+7F9619>I<00FC100383300E00B01C0070380030300030700010600010E00010E00000E00000E0
+0000E00000E00000E000106000107000103000203800201C00400E008003830000FC0014177E96
+19>I<FFFFE01C00E01C00601C00201C00101C00101C00101C04001C04001C04001C0C001FFC00
+1C0C001C04001C04081C04081C00081C00181C00101C00101C00301C00F0FFFFF015177F9618>
+69 D<FFFFE01C00E01C00601C00201C00101C00101C00101C04001C04001C04001C0C001FFC00
+1C0C001C04001C04001C04001C00001C00001C00001C00001C00001C0000FFC00014177F9617>
+I<FF83FE1C00701C00701C00701C00701C00701C00701C00701C00701C00701C00701FFFF01C00
+701C00701C00701C00701C00701C00701C00701C00701C00701C0070FF83FE17177F961A>72
+D<FFE00E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E00
+0E000E000E00FFE00B177F960D>I<FF80FE1C00781C00601C00401C00801C01001C06001C0800
+1C10001C38001C78001C9C001D0E001E0E001C07001C03801C01C01C01C01C00E01C00701C0078
+1C007CFF80FF18177F961B>75 D<FFC0001C00001C00001C00001C00001C00001C00001C00001C
+00001C00001C00001C00001C00001C00001C00201C00201C00201C00601C00601C00401C00C01C
+03C0FFFFC013177F9616>I<FC00FE1E00381F001017001013801011C01011C01010E010107010
+103810103810101C10100E10100F101007101003901001D01001D01000F0100070100030380030
+FE001017177F961A>78 D<00FC000303000E01C01C00E0380070300030700038600018E0001CE0
+001CE0001CE0001CE0001CE0001CE0001C7000387000383000303800701C00E00E01C003030000
+FC0016177E961B>I<FFFE001C03801C00C01C00601C00701C00701C00701C00701C00601C00C0
+1C03801FFE001C00001C00001C00001C00001C00001C00001C00001C00001C00001C0000FF8000
+14177F9618>I<FFFC001C03801C00C01C00E01C00701C00701C00701C00701C00E01C00C01C03
+801FFE001C07801C01C01C00E01C00E01C00E01C00E01C00E01C00E11C00E11C0072FF803C1817
+7F961A>82 D<0FC4302C601C400CC004C004C004E00070007F003FE00FF801FC001C000E000680
+0680068006C004E008D81087E00F177E9614>I<7FFFF860381840380840380880380480380480
+380400380000380000380000380000380000380000380000380000380000380000380000380000
+380000380000380007FFC016177F9619>I<FF07FC3F803C01E00E001C00E004001C00E004001C
+017004000E017008000E017008000E023808000702381000070238100007041C100003841C2000
+03841C200003880E200001C80E400001C80E400001D80F400000F007800000F007800000F00780
+0000600300000060030000006003000021177F9624>87 D<FF83FC1F01E00E0080070080078100
+03820001C20001E40000E800007800007800003800007C00005E00008E00018700010780020380
+0601C00401E00C00E01C00F0FF03FE17177F961A>I<FFC03F801E001C000F0008000700100007
+8030000380200001C0400001E0400000E0800000F1800000710000003A0000003E0000001C0000
+001C0000001C0000001C0000001C0000001C0000001C0000001C0000001C000000FF8000191780
+961A>I<204020404080408081008100E1C0F1E0F1E060C00B0A7B9612>92
+D<1FC0386038301038003803F81E3830387038E039E039E07970FF1F1E100E7F8D12>97
+D<FC00001C00001C00001C00001C00001C00001C00001C00001C00001CF8001F06001C03001C03
+801C01801C01C01C01C01C01C01C01C01C01801C03801C03001B0E0010F8001217809614>I<07
+F01838303870106000E000E000E000E000600070083008183007C00D0E7F8D10>I<007E00000E
+00000E00000E00000E00000E00000E00000E00000E0007CE001C3E00300E00700E00600E00E00E
+00E00E00E00E00E00E00600E00700E00301E00182E0007CFC012177F9614>I<0FC01860303070
+38E018FFF8E000E000E000600070083010183007C00D0E7F8D10>I<03E006700E701C201C001C
+001C001C001C00FF801C001C001C001C001C001C001C001C001C001C001C001C00FF800C178096
+0B>I<0F9E18E33060707070707070306018C02F80200060003FE03FF83FFC600EC006C006C006
+600C38380FE010157F8D12>I<FC00001C00001C00001C00001C00001C00001C00001C00001C00
+001C7C001D8E001E07001C07001C07001C07001C07001C07001C07001C07001C07001C07001C07
+00FF9FE01317809614>I<183C3C1800000000007C1C1C1C1C1C1C1C1C1C1C1C1CFF081780960A>
+I<FC00001C00001C00001C00001C00001C00001C00001C00001C00001C3F801C1C001C18001C20
+001C40001CC0001FE0001CF0001C70001C78001C3C001C1E001C1E00FF3FC01217809613>107
+D<FC001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C00
+1C001C001C00FF80091780960A>I<FC7C1F001D8E63801E0781C01C0701C01C0701C01C0701C0
+1C0701C01C0701C01C0701C01C0701C01C0701C01C0701C01C0701C0FF9FE7F81D0E808D1E>I<
+FC7C001D8E001E07001C07001C07001C07001C07001C07001C07001C07001C07001C07001C0700
+FF9FE0130E808D14>I<07C018303018600C600CE00EE00EE00EE00EE00E701C3018183007C00F
+0E7F8D12>I<FCF8001F0E001C03001C03801C01801C01C01C01C01C01C01C01C01C01801C0380
+1C07001F0E001CF8001C00001C00001C00001C00001C0000FF80001214808D14>I<07C2001C26
+00381E00700E00600E00E00E00E00E00E00E00E00E00600E00700E00301E001C2E0007CE00000E
+00000E00000E00000E00000E00007FC012147F8D13>I<FCF01D381E381C101C001C001C001C00
+1C001C001C001C001C00FF800D0E808D0E>I<1F4060C0C040C040E000FF007F801FC001E08060
+8060C060E0C09F000B0E7F8D0E>I<080008000800180018003800FF8038003800380038003800
+3800380038403840384038401C800F000A147F930E>I<FC3F001C07001C07001C07001C07001C
+07001C07001C07001C07001C07001C07001C0F000E170003E7E0130E808D14>I<FE1F3C0E3C0C
+1C081C080E100E100720072003C003C003C001800180100E7F8D13>I<FCFE7C3838383838101C
+3C201C3C201C4C200E4E400E4E400E8640078780078780070380030300030300160E7F8D19>I<
+FE3F3C181C100E20074007C0038001C002E004F008701838383CFC7F100E7F8D13>I<FE1F3C0E
+3C0C1C081C080E100E100720072003C003C003C00180018001000100E200E200A400780010147F
+8D13>I<FFF0C0E080E081C08380878007000E001E081C08381870107030FFF00D0E7F8D10>I
+E /Fi 57 122 df<0001FF0000001FFFC000007F80F00000FC00F80001F801F80003F803FC0007
+F003FC0007F003FC0007F003FC0007F001F80007F000F00007F000000007F000000007F0000000
+07F0000000FFFFFFFC00FFFFFFFC00FFFFFFFC0007F001FC0007F001FC0007F001FC0007F001FC
+0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001
+FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC0007F0
+01FC0007F001FC007FFF1FFFC07FFF1FFFC07FFF1FFFC0222A7FA926>12
+D<0001FF803FE000001FFFE3FFF800007F80FFF01E0000FE007F801F0001F800FF003F0003F801
+FF007F8007F001FE007F8007F001FE007F8007F001FE007F8007F000FE003F0007F000FE001E00
+07F000FE00000007F000FE00000007F000FE00000007F000FE000000FFFFFFFFFFFF80FFFFFFFF
+FFFF80FFFFFFFFFFFF8007F000FE003F8007F000FE003F8007F000FE003F8007F000FE003F8007
+F000FE003F8007F000FE003F8007F000FE003F8007F000FE003F8007F000FE003F8007F000FE00
+3F8007F000FE003F8007F000FE003F8007F000FE003F8007F000FE003F8007F000FE003F8007F0
+00FE003F8007F000FE003F8007F000FE003F8007F000FE003F8007F000FE003F8007F000FE003F
+807FFF0FFFE3FFF87FFF0FFFE3FFF87FFF0FFFE3FFF8352A7FA939>14 D<1C007F007F00FF80FF
+C0FFC07FC07FC01CC000C000C00180018001800300030006000C001800300020000A157BA913>
+39 D<1C003E007F00FF80FF80FF807F003E001C0009097B8813>46 D<003F800001FFF00007E0
+FC000FC07E001F803F001F803F003F001F803F001F807F001FC07F001FC07F001FC07F001FC0FF
+001FE0FF001FE0FF001FE0FF001FE0FF001FE0FF001FE0FF001FE0FF001FE0FF001FE0FF001FE0
+FF001FE0FF001FE0FF001FE0FF001FE0FF001FE07F001FC07F001FC07F001FC07F001FC03F001F
+803F001F801F803F001F803F000FC07E0007E0FC0001FFF000003F80001B277DA622>48
+D<000E00001E00007E0007FE00FFFE00FFFE00F8FE0000FE0000FE0000FE0000FE0000FE0000FE
+0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE
+0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE007FFFFE7FFFFE7FFF
+FE17277BA622>I<00FF800003FFF0000FFFFC001F03FE003800FF007C007F80FE003FC0FF003F
+C0FF003FE0FF001FE0FF001FE07E001FE03C003FE000003FE000003FC000003FC000007F800000
+7F000000FE000000FC000001F8000003F0000003E00000078000000F0000001E0000003C00E000
+7000E000E000E001C001C0038001C0070001C00FFFFFC01FFFFFC03FFFFFC07FFFFFC0FFFFFF80
+FFFFFF80FFFFFF801B277DA622>I<007F800003FFF00007FFFC000F81FE001F00FF003F80FF00
+3F807F803F807F803F807F801F807F800F007F800000FF000000FF000000FE000001FC000001F8
+000007F00000FFC00000FFF0000001FC0000007E0000007F0000007F8000003FC000003FC00000
+3FE000003FE03C003FE07E003FE0FF003FE0FF003FE0FF003FC0FF007FC07E007F807C007F003F
+01FE001FFFFC0007FFF00000FF80001B277DA622>I<00000E0000001E0000003E0000007E0000
+00FE000000FE000001FE000003FE0000077E00000E7E00000E7E00001C7E0000387E0000707E00
+00E07E0000E07E0001C07E0003807E0007007E000E007E000E007E001C007E0038007E0070007E
+00E0007E00FFFFFFF8FFFFFFF8FFFFFFF80000FE000000FE000000FE000000FE000000FE000000
+FE000000FE000000FE00007FFFF8007FFFF8007FFFF81D277EA622>I<0C0003000F803F000FFF
+FE000FFFFC000FFFF8000FFFF0000FFFE0000FFFC0000FFE00000E0000000E0000000E0000000E
+0000000E0000000E0000000E7FC0000FFFF8000F80FC000E003E000C003F0000001F8000001FC0
+00001FC000001FE000001FE018001FE07C001FE0FE001FE0FE001FE0FE001FE0FE001FC0FC001F
+C078003F8078003F803C007F001F01FE000FFFF80003FFF00000FF80001B277DA622>I<0007F0
+00003FFC0000FFFE0001FC0F0003F01F8007E03F800FC03F801FC03F801F803F803F801F003F80
+00007F0000007F0000007F000000FF000000FF0FC000FF3FF800FF707C00FFC03E00FFC03F00FF
+801F80FF801FC0FF001FC0FF001FE0FF001FE0FF001FE07F001FE07F001FE07F001FE07F001FE0
+3F001FE03F001FC01F801FC01F803F800FC03F0007E07E0003FFFC0000FFF000003FC0001B277D
+A622>I<380000003E0000003FFFFFF03FFFFFF03FFFFFF07FFFFFE07FFFFFC07FFFFF807FFFFF
+0070000E0070000E0070001C00E0003800E0007000E000E0000000E0000001C000000380000007
+800000078000000F0000000F0000001F0000001F0000003F0000003E0000003E0000007E000000
+7E0000007E0000007E000000FE000000FE000000FE000000FE000000FE000000FE000000FE0000
+00FE0000007C0000003800001C297CA822>I<003FC00001FFF00003FFFC0007C07E000F003F00
+1E001F001E000F803E000F803E000F803F000F803F000F803FC00F003FF01F001FFC1E001FFE3C
+000FFFF80007FFE00003FFF80001FFFC0001FFFE0007FFFF000F0FFF801E03FFC03C01FFC07C00
+7FE078001FE0F80007E0F80007E0F80003E0F80003E0F80003E0F80003C07C0003C07C0007803F
+000F001FC03E000FFFFC0003FFF800007FC0001B277DA622>I<007F800001FFF00007FFF8000F
+E0FC001F807E003F803F007F003F007F001F80FF001F80FF001FC0FF001FC0FF001FC0FF001FE0
+FF001FE0FF001FE0FF001FE07F001FE07F003FE03F003FE01F807FE00F807FE007C1DFE003FF9F
+E0007E1FE000001FE000001FC000001FC000001FC000003F801F003F803F803F003F803F003F80
+7E003F807C001F01F8001E03F0000FFFE00007FF800001FE00001B277DA622>I<01FF000FFFE0
+1E03F03801F87801FCFC01FEFE01FEFE01FEFE01FE7C01FE3801FC0003F80007F00007C0000F80
+001F00001E00003C00003800003800007800007000007000007000007000007000007000000000
+00000000000000000000000000000000700000F80001FC0003FE0003FE0003FE0001FC0000F800
+007000172A7CA920>63 D<000003800000000007C00000000007C0000000000FE0000000000FE0
+000000000FE0000000001FF0000000001FF0000000003FF8000000003FF8000000003FF8000000
+0073FC0000000073FC00000000F3FE00000000E1FE00000000E1FE00000001C0FF00000001C0FF
+00000003C0FF80000003807F80000007807FC0000007003FC0000007003FC000000E003FE00000
+0E001FE000001E001FF000001C000FF000001FFFFFF000003FFFFFF800003FFFFFF80000780007
+FC0000700003FC0000700003FC0000E00001FE0000E00001FE0001E00001FF0001C00000FF0001
+C00000FF00FFFE001FFFFEFFFE001FFFFEFFFE001FFFFE2F297EA834>65
+D<00003FF001800003FFFE0380000FFFFF8780003FF007DF8000FF8001FF8001FE00007F8003FC
+00003F8007F000001F800FF000000F801FE0000007801FE0000007803FC0000007803FC0000003
+807FC0000003807F80000003807F8000000000FF8000000000FF8000000000FF8000000000FF80
+00000000FF8000000000FF8000000000FF8000000000FF8000000000FF80000000007F80000000
+007F80000000007FC0000003803FC0000003803FC0000003801FE0000003801FE0000007000FF0
+0000070007F000000E0003FC00001E0001FE00003C0000FF8000F800003FF007E000000FFFFFC0
+000003FFFF000000003FF8000029297CA832>67 D<FFFFFFF80000FFFFFFFF8000FFFFFFFFE000
+03FC001FF80003FC0007FC0003FC0001FE0003FC0000FF0003FC00007F8003FC00003FC003FC00
+001FC003FC00001FE003FC00001FE003FC00000FF003FC00000FF003FC00000FF003FC00000FF0
+03FC00000FF803FC00000FF803FC00000FF803FC00000FF803FC00000FF803FC00000FF803FC00
+000FF803FC00000FF803FC00000FF803FC00000FF803FC00000FF003FC00000FF003FC00000FF0
+03FC00001FE003FC00001FE003FC00001FC003FC00003FC003FC00007F8003FC00007F0003FC00
+01FE0003FC0003FC0003FC001FF800FFFFFFFFE000FFFFFFFF8000FFFFFFFC00002D297DA835>
+I<FFFFFFFFE0FFFFFFFFE0FFFFFFFFE003FC001FE003FC0007F003FC0001F003FC0001F003FC00
+00F003FC00007003FC00007003FC00007003FC01C07803FC01C03803FC01C03803FC01C03803FC
+03C00003FC03C00003FC0FC00003FFFFC00003FFFFC00003FFFFC00003FC0FC00003FC03C00003
+FC03C00003FC01C00E03FC01C00E03FC01C00E03FC01C01C03FC00001C03FC00001C03FC00001C
+03FC00003C03FC00003803FC00007803FC0000F803FC0001F803FC0003F803FC001FF8FFFFFFFF
+F0FFFFFFFFF0FFFFFFFFF027297DA82D>I<FFFFFFFFC0FFFFFFFFC0FFFFFFFFC003FC003FC003
+FC000FE003FC0003E003FC0001E003FC0001E003FC0000E003FC0000E003FC0000E003FC0000F0
+03FC03807003FC03807003FC03807003FC03800003FC07800003FC07800003FC1F800003FFFF80
+0003FFFF800003FFFF800003FC1F800003FC07800003FC07800003FC03800003FC03800003FC03
+800003FC03800003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC
+00000003FC00000003FC000000FFFFFC0000FFFFFC0000FFFFFC000024297DA82B>I<FFFFF01F
+FFFEFFFFF01FFFFEFFFFF01FFFFE03FC00007F8003FC00007F8003FC00007F8003FC00007F8003
+FC00007F8003FC00007F8003FC00007F8003FC00007F8003FC00007F8003FC00007F8003FC0000
+7F8003FC00007F8003FC00007F8003FC00007F8003FC00007F8003FFFFFFFF8003FFFFFFFF8003
+FFFFFFFF8003FC00007F8003FC00007F8003FC00007F8003FC00007F8003FC00007F8003FC0000
+7F8003FC00007F8003FC00007F8003FC00007F8003FC00007F8003FC00007F8003FC00007F8003
+FC00007F8003FC00007F8003FC00007F8003FC00007F8003FC00007F80FFFFF01FFFFEFFFFF01F
+FFFEFFFFF01FFFFE2F297DA836>72 D<FFFFFCFFFFFCFFFFFC01FE0001FE0001FE0001FE0001FE
+0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE
+0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE
+0001FE0001FE0001FE0001FE00FFFFFCFFFFFCFFFFFC16297EA81A>I<FFFFFC0000FFFFFC0000
+FFFFFC000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC0000
+0003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00
+000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC0001C003FC
+0001C003FC0001C003FC0001C003FC0003C003FC00038003FC00038003FC00078003FC00078003
+FC000F8003FC000F8003FC001F8003FC007F8003FC01FF00FFFFFFFF00FFFFFFFF00FFFFFFFF00
+22297DA829>76 D<FFFE0000001FFFC0FFFE0000001FFFC0FFFF0000003FFFC003FF0000003FF0
+0003FF0000003FF00003BF80000077F00003BF80000077F000039FC00000E7F000039FC00000E7
+F000038FE00001C7F000038FE00001C7F0000387F0000387F0000387F0000387F0000387F00003
+87F0000383F8000707F0000383F8000707F0000381FC000E07F0000381FC000E07F0000380FE00
+1C07F0000380FE001C07F0000380FF003807F00003807F003807F00003807F003807F00003803F
+807007F00003803F807007F00003801FC0E007F00003801FC0E007F00003800FE1C007F0000380
+0FE1C007F00003800FE1C007F000038007F38007F000038007F38007F000038003FF0007F00003
+8003FF0007F000038001FE0007F000038001FE0007F000038000FC0007F000038000FC0007F000
+FFFE00FC01FFFFC0FFFE007801FFFFC0FFFE007801FFFFC03A297DA841>I<FFFC0000FFFEFFFE
+0000FFFEFFFF0000FFFE03FF8000038003FF8000038003BFC0000380039FE0000380039FF00003
+80038FF80003800387F80003800383FC0003800381FE0003800381FF0003800380FF8003800380
+7FC0038003803FC0038003801FE0038003800FF0038003800FF80380038007FC0380038003FC03
+80038001FE0380038000FF0380038000FF83800380007FC3800380003FE3800380001FE3800380
+000FF38003800007FB8003800007FF8003800003FF8003800001FF8003800000FF80038000007F
+80038000007F80038000003F80038000001F80038000000F80FFFE00000780FFFE00000380FFFE
+000003802F297DA836>I<0000FFE000000007FFFC0000003FC07F8000007F001FC00001FC0007
+F00003F80003F80007F00001FC000FF00001FE001FE00000FF001FE00000FF003FC000007F803F
+C000007F807FC000007FC07F8000003FC07F8000003FC07F8000003FC0FF8000003FE0FF800000
+3FE0FF8000003FE0FF8000003FE0FF8000003FE0FF8000003FE0FF8000003FE0FF8000003FE0FF
+8000003FE0FF8000003FE07F8000003FC07FC000007FC07FC000007FC03FC000007F803FC00000
+7F801FE00000FF001FE00000FF000FF00001FE0007F00001FC0003F80003F80001FC0007F00000
+FF001FE000003FC07F8000000FFFFE00000000FFE000002B297CA834>I<FFFFFFF800FFFFFFFF
+00FFFFFFFFC003FC003FE003FC000FF003FC0007F803FC0007FC03FC0003FC03FC0003FE03FC00
+03FE03FC0003FE03FC0003FE03FC0003FE03FC0003FE03FC0003FE03FC0003FC03FC0007FC03FC
+0007F803FC000FF003FC003FE003FFFFFF8003FFFFFE0003FC00000003FC00000003FC00000003
+FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC000000
+03FC00000003FC00000003FC00000003FC00000003FC000000FFFFF00000FFFFF00000FFFFF000
+0027297DA82F>I<0000FFE000000007FFFC0000003FC07F8000007F001FC00001FC0007F00003
+F80003F80007F00001FC000FF00001FE001FE00000FF001FE00000FF003FC000007F803FC00000
+7F807FC000007FC07FC000007FC07F8000003FC07F8000003FC0FF8000003FE0FF8000003FE0FF
+8000003FE0FF8000003FE0FF8000003FE0FF8000003FE0FF8000003FE0FF8000003FE0FF800000
+3FE0FF8000003FE07F8000003FC07F8000003FC07FC000007FC03FC000007F803FC000007F801F
+E00000FF001FE01F00FF000FF03F81FE0007F060C1FC0003F8C063F80001FCC077F00000FFC07F
+E000003FE07F8000000FFFFE00000000FFFE00600000003E00600000003F00600000001F81E000
+00001FFFE00000001FFFC00000000FFFC00000000FFFC000000007FF8000000007FF8000000003
+FF0000000001FE000000000078002B357CA834>I<FFFFFFE00000FFFFFFFE0000FFFFFFFF8000
+03FC007FE00003FC000FF00003FC0007F80003FC0007FC0003FC0003FC0003FC0003FE0003FC00
+03FE0003FC0003FE0003FC0003FE0003FC0003FE0003FC0003FE0003FC0003FC0003FC0007F800
+03FC0007F80003FC001FE00003FC007FC00003FFFFFE000003FFFFF0000003FC00FC000003FC00
+7F000003FC003F800003FC003F800003FC001FC00003FC001FE00003FC001FE00003FC001FE000
+03FC001FE00003FC001FE00003FC001FF00003FC001FF00003FC001FF00003FC001FF00703FC00
+1FF80703FC000FF80703FC0007F80EFFFFF003FE1CFFFFF001FFF8FFFFF0003FF030297DA834>
+I<007F806003FFF0E007FFF9E00F807FE01F001FE03E0007E07C0003E07C0001E0FC0001E0FC00
+01E0FC0000E0FE0000E0FE0000E0FF000000FFC000007FFE00007FFFE0003FFFFC001FFFFE000F
+FFFF8007FFFFC003FFFFE000FFFFE00007FFF000007FF000000FF8000007F8000003F8600001F8
+E00001F8E00001F8E00001F8F00001F0F00001F0F80003F0FC0003E0FF0007C0FFE01F80F3FFFF
+00E0FFFE00C01FF0001D297CA826>I<7FFFFFFFFFC07FFFFFFFFFC07FFFFFFFFFC07F803FC03F
+C07E003FC007C078003FC003C078003FC003C070003FC001C0F0003FC001E0F0003FC001E0E000
+3FC000E0E0003FC000E0E0003FC000E0E0003FC000E0E0003FC000E000003FC0000000003FC000
+0000003FC0000000003FC0000000003FC0000000003FC0000000003FC0000000003FC000000000
+3FC0000000003FC0000000003FC0000000003FC0000000003FC0000000003FC0000000003FC000
+0000003FC0000000003FC0000000003FC0000000003FC0000000003FC0000000003FC000000000
+3FC00000007FFFFFE000007FFFFFE000007FFFFFE0002B287EA730>I<FFFFF001FFFCFFFFF001
+FFFCFFFFF001FFFC03FC0000070003FC0000070003FC0000070003FC0000070003FC0000070003
+FC0000070003FC0000070003FC0000070003FC0000070003FC0000070003FC0000070003FC0000
+070003FC0000070003FC0000070003FC0000070003FC0000070003FC0000070003FC0000070003
+FC0000070003FC0000070003FC0000070003FC0000070003FC0000070003FC0000070003FC0000
+070003FC0000070003FC0000070003FC0000070001FC00000E0001FE00000E0000FE00001C0000
+7E00001C00007F00003800003FC000F000000FF007E0000007FFFFC0000001FFFF000000001FF8
+00002E297DA835>I<FFFFF0003FFF80FFFFF0003FFF80FFFFF0003FFF8003FE000001E00001FE
+000001C00001FF000003C00000FF000003800000FF0000038000007F8000070000007F80000700
+00007FC0000F0000003FC0000E0000003FE0001E0000001FE0001C0000001FF0001C0000000FF0
+00380000000FF0003800000007F8007000000007F8007000000007FC00F000000003FC00E00000
+0003FE01E000000001FE01C000000001FF01C000000000FF038000000000FF038000000000FF87
+80000000007F8700000000007FCF00000000003FCE00000000003FFE00000000001FFC00000000
+001FFC00000000000FF800000000000FF800000000000FF8000000000007F0000000000007F000
+0000000003E0000000000003E0000000000001C000000031297FA834>I<FFFFE07FFFF007FFF0
+FFFFE07FFFF007FFF0FFFFE07FFFF007FFF003FC0001FE00001C0003FC0001FE00001C0001FE00
+01FF0000380001FE0000FF0000380001FF0000FF0000780000FF0000FF8000700000FF0000FF80
+00700000FF8000FF8000F000007F8001FFC000E000007F8001FFC000E000003FC003FFE001C000
+003FC0039FE001C000003FE0039FE003C000001FE0070FF0038000001FE0070FF0038000001FF0
+0F0FF0078000000FF00E07F8070000000FF00E07F80700000007F81E07FC0E00000007F81C03FC
+0E00000007FC1C03FC1E00000003FC3801FE1C00000003FC3801FE1C00000001FE7801FF380000
+0001FE7000FF3800000001FE7000FF3800000000FFF000FFF000000000FFE0007FF000000000FF
+E0007FF0000000007FC0003FE0000000007FC0003FE0000000003FC0003FC0000000003F80001F
+C0000000003F80001FC0000000001F80001F80000000001F00000F80000000001F00000F800000
+00000E00000700000044297FA847>I<01FF800007FFF0000F81F8001FC07E001FC07E001FC03F
+000F803F8007003F8000003F8000003F8000003F80000FFF8000FFFF8007FC3F800FE03F803F80
+3F803F003F807F003F80FE003F80FE003F80FE003F80FE003F807E007F807F00DF803F839FFC0F
+FF0FFC01FC03FC1E1B7E9A21>97 D<FFE0000000FFE0000000FFE00000000FE00000000FE00000
+000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE000
+00000FE00000000FE00000000FE1FE00000FE7FF80000FFE07E0000FF801F0000FF000F8000FE0
+00FC000FE000FE000FE0007F000FE0007F000FE0007F000FE0007F800FE0007F800FE0007F800F
+E0007F800FE0007F800FE0007F800FE0007F800FE0007F000FE0007F000FE0007F000FE000FE00
+0FE000FC000FF001F8000FF803F0000F9E07E0000F07FF80000E01FC0000212A7EA926>I<001F
+F80000FFFE0003F01F0007E03F800FC03F801F803F803F801F007F800E007F0000007F000000FF
+000000FF000000FF000000FF000000FF000000FF000000FF0000007F0000007F0000007F800000
+3F8001C01F8001C00FC0038007E0070003F01E0000FFFC00001FE0001A1B7E9A1F>I<00003FF8
+0000003FF80000003FF800000003F800000003F800000003F800000003F800000003F800000003
+F800000003F800000003F800000003F800000003F800000003F800000003F800001FE3F80000FF
+FBF80003F03FF80007E00FF8000FC007F8001F8003F8003F8003F8007F0003F8007F0003F8007F
+0003F800FF0003F800FF0003F800FF0003F800FF0003F800FF0003F800FF0003F800FF0003F800
+7F0003F8007F0003F8007F0003F8003F8003F8001F8003F8000F8007F80007C00FF80003F03BFF
+8000FFF3FF80003FC3FF80212A7EA926>I<003FE00001FFF80003F07E0007C01F000F801F801F
+800F803F800FC07F000FC07F0007C07F0007E0FF0007E0FF0007E0FFFFFFE0FFFFFFE0FF000000
+FF000000FF0000007F0000007F0000007F0000003F8000E01F8000E00FC001C007E0038003F81F
+0000FFFE00001FF0001B1B7E9A20>I<0007F0003FFC00FE3E01F87F03F87F03F07F07F07F07F0
+3E07F00007F00007F00007F00007F00007F00007F000FFFFC0FFFFC0FFFFC007F00007F00007F0
+0007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F0
+0007F00007F00007F00007F00007F0007FFF807FFF807FFF80182A7EA915>I<00FF81F003FFE7
+F80FC1FE7C1F80FC7C1F007C383F007E107F007F007F007F007F007F007F007F007F007F007F00
+7F003F007E001F007C001F80FC000FC1F8001FFFE00018FF800038000000380000003C0000003E
+0000003FFFF8001FFFFF001FFFFF800FFFFFC007FFFFE01FFFFFF03E0007F07C0001F8F80000F8
+F80000F8F80000F8F80000F87C0001F03C0001E01F0007C00FC01F8003FFFE00007FF0001E287E
+9A22>I<FFE0000000FFE0000000FFE00000000FE00000000FE00000000FE00000000FE0000000
+0FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000
+000FE07F00000FE1FFC0000FE787E0000FEE03F0000FF803F0000FF803F8000FF003F8000FF003
+F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE0
+03F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000F
+E003F800FFFE3FFF80FFFE3FFF80FFFE3FFF80212A7DA926>I<07000F801FC03FE03FE03FE01F
+C00F8007000000000000000000000000000000FFE0FFE0FFE00FE00FE00FE00FE00FE00FE00FE0
+0FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE0FFFEFFFEFFFE0F2B7DAA14
+>I<FFE00000FFE00000FFE000000FE000000FE000000FE000000FE000000FE000000FE000000F
+E000000FE000000FE000000FE000000FE000000FE000000FE01FFC0FE01FFC0FE01FFC0FE00780
+0FE00F000FE01E000FE03C000FE078000FE0E0000FE3C0000FE7C0000FEFE0000FFFE0000FFFF0
+000FF3F8000FE3F8000FC1FC000FC0FE000FC07F000FC07F000FC03F800FC01FC00FC00FC00FC0
+0FE0FFFC3FFEFFFC3FFEFFFC3FFE1F2A7EA924>107 D<FFE0FFE0FFE00FE00FE00FE00FE00FE0
+0FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00F
+E00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE0FFFEFFFEFFFE0F2A7DA914>I<FFC07F
+800FF000FFC1FFE03FFC00FFC383F0707E000FC603F8C07F000FCC01F9803F000FD801FF003F80
+0FF001FE003F800FF001FE003F800FE001FC003F800FE001FC003F800FE001FC003F800FE001FC
+003F800FE001FC003F800FE001FC003F800FE001FC003F800FE001FC003F800FE001FC003F800F
+E001FC003F800FE001FC003F800FE001FC003F800FE001FC003F800FE001FC003F800FE001FC00
+3F800FE001FC003F80FFFE1FFFC3FFF8FFFE1FFFC3FFF8FFFE1FFFC3FFF8351B7D9A3A>I<FFC0
+7F0000FFC1FFC000FFC787E0000FCE03F0000FD803F0000FD803F8000FF003F8000FF003F8000F
+E003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F800
+0FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8
+00FFFE3FFF80FFFE3FFF80FFFE3FFF80211B7D9A26>I<003FE00001FFFC0003F07E000FC01F80
+1F800FC03F800FE03F0007E07F0007F07F0007F07F0007F0FF0007F8FF0007F8FF0007F8FF0007
+F8FF0007F8FF0007F8FF0007F8FF0007F87F0007F07F0007F03F800FE03F800FE01F800FC00FC0
+1F8007F07F0001FFFC00003FE0001D1B7E9A22>I<FFE1FE0000FFE7FF8000FFFE07E0000FF803
+F0000FF001F8000FE000FC000FE000FE000FE000FF000FE0007F000FE0007F000FE0007F800FE0
+007F800FE0007F800FE0007F800FE0007F800FE0007F800FE0007F800FE0007F000FE000FF000F
+E000FF000FE000FE000FE001FC000FF001F8000FF803F0000FFE0FE0000FE7FF80000FE1FC0000
+0FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000
+000FE0000000FFFE000000FFFE000000FFFE00000021277E9A26>I<FFC1F0FFC7FCFFCE3E0FD8
+7F0FD87F0FF07F0FF03E0FF01C0FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0
+000FE0000FE0000FE0000FE0000FE0000FE0000FE000FFFF00FFFF00FFFF00181B7E9A1C>114
+D<03FE300FFFF01E03F03800F0700070F00070F00070F80070FC0000FFE0007FFE007FFF803FFF
+E01FFFF007FFF800FFF80003FC0000FC60007CE0003CF0003CF00038F80038FC0070FF01E0F7FF
+C0C1FF00161B7E9A1B>I<00700000700000700000700000F00000F00000F00001F00003F00003
+F00007F0001FFFF0FFFFF0FFFFF007F00007F00007F00007F00007F00007F00007F00007F00007
+F00007F00007F00007F00007F00007F03807F03807F03807F03807F03807F03803F03803F87001
+F86000FFC0001F8015267FA51B>I<FFE03FF800FFE03FF800FFE03FF8000FE003F8000FE003F8
+000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003
+F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE003F8000FE0
+03F8000FE007F80007E007F80007E00FF80003F03BFF8001FFF3FF80003FC3FF80211B7D9A26>
+I<FFFE03FF80FFFE03FF80FFFE03FF8007F000700007F000700007F800F00003F800E00003FC01
+E00001FC01C00001FC01C00000FE03800000FE038000007F070000007F070000007F8F0000003F
+8E0000003FDE0000001FDC0000001FDC0000000FF80000000FF80000000FF800000007F0000000
+07F000000003E000000003E000000001C00000211B7F9A24>I<FFFE7FFC0FFEFFFE7FFC0FFEFF
+FE7FFC0FFE0FE007E000E007F003F001C007F003F001C007F807F803C003F807F8038003F807F8
+038001FC0EFC070001FC0EFC070001FE1EFC0F0000FE1C7E0E0000FE1C7E0E0000FF383F1E0000
+7F383F1C00007F783F3C00003FF01FB800003FF01FB800003FF01FF800001FE00FF000001FE00F
+F000000FC007E000000FC007E000000FC007E00000078003C00000078003C0002F1B7F9A32>I<
+FFFC0FFF00FFFC0FFF00FFFC0FFF0007F003C00003F807800001FC07800000FE0F000000FF1E00
+00007F3C0000003FF80000001FF00000000FF00000000FF000000007F000000007F80000000FFC
+0000001FFE0000001EFE0000003C7F000000783F800000F01FC00001E01FE00001C00FE00003C0
+07F000FFF01FFF80FFF01FFF80FFF01FFF80211B7F9A24>I<FFFE03FF80FFFE03FF80FFFE03FF
+8007F000700007F000700007F800F00003F800E00003FC01E00001FC01C00001FC01C00000FE03
+800000FE038000007F070000007F070000007F8F0000003F8E0000003FDE0000001FDC0000001F
+DC0000000FF80000000FF80000000FF800000007F000000007F000000003E000000003E0000000
+01C000000001C000000003800000000380000038078000007C07000000FE0F000000FE0E000000
+FE1E000000FE3C0000007C780000003FE00000000FC000000021277F9A24>I
+E /Fj 18 121 df<00001E000000003E00000000FE00000003FE0000003FFE0000FFFFFE0000FF
+FFFE0000FFFFFE0000FFCFFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000
+000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE00
+00000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE
+0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000F
+FE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE000000
+0FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE00007FFFFFFFC0
+7FFFFFFFC07FFFFFFFC07FFFFFFFC0223879B731>49 D<0007FE0000007FFFE00001FFFFF80003
+FFFFFE0007F01FFF000F8007FF801F0001FFC03E0000FFE07F8000FFF07FC0007FF0FFE0007FF8
+FFF0003FF8FFF0003FFCFFF0003FFCFFF0003FFCFFF0003FFC7FE0003FFC3FC0003FFC1F80003F
+FC0000003FFC0000003FF80000007FF80000007FF00000007FF0000000FFE0000000FFC0000001
+FF80000001FF00000003FE00000007FC00000007F80000000FF00000001FC00000003F80000000
+7F00000000FC00000001F800000001F0003C0003E0003C0007C0003C000F000078001E00007800
+3C00007800780000F800F00000F801FFFFFFF803FFFFFFF007FFFFFFF00FFFFFFFF01FFFFFFFF0
+3FFFFFFFF07FFFFFFFF0FFFFFFFFF0FFFFFFFFE0FFFFFFFFE0FFFFFFFFE026387BB731>I<0003
+FF8000001FFFF000007FFFFE0000FE03FF0001F000FF8003C000FFC00780007FE00FF0007FF00F
+F8007FF01FFC007FF81FFE007FF81FFE007FF81FFE007FF81FFE007FF81FFE007FF80FFC007FF0
+07F8007FF003F0007FF0000000FFE0000000FFC0000001FF80000001FF00000003FE00000007FC
+0000001FF000000FFFC000000FFF8000000FFFF800000003FE00000000FF800000007FE0000000
+3FF00000003FF80000003FFC0000001FFC0000001FFE0000001FFE0200001FFF1FC0001FFF3FE0
+001FFF7FF0001FFF7FF0001FFFFFF8001FFFFFF8001FFFFFF8001FFEFFF8001FFEFFF0001FFE7F
+F0003FFC7FE0003FFC3FC0003FF81F80007FF01FE000FFE007FC03FFC003FFFFFF0001FFFFFE00
+003FFFF0000007FF800028397CB731>I<00000007C0000000000FC0000000000FC0000000001F
+C0000000003FC0000000007FC000000000FFC000000000FFC000000001FFC000000003FFC00000
+0007FFC00000000FFFC00000000FFFC00000001EFFC00000003CFFC00000007CFFC0000000F8FF
+C0000000F0FFC0000001E0FFC0000003C0FFC0000007C0FFC000000F80FFC000000F00FFC00000
+1E00FFC000003C00FFC000007C00FFC00000F800FFC00000F000FFC00001E000FFC00003C000FF
+C00007C000FFC0000F8000FFC0000F0000FFC0001E0000FFC0003C0000FFC0007C0000FFC000F8
+0000FFC000FFFFFFFFFFC0FFFFFFFFFFC0FFFFFFFFFFC0FFFFFFFFFFC0000001FFC000000001FF
+C000000001FFC000000001FFC000000001FFC000000001FFC000000001FFC000000001FFC00000
+0001FFC000000001FFC0000007FFFFFFC00007FFFFFFC00007FFFFFFC00007FFFFFFC02A377DB6
+31>I<04000000C00F800007C00FF8007FC00FFFFFFF800FFFFFFF000FFFFFFE000FFFFFFC000F
+FFFFF8000FFFFFF0000FFFFFE0000FFFFF80000FFFFE00000FFFF800000F800000000F80000000
+0F800000000F800000000F800000000F800000000F800000000F800000000F81FF00000F8FFFE0
+000FBFFFF8000FFE03FE000FF000FF000FC000FF800F80007FC00F00007FE00700007FF0000000
+3FF00000003FF80000003FF80000003FF80000003FFC0000003FFC0600003FFC1F80003FFC3FC0
+003FFC7FE0003FFCFFE0003FFCFFF0003FFCFFF0003FFCFFF0003FF8FFE0003FF8FFE0003FF87F
+C0007FF07F00007FF03C00007FE03E0000FFC01F0000FF800FC003FF0007F00FFE0003FFFFFC00
+01FFFFF000007FFFC000000FFC000026397BB731>I<00000001F80000000000000001F8000000
+0000000003FC0000000000000003FC0000000000000007FE0000000000000007FE000000000000
+0007FE000000000000000FFF000000000000000FFF000000000000001FFF800000000000001FFF
+800000000000001FFF800000000000003FFFC00000000000003FFFC00000000000007FFFE00000
+000000007DFFE00000000000007DFFE0000000000000FDFFF0000000000000F8FFF00000000000
+01F8FFF8000000000001F07FF8000000000001F07FF8000000000003F07FFC000000000003E03F
+FC000000000007E03FFE000000000007C01FFE00000000000FC01FFF00000000000F801FFF0000
+0000000F800FFF00000000001F800FFF80000000001F0007FF80000000003F0007FFC000000000
+3E0003FFC0000000003E0003FFC0000000007E0003FFE0000000007C0001FFE000000000FC0001
+FFF000000000F80000FFF000000000F80000FFF000000001FFFFFFFFF800000001FFFFFFFFF800
+000003FFFFFFFFFC00000003FFFFFFFFFC00000003E000003FFC00000007E000003FFE00000007
+C000001FFE0000000FC000001FFF0000000F8000000FFF0000001F8000000FFF8000001F000000
+0FFF8000001F00000007FF8000003F00000007FFC000003E00000003FFC000007E00000003FFE0
+0000FF00000001FFE000FFFFFC0001FFFFFFF0FFFFFC0001FFFFFFF0FFFFFC0001FFFFFFF0FFFF
+FC0001FFFFFFF0443B7DBA4B>65 D<FFFFFFFFFFC00000FFFFFFFFFFFC0000FFFFFFFFFFFF0000
+FFFFFFFFFFFFC000007FF00001FFF000007FF000007FF800007FF000003FFC00007FF000001FFE
+00007FF000001FFE00007FF000000FFF00007FF000000FFF00007FF0000007FF80007FF0000007
+FF80007FF0000007FF80007FF0000007FF80007FF0000007FF80007FF0000007FF80007FF00000
+07FF80007FF0000007FF00007FF000000FFF00007FF000000FFF00007FF000001FFE00007FF000
+001FFC00007FF000003FF800007FF000007FF000007FF00001FFE000007FF0000FFF8000007FFF
+FFFFFE0000007FFFFFFFFE0000007FFFFFFFFFC000007FF000007FF000007FF000001FFC00007F
+F000000FFE00007FF0000007FF00007FF0000007FF80007FF0000003FFC0007FF0000003FFC000
+7FF0000001FFE0007FF0000001FFE0007FF0000001FFF0007FF0000001FFF0007FF0000001FFF0
+007FF0000001FFF0007FF0000001FFF0007FF0000001FFF0007FF0000001FFF0007FF0000001FF
+F0007FF0000001FFE0007FF0000003FFE0007FF0000003FFC0007FF0000007FFC0007FF000000F
+FF80007FF000001FFF00007FF000003FFE00007FF00001FFFC00FFFFFFFFFFFFF800FFFFFFFFFF
+FFE000FFFFFFFFFFFF8000FFFFFFFFFFF800003C3B7CBA46>I<0000001FFF000030000001FFFF
+E000F000000FFFFFFC01F000007FFFFFFE03F00001FFFE007F87F00003FFE0000FCFF0000FFF00
+0003FFF0001FFC000001FFF0003FF80000007FF0007FF00000003FF000FFC00000003FF001FFC0
+0000001FF003FF800000000FF007FF000000000FF00FFF0000000007F00FFE0000000007F01FFE
+0000000003F01FFE0000000003F03FFC0000000003F03FFC0000000001F03FFC0000000001F07F
+FC0000000001F07FF80000000001F07FF80000000000007FF8000000000000FFF8000000000000
+FFF8000000000000FFF8000000000000FFF8000000000000FFF8000000000000FFF80000000000
+00FFF8000000000000FFF8000000000000FFF8000000000000FFF8000000000000FFF800000000
+00007FF80000000000007FF80000000000007FF80000000000007FFC0000000000F03FFC000000
+0000F03FFC0000000000F03FFC0000000000F01FFE0000000000F01FFE0000000001E00FFE0000
+000001E00FFF0000000001E007FF0000000003C003FF8000000003C001FFC0000000078000FFE0
+0000000F00007FF00000001F00003FF80000003E00001FFC0000007C00000FFF000001F8000003
+FFE00007F0000001FFFE003FC00000007FFFFFFF000000000FFFFFFC0000000001FFFFF0000000
+00001FFF0000003C3D7BBB47>I<001FFF00000001FFFFF0000003FFFFFC000007F007FE00000F
+F801FF00001FFC00FF80001FFC007FC0001FFC007FE0001FFC003FE0000FF8003FF0000FF8003F
+F00007F0003FF00001C0003FF0000000003FF0000000003FF0000000003FF0000000FFFFF00000
+0FFFFFF000007FF83FF00001FF803FF00007FE003FF0000FF8003FF0001FF0003FF0003FE0003F
+F0007FE0003FF0007FE0003FF000FFC0003FF000FFC0003FF000FFC0003FF000FFC0003FF000FF
+C0007FF0007FE0007FF0007FE000DFF0003FF0039FF8001FFC0F0FFFF007FFFE0FFFF001FFFC07
+FFF0003FE000FFF02C267DA530>97 D<000000003FC00000003FFFC00000003FFFC00000003FFF
+C00000003FFFC000000001FFC000000000FFC000000000FFC000000000FFC000000000FFC00000
+0000FFC000000000FFC000000000FFC000000000FFC000000000FFC000000000FFC000000000FF
+C000000000FFC000000000FFC000000000FFC000000000FFC000000000FFC00000FFC0FFC0000F
+FFF8FFC0003FFFFEFFC000FFE03FFFC001FF000FFFC003FE0003FFC007FC0001FFC00FF80000FF
+C01FF00000FFC01FF00000FFC03FF00000FFC03FE00000FFC07FE00000FFC07FE00000FFC07FE0
+0000FFC0FFE00000FFC0FFE00000FFC0FFE00000FFC0FFE00000FFC0FFE00000FFC0FFE00000FF
+C0FFE00000FFC0FFE00000FFC0FFE00000FFC07FE00000FFC07FE00000FFC07FE00000FFC03FF0
+0000FFC03FF00000FFC01FF00000FFC00FF80001FFC007F80003FFC003FC0007FFC001FE000FFF
+E000FFC07EFFFF003FFFFCFFFF000FFFF0FFFF0001FF80FFFF303C7DBB37>100
+D<0001FFC000000FFFF800003FFFFE0000FF80FF0001FE003F8007FC001FC00FF8000FE00FF800
+0FF01FF00007F03FF00007F83FF00007F87FE00007F87FE00003FC7FE00003FC7FE00003FCFFE0
+0003FCFFFFFFFFFCFFFFFFFFFCFFFFFFFFFCFFE0000000FFE0000000FFE0000000FFE00000007F
+E00000007FE00000007FE00000003FE00000003FF000003C1FF000003C1FF000003C0FF8000078
+07FC0000F803FE0001F001FF0007E000FFC03FC0003FFFFF000007FFFC000000FFE00026267DA5
+2D>I<00FF00000000FFFF00000000FFFF00000000FFFF00000000FFFF0000000007FF00000000
+03FF0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF00
+00000003FF0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF00000000
+03FF0000000003FF0000000003FF0000000003FF007FC00003FF01FFF80003FF07FFFC0003FF0F
+03FE0003FF1C01FF0003FF3001FF8003FF6000FF8003FFE000FFC003FFC000FFC003FF8000FFC0
+03FF8000FFC003FF8000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF00
+00FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC0
+03FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF00
+00FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC0FFFFFC3FFFFFFFFFFC3FFFFF
+FFFFFC3FFFFFFFFFFC3FFFFF303C7CBB37>104 D<01F00007FC000FFE000FFE001FFF001FFF00
+1FFF001FFF001FFF000FFE000FFE0007FC0001F000000000000000000000000000000000000000
+00000000000000000000000000FF00FFFF00FFFF00FFFF00FFFF0007FF0003FF0003FF0003FF00
+03FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF00
+03FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF00FFFFF8
+FFFFF8FFFFF8FFFFF8153D7DBC1B>I<00FE007FC000FFFE01FFF800FFFE07FFFC00FFFE0F03FE
+00FFFE1C01FF0007FE3001FF8003FE6000FF8003FEE000FFC003FEC000FFC003FF8000FFC003FF
+8000FFC003FF8000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FF
+C003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF
+0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FF
+C003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC0FFFFFC3FFFFFFFFFFC3FFFFFFFFF
+FC3FFFFFFFFFFC3FFFFF30267CA537>110 D<00FF01FF8000FFFF0FFFF000FFFF3FFFFC00FFFF
+FE03FF00FFFFF000FF8003FFC0007FC003FF80003FE003FF00003FF003FF00001FF803FF00001F
+FC03FF00000FFC03FF00000FFE03FF00000FFE03FF000007FE03FF000007FF03FF000007FF03FF
+000007FF03FF000007FF03FF000007FF03FF000007FF03FF000007FF03FF000007FF03FF000007
+FF03FF000007FE03FF000007FE03FF00000FFE03FF00000FFC03FF00000FFC03FF00001FF803FF
+00001FF803FF00003FF003FF80003FE003FFC0007FC003FFF001FF8003FFFC07FF0003FF3FFFFC
+0003FF0FFFF00003FF01FF000003FF0000000003FF0000000003FF0000000003FF0000000003FF
+0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF000000
+0003FF0000000003FF00000000FFFFFC000000FFFFFC000000FFFFFC000000FFFFFC0000003037
+7DA537>112 D<00FE03F000FFFE0FFE00FFFE1FFF00FFFE3C3F80FFFE707FC007FE60FFE003FE
+E0FFE003FEC0FFE003FFC0FFE003FF807FC003FF807FC003FF803F8003FF800E0003FF00000003
+FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF000000
+03FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF0000
+0003FF00000003FF00000003FF00000003FF000000FFFFFE0000FFFFFE0000FFFFFE0000FFFFFE
+000023267DA529>114 D<0007800000078000000780000007800000078000000F8000000F8000
+000F8000000F8000001F8000001F8000003F8000003F8000007F800000FF800001FF800007FF80
+001FFFFFF0FFFFFFF0FFFFFFF0FFFFFFF001FF800001FF800001FF800001FF800001FF800001FF
+800001FF800001FF800001FF800001FF800001FF800001FF800001FF800001FF800001FF800001
+FF800001FF800001FF800001FF800001FF803C01FF803C01FF803C01FF803C01FF803C01FF803C
+01FF803C01FF803C00FF807800FFC078007FC070003FE0E0001FFFC00007FF800001FF001E377E
+B626>116 D<FFFFF007FFFCFFFFF007FFFCFFFFF007FFFCFFFFF007FFFC01FF8000FC0000FFC0
+00F80000FFE001F000007FF003E000003FF007C000001FF80FC000000FFC1F8000000FFE1F0000
+0007FF3E00000003FFFC00000001FFF800000000FFF0000000007FE0000000007FF0000000003F
+F8000000001FF8000000001FFC000000003FFE000000007FFF00000000FBFF80000001F9FF8000
+0003F0FFC0000003E07FE0000007C07FF000000F803FF800001F001FFC00003E000FFC00007C00
+07FE0000FC0003FF0001FC0003FF80FFFF801FFFFEFFFF801FFFFEFFFF801FFFFEFFFF801FFFFE
+2F267EA534>120 D E /Fk 1 98 df<00200000700000700000700000B80000B80000B800011C
+00011C00011C00020E00020E0004070004070007FF000803800803800803801801C03803C0FE0F
+F815157F9419>97 D E /Fl 94 127 df<60F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0600000000060
+F0F0600419779816>33 D<E038F078F078F078F078F078F078F078E038E03860300D0B7C9816>
+I<0387000387000387000387000387000387007FFFC0FFFFE0FFFFE0070E00070E00070E000E1C
+000E1C000E1C000E1C00FFFFE0FFFFE07FFFC01C38001C38001C38001C38001C38001C38001319
+7F9816>I<00C00001C00001C00001C00007F0001FFC003FFE007DCF0071C780E1C380E1C780E1
+C780F1C30079C0003FC0001FF00007FC0001FE0001CF0001C70061C380F1C380F1C380E1C38071
+C70079DF003FFE001FF80007E00001C00001C00000C00011207E9C16>I<3801807C03807C0380
+EE0700EE0700EE0E00EE0E00EE0E00EE1C007C1C007C380038380000700000700000700000E000
+00E00001C00001C00001C0000380000383800707C00707C00E0EE00E0EE00E0EE01C0EE01C0EE0
+3807C03807C018038013207F9C16>I<03800007E0000FE0001E70001C70001C70001C70001C77
+E01CE7E01DE7E00FC7000F8E000F0E001E0E003F1C007F1C00739C00E3F800E1F800E0F1C0E0F1
+C071F9C07FFFC03F9F801E070013197F9816>I<30787C3C1C1C1C1C3878F0E040060D789816>I<
+00E001E0038007000E001C001C0038003800700070007000E000E000E000E000E000E000E000E0
+00E000700070007000380038001C001C000E000700038001E000E00B217A9C16>I<C000E00070
+0038001C000E000E000700070003800380038001C001C001C001C001C001C001C001C001C00380
+03800380070007000E000E001C0038007000E000C0000A217B9C16>I<01C00001C00001C00001
+C00071C700F9CF807FFF001FFC0007F00007F0001FFC007FFF00F9CF8071C70001C00001C00001
+C00001C00011127E9516>I<01C00001C00001C00001C00001C00001C00001C00001C000FFFF80
+FFFF80FFFF8001C00001C00001C00001C00001C00001C00001C00001C00011137E9516>I<387C
+7E7E3E0E1E1C78F060070B798416>I<FFFF80FFFF80FFFF8011037E8D16>I<70F8F8F870050578
+8416>I<000180000380000380000700000700000E00000E00001C00001C000038000038000070
+0000700000E00000E00001C00001C0000380000380000700000700000E00000E00001C00001C00
+00380000380000700000700000E00000E00000C0000011207E9C16>I<03E0000FF8001FFC001E
+3C00380E00780F00700700700700E00380E00380E00380E00380E00380E00380E00380E00380F0
+0780700700700700780F003C1E001E3C001FFC000FF80003E00011197E9816>I<018003800380
+07800F807F80FF807380038003800380038003800380038003800380038003800380038003807F
+F87FFC7FF80E197C9816>I<07E0001FF8003FFC00783E00E00700F00780F00380600380000380
+000380000700000700000E00001C0000380000700000E00001C0000380000F00001E0380380380
+7FFF80FFFF807FFF8011197E9816>I<07E0001FF8003FFC00781E007807003007000007000007
+00000E00003E0007FC0007F00007FC00001E00000700000300000380000380600380F00380E007
+00781E003FFC001FF80007E00011197E9816>I<007C0000FC0000DC0001DC00039C00039C0007
+1C000F1C000E1C001E1C003C1C00381C00781C00F01C00FFFFE0FFFFE0FFFFE0001C00001C0000
+1C00001C00001C0001FFC001FFC001FFC013197F9816>I<3FFE003FFE003FFE00380000380000
+3800003800003800003800003800003BF0003FFC003FFE003C0F00300700000380000380600380
+F00380F00380E00700781E003FFC001FF80007E00011197E9816>I<00F80003FC0007FE000F07
+001C0F00380F00780600700000700000E3F800EFFC00FFFE00F80F00F00700F00380E00380E003
+807003807003807007803807003C1E001FFC000FF80003E00011197E9816>I<E00000FFFF80FF
+FF80FFFF80E00F00E01E00001C0000380000780000700000E00000E00001C00001C00001C00003
+8000038000038000038000070000070000070000070000070000070000070000111A7E9916>I<
+07F0001FFC003FFE007C1F00F00780E00380E00380E003807007007C1F001FFC0007F0001FFC00
+3C1E00700700F00780E00380E00380E00380F007807007007C1F003FFE001FFC0007F00011197E
+9816>I<03E0000FF8001FFC003C1E00700E00700700E00700E00780E00380E00380E007807007
+80780F803FFF801FFB800FE380000700000700300700780E00781C007078003FF0001FE0000F80
+0011197E9816>I<70F8F8F870000000000000000070F8F8F8700512789116>I<387C7C7C380000
+00000000000038787C7C3C1C1C3870E0400618799116>I<000180000780001F80003E0000F800
+01F00007C0000F80003E0000FC0000F00000FC00003E00000F800007C00001F00000F800003E00
+001F8000078000018011157E9616>I<7FFF00FFFF80FFFF800000000000000000000000000000
+00FFFF80FFFF807FFF00110B7E9116>I<C00000F00000FC00003E00000F800007C00001F00000
+F800003E00001F80000780001F80003E0000F80001F00007C0000F80003E0000FC0000F00000C0
+000011157E9616>I<0FE03FF87FFCF01EF00EF00E601E003C007800F001C00380038003800380
+03800300000000000000000003000780078003000F197D9816>I<00F80003FC0007FE000F0700
+1C3F80387F8078FF8071C3C071C3C0E381C0E381C0E381C0E381C0E381C0E381C0E381C071C380
+71C38078FF00387E001C3C000F03C007FFC003FF0000FC0012197E9816>I<00E00001F00001F0
+0001B00001B00003B80003B80003B800031800071C00071C00071C00071C00071C000E0E000E0E
+000FFE000FFE001FFF001C07001C07001C07007F1FC0FF1FE07F1FC013197F9816>I<7FF800FF
+FE007FFF001C0F001C07801C03801C03801C03801C07801C07001FFF001FFE001FFE001C1F001C
+03801C03C01C01C01C01C01C01C01C01C01C03C01C07807FFF80FFFF007FFC0012197F9816>I<
+01F18007FB800FFF801F0F803C0780380380700380700380F00000E00000E00000E00000E00000
+E00000E00000E00000F000007003807003803803803C07001F0F000FFE0007FC0001F00011197E
+9816>I<7FF800FFFE007FFF001C0F001C07801C03C01C01C01C01C01C01E01C00E01C00E01C00
+E01C00E01C00E01C00E01C00E01C00E01C01C01C01C01C03C01C07801C0F807FFF00FFFE007FF8
+001319809816>I<7FFFC0FFFFC07FFFC01C01C01C01C01C01C01C01C01C00001C00001C1C001C
+1C001FFC001FFC001FFC001C1C001C1C001C00001C00E01C00E01C00E01C00E01C00E07FFFE0FF
+FFE07FFFE013197F9816>I<FFFFE0FFFFE0FFFFE01C00E01C00E01C00E01C00E01C00001C0000
+1C1C001C1C001FFC001FFC001FFC001C1C001C1C001C00001C00001C00001C00001C00001C0000
+FF8000FFC000FF800013197F9816>I<03E30007FF000FFF001E1F003C0F003807007007007007
+00F00000E00000E00000E00000E00000E03F80E07FC0E03F80F00700700700700700380F003C0F
+001E1F000FFF0007F70003E70012197E9816>I<7F1FC0FFBFE07F1FC01C07001C07001C07001C
+07001C07001C07001C07001FFF001FFF001FFF001C07001C07001C07001C07001C07001C07001C
+07001C07001C07007F1FC0FFBFE07F1FC013197F9816>I<FFFEFFFEFFFE038003800380038003
+8003800380038003800380038003800380038003800380038003800380FFFEFFFEFFFE0F197D98
+16>I<07FE07FF07FE003800380038003800380038003800380038003800380038003800380038
+00386038F038F0707FF07FE01F8010197D9816>I<7F0FE0FF8FF07F0FE01C07801C0F001C0E00
+1C1C001C3C001C78001CF0001CE0001DF0001FF0001FF8001F38001E1C001C1C001C0E001C0E00
+1C07001C07001C03807F07E0FF8FF07F07E01419809816>I<FFC000FFC000FFC0001C00001C00
+001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00
+401C00E01C00E01C00E01C00E0FFFFE0FFFFE0FFFFE013197F9816>I<FC07E0FE0FE0FE0FE03A
+0B803B1B803B1B803B1B803B1B803B1B803BBB8039B38039B38039B38039B38039F38038E38038
+E380380380380380380380380380380380FE0FE0FE0FE0FE0FE013197F9816>I<7E1FC0FF3FE0
+7F1FC01D07001D87001D87001D87001DC7001DC7001CC7001CC7001CE7001CE7001CE7001C6700
+1C67001C77001C77001C37001C37001C37001C17007F1F00FF9F007F0F0013197F9816>I<1FFC
+003FFE007FFF00780F00F00780E00380E00380E00380E00380E00380E00380E00380E00380E003
+80E00380E00380E00380E00380E00380F00780F00780780F007FFF003FFE001FFC0011197E9816
+>I<7FF800FFFE007FFF001C0F801C03801C03C01C01C01C01C01C01C01C03C01C03801C0F801F
+FF001FFE001FF8001C00001C00001C00001C00001C00001C00001C00007F0000FF80007F000012
+197F9816>I<1FFC003FFE007FFF00780F00F00780E00380E00380E00380E00380E00380E00380
+E00380E00380E00380E00380E00380E00380E00380E0E380E1E380F0F780787F007FFF003FFE00
+1FFC00001C00001E00000E00000F00000700000700111F7E9816>I<7FE000FFF8007FFC001C1E
+001C0F001C07001C07001C07001C07001C0F001C1E001FFC001FF8001FFC001C1C001C0E001C0E
+001C0E001C0E001C0E201C0E701C0E707F07E0FF87E07F03C014197F9816>I<07E3001FFF003F
+FF00781F00F00700E00700E00700E00000F000007800003F80001FF00007FC0000FE00000F0000
+0700000380000380600380E00380E00700F80F00FFFE00FFFC00C7F00011197E9816>I<7FFFE0
+FFFFE0FFFFE0E0E0E0E0E0E0E0E0E0E0E0E000E00000E00000E00000E00000E00000E00000E000
+00E00000E00000E00000E00000E00000E00000E00000E00007FC000FFE0007FC0013197F9816>
+I<7F07F0FF8FF87F07F01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01
+C01C01C01C01C01C01C01C01C01C01C01C01C00E03800E038007070007FF0003FE0000F8001519
+809816>I<FE0FE0FF1FE0FE0FE03803801C07001C07001C07001C07000E0E000E0E000E0E000E
+0E00060C00071C00071C00071C00071C0003180003B80003B80003B80001B00001F00001F00000
+E00013197F9816>I<FC07E0FE0FE0FC07E07001C07001C07001C0300180380380380380380380
+38E38039F38039F38039B38019B30019B30019B30019B30019B30019B3001913001B1B000F1E00
+0F1E000E0E0013197F9816>I<7F1F807F3F807F1F800E1E000E1C00073C0007380003B80003F0
+0001F00001E00000E00001E00001F00003F00003B80007B800071C00071C000E0E000E0E001C07
+007F1FC0FF1FE07F1FC013197F9816>I<FE0FE0FF1FE0FE0FE01C07001C07000E0E000E0E0007
+1C00071C00071C0003B80003B80001F00001F00000E00000E00000E00000E00000E00000E00000
+E00000E00003F80007FC0003F80013197F9816>I<7FFF80FFFF80FFFF80E00700E00F00E01E00
+E01C00003C0000780000700000F00001E00001C00003C0000780000700000F00001E03801C0380
+3C0380780380700380FFFF80FFFF80FFFF8011197E9816>I<FFF0FFF0FFF0E000E000E000E000
+E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E0
+00E000E000FFF0FFF0FFF00C20789C16>I<C00000E00000E00000700000700000380000380000
+1C00001C00000E00000E000007000007000003800003800001C00001C00000E00000E000007000
+007000003800003800001C00001C00000E00000E0000070000070000038000038000018011207E
+9C16>I<FFF0FFF0FFF00070007000700070007000700070007000700070007000700070007000
+7000700070007000700070007000700070007000700070FFF0FFF0FFF00C207F9C16>I<03000F
+803FE0FDF8F07840100D067C9816>I<FFFF80FFFF80FFFF8011037E7E16>I<081C3C7870E0E0E0
+E0F0F87830060D789B16>I<1FE0003FF0007FF800783C00300E00000E00000E0003FE001FFE00
+3E0E00700E00E00E00E00E00E00E00783E007FFFE03FE7E00F83E013127E9116>I<7E0000FE00
+007E00000E00000E00000E00000E00000E3E000EFF000FFF800F83C00F00E00E00E00E00700E00
+700E00700E00700E00700E00700E00E00F01E00F83C00FFF800EFF00063C001419809816>I<03
+F80FFC1FFE3C1E780C7000E000E000E000E000E000F000700778073E0E1FFC0FF803F010127D91
+16>I<003F00007F00003F0000070000070000070000070003C7000FF7001FFF003C1F00780F00
+700700E00700E00700E00700E00700E00700E00700700F00700F003C1F001FFFE00FE7F007C7E0
+14197F9816>I<03E00FF81FFC3C1E780E7007E007FFFFFFFFFFFFE000E000700778073C0F1FFE
+0FFC03F010127D9116>I<001F00007F8000FF8001E78001C30001C00001C0007FFF00FFFF00FF
+FF0001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C0003F
+FE007FFF003FFE0011197F9816>I<03E3C007F7E00FFFE01C1CC0380E00380E00380E00380E00
+380E001C1C000FF8001FF0001BE0003800001800001FFC001FFF003FFF807803C0E000E0E000E0
+E000E0E000E07001C07C07C03FFF800FFE0003F800131C7F9116>I<7E0000FE00007E00000E00
+000E00000E00000E00000E3C000EFE000FFF000F87800F03800E03800E03800E03800E03800E03
+800E03800E03800E03800E03800E03807FC7F0FFE7F87FC7F01519809816>I<018003C003C001
+8000000000000000007FC07FC07FC001C001C001C001C001C001C001C001C001C001C001C001C0
+7FFFFFFF7FFF101A7D9916>I<003000780078003000000000000000001FF81FF81FF800380038
+003800380038003800380038003800380038003800380038003800380038003800386070F0F0FF
+E07FC03F800D237E9916>I<7E0000FE00007E00000E00000E00000E00000E00000E7FE00E7FE0
+0E7FE00E0F000E1E000E3C000E78000EF0000FF0000FF8000FBC000F1E000E0E000E07000E0780
+7F87F0FFCFF07F87F01419809816>I<FFC000FFC000FFC00001C00001C00001C00001C00001C0
+0001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C0
+0001C000FFFF80FFFF80FFFF8011197E9816>I<F9C380FFEFC0FFFFE03C78E03C78E03870E038
+70E03870E03870E03870E03870E03870E03870E03870E03870E0FE7CF8FE7CF8FE3C7815128091
+16>I<7E3C00FEFE007FFF000F87800F03800E03800E03800E03800E03800E03800E03800E0380
+0E03800E03800E03807FC7F0FFE7F87FC7F01512809116>I<03E0000FF8001FFC003C1E00780F
+00700700E00380E00380E00380E00380E00380F00780700700780F003C1E001FFC000FF80003E0
+0011127E9116>I<7E3E00FEFF007FFF800F83C00F00E00E00E00E00700E00700E00700E00700E
+00700E00700E00E00F01E00F83C00FFF800EFF000E3C000E00000E00000E00000E00000E00000E
+00007FC000FFE0007FC000141B809116>I<07C7000FE7001FF7003C1F00700F00700F00E00700
+E00700E00700E00700E00700E00700700F00700F003C3F003FF7001FE70007C700000700000700
+000700000700000700000700003FE0007FF0003FE0141B7E9116>I<FF0FC0FF3FE0FF7FE007F0
+4007C000078000078000070000070000070000070000070000070000070000070000FFFC00FFFC
+00FFFC0013127F9116>I<0FEC3FFC7FFCF03CE01CE01C70007F801FF007F8003C600EE00EF00E
+F81EFFFCFFF8C7E00F127D9116>I<0300000700000700000700000700007FFF00FFFF00FFFF00
+07000007000007000007000007000007000007000007010007038007038007038007870003FE00
+01FC0000F80011177F9616>I<7E1F80FE3F807E1F800E03800E03800E03800E03800E03800E03
+800E03800E03800E03800E03800E03800E0F800FFFF007FBF803E3F01512809116>I<7F1FC0FF
+1FE07F1FC01C07001E0F000E0E000E0E000E0E00071C00071C00071C00071C0003B80003B80003
+B80001F00001F00000E00013127F9116>I<FF1FE0FFBFE0FF1FE0380380380380380380380380
+38E38019F30019F30019B3001DB7001DB7001DB7001DB7000F1E000F1E000F1E0013127F9116>
+I<7F1FC07F3FC07F1FC00F1C00073C0003B80003F00001F00000E00001E00001F00003B800073C
+00071C000E0E007F1FC0FF3FE07F1FC013127F9116>I<7F1FC0FF9FE07F1FC01C07000E07000E
+0E000E0E00070E00071C00071C00039C00039C0003980001B80001B80000F00000F00000F00000
+E00000E00000E00001C00079C0007BC0007F80003F00003C0000131B7F9116>I<3FFFC07FFFC0
+7FFFC0700780700F00701E00003C0000780001F00003E0000780000F00001E01C03C01C07801C0
+FFFFC0FFFFC0FFFFC012127F9116>I<001F80007F8000FF8001E00001C00001C00001C00001C0
+0001C00001C00001C00001C00001C00003C0007F8000FF0000FF00007F800003C00001C00001C0
+0001C00001C00001C00001C00001C00001C00001C00001E00000FF80007F80001F8011207E9C16
+>I<E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E00320779C16>
+I<7C0000FF0000FF800003C00001C00001C00001C00001C00001C00001C00001C00001C00001C0
+0001E00000FF00007F80007F8000FF0001E00001C00001C00001C00001C00001C00001C00001C0
+0001C00001C00003C000FF8000FF00007C000011207E9C16>I<1C303F78FFF8F7E061C00D057C
+9816>I E /Fm 47 122 df<0001FC3C00060E67000C0EC7001C0DC6001C01C0003801C0003803
+800038038000380380003803800070038007FFFFF800700700007007000070070000E0070000E0
+0E0000E00E0000E00E0000E00E0001C00E0001C01C0001C01C0001C01C0001C01C0003801C0003
+803800038038000380380003003800070030000700700006006000C6606000E470C000C8618000
+703E00002025819C19>11 D<0001FC000703000C03001C07001C03001800003800003800003800
+00380000700007FFFC00701C00701C00701C00E03800E03800E03800E03800E07001C07001C070
+01C07001C0E201C0E201C0E20380E4038064038038038000030000070000060000C60000E40000
+CC00007000001825819C17>I<00C001E001E001E001C003C003C0038003800380030007000700
+06000600060004000C000C00080008000000000000000000000030007800F00060000B1E7C9D0D
+>33 D<183C3C3C0404080810204080060C779C0D>39 D<183878380808101020404080050C7D83
+0D>44 D<FFC0FFC0FFC00A037D890F>I<3078F06005047C830D>I<0001800001C0000380000380
+000380000300000700000700000600000E00000C00001C00001800001800003000003000006000
+00400000C600018E00010E00020E00061C000C1C00181C003F1C0040F800803F00003800003800
+00700000700000700000700000E00000600012247E9B15>52 D<060F0F06000000000000000000
+003078F06008127C910D>58 D<0000180000001800000038000000380000007800000078000000
+B8000001B800000138000002380000023C0000041C0000041C0000081C0000181C0000101C0000
+201C0000201C00007FFC0000401C0000801C0001801C0001001C0002001C0002001C0004000E00
+0C000E001C001E00FF00FFC01A1D7E9C1F>65 D<0003F020001E0C60003002E000E003C001C001
+C0038001C0070000C00E0000801E0000801C0000803C0000803C00000078000000780000007800
+0000F0000000F0000000F0000000F0000000F0000400F0000400F0000400F00008007000080070
+00100038002000180040000C0180000706000001F800001B1E7A9C1E>67
+D<01FFFE00003C0780003801C0003801C0003800E0003800E0007000F000700070007000700070
+00F000E000F000E000F000E000F000E000F001C001E001C001E001C001E001C001C0038003C003
+800380038007800380070007000E0007001C0007003800070070000E01C000FFFF00001C1C7D9B
+1F>I<01FFFFC0003C01C0003800C0003800800038008000380080007000800070008000702080
+0070200000E0400000E0400000E0C00000FFC00001C0800001C0800001C0800001C08000038100
+00038000000380000003800000070000000700000007000000070000000F000000FFF000001A1C
+7D9B1B>70 D<01FFCFFE003C01E0003801C0003801C0003801C0003801C0007003800070038000
+7003800070038000E0070000E0070000E0070000FFFF0001C00E0001C00E0001C00E0001C00E00
+03801C0003801C0003801C0003801C00070038000700380007003800070038000F007800FFE7FF
+001F1C7D9B1F>72 D<01FFC0003C00003800003800003800003800007000007000007000007000
+00E00000E00000E00000E00001C00001C00001C00001C000038000038000038000038000070000
+0700000700000700000F0000FFE000121C7E9B10>I<007FF00007800007000007000007000007
+00000E00000E00000E00000E00001C00001C00001C00001C000038000038000038000038000070
+0000700000700000700060E000E0E000C0C00081C0008380004700003C0000141D7B9B16>I<01
+FFE0003C0000380000380000380000380000700000700000700000700000E00000E00000E00000
+E00001C00001C00001C00001C0000380080380080380080380100700100700300700600700E00E
+03C0FFFFC0151C7D9B1A>76 D<01FE0007F8003E000780002E000F00002E001700002E00170000
+2E002700004E002E00004E004E00004E004E00004E008E00008E011C00008E011C00008E021C00
+008E021C0001070438000107043800010708380001071038000207107000020720700002072070
+000207407000040740E000040780E000040700E0000C0700E0001C0601E000FF861FFC00251C7D
+9B25>I<01FC03FE001C0070003C0060002E0040002E0040002E00400047008000470080004700
+80004380800083810000838100008181000081C1000101C2000101C2000100E2000100E2000200
+E4000200740002007400020074000400380004003800040038000C0018001C001000FF8010001F
+1C7D9B1F>I<01FFF800003C0E0000380700003803800038038000380380007007800070078000
+70078000700F0000E00E0000E01C0000E0700000FFC00001C0C00001C0600001C0700001C07000
+038070000380700003807000038070000700F0000700F0400700F0400700F0800F007880FFE079
+0000001E001A1D7D9B1E>82 D<1FFFFFC01C0701C0300E00C0200E0080600E0080400E0080401C
+0080801C0080801C0080001C000000380000003800000038000000380000007000000070000000
+7000000070000000E0000000E0000000E0000000E0000001C0000001C0000001C0000001C00000
+03C000007FFE00001A1C799B1E>84 D<7FF0FF800F001C000E0018000E0010000E0010000E0010
+001C0020001C0020001C0020001C00200038004000380040003800400038004000700080007000
+80007000800070008000E0010000E0010000E0010000E0020000E0020000E0040000E004000060
+08000030300000104000000F800000191D779B1F>I<FF83FF0FF03C007001C038007001803800
+F001003800F0020038017002003801700400380270040038027008001C047008001C047010001C
+087010001C087020001C107020001C107040001C207040001C207080001C407180001C40710000
+1C807200001D807200001D007400001E007400001E007800001C007800001C0070000018007000
+0018006000001000600000241D779B29>87 D<03CC063C0C3C181C3838303870387038E070E070
+E070E070E0E2C0E2C0E261E462643C380F127B9115>97 D<3F00070007000E000E000E000E001C
+001C001C001C0039C03E60383038307038703870387038E070E070E070E060E0E0C0C0C1C06180
+63003C000D1D7B9C13>I<01F007080C08181C3838300070007000E000E000E000E000E000E008
+E010602030C01F000E127B9113>I<001F80000380000380000700000700000700000700000E00
+000E00000E00000E0003DC00063C000C3C00181C00383800303800703800703800E07000E07000
+E07000E07000E0E200C0E200C0E20061E4006264003C3800111D7B9C15>I<01E007100C101808
+3810701070607F80E000E000E000E000E000E0086010602030C01F000D127B9113>I<0003C000
+0670000C70001C60001C00001C0000380000380000380000380000380003FF8000700000700000
+700000700000700000E00000E00000E00000E00000E00001C00001C00001C00001C00001C00003
+8000038000038000030000030000070000C60000E60000CC00007800001425819C0D>I<00F301
+8F030F06070E0E0C0E1C0E1C0E381C381C381C381C383830383038187818F00F700070007000E0
+00E0C0C0E1C0C3007E00101A7D9113>I<0FC00001C00001C00003800003800003800003800007
+00000700000700000700000E78000E8C000F0E000E0E001C0E001C0E001C0E001C0E00381C0038
+1C00381C00383800703880703880707080707100E03200601C00111D7D9C15>I<018003800100
+00000000000000000000000000001C002600470047008E008E000E001C001C001C003800380071
+0071007100720072003C00091C7C9B0D>I<0FC00001C00001C000038000038000038000038000
+0700000700000700000700000E0F000E11000E23800E43801C83001C80001D00001E00003F8000
+39C00038E00038E00070E20070E20070E20070E400E06400603800111D7D9C13>107
+D<1F800380038007000700070007000E000E000E000E001C001C001C001C003800380038003800
+7000700070007000E400E400E400E40068003800091D7C9C0B>I<3C1E0780266318C04683A0E0
+4703C0E08E0380E08E0380E00E0380E00E0380E01C0701C01C0701C01C0701C01C070380380E03
+88380E0388380E0708380E0710701C0320300C01C01D127C9122>I<3C3C002646004687004707
+008E07008E07000E07000E07001C0E001C0E001C0E001C1C00381C40381C403838403838807019
+00300E0012127C9117>I<01E007180C0C180C380C300E700E700EE01CE01CE01CE018E038E030
+E06060C031801E000F127B9115>I<07870004D98008E0C008E0C011C0E011C0E001C0E001C0E0
+0381C00381C00381C00381800703800703000707000706000E8C000E70000E00000E00001C0000
+1C00001C00001C00003C0000FF8000131A7F9115>I<03C4062C0C3C181C3838303870387038E0
+70E070E070E070E0E0C0E0C0E061E063C03DC001C001C0038003800380038007803FF00E1A7B91
+13>I<3C3C26C2468747078E068E000E000E001C001C001C001C00380038003800380070003000
+10127C9112>I<01F006080C080C1C18181C001F001FC00FF007F0007800386030E030C0308060
+60C01F000E127D9111>I<00C001C001C001C00380038003800380FFE00700070007000E000E00
+0E000E001C001C001C001C00384038403840388019000E000B1A7D990E>I<1E03002707004707
+00470700870E00870E000E0E000E0E001C1C001C1C001C1C001C1C003838803838801838801839
+001C5900078E0011127C9116>I<1E06270E470E4706870287020E020E021C041C041C041C0818
+083808181018200C4007800F127C9113>I<1E01832703874703874703838707018707010E0701
+0E07011C0E021C0E021C0E021C0E04180C04181C04181C081C1C100C263007C3C018127C911C>
+I<070E0019910010E38020E38041C30041C00001C00001C0000380000380000380000380000702
+00670200E70400CB04008B080070F00011127D9113>I<1E03270747074707870E870E0E0E0E0E
+1C1C1C1C1C1C1C1C38383838183818381C7007F00070007000E0E0C0E1C0818047003C00101A7C
+9114>I E /Fn 7 121 df<60F0F06004047C830C>58 D<60F0F0701010101020204080040C7C83
+0C>I<0000038000000F0000003C000000F0000003C000000F0000003C000000F0000003C00000
+0F0000003C000000F0000000F00000003C0000000F00000003C0000000F00000003C0000000F00
+000003C0000000F00000003C0000000F000000038019187D9520>I<E0000000780000001E0000
+000780000001E0000000780000001E0000000780000001E0000000780000001E00000007800000
+078000001E00000078000001E00000078000001E00000078000001E00000078000001E00000078
+000000E000000019187D9520>62 D<0003F800000E0E000038038000E001C001C001C0038000E0
+070000E00F0000F01E0000F01C0000F03C0000F03C0000F0780000F0780000F0780000F0F00001
+E0F00001E0F00001E0F00003C0F00003C0F0000780F0000780F0000F0070000E0070001C003800
+38003C0070001C01C0000707800001FC00001C1E7E9C20>79 D<381F004E61804681C04701C08F
+01C08E01C00E01C00E01C01C03801C03801C03801C0700380710380710380E10380E2070064030
+038014127E9119>110 D<07878008C84010F0C020F1E020E3C040E18000E00000E00001C00001
+C00001C00001C000638080F38080F38100E5810084C60078780013127E9118>120
+D E /Fo 73 123 df<003FE3F801F03F1C03C03E3E07C07C3E0F807C3E0F807C1C0F807C000F80
+7C000F807C000F807C000F807C00FFFFFFC0FFFFFFC00F807C000F807C000F807C000F807C000F
+807C000F807C000F807C000F807C000F807C000F807C000F807C000F807C000F807C000F807C00
+7FE1FFC07FE1FFC01F1D809C1C>11 D<003FC00001F0300003C0380007C07C000F807C000F807C
+000F8038000F8000000F8000000F8000000F800000FFFFFC00FFFFFC000F807C000F807C000F80
+7C000F807C000F807C000F807C000F807C000F807C000F807C000F807C000F807C000F807C000F
+807C000F807C007FE1FF807FE1FF80191D809C1B>I<781E00FC3F00FC3F00FE3F80FE3F807A1E
+80020080020080040100040100080200080200300C00401000110E7E9C19>34
+D<78FCFCFEFE7A0202040408083040070E7D9C0D>39 D<78FCFCFEFE7A0202040408083040070E
+7D850D>44 D<FFE0FFE0FFE0FFE00B047F8A10>I<78FCFCFCFC7806067D850D>I<03F8000F1E00
+1C07003C07803803807803C07803C07803C0F803E0F803E0F803E0F803E0F803E0F803E0F803E0
+F803E0F803E0F803E0F803E0F803E07803C07803C03803803C07801C07000F1E0003F800131B7E
+9A18>48 D<00600001E0000FE000FFE000F3E00003E00003E00003E00003E00003E00003E00003
+E00003E00003E00003E00003E00003E00003E00003E00003E00003E00003E00003E00003E00003
+E0007FFF807FFF80111B7D9A18>I<07F8001FFE00383F80780FC0FC07C0FC07E0FC03E0FC03E0
+7803E00007E00007C00007C0000F80001F00001E0000380000700000E000018060030060060060
+0800E01FFFC03FFFC07FFFC0FFFFC0FFFFC0131B7E9A18>I<03F8001FFE003C1F003C0F807C07
+C07E07C07C07C03807C0000F80000F80001E00003C0003F800001E00000F800007C00007C00007
+E03007E07807E0FC07E0FC07E0FC07C0780F80781F001FFE0007F800131B7E9A18>I<00018000
+0380000780000F80001F80003F80006F8000CF80008F80018F80030F80060F800C0F80180F8030
+0F80600F80C00F80FFFFF8FFFFF8000F80000F80000F80000F80000F80000F8001FFF801FFF815
+1B7F9A18>I<1801801FFF001FFE001FFC001FF8001FC00018000018000018000018000019F800
+1E0E00180F801007800007C00007E00007E00007E07807E0F807E0F807E0F807C0F007C0600F80
+381F001FFE0007F000131B7E9A18>I<007E0003FF000781800F03C01E07C03C07C03C03807800
+00780000F80000F8F800FB0E00FA0780FC0380FC03C0F803E0F803E0F803E0F803E07803E07803
+E07803C03C03C03C07801E0F0007FE0003F800131B7E9A18>I<6000007FFFE07FFFE07FFFC07F
+FF807FFF80E00300C00600C00C00C0180000300000300000600000E00000E00001E00001C00003
+C00003C00003C00003C00007C00007C00007C00007C00007C00007C000038000131C7D9B18>I<
+03F8000FFE001E0F803807803803C07803C07803C07E03C07F83807FC7003FFE001FFC000FFE00
+07FF801DFF80387FC0781FE0F007E0F003E0F001E0F001E0F001E07801C07803803E07801FFE00
+03F800131B7E9A18>I<03F8000FFE001E0F003C07807807807803C0F803C0F803C0F803E0F803
+E0F803E0F803E07807E03807E03C0BE00E1BE003E3E00003E00003C00003C03807C07C07807C07
+00780F00383C001FF8000FE000131B7E9A18>I<78FCFCFCFC7800000000000078FCFCFCFC7806
+127D910D>I<00038000000380000007C0000007C0000007C000000FE000000FE000001FF00000
+1BF000001BF0000031F8000031F8000061FC000060FC0000E0FE0000C07E0000C07E0001803F00
+01FFFF0003FFFF8003001F8003001F8006000FC006000FC00E000FE00C0007E0FFC07FFEFFC07F
+FE1F1C7E9B24>65 D<FFFFF800FFFFFF000FC01F800FC00FC00FC007C00FC007E00FC007E00FC0
+07E00FC007E00FC007E00FC007C00FC00F800FC03F000FFFFE000FC00F800FC007C00FC007E00F
+C003E00FC003F00FC003F00FC003F00FC003F00FC003F00FC007E00FC007E00FC01FC0FFFFFF00
+FFFFFC001C1C7E9B22>I<001FE02000FFF8E003F80FE007C003E00F8001E01F0000E03E0000E0
+3E0000607E0000607C000060FC000000FC000000FC000000FC000000FC000000FC000000FC0000
+00FC0000007C0000607E0000603E0000603E0000C01F0000C00F80018007C0030003F80E0000FF
+FC00001FE0001B1C7D9B22>I<FFFFF800FFFFFF000FC01FC00FC007E00FC001F00FC001F80FC0
+00F80FC000FC0FC0007C0FC0007C0FC0007E0FC0007E0FC0007E0FC0007E0FC0007E0FC0007E0F
+C0007E0FC0007E0FC0007C0FC0007C0FC0007C0FC000F80FC000F80FC001F00FC007E00FC01FC0
+FFFFFF00FFFFF8001F1C7E9B25>I<FFFFFF00FFFFFF000FC01F000FC007000FC003000FC00380
+0FC003800FC181800FC181800FC181800FC180000FC380000FFF80000FFF80000FC380000FC180
+000FC180000FC180600FC180600FC000E00FC000C00FC000C00FC001C00FC001C00FC003C00FC0
+0F80FFFFFF80FFFFFF801B1C7E9B1F>I<FFFFFF00FFFFFF000FC01F000FC007000FC003000FC0
+03800FC003800FC001800FC181800FC181800FC180000FC180000FC380000FFF80000FFF80000F
+C380000FC180000FC180000FC180000FC180000FC000000FC000000FC000000FC000000FC00000
+0FC00000FFFF0000FFFF0000191C7E9B1E>I<000FF008007FFE3801FC07F807E001F80F800078
+1F0000783F0000383E0000387E0000187C000018FC000000FC000000FC000000FC000000FC0000
+00FC000000FC007FFFFC007FFF7C0001F87E0001F83E0001F83F0001F81F0001F80F8001F807E0
+01F801FC07F8007FFE78000FF818201C7D9B26>I<FFFC3FFFFFFC3FFF0FC003F00FC003F00FC0
+03F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F00FFFFFF00FFFFFF00F
+C003F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F0
+0FC003F00FC003F0FFFC3FFFFFFC3FFF201C7E9B25>I<FFFFFFFF07E007E007E007E007E007E0
+07E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E0FFFFFF
+FF101C7F9B12>I<07FFF007FFF0001F80001F80001F80001F80001F80001F80001F80001F8000
+1F80001F80001F80001F80001F80001F80001F80001F80001F80001F80301F80781F80FC1F80FC
+1F80FC1F00783E00387C000FF000141C7F9B19>I<FFFC07FFFFFC07FF0FC000E00FC001C00FC0
+03800FC006000FC00C000FC038000FC070000FC0E0000FC1C0000FC3C0000FC7E0000FCFE0000F
+FBF0000FF3F8000FE1F8000FC0FC000FC0FE000FC07E000FC03F000FC01F800FC01FC00FC00FC0
+0FC007E00FC007F0FFFC3FFFFFFC3FFF201C7E9B25>I<FFFF00FFFF000FC0000FC0000FC0000F
+C0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0030F
+C0030FC0030FC0070FC0070FC0060FC00E0FC01E0FC07EFFFFFEFFFFFE181C7E9B1D>I<FFC000
+03FFFFE00007FF0FE00007F00DF0000DF00DF0000DF00DF0000DF00CF80019F00CF80019F00C7C
+0031F00C7C0031F00C3E0061F00C3E0061F00C1F00C1F00C1F00C1F00C1F00C1F00C0F8181F00C
+0F8181F00C07C301F00C07C301F00C03E601F00C03E601F00C01FC01F00C01FC01F00C01FC01F0
+0C00F801F00C00F801F0FFC0701FFFFFC0701FFF281C7E9B2D>I<FFE003FFFFE003FF0FF00030
+0FF800300DFC00300CFE00300C7E00300C3F00300C1F80300C1FC0300C0FE0300C07F0300C03F0
+300C01F8300C01FC300C00FE300C007F300C003F300C001FB00C001FF00C000FF00C0007F00C00
+03F00C0001F00C0000F00C0000F0FFC00070FFC00030201C7E9B25>I<003FE00001F07C0003C0
+1E000F800F801F0007C01E0003C03E0003E07E0003F07C0001F07C0001F0FC0001F8FC0001F8FC
+0001F8FC0001F8FC0001F8FC0001F8FC0001F8FC0001F87C0001F07E0003F07E0003F03E0003E0
+3F0007E01F0007C00F800F8003C01E0001F07C00003FE0001D1C7D9B24>I<FFFFF800FFFFFE00
+0FC03F800FC00F800FC007C00FC007E00FC007E00FC007E00FC007E00FC007E00FC007C00FC007
+C00FC00F800FC03F000FFFFC000FC000000FC000000FC000000FC000000FC000000FC000000FC0
+00000FC000000FC000000FC000000FC00000FFFC0000FFFC00001B1C7E9B21>I<003FE00001F0
+7C0003C01E000F800F801F0007C01F0007C03E0003E07E0003F07C0001F07C0001F0FC0001F8FC
+0001F8FC0001F8FC0001F8FC0001F8FC0001F8FC0001F8FC0001F87C0001F07C0001F07E0003F0
+3E0003E03E0703E01F08C7C00F906F8003D07E0001F87C00003FF8080000380800003C1800003F
+F800001FF800001FF000000FF0000007E0000003C01D247D9B24>I<FFFFF00000FFFFFE00000F
+C03F00000FC00F80000FC007C0000FC007E0000FC007E0000FC007E0000FC007E0000FC007E000
+0FC007C0000FC00F80000FC03E00000FFFF000000FC07C00000FC03E00000FC03F00000FC01F80
+000FC01F80000FC01F80000FC01F80000FC01F80000FC01F80000FC01F81800FC01F81800FC00F
+C180FFFC07C300FFFC01FE00211C7E9B24>I<07F8201FFEE03C07E07801E07000E0F000E0F000
+60F00060F80000FE0000FFE0007FFE003FFF003FFF800FFFC007FFE0007FE00003F00001F00000
+F0C000F0C000F0C000E0E000E0F001C0FC03C0EFFF0083FC00141C7D9B1B>I<7FFFFFE07FFFFF
+E0781F81E0701F80E0601F8060E01F8070C01F8030C01F8030C01F8030C01F8030001F8000001F
+8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F800000
+1F8000001F8000001F8000001F8000001F800007FFFE0007FFFE001C1C7E9B21>I<FFFC03FFFF
+FC03FF0FC000300FC000300FC000300FC000300FC000300FC000300FC000300FC000300FC00030
+0FC000300FC000300FC000300FC000300FC000300FC000300FC000300FC000300FC000300FC000
+3007C0003007C0006003E000E001F001C000FC0780007FFE00000FF800201C7E9B25>I<FFFC01
+FF80FFFC01FF800FC000180007E000300007E000300007F000700003F000600003F800E00001F8
+00C00001FC00C00000FC01800000FC018000007E030000007E030000007F070000003F06000000
+3F8E0000001F8C0000001FCC0000000FD80000000FD800000007F000000007F000000007F00000
+0003E000000003E000000001C000000001C00000211C7F9B24>I<FFFC7FFE0FFCFFFC7FFE0FFC
+0FC007E000C00FC007F000C00FE003F001C007E003F0018007E007F8018003F007F8030003F007
+F8030003F80CFC070001F80CFC060001F81CFE060001FC187E0E0000FC187E0C0000FC387F0C00
+007E303F1800007E303F1800007F601FB800003F601FB000003FE01FF000003FC00FF000001FC0
+0FE000001FC00FE000000F8007C000000F8007C000000F0003C000000700038000000700038000
+2E1C7F9B31>I<7FFE1FFE007FFE1FFE0007F001800003F803800001FC07000000FC06000000FE
+0C0000007F1C0000003F380000003FB00000001FE00000000FE00000000FE000000007F0000000
+03F800000007F80000000FFC0000000CFE000000187E000000387F000000703F800000601F8000
+00C01FC00001C00FE000018007F000030007F000FFF03FFF80FFF03FFF80211C7F9B24>I<FFFC
+01FF80FFFC01FF800FE000380007F000300003F800700003F800600001FC00C00000FE01C00000
+FE018000007F030000003F870000003F860000001FCE0000000FFC0000000FF800000007F80000
+0003F000000003F000000003F000000003F000000003F000000003F000000003F000000003F000
+000003F000000003F00000003FFF0000003FFF0000211C7F9B24>I<7FFFFC7FFFFC7E01F87803
+F87003F0E007E0E007E0C00FC0C01FC0C01F80003F00007F00007E0000FC0000FC0001F80003F8
+0603F00607E0060FE0060FC00E1F800E1F801C3F001C7F003C7E00FCFFFFFCFFFFFC171C7D9B1D
+>I<FEFEFEE0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0
+E0FEFEFE07297C9E0D>I<040100180600200800200800401000401000802000802000BC2F00FE
+3F80FE3F807E1F807E1F803C0F00110E7B9C19>I<FEFEFE0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E
+0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0EFEFEFE07297F9E0D>I<0FF8001C1E003E0F80
+3E07803E07C01C07C00007C0007FC007E7C01F07C03C07C07C07C0F807C0F807C0F807C0780BC0
+3E13F80FE1F815127F9117>97 D<FF0000FF00001F00001F00001F00001F00001F00001F00001F
+00001F00001F00001F3F801FE1E01F80701F00781F003C1F003C1F003E1F003E1F003E1F003E1F
+003E1F003E1F003C1F003C1F00781F80701EC1E01C3F00171D7F9C1B>I<03FC000E0E001C1F00
+3C1F00781F00780E00F80000F80000F80000F80000F80000F800007800007801803C01801C0300
+0E0E0003F80011127E9115>I<000FF0000FF00001F00001F00001F00001F00001F00001F00001
+F00001F00001F001F9F00F07F01C03F03C01F07801F07801F0F801F0F801F0F801F0F801F0F801
+F0F801F07801F07801F03C01F01C03F00F0FFE03F9FE171D7E9C1B>I<01FC000F07001C03803C
+01C07801C07801E0F801E0F801E0FFFFE0F80000F80000F800007800007C00603C00601E00C00F
+038001FC0013127F9116>I<007F0001E38003C7C00787C00F87C00F83800F80000F80000F8000
+0F80000F8000FFF800FFF8000F80000F80000F80000F80000F80000F80000F80000F80000F8000
+0F80000F80000F80000F80000F80007FF8007FF800121D809C0F>I<03F8F00E0F381E0F381C07
+303C07803C07803C07803C07801C07001E0F000E0E001BF8001000001800001800001FFF001FFF
+C00FFFE01FFFF07801F8F00078F00078F000787000707800F01E03C007FF00151B7F9118>I<FF
+0000FF00001F00001F00001F00001F00001F00001F00001F00001F00001F00001F0FC01F31E01F
+40F01F80F81F80F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F
+00F8FFE7FFFFE7FF181D7F9C1B>I<1E003F003F003F003F001E00000000000000000000000000
+FF00FF001F001F001F001F001F001F001F001F001F001F001F001F001F001F00FFE0FFE00B1E7F
+9D0E>I<007800FC00FC00FC00FC007800000000000000000000000003FC03FC007C007C007C00
+7C007C007C007C007C007C007C007C007C007C007C007C007C007C007C707CF87CF878F8F070E0
+1F800E26839D0F>I<FF0000FF00001F00001F00001F00001F00001F00001F00001F00001F0000
+1F00001F0FF81F0FF81F03801F07001F0C001F18001F70001FF8001FFC001FBC001F3E001F1F00
+1F0F001F0F801F07C01F03E0FFC7FCFFC7FC161D7F9C19>I<FF00FF001F001F001F001F001F00
+1F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F
+00FFE0FFE00B1D7F9C0E>I<FF0FC07E00FF31E18F001F40F207801F80FC07C01F80FC07C01F00
+F807C01F00F807C01F00F807C01F00F807C01F00F807C01F00F807C01F00F807C01F00F807C01F
+00F807C01F00F807C01F00F807C0FFE7FF3FF8FFE7FF3FF825127F9128>I<FF0FC0FF31E01F40
+F01F80F81F80F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F00
+F8FFE7FFFFE7FF18127F911B>I<01FC000F07801C01C03C01E07800F07800F0F800F8F800F8F8
+00F8F800F8F800F8F800F87800F07800F03C01E01E03C00F078001FC0015127F9118>I<FF3F80
+FFE1E01F80F01F00781F007C1F003C1F003E1F003E1F003E1F003E1F003E1F003E1F003C1F007C
+1F00781F80F01FC1E01F3F001F00001F00001F00001F00001F00001F0000FFE000FFE000171A7F
+911B>I<03F0600F0CE01E07E03C03E07C03E07803E0F803E0F803E0F803E0F803E0F803E0F803
+E07803E07C03E03C03E01C07E00E0FE003F3E00003E00003E00003E00003E00003E00003E0001F
+FC001FFC161A7E9119>I<FE3E00FE47001E8F801E8F801E8F801F07001F00001F00001F00001F
+00001F00001F00001F00001F00001F00001F0000FFF000FFF00011127F9114>I<1FD830786018
+E018E018F000FF807FE07FF01FF807FC007CC01CC01CE01CE018F830CFC00E127E9113>I<0300
+030003000300070007000F000F003FFCFFFC1F001F001F001F001F001F001F001F001F001F0C1F
+0C1F0C1F0C0F08079803F00E1A7F9913>I<FF07F8FF07F81F00F81F00F81F00F81F00F81F00F8
+1F00F81F00F81F00F81F00F81F00F81F00F81F00F81F01F80F01F80786FF01F8FF18127F911B>
+I<FFC1FCFFC1FC1F00601F80E00F80C00FC0C007C18007C18003E30003E30001F60001F60001FE
+0000FC0000FC0000780000780000300016127F9119>I<FF8FF8FEFF8FF8FE1F03E0301F03E030
+1F83E0700F83F0600F86F06007C6F0C007CEF8C007EC79C003EC7D8003F83D8001F83F0001F83F
+0001F01F0000F01E0000E00E0000E00E001F127F9122>I<FFC7FCFFC7FC1F81800F838007C700
+03EE0001FC0001F80000F800007C0000FE0001DF00039F00070F800607C00C03E0FF07FCFF07FC
+16127F9119>I<FFC1FCFFC1FC1F00601F80E00F80C00FC0C007C18007C18003E30003E30001F7
+0001F60000FE0000FC0000FC00007800007800003000003000007000706000F86000F8C000F980
+007300003E0000161A7F9119>I<3FFF803C1F00303F00303E00607C0060FC0060F80001F00003
+F00007E00007C1800F81801F81801F03803E03007E07007C0F00FFFF0011127F9115>I
+E /Fp 33 122 df<00000007FF800000000001FFFFF0000000000FFFFFFC000000003FFFFFFE00
+000000FFFC00FF00000001FFC0003F80000007FF00007FC000000FFE0001FFC000001FFC0001FF
+E000001FF80003FFE000003FF00003FFE000003FF00003FFE000007FE00003FFE000007FE00003
+FFE000007FE00003FFE000007FE00003FFE000007FE00001FFC000007FE00000FF8000007FE000
+003E0000007FE00000000000007FE00000000000007FE00000000000007FE00000000000007FE0
+0000000000007FE00000000000007FE0003FFFF000FFFFFFFFFFFFF000FFFFFFFFFFFFF000FFFF
+FFFFFFFFF000FFFFFFFFFFFFF000FFFFFFFFFFFFF000007FF00000FFF000007FF000007FF00000
+7FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000
+007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF0
+00007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007F
+F000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF00000
+7FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000
+007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF0
+00007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF000007FF0003FFF
+FFE03FFFFFE03FFFFFE03FFFFFE03FFFFFE03FFFFFE03FFFFFE03FFFFFE03FFFFFE03FFFFFE03B
+487EC742>12 D<0000000003E000000000000000000007F000000000000000000007F000000000
+00000000000FF80000000000000000000FF80000000000000000000FF80000000000000000001F
+FC0000000000000000001FFC0000000000000000003FFE0000000000000000003FFE0000000000
+000000007FFF0000000000000000007FFF0000000000000000007FFF000000000000000000FFFF
+800000000000000000FFFF800000000000000001FFFFC00000000000000001FFFFC00000000000
+000001FFFFC00000000000000003FFFFE00000000000000003EFFFE00000000000000007EFFFF0
+0000000000000007CFFFF00000000000000007C7FFF0000000000000000FC7FFF8000000000000
+000F83FFF8000000000000001F83FFFC000000000000001F03FFFC000000000000001F01FFFC00
+0000000000003F01FFFE000000000000003E00FFFE000000000000007E00FFFF00000000000000
+7C007FFF00000000000000FC007FFF80000000000000F8007FFF80000000000000F8003FFF8000
+0000000001F8003FFFC0000000000001F0001FFFC0000000000003F0001FFFE0000000000003E0
+001FFFE0000000000003E0000FFFE0000000000007E0000FFFF0000000000007C00007FFF00000
+0000000FC00007FFF800000000000F800007FFF800000000000F800003FFF800000000001F8000
+03FFFC00000000001F000001FFFC00000000003FFFFFFFFFFE00000000003FFFFFFFFFFE000000
+00007FFFFFFFFFFF00000000007FFFFFFFFFFF00000000007FFFFFFFFFFF0000000000FC000000
+7FFF8000000000F80000003FFF8000000001F80000003FFFC000000001F00000003FFFC0000000
+01F00000001FFFC000000003F00000001FFFE000000003E00000000FFFE000000007E00000000F
+FFF000000007C00000000FFFF000000007C000000007FFF00000000FC000000007FFF80000000F
+8000000003FFF80000001F8000000003FFFC0000001F0000000003FFFC0000007FC000000001FF
+FC0000FFFFFFC00007FFFFFFFF80FFFFFFC00007FFFFFFFF80FFFFFFC00007FFFFFFFF80FFFFFF
+C00007FFFFFFFF80FFFFFFC00007FFFFFFFF8051487CC75A>65 D<000000003FFE00000E000000
+0FFFFFC0001E0000007FFFFFF8003E000003FFFFFFFE00FE00000FFFFFFFFF81FE00003FFFF800
+FFC3FE0000FFFF80000FF7FE0001FFFC000003FFFE0007FFF0000001FFFE000FFFC00000007FFE
+001FFF800000003FFE003FFF000000001FFE007FFE000000000FFE00FFFC0000000007FE01FFF8
+0000000007FE03FFF00000000003FE03FFF00000000001FE07FFE00000000001FE07FFE0000000
+0000FE0FFFC00000000000FE0FFFC000000000007E1FFFC000000000007E1FFF8000000000007E
+3FFF8000000000007E3FFF8000000000003E3FFF8000000000003E7FFF8000000000003E7FFF00
+00000000003E7FFF000000000000007FFF00000000000000FFFF00000000000000FFFF00000000
+000000FFFF00000000000000FFFF00000000000000FFFF00000000000000FFFF00000000000000
+FFFF00000000000000FFFF00000000000000FFFF00000000000000FFFF00000000000000FFFF00
+000000000000FFFF00000000000000FFFF000000000000007FFF000000000000007FFF00000000
+0000007FFF000000000000007FFF8000000000003E3FFF8000000000003E3FFF8000000000003E
+3FFF8000000000003E1FFF8000000000003E1FFFC000000000003E0FFFC000000000007C0FFFC0
+00000000007C07FFE000000000007C07FFE00000000000F803FFF00000000000F803FFF0000000
+0001F801FFF80000000001F000FFFC0000000003E0007FFE0000000007E0003FFF000000000FC0
+001FFF800000001F80000FFFC00000003F000007FFF0000000FE000001FFFC000001FC000000FF
+FF80000FF80000003FFFF8007FF00000000FFFFFFFFFC000000003FFFFFFFF00000000007FFFFF
+FC00000000000FFFFFE00000000000003FFE000000474979C756>67 D<FFFFFFFFFFFFC0000000
+FFFFFFFFFFFFFE000000FFFFFFFFFFFFFFC00000FFFFFFFFFFFFFFF00000FFFFFFFFFFFFFFFC00
+00001FFF800007FFFF0000001FFF8000007FFF8000001FFF8000000FFFE000001FFF80000007FF
+F000001FFF80000001FFF800001FFF80000000FFFC00001FFF800000007FFE00001FFF80000000
+3FFF00001FFF800000001FFF00001FFF800000000FFF80001FFF800000000FFFC0001FFF800000
+0007FFC0001FFF8000000007FFE0001FFF8000000003FFE0001FFF8000000003FFF0001FFF8000
+000003FFF0001FFF8000000003FFF8001FFF8000000001FFF8001FFF8000000001FFF8001FFF80
+00000001FFFC001FFF8000000001FFFC001FFF8000000001FFFC001FFF8000000001FFFC001FFF
+8000000001FFFC001FFF8000000001FFFE001FFF8000000000FFFE001FFF8000000000FFFE001F
+FF8000000000FFFE001FFF8000000000FFFE001FFF8000000000FFFE001FFF8000000000FFFE00
+1FFF8000000000FFFE001FFF8000000000FFFE001FFF8000000000FFFE001FFF8000000000FFFE
+001FFF8000000000FFFE001FFF8000000000FFFE001FFF8000000001FFFE001FFF8000000001FF
+FC001FFF8000000001FFFC001FFF8000000001FFFC001FFF8000000001FFFC001FFF8000000001
+FFF8001FFF8000000001FFF8001FFF8000000001FFF8001FFF8000000003FFF0001FFF80000000
+03FFF0001FFF8000000003FFF0001FFF8000000007FFE0001FFF8000000007FFE0001FFF800000
+000FFFC0001FFF800000000FFF80001FFF800000001FFF80001FFF800000003FFF00001FFF8000
+00003FFE00001FFF800000007FFC00001FFF80000001FFF800001FFF80000003FFF000001FFF80
+00000FFFE000001FFF8000007FFFC000001FFF800003FFFF0000FFFFFFFFFFFFFFFE0000FFFFFF
+FFFFFFFFF80000FFFFFFFFFFFFFFC00000FFFFFFFFFFFFFE000000FFFFFFFFFFFFC00000004F47
+7CC65B>I<FFFFFFFFFFFFFFFC00FFFFFFFFFFFFFFFC00FFFFFFFFFFFFFFFC00FFFFFFFFFFFFFF
+FC00FFFFFFFFFFFFFFFE00001FFFC00003FFFE00001FFFC000003FFE00001FFFC000000FFE0000
+1FFFC0000003FE00001FFFC0000001FE00001FFFC0000000FE00001FFFC0000000FE00001FFFC0
+0000007E00001FFFC00000007F00001FFFC00000003F00001FFFC00000003F00001FFFC0000000
+1F00001FFFC00000001F00001FFFC00000001F00001FFFC00000001F00001FFFC0007C001F0000
+1FFFC0007C000F80001FFFC0007C000F80001FFFC0007C000F80001FFFC0007C000F80001FFFC0
+007C000000001FFFC000FC000000001FFFC000FC000000001FFFC000FC000000001FFFC001FC00
+0000001FFFC003FC000000001FFFC01FFC000000001FFFFFFFFC000000001FFFFFFFFC00000000
+1FFFFFFFFC000000001FFFFFFFFC000000001FFFFFFFFC000000001FFFC01FFC000000001FFFC0
+03FC000000001FFFC001FC000000001FFFC000FC000000001FFFC000FC000000001FFFC000FC00
+0000001FFFC0007C000000001FFFC0007C000000001FFFC0007C000000001FFFC0007C00000000
+1FFFC0007C000000001FFFC0007C000000001FFFC00000000000001FFFC00000000000001FFFC0
+0000000000001FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC0000000
+0000001FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC0000000000000
+1FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC0
+0000000000FFFFFFFFFF00000000FFFFFFFFFF00000000FFFFFFFFFF00000000FFFFFFFFFF0000
+0000FFFFFFFFFF0000000041467CC54B>70 D<000000003FFE00000E000000000FFFFFC0001E00
+0000007FFFFFF8003E00000003FFFFFFFE00FE0000000FFFFFFFFF81FE0000003FFFF800FFC3FE
+000000FFFF80000FF7FE000001FFFC000003FFFE000007FFF0000001FFFE00000FFFC00000007F
+FE00001FFF800000003FFE00003FFF000000001FFE00007FFE000000000FFE0000FFFC00000000
+07FE0001FFF80000000007FE0003FFF00000000003FE0003FFF00000000001FE0007FFE0000000
+0001FE0007FFE00000000000FE000FFFC00000000000FE000FFFC000000000007E001FFFC00000
+0000007E001FFF8000000000007E003FFF8000000000007E003FFF8000000000003E003FFF8000
+000000003E007FFF8000000000003E007FFF0000000000003E007FFF00000000000000007FFF00
+00000000000000FFFF0000000000000000FFFF0000000000000000FFFF0000000000000000FFFF
+0000000000000000FFFF0000000000000000FFFF0000000000000000FFFF0000000000000000FF
+FF0000000000000000FFFF0000000000000000FFFF0000000000000000FFFF0000000000000000
+FFFF0000000000000000FFFF0000007FFFFFFFFE7FFF0000007FFFFFFFFE7FFF0000007FFFFFFF
+FE7FFF8000007FFFFFFFFE7FFF8000007FFFFFFFFE3FFF8000000000FFFE003FFF8000000000FF
+FE003FFF8000000000FFFE001FFF8000000000FFFE001FFFC000000000FFFE000FFFC000000000
+FFFE000FFFC000000000FFFE0007FFE000000000FFFE0007FFE000000000FFFE0003FFF0000000
+00FFFE0003FFF800000000FFFE0001FFF800000000FFFE0000FFFC00000000FFFE00007FFE0000
+0000FFFE00003FFF00000000FFFE00001FFF80000000FFFE00000FFFE0000001FFFE000007FFF0
+000003FFFE000001FFFC000007FFFE000000FFFF80001FFFFE0000003FFFFC00FFC7FE0000000F
+FFFFFFFF83FE00000003FFFFFFFE00FE000000007FFFFFF8003E000000000FFFFFE0000E000000
+00003FFE000000004F4979C75D>I<FFFFFFFFF801FFFFFFFFF0FFFFFFFFF801FFFFFFFFF0FFFF
+FFFFF801FFFFFFFFF0FFFFFFFFF801FFFFFFFFF0FFFFFFFFF801FFFFFFFFF0001FFFC00000003F
+FF8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFF
+C00000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF
+8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC0
+0000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF80
+00001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC000
+00003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF8000
+001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC00000
+003FFF8000001FFFC00000003FFF8000001FFFFFFFFFFFFFFF8000001FFFFFFFFFFFFFFF800000
+1FFFFFFFFFFFFFFF8000001FFFFFFFFFFFFFFF8000001FFFFFFFFFFFFFFF8000001FFFC0000000
+3FFF8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF8000001F
+FFC00000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC00000003F
+FF8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFF
+C00000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF
+8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC0
+0000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF80
+00001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC000
+00003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF8000001FFFC00000003FFF8000
+FFFFFFFFF801FFFFFFFFF0FFFFFFFFF801FFFFFFFFF0FFFFFFFFF801FFFFFFFFF0FFFFFFFFF801
+FFFFFFFFF0FFFFFFFFF801FFFFFFFFF054477CC65D>I<FFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFF
+FFFFFFFEFFFFFFFFFE000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000
+000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE0
+00000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFF
+E000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000F
+FFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE00000
+0FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000
+000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE0
+00000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFFE000000FFF
+E000FFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFE27477DC62D>I<FFFFFFC000
+0000FFFFFFF0FFFFFFE0000000FFFFFFF0FFFFFFF0000000FFFFFFF0FFFFFFF8000000FFFFFFF0
+FFFFFFFC000000FFFFFFF0001FFFFC000000007FE000001FFFFE000000001F8000001FFFFF0000
+00001F8000001FFFFF800000001F8000001FFFFFC00000001F8000001FBFFFE00000001F800000
+1F9FFFE00000001F8000001F9FFFF00000001F8000001F8FFFF80000001F8000001F87FFFC0000
+001F8000001F83FFFE0000001F8000001F81FFFF0000001F8000001F80FFFF0000001F8000001F
+80FFFF8000001F8000001F807FFFC000001F8000001F803FFFE000001F8000001F801FFFF00000
+1F8000001F800FFFF800001F8000001F8007FFF800001F8000001F8007FFFC00001F8000001F80
+03FFFE00001F8000001F8001FFFF00001F8000001F8000FFFF80001F8000001F80007FFFC0001F
+8000001F80003FFFC0001F8000001F80003FFFE0001F8000001F80001FFFF0001F8000001F8000
+0FFFF8001F8000001F800007FFFC001F8000001F800003FFFE001F8000001F800001FFFF001F80
+00001F800001FFFF001F8000001F800000FFFF801F8000001F8000007FFFC01F8000001F800000
+3FFFE01F8000001F8000001FFFF01F8000001F8000000FFFF81F8000001F8000000FFFF81F8000
+001F80000007FFFC1F8000001F80000003FFFE1F8000001F80000001FFFF1F8000001F80000000
+FFFF9F8000001F800000007FFFDF8000001F800000007FFFDF8000001F800000003FFFFF800000
+1F800000001FFFFF8000001F800000000FFFFF8000001F8000000007FFFF8000001F8000000003
+FFFF8000001F8000000003FFFF8000001F8000000001FFFF8000001F8000000000FFFF8000001F
+80000000007FFF8000001F80000000003FFF8000001F80000000001FFF8000001F80000000001F
+FF8000001F80000000000FFF8000001F800000000007FF8000001F800000000003FF8000001F80
+0000000001FF8000007FE00000000000FF8000FFFFFFF000000000FF8000FFFFFFF0000000007F
+8000FFFFFFF0000000003F8000FFFFFFF0000000001F8000FFFFFFF0000000000F000054477CC6
+5D>78 D<FFFFFFFFFFFF800000FFFFFFFFFFFFFC0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFC0
+00FFFFFFFFFFFFFFF000001FFF80000FFFFC00001FFF800001FFFE00001FFF8000007FFF00001F
+FF8000003FFF80001FFF8000001FFFC0001FFF8000000FFFC0001FFF8000000FFFE0001FFF8000
+000FFFE0001FFF80000007FFF0001FFF80000007FFF0001FFF80000007FFF0001FFF80000007FF
+F8001FFF80000007FFF8001FFF80000007FFF8001FFF80000007FFF8001FFF80000007FFF8001F
+FF80000007FFF8001FFF80000007FFF8001FFF80000007FFF8001FFF80000007FFF0001FFF8000
+0007FFF0001FFF80000007FFF0001FFF8000000FFFE0001FFF8000000FFFE0001FFF8000000FFF
+C0001FFF8000001FFF80001FFF8000003FFF80001FFF8000007FFF00001FFF800001FFFE00001F
+FF80000FFFF800001FFFFFFFFFFFF000001FFFFFFFFFFFC000001FFFFFFFFFFE0000001FFFFFFF
+FFF00000001FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC000000000
+00001FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC00000000000001F
+FFC00000000000001FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC000
+00000000001FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC000000000
+00001FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC00000000000001F
+FFC00000000000001FFFC00000000000001FFFC00000000000001FFFC00000000000001FFFC000
+00000000001FFFC00000000000FFFFFFFFF800000000FFFFFFFFF800000000FFFFFFFFF8000000
+00FFFFFFFFF800000000FFFFFFFFF80000000045477CC651>80 D<FFFFFFFFFFFC0000000000FF
+FFFFFFFFFFF000000000FFFFFFFFFFFFFE00000000FFFFFFFFFFFFFF80000000FFFFFFFFFFFFFF
+E0000000001FFF80001FFFF8000000001FFF800001FFFC000000001FFF8000007FFF000000001F
+FF8000003FFF800000001FFF8000001FFF800000001FFF8000000FFFC00000001FFF8000000FFF
+E00000001FFF8000000FFFE00000001FFF80000007FFF00000001FFF80000007FFF00000001FFF
+80000007FFF80000001FFF80000007FFF80000001FFF80000007FFF80000001FFF80000007FFF8
+0000001FFF80000007FFF80000001FFF80000007FFF80000001FFF80000007FFF80000001FFF80
+000007FFF80000001FFF80000007FFF00000001FFF80000007FFF00000001FFF8000000FFFE000
+00001FFF8000000FFFE00000001FFF8000000FFFC00000001FFF8000001FFF800000001FFF8000
+003FFF000000001FFF800000FFFE000000001FFF800003FFF8000000001FFF80001FFFF0000000
+001FFFFFFFFFFFC0000000001FFFFFFFFFFE00000000001FFFFFFFFFF800000000001FFFFFFFFF
+FE00000000001FFF80007FFF80000000001FFF80001FFFC0000000001FFF800007FFE000000000
+1FFF800003FFF0000000001FFF800001FFF8000000001FFF800001FFFC000000001FFF800000FF
+FE000000001FFF800000FFFE000000001FFF8000007FFE000000001FFF8000007FFF000000001F
+FF8000007FFF000000001FFF8000007FFF000000001FFF8000007FFF000000001FFF8000007FFF
+000000001FFF8000007FFF000000001FFF8000007FFF000000001FFF8000007FFF800000001FFF
+8000007FFF800000001FFF8000007FFF800000001FFF8000007FFF800000001FFF8000007FFF80
+0000001FFF8000007FFF8000E0001FFF8000007FFF8001F0001FFF8000007FFFC001F0001FFF80
+00007FFFC001F0001FFF8000003FFFC001F0001FFF8000003FFFC003F0001FFF8000001FFFE003
+E0001FFF8000000FFFE007E0FFFFFFFFF00007FFF007C0FFFFFFFFF00003FFFC1F80FFFFFFFFF0
+0001FFFFFF00FFFFFFFFF000007FFFFE00FFFFFFFFF000001FFFFC000000000000000000FFF000
+54487CC659>82 D<3FFFFFFFFFFFFFFFFF003FFFFFFFFFFFFFFFFF003FFFFFFFFFFFFFFFFF003F
+FFFFFFFFFFFFFFFF003FFFFFFFFFFFFFFFFF003FFF0003FFF8003FFF007FF80003FFF80007FF80
+7FE00003FFF80001FF807FC00003FFF80000FF807F800003FFF800007F807F000003FFF800003F
+807F000003FFF800003F807E000003FFF800001F807E000003FFF800001F807E000003FFF80000
+0F807C000003FFF800000F807C000003FFF800000F807C000003FFF800000F807C000003FFF800
+000F80FC000003FFF800000FC0F8000003FFF8000007C0F8000003FFF8000007C0F8000003FFF8
+000007C0F8000003FFF8000007C0F8000003FFF8000007C000000003FFF80000000000000003FF
+F80000000000000003FFF80000000000000003FFF80000000000000003FFF80000000000000003
+FFF80000000000000003FFF80000000000000003FFF80000000000000003FFF800000000000000
+03FFF80000000000000003FFF80000000000000003FFF80000000000000003FFF8000000000000
+0003FFF80000000000000003FFF80000000000000003FFF80000000000000003FFF80000000000
+000003FFF80000000000000003FFF80000000000000003FFF80000000000000003FFF800000000
+00000003FFF80000000000000003FFF80000000000000003FFF80000000000000003FFF8000000
+0000000003FFF80000000000000003FFF80000000000000003FFF80000000000000003FFF80000
+000000000003FFF80000000000000003FFF80000000000000003FFF80000000000000003FFF800
+00000000000003FFF80000000000000003FFF80000000000000003FFF80000000000000003FFF8
+0000000000000003FFF80000000000000003FFF80000000000000003FFF8000000000003FFFFFF
+FFFFF800000003FFFFFFFFFFF800000003FFFFFFFFFFF800000003FFFFFFFFFFF800000003FFFF
+FFFFFFF800004A467CC553>84 D<FFFFFFFFC03FFFFFFFF0001FFFFFF0FFFFFFFFC03FFFFFFFF0
+001FFFFFF0FFFFFFFFC03FFFFFFFF0001FFFFFF0FFFFFFFFC03FFFFFFFF0001FFFFFF0FFFFFFFF
+C03FFFFFFFF0001FFFFFF0007FFF0000001FFFE00000000FF800007FFF0000000FFFE000000003
+E000007FFF8000000FFFE000000007E000003FFF8000000FFFF000000007C000003FFFC0000007
+FFF000000007C000003FFFC0000007FFF80000000FC000001FFFC0000003FFF80000000F800000
+1FFFE0000003FFF80000001F8000000FFFE0000003FFFC0000001F0000000FFFE0000001FFFC00
+00001F0000000FFFF0000001FFFE0000003F00000007FFF0000001FFFE0000003E00000007FFF8
+000001FFFE0000007E00000003FFF8000003FFFF0000007C00000003FFF8000003FFFF0000007C
+00000003FFFC000003FFFF000000FC00000001FFFC000007FFFF800000F800000001FFFE000007
+FFFF800000F800000001FFFE000007FFFFC00001F800000000FFFE00000F9FFFC00001F0000000
+00FFFF00000F9FFFC00003F0000000007FFF00001F9FFFE00003E0000000007FFF00001F0FFFE0
+0003E0000000007FFF80001F0FFFE00007E0000000003FFF80003F0FFFF00007C0000000003FFF
+C0003E07FFF00007C0000000001FFFC0007E07FFF8000F80000000001FFFC0007C03FFF8000F80
+000000001FFFE0007C03FFF8001F80000000000FFFE000FC03FFFC001F00000000000FFFE000F8
+01FFFC001F00000000000FFFF000F801FFFE003F000000000007FFF001F801FFFE003E00000000
+0007FFF801F000FFFE007E000000000003FFF803F000FFFF007C000000000003FFF803E0007FFF
+007C000000000003FFFC03E0007FFF00FC000000000001FFFC07E0007FFF80F8000000000001FF
+FE07C0003FFF80F8000000000001FFFE0FC0003FFFC1F8000000000000FFFE0F80001FFFC1F000
+0000000000FFFF0F80001FFFC3F00000000000007FFF1F80001FFFE3E00000000000007FFF1F00
+000FFFE3E00000000000007FFF9F00000FFFF7E00000000000003FFFBF00000FFFF7C000000000
+00003FFFFE000007FFFFC00000000000001FFFFE000007FFFF800000000000001FFFFC000003FF
+FF800000000000001FFFFC000003FFFF800000000000000FFFFC000003FFFF000000000000000F
+FFF8000001FFFF000000000000000FFFF8000001FFFF0000000000000007FFF0000000FFFE0000
+000000000007FFF0000000FFFE0000000000000003FFF0000000FFFC0000000000000003FFE000
+00007FFC0000000000000003FFE00000007FFC0000000000000001FFE00000007FF80000000000
+000001FFC00000003FF80000000000000001FFC00000003FF80000000000000000FF800000001F
+F00000000000000000FF800000001FF000000000000000007F800000001FE00000000000000000
+7F000000000FE000000000000000007F000000000FE000000000000000003E0000000007C00000
+000074487DC67B>87 D<0007FFFC000000007FFFFFC0000001FFFFFFF8000003FFFFFFFE000007
+FE001FFF000007FF0003FFC0000FFF8001FFE0000FFF8000FFF0000FFF80007FF0000FFF80007F
+F8000FFF80007FF80007FF00003FFC0007FF00003FFC0003FE00003FFC0000F800003FFC000000
+00003FFC00000000003FFC00000000003FFC00000000003FFC00000007FFFFFC000000FFFFFFFC
+000007FFFFFFFC00003FFFE03FFC0000FFFE003FFC0003FFF0003FFC0007FFC0003FFC000FFF00
+003FFC001FFE00003FFC003FFC00003FFC007FF800003FFC007FF800003FFC00FFF000003FFC00
+FFF000003FFC00FFF000003FFC00FFF000003FFC00FFF000003FFC00FFF000007FFC007FF80000
+FFFC007FF80001EFFC003FFC0003EFFC003FFF0007CFFF000FFFC03F8FFFF807FFFFFF07FFFC01
+FFFFFC03FFFC007FFFF001FFFC0003FF80007FF8362E7DAD3A>97 D<007FC00000000000FFFFC0
+0000000000FFFFC00000000000FFFFC00000000000FFFFC00000000000FFFFC0000000000003FF
+C0000000000001FFC0000000000001FFC0000000000001FFC0000000000001FFC0000000000001
+FFC0000000000001FFC0000000000001FFC0000000000001FFC0000000000001FFC00000000000
+01FFC0000000000001FFC0000000000001FFC0000000000001FFC0000000000001FFC000000000
+0001FFC0000000000001FFC0000000000001FFC0000000000001FFC0000000000001FFC0000000
+000001FFC00FFC00000001FFC07FFFC0000001FFC3FFFFF0000001FFCFFFFFFC000001FFDFF00F
+FF000001FFFF8003FF800001FFFE0001FFC00001FFF800007FE00001FFF000007FF00001FFE000
+003FF80001FFE000001FFC0001FFE000001FFC0001FFE000001FFE0001FFE000001FFE0001FFE0
+00000FFF0001FFE000000FFF0001FFE000000FFF0001FFE000000FFF0001FFE000000FFF8001FF
+E000000FFF8001FFE000000FFF8001FFE000000FFF8001FFE000000FFF8001FFE000000FFF8001
+FFE000000FFF8001FFE000000FFF8001FFE000000FFF8001FFE000000FFF8001FFE000000FFF00
+01FFE000000FFF0001FFE000000FFF0001FFE000001FFE0001FFE000001FFE0001FFE000001FFC
+0001FFE000001FFC0001FFE000003FF80001FFF000003FF80001FFF800007FF00001FFFC0000FF
+E00001FFFE0001FFC00001FFBF0007FF800001FF1FE01FFE000001FE0FFFFFFC000001FC03FFFF
+F0000001F800FFFF80000001F0001FF800000039487CC742>I<00001FFFC0000000FFFFF80000
+07FFFFFE00001FFFFFFF80007FFC00FFC000FFE001FFC001FFC003FFE003FF8003FFE007FF0003
+FFE00FFE0003FFE00FFE0003FFE01FFC0001FFC01FFC0001FFC03FFC0000FF803FFC00003E007F
+F8000000007FF8000000007FF800000000FFF800000000FFF800000000FFF800000000FFF80000
+0000FFF800000000FFF800000000FFF800000000FFF800000000FFF800000000FFF8000000007F
+F8000000007FF8000000007FFC000000003FFC000000003FFC000000001FFC000000F81FFE0000
+00F80FFE000000F80FFF000001F007FF800003F003FFC00007E001FFE0000FC000FFF0001F8000
+7FFE00FF00001FFFFFFE000007FFFFF8000000FFFFE00000001FFE00002D2E7CAD35>I<000000
+00007FC00000000000FFFFC00000000000FFFFC00000000000FFFFC00000000000FFFFC0000000
+0000FFFFC0000000000003FFC0000000000001FFC0000000000001FFC0000000000001FFC00000
+00000001FFC0000000000001FFC0000000000001FFC0000000000001FFC0000000000001FFC000
+0000000001FFC0000000000001FFC0000000000001FFC0000000000001FFC0000000000001FFC0
+000000000001FFC0000000000001FFC0000000000001FFC0000000000001FFC0000000000001FF
+C0000000000001FFC00000000FFC01FFC0000000FFFF81FFC0000007FFFFE1FFC000001FFFFFF9
+FFC000007FFC03FFFFC00000FFF0007FFFC00001FFC0001FFFC00003FF80000FFFC00007FF0000
+07FFC0000FFE000003FFC0000FFE000003FFC0001FFC000003FFC0001FFC000003FFC0003FFC00
+0003FFC0003FFC000003FFC0007FF8000003FFC0007FF8000003FFC0007FF8000003FFC000FFF8
+000003FFC000FFF8000003FFC000FFF8000003FFC000FFF8000003FFC000FFF8000003FFC000FF
+F8000003FFC000FFF8000003FFC000FFF8000003FFC000FFF8000003FFC000FFF8000003FFC000
+7FF8000003FFC0007FF8000003FFC0007FF8000003FFC0003FF8000003FFC0003FFC000003FFC0
+003FFC000003FFC0001FFC000003FFC0001FFC000003FFC0000FFE000007FFC00007FF00000FFF
+C00003FF00001FFFC00001FFC0003FFFC00000FFE000FFFFE000007FF807FBFFFF80001FFFFFF3
+FFFF800007FFFFC3FFFF800001FFFF03FFFF8000001FF803FFFF8039487CC742>I<00001FFE00
+000001FFFFE0000007FFFFF800001FFFFFFE00007FFC07FF0000FFE001FF8001FFC0007FC003FF
+80003FE007FF00003FF00FFE00001FF01FFE00000FF81FFC00000FF83FFC00000FFC3FFC000007
+FC7FFC000007FC7FF8000007FC7FF8000007FE7FF8000007FEFFF8000007FEFFF8000007FEFFFF
+FFFFFFFEFFFFFFFFFFFEFFFFFFFFFFFEFFFFFFFFFFFCFFF800000000FFF800000000FFF8000000
+00FFF8000000007FF8000000007FF8000000007FFC000000003FFC000000003FFC000000003FFC
+0000001C1FFE0000003E0FFE0000003E07FF0000007E07FF000000FC03FF800001F801FFC00003
+F0007FF0001FE0003FFE00FFC0001FFFFFFF800007FFFFFE000000FFFFF80000000FFF80002F2E
+7DAD36>I<000000FFC000000007FFF80000003FFFFC000000FFFFFF000001FFC1FF000007FF03
+FF80000FFC03FF80000FF807FFC0001FF807FFC0003FF007FFC0003FF007FFC0003FE003FF8000
+7FE003FF80007FE001FF00007FE000FE00007FE0003800007FE0000000007FE0000000007FE000
+0000007FE0000000007FE0000000007FE0000000007FE0000000007FE0000000007FE000000000
+7FE0000000FFFFFFFE0000FFFFFFFE0000FFFFFFFE0000FFFFFFFE0000FFFFFFFE0000007FF000
+0000007FF0000000007FF0000000007FF0000000007FF0000000007FF0000000007FF000000000
+7FF0000000007FF0000000007FF0000000007FF0000000007FF0000000007FF0000000007FF000
+0000007FF0000000007FF0000000007FF0000000007FF0000000007FF0000000007FF000000000
+7FF0000000007FF0000000007FF0000000007FF0000000007FF0000000007FF0000000007FF000
+0000007FF0000000007FF0000000007FF0000000007FF0000000007FF0000000007FF000000000
+7FF0000000007FF0000000007FF00000003FFFFFF800003FFFFFF800003FFFFFF800003FFFFFF8
+00003FFFFFF800002A487DC724>I<00000000001F8000007FF000FFE00007FFFF03FFF0001FFF
+FFC7FFF0007FFFFFFFC7F800FFE03FFE0FF801FF800FFC0FF803FF0007FE0FF807FE0003FF07F0
+07FE0003FF07F00FFC0001FF81C00FFC0001FF80000FFC0001FF80001FFC0001FFC0001FFC0001
+FFC0001FFC0001FFC0001FFC0001FFC0001FFC0001FFC0001FFC0001FFC0000FFC0001FF80000F
+FC0001FF80000FFC0001FF800007FE0003FF000007FE0003FF000003FF0007FE000001FF800FFC
+000000FFE03FF8000001FFFFFFF0000001DFFFFFC0000003C7FFFF00000003C07FF000000007C0
+000000000007C0000000000007C0000000000007C0000000000007E0000000000007F000000000
+0007F8000000000007FFFFFFF0000007FFFFFFFF000003FFFFFFFFE00003FFFFFFFFF80001FFFF
+FFFFFE0001FFFFFFFFFF0000FFFFFFFFFF80007FFFFFFFFF8003FFFFFFFFFFC00FFFFFFFFFFFC0
+1FF800001FFFE03FE0000001FFE07FC00000007FF07FC00000003FF0FF800000001FF0FF800000
+001FF0FF800000001FF0FF800000001FF0FF800000001FF07FC00000003FE07FC00000003FE03F
+E00000007FC03FF0000000FFC01FFC000003FF800FFF00000FFF0003FFF000FFFC0000FFFFFFFF
+F000003FFFFFFFC0000007FFFFFE000000003FFFC0000035447DAE3B>I<00FC0001FE0003FF00
+07FF800FFFC01FFFE01FFFE01FFFE01FFFE01FFFE01FFFE00FFFC007FF8003FF0001FE0000FC00
+000000000000000000000000000000000000000000000000000000000000000000007FC0FFFFC0
+FFFFC0FFFFC0FFFFC0FFFFC003FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC0
+01FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC0
+01FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC0
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18497CC820>105 D<007FC000000000FFFFC000000000FF
+FFC000000000FFFFC000000000FFFFC000000000FFFFC00000000003FFC00000000001FFC00000
+000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FF
+C00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC0000000
+0001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC0
+0000000001FFC00000000001FFC0007FFFF801FFC0007FFFF801FFC0007FFFF801FFC0007FFFF8
+01FFC0007FFFF801FFC0000FFE0001FFC00007F00001FFC0000FE00001FFC0003FC00001FFC000
+7F800001FFC000FE000001FFC001FC000001FFC007F8000001FFC00FF0000001FFC01FC0000001
+FFC03F80000001FFC0FF00000001FFC1FE00000001FFC3FF00000001FFCFFF80000001FFDFFFC0
+000001FFFFFFC0000001FFFFFFE0000001FFFFFFF0000001FFFCFFF8000001FFF87FFC000001FF
+E03FFC000001FFC01FFE000001FFC01FFF000001FFC00FFF800001FFC007FFC00001FFC003FFC0
+0001FFC001FFE00001FFC001FFF00001FFC000FFF80001FFC0007FFC0001FFC0003FFC0001FFC0
+001FFE0001FFC0000FFF0001FFC0000FFF8001FFC0000FFFC0FFFFFF807FFFFFFFFFFF807FFFFF
+FFFFFF807FFFFFFFFFFF807FFFFFFFFFFF807FFFFF38487CC73F>107 D<007FC000FFFFC000FF
+FFC000FFFFC000FFFFC000FFFFC00003FFC00001FFC00001FFC00001FFC00001FFC00001FFC000
+01FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC0
+0001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FF
+C00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001
+FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC000
+01FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC0
+0001FFC00001FFC00001FFC00001FFC00001FFC00001FFC000FFFFFF80FFFFFF80FFFFFF80FFFF
+FF80FFFFFF8019487CC720>I<007FC001FFC00000FFE00000FFFFC00FFFF80007FFFC0000FFFF
+C03FFFFE001FFFFF0000FFFFC0FFFFFF007FFFFF8000FFFFC1FC07FF80FE03FFC000FFFFC3E003
+FFC1F001FFE00003FFC7C001FFC3E000FFE00001FFCF0001FFE78000FFF00001FFDE0000FFEF00
+007FF00001FFDC0000FFEE00007FF00001FFFC0000FFFE00007FF80001FFF80000FFFC00007FF8
+0001FFF00000FFF800007FF80001FFF00000FFF800007FF80001FFF00000FFF800007FF80001FF
+E00000FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF000007FF80001FFE00000
+FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF000
+007FF80001FFE00000FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF000007FF8
+0001FFE00000FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF000007FF80001FF
+E00000FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF000007FF80001FFE00000
+FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF000
+007FF80001FFE00000FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF000007FF8
+0001FFE00000FFF000007FF80001FFE00000FFF000007FF80001FFE00000FFF000007FF800FFFF
+FFC07FFFFFE03FFFFFF0FFFFFFC07FFFFFE03FFFFFF0FFFFFFC07FFFFFE03FFFFFF0FFFFFFC07F
+FFFFE03FFFFFF0FFFFFFC07FFFFFE03FFFFFF05C2E7CAD63>I<007FC001FFC00000FFFFC00FFF
+F80000FFFFC03FFFFE0000FFFFC0FFFFFF0000FFFFC1FC07FF8000FFFFC3E003FFC00003FFC7C0
+01FFC00001FFCF0001FFE00001FFDE0000FFE00001FFDC0000FFE00001FFFC0000FFF00001FFF8
+0000FFF00001FFF00000FFF00001FFF00000FFF00001FFF00000FFF00001FFE00000FFF00001FF
+E00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001
+FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF000
+01FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF0
+0001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FF
+F00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000
+FFF000FFFFFFC07FFFFFE0FFFFFFC07FFFFFE0FFFFFFC07FFFFFE0FFFFFFC07FFFFFE0FFFFFFC0
+7FFFFFE03B2E7CAD42>I<00000FFF0000000000FFFFF000000007FFFFFE0000001FFFFFFF8000
+003FFC03FFC00000FFE0007FF00001FF80001FF80003FF00000FFC0007FE000007FE000FFE0000
+07FF000FFC000003FF001FFC000003FF803FFC000003FFC03FF8000001FFC03FF8000001FFC07F
+F8000001FFE07FF8000001FFE07FF8000001FFE0FFF8000001FFF0FFF8000001FFF0FFF8000001
+FFF0FFF8000001FFF0FFF8000001FFF0FFF8000001FFF0FFF8000001FFF0FFF8000001FFF0FFF8
+000001FFF0FFF8000001FFF07FF8000001FFE07FF8000001FFE07FF8000001FFE07FF8000001FF
+E03FFC000003FFC03FFC000003FFC01FFC000003FF801FFE000007FF800FFE000007FF0007FF00
+000FFE0003FF80001FFC0001FFC0003FF80000FFE0007FF000007FFC03FFE000001FFFFFFF8000
+0007FFFFFE00000000FFFFF0000000000FFF000000342E7DAD3B>I<00FF803F8000FFFF80FFF0
+00FFFF83FFFC00FFFF87FFFE00FFFF8FC3FF00FFFF8F07FF0003FF9E0FFF8001FFBC0FFF8001FF
+B80FFF8001FFF80FFF8001FFF00FFF8001FFF007FF0001FFF007FF0001FFE003FE0001FFE000F8
+0001FFE000000001FFE000000001FFC000000001FFC000000001FFC000000001FFC000000001FF
+C000000001FFC000000001FFC000000001FFC000000001FFC000000001FFC000000001FFC00000
+0001FFC000000001FFC000000001FFC000000001FFC000000001FFC000000001FFC000000001FF
+C000000001FFC000000001FFC000000001FFC000000001FFC000000001FFC000000001FFC00000
+00FFFFFFE00000FFFFFFE00000FFFFFFE00000FFFFFFE00000FFFFFFE00000292E7CAD31>114
+D<000FFF00E0007FFFF3E001FFFFFFE007FFFFFFE00FF800FFE01FC0001FE03F80000FE03F0000
+07E07F000003E07F000003E0FF000003E0FF000003E0FF800003E0FFC0000000FFF0000000FFFE
+000000FFFFF800007FFFFFC0007FFFFFF0003FFFFFFC001FFFFFFF000FFFFFFF8007FFFFFFC003
+FFFFFFE000FFFFFFF0003FFFFFF00003FFFFF800001FFFF8000000FFFC0000001FFC7800000FFC
+F8000007FCF8000003FCFC000003FCFC000003FCFE000003F8FE000003F8FF000003F8FF800007
+F0FFC0000FF0FFF0001FE0FFFC00FFC0FFFFFFFF80FC7FFFFE00F81FFFF800E003FF8000262E7C
+AD2F>I<0001F000000001F000000001F000000001F000000001F000000001F000000003F00000
+0003F000000003F000000007F000000007F000000007F00000000FF00000000FF00000001FF000
+00003FF00000003FF00000007FF0000001FFF0000003FFF000000FFFFFFFC0FFFFFFFFC0FFFFFF
+FFC0FFFFFFFFC0FFFFFFFFC000FFF0000000FFF0000000FFF0000000FFF0000000FFF0000000FF
+F0000000FFF0000000FFF0000000FFF0000000FFF0000000FFF0000000FFF0000000FFF0000000
+FFF0000000FFF0000000FFF0000000FFF0000000FFF0000000FFF0000000FFF0000000FFF00000
+00FFF0000000FFF0000000FFF001F000FFF001F000FFF001F000FFF001F000FFF001F000FFF001
+F000FFF001F000FFF001F000FFF001F0007FF001E0007FF803E0003FF803E0003FFC07C0001FFE
+0F80000FFFFF800007FFFE000001FFFC0000001FF00024427EC12E>I<007FE000003FF000FFFF
+E0007FFFF000FFFFE0007FFFF000FFFFE0007FFFF000FFFFE0007FFFF000FFFFE0007FFFF00003
+FFE00001FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF000
+01FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF0
+0001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FF
+F00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000
+FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE00000FFF00001FFE000
+00FFF00001FFE00000FFF00001FFE00000FFF00001FFE00001FFF00001FFE00001FFF00001FFE0
+0001FFF00001FFE00003FFF00000FFE00007FFF00000FFE0000F7FF000007FE0001F7FF000007F
+F0003E7FF800003FFC00FC7FFFE0001FFFFFF87FFFE00007FFFFE07FFFE00001FFFF807FFFE000
+003FFE007FFFE03B2E7CAD42>I<FFFFFF07FFFFE007FFFEFFFFFF07FFFFE007FFFEFFFFFF07FF
+FFE007FFFEFFFFFF07FFFFE007FFFEFFFFFF07FFFFE007FFFE03FFC0001FFC00003FC003FFE000
+0FFC00001F8001FFE0000FFC00001F0001FFE0000FFE00001F0001FFF00007FE00003F0000FFF0
+000FFF00003E0000FFF8000FFF00007E00007FF8000FFF00007C00007FF8001FFF80007C00003F
+FC001FFF8000F800003FFC003FFFC000F800003FFE003EFFC001F800001FFE003EFFC001F00000
+1FFE007EFFE003F000000FFF007C7FE003E000000FFF00FC7FF003E000000FFF80F83FF007E000
+0007FF80F83FF007C0000007FF81F83FF80FC0000003FFC1F01FF80F80000003FFC3F01FFC0F80
+000003FFE3E00FFC1F80000001FFE3E00FFC1F00000001FFE7E00FFE3F00000000FFF7C007FE3E
+00000000FFFFC007FF3E00000000FFFF8003FF7E000000007FFF8003FF7C000000007FFF8003FF
+FC000000003FFF0001FFF8000000003FFF0001FFF8000000003FFE0000FFF8000000001FFE0000
+FFF0000000001FFE0000FFF0000000000FFC00007FE0000000000FFC00007FE0000000000FF800
+003FE00000000007F800003FC00000000007F800003FC00000000003F000001F800000000001E0
+00000F0000004F2E7DAD56>119 D<7FFFFF801FFFFF007FFFFF801FFFFF007FFFFF801FFFFF00
+7FFFFF801FFFFF007FFFFF801FFFFF00007FF80001FF0000007FFC0001FC0000003FFE0003F800
+00001FFF0007F00000000FFF0007E000000007FF800FC000000003FFC01F8000000003FFE03F80
+00000001FFF07F0000000000FFF8FE00000000007FF9FC00000000003FFFF800000000003FFFF0
+00000000001FFFE000000000000FFFC0000000000007FFC0000000000003FFC0000000000001FF
+E0000000000001FFF0000000000001FFF8000000000003FFFC000000000003FFFE000000000007
+FFFE00000000000FEFFF00000000001FCFFF80000000003F87FFC0000000007F03FFE000000000
+FE01FFE000000001FC00FFF000000001F8007FF800000003F0007FFC00000007F0003FFE000000
+0FE0001FFF0000001FC0000FFF0000003F800007FF800000FF800007FFC000FFFFF8003FFFFFC0
+FFFFF8003FFFFFC0FFFFF8003FFFFFC0FFFFF8003FFFFFC0FFFFF8003FFFFFC03A2E7EAD3F>I<
+7FFFFFC000FFFF807FFFFFC000FFFF807FFFFFC000FFFF807FFFFFC000FFFF807FFFFFC000FFFF
+8000FFF000000FE00000FFF800000FC00000FFF800000FC000007FFC00000F8000007FFC00001F
+8000003FFC00001F0000003FFE00003F0000001FFE00003E0000001FFF00007E0000000FFF0000
+7C0000000FFF8000FC00000007FF8000F800000007FFC001F800000003FFC001F000000003FFE0
+03F000000003FFE003F000000001FFF003E000000001FFF007E000000000FFF007C000000000FF
+F80FC0000000007FF80F80000000007FFC1F80000000003FFC1F00000000003FFE3F0000000000
+1FFE3E00000000001FFF7E00000000000FFF7C00000000000FFFFC00000000000FFFFC00000000
+0007FFF8000000000007FFF8000000000003FFF0000000000003FFF0000000000001FFE0000000
+000001FFE0000000000000FFC0000000000000FFC00000000000007F800000000000007F800000
+000000003F000000000000003F000000000000003F000000000000003E000000000000007E0000
+00000000007C00000000000000FC000000001F8000F8000000003FC001F8000000007FE001F000
+000000FFF003F000000000FFF003E000000000FFF007E000000000FFF00FC000000000FFF01F80
+00000000FFF03F80000000007FE07F00000000007F43FE00000000003FFFF800000000001FFFF0
+000000000007FFC0000000000001FE00000000000039427EAD3F>I E /Fq
+7 104 df<FFFFFF80FFFFFF8019027D8A20>0 D<0003FE0000000FFF8000003C01E00000F00078
+0001C0001C00030000060006000003000C0000018018000000C018000000C03000000060300000
+0060600000003060000000306000000030C000000018C000000018C000000018C000000018C000
+000018C000000018C000000018C000000018C00000001860000000306000000030600000003030
+00000060300000006018000000C018000000C00C000001800600000300030000060001C0001C00
+00F0007800003C01E000000FFF80000003FE000025277E9D2A>13 D<03C00FF01FF83FFC7FFE7F
+FEFFFFFFFFFFFFFFFF7FFE7FFE3FFC1FF80FF003C010107E9115>15 D<02000000000400000000
+0400000000080000000010000000002000000000FFFFFFFFF0FFFFFFFFF0200000000010000000
+000800000000040000000004000000000200000000240E7D902A>32 D<0000600000600000C000
+00C0000180000180000180000300000300000600000600000C00000C0000180000180000180000
+300000300000600000600000C00000C0000180000180000300000300000300000600000600000C
+00000C0000180000180000300000300000300000600000600000C0000040000013287A9D00>54
+D<003C00E001C00180038003800380038003800380038003800380038003800380038003000700
+1C00F0001C00070003000380038003800380038003800380038003800380038003800380018001
+C000E0003C0E297D9E15>102 D<F0001C00070003000380038003800380038003800380038003
+800380038003800380018001C000E0003C00E001C0018003800380038003800380038003800380
+03800380038003800380030007001C00F0000E297D9E15>I E /Fr 91 125
+df<007E1F0001C1B1800303E3C00703C3C00E03C1800E01C0000E01C0000E01C0000E01C0000E
+01C0000E01C000FFFFFC000E01C0000E01C0000E01C0000E01C0000E01C0000E01C0000E01C000
+0E01C0000E01C0000E01C0000E01C0000E01C0000E01C0000E01C0000E01C0000E01C0007F87FC
+001A1D809C18>11 D<007E0001C1800301800703C00E03C00E01800E00000E00000E00000E0000
+0E0000FFFFC00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C0
+0E01C00E01C00E01C00E01C00E01C07F87F8151D809C17>I<007FC001C1C00303C00703C00E01
+C00E01C00E01C00E01C00E01C00E01C00E01C0FFFFC00E01C00E01C00E01C00E01C00E01C00E01
+C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C07FCFF8151D809C17
+>I<003F07E00001C09C18000380F018000701F03C000E01E03C000E00E018000E00E000000E00
+E000000E00E000000E00E000000E00E00000FFFFFFFC000E00E01C000E00E01C000E00E01C000E
+00E01C000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C00
+0E00E01C000E00E01C000E00E01C000E00E01C000E00E01C007FC7FCFF80211D809C23>I<003F
+07FC0001C0DC1C000381F03C000701F03C000E01E01C000E00E01C000E00E01C000E00E01C000E
+00E01C000E00E01C000E00E01C00FFFFFFFC000E00E01C000E00E01C000E00E01C000E00E01C00
+0E00E01C000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C
+000E00E01C000E00E01C000E00E01C000E00E01C007FC7FCFF80211D809C23>I<60F0F0F0F0F0
+F0F060606060606060606060606060000000000060F0F060041E7C9D0C>33
+D<6060F0F0F8F86868080808080808101010102020404080800D0C7F9C15>I<0080008007E018
+98308460824081C087C08FC08FC086E080F0807E803FC01FF00FF803FC00BE008E00876087F083
+F083E0838082408240842088189007E00080008010217E9E15>36 D<00E0000001900000030800
+0003080000070800000708000007080000070800000710000007100000072000000740000003C0
+3FE003800F00038006000380040005C0040009C0080010E0100030E010006070200060702000E0
+384000E03C4000E01C8000E00F0020E0070020700780403009C0401830E18007C03E001B1F7E9D
+20>38 D<60F0F8680808081010204080050C7C9C0C>I<004000800100020006000C000C001800
+1800300030007000600060006000E000E000E000E000E000E000E000E000E000E000E000E00060
+0060006000700030003000180018000C000C00060002000100008000400A2A7D9E10>I<800040
+002000100018000C000C000600060003000300038001800180018001C001C001C001C001C001C0
+01C001C001C001C001C001C0018001800180038003000300060006000C000C0018001000200040
+0080000A2A7E9E10>I<0006000000060000000600000006000000060000000600000006000000
+0600000006000000060000000600000006000000060000FFFFFFE0FFFFFFE00006000000060000
+000600000006000000060000000600000006000000060000000600000006000000060000000600
+00000600001B1C7E9720>43 D<60F0F0701010101020204080040C7C830C>I<FFE0FFE00B0280
+890E>I<60F0F06004047C830C>I<00010003000600060006000C000C000C001800180018003000
+3000300060006000C000C000C0018001800180030003000300060006000C000C000C0018001800
+1800300030003000600060006000C000C00010297E9E15>I<03C00C301818300C300C700E6006
+6006E007E007E007E007E007E007E007E007E007E007E007E007E00760066006700E300C300C18
+180C3007E0101D7E9B15>I<030007003F00C70007000700070007000700070007000700070007
+000700070007000700070007000700070007000700070007000F80FFF80D1C7C9B15>I<07C018
+30201C400C400EF00FF80FF807F8077007000F000E000E001C001C00380070006000C001800300
+06010C01180110023FFE7FFEFFFE101C7E9B15>I<07E01830201C201C781E780E781E381E001C
+001C00180030006007E00030001C001C000E000F000F700FF80FF80FF80FF00E401C201C183007
+E0101D7E9B15>I<000C00000C00001C00003C00003C00005C0000DC00009C00011C00031C0002
+1C00041C000C1C00081C00101C00301C00201C00401C00C01C00FFFFC0001C00001C00001C0000
+1C00001C00001C00001C0001FFC0121C7F9B15>I<300C3FF83FF03FC020002000200020002000
+200023E024302818301C200E000E000F000F000F600FF00FF00FF00F800E401E401C2038187007
+C0101D7E9B15>I<00F0030C06040C0E181E301E300C700070006000E3E0E430E818F00CF00EE0
+06E007E007E007E007E007600760077006300E300C18180C3003E0101D7E9B15>I<4000007FFF
+807FFF007FFF0040020080040080040080080000100000100000200000600000400000C00000C0
+0001C0000180000180000380000380000380000380000780000780000780000780000780000780
+00030000111D7E9B15>I<03E00C301008200C20066006600660067006780C3E083FB01FE007F0
+07F818FC307E601E600FC007C003C003C003C00360026004300C1C1007E0101D7E9B15>I<03C0
+0C301818300C700C600EE006E006E007E007E007E007E0076007700F300F18170C2707C7000600
+06000E300C780C78187010203030C00F80101D7E9B15>I<60F0F0600000000000000000000060
+F0F06004127C910C>I<60F0F0600000000000000000000060F0F0701010101020204080041A7C
+910C>I<60F0F060000000000060606060606060606060606060F0F0F0F0F0F0F060041E7C940C>
+I<7FFFFFC0FFFFFFE0000000000000000000000000000000000000000000000000000000000000
+0000FFFFFFE07FFFFFC01B0C7E8F20>I<03000780078003000000000000000000000001000100
+0200020002000200060004000C00180038007000E000E01EE01EE01EE00E600430180FE00F1D7E
+9414>I<0FE03038401CE00EF00EF00EF00E000C001C0030006000C00080018001000100010001
+00010001000000000000000000000003000780078003000F1D7E9C14>I<003F800000C0600003
+001800040004000800020010000100201F00802070808040E0404040C0384041C0384081803820
+83803820838038208380382083803820838038208180382041C0382040C0384040E07840207098
+80201F0F00100000000800000004000000030001E000C01F80003FF0001B1D7E9C20>I<000600
+000006000000060000000F0000000F0000000F00000017800000178000001780000023C0000023
+C0000023C0000041E0000041E0000041E0000080F0000080F0000180F8000100780001FFF80003
+007C0002003C0002003C0006003E0004001E0004001E000C001F001E001F00FF80FFF01C1D7F9C
+1F>I<FFFFC00F00F00F00380F003C0F001C0F001E0F001E0F001E0F001E0F001C0F003C0F0078
+0F01F00FFFE00F00780F003C0F001E0F000E0F000F0F000F0F000F0F000F0F000F0F001E0F001E
+0F003C0F0078FFFFE0181C7E9B1D>I<001F808000E0618001801980070007800E0003801C0003
+801C00018038000180780000807800008070000080F0000000F0000000F0000000F0000000F000
+0000F0000000F0000000F0000000700000807800008078000080380000801C0001001C0001000E
+000200070004000180080000E03000001FC000191E7E9C1E>I<FFFFC0000F00F0000F003C000F
+000E000F0007000F0007000F0003800F0003C00F0001C00F0001C00F0001E00F0001E00F0001E0
+0F0001E00F0001E00F0001E00F0001E00F0001E00F0001C00F0001C00F0003C00F0003800F0007
+800F0007000F000E000F001C000F007000FFFFC0001B1C7E9B20>I<FFFFFC0F003C0F000C0F00
+040F00040F00060F00020F00020F02020F02000F02000F02000F06000FFE000F06000F02000F02
+000F02000F02010F00010F00020F00020F00020F00060F00060F000C0F003CFFFFFC181C7E9B1C
+>I<FFFFF80F00780F00180F00080F00080F000C0F00040F00040F02040F02000F02000F02000F
+06000FFE000F06000F02000F02000F02000F02000F00000F00000F00000F00000F00000F00000F
+00000F8000FFF800161C7E9B1B>I<001F808000E0618001801980070007800E0003801C000380
+1C00018038000180780000807800008070000080F0000000F0000000F0000000F0000000F00000
+00F0000000F000FFF0F0000F80700007807800078078000780380007801C0007801C0007800E00
+078007000B800180118000E06080001F80001C1E7E9C21>I<FFF3FFC00F003C000F003C000F00
+3C000F003C000F003C000F003C000F003C000F003C000F003C000F003C000F003C000F003C000F
+FFFC000F003C000F003C000F003C000F003C000F003C000F003C000F003C000F003C000F003C00
+0F003C000F003C000F003C000F003C00FFF3FFC01A1C7E9B1F>I<FFF00F000F000F000F000F00
+0F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F
+000F00FFF00C1C7F9B0F>I<1FFF00F80078007800780078007800780078007800780078007800
+7800780078007800780078007800787078F878F878F878F0F040E021C01F00101D7F9B15>I<FF
+F03FE00F000F000F000C000F0008000F0010000F0020000F0040000F0080000F0100000F020000
+0F0400000F0E00000F1F00000F2F00000F2780000F4780000F83C0000F01E0000F01E0000F00F0
+000F00F8000F0078000F003C000F003C000F001E000F001F000F001F80FFF07FF01C1C7E9B20>
+I<FFF8000F80000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00
+000F00000F00000F00000F00000F00000F00080F00080F00080F00180F00180F00100F00300F00
+700F01F0FFFFF0151C7E9B1A>I<FF8000FF800F8000F8000F8000F8000BC00178000BC0017800
+0BC001780009E002780009E002780008F004780008F004780008F0047800087808780008780878
+000878087800083C107800083C107800083C107800081E207800081E207800081E207800080F40
+7800080F40780008078078000807807800080780780008030078001C03007800FF8307FF80211C
+7E9B26>I<FF007FC00F800E000F8004000BC0040009E0040009E0040008F0040008F804000878
+0400083C0400083C0400081E0400080F0400080F0400080784000807C4000803C4000801E40008
+01E4000800F40008007C0008007C0008003C0008003C0008001C0008000C001C000C00FF800400
+1A1C7E9B1F>I<003F800000E0E0000380380007001C000E000E001C0007003C00078038000380
+780003C0780003C0700001C0F00001E0F00001E0F00001E0F00001E0F00001E0F00001E0F00001
+E0F00001E0700001C0780003C0780003C0380003803C0007801C0007000E000E0007001C000380
+380000E0E000003F80001B1E7E9C20>I<FFFF800F00E00F00780F003C0F001C0F001E0F001E0F
+001E0F001E0F001E0F001C0F003C0F00780F00E00FFF800F00000F00000F00000F00000F00000F
+00000F00000F00000F00000F00000F00000F0000FFF000171C7E9B1C>I<003F800000E0E00003
+80380007001C000E000E001C0007003C00078038000380780003C0780003C0700001C0F00001E0
+F00001E0F00001E0F00001E0F00001E0F00001E0F00001E0F00001E0700001C0780003C0780003
+C0380003803C0E07801C1107000E208E000720DC0003A0F80000F0E020003FE020000060200000
+7060000078E000003FC000003FC000001F8000000F001B257E9C20>I<FFFF00000F01E0000F00
+78000F003C000F001C000F001E000F001E000F001E000F001E000F001C000F003C000F0078000F
+01E0000FFF00000F03C0000F00E0000F00F0000F0078000F0078000F0078000F0078000F007800
+0F0078000F0078100F0078100F0038100F003C20FFF01C20000007C01C1D7E9B1F>I<07E0801C
+1980300580700380600180E00180E00080E00080E00080F00000F800007C00007FC0003FF8001F
+FE0007FF0000FF80000F800007C00003C00001C08001C08001C08001C0C00180C00180E00300D0
+0200CC0C0083F800121E7E9C17>I<7FFFFFC0700F01C0600F00C0400F0040400F0040C00F0020
+800F0020800F0020800F0020000F0000000F0000000F0000000F0000000F0000000F0000000F00
+00000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F
+0000001F800003FFFC001B1C7F9B1E>I<FFF07FC00F000E000F0004000F0004000F0004000F00
+04000F0004000F0004000F0004000F0004000F0004000F0004000F0004000F0004000F0004000F
+0004000F0004000F0004000F0004000F0004000F0004000F000400070008000780080003801000
+0180100000C020000070C000001F00001A1D7E9B1F>I<FFE00FF01F0003C00F0001800F000100
+0F800300078002000780020003C0040003C0040003C0040001E0080001E0080001F0080000F010
+0000F0100000F830000078200000782000003C4000003C4000003C4000001E8000001E8000001F
+8000000F0000000F00000006000000060000000600001C1D7F9B1F>I<FFE0FFE0FF1F001F003C
+1E001E00180F001F00100F001F00100F001F001007801F00200780278020078027802003C02780
+4003C043C04003C043C04003E043C04001E081E08001E081E08001E081E08000F100F10000F100
+F10000F100F100007900FA00007A007A00007A007A00003E007C00003C003C00003C003C00003C
+003C00001800180000180018000018001800281D7F9B2B>I<7FF0FFC00FC03E000780180003C0
+180003E0100001E0200001F0600000F0400000788000007D8000003D0000001E0000001F000000
+0F0000000F8000000F80000013C0000023E0000021E0000041F00000C0F8000080780001007C00
+03003C0002001E0006001F001F003F80FFC0FFF01C1C7F9B1F>I<FFF007FC0F8001E007800080
+07C0018003C0010003E0020001F0020000F0040000F8040000780800007C1800003C1000001E20
+00001F2000000F4000000FC0000007800000078000000780000007800000078000000780000007
+800000078000000780000007800000078000007FF8001E1C809B1F>I<7FFFF07C01F07001E060
+03C06003C0400780400F80400F00401E00001E00003C00007C0000780000F00000F00001E00003
+E00003C0100780100780100F00101F00301E00203C00203C00607800E0F803E0FFFFE0141C7E9B
+19>I<FEFEC0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0
+C0C0C0FEFE07297C9E0C>I<08081010202040404040808080808080B0B0F8F8787830300D0C7A
+9C15>I<FEFE060606060606060606060606060606060606060606060606060606060606060606
+06060606FEFE0729809E0C>I<1FC000307000783800781C00301C00001C00001C0001FC000F1C
+00381C00701C00601C00E01C40E01C40E01C40603C40304E801F870012127E9115>97
+D<FC00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C7C001D86
+001E03001C01801C01C01C00C01C00E01C00E01C00E01C00E01C00E01C00E01C00C01C01C01C01
+801E030019060010F800131D7F9C17>I<07E00C301878307870306000E000E000E000E000E000
+E00060007004300418080C3007C00E127E9112>I<003F00000700000700000700000700000700
+00070000070000070000070000070003E7000C1700180F00300700700700600700E00700E00700
+E00700E00700E00700E00700600700700700300700180F000C370007C7E0131D7E9C17>I<03E0
+0C301818300C700E6006E006FFFEE000E000E000E00060007002300218040C1803E00F127F9112
+>I<00F8018C071E061E0E0C0E000E000E000E000E000E00FFE00E000E000E000E000E000E000E
+000E000E000E000E000E000E000E000E000E007FE00F1D809C0D>I<00038003C4C00C38C01C38
+80181800381C00381C00381C00381C001818001C38000C300013C0001000003000001800001FF8
+001FFF001FFF803003806001C0C000C0C000C0C000C06001803003001C0E0007F800121C7F9215
+>I<FC00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C7C001C
+87001D03001E03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C
+03801C03801C0380FF9FF0141D7F9C17>I<18003C003C00180000000000000000000000000000
+00FC001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C00FF80091D
+7F9C0C>I<00C001E001E000C000000000000000000000000000000FE000E000E000E000E000E0
+00E000E000E000E000E000E000E000E000E000E000E000E000E000E000E060E0F0C0F1C061803E
+000B25839C0D>I<FC00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C
+00001C3FC01C0F001C0C001C08001C10001C20001C40001CE0001DE0001E70001C78001C38001C
+3C001C1C001C0E001C0F001C0F80FF9FE0131D7F9C16>I<FC001C001C001C001C001C001C001C
+001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C00
+1C00FF80091D7F9C0C>I<FC7E07E0001C838838001D019018001E01E01C001C01C01C001C01C0
+1C001C01C01C001C01C01C001C01C01C001C01C01C001C01C01C001C01C01C001C01C01C001C01
+C01C001C01C01C001C01C01C001C01C01C00FF8FF8FF8021127F9124>I<FC7C001C87001D0300
+1E03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C0380
+1C0380FF9FF014127F9117>I<03F0000E1C00180600300300700380600180E001C0E001C0E001
+C0E001C0E001C0E001C06001807003803003001806000E1C0003F00012127F9115>I<FC7C001D
+86001E03001C01801C01C01C00C01C00E01C00E01C00E01C00E01C00E01C00E01C01C01C01C01C
+01801E03001D06001CF8001C00001C00001C00001C00001C00001C00001C0000FF8000131A7F91
+17>I<03C1000C3300180B00300F00700700700700E00700E00700E00700E00700E00700E00700
+600700700700300F00180F000C370007C700000700000700000700000700000700000700000700
+003FE0131A7E9116>I<FCE01D301E781E781C301C001C001C001C001C001C001C001C001C001C
+001C001C00FFC00D127F9110>I<1F9030704030C010C010E010F8007F803FE00FF000F8803880
+18C018C018E010D0608FC00D127F9110>I<04000400040004000C000C001C003C00FFE01C001C
+001C001C001C001C001C001C001C001C101C101C101C101C100C100E2003C00C1A7F9910>I<FC
+1F801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C
+03801C07800C07800E1B8003E3F014127F9117>I<FF07E03C03801C01001C01000E02000E0200
+07040007040007040003880003880003D80001D00001D00000E00000E00000E00000400013127F
+9116>I<FF3FCFE03C0F03801C0701801C0701001C0B01000E0B82000E0B82000E1182000711C4
+000711C4000720C40003A0E80003A0E80003C0680001C0700001C0700001803000008020001B12
+7F911E>I<7F8FF00F03800F030007020003840001C80001D80000F00000700000780000F80000
+9C00010E00020E000607000403801E07C0FF0FF81512809116>I<FF07E03C03801C01001C0100
+0E02000E020007040007040007040003880003880003D80001D00001D00000E00000E00000E000
+004000004000008000008000F08000F10000F300006600003C0000131A7F9116>I<7FFC703860
+38407040F040E041C003C0038007000F040E041C043C0C380870087038FFF80E127F9112>I<FF
+FFF01401808B15>I<FFFFFFFFFF802901808B2A>I E /Fs 20 122 df<78FCFCFCFC7806067B85
+11>46 D<007F000001C1C0000780F0000F0078000E0038001C001C003C001E003C001E003C001E
+0078000F0078000F0078000F0078000F00F8000F80F8000F80F8000F80F8000F80F8000F80F800
+0F80F8000F80F8000F80F8000F80F8000F80F8000F80F8000F80F8000F80F8000F80F8000F8078
+000F0078000F0078000F0078000F003C001E003C001E003C001E001C001C000E0038000F007800
+0780F00001C1C000007F000019297EA71E>48 D<00100000700001F0000FF000FEF000F0F00000
+F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000
+F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000
+F00000F00000F00000F00000F00001F8007FFFE07FFFE013287BA71E>I<00FE0007FF800E07E0
+1803F02001F82000F840007C40007CF8007EFC007EFC003EFC003EFC003E78007E00007E00007C
+00007C0000F80000F80001F00001E00003C0000780000700000E00001C00003800007000006000
+00C0000180020300020600040C000418000410000C3FFFFC7FFFF8FFFFF8FFFFF817287DA71E>
+I<007F000003FFC0000701F0000C00F80010007C001C007C003E007E003E003E003E003E001E00
+3E000C007E0000007C0000007C00000078000000F0000000E0000001C0000007000000FF000000
+01E0000000F0000000780000003C0000003E0000001F0000001F0000001F8000001F8030001F80
+78001F80FC001F80FC001F80FC001F00F8001F0040003F0040003E0030007C001800F8000F01F0
+0003FFC000007F000019297EA71E>I<007F000001FFC00007C1E0000F0070001E0038001C003C
+003C001C0078001E0078001E00F8000F00F8000F00F8000F00F8000F00F8000F80F8000F80F800
+0F80F8000F8078000F8078001F803C001F803C001F801C002F800E004F800700CF8003810F8000
+7E0F8000000F0000000F0000000F0000001E0000001E0000001E0000003C001C003C003E007800
+3E0070003C00E0001801C0001C0780000FFE000003F8000019297EA71E>57
+D<FFFFFFFF00FFFFFFFF0007E0003F0003E000070003E000038003E000018003E000018003E000
+008003E000008003E000008003E000008003E000004003E002004003E002004003E002000003E0
+02000003E002000003E006000003E00E000003FFFE000003FFFE000003E00E000003E006000003
+E002000003E002000003E002000003E002000003E002000003E000000003E000000003E0000000
+03E000000003E000000003E000000003E000000003E000000003E000000003E000000007F00000
+00FFFFE00000FFFFE0000022297EA827>70 D<FFE0000003FFC0FFE0000003FFC007E0000003F8
+0002F0000005F00002F0000005F0000278000009F0000278000009F0000278000009F000023C00
+0011F000023C000011F000021E000021F000021E000021F000021E000021F000020F000041F000
+020F000041F0000207800081F0000207800081F0000207800081F0000203C00101F0000203C001
+01F0000203E00201F0000201E00201F0000201E00201F0000200F00401F0000200F00401F00002
+00F00401F0000200780801F0000200780801F00002003C1001F00002003C1001F00002003C1001
+F00002001E2001F00002001E2001F00002000F4001F00002000F4001F00002000F4001F0000200
+078001F0000700078001F0000F80030003F800FFF803007FFFC0FFF803007FFFC032297EA837>
+77 D<FFFF0003FFC0FFFF0003FFC007F000007E0003E00000380003E00000100001F000002000
+01F00000200001F00000200000F80000400000F80000400000FC0000C000007C00008000007C00
+008000003E00010000003E00010000003F00010000001F00020000001F00020000001F80060000
+000F80040000000F800400000007C00800000007C00800000007E00800000003E01000000003E0
+1000000001F02000000001F02000000001F02000000000F84000000000F84000000000FCC00000
+00007C80000000007C80000000003F00000000003F00000000003F00000000001E00000000001E
+00000000000C00000000000C00000000000C0000002A2A7FA82D>86 D<FFFE03FFF803FFC0FFFE
+03FFF803FFC00FE0003F80007E0007C0001F0000180003E0001F0000180003E0000F8000100003
+E0000F8000100001F0000F8000200001F0000FC000200001F0000FC000200000F8000FC0004000
+00F80013E000400000F80013E000400000FC0013E000C000007C0033F0008000007C0021F00080
+00007E0021F0008000003E0021F8010000003E0040F8010000003E0040F8010000001F0040F802
+0000001F00807C020000001F00807C020000000F80807C040000000F81003E040000000F81003E
+0400000007C1003E0800000007C2001F0800000007C2001F0800000003E2001F1000000003E400
+0F9000000003E4000F9000000001F4000FA000000001F80007E000000001F80007E000000000F8
+0007C000000000F00003C000000000F00003C00000000070000380000000006000018000000000
+60000180000000006000018000003A2A7FA83D>I<01FC00000E0780001001C0003C00E0003E00
+F0003E0078001C00780008007800000078000000780000007800007FF80003E078000F8078001F
+0078003E0078007C00780078007820F8007820F8007820F8007820F800F8207C00F8203C013C40
+1F063FC007F80F001B1A7E991E>97 D<07800000FF800000FF8000000F80000007800000078000
+000780000007800000078000000780000007800000078000000780000007800000078000000780
+00000783F000078C1C0007B0070007A0038007C003C0078001E0078001E0078000F0078000F007
+8000F8078000F8078000F8078000F8078000F8078000F8078000F8078000F0078000F0078001F0
+078001E0078001C007C003C00740078007200E0006181C000407E0001D2A7FA921>I<007E0003
+C3800700E00E00F01C00703C00783C003878003C78003CF8003CF8003CFFFFFCF80000F80000F8
+0000F80000F800007800007C00003C00043C00041E00080E001007002001C0C0007F00161A7E99
+1B>101 D<001F000070C000E1E001C3E003C3E00381C007808007800007800007800007800007
+8000078000078000078000078000FFFE00FFFE0007800007800007800007800007800007800007
+800007800007800007800007800007800007800007800007800007800007800007800007800007
+800007800007C000FFFE00FFFE00132A7FA912>I<0780FF80FF800F8007800780078007800780
+078007800780078007800780078007800780078007800780078007800780078007800780078007
+8007800780078007800780078007800780078007800780FFFCFFFC0E2A7FA911>108
+D<0783F800FF8C1C00FF900E000FA0070007A0078007C0078007C0078007800780078007800780
+078007800780078007800780078007800780078007800780078007800780078007800780078007
+80078007800780078007800780078007800780FFFCFFFCFFFCFFFC1E1A7F9921>110
+D<007F000001C1C000070070000E0038001C001C003C001E003C001E0078000F0078000F00F800
+0F80F8000F80F8000F80F8000F80F8000F80F8000F80F8000F80F8000F8078000F0078000F003C
+001E003C001E001E003C000E0038000700700001C1C000007F0000191A7E991E>I<0787C0FF98
+E0FF91F00FA1F007C1F007C0E007C0000780000780000780000780000780000780000780000780
+0007800007800007800007800007800007800007800007800007C000FFFE00FFFE00141A7F9917
+>114 D<07800780FF80FF80FF80FF800F800F8007800780078007800780078007800780078007
+800780078007800780078007800780078007800780078007800780078007800780078007800780
+07800780078007800F8007800F800380178001C027C000E047FC003F87FC1E1A7F9921>117
+D<FFF00FF8FFF00FF80F8003C0078003800780010003C0020003C0020003E0020001E0040001E0
+040000F0080000F0080000F818000078100000781000003C2000003C2000003E6000001E400000
+1E4000000F8000000F800000070000000700000007000000020000000200000004000000040000
+000400000008000070080000F8100000F8100000F8200000F0400000608000001F0000001D267F
+9920>121 D E /Ft 10 116 df<78FCFCFCFC7806067A8512>46 D<FFE00007FFC0FFF00007FF
+C003F000007C0002F80000380002FC00001000027C00001000023E00001000023E00001000021F
+00001000021F80001000020F800010000207C00010000207E00010000203E00010000203F00010
+000201F00010000200F80010000200FC00100002007C00100002007E00100002003E0010000200
+1F00100002001F80100002000F80100002000FC01000020007C01000020003E01000020003F010
+00020001F01000020000F81000020000F810000200007C10000200007E10000200003E10000200
+001F10000200001F10000200000F90000200000FD00002000007D00002000003F00002000003F0
+0002000001F00002000001F00002000000F0000200000070000700000070000F8000003000FFF8
+00003000FFF8000010002A317CB032>78 D<FFFFFF000000FFFFFFF0000007E001FC000003E000
+3E000003E0000F800003E00007C00003E00003E00003E00001E00003E00001F00003E00000F000
+03E00000F80003E00000F80003E00000F80003E00000F80003E00000F80003E00000F80003E000
+00F00003E00001F00003E00001E00003E00003C00003E00007800003E0000F000003E0003C0000
+03E001F0000003FFFF00000003E001F0000003E0007C000003E0001E000003E0000F800003E000
+07800003E00007C00003E00003E00003E00003E00003E00003E00003E00003E00003E00003E000
+03E00003E00003E00003E00003E00003E00003E00003E00003E00003E00003E00003E00003E000
+03E00803E00003E00803E00001E00803E00001E00807F00000F010FFFF80007010FFFF80003860
+000000000F802D327CB031>82 D<FFFE003FFF8001FFC0FFFE003FFF8001FFC00FE00003F80000
+7E0007C00001F000003C0007C00001F00000180003E00000F80000100003E00000F80000100003
+E00000F80000100001F00000FC0000200001F00000FC0000200001F00000FC0000200000F80001
+3E0000400000F800013E0000400000F800013E0000400000FC00033F0000C000007C00021F0000
+8000007C00021F00008000007E00021F80008000003E00040F80010000003E00040F8001000000
+3E00040F80010000001F000807C0020000001F000807C0020000001F000807C0020000000F8010
+03E0040000000F801003E0040000000F801003E0040000000FC02001F00C00000007C02001F008
+00000007C02001F00800000007E02001F80800000003E04000F81000000003E04000F810000000
+03E04000F81000000001F080007C2000000001F080007C2000000001F080007C2000000000F900
+003E4000000000F900003E4000000000F900003E40000000007E00001F80000000007E00001F80
+000000007E00001F80000000007E00001F80000000003C00000F00000000003C00000F00000000
+003C00000F00000000001800000600000000001800000600000000001800000600000042327FB0
+44>87 D<00FE00000303C0000C00E00010007000100038003C003C003E001C003E001E003E001E
+0008001E0000001E0000001E0000001E00000FFE0000FC1E0003E01E000F801E001F001E003E00
+1E003C001E007C001E00F8001E04F8001E04F8001E04F8003E04F8003E0478003E047C005E043E
+008F080F0307F003FC03E01E1F7D9E21>97 D<0F001F801F801F801F800F000000000000000000
+00000000000000000000000000000780FF80FF800F800780078007800780078007800780078007
+800780078007800780078007800780078007800780078007800780078007800FC0FFF8FFF80D30
+7EAF12>105 D<0780FF80FF800F80078007800780078007800780078007800780078007800780
+078007800780078007800780078007800780078007800780078007800780078007800780078007
+80078007800780078007800780078007800780078007800FC0FFFCFFFC0E327EB112>108
+D<0780FE001FC000FF83078060F000FF8C03C18078000F9001E2003C0007A001E4003C0007A000
+F4001E0007C000F8001E0007C000F8001E00078000F0001E00078000F0001E00078000F0001E00
+078000F0001E00078000F0001E00078000F0001E00078000F0001E00078000F0001E00078000F0
+001E00078000F0001E00078000F0001E00078000F0001E00078000F0001E00078000F0001E0007
+8000F0001E00078000F0001E00078000F0001E00078000F0001E00078000F0001E00078000F000
+1E000FC001F8003F00FFFC1FFF83FFF0FFFC1FFF83FFF0341F7E9E38>I<001FC00000F0780001
+C01C00070007000F0007801E0003C01C0001C03C0001E03C0001E0780000F0780000F0780000F0
+F80000F8F80000F8F80000F8F80000F8F80000F8F80000F8F80000F8F80000F8780000F07C0001
+F03C0001E03C0001E01E0003C01E0003C00F00078007800F0001C01C0000F07800001FC0001D1F
+7E9E21>111 D<01FC100E03301800F0300070600030E00030E00010E00010E00010F00010F800
+007E00003FF0001FFF000FFFC003FFE0003FF00001F80000F880003C80003C80001CC0001CC000
+1CE0001CE00018F00038F00030CC0060C301C080FE00161F7E9E1A>115
+D E /Fu 13 118 df<1F003F807FC0FFC0FFE0FFE0FFF0FFF07FF03FB01F300030003000300030
+003000600060006000C000C000C0018001800300060006000C001800300020000C1F77C71D>39
+D<FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00007FF800001FFF00003FF0000001
+FF80001FF00000007F80001FF00000003F80001FF00000001F80001FF00000000F80001FF00000
+000780001FF00000000780001FF00000000380001FF000000003C0001FF000000003C0001FF000
+000001C0001FF000000001C0001FF000000001C0001FF000000001C0001FF000000001C0001FF0
+00000000E0001FF000000000E0001FF000000000E0001FF00001C000E0001FF00001C00000001F
+F00001C00000001FF00001C00000001FF00001C00000001FF00001C00000001FF00001C0000000
+1FF00003C00000001FF00003C00000001FF00007C00000001FF0000FC00000001FF0003FC00000
+001FFFFFFFC00000001FFFFFFFC00000001FFFFFFFC00000001FF0003FC00000001FF0000FC000
+00001FF00007C00000001FF00003C00000001FF00003C00000001FF00001C00000001FF00001C0
+0000001FF00001C00000001FF00001C00000001FF00001C00000001FF00001C00000001FF00001
+C00000001FF00000000000001FF00000000000001FF00000000000001FF00000000000001FF000
+00000000001FF00000000000001FF00000000000001FF00000000000001FF00000000000001FF0
+0000000000001FF00000000000001FF00000000000001FF00000000000001FF00000000000001F
+F00000000000001FF00000000000001FF00000000000003FF80000000000007FFE0000000000FF
+FFFFFF80000000FFFFFFFF80000000FFFFFFFF800000003B477DC643>70
+D<FFFFF800000000001FFFFFFFFFF800000000001FFFFFFFFFF800000000001FFFFF007FFC0000
+0000003FFE00003FFC00000000003FFC00001DFE000000000077F800001DFE000000000077F800
+001DFE000000000077F800001CFF0000000000E7F800001CFF0000000000E7F800001C7F800000
+0001C7F800001C7F8000000001C7F800001C7F8000000001C7F800001C3FC00000000387F80000
+1C3FC00000000387F800001C1FE00000000707F800001C1FE00000000707F800001C1FE0000000
+0707F800001C0FF00000000E07F800001C0FF00000000E07F800001C0FF00000000E07F800001C
+07F80000001C07F800001C07F80000001C07F800001C03FC0000003807F800001C03FC00000038
+07F800001C03FC0000003807F800001C01FE0000007007F800001C01FE0000007007F800001C00
+FF000000E007F800001C00FF000000E007F800001C00FF000000E007F800001C007F800001C007
+F800001C007F800001C007F800001C007F800001C007F800001C003FC000038007F800001C003F
+C000038007F800001C001FE000070007F800001C001FE000070007F800001C001FE000070007F8
+00001C000FF0000E0007F800001C000FF0000E0007F800001C0007F8001C0007F800001C0007F8
+001C0007F800001C0007F8001C0007F800001C0003FC00380007F800001C0003FC00380007F800
+001C0001FE00700007F800001C0001FE00700007F800001C0001FE00700007F800001C0000FF00
+E00007F800001C0000FF00E00007F800001C0000FF00E00007F800001C00007F81C00007F80000
+1C00007F81C00007F800001C00003FC3800007F800001C00003FC3800007F800001C00003FC380
+0007F800001C00001FE7000007F800001C00001FE7000007F800001C00000FFE000007F800001C
+00000FFE000007F800001C00000FFE000007F800001C000007FC000007F800001C000007FC0000
+07F800003E000007FC000007F800007F000003F8000007F80000FF800003F800000FFC0003FFE0
+0001F000001FFE00FFFFFF8001F0003FFFFFFFFFFFFF8001F0003FFFFFFFFFFFFF8000E0003FFF
+FFFF58477DC65F>77 D<FFFFFFFE0007FFFFFCFFFFFFFE0007FFFFFCFFFFFFFE0007FFFFFC007F
+FC0000001FFF00003FF800000007FC00001FF000000003F800001FF000000001F000001FF00000
+0000E000001FF000000000E000001FF000000000E000001FF000000000E000001FF000000000E0
+00001FF000000000E000001FF000000000E000001FF000000000E000001FF000000000E000001F
+F000000000E000001FF000000000E000001FF000000000E000001FF000000000E000001FF00000
+0000E000001FF000000000E000001FF000000000E000001FF000000000E000001FF000000000E0
+00001FF000000000E000001FF000000000E000001FF000000000E000001FF000000000E000001F
+F000000000E000001FF000000000E000001FF000000000E000001FF000000000E000001FF00000
+0000E000001FF000000000E000001FF000000000E000001FF000000000E000001FF000000000E0
+00001FF000000000E000001FF000000000E000001FF000000000E000001FF000000000E000001F
+F000000000E000001FF000000000E000001FF000000000E000001FF000000000E000001FF00000
+0000E000001FF000000000E000001FF000000000E000001FF000000000E000001FF000000000E0
+00001FF000000000E000000FF000000000C000000FF000000001C000000FF800000001C0000007
+F800000001C0000007F80000000380000007F80000000380000003FC0000000700000003FC0000
+000700000001FC0000000E00000000FE0000000E000000007F0000001C000000003F0000003800
+0000001F80000070000000000FC00000E00000000007F00003C00000000003FC000F8000000000
+00FF007F0000000000003FFFFC0000000000000FFFF000000000000001FF8000000046487DC64D
+>85 D<FFFFFFE003FFFFFF8001FFFFF8FFFFFFE003FFFFFF8001FFFFF8FFFFFFE003FFFFFF8001
+FFFFF803FFF800000FFFE000001FFF8000FFE0000003FF80000007FE00007FC0000001FF000000
+01FC00007FC0000001FF00000000F800007FC0000001FF80000000F000003FE0000000FF800000
+00E000003FE0000000FF80000000E000003FE0000000FF80000000E000001FF00000007FC00000
+01C000001FF00000007FC0000001C000001FF00000007FC0000001C000001FF8000000FFE00000
+03C000000FF8000000FFE00000038000000FF8000000FFE00000038000000FFC000001DFF00000
+0780000007FC000001DFF000000700000007FC000001DFF000000700000007FE0000038FF80000
+0F00000003FE0000038FF800000E00000003FE0000038FF800000E00000003FF0000078FFC0000
+1E00000001FF00000707FC00001C00000001FF00000707FC00001C00000001FF00000F07FE0000
+1C00000000FF80000E03FE00003800000000FF80000E03FE00003800000000FF80001E03FF0000
+38000000007FC0001C01FF000070000000007FC0001C01FF000070000000007FC0003C01FF8000
+70000000003FE0003800FF8000E0000000003FE0003800FF8000E0000000003FE0003800FF8000
+E0000000001FF00070007FC001C0000000001FF00070007FC001C0000000001FF00070007FC001
+C0000000001FF800E0003FE003C0000000000FF800E0003FE00380000000000FF800E0003FE003
+80000000000FFC01C0001FF007800000000007FC01C0001FF007000000000007FC01C0001FF007
+000000000007FE0380000FF80F000000000003FE0380000FF80E000000000003FE0380000FF80E
+000000000003FF0780000FFC1E000000000001FF07000007FC1C000000000001FF07000007FC1C
+000000000001FF0F000007FE1C000000000000FF8E000003FE38000000000000FF8E000003FE38
+000000000000FF9E000003FF380000000000007FDC000001FF700000000000007FDC000001FF70
+0000000000007FFC000001FFF00000000000003FF8000000FFE00000000000003FF8000000FFE0
+0000000000003FF8000000FFE00000000000001FF00000007FC00000000000001FF00000007FC0
+0000000000001FF00000007FC00000000000001FE00000003FC00000000000000FE00000003F80
+0000000000000FE00000003F800000000000000FC00000001F8000000000000007C00000001F00
+00000000000007C00000001F0000000000000007800000000F0000000000000003800000000E00
+00000065487EC66A>87 D<0003FE000000001FFFC00000007E03F0000000F000FC000001C0007E
+00000380003F000007C0001F800007F0001FC0000FF0000FC0000FF8000FE0000FF8000FE0000F
+F80007F00007F00007F00007F00007F00001C00007F00000000007F00000000007F00000000007
+F00000000007F000000001FFF00000007FFFF0000003FF87F000001FF007F000007F8007F00001
+FE0007F00003F80007F00007F00007F0000FE00007F0001FC00007F0003FC00007F0003F800007
+F0007F800007F01C7F800007F01CFF000007F01CFF000007F01CFF000007F01CFF00000FF01CFF
+00000FF01CFF00000FF01C7F80001BF01C7F800033F01C3FC00031F8381FC00061F8380FF001C0
+FC7003FC0780FFE000FFFE003FC0001FF8001F802E2F7CAD34>97 D<01FE0000000000FFFE0000
+000000FFFE0000000000FFFE000000000003FE000000000001FE000000000000FE000000000000
+FE000000000000FE000000000000FE000000000000FE000000000000FE000000000000FE000000
+000000FE000000000000FE000000000000FE000000000000FE000000000000FE000000000000FE
+000000000000FE000000000000FE000000000000FE000000000000FE000000000000FE00000000
+0000FE000000000000FE000000000000FE000000000000FE00FF00000000FE07FFF0000000FE1F
+01FC000000FE38003E000000FE70001F800000FEC0000FC00000FF800007E00000FF800003F000
+00FF000003F80000FE000001FC0000FE000001FC0000FE000000FE0000FE000000FE0000FE0000
+00FF0000FE000000FF0000FE0000007F8000FE0000007F8000FE0000007F8000FE0000007FC000
+FE0000007FC000FE0000007FC000FE0000007FC000FE0000007FC000FE0000007FC000FE000000
+7FC000FE0000007FC000FE0000007FC000FE0000007FC000FE0000007F8000FE0000007F8000FE
+000000FF8000FE000000FF0000FE000000FF0000FE000000FE0000FE000001FE0000FE000001FC
+0000FE000001F80000FF000003F00000FF800007F00000FD800007E00000F9C0000F800000F8E0
+003F000000F078007E000000F01E03F8000000E00FFFE00000000001FE00000032497DC739>I<
+00007F80000003FFF000000FC0FC00003F003F00007C001F8000F8000FC001F80007E003F00007
+E007E00003F00FE00003F80FE00003F81FC00001FC1FC00001FC3FC00001FC3FC00001FC7F8000
+01FE7F800000FE7F800000FEFF800000FEFF800000FEFFFFFFFFFEFFFFFFFFFEFF80000000FF80
+000000FF80000000FF80000000FF80000000FF800000007F800000007F800000007F800000007F
+C00000003FC00000003FC000000E1FC000000E1FE000000E0FE000001C07E000001C07F0000038
+03F000007001F800007000FC0000E0003E0003C0001F8007000007E03E000001FFF80000003FC0
+00272F7DAD2E>101 D<01FE00FFFE00FFFE00FFFE0003FE0001FE0000FE0000FE0000FE0000FE
+0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE
+0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE
+0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE
+0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE
+0000FE0000FE0000FE0000FE0000FE0000FE0003FF80FFFFFEFFFFFEFFFFFE17487DC71C>108
+D<01FC007F800000FFFC03FFF00000FFFC0781F80000FFFC0C007C000003FC18007E000001FC30
+003F000000FC60003F800000FCC0001F800000FD80001F800000FD80001FC00000FF00001FC000
+00FF00001FC00000FF00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE0000
+1FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000
+FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001F
+C00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE
+00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC0
+0000FE00001FC00000FE00001FC00003FF80007FF000FFFFFE1FFFFFC0FFFFFE1FFFFFC0FFFFFE
+1FFFFFC0322D7CAC39>110 D<01FC01F800FFFC07FE00FFFC1E1F00FFFC383F8003FC607FC001
+FC607FC000FCC07FC000FCC07FC000FD803F8000FD801F0000FF000E0000FF00000000FF000000
+00FF00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE0000
+0000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00
+000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE
+00000000FE00000000FE00000000FE00000000FF00000003FF800000FFFFFF8000FFFFFF8000FF
+FFFF8000222D7DAC28>114 D<001FF8060000FFFF0E0003F0079E00078001FE000E00007E001C
+00003E003C00003E007800001E007800001E00F800001E00F800000E00F800000E00FC00000E00
+FC00000E00FE00000E00FF000000007FC00000007FF80000003FFFE000001FFFFE00000FFFFF80
+0007FFFFE00003FFFFF00000FFFFFC00001FFFFE000001FFFE0000000FFF00000001FF80000000
+7F806000001FC0E000001FC0E000000FC0F000000FC0F0000007C0F0000007C0F0000007C0F800
+0007C0F800000780FC00000780FC00000F00FE00000F00FF00001E00FF80003C00F9E0007800F0
+F803E000E03FFFC000C007FC0000222F7DAD29>I<01FE00003FC000FFFE001FFFC000FFFE001F
+FFC000FFFE001FFFC00003FE00007FC00001FE00003FC00000FE00001FC00000FE00001FC00000
+FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001F
+C00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE
+00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC0
+0000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00001FC00000FE00
+001FC00000FE00001FC00000FE00001FC00000FE00003FC00000FE00003FC00000FE00003FC000
+00FE00007FC000007E00007FC000007E00007FC000003F0000DFC000003F00019FE000001F0003
+1FF000000F80061FFFC00007F01C1FFFC00001FFF81FFFC000003FE01FE000322E7CAC39>117
+D E end
+%%EndProlog
+%%BeginSetup
+%%Feature: *Resolution 300dpi
+TeXDict begin
+
+%%EndSetup
+%%Page: 0 1
+0 0 bop 258 823 a Fu(F)-9 b(unnelW)g(eb)38 b(User's)c(Man)m(ual)603
+1151 y Ft(Ross)21 b(N.)g(Williams)519 1343 y Fs(V1.0)e(for)h(F)-5
+b(unnelW)g(eb)20 b(V3.0)725 1536 y(Ma)n(y)g(1992)p eop
+%%Page: 1 2
+1 1 bop 177 2597 1772 2 v 177 2675 a Fr(Cop)o(yrigh)o(t)384
+2674 y(c)372 2675 y Fq(\015)14 b Fr(1992)e(Ross)i(N.)g(William)o(s.)177
+2750 y(P)o(ermission)j(is)g(gran)o(ted)g(to)h(mak)o(e)d(and)j(distribute)g(v)
+o(erbatim)d(copies)j(of)f(this)h(man)o(ual)c(pro)o(vided)k(that)f(the)177
+2800 y(cop)o(yrigh)o(t)d(notice)g(and)g(this)g(p)q(ermission)e(notice)j(are)f
+(preserv)o(ed)i(on)e(all)e(copies.)p 177 2835 V 1053 2940 a(1)p
+eop
+%%Page: 2 3
+2 2 bop 1053 2940 a Fr(2)p eop
+%%Page: 3 4
+3 3 bop 177 401 a Fp(Con)m(ten)m(ts)177 687 y Fo(Preface)1592
+b(9)177 808 y(Ac)o(kno)o(wledgemen)o(ts)1324 b(11)177 928 y(Presen)o(tation)
+12 b(Notes)1323 b(13)177 1048 y(1)38 b(A)16 b(T)l(utorial)e(In)o(tro)q
+(duction)1159 b(15)239 1126 y Fr(1.1)42 b(What)13 b(is)h(Literate)h
+(Programmi)o(ng?)9 b Fn(:)20 b(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)
+f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(15)239 1204 y(1.2)42 b(What)13 b(is)h(F)m(unnelW)m(eb?)19
+b Fn(:)i(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(18)239 1281 y(1.3)42 b(The)14 b(Name)f(F)m(unnelW)m(eb)26
+b Fn(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(19)239 1359 y(1.4)42 b(A)14 b(F)m(unnelW)m(eb)f(T)m(utorial)24
+b Fn(:)c(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(19)239 1437 y(1.5)42 b(A)14 b(Hello)f(W)m(orld)g(Do)q(cumen)o(t)34
+b Fn(:)21 b(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(20)239 1514 y(1.6)42 b(Macro)14 b(F)m(acilities)i Fn(:)k(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b
+Fr(22)335 1592 y(1.6.1)46 b(Simple)12 b(Macros)35 b Fn(:)20
+b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b
+Fr(22)335 1670 y(1.6.2)46 b(Num)o(b)q(er)13 b(of)g(Times)g(Called)h
+Fn(:)20 b(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(23)335 1747
+y(1.6.3)46 b(Inden)o(tation)26 b Fn(:)20 b(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)
+f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(25)335 1825 y(1.6.4)46 b(Additiv)o(e)13
+b(Macros)34 b Fn(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(26)335 1903 y(1.6.5)46 b(P)o(arameterized)14 b(Macros)26
+b Fn(:)20 b(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(28)335
+1980 y(1.6.6)46 b(Macro)14 b(Expansion)i Fn(:)k(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(30)335 2058 y(1.6.7)46 b(Include)14
+b(Files)37 b Fn(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)
+h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)61 b Fr(30)239 2136 y(1.7)42 b(T)o(yp)q(esetting)15 b(F)m(acilities)10
+b Fn(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(32)335 2213 y(1.7.1)46 b(Ov)o(erview)35 b Fn(:)20 b(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(32)335
+2291 y(1.7.2)46 b(T)o(yp)q(esetter)16 b(Indep)q(endence)41
+b Fn(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(34)335 2369
+y(1.7.3)46 b(Hierarc)o(hical)14 b(Structure)30 b Fn(:)20 b(:)g(:)h(:)f(:)g(:)
+h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)61 b Fr(34)335 2446 y(1.7.4)46 b(Understanding)14
+b(the)h(Prin)o(ted)f(Do)q(cumen)o(tation)36 b Fn(:)21 b(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(35)335
+2524 y(1.7.5)46 b(Literals)14 b(and)f(Emphasis)24 b Fn(:)c(:)g(:)h(:)f(:)g(:)
+h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)61 b Fr(37)335 2602 y(1.7.6)46 b(Adding)13
+b(a)h(Header)h(P)o(age)20 b Fn(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)
+g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(37)335 2679 y(1.7.7)46 b(Commen)o(ts)9 b Fn(:)20 b(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(37)239
+2757 y(1.8)42 b(A)14 b(Complete)f(Example)c Fn(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(38)239 2835 y(1.9)42
+b(Summary)31 b Fn(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(39)1053 2940 y(3)p eop
+%%Page: 4 5
+4 4 bop 177 42 a Fo(2)38 b(F)l(unnelW)l(eb)14 b(Hin)o(ts)1296
+b(41)239 116 y Fr(2.1)42 b(Macro)14 b(Names)22 b Fn(:)f(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b
+Fr(41)239 190 y(2.2)42 b(Quic)o(k)14 b(Names)30 b Fn(:)21 b(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(42)239 265 y(2.3)42 b(F)m(unnelW)m(eb)13 b(the)i(Martinet)i
+Fn(:)j(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)
+g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(42)239 339 y(2.4)42 b(Fiddling)12 b(With)i(End)g(of)f(Lines)28
+b Fn(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b
+Fr(43)239 413 y(2.5)42 b(F)m(udging)13 b(Conditionals)e Fn(:)21
+b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(44)239 488 y(2.6)42 b(Changing)13 b(the)h(Strength)h(of)e(Headings)19
+b Fn(:)h(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(46)239 562 y(2.7)42
+b(E\016ciency)14 b(Notes)h Fn(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(47)239 636 y(2.8)42
+b(In)o(teractiv)o(e)15 b(Mo)q(de)28 b Fn(:)20 b(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(47)239 711 y(2.9)42
+b(Setting)14 b(Up)g(Default)f(Options)29 b Fn(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)61 b Fr(49)239 785 y(2.10)21 b(F)m(unnelW)m(eb)13
+b(and)h(Mak)o(e)38 b Fn(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)
+g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)61 b Fr(49)239 860 y(2.11)21 b(The)14 b(Dangers)g(of)g(F)m(unnelW)m
+(eb)33 b Fn(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)
+g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(50)239 934 y(2.12)21 b(Wholistic)13 b(Debugging)21 b Fn(:)g(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(53)239
+1008 y(2.13)21 b(Examples)13 b(of)g(F)m(unnelW)m(eb)g(Applications)e
+Fn(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(53)335 1083 y(2.13.1)25
+b(Analyzing)13 b(the)h(Monster)h(P)o(ostscript)g(Header)g(File)e
+Fn(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(54)335 1157 y(2.13.2)25 b(Making)13 b(Ada)g(ADTs)h(more)f(A)31
+b Fn(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(55)335 1231
+y(2.13.3)25 b(Multiple)13 b(Language)g(Systems)26 b Fn(:)20
+b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(55)335 1306 y(2.13.4)25
+b(The)14 b(Case)g(of)g(the)g(Small)e(F)m(unction)g Fn(:)21
+b(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)61 b Fr(56)335 1380 y(2.13.5)25 b(When)14
+b(Commen)o(ts)d(are)k(Bad)24 b Fn(:)d(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(57)335 1455 y(2.13.6)25 b(Do)q(cumen)o(ts)13 b(That)h(Share)g(T)m(ext)41
+b Fn(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(58)335 1529 y(2.13.7)25
+b(Generics)18 b Fn(:)i(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)
+f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)61 b Fr(59)239 1603 y(2.14)21 b(Summary)31 b
+Fn(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)61 b Fr(62)177 1719 y Fo(3)38 b(F)l(unnelW)l(eb)14
+b(De\014niti)o(on)1201 b(63)239 1793 y Fr(3.1)42 b(In)o(tro)q(duction)13
+b Fn(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)61 b Fr(63)239 1868 y(3.2)42 b(Notation)14 b
+Fn(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)61 b Fr(63)239 1942 y(3.3)42 b(T)m(erminology)11
+b Fn(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)61 b Fr(63)239 2017 y(3.4)42 b(An)14 b(Arc)o(hitectural)h(Ov)o
+(erview)40 b Fn(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)
+f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(64)239 2091 y(3.5)42 b(Diagnostics)32 b Fn(:)20 b(:)h(:)f(:)g(:)g(:)h(:)
+f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b
+Fr(65)239 2165 y(3.6)42 b(T)o(yp)q(esetter)16 b(Indep)q(endence)45
+b Fn(:)21 b(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(65)239 2240 y(3.7)42 b(Command)11 b(Line)i(In)o(terface)j
+Fn(:)k(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)
+g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(66)335 2314 y(3.7.1)46 b(In)o(v)o(oking)12 b(F)m(unnelW)m(eb)25
+b Fn(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b
+Fr(66)335 2388 y(3.7.2)46 b(Comma)o(nd)11 b(Line)j(Argumen)o(ts)35
+b Fn(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(67)335 2463
+y(3.7.3)46 b(Options)29 b Fn(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(68)239 2537 y(3.8)42
+b(File)13 b(Name)g(Inheritance)30 b Fn(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(70)239 2612 y(3.9)42 b(F)m(unnelW)m(eb)13
+b(Startup)h Fn(:)20 b(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)61 b Fr(70)239 2686 y(3.10)21 b(Scanner)33 b Fn(:)21
+b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)61 b Fr(71)335 2760 y(3.10.1)25 b(Basic)14 b(Input)g(File)g(Pro)q
+(cessing)30 b Fn(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(71)335
+2835 y(3.10.2)25 b(Sp)q(ecial)14 b(Sequences)44 b Fn(:)21 b(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(72)1053 2940 y(4)p eop
+%%Page: 5 6
+5 5 bop 335 42 a Fr(3.10.3)25 b(Setting)14 b(the)g(Sp)q(ecial)g(Character)24
+b Fn(:)c(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(74)335 115 y(3.10.4)25
+b(Inserting)14 b(the)h(Sp)q(ecial)f(Character)g(in)o(to)g(the)g(T)m(ext)30
+b Fn(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(74)335 189 y(3.10.5)25 b(Inserting)14 b(Arbitrary)g(Characters)i(in)o
+(to)d(the)h(T)m(ext)40 b Fn(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)
+f(:)g(:)h(:)f(:)g(:)61 b Fr(74)335 262 y(3.10.6)25 b(Commen)o(ts)9
+b Fn(:)20 b(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)61 b Fr(75)335 336 y(3.10.7)25 b(Quic)o(k)14 b(Names)26
+b Fn(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(76)335 409 y(3.10.8)25 b(Inserting)14 b(End)g(of)g(Line)g(Mark)o(ers)42
+b Fn(:)21 b(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(76)335 483 y(3.10.9)25
+b(Suppressing)15 b(End)f(of)f(Line)h(Mark)o(ers)21 b Fn(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(77)335 556 y(3.10.10)t(Include)14 b(Files)37 b Fn(:)21
+b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(77)335 630 y(3.10.11)t(Pragmas)13 b Fn(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)
+f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(78)468 703
+y(3.10.11.1)8 b(Inden)o(tation)18 b Fn(:)i(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)
+g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)61 b Fr(78)468 777 y(3.10.11.2)8 b(Maxim)o(um)i(Input)k(Line)g(Length)
+19 b Fn(:)i(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)61 b Fr(79)468 850 y(3.10.11.3)8 b(Maxim)o(um)i(Output)15
+b(File)e(Line)h(Length)33 b Fn(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(79)468 924 y(3.10.11.4)8 b(T)o(yp)q(esetter)35
+b Fn(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b
+Fr(80)335 997 y(3.10.12)t(F)m(reestanding)14 b(T)o(yp)q(esetter)i(Directiv)o
+(es)23 b Fn(:)d(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(81)468 1071 y(3.10.12.1)8
+b(New)14 b(P)o(age)h Fn(:)21 b(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)
+f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)
+61 b Fr(81)468 1144 y(3.10.12.2)8 b(T)m(able)13 b(of)g(Con)o(ten)o(ts)35
+b Fn(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(81)468 1218
+y(3.10.12.3)8 b(V)m(ertical)14 b(Skip)25 b Fn(:)20 b(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)61 b Fr(81)468 1291 y(3.10.12.4)8 b(Title)i
+Fn(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(82)335 1365 y(3.10.13)t(Scanner/P)o(arser)16 b(In)o(terface)c
+Fn(:)20 b(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(82)239 1438
+y(3.11)21 b(P)o(arser)29 b Fn(:)20 b(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(82)335
+1512 y(3.11.1)25 b(High)13 b(Lev)o(el)h(Structure)20 b Fn(:)g(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(82)335 1585 y(3.11.2)25
+b(F)m(ree)14 b(T)m(ext)31 b Fn(:)20 b(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(83)335 1659 y(3.11.3)25
+b(T)o(yp)q(esetter)16 b(Directiv)o(es)42 b Fn(:)20 b(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)61 b Fr(83)468 1732 y(3.11.3.1)29 b(Section)j
+Fn(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(83)468 1806 y(3.11.3.2)29 b(Literal)13 b(Directiv)o(e)27
+b Fn(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(84)468 1879
+y(3.11.3.3)29 b(Emphasis)13 b(Directiv)o(e)38 b Fn(:)20 b(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)61 b Fr(85)335 1953 y(3.11.4)25 b(Macros)42 b Fn(:)20 b(:)g(:)g(:)h(:)f(:)
+g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(85)468
+2026 y(3.11.4.1)29 b(Names)41 b Fn(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)61 b Fr(86)468 2100 y(3.11.4.2)29 b(F)m(ormal)11
+b(P)o(arameter)j(Lists)24 b Fn(:)c(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)
+f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(86)335
+2173 y(3.11.5)25 b(Expressions)g Fn(:)20 b(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)
+f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(86)335 2247 y(3.11.6)25
+b(Macro)14 b(Calls)j Fn(:)j(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)61 b Fr(86)335 2320 y(3.11.7)25 b(F)m(ormal)11
+b(P)o(arameters)19 b Fn(:)i(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(87)335 2394 y(3.11.8)25 b(Macros)14 b(are)h(Static)e Fn(:)20
+b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(87)239
+2467 y(3.12)21 b(Analyser)16 b Fn(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(88)239
+2541 y(3.13)21 b(T)m(angle)g Fn(:)f(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(88)239
+2614 y(3.14)21 b(W)m(ea)o(v)o(e)26 b Fn(:)20 b(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)
+h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(89)335 2688 y(3.14.1)25 b(T)m(arget)13 b(T)o(yp)q(esetter)40
+b Fn(:)21 b(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(89)335 2761 y(3.14.2)25 b(Cross)14 b(Reference)i(Num)o(b)q(ering)22
+b Fn(:)e(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(89)239 2835 y(3.15)21
+b(F)m(unnelW)m(eb)13 b(Shell)32 b Fn(:)20 b(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(90)1053 2940 y(5)p
+eop
+%%Page: 6 7
+6 6 bop 335 42 a Fr(3.15.1)25 b(In)o(tro)q(duction)41 b Fn(:)21
+b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(90)335 116 y(3.15.2)25 b(Return)14 b(Statuses)43 b Fn(:)20
+b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(90)335
+190 y(3.15.3)25 b(Comma)o(nd)11 b(Line)j(Length)42 b Fn(:)20
+b(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(91)335 265 y(3.15.4)25
+b(String)13 b(Substitution)k Fn(:)k(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)61 b Fr(91)335 339 y(3.15.5)25 b(Ho)o(w)13 b(a)h(Command)d(Line)i(is)h
+(Pro)q(cessed)j Fn(:)j(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)
+g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(92)335 413 y(3.15.6)25
+b(Options)k Fn(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)61 b Fr(92)335 488 y(3.15.7)25 b(Shell)13 b(Commands)26
+b Fn(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(93)468 562 y(3.15.7.1)29 b(Absen)o(t)37 b Fn(:)20 b(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(93)468 636 y(3.15.7.2)29
+b(Co)q(dify)41 b Fn(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)
+f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)
+61 b Fr(93)468 711 y(3.15.7.3)29 b(Compare)h Fn(:)21 b(:)f(:)g(:)g(:)h(:)f(:)
+g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(93)468 785 y(3.15.7.4)29 b(De\014ne)17
+b Fn(:)j(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(94)468 860 y(3.15.7.5)29 b(Di\013)h Fn(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)
+h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(94)468 934 y(3.15.7.6)29
+b(Di\013summary)22 b Fn(:)e(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(95)468 1008 y(3.15.7.7)29 b(Di\013zero)22 b Fn(:)e(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(95)468 1083 y(3.15.7.8)29
+b(Eneo)41 b Fn(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(95)468 1157 y(3.15.7.9)29 b(Execute)20 b Fn(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(96)468 1231 y(3.15.7.10)8
+b(Exists)21 b Fn(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(96)468 1306 y(3.15.7.11)8 b(Fixeols)35 b Fn(:)20 b(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(96)468 1380 y(3.15.7.12)8
+b(Fw)41 b Fn(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)61 b Fr(97)468 1455 y(3.15.7.13)8 b(Help)14 b Fn(:)21 b(:)f(:)g(:)h(:)f(:)
+g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(97)468 1529
+y(3.15.7.14)8 b(Here)15 b Fn(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)61 b Fr(98)468 1603 y(3.15.7.15)8 b(Quit)15
+b Fn(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61
+b Fr(98)468 1678 y(3.15.7.16)8 b(Set)41 b Fn(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(98)468 1752 y(3.15.7.17)8
+b(Sho)o(w)35 b Fn(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)61 b Fr(98)468 1826 y(3.15.7.18)8 b(Skipto)14 b Fn(:)20
+b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b
+Fr(98)468 1901 y(3.15.7.19)8 b(Status)16 b Fn(:)k(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)61 b Fr(99)468 1975 y(3.15.7.20)8
+b(T)m(olerate)14 b Fn(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)41 b Fr(100)468 2049 y(3.15.7.21)8 b(T)m(race)31 b Fn(:)20
+b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41 b
+Fr(100)468 2124 y(3.15.7.22)8 b(W)m(rite)29 b Fn(:)20 b(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41 b Fr(100)468 2198 y(3.15.7.23)8
+b(W)m(riteu)38 b Fn(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)
+f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)
+41 b Fr(100)239 2273 y(3.16)21 b(Concluding)13 b(Remarks)22
+b Fn(:)f(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41
+b Fr(100)177 2388 y Fo(4)d(F)l(unnelW)l(eb)14 b(Installation)1146
+b(101)239 2463 y Fr(4.1)42 b(Obtaining)13 b(a)h(Cop)o(y)f(of)g(F)m(unnelW)m
+(eb)37 b Fn(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)
+f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41 b Fr(101)239
+2537 y(4.2)h(Establishing)13 b(The)i(Directory)f(T)m(ree)41
+b Fn(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41 b Fr(102)335
+2612 y(4.2.1)46 b(Admin)12 b(Directory)25 b Fn(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)41 b Fr(102)335 2686 y(4.2.2)46
+b(Answ)o(ers)15 b(Directory)30 b Fn(:)21 b(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)
+g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)41 b Fr(102)335 2760 y(4.2.3)46 b(Hac)o(kman)12
+b(Directory)f Fn(:)21 b(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41
+b Fr(103)335 2835 y(4.2.4)46 b(Results)14 b(Directory)i Fn(:)k(:)h(:)f(:)g(:)
+g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41 b Fr(103)1053 2940 y(6)p
+eop
+%%Page: 7 8
+7 7 bop 335 42 a Fr(4.2.5)46 b(Scripts)14 b(Directory)24 b
+Fn(:)c(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)
+g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41
+b Fr(103)335 116 y(4.2.6)46 b(Sources)15 b(Directory)d Fn(:)20
+b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41 b Fr(103)335
+191 y(4.2.7)46 b(T)m(ests)14 b(Directory)23 b Fn(:)d(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41 b Fr(104)335 266 y(4.2.8)46
+b(Userman)13 b(Directory)20 b Fn(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)41 b Fr(105)239 340 y(4.3)h(Compiling)11 b(F)m(unnelW)m(eb)29
+b Fn(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41
+b Fr(105)239 415 y(4.4)h(T)m(esting)14 b(F)m(unnelW)m(eb)k
+Fn(:)i(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)
+h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41
+b Fr(105)239 490 y(4.5)h(Installing)12 b(F)m(unnelW)m(eb)i
+Fn(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41
+b Fr(106)239 565 y(4.6)h(Prin)o(ting)13 b(Man)o(uals)21 b Fn(:)f(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41 b
+Fr(107)239 639 y(4.7)h(Installation)12 b(Problems?)24 b Fn(:)c(:)g(:)h(:)f(:)
+g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41 b Fr(107)177 756
+y Fo(5)d(F)l(unnelW)l(eb)14 b(Administr)o(ati)o(on)1066 b(109)239
+830 y Fr(5.1)42 b(In)o(tro)q(duction)13 b Fn(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41 b
+Fr(109)239 905 y(5.2)h(The)14 b(User's)h(Commitm)n(en)o(t)d(T)m(o)h(F)m
+(unnelW)m(eb)30 b Fn(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41 b Fr(109)239
+980 y(5.3)h(Do)q(cumen)o(tation)25 b Fn(:)20 b(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)
+g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41 b Fr(110)239 1054
+y(5.4)h(Registration)17 b Fn(:)j(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g
+(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41 b Fr(110)239 1129 y(5.5)h(Supp)q(ort)29
+b Fn(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
+(:)f(:)g(:)h(:)f(:)g(:)41 b Fr(110)239 1204 y(5.6)h(Cop)o(yrigh)o(t)26
+b Fn(:)20 b(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
+(:)g(:)h(:)f(:)g(:)41 b Fr(112)239 1279 y(5.7)h(No)o(w)o(arran)o(t)o(y)27
+b Fn(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)41 b Fr(112)239 1353 y(5.8)h(Distribution)18
+b Fn(:)i(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
+(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
+(:)f(:)g(:)41 b Fr(113)239 1428 y(5.9)h(Mo)q(di\014cation)11
+b Fn(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
+(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)41 b Fr(113)239 1503 y(5.10)21 b(V)m(ersions)k
+Fn(:)c(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)
+f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)41 b Fr(114)239 1577 y(5.11)21 b(FTP)14 b(Arc)o(hiv)o(e)g(and)
+g(Author)36 b Fn(:)21 b(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g
+(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)41
+b Fr(114)177 1694 y Fo(A)26 b(Glossary)1456 b(115)177 1810
+y(B)28 b(References)1412 b(117)177 1926 y(Index)1581 b(117)1053
+2940 y Fr(7)p eop
+%%Page: 8 9
+8 8 bop 1053 2940 a Fr(8)p eop
+%%Page: 9 10
+9 9 bop 177 399 a Fp(Preface)177 639 y Fr(When,)17 b(in)f(1986,)g(I)g
+(\014rst)i(read)f(Donald)e(Kn)o(uth's)i(tec)o(hnical)g(rep)q(ort)h(on)e(W)m
+(eb)p Fo([Kn)o(uth83])p Fr(,)f(and)h(tried)h(W)m(eb)177 689
+y(out,)f(I)f(w)o(as)h(sim)o(ultaneously)d(excited)k(b)o(y)e(Kn)o(uth's)h
+(idea)f(of)g(literate)h(programming,)c(and)k(disapp)q(oin)o(ted)f(b)o(y)177
+739 y(his)f(implemen)o(tati)o(on)d(of)i(it.)18 b(I)13 b(w)o(as)h(excited)g(b)
+q(ecause)i(I)d(could)h(sense)h(the)f(p)q(oten)o(tial)g(for)f(the)h(literate)g
+(st)o(yle)g(to)177 789 y(transform)g(the)h(state)g(of)f(mind)f(of)h(the)h
+(programmer,)d(but)j(w)o(as)f(disapp)q(oin)o(ted)g(b)o(y)h(W)m(eb's)f
+(rigidit)o(y)f(and)h(lac)o(k)177 839 y(of)h(practicalit)o(y)m(,)f(whic)o(h)h
+(seemed)h(to)f(b)q(etra)o(y)g(this)h(p)q(oten)o(tial.)21 b(The)16
+b(W)m(eb)f(I)g(used)h(w)o(as)f(P)o(ascal-sp)q(eci\014c,)i(T)1881
+847 y(E)1904 839 y(X-)177 888 y(sp)q(eci\014c,)c(and)e(applied)f(to)q(o)h
+(man)o(y)e(constrain)o(ts)i(to)g(the)h(programmi)o(ng)c(pro)q(cess.)19
+b(In)11 b(particular,)g(it)g(insisted)g(on)177 938 y(taking)i(con)o(trol)g
+(of)g(the)h(program)e(text,)h(mangling)e(the)j(co)q(de)g(in)f(the)h(P)o
+(ascal)f(output)h(\014les,)f(and)h(imp)q(osing)d(its)177 988
+y(o)o(wn)i(rather)g(rigid)f(ideas)h(ab)q(out)g(inden)o(ting)f(in)g(the)i(T)
+1026 997 y(E)1049 988 y(X)f(output.)18 b(All)12 b(this,)g(com)o(bined)g(with)
+g(the)i(complexit)o(y)177 1038 y(of)f(the)i(to)q(ol,)e(led)h(me)e(to)i(come)f
+(to)h(p)q(erceiv)o(e)h(W)m(eb)f(as)g(problem)e(rather)j(than)f(solution.)177
+1112 y(Despite)h(all)f(this,)g(I)h(w)o(as)f(w)o(ell)g(and)g(truly)h(ho)q(ok)o
+(ed)f(on)h(the)g(idea)f(of)g(literate)h(programming)o(.)i(The)e(inevitable)
+177 1162 y(result)g(w)o(as)f(that)g(I)f(designed)i(and)f(implem)o(en)o(ted)e
+(m)o(y)g(o)o(wn)i(v)o(ersion)g(of)f(W)m(eb)h(|)f(F)m(unnelW)m(eb!)177
+1237 y(F)m(unnelW)m(eb)d(is)h(not)f(the)i(most)d(sophisticated)j(literate)e
+(programming)d(to)q(ol)j(a)o(v)n(ailable,)f(but)i(it)f(is)h(an)f(extremely)
+177 1287 y Fm(pr)n(actic)n(al)i Fr(to)q(ol,)g(striving)g(for)g(simplicit)o(y)
+f(and)h(p)q(ortabilit)o(y)g(in)g(all)f(areas.)18 b(Not)13 b(only)f(is)h(F)m
+(unnelW)m(eb)f(language-)177 1337 y(indep)q(enden)o(t,)23 b(and)d(to)g(some)f
+(exten)o(t)i(t)o(yp)q(esetter)i(indep)q(enden)o(t,)f(but)f(its)f(implemen)o
+(tatio)o(n)d(also)j(stresses)177 1386 y(p)q(ortabilit)o(y)m(,)14
+b(b)q(eing)h(written)h(in)f(C,)g(and)h(curren)o(tly)g(op)q(erating)g(on)f
+(four)g(ma)r(jor)f(platforms)g(\(Sun,)h(V)m(ax,)g(PC,)177 1436
+y(Mac\).)j(F)m(unnelW)m(eb)13 b(allo)o(ws)f(the)j(programmer)c(total)h(con)o
+(trol)i(o)o(v)o(er)f(the)h(output)g(\014le,)f(making)e(it)i(suitable)g(for)
+177 1486 y(use)18 b(with)e(all)g(sorts)h(of)f(format-sensitiv)o(e)g
+(languages.)26 b(It)17 b(also)f(allo)o(ws)f(con)o(trol)i(o)o(v)o(er)f(its)h
+(o)o(wn)f(source)i(co)q(de,)177 1536 y(whic)o(h)11 b(has)g(b)q(een)h
+(released)g(under)g(a)e(GNU)h(license.)18 b(F)m(unnelW)m(eb)10
+b(is)h(quite)g(solid,)f(ha)o(ving)g(to)h(pass)g(a)g(regression)177
+1586 y(testing)17 b(suite)h(of)e(o)o(v)o(er)h(200)f(tests)i(b)q(efore)f(b)q
+(eing)g(released.)28 b(Finally)m(,)15 b(F)m(unnelW)m(eb)h(is)h(w)o(ell)f(do)q
+(cumen)o(ted)h(b)o(y)177 1636 y(this)d(man)o(ual)e(whic)o(h)h(pro)o(vides)h
+(a)g(tutorial,)f(adv)n(anced)h(hin)o(ts,)f(and)h(a)f(language)g
+(de\014nition.)177 1710 y(I)e(w)o(ould)e(lik)o(e)h(to)g(dedicate)i(F)m
+(unnelW)m(eb)e(and)g(this)g(man)o(ual)e(to)j(Donald)e(Kn)o(uth)i(and)f(his)h
+(literate)f(programming)177 1760 y(to)q(ol)g(W)m(eb.)17 b(Although)10
+b(this)g(man)o(ual)f(is)h(somewhat)g(critical)g(of)g(some)g(asp)q(ects)i(of)e
+(W)m(eb,)h(this)f(criticism)g(is)g(really)177 1810 y(a)j(pro)q(duct)h(of)e
+(di\013ering)h(design)g(goals.)k(Kn)o(uth)d(designed)f(a)g(paradigm)e
+(\(literate)i(programming\))d(and)j(a)f(to)q(ol)177 1860 y(\(W)m(eb\))20
+b(aimed)f(at)h(the)h(highest)f(pitc)o(h)h(of)e(program)g(presen)o(tation)i
+(and)f(t)o(yp)q(esetting.)38 b(F)m(unnelW)m(eb)20 b(aims)177
+1910 y(lo)o(w)o(er,)13 b(relaxing)f(constrain)o(ts,)h(and)g(making)e
+(compromises)g(in)h(order)i(to)f(ac)o(hiev)o(e)g(simplicit)o(y)m(,)d
+(\015exibilit)o(y)m(,)h(and)177 1959 y(p)q(ortabilit)o(y)m(.)16
+b(The)c(result)g(is)f(a)g(practical)h(to)q(ol)f(whic)o(h)g(I)g(hop)q(e)h
+(will)e(attract)i(more)f(p)q(eople)h(to)f(the)h(literate)g(st)o(yle.)177
+2059 y Fo(Ross)j(N.)i(Williams)177 2109 y(Adelaide,)d(Australia)177
+2159 y(Ma)o(y)i(1992)1053 2940 y Fr(9)p eop
+%%Page: 10 11
+10 10 bop 1042 2940 a Fr(10)p eop
+%%Page: 11 12
+11 11 bop 177 399 a Fp(Ac)m(kno)m(wledgemen)m(ts)177 645 y
+Fr(Man)o(y)16 b(thanks)h(to)g Fo(Da)o(vid)h(Hulse)d Fr(\()p
+Fl(dave@cs.adelaide.e)o(du.au)o Fr(\))f(for)j(translating)f(the)h(original)e
+(v)o(ersion)177 695 y(of)g(F)m(unnelW)m(eb)g(\(F)m(unnelW)m(eb)h(V1\))f(from)
+f(Ada)i(in)o(to)f(C)g(and)h(getting)f(it)h(to)f(w)o(ork)g(on)h(Unix)f(and)h
+(a)f(PC.)g(The)177 744 y(C)i(co)q(de)h(written)f(b)o(y)g(Da)o(vid)e(\(F)m
+(unnelW)m(eb)i(V2\))f(formed)g(the)h(basis)g(of)g(F)m(unnelW)m(eb)f(V3,)h
+(but)g(w)o(as)g(en)o(tirely)177 794 y(rewritten)h(during)f(the)h(in)o(tensiv)
+o(e)f(re\014nemen)o(t)h(and)e(feature-injection)i(p)q(erio)q(d)f(leading)f
+(up)h(to)g(this)h(release)177 844 y(\(F)m(unnelW)m(eb)12 b(V3)g(is)f(ab)q
+(out)h(three)h(times)e(the)i(size)g(of)e(F)m(unnelW)m(eb)g(V2\).)18
+b(Nev)o(ertheless,)c(without)e(this)g(imp)q(or-)177 894 y(tan)o(t)h(\014rst)i
+(translation)d(step,)i(I)g(w)o(ould)e(probably)h(not)g(ha)o(v)o(e)g(found)g
+(the)h(motiv)n(ation)d(to)i(dev)o(elop)g(F)m(unnelW)m(eb)177
+944 y(to)h(its)g(presen)o(t)h(state.)177 1018 y(Thanks)f(go)e(to)h
+Fo(Simon)h(Hac)o(k)o(ett)e Fr(\()p Fl(simon@internode.com)o(.au)p
+Fr(\))e(of)j(In)o(terno)q(de)h(Systems)f(Pt)o(y)h(Ltd)f(for)g(the)177
+1068 y(use)18 b(of)e(his)h(Sun,)h(Mac,)g(and)e(PC,)h(for)g(assistance)h(in)f
+(p)q(orting)f(F)m(unnelW)m(eb)h(to)g(the)g(Sun)h(and)e(PC,)h(and)g(for)177
+1118 y(helpful)c(discussions.)177 1193 y(Thanks)j(go)g(to)f
+Fo(Jerem)o(y)i(Begg)f Fr(\()p Fl(jeremy@vsm.com.au)o Fr(\))d(of)j(VSM)g(Soft)
+o(w)o(are)f(Services)j(for)d(the)i(use)g(of)e(his)177 1243
+y(V)-5 b(AX,)14 b(and)g(for)g(assistance)h(with)e(the)i(VMS-sp)q(eci\014c)g
+(co)q(de.)177 1317 y(Thanks)50 b(to)h Fo(Barry)57 b(Dwy)o(er)50
+b Fr(\()p Fl(dwyer@cs.adelaid)o(e.edu)o(.au)p Fr(\))d(and)j
+Fo(Roger)57 b(Brissenden)177 1367 y Fr(\()p Fl(rjb@koala.harvard.e)o(du)p
+Fr(\))15 b(for)j(trying)g(out)g(F)m(unnelW)m(eb)g(V)m(ersion)g(1)g(in)g(1987)
+f(and)h(pro)o(viding)f(v)n(aluable)177 1417 y(feedbac)o(k.)177
+1492 y(Thanks)d(to)g(Donald)f(Kn)o(uth)h(for)f(establishing)h(the)g(idea)g
+(of)f(literate)h(programming)d(in)i(the)i(\014rst)f(place.)177
+1591 y Fo(Ross)h(N.)i(Williams)177 1641 y(Adelaide,)d(Australia)177
+1691 y(Ma)o(y)i(1992)1042 2940 y Fr(11)p eop
+%%Page: 12 13
+12 12 bop 1042 2940 a Fr(12)p eop
+%%Page: 13 14
+13 13 bop 177 399 a Fp(Presen)m(tation)42 b(Notes)177 639 y
+Fo(References:)e Fr(All)24 b(references)29 b(are)c(set)i(in)e(b)q(old)f(and)i
+(are)f(cited)h(in)f(square)h(brac)o(k)o(ets)h(in)e(the)h(form)177
+689 y Fo([)p Fn(<)p Fm(\014rstauthor)p Fn(><)p Fm(ye)n(ar)p
+Fn(>)p Fo(])p Fr(.)19 b(All)13 b(references)j(cited)e(in)f(the)g(text)h(app)q
+(ear)g(in)f(the)h(reference)h(list)e(and)g(the)h(index.)177
+764 y Fo(Sp)q(ecial)d(terms:)17 b Fr(New)12 b(or)f(imp)q(ortan)o(t)f
+(terminology)f(has)i(b)q(een)i(set)f(in)f(b)q(old)g(face)h(and)f(app)q(ears)h
+(in)f(the)h(index.)177 814 y(A)i(glossary)g(app)q(ears)g(as)g(an)g(app)q
+(endix.)177 888 y Fo(T)o(yp)q(esetting:)69 b Fr(This)41 b(do)q(cumen)o(t)f(w)
+o(as)g(prepared)i(b)o(y)e(the)h(author)f(using)h(Andrew)g(T)m(rev)o(or-)177
+938 y(ro)o(w's)29 b(\()p Fl(akt150@cscgpo.anu.e)o(du.au)o Fr(\))e(implemen)o
+(tatio)o(n)g(\(OzT)m(eX\))j(of)f(the)h(T)1558 947 y(E)1581
+938 y(X/L)1644 933 y Fk(a)1663 938 y Fr(T)1686 951 y(E)1709
+938 y(X)p Fo([Kn)o(uth84])177 988 y([Lamp)q(ort86])13 b Fr(t)o(yp)q(esetting)
+i(system)e(running)h(on)g(a)f(Macin)o(tosh-SE.)177 1063 y Fo(Graphics:)i
+Fr(All)c(diagrams)e(ha)o(v)o(e)i(b)q(een)i(constructed)g(out)e(of)g(text)h
+(using)f(the)h(L)1431 1058 y Fk(a)1450 1063 y Fr(T)1473 1075
+y(E)1496 1063 y(X)f Fl(verbatim)f Fr(en)o(vironmen)o(t)177
+1112 y(so)17 b(as)f(to)h(allo)o(w)e(this)h(do)q(cumen)o(t)g(to)h(b)q(e)g
+(disseminated)e(electronically)i(and)f(prin)o(ted)h(using)f(L)1695
+1107 y Fk(a)1714 1112 y Fr(T)1737 1125 y(E)1761 1112 y(X)g(without)177
+1162 y(access)g(to)e(the)g(author's)g(dra)o(wing)f(to)q(ols.)177
+1237 y Fo(Kno)o(wn)g(t)o(yp)q(esetting)d(problems:)k Fr(While)d(ev)o(ery)h
+(attempt)f(has)h(b)q(een)g(made)e(to)i(giv)o(e)f(a)g(go)q(o)q(d)g(presen)o
+(tation)177 1287 y(within)h(the)h(time)e(a)o(v)n(ailable,)f(some)i(shortcuts)
+i(ha)o(v)o(e)e(had)g(to)g(b)q(e)h(tak)o(en.)18 b(In)13 b(particular,)f(the)h
+(author)f(has)h(b)q(een)177 1337 y(unable)h(to)g(w)o(ork)f(out)h(ho)o(w)g(to)
+f(get)h(L)754 1332 y Fk(a)773 1337 y Fr(T)796 1349 y(E)820
+1337 y(X)g(to)g(suppress)h(blank)f(pages)g(at)f(the)i(start)f(of)g(c)o
+(hapters.)1042 2940 y(13)p eop
+%%Page: 14 15
+14 14 bop 1042 2940 a Fr(14)p eop
+%%Page: 15 16
+15 15 bop 177 378 a Fj(Chapter)34 b(1)177 610 y Fp(A)40 b(T)-10
+b(utorial)41 b(In)m(tro)s(duction)177 876 y Fi(1.1)70 b(What)23
+b(is)f(Literate)g(Programming?)177 992 y Fr(A)e(traditional)e(computer)h
+(program)f(consists)i(of)f(a)g(text)h(\014le)f(con)o(taining)g(program)f(co)q
+(de.)35 b(Scattered)21 b(in)177 1041 y(amongst)12 b(the)j(program)d(co)q(de)j
+(are)f(commen)o(ts)e(whic)o(h)i(describ)q(e)i(the)e(v)n(arious)f(parts)i(of)e
+(the)i(co)q(de.)177 1116 y(In)d Fo(literate)f(programming)e
+Fr(the)k(emphasis)e(is)h(rev)o(ersed.)20 b(Instead)13 b(of)e(writing)g(co)q
+(de)i(con)o(taining)e(do)q(cumen-)177 1166 y(tation,)g(the)i(literate)f
+(programmer)e(writes)i(do)q(cumen)o(tation)f(con)o(taining)g(co)q(de.)18
+b(No)11 b(longer)h(do)q(es)h(the)f(English)177 1216 y(commen)o(tary)d
+(injected)j(in)o(to)f(a)g(program)f(ha)o(v)o(e)h(to)g(b)q(e)h(hidden)f(in)g
+(commen)o(t)e(delimiters)h(at)i(the)f(top)h(of)e(the)i(\014le,)177
+1266 y(or)j(under)g(pro)q(cedure)h(headings,)e(or)h(at)f(the)h(end)g(of)f
+(lines.)19 b(Instead,)c(it)f(is)g(wrenc)o(hed)i(in)o(to)e(the)h(da)o(yligh)o
+(t)e(and)177 1315 y(made)j(the)h(main)e(fo)q(cus.)26 b(The)17
+b(\\program")e(then)i(b)q(ecomes)g(primarily)d(a)j(do)q(cumen)o(t)f(directed)
+i(at)f(h)o(umans,)177 1365 y(with)12 b(the)h(co)q(de)h(b)q(eing)e(herded)i(b)
+q(et)o(w)o(een)g(\\co)q(de)f(delimiters")e(from)g(where)i(it)f(can)h(b)q(e)g
+(extracted)h(and)e(sh)o(u\017ed)177 1415 y(out)i(sidew)o(a)o(ys)g(to)g(the)g
+(language)f(system)h(b)o(y)f(literate)i(programmi)o(ng)c(to)q(ols.)177
+1490 y(The)k(e\013ect)i(of)d(this)h(simple)e(shift)h(of)h(emphasis)e(can)i(b)
+q(e)h(so)f(profound)f(as)h(to)f(c)o(hange)h(one's)g(whole)g(approac)o(h)177
+1540 y(to)f(programming.)i(Under)f(the)g(literate)g(programming)c(paradigm,)g
+(the)k(cen)o(tral)g(activit)o(y)f(of)f(programming)177 1589
+y(b)q(ecomes)i(that)g(of)f(con)o(v)o(eying)g(meaning)f(to)i(other)g(in)o
+(telligen)o(t)f(b)q(eings)h(rather)g(than)g(merely)f(con)o(vincing)g(the)177
+1639 y(computer)i(to)g(b)q(eha)o(v)o(e)g(in)g(a)g(particular)g(w)o(a)o(y)m(.)
+23 b(It)16 b(is)g(the)h(di\013erence)h(b)q(et)o(w)o(een)f(p)q(erforming)e
+(and)h(exp)q(osing)g(a)177 1689 y(magic)c(tric)o(k.)177 1764
+y(In)18 b(order)g(to)g(program)e(in)i(a)f(literate)h(st)o(yle,)h(particular)e
+(to)q(ols)h(are)g(required.)30 b(The)19 b(traditional)d(approac)o(h)177
+1814 y(\(used)f(in)f(the)g(F)m(unnelW)m(eb)g(system\))g(is)g(to)f(ha)o(v)o(e)
+h(some)f(sort)i(of)e(text-\014le-in/text-\014le-out)h(utilit)o(y)f(that)h
+(reads)177 1863 y(a)20 b(literate)f(program)f(\(con)o(taining)h(a)h(program)e
+(commen)o(tary)f(p)q(epp)q(ered)22 b(with)d(scraps)i(of)e(program)f(text\))
+177 1913 y(and)e(writes)g(out)g(a)g(\014le)g(con)o(taining)e(all)h(the)h
+(program)f(co)q(de)h(and)g(a)f(\014le)h(con)o(taining)f(t)o(yp)q(esetter)j
+(commands)177 1963 y(represen)o(ting)e(the)e(en)o(tire)h(input)e(do)q(cumen)o
+(t,)g(do)q(cumen)o(tation,)g(co)q(de,)h(and)g(all)e(\()p Fo(Figure)i(1)p
+Fr(\).)177 2038 y(Giv)o(en)h(the)h(coming)e(age)h(of)g(h)o(yp)q(ertext)i
+(systems,)e(this)h(is)f(probably)g(not)h(the)g(b)q(est)g(approac)o(h.)23
+b(Ho)o(w)o(ev)o(er,)16 b(it)177 2087 y(do)q(es)c(mesh)f(b)q(eautifully)f
+(with)h(curren)o(t)i(text)f(\014les)g(and)f(command)e(line)i(in)o(terfaces,)h
+(the)g(exp)q(ectation)g(of)f(linear)177 2137 y(presen)o(tations)k(in)f(the)g
+(do)q(cumen)o(ts)g(w)o(e)g(read,)g(and)g(the)h(particular)e(requiremen)o(ts)i
+(of)e(curren)o(t)i(programming)177 2187 y(languages)f(and)f(t)o(yp)q
+(esetting)i(systems.)j(It)c(is)g(certainly)g(not)g(a)f(bad)h(approac)o(h.)177
+2262 y(With)i(this)h(structure)h(in)e(place,)h(the)g(literate)g(programming)c
+(system)j(can)h(pro)o(vide)f(far)g(more)g(than)g(just)h(a)177
+2312 y(rev)o(ersal)h(of)e(the)i(priorit)o(y)e(of)h(commen)o(ts)e(and)i(co)q
+(de.)28 b(In)17 b(its)g(full)e(blo)o(wn)i(form,)e(a)i(go)q(o)q(d)f(literate)i
+(program-)177 2361 y(ming)c(facilit)o(y)g(can)h(pro)o(vide)h(total)f(supp)q
+(ort)h(for)f(the)h(essen)o(tial)g(thrust)h(of)e(literate)h(programmi)o(ng,)c
+(whic)o(h)k(is)177 2411 y(that)f(computer)g(programs)f(should)h(b)q(e)h
+(written)g(more)e(for)h(the)h(h)o(uman)e(reader)i(than)f(for)g(the)h
+(compiler.)21 b(In)177 2461 y(particular,)13 b(a)h(literate)g(programming)c
+(system)k(can)g(pro)o(vide:)295 2536 y Fo(Re-ordering)f(of)j(co)q(de:)k
+Fr(Programmi)o(ng)11 b(languages)j(often)g(force)h(the)g(programmer)d(to)i
+(giv)o(e)295 2586 y(the)g(v)n(arious)e(parts)h(of)f(a)h(computer)f(program)f
+(in)h(a)h(particular)f(order.)19 b(F)m(or)12 b(example,)f(the)j(P)o(as-)295
+2635 y(cal)f(programming)d(language)p Fo([BSI82])i Fr(imp)q(oses)g(the)i
+(ordering:)j(constan)o(ts,)d(t)o(yp)q(es,)g(v)n(ariables,)295
+2685 y(pro)q(cedures,)i(co)q(de.)k(P)o(ascal)14 b(also)g(requires)h(that)g
+(pro)q(cedures)h(app)q(ear)f(in)f(an)g(order)h(consisten)o(t)295
+2735 y(with)g(the)g(partial)f(ordering)h(imp)q(osed)e(b)o(y)i(the)g(static)g
+(call)f(graph)h(\(but)g(forw)o(ard)g(declarations)295 2785
+y(allo)o(w)e(this)i(to)g(b)q(e)g(b)o(ypassed\).)21 b(In)15
+b(con)o(trast,)g(the)h(literate)f(st)o(yle)f(requires)i(that)f(the)g
+(program-)295 2835 y(mer)c(b)q(e)i(free)f(to)g(presen)o(t)h(the)f(computer)g
+(program)e(in)h(an)o(y)h(order)g(whatso)q(ev)o(er.)19 b(The)12
+b(facilit)o(y)e(to)1042 2940 y(15)p eop
+%%Page: 16 17
+16 16 bop 526 789 a Fl(+----------------)o(-----)o(----)o(-----)o(-----)o
+(-----)o(-+)526 838 y(|)21 b(File)g(containing)f(the)h(program)g(description)
+e(|)526 888 y(|)i(peppered)g(with)g(scraps)f(of)h(program)g(code.)64
+b(|)526 938 y(|)21 b(This)g(is)h(what)f(the)g(programmer)f(works)g(on.)65
+b(|)526 988 y(|)218 b(\(e.g.)20 b(sloth.web\))325 b(|)526 1038
+y(+----------------)o(-----)o(----)o(-----)o(-----)o(-----)o(-+)962
+1087 y(|)962 1137 y(v)657 1187 y(o---------------)o(----)o(-----)o(---o)657
+1237 y(|)21 b(Literate)f(Programming)g(Tool)h(|)657 1287 y(o---------------)o
+(----)o(-----)o(---o)962 1336 y(|)526 1386 y(+----------------)o(---+-)o
+(----)o(-----)o(-----)o(----+)526 1436 y(|)850 b(|)526 1486
+y(v)g(v)330 1536 y(+---------------)o(---+)236 b(+------------------)o(-----)
+o(-----)o(----)o(--+)330 1586 y(|)65 b(Traditional)85 b(|)239
+b(|)22 b(Documentation)d(file)i(suitable)f(for)43 b(|)330 1635
+y(|)21 b(Computer)f(Program)h(|)239 b(|)22 b(input)f(into)g(a)g(typesetting)f
+(program)g(|)330 1685 y(|)43 b(\(e.g.)21 b(sloth.c\))42 b(|)239
+b(|)174 b(\(e.g.)21 b(sloth.tex\))216 b(|)330 1735 y(+---------------)o(---+)
+236 b(+------------------)o(-----)o(-----)o(----)o(--+)343
+1876 y Fh(Literate)14 b(programming)e(to)q(ols)j(could)g(b)q(e)g(organized)e
+(in)j(a)g(n)o(um)o(b)q(er)e(of)h(w)o(a)o(ys.)28 b(Ho)o(w)o(ev)o(er,)17
+b(to)e(\014t)h(in)f(with)281 1926 y(curren)o(t)9 b(\014le)h(and)h(command)d
+(line)i(based)g(en)o(vironmen)n(ts,)e(most)i(to)q(ols)g(conform)f(to)h(the)h
+(traditional)d(arc)o(hitectur)o(e)281 1976 y(sho)o(wn)g(here)g(in)h(whic)o(h)
+g(the)f(user)g(feeds)g(in)h(a)f(\014le)h(con)o(taining)d(a)j(literate)e
+(program,)g(and)h(the)g(literate)f(programmin)o(g)281 2026
+y(utilit)o(y)j(generates)f(program)g(\014les)i(and)f(a)i(do)q(cumen)o(ta)o
+(tion)c(\014le.)465 2117 y Fo(Figure)15 b(1)p Fr(:)i(T)m(raditional)12
+b(arc)o(hitecture)k(of)d(literate)h(programming)c(to)q(ols.)1042
+2940 y(16)p eop
+%%Page: 17 18
+17 17 bop 295 42 a Fr(do)15 b(this)g(is)g(implemen)o(ted)e(in)i(literate)g
+(programming)d(to)q(ols)i(b)o(y)h(pro)o(viding)f(text)i Fm(macr)n(os)f
+Fr(that)295 91 y(can)f(b)q(e)h(de\014ned)g(and)f(used)g(in)g(an)o(y)f(order.)
+295 170 y Fo(T)o(yp)q(eset)h(co)q(de)g(and)g(do)q(cumen)o(tation)o(:)i
+Fr(T)m(raditionally)10 b(program)h(listings)h(are)h(dull)f(a\013airs)295
+220 y(consisting)i(of)g(pages)h(of)e(fan-form)f(pap)q(er)j(imprin)o(ted)d
+(with)i(meandering)f(coastlines)i(of)f(struc-)295 270 y(tured)k(text)f(in)g
+(a)f(b)q(oring)g(fon)o(t.)26 b(In)17 b(con)o(trast,)h(literate)f(programmi)o
+(ng)d(systems)j(are)g(capable)295 320 y(of)d(pro)q(ducing)g(do)q(cumen)o
+(tation)e(that)i(is)g(sup)q(erior)h(in)e(t)o(w)o(o)h(w)o(a)o(ys.)k(First,)13
+b(b)q(ecause)j(most)d(of)g(the)295 369 y(do)q(cumen)o(tation)i(text)h(is)g
+(fed)g(straigh)o(t)f(to)h(the)g(t)o(yp)q(esetter,)j(the)d(programmer)e(can)i
+(mak)o(e)e(use)295 419 y(of)k(all)f(the)i(p)q(o)o(w)o(er)f(of)g(the)g
+(underlying)g(t)o(yp)q(esetter,)j(resulting)e(in)e(do)q(cumen)o(tation)g
+(that)i(has)295 469 y(the)14 b(same)e(presen)o(tation)h(as)g(an)g(ordinary)f
+(t)o(yp)q(eset)i(do)q(cumen)o(t.)j(Second,)d(b)q(ecause)g(the)f(literate)295
+519 y(programming)f(utilit)o(y)j(sees)i(all)e(the)h(co)q(de,)h(it)f(can)g
+(use)g(its)g(kno)o(wledge)g(of)f(the)h(programming)295 569
+y(language)c(and)g(the)h(features)h(of)d(the)i(t)o(yp)q(esetting)h(language)d
+(to)i(t)o(yp)q(eset)h(the)f(program)d(co)q(de)k(as)295 618
+y(if)f(it)h(w)o(ere)h(app)q(earing)e(in)h(a)f(tec)o(hnical)h(journal.)k(It)c
+(is)f(the)i(di\013erence)h(b)q(et)o(w)o(een:)264 745 y Fl(while)21
+b(sloth<walrus)e(loop)330 795 y(sloth:=sloth+1;)264 845 y(end)j(loop)295
+971 y Fr(and)281 1098 y Fo(while)12 b Fm(sloth)p Fn(<)p Fm(walrus)h
+Fo(lo)q(op)447 1147 y Fm(sloth)p Fq( )p Fm(sloth)p Fr(+1;)281
+1197 y Fo(end)g(lo)q(op)295 1324 y Fr(Unfortunately)m(,)18
+b(while)g(F)m(unnelW)m(eb)f(pro)o(vides)h(full)f(t)o(yp)q(esetting)i(of)e
+(the)i(do)q(cumen)o(tation,)e(it)295 1374 y(t)o(yp)q(esets)j(all)d(of)h(its)g
+(co)q(de)h(in)e(the)i(st)o(yle)f(of)g(the)h(\014rst)f(of)g(these)h(t)o(w)o(o)
+f(examples.)30 b(T)m(o)17 b(t)o(yp)q(eset)295 1423 y(in)e(the)g(st)o(yle)g
+(of)f(the)h(second)h(requires)g(kno)o(wledge)e(of)h(the)g(programmi)o(ng)d
+(language,)i(and)g(the)295 1473 y(curren)o(t)f(v)o(ersion)d(of)h(F)m(unnelW)m
+(eb)f(is)g(programming)d(language)j(indep)q(enden)o(t.)19 b(A)o(t)10
+b(a)h(later)g(stage,)295 1523 y(it)h(is)g(p)q(ossible)h(that)f(F)m(unnelW)m
+(eb)g(will)f(b)q(e)i(mo)q(di\014ed)e(to)h(read)h(in)f(a)g(\014le)g(con)o
+(taining)g(information)295 1573 y(ab)q(out)j(the)g(target)h(programmi)o(ng)c
+(language)i(to)g(b)q(e)i(used)f(to)g(assist)g(in)g(t)o(yp)q(esetting)g(the)h
+(co)q(de)295 1623 y(prop)q(erly)m(.)295 1702 y Fo(Cross)h(referencing:)h
+Fr(Because)f(the)e(literate)h(to)q(ol)e(sees)i(all)e(the)i(co)q(de)g(and)e
+(do)q(cumen)o(tation,)295 1751 y(it)19 b(is)g(able)h(to)f(generate)h
+(extensiv)o(e)h(cross)f(referencing)h(information)c(in)i(the)h(t)o(yp)q(eset)
+g(do)q(cu-)295 1801 y(men)o(tation.)28 b(This)18 b(mak)o(es)e(the)j(prin)o
+(ted)f(program)e(do)q(cumen)o(t)h(more)g(easy)h(to)g(na)o(vigate)f(and)295
+1851 y(partially)g(comp)q(ensates)h(for)g(the)g(lac)o(k)g(of)f(an)h
+(automatic)e(searc)o(hing)i(facilit)o(y)e(when)j(reading)295
+1901 y(prin)o(ted)c(do)q(cumen)o(tation.)177 1980 y(In)e(the)h(end,)f(the)g
+(details)g(don't)g(matter.)k(The)c(most)f(signi\014can)o(t)g(b)q(ene\014t)i
+(that)f(literate)h(programmi)o(ng)c(o\013ers)177 2029 y(is)17
+b Fm(its)h(c)n(ap)n(acity)g(to)g(tr)n(ansform)f(the)h(state)g(of)g(mind)g(of)
+g(the)g(pr)n(o)n(gr)n(ammer)p Fr(.)27 b(It)18 b(is)f(no)o(w)g(legend)g(that)h
+(the)f(act)177 2079 y(of)d(explaining)g(something)g(can)h(transform)f(one's)h
+(understanding)g(of)f(it.)21 b(This)15 b(is)g(one)g(of)f(the)i
+(justi\014cations)177 2129 y(b)q(ehind)j(the)h(p)q(o)o(w)o(erful)e(com)o
+(bination)e(of)i(researc)o(h)j(and)d(teac)o(hing)h(in)f(univ)o(ersities)p
+Fo([Roso)o(vsky90])p Fr(.)33 b(Simi-)177 2179 y(larly)m(,)12
+b(b)o(y)h(constan)o(tly)h(explaining)e(the)i(unfolding)e(program)g(co)q(de)j
+(in)e(English)g(to)h(an)f(imaginary)e(reader,)j(the)177 2229
+y(programmer)e(transforms)h(his)h(p)q(erception)h(of)e(the)i(co)q(de,)f(la)o
+(ying)e(it)i(op)q(en,)f(prone,)h(to)g(the)h(critical)e(ey)o(e.)177
+2307 y(The)f(result)h(of)e(this)h(exp)q(osure)h(is)e(a)h(higher)f(qualit)o(y)
+g(of)g(programmi)o(ng.)j(When)e(exp)q(osed)h(to)e(the)i(harsh)f(ligh)o(t)e
+(of)177 2357 y(the)i(literate)g(ey)o(e,)g(bugs)g(cra)o(wl)g(out,)f(sp)q
+(ecial)h(cases)h(v)n(anish,)e(and)h(slopp)o(y)f(co)q(de)h(ev)n(ap)q(orates.)
+18 b(As)12 b(a)g(rule)g(literate)177 2407 y(programs)18 b(tak)o(e)i(longer)f
+(to)g(write)g(than)h(ordinary)f(programs,)g(but)g(the)h(total)f(dev)o
+(elopmen)o(t)f(time)g(is)h(the)177 2457 y(same)13 b(or)h(less)g(b)q(ecause)h
+(the)f(time)f(tak)o(en)g(to)h(write)g(and)f(do)q(cumen)o(t)h(the)g(program)e
+(carefully)h(is)h(comp)q(ensated)177 2507 y(for)i(b)o(y)g(a)g(reduced)j
+(debugging)c(and)i(main)o(tenance)e(time.)24 b(Th)o(us)17 b(literate)g
+(programmi)o(ng)c(do)q(es)k(not)g(merely)177 2557 y(assist)c(in)f(the)g
+(preparation)g(of)g(do)q(cumen)o(tation,)f(but)h(also)g(mak)o(es)f
+(signi\014can)o(t)g(con)o(tributes)j(to)e(the)g(pro)q(cess)i(of)177
+2606 y(programming)d(itself.)18 b(In)c(practice)h(this)f(has)g(turned)h(out)f
+(to)g(b)q(e)g(a)g(con)o(tribution)g(far)f(more)h(imp)q(ortan)o(t)e(than)177
+2656 y(the)j(mere)e(capacit)o(y)h(to)g(pro)q(duce)h(t)o(yp)q(eset)g(do)q
+(cumen)o(tation.)177 2735 y(F)m(or)h(more)f(information)e(on)j(literate)h
+(programmi)o(ng,)c(the)k(reader)h(is)e(directed)h(to)f(Kn)o(uth's)h(early)f
+(founding)177 2785 y(w)o(ork)10 b Fo([Kn)o(uth83])f Fr(and)h
+Fo([Kn)o(uth84])p Fr(.)16 b(F)m(or)10 b(more)f(recen)o(t)j(information)c
+(refer)j(to)g Fo([Smith91])p Fr(,)d(whic)o(h)j(pro)o(vides)177
+2835 y(a)j(comprehensiv)o(e)g(bibliograph)o(y)e(up)i(to)f(1990.)1042
+2940 y(17)p eop
+%%Page: 18 19
+18 18 bop 177 42 a Fi(1.2)70 b(What)23 b(is)f(F)-6 b(unnelW)g(eb?)177
+160 y Fr(F)m(unnelW)m(eb)10 b(is)h(a)g(particular)f(literate)h(programming)c
+(system)k(that)g(is)f(implemen)o(ted)f(b)o(y)h(a)h(single)f(C)h(program.)177
+210 y(F)m(unnelW)m(eb)16 b(tak)o(es)h(as)f(input)h(a)f(single)g
+Fl(.fw)g Fo(input)g(\014le)f Fr(and)h(writes)h(one)g(or)f(more)g
+Fo(pro)q(duct)h(\014les)e Fr(and)h(a)177 260 y Fo(do)q(cumen)o(tation)c
+(\014le)h Fr(\()p Fo(Figure)h(2)p Fr(\).)831 386 y Fl(+-----------+)831
+436 y(|)22 b(sloth.fw)41 b(|)831 485 y(+-----------+)962 535
+y(|)962 585 y(v)744 635 y(o---------------)o(----o)744 685
+y(|)21 b(FUNNELWEB)f(Program)h(|)744 734 y(o---------------)o(----o)962
+784 y(|)526 834 y(+----------------)o(---+-)o(----)o(-----)o(-----)o(-+)526
+884 y(|)784 b(|)526 934 y(v)g(v)221 983 y(+---------------)o(-----)o(-----)o
+(----+)84 b(+--------------)o(-----)o(-----)o(-----)o(---+)221
+1033 y(|)21 b(Product)g(File)g(\(e.g.)f(sloth.c\))h(|)87 b(|)21
+b(Documentation)e(File)i(\(sloth.tex\))f(|)221 1083 y(+---------------)o
+(-----)o(-----)o(----+)84 b(+--------------)o(-----)o(-----)o(-----)o(---+)
+343 1174 y Fh(F)m(unnelW)m(eb)10 b(follo)o(ws)h(the)g(traditiona)o(l)e(arc)o
+(hitecture)f(of)j(literate)f(programmin)o(g)f(to)q(ols.)709
+1266 y Fo(Figure)14 b(2)p Fr(:)k(Arc)o(hitecture)e(of)e(F)m(unnelW)m(eb.)177
+1378 y(In)c(literate)f(programming)d(systems,)k(it)g(is)f(usual)g(to)h(refer)
+g(to)g(the)g(pro)q(duct)g(\014le)g(as)g(a)f(\\program)e(\014le".)17
+b(Ho)o(w)o(ev)o(er,)177 1427 y(as)i(F)m(unnelW)m(eb)f(is)g(a)g(general)h(to)q
+(ol)f(that)g(can)h(b)q(e)g(used)h(to)e(prepare)i(all)d(sorts)i(of)f(text)h
+(\014les)g(that)g(are)g(not)177 1477 y(computer)f(programs,)g(the)g(more)g
+(generic)h(term)e(\\pro)q(duct)i(\014le")f(w)o(as)g(c)o(hosen.)32
+b(Pro)q(duct)20 b(\014les)e(should)g(b)q(e)177 1527 y(carefully)13
+b(distinguished)g(from)e(the)j(term)e Fo(output)g(\014les)g
+Fr(whic)o(h)h(refers)h(to)f(all)f(of)g(the)i(output)f(\014les)h(pro)q(duced)
+177 1577 y(b)o(y)g(F)m(unnelW)m(eb.)177 1654 y(F)m(unnelW)m(eb)g(is)f
+(distinguished)h(b)o(y)g(the)g(follo)o(wing)e(c)o(haracteristics:)295
+1730 y Fo(Simplici)o(t)o(y:)18 b Fr(A)d(go)o(v)o(erning)g(design)g(goal)f(of)
+h(F)m(unnelW)m(eb)f(is)h(to)g(pro)o(vide)g(a)g Fm(simple)g
+Fr(to)q(ol)g(that)295 1780 y(could)i(b)q(e)g(easily)f(learn)o(t)h(and)f
+(completely)g(mastered.)26 b(This)17 b(man)o(ual)d(is)j(thic)o(k)f(b)q
+(ecause)j(it)d(is)295 1830 y(comprehensiv)o(e)h(and)e(lingers)h(on)g(the)h(w)
+o(a)o(ys)f(in)f(whic)o(h)h(F)m(unnelW)m(eb)g(can)g(b)q(e)g(used.)26
+b(The)16 b(to)q(ol)295 1880 y(itself)e(is)g(quite)f(simple.)295
+1957 y Fo(Reliabili)o(t)n(y:)22 b Fr(Another)17 b(design)g(goal)f(is)h(to)f
+(pro)o(vide)h(a)f(to)q(ol)g(that)h(will)e(protect)j(the)g(user)g(as)295
+2007 y(m)o(uc)o(h)g(as)h(p)q(ossible)g(from)e(silly)h(errors.)34
+b(Macro)19 b(prepro)q(cessors)j(are)e(notorious)e(for)h(causing)295
+2056 y(obscure)j(errors.)38 b(Ev)o(ery)21 b(attempt)e(has)h(b)q(een)i(made)d
+(in)g(F)m(unnelW)m(eb)h(to)g(k)o(eep)h(the)g(syn)o(tax)295
+2106 y(robust.)31 b(F)m(or)18 b(example,)f(in)h(F)m(unnelW)m(eb)f(the)i(syn)o
+(tax)f(of)f(macro)g(calls)h(has)g(b)q(een)h(purp)q(osely)295
+2156 y(designed)i(to)e(b)q(e)i(highly)e(visible)g(so)h(that)g(the)g(reader)h
+(is)f(alw)o(a)o(ys)e(a)o(w)o(are)i(when)g(the)h(macro)295 2206
+y(facilit)o(y)12 b(is)i(b)q(eing)g(in)o(v)o(ok)o(ed.)295 2283
+y Fo(Language)i(and)h(T)o(yp)q(esetter)e(Indep)q(endence:)k
+Fr(Unlik)o(e)14 b(Kn)o(uth's)i(original)d(W)m(eb)i(system)295
+2332 y(whic)o(h)h(w)o(as)g(sp)q(eci\014c)h(to)f(the)h(P)o(ascal)f(programmi)o
+(ng)d(language)p Fo([BSI82])i Fr(and)h(the)g(T)1667 2341 y(E)1690
+2332 y(X)g(t)o(yp)q(e-)295 2382 y(setting)g(language)p Fo([Kn)o(uth84])p
+Fr(,)d(F)m(unnelW)m(eb)h(striv)o(es)j(to)e(b)q(e)h(language)e(and)h(t)o(yp)q
+(esetter)j(inde-)295 2432 y(p)q(enden)o(t.)h(The)14 b(curren)o(t)g(v)o
+(ersion)f(of)g(F)m(unnelW)m(eb)f(is)h(completely)f(language)g(indep)q(enden)o
+(t,)i(but)295 2482 y(is)g(still)f(somewhat)g(dep)q(enden)o(t)j(on)d(the)i(T)
+965 2491 y(E)988 2482 y(X)f(t)o(yp)q(esetter)i(language.)295
+2559 y Fo(P)o(ortabili)o(t)n(y:)f Fr(F)m(unnelW)m(eb)10 b(has)g(b)q(een)i
+(written)f(in)f(the)h(C)f(programming)d(language)i(with)h(great)295
+2608 y(emphasis)k(on)g(p)q(ortabilit)o(y)m(.)k(F)m(unnelW)m(eb)c(curren)o
+(tly)h(runs)h(on)e(the)h(Sun,)f(V)-5 b(AX,)15 b(IBM)g(PC,)f(and)295
+2658 y(Mac.)295 2735 y Fo(Con)o(trollabl)o(e:)h Fr(F)m(unnelW)m(eb)10
+b(is)h(an)f(extremely)h(con)o(trollable)f(to)q(ol.)16 b(T)m(o)11
+b(protect)h(users')g(in)o(v)o(est-)295 2785 y(men)o(t)f(in)h(source)h
+(\014les)g(constructed)h(in)e(the)g(F)m(unnelW)m(eb)g(macro)f(language,)g
+(the)h(C)g(source)i(co)q(de)295 2835 y(to)h(F)m(unnelW)m(eb)f(has)h(b)q(een)h
+(released)g(under)g(GNU)e(license.)22 b(This)14 b(means)g(that)h(it)f(will)g
+(alw)o(a)o(ys)1042 2940 y(18)p eop
+%%Page: 19 20
+19 19 bop 295 42 a Fr(b)q(e)17 b(a)o(v)n(ailable)c(to)j(ev)o(ery)o(one.)24
+b(F)m(urthermore,)16 b(license)h(has)e(b)q(een)i(gran)o(ted)f(for)g(the)g(F)m
+(unnelW)m(eb)295 91 y(User's)h(Man)o(ual)e(and)h(F)m(unnelW)m(eb)f(Hac)o(k)o
+(er's)i(Man)o(ual)e(to)g(b)q(e)i(copied)f(freely)g(so)g(long)f(as)h(they)295
+141 y(are)e(not)f(mo)q(di\014ed.)j(All)c(this)h(means)g(that)g(F)m(unnelW)m
+(eb)f(is)h(not)g(going)f(to)h(disapp)q(ear)g(suddenly)m(.)295
+217 y Fo(A)18 b(Pro)q(duction)c(T)l(o)q(ol:)20 b Fr(Ab)q(o)o(v)o(e)c(all,)d
+(F)m(unnelW)m(eb)i(has)g(b)q(een)h(designed)g(to)f(b)q(e)h(a)e(pro)q(duction)
+295 267 y(to)q(ol)e(and)h(ev)o(ery)g(e\013ort)g(has)g(b)q(een)h(made)d(to)h
+(ensure)j(that)d(it)g(will)f(op)q(erate)j(e\013ectiv)o(ely)f(in)g(a)f(pro-)
+295 317 y(fessional)h(en)o(vironmen)o(t.)j(F)m(unnelW)m(eb)d(is)g(\\op)q(en")
+g(and)g(p)q(ortable.)18 b(There)c(is)f(a)f(comprehensiv)o(e)295
+367 y(user)18 b(man)o(ual.)24 b(Its)17 b(error)g(messages)g(are)g
+(comprehensiv)o(e.)26 b(It)17 b(is)f(fast.)26 b(Finally)m(,)15
+b(it)h(has)h(b)q(een)295 417 y(designed)e(with)e(the)i(exp)q(erience)h(of)d
+(three)i(y)o(ears)g(of)e(using)h(F)m(unnelW)m(eb)f(V1.)177
+493 y(F)m(or)c(more)g(information)e(on)i(the)h(history)g(and)f(design)h(of)f
+(F)m(unnelW)m(eb,)g(see)i(the)f Fm(F)m(unnelWeb)i(Hacker's)e(Manual)p
+Fr(.)177 660 y Fi(1.3)70 b(The)22 b(Name)g(F)-6 b(unnelW)g(eb)177
+779 y Fr(The)16 b(name)e(\\F)m(unnelW)m(eb")g(w)o(as)h(c)o(hosen)i(b)q
+(ecause)g(it)d(con)o(tains)i(the)g(name)e(\\WEB",)g(whic)o(h)h(is)g(the)h
+(name)e(of)177 828 y(Kn)o(uth's)g(system.)k(It)c(w)o(as)g(also)f(c)o(hosen)i
+(b)q(ecause)h(it)d(has)h(a)g(distinctly)f(Australian)h(\015a)o(v)o(our.)177
+905 y(F)m(unnel-w)o(eb)j(spiders)g(are)g(found)f(in)g(Northern)i(and)e
+(Eastern)i(Australia.)26 b(They)16 b(are)h(ab)q(out)g(three)h(to)e(four)177
+955 y(cen)o(timetres)c(long)e(and)g(are)i(v)o(ery)f(p)q(oisonous.)17
+b(The)11 b(Sydney)g(F)m(unnel-w)o(eb)g(spider)h(\()p Fm(A)o(tr)n(ax)g(r)n
+(obustus)p Fr(\),)f(common)177 1004 y(in)k(Sydney)m(,)g(has)h(caused)g(the)g
+(most)e(trouble)i(and)f(has)h(b)q(een)g(resp)q(onsible)h(for)e(sev)o(eral)h
+(deaths.)23 b(F)m(unnel-w)o(eb)177 1054 y(spiders)16 b(lo)o(v)o(e)f(to)g(cra)
+o(wl)f(in)o(to)h(temp)q(orarily)e(discarded)j(sho)q(es)g(where)h(they)e
+(later)g(react)h(in)f(a)g(hostile)g(manner)177 1104 y(to)h(an)g(unsusp)q
+(ecting)h(fo)q(ot.)24 b(They)17 b(are)f(kno)o(wn)g(to)f(hang)h(on)g(once)g
+(they)h(sink)f(their)g(fangs)g(in.)24 b(F)m(unnel-w)o(eb)177
+1154 y(spiders)17 b(deriv)o(e)f(their)h(name)e(from)f(the)i(shap)q(e)h(of)e
+(their)h(w)o(ebs)h(whic)o(h)f(are)g(horizon)o(tally-aligned)e(narro)o(wing)
+177 1204 y(tub)q(es,)h(op)q(en)f(at)g(one)g(end)p Fo([ANZE])p
+Fr(.)177 1280 y(The)j(F)m(unnel-w)o(eb)f(spider,)g(lik)o(e)g(the)g(tiger)h
+(snak)o(e)f(and)g(the)h(white)f(p)q(oin)o(ter)g(shark,)g(is)g(secretly)i
+(regarded)f(b)o(y)177 1330 y(Australians)d(as)g(a)g(kind)f(of)g(national)g
+(treasure.)281 1450 y Fo(F)h Fr(is)g(for)f(F)m(unnel-w)o(eb)281
+1500 y(Our)h(furry-legged)g(fo)q(e.)281 1550 y(He)g(sleeps)h(in)f(y)o(our)g
+(slipp)q(er)281 1599 y(And)g(breakfasts)h(on)e(to)q(e.)281
+1649 y(|)g(One)i(v)o(erse)g(from)d Fm(A)j(Me)n(gastar's)f(Mantr)n(as:)19
+b(Things)c(that)g(Me)n(an)h(a)f(L)n(ot)g(to)f(Me)p Fr(,)378
+1699 y(b)o(y)f(Dame)g(Edna)h(Ev)o(erage)p Fo([Humphries91])p
+Fr(.)177 1866 y Fi(1.4)70 b(A)23 b(F)-6 b(unnelW)g(eb)22 b(T)-6
+b(utorial)177 1985 y Fr(The)19 b(remainder)f(of)g(this)h(c)o(hapter)h
+(consists)g(of)e(an)g(in)o(tro)q(ductory)h(tutorial)f(on)g(F)m(unnelW)m(eb.)
+32 b(Ideally)18 b(y)o(ou)177 2034 y(should)13 b(ha)o(v)o(e)f(a)h(w)o(orking)e
+(v)o(ersion)i(of)f(F)m(unnelW)m(eb)g(in)h(fron)o(t)f(of)g(y)o(ou)g(when)i
+(reading)e(this)h(c)o(hapter)h(so)e(that)h(y)o(ou)177 2084
+y(can)h(try)g(out)f(the)h(examples)f(y)o(ourself.)k(There)e(is)e(no)g(need)i
+(to)e(try)h(all)e(the)i(examples)f(so)g(long)g(as)g(y)o(ou)g(t)o(yp)q(e)h(in)
+177 2134 y(enough)i(to)f(feel)g(comfortable)f(with)h(what)g(y)o(ou)g(are)h
+(reading.)22 b(There)16 b(is)f(no)g(harm)f(in)h(reading)g(this)h(c)o(hapter)
+177 2184 y(o\017ine)d(to)q(o,)h(so)f(long)g(as)h(y)o(ou)g(get)g(to)g(the)g
+(computer)g(within)f(a)g(couple)h(of)g(da)o(ys)f(to)h(reinforce)h(what)f(y)o
+(ou)f(ha)o(v)o(e)177 2234 y(read.)177 2310 y(F)m(or)g(b)q(est)i(e\013ect,)g
+(y)o(ou)e(should)g(create)i(a)e(new,)g(temp)q(orary)m(,)f(empt)o(y)h
+(directory)h(in)f(whic)o(h)g(to)h(exp)q(erimen)o(t)f(with)177
+2360 y(F)m(unnelW)m(eb.)21 b(That)15 b(w)o(a)o(y)m(,)f(it)h(will)e(b)q(e)j
+(more)e(ob)o(vious)g(when)i(F)m(unnelW)m(eb)e(creates)j(an)e(output)g
+(\014le.)22 b(Y)m(ou)15 b(can)177 2410 y(either)f(t)o(yp)q(e)f(in)f(the)h
+(examples)e(in)h(this)h(c)o(hapter)g(directly)m(,)f(or)h(cop)o(y)f(and)h
+(paste)g(them)f(from)e(the)k(L)1727 2405 y Fk(a)1746 2410 y
+Fr(T)1769 2422 y(E)1792 2410 y(X)e(source)177 2459 y(\014le)f(for)g(this)h(c)
+o(hapter)g(or)f(the)h(F)m(unnelW)m(eb)f(test)h(suite.)18 b(The)12
+b(source)g(\014le)f(for)g(this)h(c)o(hapter)g(should)f(b)q(e)h(a)o(v)n
+(ailable)177 2509 y(in)i(a)g(\014le)g(suc)o(h)h(as)f Fl(/fwdir/userman/c)o
+(h1.te)o(x)p Fr(.)i(The)e(test)i(suite)e(should)g(b)q(e)h(a)o(v)n(ailable)d
+(in)h(a)h(directory)h(suc)o(h)177 2559 y(as)i Fl(/fwdir/tests/)p
+Fr(.)23 b(The)16 b(test)i(\014les)f(called)f Fl(ex01.fw)f Fr(through)h
+Fl(ex16.fw)f Fr(con)o(tain)h(the)h(examples)f(in)g(this)177
+2609 y(c)o(hapter.)j(The)14 b(test)g(\014les)g(called)f Fl(hi01.fw)f
+Fr(through)h Fl(hi10.fw)f Fr(con)o(tain)h(the)h(examples)f(in)f(the)i(next)g
+(c)o(hapter.)177 2685 y(If)h(y)o(ou)f(do)g(not)h(y)o(et)g(ha)o(v)o(e)g(an)f
+(installed)h(cop)o(y)f(of)h(F)m(unnelW)m(eb,)f(refer)h(to)g(Chapter)h(4)e
+(for)g(full)g(details)h(on)f(ho)o(w)177 2735 y(to)h(obtain)g(and)g(install)f
+(a)h(cop)o(y)g(of)f(F)m(unnelW)m(eb.)22 b(If)15 b(y)o(ou)f(are)i(not)f(sure)h
+(if)f(y)o(ou)f(ha)o(v)o(e)h(an)g(installed)g(cop)o(y)m(,)g(try)177
+2785 y(in)o(v)o(oking)e(F)m(unnelW)m(eb)i(b)o(y)f(giving)g(the)i(command)c
+(\\)p Fl(fw)p Fr(".)20 b(If)15 b(this)g(yields)f(an)h(error)h(suc)o(h)g(as)f
+(\\command)d(not)177 2835 y(found")h(then)i(y)o(ou)e(do)h(not)g(ha)o(v)o(e)g
+(a)f(prop)q(erly)h(installed)g(v)o(ersion)g(of)f(F)m(unnelW)m(eb.)1042
+2940 y(19)p eop
+%%Page: 20 21
+20 20 bop 177 42 a Fi(1.5)70 b(A)23 b(Hello)d(W)-6 b(orld)24
+b(Do)r(cumen)n(t)177 153 y Fr(Just)c(as)f(one)g(starts)i(the)e(pro)q(cess)i
+(of)d(learning)h(a)g(new)g(programming)d(language)i(with)g(a)h(\\Hello)f(W)m
+(orld")177 202 y(program,)c(when)i(learning)e(F)m(unnelW)m(eb,)h(y)o(ou)g
+(can)h(start)g(with)f(a)g(\\Hello)f(W)m(orld")g(do)q(cumen)o(t!)22
+b(And)16 b(here)g(it)177 252 y(is!)k(Edit)14 b(a)g(text)h(\014le)g(called)f
+Fl(hello.fw)e Fr(and)j(put)f(the)h(follo)o(wing)d(text)j(in)f(it.)19
+b(\(Note:)h(The)15 b(second)g(c)o(haracter)177 302 y(is)f(the)g(letter)h
+(\\Oh",)e(not)h(the)h(digit)e(\\Zero"\).)177 402 y Fl(@O@<hello.txt@>@{H)o
+(ello)18 b(World@+@})177 502 y Fr(T)m(o)13 b(\\run")h(this)g(\\program",)d
+(in)o(v)o(ok)o(e)i(F)m(unnelW)m(eb)h(using)f(the)i(\\)p Fl(fw)p
+Fr(")e(command)e(as)j(follo)o(ws.)177 602 y Fl(fw)22 b(hello)177
+701 y Fm(If)c(this)g(c)n(ommand)h(do)n(esn)l('t)f(work,)g(then)h(chanc)n(es)g
+(ar)n(e)f(that)g(F)m(unnelWeb)i(has)e(not)h(b)n(e)n(en)f(instal)r(le)n(d)g
+(on)h(your)177 751 y(machine.)h(R)n(efer)14 b(to)h(Chapter)g(4)g(for)f(ful)r
+(l)g(details)h(on)g(how)g(to)g(obtain)g(and)h(instal)r(l)e(a)h(c)n(opy)g(of)g
+(F)m(unnelWeb.)177 821 y Fr(There)j(should)e(b)q(e)h(no)f(errors.)28
+b(If)16 b(there)h(are,)h(ha)o(v)o(e)e(a)g(lo)q(ok)g(at)g(the)h(listing)e
+(\014le)i Fl(hello.lis)p Fr(,)e(whic)o(h)h(should)177 871 y(con)o(tain)c(an)g
+(explanation)f(of)h(the)g(error,)h(and)f(compare)g(the)h(area)f(in)g(the)h
+(\014le)f(where)h(the)g(error)g(o)q(ccurred)h(with)177 921
+y(the)h(text)f(ab)q(o)o(v)o(e.)k(If)13 b(there)j(are)e(no)g(errors,)g(y)o(ou)
+g(will)e(\014nd)i(that)g(the)h(follo)o(wing)c(t)o(w)o(o)i(\014les)h(ha)o(v)o
+(e)g(b)q(een)h(created.)177 1021 y Fl(hello.lis)64 b(-)21 b(The)g(LISTING)g
+(file.)177 1071 y(hello.txt)64 b(-)21 b(The)g(PRODUCT)g(file.)177
+1170 y Fr(T)m(ak)o(e)14 b(a)h(lo)q(ok)f(at)g Fl(hello.txt)p
+Fr(.)19 b(It)c(should)f(con)o(tain)h(a)f(single)h(line)f(with)g(the)i(text)f
+Fl(Hello)21 b(World)p Fr(.)f(Let's)15 b(tak)o(e)177 1220 y(another)f(lo)q(ok)
+f(at)h(the)h(input)e(\014le.)177 1320 y Fl(@O@<hello.txt@>@{H)o(ello)18
+b(World@+@})177 1420 y Fr(The)f(whole)g(structure)i(of)d(the)h(input)g
+(\014le)g(is)f(con)o(trolled)h(b)o(y)f(\\)p Fl(@)p Fr(",)h(called)f(the)h
+Fo(sp)q(ecial)h(c)o(haracter)p Fr(,)e(whic)o(h)177 1470 y(in)o(tro)q(duces)f
+Fo(sp)q(ecial)g(sequence)p Fr(s.)i(A)d(scanner's-ey)o(e)h(view)f(of)f(the)i
+(command)c(line)i(lo)q(oks)h(lik)o(e)f(this:)177 1570 y Fl(@O)43
+b(@<)h("hello.txt")d(@>)i(@{)g("Hello)21 b(World")42 b(@+)h(@})177
+1669 y Fr(The)11 b Fl(@)f Fr(c)o(haracter)h(con)o(trols)f(ev)o(erything.)17
+b(In)10 b(this)h(\014le)f(w)o(e)g(ha)o(v)o(e)g(six)g(di\013eren)o(t)h(sp)q
+(ecial)f(sequences)j(that)d(together)177 1719 y(form)i(a)i(single)f(macro)g
+(de\014nition.)18 b(The)c Fl(@<)g Fr(and)f Fl(@>)h Fr(delimit)d(the)k(name)e
+(of)g(the)h(macro.)j(The)e Fl(@O)e Fr(signals)g(the)177 1769
+y(start)g(of)f(the)h(macro)e(de\014nition)h(and)g(indicates)h(that)f(the)h
+(macro)e(is)i(to)f(b)q(e)h(connected)h(to)e(a)g(pro)q(duct)i(\014le)e(with)
+177 1819 y(the)j(same)e(name)g(as)h(the)g(macro)f(\(This)h(is)g(is)g(wh)o(y)f
+(w)o(e)i(got)e(a)h(pro)q(duct)h(\014le)f(when)g(w)o(e)g(ran)g(F)m(unnelW)m
+(eb\).)k(The)177 1869 y Fl(@)p Fq(f)e Fr(and)f Fl(@)p Fq(g)h
+Fr(delimit)e(the)i(b)q(o)q(dy)g(of)g(the)g(macro.)23 b(Finally)m(,)14
+b(the)j Fl(@+)e Fr(instructs)j(that)e(an)f(end)i(of)e(line)h(sequence)177
+1918 y(should)e(b)q(e)g(inserted)i(at)d(that)h(p)q(oin)o(t)g(in)f(the)i(pro)q
+(duct)f(\014le.)177 1988 y(If)c(y)o(ou)g(think)f(this)h(syn)o(tax)g(lo)q(oks)
+g(messy)m(,)g(then)g(y)o(ou're)g(righ)o(t.)17 b(It)10 b Fm(is)g
+Fr(messy)m(.)15 b(F)m(unnelW)m(eb)10 b Fm(c)n(ould)g Fr(ha)o(v)o(e)g(emplo)o
+(y)o(ed)177 2038 y(a)k(\\simpler")e(notation)h(in)g(whic)o(h)h(more)f(of)g
+(the)i Fl(@)e Fr(sequences)k(w)o(ere)e(eliminated.)h(F)m(or)d(example:)177
+2138 y Fl(Warning:)20 b(This)h(example)g(is)g(NOT)g(legal)g(FunnelWeb.)177
+2238 y(#hello.txt{Hello)e(World+})177 2338 y Fr(Ho)o(w)o(ev)o(er,)14
+b(if)f(suc)o(h)h(a)f(syn)o(tax)h(w)o(ere)h(used,)f(the)g(user)h(\(y)o(ou!\))j
+(w)o(ould)12 b(ha)o(v)o(e)i(to)f(remem)o(b)q(er)g(that)h Fl(#)f
+Fr(starts)i(a)e(new)177 2387 y(macro.)18 b(Y)m(ou)c(w)o(ould)g(also)f(ha)o(v)
+o(e)i(to)f(remem)o(b)q(er)f(that)i(the)g(c)o(haracters)h Fq(g)e
+Fr(and)g Fl(+)g Fr(cannot)h(b)q(e)g(used)g(in)f(a)g(macro)177
+2437 y(b)q(o)q(dy)j(without)f(a)h(fuss.)27 b(And)17 b(so)g(on.)27
+b(F)m(unnelW)m(eb)16 b(is)h(messier,)g(but)g(pro)o(vides)g(one)g(simple)e
+(rule:)25 b Fm(Nothing)177 2487 y(sp)n(e)n(cial)15 b(happ)n(ens)h(unless)f
+(the)g(sp)n(e)n(cial)f(char)n(acter)h Fl(@)f Fm(app)n(e)n(ars.)177
+2557 y Fr(This)f(means)g(that)g(in)g(F)m(unnelW)m(eb,)g(y)o(ou)g(can)g(lo)q
+(ok)g(at)g(large)g(blo)q(c)o(ks)g(of)g(text)h(in)f(the)h(con\014dence)h(that)
+e(\(unlik)o(e)177 2607 y(for)g(the)g(C)g(pre-pro)q(cessor\))j(there)e(are)f
+(no)g(macro)f(calls)g(hidden)h(in)g(there.)19 b(If)12 b(there)j(w)o(ere,)e
+(there)h(w)o(ould)e(b)q(e)i(an)177 2657 y Fl(@)g Fr(c)o(haracter!)391
+2642 y Fg(1)177 2727 y Fr(Let's)g(tak)o(e)g(another)h(lo)q(ok)e(at)g(the)i
+(hello)e(w)o(orld)g(program.)p 177 2757 709 2 v 223 2783 a
+Ff(1)241 2795 y Fh(The)e(only)g(exception)e(to)i(this)g(rule)f(o)q(ccurs)h
+(where)g(the)f(user)h(has)g(explicitly)e(c)o(hanged)g(the)i(sp)q(ecial)f(c)o
+(haracter)f(using)i(the)g Fe(@=)177 2835 y Fh(sp)q(ecial)f(sequence.)1042
+2940 y Fr(20)p eop
+%%Page: 21 22
+21 21 bop 177 42 a Fl(@O@<hello.txt@>@{H)o(ello)18 b(World@+@})177
+177 y Fr(In)c(its)f(curren)o(t)j(form,)11 b(it)i(consists)i(of)e(a)g(single)g
+(macro)g(de\014nition.)k(This)d(de\014nition,)f(while)g(completely)f(v)n
+(alid)177 226 y(on)i(its)g(o)o(wn,)f(only)g(represen)o(ts)j(half)d(the)i(p)q
+(o)o(w)o(er)f(of)f(F)m(unnelW)m(eb.)k(In)d(fact)g(y)o(ou)g(could)f(sa)o(y)h
+(that)g(it)f(is)h(a)g(\\Hello)177 276 y(Northern)h(Hemisphere)f(Program".)i
+(T)m(o)d(turn)h(it)f(in)o(to)g(a)g(prop)q(er)i(F)m(unnelW)m(eb)e(\\Hello)g(W)
+m(orld")f(program,)g(w)o(e)177 326 y(need)j(to)f(add)f(some)g(do)q(cumen)o
+(tation!)177 408 y(A)k(F)m(unnelW)m(eb)g(input)f(\014le)h(consists)h(of)f(a)f
+(sequence)j(of)e(macro)e(de\014nitions)i(surrounded)h(b)o(y)f(a)g(sea)g(of)g
+(do)q(c-)177 458 y(umen)o(tation)e(whic)o(h)h(is)h(just)g(ordinary)f(text.)26
+b(Mo)q(dify)16 b(y)o(our)g(hello)g(w)o(orld)g(do)q(cumen)o(t)g(so)h(that)f
+(it)h(lo)q(oks)f(lik)o(e)177 508 y(this:)177 643 y Fl(This)21
+b(hello)g(world)g(document)f(was)h(created)f(by)i(-insert)e(your)h(name)g
+(here-.)177 743 y(@O@<hello.txt@>@{H)o(ello)d(World@+@})177
+842 y(It)k(writes)e(out)h(a)h(file)f(called)f(hello.txt)g(containing)g(the)h
+(string)g(``Hello)f(World''.)177 977 y Fr(No)o(w)14 b(run)g(it)f(through)h(F)
+m(unnelW)m(eb,)f(but)h(this)g(time,)e(add)i(a)g Fl(+t)f Fr(to)h(the)g
+(command)d(line.)177 1113 y Fl(fw)22 b(hello)e(+t)177 1248
+y Fr(If)14 b(all)e(go)q(es)j(w)o(ell,)d(y)o(ou)i(should)f(\014nd)h(that)g(y)o
+(ou)g(no)o(w)f(ha)o(v)o(e)177 1383 y Fl(hello.lis)64 b(-)21
+b(A)h(LISTING)151 b(file.)177 1433 y(hello.tex)64 b(-)21 b(A)h(DOCUMENTATION)
+d(file)i(\(in)g(TeX)g(format\).)177 1482 y(hello.txt)64 b(-)21
+b(A)h(PRODUCT)151 b(file.)177 1618 y Fr(T)m(ak)o(e)13 b(a)g(lo)q(ok)g(at)g
+Fl(hello.txt)p Fr(.)j(Y)m(ou)d(will)f(\014nd)i(that)f(it)g(is)g(iden)o(tical)
+g(to)h(the)g Fl(hello.txt)d Fr(of)i(the)h(previous)g(run.)177
+1667 y(Only)g(macro)f(de\014nitions)i(a\013ect)g(the)g(pro)q(duct)g(\014les)g
+(that)f(F)m(unnelW)m(eb)g(pro)q(duces)i(\(as)e(a)g(result)h(of)f
+Fl(@O)g Fr(macro)177 1717 y(de\014nitions\).)23 b(The)16 b(surrounding)f(do)q
+(cumen)o(tation)f(has)i Fm(no)g Fr(e\013ect.)24 b(In)16 b(con)o(trast,)g(the)
+g(new)f(\014le,)h Fl(hello.tex)177 1767 y Fr(\(ha)o(v)o(e)i(a)g(lo)q(ok)e(at)
+i(it)g(no)o(w\))f(whic)o(h)h(w)o(as)g(created)h(as)f(a)g(result)g(of)g(y)o
+(our)f(adding)g(the)i Fl(+t)e Fr(option)g(con)o(tains)h(a)177
+1817 y(fairly)d(full)g(represen)o(tation)j(of)d(the)i(input)f(\014le.)25
+b(Whereas)18 b Fl(hello.txt)c Fr(is)i(the)h Fm(pr)n(o)n(duct)g(\014le)f
+Fr(of)g(F)m(unnelW)m(eb,)177 1867 y Fl(hello.tex)e Fr(is)h(the)i
+Fm(do)n(cumentation)g(\014le)p Fr(.)24 b(T)m(ry)15 b(t)o(yp)q(esetting)h(the)
+h(do)q(cumen)o(tation)d(\014le)i(no)o(w)f(using)g(the)i(T)1895
+1876 y(E)1918 1867 y(X)177 1916 y(t)o(yp)q(esetting)k(program.)36
+b(Then)20 b(prin)o(t)g(it.)37 b(The)21 b(follo)o(wing)c(commands)h(are)j(an)e
+(example)g(of)h(the)h(sort)f(of)177 1966 y(commands)12 b(y)o(ou)h(will)f(ha)o
+(v)o(e)i(to)g(giv)o(e)f(to)h(do)g(this.)177 2101 y Fl(tex)21
+b(hello)392 b(!)21 b(Typeset)g(the)g(documentation.)177 2151
+y(lpr)g(-Pcslw)g(-d)g(hello.dvi)86 b(!)21 b(Print)g(the)g(typeset)f
+(documentation.)177 2286 y Fr(The)14 b(result)g(should)f(b)q(e)g(a)g(single)g
+(page)g(con)o(taining)f(the)i(t)o(w)o(o)e(lines)h(of)g(do)q(cumen)o(tation)f
+(along)g(with)g(a)h(t)o(yp)q(eset)177 2336 y(represen)o(tation)g(of)e(the)i
+(macro.)j(A)o(t)11 b(this)h(p)q(oin)o(t,)f(y)o(ou)g(ha)o(v)o(e)h(exercised)h
+(the)g(t)o(w)o(o)e(main)e(asp)q(ects)14 b(of)d(F)m(unnelW)m(eb.)177
+2386 y(Starting)h(with)g(an)g(input)g(\014le)g(con)o(taining)g(macros)f(\(or)
+h(in)g(this)h(case)g(macro\))e(and)h(do)q(cumen)o(tation,)f(y)o(ou)h(ha)o(v)o
+(e)177 2436 y(successfully)j(generated)g(a)f(pro)q(duct)g(\014le)g(based)g
+(on)g(the)g(macros,)f(and)g(a)h(do)q(cumen)o(tation)e(\014le,)h(based)i(on)e
+(the)177 2486 y(en)o(tire)i(do)q(cumen)o(t.)i(Congratulations!)177
+2568 y(The)11 b(remainder)e(of)g(this)h(tutorial)f(is)h(divided)f(in)o(to)h
+(t)o(w)o(o)f(parts,)i(whic)o(h)f(fo)q(cus)g(on)g(F)m(unnelW)m(eb's)f(macro)g
+(facilities)177 2618 y(and)15 b(its)h(t)o(yp)q(esetting)g(facilities.)22
+b(By)16 b(tradition,)e(the)i(generation)g(of)f(program)f(\014les)h(from)f(a)h
+(literate)h(text)g(is)177 2667 y(called)e Fo(T)l(angling)p
+Fr(,)d(and)j(the)g(generation)g(of)f(t)o(yp)q(eset)j(do)q(cumen)o(tation)c
+(is)i(called)g Fo(W)l(ea)o(ving)p Fr(.)1681 2652 y Fg(2)p 177
+2717 709 2 v 223 2744 a Ff(2)241 2756 y Fh(In)8 b(F)m(unnelW)m(eb,)f(these)h
+(t)o(w)o(o)h(functions)d(are)j(asp)q(ects)e(of)h(a)h(single)e(computer)g
+(program.)12 b(Ho)o(w)o(ev)o(er,)c(in)h(Kn)o(uth's)e(WEB)j(system,)177
+2795 y(the)g(t)o(w)o(o)i(functions)c(are)j(em)o(b)q(o)q(died)d(in)i(t)o(w)o
+(o)i(separate)d(computer)f(programs)g(called)i(T)m(angle)g(and)g(W)m(ea)o(v)o
+(e,)g(presumably)e(b)q(ecause,)177 2835 y(as)j(ev)o(ery)o(one)f(kno)o(ws,)g
+(\\it)h(tak)o(es)g(t)o(w)o(o)g(to)g(T)m(angle".)1042 2940 y
+Fr(21)p eop
+%%Page: 22 23
+22 22 bop 177 42 a Fi(1.6)70 b(Macro)24 b(F)-6 b(aciliti)o(es)177
+154 y Fr(The)13 b(hello)e(w)o(orld)h(program)f(of)g(the)i(previous)g(section)
+g(exercised)h(b)q(oth)f(the)f(macro)g(expansion)g(\(pro)q(duct-\014le\))177
+204 y(asp)q(ect)i(of)e(F)m(unnelW)m(eb,)g(and)h(the)h(t)o(yp)q(esetting)f
+(\(do)q(cumen)o(tation)f(\014le\))h(asp)q(ect)h(of)e(F)m(unnelW)m(eb.)17
+b(This)c(section)177 254 y(con)o(tains)h(an)g(exp)q(osition)g(of)f(the)i
+(macro)e(facilities,)f(and)i(totally)f(ignores)h(the)h(do)q(cumen)o(tation)e
+(side.)19 b(This)14 b(is)177 303 y(partly)e(to)g(increase)h(the)g(fo)q(cus)g
+(of)e(the)i(tutorial,)e(and)h(partly)g(b)q(ecause)i(do)q(cumen)o(tation)d(is)
+h(usually)f(bulky)h(and)177 353 y(w)o(ould)h(tak)o(e)h(to)q(o)g(long)f(for)g
+(the)i(reader)g(to)f(t)o(yp)q(e)g(in)f(to)h(mak)o(e)f(the)h(tutorial)f
+(e\013ectiv)o(e.)177 490 y Fd(1.6.1)55 b(Simple)17 b(Macros)177
+588 y Fr(The)d(original)f(\\Hello)g(W)m(orld")f(program)g(consisted)j(of)e(a)
+h(single)g(macro)e(de\014nition.)177 692 y Fl(@O@<hello.txt@>@{H)o(ello)18
+b(World@+@})177 797 y Fr(In)e(fact,)g(this)g(is)g(a)g(rather)h(exceptional)f
+(macro,)f(as)h(it)g(causes)h(its)f(expansion)g(to)g(b)q(e)h(written)f(to)g(a)
+g(pro)q(duct)177 847 y(\014le.)28 b(The)17 b Fl(@O)g Fr(\(for)g
+Fo(O)p Fr(utput\))h(signals)e(this.)28 b(In)17 b(F)m(unnelW)m(eb,)g(most)f
+(macros)g(are)i(de\014ned)g(using)f Fl(@$)p Fr(.)27 b(This)177
+897 y(results)16 b(in)e(a)g(macro)f(that)i(do)q(es)g(not)f(generate)i(a)e
+(pro)q(duct)h(\014le,)g(but)f(whic)o(h)h(can)f(b)q(e)h(called)g(in)f(other)h
+(macros)177 947 y(\(including)e Fl(@O)h Fr(macros\).)j(Let)d(us)h(expand)f
+(the)g(hello)f(w)o(orld)h(program)e(to)i(include)g(some)f(other)h(macros.)177
+1051 y Fl(@O@<hello.txt@>@{@)o(<Gree)o(tings)o(@>@+@)o(})177
+1151 y(@$@<H@>==@{Hello@})177 1201 y(@$@<W@>==@{World@})177
+1300 y(@$@<Greetings@>==@)o({@<H@)o(>)19 b(@<W@>@})177 1405
+y Fr(T)o(yp)q(e)14 b(in)g(the)g(\014le)g(and)g(run)g(it)g(through)g(F)m
+(unnelW)m(eb)f(using)h(the)g(command:)177 1510 y Fl(fw)22 b(hello)177
+1614 y Fr(The)14 b(pro)q(duct)h(\014le)f(\(result.out\))h(should)e(lo)q(ok)g
+(lik)o(e)g(this:)177 1719 y Fl(Hello)21 b(World)177 1823 y
+Fr(This)16 b(short)h(program)e(illustrates)h(some)g(of)f(the)i(features)h(of)
+d(ordinary)h(macros)g(in)g(F)m(unnelW)m(eb.)24 b(Consider)177
+1873 y(the)15 b Fl(@O)e Fr(macro.)k(Instead)d(of)g(con)o(taining)e(straigh)o
+(t)i(text)h(\(\\Hello)e(W)m(orld"\),)f(it)h(no)o(w)h(con)o(tains)f(the)i
+(macro)e(call)177 1923 y Fl(@<Greetings@>)p Fr(.)20 b(A)c(F)m(unnelW)m(eb)f
+(macro)f(can)h(b)q(e)i(called)e(from)e(within)i(the)h(b)q(o)q(dy)g(of)e
+(another)i(macro)f(just)177 1973 y(b)o(y)f(giving)e(the)j(macro)d(name)h
+(delimited)f(in)i Fl(@<)f Fr(and)h Fl(@>)p Fr(.)177 2044 y(A)o(t)e(the)h(b)q
+(ottom)d(of)i(the)g(\014le)g(is)g(the)h(de\014nition)e(of)h(the)g
+Fl(@<Greetings@>)d Fr(macro.)17 b(The)12 b(de\014nition)g(is)f(similar)f(to)
+177 2094 y(the)k(de\014nition)e(of)g Fl(hello.txt)f Fr(except)j(that)f(it)g
+(starts)h(with)e Fl(@$)g Fr(to)h(indicate)g(that)g(no)f(pro)q(duct)i(\014le)f
+(is)g(desired)177 2144 y(from)f(this)i(macro)f(\(directly\).)18
+b(It)c(also)f(emplo)o(ys)g(the)h(optional)e Fl(==)i Fr(syn)o(tax)g(whic)o(h)f
+(has)h(no)g(seman)o(tic)f(impact,)177 2194 y(but)k(can)f(b)q(e)h(used)g(to)f
+(mak)o(e)f(de\014nitions)h(clearer.)27 b(The)17 b(b)q(o)q(dy)f(of)g(the)g
+Fl(@<Greetings@>)e Fr(macro)h(consists)i(of)177 2244 y(calls)d(to)f(the)i
+Fl(H)e Fr(and)h Fl(W)g Fr(macros)f(whic)o(h)h(are)g(de\014ned)h(immedia)o
+(tely)c(ab)q(o)o(v)o(e.)177 2315 y(Note)k(that)g(the)g(macros)f(are)h(not)g
+(constrained)g(to)g(b)q(e)g(de\014ned)g(in)g(an)o(y)f(particular)g(order.)21
+b(One)16 b(of)e(the)h(main)177 2365 y(features)h(of)e(literate)h(programmi)o
+(ng)d(to)q(ols)i(is)h(that)f(they)i(allo)o(w)d(the)i(di\013eren)o(t)g(parts)h
+(of)e(the)h(text)g(do)q(cumen)o(t)177 2415 y(b)q(eing)f(dev)o(elop)q(ed)h
+(\(usually)e(a)g(computer)h(program\))e(to)i(b)q(e)h(la)o(y)o(ed)e(out)h(in)f
+(an)o(y)h(order.)k(So)c(long)f(as)h(there)h(is)f(a)177 2464
+y(de\014nition)g(somewhere)g(in)f(the)i(input)e(\014le)h(for)g(ev)o(ery)h
+(macro)d(call,)h(F)m(unnelW)m(eb)g(will)g(sort)h(it)f(all)g(out.)177
+2536 y(In)h(fact,)g(F)m(unnelW)m(eb's)g(macro)f(facilit)o(y)f(is)i(v)o(ery)h
+(simple.)i(Unlik)o(e)d(man)o(y)e(macro)h(prepro)q(cessors)k(whic)o(h)d(allo)o
+(w)177 2586 y(macros)d(to)g(de\014ne)i(other)f(macros,)f(F)m(unnelW)m(eb)g
+(completely)f(\014nishes)i(parsing)g(and)f(analysing)f(the)j(macros)d(in)177
+2635 y(the)k(input)e(\014le)h(b)q(efore)g(it)g(starts)h(expanding)e(them)g
+(in)o(to)g(pro)q(duct)i(\014les.)k(Other)c(prepro)q(cessors)h(allo)o(w)d
+(macros)177 2685 y(to)j(b)q(e)h(rede\014ned)g(lik)o(e)f(v)n(ariables)f(\(as)h
+(in,)g(sa)o(y)m(,)f(T)950 2694 y(E)973 2685 y(X\))h(taking)f(on)h(man)o(y)e
+(di\013eren)o(t)j(v)n(alues)f(as)g(the)g(macro)f(pre-)177 2735
+y(pro)q(cessor)f(tra)o(v)o(els)e(through)g(the)g(input)g(\014le.)17
+b(In)10 b(con)o(trast,)i(F)m(unnelW)m(eb)e(has)h(no)g(concept)h(of)e
+(\\di\013eren)o(t)i(times")177 2785 y(and)h(treats)h(the)f(input)f(as)h(one)g
+(h)o(uge)g(static)g(orderless,)h(timeless,)e(collection)g(of)g
+(de\014nitions.)18 b(In)13 b(F)m(unnelW)m(eb,)177 2835 y(there)i(is)f(only)f
+(ev)o(er)i(one)f(time,)e(and)i(so)g(there)h(can)f(only)f(ev)o(er)i(b)q(e)f
+(one)h(v)n(alue/de\014nition)d(for)i(eac)o(h)g(macro.)1042
+2940 y(22)p eop
+%%Page: 23 24
+23 23 bop 177 42 a Fd(1.6.2)55 b(Num)n(b)r(er)17 b(of)i(Times)e(Called)177
+140 y Fr(So)e(far)g(w)o(e)g(ha)o(v)o(e)g(seen)i(only)d(tin)o(y)m(,)g
+(degenerate)j(input)e(\014les.)22 b(The)16 b(next)g(example)e(mo)o(v)o(es)f
+(up)j(to)f(the)h(lev)o(el)e(of)177 190 y(\\trivial",)c(but)h(starts)i(to)e
+(con)o(v)o(ey)g(the)h(\015a)o(v)o(our)f(of)g(the)h(w)o(a)o(y)f(F)m(unnelW)m
+(eb)f(can)i(b)q(e)g(used)g(in)f(practice.)18 b(Normally)m(,)177
+240 y(there)f(w)o(ould)d(b)q(e)i(do)q(cumen)o(tation)e(text)i(app)q(earing)f
+(b)q(et)o(w)o(een)i(the)f(macros,)e(but)i(this)f(has)g(b)q(een)i(omitted)d
+(so)177 289 y(as)i(to)f(k)o(eep)i(the)f(fo)q(cus)g(on)g(the)g(macros)f
+(themselv)o(es.)23 b(Although)15 b(the)i(next)f(example)e(is)i(m)o(uc)o(h)e
+(longer)i(than)177 339 y(the)h(previous)g(example,)f(the)h(only)f(new)h
+(construct)h(is)e Fl(@-)h Fr(whic)o(h)f(can)h(app)q(ear)g(only)f(at)g(the)h
+(end)g(of)f(a)h(line,)177 389 y(and)d(suppresses)j(it,)c(prev)o(en)o(ting)h
+(it)g(from)e(app)q(earing)i(in)g(the)g(text.)19 b(The)c Fl(@-)e
+Fr(construct)j(allo)o(ws)c(the)j(text)g(of)e(a)177 439 y(macro)g(to)g(b)q(e)h
+(aligned)f(at)h(the)g(left)g(margin,)d(rather)j(than)g(ha)o(ving)e(the)j
+(\014rst)f(line)f(hanging)g(at)h(the)g(end)g(of)f(the)177 489
+y Fl(@)p Fq(f)p Fr(.)20 b(F)m(unnelW)m(eb)14 b(could)h(ha)o(v)o(e)f(b)q(een)i
+(set)g(up)f(so)f(that)h(this)g(end)g(of)f(line)g(mark)o(er)g(w)o(as)h
+(suppressed.)23 b(Ho)o(w)o(ev)o(er,)177 538 y(it)14 b(w)o(ould)g(ha)o(v)o(e)g
+(b)q(een)i(a)e(sp)q(ecial)h(case)g(that)f(w)o(ould)g(ha)o(v)o(e)g(brok)o(en)h
+(the)g(v)o(ery)g(memorable)d(rule)i(\\the)h(text)g(of)f(a)177
+588 y(macro)f(is)h(the)g(text)h(app)q(earing)e(b)q(et)o(w)o(een)i(the)g
+Fl(@)p Fq(f)e Fr(and)h Fl(@)p Fq(g)p Fr(".)177 660 y(T)o(yp)q(e)i(the)g
+(follo)o(wing)e(text)i(in)o(to)f(the)h(\014le)g Fl(hello.fw)e
+Fr(and)h(run)h(it)f(through)h(F)m(unnelW)m(eb.)23 b(The)16
+b(\014le)g(con)o(tains)177 710 y(some)9 b(in)o(ten)o(tional)g(errors)j(so)e
+(b)q(e)h(sure)g(to)f(t)o(yp)q(e)g(it)g(in)g(exactly)g(and)g(w)o(orry)g(only)g
+(if)f(F)m(unnelW)m(eb)g Fm(do)n(esn)l('t)h Fr(generate)177
+759 y(some)j(errors.)177 865 y Fl(@O@<hello.c@>==@{@)o(-)177
+914 y(@<Include)20 b(Files@>)177 964 y(@<Include)g(Files@>)177
+1014 y(@<Main)h(Program@>)177 1064 y(@})177 1163 y(@$@<Main)f
+(Program@>==@{@-)177 1213 y(main\(\))177 1263 y({)199 1313
+y(doit\(\);)177 1363 y(})177 1413 y(@})177 1512 y(@$@<Subroutine@>==)o(@{@-)
+177 1562 y(void)h(doit\(\))177 1612 y({)199 1662 y(int)g(i;)199
+1711 y(for)g(\(i=0;i<10;i++\))243 1761 y({)264 1811 y(@<Print@>)264
+1861 y(@<Print@>)243 1911 y(})177 1960 y(}@})177 2060 y(@$@<Print@>==@{@-)177
+2110 y(printf\("Hello)e(World!"\);)177 2160 y(printf\("\\n"\);@})177
+2259 y(@$@<Scan@>==@{scan)o(f@})177 2359 y(@$@<Include)h(Files@>==@{@-)177
+2409 y(#include)g(<stdio.h>)177 2459 y(#include)g(<stdlib.h>@})177
+2564 y Fr(What)14 b(happ)q(ened?)21 b(W)m(ell,)13 b(if)g(y)o(ou)h(ha)o(v)o
+(en't)g(t)o(yp)q(ed)i(the)f(\014le)f(in)g(prop)q(erly)m(,)g(y)o(ou)g(ma)o(y)f
+(get)h(some)g(miscellaneous)177 2614 y(syn)o(tax)e(errors.)18
+b(Fix)12 b(these)h(b)q(efore)f(con)o(tin)o(uing.)k(If)c(the)g(\014le)g(has)g
+(b)q(een)g(correctly)h(t)o(yp)q(ed,)f(y)o(ou)g(should)f(b)q(e)h(faced)177
+2663 y(with)i(some)f(error)i(messages)f(to)f(do)h(with)f(the)i(n)o(um)o(b)q
+(er)e(of)g(times)g(some)g(of)h(the)g(macros)f(are)h(called.)177
+2735 y(By)h(default,)f(F)m(unnelW)m(eb)g(insists)h(that)g(eac)o(h)g(macro)e
+(de\014ned)j(is)e(in)o(v)o(ok)o(ed)g(exactly)h(once.)21 b(Ho)o(w)o(ev)o(er,)
+15 b(the)g(\014le)177 2785 y(ab)q(o)o(v)o(e)h(de\014nes)i(macros)d(that)h
+(are)h(used)g(more)e(than)h(once)h(and)f(a)g(macro)f(that)i(is)f(not)g(used)h
+(at)f(all.)24 b(Let)16 b(us)177 2835 y(examine)d(the)h(errors.)1042
+2940 y(23)p eop
+%%Page: 24 25
+24 24 bop 177 42 a Fr(First,)15 b(w)o(e)g(see)h(that)e(F)m(unnelW)m(eb)g(has)
+h(alerted)g(us)g(to)g(the)g(fact)g(that)f(the)i Fl(Include)k(Files)13
+b Fr(macro)h(has)h(b)q(een)177 91 y(called)d(t)o(wice.)18 b(Once)c(alerted)f
+(to)g(this,)f(a)g(quic)o(k)h(lo)q(ok)e(at)i(the)g(program)e(con)o(vinces)i
+(us)g(that)g(calling)e(the)i(macro)177 141 y(t)o(wice)h(is)g(a)g(mistak)o(e,)
+e(and)h(that)h(one)g(of)g(the)g(calls)g(should)f(b)q(e)i(eliminated.)177
+217 y(Second,)d(w)o(e)e(note)h(that)f(F)m(unnelW)m(eb)g(has)h(alerted)g(us)g
+(to)f(the)h(fact)f(that)h(the)g Fl(@<subroutine@>)c Fr(macro)j(is)g(nev)o(er)
+177 267 y(called.)18 b(Again,)12 b(a)h(quic)o(k)g(lo)q(ok)g(at)g(the)h
+(program)e(tells)h(us)h(that)f(this)h(is)f(a)g(mistak)o(e)f(\(and)h(a)g(v)o
+(ery)h(common)d(one)177 317 y(in)k(the)h(use)h(of)e(F)m(unnelW)m(eb\),)g(and)
+g(that)h(a)f(call)g(to)g(the)h Fl(@<subroutine@>)d Fr(macro)h(should)i(b)q(e)
+g(inserted)h(just)177 367 y(ab)q(o)o(v)o(e)d(the)g(call)f(to)h(the)h
+Fl(@<Main)20 b(Program@>)12 b Fr(macro)h(in)g(the)i(de\014nition)e(of)g
+Fl(@<hello.c@>)p Fr(.)177 443 y(These)g(t)o(w)o(o)f(cases)h(demonstrate)f(wh)
+o(y)g(these)h(c)o(hec)o(ks)h(ha)o(v)o(e)d(b)q(een)i(placed)g(in)e(F)m(unnelW)
+m(eb.)17 b(It)12 b(is)g(nearly)g(alw)o(a)o(ys)177 492 y(acceptable)k(for)f(a)
+f(macro)g(to)h(b)q(e)g(called)g(once.)22 b(Ho)o(w)o(ev)o(er,)15
+b(if)f(a)h(macro)f(is)g(not)h(called)g(at)g(all,)e(or)i(called)g(more)177
+542 y(than)f(once,)g(this)g(is)g(often)g(a)f(sign)h(that)g(the)g(user)h(has)f
+(made)f(a)h(mistak)o(e.)177 618 y(These)19 b(c)o(hec)o(ks)g(ha)o(v)o(e)e(a)g
+(dark)g(side)h(to)q(o.)28 b(In)18 b(addition)e(to)h(the)h(errors)h(men)o
+(tioned)d(ab)q(o)o(v)o(e,)i(F)m(unnelW)m(eb)f(has)177 668 y(generated)e(t)o
+(w)o(o)f(similar)d(errors)k(that)f(do)g(not)g(help)g(us.)177
+744 y(First,)h(w)o(e)f(are)h(alerted)g(to)f(the)h(fact)f(that)h(the)g
+Fl(@<print@>)d Fr(macro)h(has)i(b)q(een)g(called)f(t)o(wice.)20
+b(Clearly)m(,)13 b(in)h(this)177 794 y(case,)h(this)f(is)f(not)h(a)g
+(problem,)e(and)h(so)h(here)h(F)m(unnelW)m(eb's)f(fussiness)h(is)f(a)f(n)o
+(uisance.)177 870 y(Second,)22 b(w)o(e)e(are)g(alerted)g(to)g(the)g(fact)g
+(that)g(the)g Fl(@<scan@>)e Fr(macro)h(has)h(nev)o(er)g(b)q(een)h(called.)36
+b(Lik)o(e)19 b(the)177 920 y Fl(@<print@>)e Fr(macro,)h(this)g(macro)f(w)o
+(as)i(de\014ned)g(as)g(a)f(notational)f(con)o(v)o(enience,)j(and)e(clearly)h
+(it)f(do)q(es)h(not)177 969 y(matter)13 b(here)i(if)e(it)h(is)g(not)g(used.)k
+(Again,)13 b(F)m(unnelW)m(eb)g(is)h(b)q(eing)g(a)g(n)o(uisance.)177
+1045 y(The)19 b(four)f(cases)i(ab)q(o)o(v)o(e)e(demonstrate)h(the)g(ligh)o(t)
+e(and)h(dark)h(side)f(of)g(F)m(unnelW)m(eb's)g(insistence)i(that)e(eac)o(h)
+177 1095 y(macro)10 b(b)q(e)i(called)f(exactly)h(once.)17 b(T)m(o)11
+b(resolv)o(e)h(the)g(con\015ict)f(without)g(reducing)h(the)g(strength)g(of)f
+(the)h(c)o(hec)o(king,)177 1145 y(F)m(unnelW)m(eb)i(pro)o(vides)g(t)o(w)o(o)f
+(sp)q(ecial)h(sequences)j Fl(@Z)c Fr(\(for)h Fo(Z)p Fr(ero\))h(and)e
+Fl(@M)h Fr(\(for)g Fo(M)p Fr(an)o(y\))f(that)h(can)h(b)q(e)f(attac)o(hed)177
+1195 y(to)h(macro)e(de\014nitions.)20 b(Presence)e(of)c(the)h
+Fl(@Z)f Fr(tag)g(allo)o(ws)g(the)h(designated)g(macro)f(to)g(b)q(e)h(called)g
+(zero)g(times.)177 1245 y(Presence)j(of)c(the)i Fl(@M)e Fr(tag)h(allo)o(ws)e
+(the)j(designated)f(macro)f(to)h(b)q(e)g(called)g(more)f(than)h(once.)21
+b(A)15 b(single)g(macro)177 1294 y(ma)o(y)d(carry)j(b)q(oth)f(tags.)k(It)c
+(is)f(alw)o(a)o(ys)g(true)i(that)f(all)e(macros)i(are)g(allo)o(w)o(ed)e(to)i
+(b)q(e)h(called)e(exactly)h(once.)177 1370 y(Here)20 b(is)e(the)h(revised)g
+(program)e(with)h(the)h(errors)g(\014xed,)h(b)o(y)e(eliminating)d(or)k
+(adding)e(macro)g(calls,)i(or)f(b)o(y)177 1420 y(adding)13
+b(tags.)18 b(T)m(ry)c(pro)q(cessing)h(the)f(\014le)g(no)o(w.)k(There)d
+(should)f(b)q(e)g(no)g(errors.)177 1540 y Fl(@O@<hello.c@>==@{@)o(-)177
+1589 y(@<Include)20 b(Files@>)177 1639 y(@<Function@>)177 1689
+y(@<Main)h(Program@>)177 1739 y(@})177 1838 y(@$@<Main)f(Program@>==@{@-)177
+1888 y(main\(\))177 1938 y({)199 1988 y(doit\(\);)177 2038
+y(})177 2087 y(@})177 2187 y(@$@<Function@>==@{)o(@-)177 2237
+y(void)h(doit\(\))177 2287 y({)199 2337 y(int)g(i;)199 2386
+y(for)g(\(i=0;i<10;i++\))243 2436 y({)264 2486 y(@<Print@>)264
+2536 y(@<Print@>)243 2586 y(})177 2635 y(}@})177 2735 y(@$@<Print@>@M==@{@)o
+(-)177 2785 y(printf\("Hello)e(World!"\);)177 2835 y(printf\("\\n"\);@})1042
+2940 y Fr(24)p eop
+%%Page: 25 26
+25 25 bop 177 91 a Fl(@$@<Scan@>@Z==@{sc)o(anf@})177 191 y(@$@<Include)20
+b(Files@>==@{@-)177 241 y(#include)g(<stdio.h>)177 291 y(#include)g
+(<stdlib.h>@})177 450 y Fd(1.6.3)55 b(Inden)n(tation)177 560
+y Fr(The)14 b(b)q(o)q(dy)g(of)f(the)i Fl(print)d Fr(macro)h(of)g(the)h
+(previous)g(example)f(con)o(tains)g(t)o(w)o(o)g(lines)h(of)f(text.)19
+b(A)14 b(literal)e(substi-)177 610 y(tution)i(of)f(this)h(macro's)e(b)q(o)q
+(dy)i(in)g(its)g(con)o(text)g(w)o(ould)f(result)i(in:)243 741
+y Fl({)264 791 y(printf\("Hello)k(World!"\);)177 841 y(printf\("\\n"\);)264
+891 y(printf\("Hello)g(World!"\);)177 941 y(printf\("\\n"\);)243
+990 y(})177 1121 y Fr(But)c(instead,)e(it)h(comes)f(out)h(as)g(\(ha)o(v)o(e)g
+(a)g(lo)q(ok)e(at)i(this)g(part)g(of)f Fl(hello.c)g Fr(no)o(w\):)243
+1252 y Fl({)264 1302 y(printf\("Hello)19 b(World!"\);)264 1352
+y(printf\("\\n"\);)264 1402 y(printf\("Hello)g(World!"\);)264
+1452 y(printf\("\\n"\);)243 1502 y(})177 1633 y Fr(The)12 b(explanation)e(is)
+g(that)h(F)m(unnelW)m(eb)g(inden)o(ts)g(eac)o(h)h(line)e(of)h(m)o(ultili)o
+(ne)e(macros)h(b)o(y)h(the)g(lev)o(el)g(of)f(inden)o(tation)177
+1682 y(at)i(the)h(p)q(oin)o(t)e(of)g(call.)17 b(This)12 b(means)f(that,)h(as)
+g(in)f(the)i(case)g(ab)q(o)o(v)o(e,)e(program)g(texts,)i(whic)o(h)e(are)i
+(usually)e(highly)177 1732 y(inden)o(ted,)j(come)f(out)h(lo)q(oking)e(\\righ)
+o(t".)177 1813 y(In)i(other)h(circumstances,)g(where)g(the)g(mo)q(del)e(of)g
+(the)i(text)g(is)f(one)g(dimensional,)e(F)m(unnelW)m(eb's)h(inden)o(tation)
+177 1863 y(could)g(b)q(ecome)h(an)f(imp)q(edimen)o(t)e(or)i(ev)o(en)i(a)e
+(danger.)18 b(In)13 b(these)i(cases,)g(it)e(can)h(b)q(e)g(switc)o(hed)g
+(o\013)g(b)o(y)f(including)177 1912 y(the)i(F)m(unnelW)m(eb)e
+Fo(pragma)g Fr(line)177 2044 y Fl(@p)22 b(indentation)d(=)j(none)177
+2175 y Fr(an)o(ywhere)15 b(in)e(the)i(input)e(\014le.)177 2255
+y(One)19 b(of)f(the)h(design)f(goals)g(of)f(F)m(unnelW)m(eb)h(is)g(to)g(allo)
+o(w)f(the)i(user)g(total)f(con)o(trol)g(o)o(v)o(er)g(the)h(pro)q(duct)g
+(\014les.)177 2305 y(This)13 b(con)o(trasts)h(with)f(the)h(approac)o(h)f(of)g
+(Kn)o(uth's)g(WEB)g(system)g Fo([Kn)o(uth83])f Fr(\(up)q(on)h(whic)o(h)g(F)m
+(unnelW)m(eb)g(is)177 2355 y(based\),)18 b(whic)o(h)e(mangles)f(the)i(input)f
+(text)h(at)f(the)h(P)o(ascal)g(program)d(syn)o(tax)j(lev)o(el,)f(truncating)h
+(iden)o(ti\014ers,)177 2405 y(con)o(v)o(erting)e(the)g(text)g(to)f(upp)q(er)i
+(case,)f(and)f(paragraphing)g(text.)20 b(Here)c(is)e(an)g(example)f(of)h
+(part)h(of)f(a)g(P)o(ascal)177 2455 y(program)e(pro)q(duced)k(b)o(y)d(WEB)h
+(\(from)f(page)h(14)f(of)g Fo([Kn)o(uth83])p Fr(\):)177 2586
+y Fl(IF)22 b(R=0)f(THEN)g(XREF[P]:=XREFPTR)d(ELSE)j(XMEM[R].XLINKFIELD)o
+(:=XRE)o(FPTR;)o(END;{)o(:51})177 2635 y({58:}FUNCTION)e
+(IDLOOKUP\(T:EIGHTBIT)o(S\):NA)o(MEPO)o(INTER)o(;LABE)o(L)g(31;)177
+2685 y(VAR)i(I:0..LONGBUFSIZE;H:)o(0..HA)o(SHSIZ)o(E;K:0)o(..MA)o(XBYTE)o
+(S;W:0)o(..1;)177 2735 y(L:0..LONGBUFSIZE;P)o(:NAME)o(POINT)o(ER;BE)o(GIN)e
+(L:=IDLOC-IDFIRS)o(T;{59)o(:})177 2785 y(H:=BUFFER[IDFIRST])o(;I=ID)o(FIRST)o
+(+1;)177 2835 y(WHILE)i(I<IDLOC)f(DO)i(BEGIN)e(H:=\(H+H+BUFFER[I]\)M)o(OD)f
+(HASHSIZE;I=I+1;EN)o(D{:59)o(};)1042 2940 y Fr(25)p eop
+%%Page: 26 27
+26 26 bop 177 42 a Fr(Kn)o(uth's)13 b(theory)g(is)f(that)g(the)h(program)e
+(generated)i(b)o(y)f(a)g(literate)h(programmi)o(ng)c(system)k(should)f(b)q(e)
+h(treated)177 91 y(as)20 b(ob)r(ject)h(co)q(de)g(and)f(hence)h(should)f(lo)q
+(ok)f(lik)o(e)g(ob)r(ject)i(co)q(de)f(to)q(o.)36 b(While)20
+b(this)g(ma)o(y)e(b)q(e)i(an)g(admirable)177 141 y(approac)o(h)d(in)g(the)h
+(long)f(run,)h(the)f(presen)o(t)i(programming)14 b(en)o(vironmen)o(t)i(is)h
+(one)h(of)f(fault)o(y)f(compilers)g(and)177 191 y(buggy)c(to)q(ols.)18
+b(The)13 b(F)m(unnelW)m(eb)f(view)h(is)g(that,)f(in)g(this)h(en)o(vironmen)o
+(t,)f(the)h(programmer)e(needs)j(all)d(the)j(help)177 241 y(he)j(can)g(get)g
+(and)f(that)h(therefore)h(he)f(should)f(b)q(e)h(allo)o(w)o(ed)f(total)f(con)o
+(trol)i(o)o(v)o(er)f(the)h(pro)q(duct)h(\014le.)26 b(Another)177
+291 y(reason)12 b(for)g(F)m(unnelW)m(eb's)f(pro)o(viding)f(total)h(con)o
+(trol)g(o)o(v)o(er)h(the)g(pro)q(duct)h(\014le,)e(is)h(that)g(F)m(unnelW)m
+(eb)f(is)g(in)o(tended)177 340 y(to)17 b(b)q(e)i(target)e(language)g(indep)q
+(enden)o(t,)i(and)e(so)h(ev)o(en)g(if)f(Kn)o(uth's)g(view)h(w)o(ere)g
+(adopted,)g(it)f(w)o(ould)g(not)g(b)q(e)177 390 y(clear)d(what)g(a)g
+(legitimate)e(transformation)g(of)h(the)h(text)h(could)e(b)q(e.)177
+529 y Fd(1.6.4)55 b(Additiv)n(e)18 b(Macros)177 629 y Fr(Sometimes)c(it)i(is)
+h(con)o(v)o(enien)o(t)f(to)h(build)e(up)i(the)g(de\014nition)f(of)f(a)h
+(macro)g(in)f(stages)j(throughout)e(the)h(input)177 679 y(\014le.)h(In)13
+b(F)m(unnelW)m(eb,)g(this)g(can)g(b)q(e)h(done)g(using)f(an)g
+Fo(additiv)o(e)f(macro)p Fr(.)17 b(An)d(additiv)o(e)e(macro)g(is)h(iden)o
+(tical)g(to)177 728 y(an)h(ordinary)f(macro)g(except)i(that)228
+839 y(1.)20 b(It)14 b(has)g Fl(+=)f Fr(instead)i(of)e Fl(==)p
+Fr(.)228 920 y(2.)20 b(It)13 b(can)g(b)q(e)g(de\014ned)h(in)e(one)h(or)f
+(more)g(parts)h(throughout)g(the)g(input)g(\014le.)k(The)c(de\014nition)g(of)
+f(the)h(macro)281 970 y(is)h(the)g(concatenation)g(of)g(all)e(the)j(parts)f
+(in)g(the)g(order)h(in)e(whic)o(h)h(they)g(app)q(ear.)177 1080
+y(The)f(follo)o(wing)c(example)h(sho)o(ws)j(ho)o(w)e(additiv)o(e)g(macros)g
+(can)h(b)q(e)h(used)g(to)f(scatter)h(and)f(regroup)g(information,)177
+1130 y(in)k(this)h(case)g(assisting)g(in)f(the)h(lucid)f(construction)h(of)f
+(a)g(data)g(abstraction)h(in)f(a)g(language)g(\(P)o(ascal\))h(that)177
+1180 y(do)q(es)e(not)f(supp)q(ort)g(them)f(explicitly)m(.)177
+1290 y Fl(@!****************)o(*****)o(*****)o(****)177 1390
+y(@O@<prog.pas@>==@{)o(@-)177 1440 y(program)21 b(adt\(input,outpu)o(t\);)177
+1490 y(@<Types@>)177 1540 y(@<Variables@>)177 1589 y(@<Procedures@>)177
+1639 y(begin)g(startproc;)f(end.)177 1689 y(@})177 1789 y(@!****************)
+o(*****)o(*****)o(****)177 1888 y(@$@<Types@>+=@{@-)177 1938
+y(type)h(buffer_type)f(=)243 1988 y(record)243 2038 y(length)g(:)i(integer;)
+243 2087 y(buf)f(:)g(array[1..100])e(of)j(char;)243 2137 y(end;)177
+2187 y(@})177 2287 y(@$@<Variables@>+=@)o({@-)177 2337 y(bigbuf)f(:)g
+(buffer_type;)177 2386 y(@})177 2486 y(@$@<Procedures@>+=)o(@{@-)177
+2536 y(procedure)f(buf_init)g(\(var)h(b)h(:)f(buffer_type)325
+b(\))22 b({Body)e(of)i(buf_init})177 2586 y(procedure)e(buf_add)42
+b(\(var)21 b(b)h(:)f(buffer_type;)107 b(ch)21 b(:)h(char\))f({Body)f(of)i
+(buf_add})177 2635 y(procedure)e(buf_get)42 b(\(var)21 b(b)h(:)f
+(buffer_type;)f(var)h(ch)g(:)h(char\))f({Body)f(of)i(buf_get})177
+2685 y(@})177 2785 y(@!****************)o(*****)o(*****)o(****)1042
+2940 y Fr(26)p eop
+%%Page: 27 28
+27 27 bop 177 42 a Fl(@$@<Types@>+=@{@-)177 91 y(type)21 b(complex_type)e(=)j
+(record)f(r,i)g(:)g(real;)g(end;)177 141 y(@})177 241 y(@$@<Procedures@>+=)o
+(@{@-)177 291 y(procedure)f(cm_set)h(\(var)g(c:)g(complex_type;)e(a,b:)i
+(real\))195 b({Body)21 b(of)g(cm_set})177 340 y(procedure)f(cm_add)h(\(a,b:)f
+(complex_type;)g(var)h(c:)g(complex_type\))e({Body)i(of)g(cm_add})177
+390 y({Other)g(procedures)e(and)j(functions})177 440 y(@})177
+540 y(@!****************)o(*****)o(*****)o(****)177 639 y({...more)e(pieces)h
+(of)g(program...})177 739 y(@!****************)o(*****)o(*****)o(****)177
+853 y Fr(It)d(is)f(imp)q(ortan)o(t)f(to)h(remem)o(b)q(er)g(that)g(the)h
+(de\014nition)f(of)g(eac)o(h)h(macro)e(do)q(es)j(not)e(c)o(hange)h
+(throughout)f(the)177 903 y(input)c(\014le.)18 b(F)m(unnelW)m(eb)13
+b(parses)i(the)f(en)o(tire)g(input)f(\014le)h(and)f(assem)o(bles)g(all)f(the)
+i(macro)f(de\014nitions)g(b)q(efore)h(it)177 953 y(ev)o(en)h(starts)g(to)f
+(expand)h(macros.)j(As)d(a)f(result,)h(eac)o(h)f(additiv)o(e)g(macro)f(can)h
+(only)g(ha)o(v)o(e)g(one)g(de\014nition,)g(and)177 1003 y(that)g
+(de\014nition)g(is)f(the)i(concatenation)f(of)f(all)g(its)h(parts.)177
+1077 y(The)19 b(example)d(ab)q(o)o(v)o(e)i(sho)o(ws)g(ho)o(w)g(additiv)o(e)f
+(macros)g(can)h(b)q(e)h(used)g(to)e(rearrange)i(the)g(presen)o(tation)g(of)e
+(a)177 1126 y(computer)h(program)e(in)i(the)g(order)h(in)e(whic)o(h)h(the)g
+(user)h(wishes)g(to)f(discuss)h(it)e(rather)i(than)f(the)h(order)f(in)177
+1176 y(whic)o(h)h(the)h(compiler)d(requires)j(that)f(it)g(b)q(e)g(consumed.)
+33 b(It)19 b(is)g(easy)m(,)h(ho)o(w)o(ev)o(er,)g(to)f(abuse)g(the)h(feature)f
+(of)177 1226 y(additiv)o(e)c(macros.)24 b(In)15 b(man)o(y)f(cases,)k(the)e
+(same)f(e\013ect)j(can)e(b)q(e)h(obtained)e(more)g(clearly)h(b)o(y)g
+(replacing)f(eac)o(h)177 1276 y(part)d(of)e(an)h(additiv)o(e)g(macro)f
+(in-situ)h(using)g(uniquely)f(named)g(non-additiv)o(e)h(macros,)f(and)h(then)
+h(collect)g(them)177 1326 y(together)j(as)e(a)h(group)f(at)h(the)g(p)q(oin)o
+(t)f(where)i(the)f(additiv)o(e)f(macro)f(is)h(called.)18 b(Doing)12
+b(this)i(is)f(more)g(w)o(ork,)g(and)177 1376 y(is)i(more)e(error)j(prone,)e
+(but)h(can)g(result)g(in)f(a)h(clearer)g(exp)q(osition.)20
+b(The)15 b(follo)o(wing)d(program)h(illustrates)i(this)177
+1425 y(alternativ)o(e)f(approac)o(h.)177 1540 y Fl(@!****************)o
+(*****)o(*****)o(****)177 1639 y(@O@<prog.pas@>==@{)o(@-)177
+1689 y(program)21 b(adt\(input,outpu)o(t\);)177 1739 y(@<Types@>)177
+1789 y(@<Variables@>)177 1838 y(@<Procedures@>)177 1888 y(begin)g(startproc;)
+f(end.)177 1938 y(@})177 2038 y(@$@<Types@>==@{@-)177 2087
+y(@<Buffer)g(type@>)177 2137 y(@<Complex)g(type@>)177 2187
+y(@})177 2287 y(@$@<Variables@>==@)o({@-)177 2337 y(@<Buffer)g(variable@>)177
+2386 y(@})177 2486 y(@$@<Procedures@>==)o(@{@-)177 2536 y(@<Buffer)g
+(procedures@>)177 2586 y(@<Complex)g(procedures@>)177 2635
+y(@})177 2735 y(@!****************)o(*****)o(*****)o(****)177
+2835 y(@$@<Buffer)g(type@>==@{@-)1042 2940 y Fr(27)p eop
+%%Page: 28 29
+28 28 bop 177 42 a Fl(type)21 b(buffer_type)f(=)h(record)591
+91 y(length)g(:)g(integer;)591 141 y(buf)g(:)h(array[1..100])d(of)i(char;)591
+191 y(end;)177 241 y(@})177 340 y(@$@<Buffer)f(variable@>==@{@-)177
+390 y(bigbuf)h(:)g(buffer_type;)177 440 y(@})177 540 y(@$@<Buffer)f
+(procedures@>==@{@)o(-)177 589 y(procedure)g(buf_init\(var)f(b)j(:)g
+(buffer_type\))d({Body)i(of)g(buf_init})177 639 y(procedure)f(buf_add\(var)g
+(b)h(:)h(buffer_type;)d(ch)i(:)h(char\))f({Body)g(of)g(buf_add})177
+689 y(procedure)f(buf_get\(var)g(b)h(:)h(buffer_type;)d(var)i(ch)h(:)f
+(char\))g({Body)g(of)g(buf_get})177 739 y(@})177 839 y(@!****************)o
+(*****)o(*****)o(****)177 938 y(@$@<Complex)f(type@>==@{@-)177
+988 y(type)h(complex_type)e(=)j(record)f(r,i)g(:)g(real;)g(end;)177
+1038 y(@})177 1137 y(@$@<Complex)f(procedures@>+=@{)o(@-)177
+1187 y(procedure)g(cm_set\(var)g(c:)h(complex_type;)e(a,b)i(:)h(real\))43
+b({Body)20 b(of)i(cm_set})177 1237 y(procedure)e(cm_add\(a,b)g(:)h
+(complex_type;)f(var)h(c:)g(complex_type\))e({Body)i(of)g(cm_add})177
+1287 y({Other)g(procedures)e(and)j(functions})177 1337 y(@})177
+1436 y(@!****************)o(*****)o(*****)o(****)177 1536 y({...more)e
+(pieces)h(of)g(program...})177 1636 y(@!****************)o(*****)o(*****)o
+(****)177 1745 y Fr(One)16 b(of)e(adv)n(an)o(tages)g(of)g(F)m(unnelW)m(eb)g
+(\(and)h(literate)g(programmi)o(ng)d(in)i(general\))h(is)g(that)f(\(as)h(sho)
+o(wn)g(ab)q(o)o(v)o(e\))177 1794 y(it)d(allo)o(ws)f(the)i(user)g(to)f(la)o(y)
+f(out)h(the)h(program)e(in)g(whatev)o(er)i(order)g(is)f(desired)i(with)d
+(near)i(total)f(indep)q(endence)177 1844 y(from)g(the)j(ordering)f
+(requiremen)o(ts)g(of)f(the)i(target)f(programming)c(language.)177
+1917 y(Additiv)o(e)15 b(macros)f(are)h(allo)o(w)o(ed)f(to)h(b)q(e)h(tagged)f
+(with)f Fl(@Z)h Fr(and)g Fl(@M)g Fr(just)g(as)g(other)h(macros)e(can,)h(but)g
+(the)h(tags)177 1967 y(m)o(ust)9 b(app)q(ear)i(only)e(on)h(the)h(\014rst)g
+(de\014nition)f(of)g(the)g(macro.)16 b(Additiv)o(e)10 b(macros)f(cannot)i(b)q
+(e)f(connected)i(directly)177 2017 y(to)i(pro)q(duct)h(\014les.)177
+2155 y Fd(1.6.5)55 b(P)n(arameterized)17 b(Macros)177 2254
+y Fr(No)c(self-resp)q(ecting)i(macro)d(prepro)q(cessor)k(w)o(ould)c(b)q(e)i
+(complete)e(without)h(some)f(form)g(of)g(macro)g(parameter-)177
+2304 y(ization,)h(and)h(F)m(unnelW)m(eb)g(is)g(no)g(exception.)20
+b(F)m(unnelW)m(eb)14 b(allo)o(ws)f(eac)o(h)i(macro)e(to)h(ha)o(v)o(e)g(from)e
+(zero)k(to)e(nine)177 2354 y(formal)e(parameters)i(named)e
+Fl(@1)p Fr(,)h Fl(@2)p Fr(,)g Fl(@3)p Fr(,)g Fl(@4)p Fr(,)g
+Fl(@5)p Fr(,)g Fl(@6)p Fr(,)g Fl(@7)p Fr(,)g Fl(@8)p Fr(,)g(and)h
+Fl(@9)p Fr(.)177 2427 y(T)m(o)d(de\014ne)i(a)f(macro)f(with)h(one)g(or)g
+(more)f(parameters,)h(insert)g(a)g(formal)e(parameter)h(list)h(just)g(after)g
+(the)h(macro)177 2476 y(name)g(in)h(the)h(macro)f(de\014nition.)19
+b(Because)d(macro)e(parameters)g(ha)o(v)o(e)g(\014xed)h(names)f(\()p
+Fl(@1)p Fn(:)7 b(:)g(:)n Fl(@9)p Fr(\),)14 b(there)i(is)e(no)177
+2526 y(need)19 b(to)e(sp)q(ecify)h(the)g(names)e(of)h(formal)e(parameters)j
+(in)f(the)h(formal)d(parameter)i(list.)28 b(All)16 b(that)i(need)g(b)q(e)177
+2576 y(con)o(v)o(ey)o(ed)c(is)g(ho)o(w)f(man)o(y)f(parameters)i(the)g(macro)e
+(has.)19 b(Here)c(is)e(an)h(example)e(of)h(the)h(de\014nition)g(of)f(a)g
+(macro)177 2626 y(ha)o(ving)g(three)i(parameters:)177 2735
+y Fl(@$@<While)20 b(loop@>@\(@3@\)@M==@{)o(@-)177 2785 y(@1)177
+2835 y(while)h(\(@2\))1042 2940 y Fr(28)p eop
+%%Page: 29 30
+29 29 bop 221 42 a Fl({)243 91 y(@3)221 141 y(})177 191 y(@})177
+310 y Fr(T)m(o)11 b(call)g(a)g(parameterized)h(macro,)e(an)i(actual)f
+(parameter)g(list)h(m)o(ust)e(b)q(e)i(supplied)g(that)g(con)o(tains)f
+(exactly)h(the)177 360 y(same)j(n)o(um)o(b)q(er)g(of)f(actual)i(parameters)f
+(as)h(there)g(are)g(formal)d(parameters)j(in)f(the)h(de\014nition)f(of)g(the)
+h(macro)177 410 y(b)q(eing)h(called.)26 b(An)16 b(actual)h(parameter)f(list)g
+(is)h(delimited)d(b)o(y)j Fl(@\()f Fr(and)g Fl(@\))p Fr(,)h(and)f(parameters)
+h(are)g Fm(sep)n(ar)n(ate)n(d)177 459 y Fr(b)o(y)c(\\)p Fl(@,)p
+Fr(".)k(The)c(actual)g(parameters)g(themselv)o(es)h(are)f(general)h(F)m
+(unnelW)m(eb)e(expressions)j(\(see)f(Chapter)g(3)f(for)177
+509 y(the)g(exact)g(syn)o(tax\))f(and)h(can)f(b)q(e)h(inserted)h(in)o(to)d
+(the)i(list)f(directly)g(or)h(can)f(b)q(e)h(delimited)e(b)o(y)h
+Fl(@")g Fr(so)g(as)g(to)g(allo)o(w)177 559 y(some)j(white)g(space)h(to)f
+(assist)h(in)f(formatting)e(the)j(actual)e(parameters.)23 b(Here)16
+b(are)g(some)e(examples)h(of)f(calls)177 609 y(of)f(the)i Fl(While)21
+b(loop)13 b Fr(macro)f(de\014ned)j(ab)q(o)o(v)o(e.)177 728
+y Fl(@!)22 b(First)e(form)h(of)h(actual)e(parameters)g(without)g(whitespace)g
+(and)h(double)g(quotes.)177 778 y(@<While)g(loop@>@\(x=1;@,x)o(<=10@)o(,prin)
+o(tf\("X)o(=\045u\\)o(n",x\))o(;@\))177 877 y(@!)h(Second)e(form)h(of)g
+(actual)g(parameters.)f(The)h(double)f(quotes)h(allow)g(non-active)177
+927 y(@!)h(whitespace)d(that)i(helps)g(to)g(lay)h(out)f(the)g(actual)f
+(parameters)g(neatly.)177 977 y(@!)i(This)f(call)f(is)i(functionally)d
+(identical)h(to)h(the)h(one)f(above.)177 1027 y(@<While)g(loop@>@\()243
+1076 y(@"x:=1;@")e(@,)243 1126 y(@"x<=10@")g(@,)243 1176 y
+(@"printf\("X=\045u\\)o(n",x\))o(;@")g(@\))177 1276 y(@!)j(The)f(two)g(forms)
+g(can)g(be)g(mixed)g(in)g(a)h(single)e(call.)177 1325 y(@<While)h
+(loop@>@\(x=1;@,x)o(<=10@)o(,)482 1375 y(@"printf\("X=\045u\\n",x)o(\);@")d
+(@\))177 1494 y Fr(A)h(few)g(rules)g(ab)q(out)f(parameterized)h(macros)f(are)
+h(w)o(orth)g(men)o(tioning.)30 b(Macros)19 b(that)g(do)f(not)h(ha)o(v)o(e)f
+(an)o(y)177 1544 y(parameters)c(m)o(ust)f(ha)o(v)o(e)g(no)h(formal)d(or)j
+(actual)g(parameter)f(lists.)18 b(Additiv)o(e)c(macros)f(can)h(ha)o(v)o(e)f
+(parameters,)177 1594 y(but)h(the)h(formal)c(parameter)j(list)f(m)o(ust)g
+(app)q(ear)h(in)g(the)g(\014rst)h(de\014nition)e(part)h(only)m(.)177
+1670 y(Here)k(is)f(another)g(example)e(of)h(the)h(use)h(of)e(parameterized)g
+(macros.)26 b(This)16 b(time,)g(parameters)h(and)f(macro)177
+1719 y(calls)g(are)g(used)g(in)g(a)f(F)m(unnelW)m(eb)g(input)h(\014le)g(that)
+g(constructs)h(an)f Fn(O)q Fr(\()p Fn(n)p Fr(\))g(represen)o(tation)h(of)e(a)
+h(song)f(whose)177 1769 y(full)e(size)h(is)g Fn(O)q Fr(\()p
+Fn(n)444 1754 y Fg(2)463 1769 y Fr(\))g(in)f(the)i(n)o(um)o(b)q(er)e
+Fn(n)h Fr(of)f(unique)h(lines.)177 1938 y Fl(@O@<Twelve_bugs.tx)o(t@>==)o
+(@{@-)177 1988 y(The)21 b(Twelve)g(Bugs)g(of)g(Christmas)177
+2038 y(------------------)o(-----)o(-----)177 2087 y(@<Verse@>@\(@"first)o
+(@")84 b(@,@<1@>@\))177 2137 y(@<Verse@>@\(@"secon)o(d@")62
+b(@,@<2@>@\))177 2187 y(@<Verse@>@\(@"third)o(@")84 b(@,@<3@>@\))177
+2237 y(@<Verse@>@\(@"fourt)o(h@")62 b(@,@<4@>@\))177 2287 y
+(@<Verse@>@\(@"fifth)o(@")84 b(@,@<5@>@\))177 2337 y(@<Verse@>@\(@"sixth)o
+(@")g(@,@<6@>@\))177 2386 y(@<Verse@>@\(@"seven)o(th@")40 b(@,@<7@>@\))177
+2436 y(@<Verse@>@\(@"eight)o(h@")62 b(@,@<8@>@\))177 2486 y
+(@<Verse@>@\(@"ninth)o(@")84 b(@,@<9@>@\))177 2536 y(@<Verse@>@\(@"tenth)o
+(@")g(@,@<A@>@\))177 2586 y(@<Verse@>@\(@"eleve)o(nth@")18
+b(@,@<B@>@\))177 2635 y(@<Verse@>@\(@"twelf)o(th@")40 b(@,@<C@>@\))177
+2735 y(This)21 b(song)g(appeared)f(in)i(the)f(internet)f(newsgroup)g
+(rec.humor.funny)f(on)i(24-Dec-1991.)177 2785 y(It)h(was)f(contributed)e(by)j
+(Pat)f(Scannell)f(\(scannell@@darkst)o(ar.ma)o(30.bu)o(ll.co)o(m\).)177
+2835 y(@})1042 2940 y Fr(29)p eop
+%%Page: 30 31
+30 30 bop 177 91 a Fl(@$@<Verse@>@\(@2@\)@)o(M==@{)o(@-)177
+141 y(For)21 b(the)h(@1)f(bug)g(of)g(Christmas,)f(my)i(manager)e(said)h(to)g
+(me)286 191 y(@2)177 241 y(@})177 340 y(@$@<1@>@M==@{See)e(if)i(they)g(can)g
+(do)h(it)f(again.@})177 390 y(@$@<2@>@M==@{Ask)e(them)i(how)g(they)g(did)g
+(it)g(and@+@<1@>@})177 440 y(@$@<3@>@M==@{Try)e(to)i(reproduce)f(it@+@<2@>@})
+177 490 y(@$@<4@>@M==@{Run)f(with)i(the)g(debugger@+@<3@>@)o(})177
+540 y(@$@<5@>@M==@{Ask)e(for)i(a)g(dump@+@<4@>@})177 589 y
+(@$@<6@>@M==@{Reins)o(tall)d(the)k(software@+@<5@>)o(@})177
+639 y(@$@<7@>@M==@{Say)d(they)i(need)g(an)g(upgrade@+@<6@>@})177
+689 y(@$@<8@>@M==@{Find)d(a)k(way)f(around)g(it@+@<7@>@})177
+739 y(@$@<9@>@M==@{Blame)d(it)k(on)f(the)g(hardware@+@<8@>@})177
+789 y(@$@<A@>@M==@{Chang)o(e)e(the)i(documentation@+@<9)o(@>@})177
+839 y(@$@<B@>@M==@{Say)e(it's)i(not)g(supported@+@<A@>)o(@})177
+888 y(@$@<C@>@M==@{Tell)d(them)j(it's)g(a)h(feature@+@<B@>@})177
+1028 y Fd(1.6.6)55 b(Macro)19 b(Expansion)177 1128 y Fr(One)g(of)f(the)g
+(strengths)i(of)d(F)m(unnelW)m(eb)h(is)g(that,)h(when)f(writing)g(pro)q(duct)
+h(\014les,)g(it)f(do)q(es)h(not)f(attempt)f(to)177 1178 y(ev)n(aluate)g(an)o
+(y)f(text)h(expression)h(\(e.g.)e(text)h(blo)q(c)o(k,)g(parameter,)g(macro)e
+(call\))h(in)g(memory)f(and)h(then)h(write)177 1228 y(the)f(result)f(out.)22
+b(Instead,)15 b(it)g(alw)o(a)o(ys)f(writes)h(out)g(what)g(it)g(is)f
+(expanding)h(dynamically)d(and)j(directly)m(.)21 b(This)177
+1277 y(means)13 b(that)h(the)h(user)f(need)h(not)f(fear)g(de\014ning)g
+(macros)f(that)h(expand)g(to)f(h)o(uge)h(amoun)o(ts)f(of)g(text)h(and)g(then)
+177 1327 y(calling)d(those)i(macros)e(in)g(other)i(macros,)e(or)h(passing)g
+(those)h(h)o(uge)f(macros)f(as)h(parameters)h(to)e(other)i(macros.)177
+1377 y(In)f(all)e(cases,)i(F)m(unnelW)m(eb)f(expands)h(directly)g(to)f(the)h
+(pro)q(duct)g(\014le,)g(and)f(there)i(can)e(b)q(e)h(no)f(danger)h(in)f
+(running)177 1427 y(out)i(of)f(memory)f(during)i(expansion)f(\(except)j(for)e
+(running)f(out)h(of)f(stac)o(k)i(space)g(and)f(other)g(marginally)d(used)177
+1477 y(resources)16 b(in)e(pathological)e(cases\).)177 1550
+y(The)17 b(only)e(thing)h(to)f(remem)o(b)q(er)h(in)f(this)h(regard)h(is)f
+(that)g(F)m(unnelW)m(eb)g(alw)o(a)o(ys)f(stores)i(the)g(en)o(tire)f
+Fm(input)h Fr(\014le)177 1600 y(and)d(all)f(included)h(\014les,)f(in)h(their)
+g(en)o(tiret)o(y)h(in)e(memory)m(,)d(for)k(the)g(duration)g(of)f(the)i(run.)
+177 1674 y(Here)g(is)f(an)g(example,)e(that)i(illustrates)g(ho)o(w)f(robust)i
+(F)m(unnelW)m(eb)e(is:)177 1786 y Fl(@!)22 b(FunnelWeb)d(copes)i(well)g(with)
+g(the)g(following)f(macro)h(definitions.)177 1835 y(@!)h(\(Providing)d(that)i
+(it)h(has)f(a)g(little)g(over)g(ten)g(megabytes)f(of)h(memory\).)177
+1935 y(@O@<woppa.txt@>==@)o({@<Qu)o(ote@>)o(@\(@<H)o(umung)o(eous)o(@>@\)@)o
+(+@})177 2035 y(@$@<Quote@>@\(@1@\)=)o(=@{"@)o(1"@})177 2134
+y(@$@<Humungeous@>==)o(@{@-)177 2184 y(...Ten)g(Megabytes)f(of)h(Text...)177
+2234 y(@})177 2373 y Fd(1.6.7)55 b(Include)18 b(Files)177 2474
+y Fr(F)m(unnelW)m(eb)i(pro)o(vides)g(a)g(nested)i(include)e(\014le)h(facilit)
+o(y)d(that)i(can)h(b)q(e)g(used)g(for)f(a)g(n)o(um)o(b)q(er)f(of)h(purp)q
+(oses.)177 2523 y(When)c(F)m(unnelW)m(eb)f(runs)h(in)o(to)f(a)h(single)f
+(line)g(con)o(taining)f(the)j(sp)q(ecial)e(sequence)j Fl(@i)d
+Fr(follo)o(w)o(ed)f(b)o(y)i(a)f(blank,)177 2573 y(follo)o(w)o(ed)10
+b(b)o(y)g(a)h(\014le)g(name,)f(it)g(reads)i(in)f(the)g(designated)h(\014le)f
+(and)g(replaces)h(the)g(line)e(con)o(taining)g(the)i(command)177
+2623 y(\(including)h(the)g(end)h(of)f(line)f(mark)o(er)h(at)g(the)h(end)f(of)
+g(the)h(line\))f(with)g(the)g(en)o(tire)h(con)o(ten)o(ts)h(of)d(the)i
+(designated)177 2673 y(\014le.)k(F)m(or)c(example,)e(if)h(there)i(w)o(as)f(a)
+f(\014le)h(called)g Fl(camera.txt)e Fr(con)o(taining)g(the)j(t)o(w)o(o)e
+(lines:)177 2785 y Fl('Cos)21 b(I)h(shoot)e(with)h(a)h(camera)f(instead)f(of)
+h(a)h(gun.)177 2835 y(The)f(animals)g(flock)f(to)i(be)f(petted)g(and)g(fed,)
+1042 2940 y Fr(30)p eop
+%%Page: 31 32
+31 31 bop 177 42 a Fr(and)14 b(another)g(\014le)g(called)g
+Fl(poem.fw)e Fr(con)o(taining)h(the)h(follo)o(wing)e(four)h(lines)177
+152 y Fl(I)22 b(like)f(to)g(go)g(shooting,)f(it's)h(a)h(whole)f(lot)g(of)g
+(fun,)177 202 y(@i)h(camera.txt)177 251 y(Cos)f(they)g(know)g(my)h(camera)e
+(isn't)h(loaded)g(with)f(lead.)177 301 y(-)i(RNW,)f(04-Jan-1991.)177
+412 y Fr(Then,)14 b(if)f(F)m(unnelW)m(eb)g(w)o(ere)i(to)f(pro)q(cess)i
+Fl(poem.fw)p Fr(,)c(the)i(result)h(w)o(ould)e(b)q(e)h(as)g(if)f(F)m(unnelW)m
+(eb)h(had)f(read)i(in:)177 522 y Fl(I)22 b(like)f(to)g(go)g(shooting,)f(it's)
+h(a)h(whole)f(lot)g(of)g(fun,)177 572 y('Cos)g(I)h(shoot)e(with)h(a)h(camera)
+f(instead)f(of)h(a)h(gun.)177 621 y(The)f(animals)g(flock)f(to)i(be)f(petted)
+g(and)g(fed,)177 671 y('Cos)g(they)g(know)g(my)g(camera)g(isn't)g(loaded)f
+(with)h(lead.)177 721 y(-)h(RNW,)f(04-Jan-1991.)177 831 y Fr(F)m(unnelW)m(eb)
+11 b(expands)g(include)g(\014les)h(b)q(efore)f(it)g(starts)h(scanning)f(and)g
+(parsing)f(the)i(included)f(text.)18 b(The)11 b(result)177
+881 y(is)17 b(that)f(include)h(\014les)g(can)g(con)o(tain)f(an)o(ything)g
+(that)g(can)h(b)q(e)g(found)g(in)f(a)g(F)m(unnelW)m(eb)g(\014le.)26
+b(The)17 b(follo)o(wing)177 931 y(example)c(illustrates)h(the)g(lev)o(el)g
+(at)g(whic)o(h)f(the)i(include)f(mec)o(hanism)d(op)q(erates.)20
+b(If)13 b Fl(main.fw)g Fr(con)o(tains)177 1041 y Fl(@O@<output.dat@>==)o
+(@{@-)177 1091 y(@i)22 b(inc.fw)177 1141 y(This)f(is)h(the)f(text)g(of)g(the)
+g(sloth)g(macro.)177 1191 y(@})177 1301 y Fr(and)14 b(inc.fw)f(con)o(tains)
+177 1411 y Fl(@<Sloth@>)177 1461 y(@})177 1561 y(@$@<Sloth@>==@{@-)177
+1671 y Fr(Then)i(if)e(F)m(unnelW)m(eb)g(w)o(ere)i(applied)e(to)h
+Fl(main.fw)p Fr(,)e(it)h(w)o(ould)g(see:)177 1781 y Fl(@O@<output.dat@>==)o
+(@{@-)177 1831 y(@<Sloth@>)177 1881 y(@})177 1981 y(@$@<Sloth@>==@{@-)177
+2030 y(This)21 b(is)h(the)f(text)g(of)g(the)g(sloth)g(macro.)177
+2080 y(@})177 2190 y Fr(whic)o(h)c(it)g(w)o(ould)f(pro)q(cess)j(in)e(the)h
+(normal)d(manner.)27 b(The)18 b(only)e(sp)q(ecial)h(sequence)j(pro)q(cessing)
+e(that)f(tak)o(es)177 2240 y(place)12 b(at)g(a)f(lev)o(el)h(lo)o(w)o(er)f
+(than)h(include)g(\014les)g(is)g(the)g(pro)q(cessing)h(of)e(the)h
+Fl(<special>=<newspecia)o(l>)d Fr(sequence)177 2290 y(whic)o(h)14
+b(c)o(hanges)h(the)f(sp)q(ecial)g(c)o(haracter.)177 2363 y(A)g(few)f(other)h
+(facts)g(ab)q(out)f(include)g(\014les)h(are)g(w)o(orth)f(men)o(tioning)e
+(here.)19 b(Include)14 b(\014les)g(inherit)f(the)h(directory)177
+2413 y(sp)q(eci\014cation)k(supplied)g(using)f(the)h Fl(+I)f
+Fr(command)e(line)i(option.)28 b(The)17 b(sp)q(ecial)h(c)o(haracter)h(is)e
+(sa)o(v)o(ed)h(at)f(the)177 2463 y(start)e(of)e(eac)o(h)h(include)g(\014le)g
+(and)g(restored)i(to)d(its)h(previous)h(v)n(alue)e(at)h(the)g(end)g(of)g(eac)
+o(h)g(include)g(\014le.)k(Include)177 2513 y(\014les)c(can)g(b)q(e)g(nested)h
+(up)f(to)f(ten)i(lev)o(els.)i(Recursiv)o(e)e(included)f(\014les)g(will)e(alw)
+o(a)o(ys)g(cause)j(an)e(in\014nite)h(recursion)177 2562 y(as)f(there)h(is)e
+(no)g(b)q(ottoming)f(out)h(mec)o(hanism)e(a)o(v)n(ailable.)16
+b(Include)d(\014les)g(m)o(ust)e(con)o(tain)h(an)h(in)o(teger)g(n)o(um)o(b)q
+(er)e(of)177 2612 y(lines)i(\(i.e.)g(the)h(last)f(line)g(m)o(ust)f(b)q(e)i
+(terminated)e(with)h(an)g(end)h(of)f(line)g(mark)o(er\).)k(Once)d(F)m(unnelW)
+m(eb)f(has)g(seen)177 2662 y(\\)p Fl(@i)21 b Fr(")14 b(at)g(the)h(start)f(of)
+g(a)f(line,)h(it)f(will)g(grab)h(the)g(rest)i(of)d(the)i(line)e(ra)o(w)h(and)
+g(treat)h(it)e(as)h(a)g(\014le)g(name.)k(There)177 2712 y(is)c(no)g(place)g
+(on)f(the)i(line)e(for)h(things)f(lik)o(e)h(F)m(unnelW)m(eb)f(commen)o(ts)f
+(\(see)j(later\))f(or)g(extraneous)h(text.)177 2785 y(Include)21
+b(\014les)f(can)h(b)q(e)f(used)h(for)f(man)o(y)e(purp)q(oses,)23
+b(but)d(are)g(particularly)g(useful)g(for)g(hauling)e(in)i(macro)177
+2835 y(libraries.)1042 2940 y(31)p eop
+%%Page: 32 33
+32 32 bop 177 42 a Fi(1.7)70 b(T)n(yp)r(esetting)21 b(F)-6
+b(acilitie)o(s)177 158 y Fr(The)14 b(\014rst)g(half)e(of)g(this)h(tutorial)f
+(fo)q(cuses)j(solely)d(on)h(the)h(macro)e(facilities)g(of)g(F)m(unnelW)m(eb)h
+(\(whic)o(h)g(it)g(more)f(or)177 208 y(less)j(co)o(v)o(ers)g(completely\).)i
+(As)e(a)e(result,)i(the)f(example)f(do)q(cumen)o(ts)h(y)o(ou)f(ha)o(v)o(e)h
+(seen)i(so)e(far)f(ha)o(v)o(e)h(b)q(een)h(gross)177 257 y(distortions)k(of)g
+(\\normal")e(F)m(unnelW)m(eb)h(do)q(cumen)o(ts)h(whic)o(h)g(often)h(con)o
+(tain)e(as)i(m)o(uc)o(h)e(do)q(cumen)o(tation)g(as)177 307
+y(co)q(de.)270 292 y Fg(3)307 307 y Fr(While)12 b(there)j(are)e(applications)
+f(where)i(F)m(unnelW)m(eb)e(can)i(b)q(e)f(used)h(solely)e(as)h(a)g(macro)f
+(prepro)q(cessor,)177 357 y(most)h(applications)g(will)f(use)j(its)f(t)o(yp)q
+(esetting)h(facilities)d(as)i(w)o(ell.)177 432 y(This)g(section)h(restores)g
+(the)g(balance)f(in)f(this)h(tutorial)f(b)o(y)h(presen)o(ting)h(F)m(unnelW)m
+(eb's)e(t)o(yp)q(esetting)i(facilities.)177 574 y Fd(1.7.1)55
+b(Ov)n(erview)177 676 y Fr(The)12 b(macro)e(de\014nitions)h(discussed)h(in)f
+(the)h(macro)e(tutorial)g(completely)g(de\014ne)i(the)g(con)o(ten)o(ts)g(of)e
+(the)i(pro)q(duct)177 726 y(\014les)19 b(that)f(F)m(unnelW)m(eb)f(will)g
+(generate.)32 b(These)19 b(macro)e(de\014nitions)h(can)g(b)q(e)h(arranged)f
+(in)g(an)o(y)f(order)i(and)177 776 y(nothing)14 b(external)g(to)g(them)f(can)
+i(a\013ect)g(the)g(con)o(ten)o(ts)g(of)e(the)i(pro)q(duct)g(\014les.)k(The)c
+(macros)e(can)h(b)q(e)h(though)o(t)177 826 y(of)e(as)h(a)g(group)g(of)f
+(self-con)o(tained)h(islands.)177 901 y(Although)f(F)m(unnelW)m(eb)f(will)g
+(can)i(pro)q(cess)h(the)e(macros)g(all)f(on)h(their)g(o)o(wn,)g(the)g(full)f
+(p)q(o)o(w)o(er)i(of)e(F)m(unnelW)m(eb)h(is)177 950 y(realized)i(only)f(when)
+i(the)f(macros)f(are)i(surrounded)g(b)o(y)e(a)h(sea)g(of)f(do)q(cumen)o
+(tation.)20 b(This)15 b(sea)g(can)g(tak)o(e)g(t)o(w)o(o)177
+1000 y(forms:)j(directiv)o(es)d(and)f(free)h(text.)20 b(Some)13
+b(of)h(the)h(directiv)o(es)g(con)o(trol)f(things)g(suc)o(h)h(as)g(the)g
+(maxim)n(um)10 b(input)177 1050 y(line)f(length.)17 b(Ho)o(w)o(ev)o(er,)10
+b(most)f(of)f(them)h(are)h(t)o(yp)q(esetting)h(directiv)o(es)f(that)g
+(a\013ect)g(the)h(prin)o(ted)e(do)q(cumen)o(tation.)177 1100
+y(Th)o(us)j(a)g(F)m(unnelW)m(eb)g(do)q(cumen)o(t)f(can)h(b)q(e)h(view)o(ed)f
+(as)g(a)g(sequence)i(of)d Fo(macro)j(de\014niti)o(ons)o Fr(,)9
+b Fo(directiv)o(es)p Fr(,)g(and)177 1150 y Fo(free)15 b(text)p
+Fr(.)177 1225 y(Unlik)o(e)10 b(the)i(pro)q(duct)f(\014les)g(whic)o(h)g
+(consist)g(of)g(unscram)o(bled)f(macro)f(calls,)i(the)g(do)q(cumen)o(tation)f
+(\014le)g(is)h(more)f(or)177 1274 y(less)g(a)f(direct)h(represen)o(tation)h
+(of)e(the)h(input)f(\014le.)17 b(Eac)o(h)9 b(part)h(of)f(the)h(input)f
+(\014le)g(app)q(ears)h(in)f(the)h(do)q(cumen)o(tation)177 1324
+y(\014le)h(in)f(the)h(order)h(in)e(whic)o(h)h(it)f(app)q(ears)i(in)e(the)h
+(input)g(\014le.)17 b(Ho)o(w)o(ev)o(er,)11 b(eac)o(h)g(di\013eren)o(t)h(kind)
+e(of)g(part)h(is)g(t)o(yp)q(eset)1929 1309 y Fg(4)177 1374
+y Fr(in)i(a)g(di\013eren)o(t)i(manner.)i(Macros)d(are)g(t)o(yp)q(eset)h(in)e
+(a)g(particular)g(st)o(yle,)h(with)f(the)h(macro)e(b)q(o)q(dy)i(app)q(earing)
+f(in)177 1424 y Fl(tt)22 b(font)11 b Fr(\(see)i(some)e(F)m(unnelW)m(eb)h
+(prin)o(ted)g(do)q(cumen)o(tation)f(for)h(an)f(example\).)17
+b(T)o(yp)q(esetter)d(directiv)o(es)f(ha)o(v)o(e)177 1474 y(sp)q(eci\014c)j
+(de\014ned)f(e\013ects)h(\(more)d(later\).)18 b(F)m(ree)d(text)f(is)g(t)o(yp)
+q(eset)h(exactly)f(as)g(it)g(is,)f(except)i(that)f(eac)o(h)h(blo)q(c)o(k)e
+(of)177 1524 y(text)i(b)q(et)o(w)o(een)g(blank)e(lines)h(is)g(\014lled)f(and)
+h(justi\014ed)g(as)g(a)g(paragraph.)177 1599 y(The)f(follo)o(wing)d(example)i
+(demonstrates)h(ho)o(w)f(all)f(this)i(w)o(orks.)k(T)o(yp)q(e)c(in)g(the)g
+(follo)o(wing)d(as)i Fl(example.fw)f Fr(and)177 1648 y(run)k(it)g(through)f
+(F)m(unnelW)m(eb)g(with)h(the)g(command)d(\\)p Fl(fw)21 b(example)g(+t)p
+Fr(".)e(The)c(\\)p Fl(+t)p Fr(")f(instructs)i(F)m(unnelW)m(eb)177
+1698 y(to)j(generate)h(a)f(do)q(cumen)o(tation)f(\014le)h(called)g
+Fl(example.tex)p Fr(.)31 b(Run)19 b(the)g(\014le)g(through)h(T)1643
+1707 y(E)1666 1698 y(X)f(and)g(prin)o(t)g(it.)177 1748 y(Examine)13
+b(the)h(\014les)g Fl(example.out)e Fr(and)i Fl(example.tex)p
+Fr(.)177 1865 y Fl(You)21 b(are)h(reading)e(some)h(free)g(text)g(before)f
+(the)h(macro.)g(Free)g(text)g(can)g(consist)177 1915 y(of)h(any)f(text)g
+(\(not)g(containing)e(the)j(FunnelWeb)d(special)i(character\))f(including)177
+1965 y(typesetter)g(commands)177 2014 y(such)h(as)h($,)f(\045,)g(#,)h(and)f
+(\\TeX{})f(which)177 2064 y(will)h(be)h(typeset)e(to)h(appear)g(exactly)f(as)
+i(they)e(do)i(in)f(the)g(input)g(file!)177 2114 y(Look)g(out!)g(Here)g(comes)
+g(a)g(macro!)177 2214 y(@O@<example.out@>=)o(=@{@-)177 2263
+y(This)g(text)g(is)g(part)g(of)177 2313 y(a)h(macro)f(definition.)177
+2363 y(@})177 2463 y(This)g(is)h(free)e(text)h(following)f(the)i(macro.)e
+(This)h(sentence)f(contains)177 2513 y(two)h(@{inline@})f(typesetter)g
+(@/directives@/.)177 2562 y(Now)h(here)g(is)h(a)f(non-inline)f(typesetting)g
+(directive.)p 177 2599 709 2 v 223 2626 a Ff(3)241 2637 y Fh(As)12
+b(an)f(example,)e(the)h(author)g(used)h(F)m(unnelW)m(eb)e(to)i(dev)o(elop)f
+(a)h(largish)f(computer)f(program)g(and)i(found)f(that)g(on)h(a)o(v)o(erage)
+177 2677 y(his)g(st)o(yle)g(of)g(using)f(F)m(unnelW)m(eb)g(resulted)f(in)j
+(ab)q(out)d(30\045)j(do)q(cumen)o(ta)o(tion)c(and)j(70\045)g(macros)f(\(co)q
+(de\))g(\(measured)e(b)o(y)j(n)o(um)o(b)q(ers)177 2716 y(of)g(lines\).)223
+2744 y Ff(4)241 2756 y Fh(Here)i(the)h(term)e(\\t)o(yp)q(eset")g(is)i(used)f
+(lo)q(osely)f(to)i(refer)e(to)i(F)m(unnelW)m(eb's)e(generation)f(of)i(t)o(yp)
+q(esetter)f(commands)f(for)i(eac)o(h)177 2795 y(construct)e(in)h(the)g(input)
+g(\014le.)18 b(Strictly)m(,)11 b(the)h(term)g(should)f(b)q(e)i(used)f(only)f
+(to)i(describ)q(e)e(the)h(actions)f(of)h(a)h(t)o(yp)q(esetter)d(program)177
+2835 y(\(e.g.)h(T)275 2842 y(E)295 2835 y(X\).)1042 2940 y
+Fr(32)p eop
+%%Page: 33 34
+33 33 bop 177 91 a Fl(@t)22 b(new_page)177 191 y(This)f(sentence)f(will)h
+(appear)g(on)g(the)g(next)g(page.)177 312 y Fr(A)o(t)12 b(the)h(top)e(of)h
+(the)g Fl(example.tex)d Fr(do)q(cumen)o(tation)i(\014le)h(will)e(b)q(e)j(a)e
+(set)i(of)e(T)1383 321 y(E)1406 312 y(X)h(macro)f(de\014nitions.)17
+b(The)c(T)1895 321 y(E)1918 312 y(X)177 362 y(co)q(de)g(corresp)q(onding)h
+(to)e(the)h(input)f(ab)q(o)o(v)o(e)g(app)q(ears)h(at)f(the)h(end)g(of)f(the)h
+(\014le.)18 b(It)12 b(should)g(lo)q(ok)g(something)f(lik)o(e)177
+412 y(this.)177 533 y Fl(You)21 b(are)h(reading)e(some)h(free)g(text)g
+(before)f(the)h(macro.)g(Free)g(text)g(can)g(consist)177 583
+y(of)h(any)f(text)g(\(not)g(containing)e(the)j(FunnelWeb)d(special)i
+(character\))f(including)177 632 y(typesetter)g(commands)177
+682 y(such)h(as)h(\\$,)f(\\\045,)g(\\#,)g(and)g($\\backslash$TeX$\\{)o
+($$\\}$)d(which)177 732 y(will)j(be)h(typeset)e(to)h(appear)g(exactly)f(as)i
+(they)e(do)i(in)f(the)g(input)g(file!)177 782 y(Look)g(out!)g(Here)g(comes)g
+(a)g(macro!)177 882 y(\\fwbeginmacro)177 931 y(\\fwfilename{exampl)o(e.out)o
+(}{1}\\)o(fwequ)o(als)e(\\fwodef)h(\\fwbtx[This)f(text)i(is)h(part)f(of)177
+981 y(a)h(macro)f(definition.)177 1031 y(]fwetx=\045)177 1081
+y(\\fwcdef)177 1131 y(\\fwbeginmacronotes)177 1180 y(\\fwisafile{This)e
+(macro)i(is)g(attached)f(to)i(an)f(output)f(file.})177 1230
+y(\\fwendmacronotes)177 1280 y(\\fwendmacro)177 1380 y(This)h(is)h(free)e
+(text)h(following)f(the)i(macro.)e(This)h(sentence)f(contains)177
+1430 y(two)h(\\fwlit{inline})e(typesetter)h(\\fwemp{directives)o(}.)177
+1479 y(Now)h(here)g(is)h(a)f(non-inline)f(typesetting)g(directive.)177
+1579 y(\\fwnewpage)177 1679 y(This)h(sentence)f(will)h(appear)g(on)g(the)g
+(next)g(page.)177 1800 y Fr(The)14 b(follo)o(wing)e(p)q(oin)o(ts)i(explain)f
+(the)h Fl(example.tex)e Fr(\014le.)295 1876 y Fo(Y)l(ou)f(don't)e(ha)o(v)o(e)
+h(to)g(kno)o(w)h(T)l(eX:)f Fr(If)f(y)o(ou)g(don't)g(kno)o(w)g(T)1238
+1885 y(E)1261 1876 y(X,)g(don't)g(pa)o(y)g(to)q(o)h(m)o(uc)o(h)e(atten)o
+(tion)295 1926 y(to)14 b(this)g(section.)19 b(Y)m(ou)13 b(don't)g(need)i(to)f
+(kno)o(w)f(T)1054 1935 y(E)1078 1926 y(X)g(to)h(use)h(F)m(unnelW)m(eb.)295
+2003 y Fo(In)h(order:)h Fr(F)m(unnelW)m(eb)c(has)h(merely)g(transformed)f
+(the)h(input.)k(It)c(hasn't)g(rearranged)h(it.)295 2080 y Fo(F)l(ree)i(text:)
+22 b Fr(Most)15 b(of)g(the)h(free)h(text)f(has)f(b)q(een)i(simply)c(copied)j
+(o)o(v)o(er.)23 b(The)16 b(T)1580 2089 y(E)1603 2080 y(X)f(t)o(yp)q(esetter)
+295 2129 y(justi\014es)f(and)f(\014lls)g(all)e(paragraphs)j(fed)f(to)g(it)g
+(b)o(y)f(default,)h(so)g(most)f(of)h(the)g(text)h(has)f(just)h(b)q(een)295
+2179 y(copied)g(v)o(erbatim.)295 2256 y Fo(T)l(eX)20 b(co)q(des:)25
+b Fr(The)17 b(c)o(haracters)i(and)e(sequences)i(whic)o(h)e(T)1263
+2265 y(E)1286 2256 y(X)g(treats)h(as)f(sp)q(ecial)h(ha)o(v)o(e)f(b)q(een)295
+2306 y(neutralized)12 b(in)e(the)i(do)q(cumen)o(tation)d(\014le.)17
+b(F)m(or)11 b(example,)e(\\)p Fl($)p Fr(")i(has)g(b)q(ecome)f(\\)p
+Fl(\\$)p Fr(".)16 b(By)11 b(default,)295 2356 y(F)m(unnelW)m(eb)h(allo)o(ws)f
+(the)i(user)g(to)f(write)g(an)o(y)g(text)h(as)f(free)h(text)g(and)f(not)g(ha)
+o(v)o(e)g(to)g(w)o(orry)g(ab)q(out)295 2405 y(acciden)o(tally)i(in)o(v)o
+(oking)e(t)o(yp)q(esetter)k(features.)295 2482 y Fo(fw)h(sequences:)j
+Fr(The)15 b Fl(fw)f Fr(sequences)j(\(e.g.)e Fl(\\fwbeginmacro)p
+Fr(\))d(in)o(v)o(ok)o(e)i(T)1491 2491 y(E)1514 2482 y(X)h(macros)f(de\014ned)
+295 2532 y(earlier)g(in)g(the)g(do)q(cumen)o(tation)f(\014le)h(\(and)g(not)f
+(sho)o(wn)h(here\).)295 2609 y Fo(The)19 b(macro:)24 b Fr(The)17
+b(macro)e(is)i(t)o(yp)q(eset)h(using)e(a)g(set)i(of)e(prede\014ned)i(T)1460
+2617 y(E)1484 2609 y(X)e(macros.)26 b(See)17 b(the)295 2658
+y(prin)o(ted)e(do)q(cumen)o(tation)d(to)i(see)h(what)f(this)g(lo)q(oks)f(lik)
+o(e)g(on)h(pap)q(er.)295 2735 y Fo(T)o(yp)q(esetter)i(directiv)o(es:)k
+Fr(Unlik)o(e)15 b(the)h(T)1002 2744 y(E)1025 2735 y(X)g(command)d(sequences)
+18 b(\(whic)o(h)e(w)o(ere)h(neutral-)295 2785 y(ized\),)f(the)g(F)m(unnelW)m
+(eb)f(t)o(yp)q(esetter)i(directiv)o(es)f(turn)g(in)o(to)e(T)1286
+2794 y(E)1310 2785 y(X)h(macro)f(calls.)22 b(F)m(or)14 b(example,)295
+2835 y(\\)p Fl(@)p Fq(f)p Fl(inline@)p Fq(g)p Fr(")d(b)q(ecame)j(\\)p
+Fl(\\fwlit)p Fq(f)p Fl(inline)p Fq(g)p Fr(".)1042 2940 y(33)p
+eop
+%%Page: 34 35
+34 34 bop 177 42 a Fr(In)16 b(summary)m(,)c(F)m(unnelW)m(eb)j(pro)q(duces)i
+(t)o(yp)q(eset)g(do)q(cumen)o(tation)d(that)h(transforms,)g(but)g(do)q(es)h
+(not)g(reorder,)177 91 y(the)e(input)f(\014le.)18 b(Macros)c(are)g(t)o(yp)q
+(eset)h(in)e(a)g(sp)q(eci\014c)i(st)o(yle.)j(F)m(unnelW)m(eb)13
+b(t)o(yp)q(esetter)j(directiv)o(es)f(ha)o(v)o(e)e(partic-)177
+141 y(ular)i(w)o(ell-de\014ned)g(e\013ects.)23 b(F)m(ree)16
+b(text)g(is)f(\014lled)f(and)h(justi\014ed,)g(but)g(will)f(otherwise)i(app)q
+(ear)f(in)g(the)g(prin)o(ted)177 191 y(do)q(cumen)o(tation)e(exactly)h(as)g
+(it)f(app)q(ears)i(in)e(the)i(input)f(\014le.)177 333 y Fd(1.7.2)55
+b(T)n(yp)r(esetter)17 b(Indep)r(endence)177 436 y Fr(Although)f(the)h(curren)
+o(t)h(v)o(ersion)e(of)g(F)m(unnelW)m(eb)f(can)i(only)e(generate)j(do)q(cumen)
+o(tation)d(\014les)i(in)f(T)1783 444 y(E)1806 436 y(X)g(form,)177
+485 y(it)i(encourages)i(t)o(yp)q(esetter)h(indep)q(endence)g(b)o(y)d
+(neutralizing)g(all)f(T)1280 494 y(E)1303 485 y(X)i(con)o(trol)f(sequences)j
+(b)q(efore)f(writing)177 535 y(them)f(out.)34 b(The)20 b(result)g(is)f(that)h
+(y)o(ou)f(don't)f(ha)o(v)o(e)i(w)o(orry)f(ab)q(out)g(upsetting)h(or)f(dep)q
+(ending)h(on)f(T)1831 544 y(E)1855 535 y(X)g(b)o(y)177 585
+y(acciden)o(tally)11 b(including)g(some)g(sp)q(ecial)h(c)o(haracter)h(or)f
+(sequence.)19 b(By)12 b(default)g(y)o(our)f(input)h(\014le)g(is)f
+Fo(t)o(yp)q(esetter)177 635 y(indep)q(enden)n(t)p Fr(.)177
+710 y(This)i(sc)o(heme)g(di\013ers)h(from)d(other)i(literate)g(programming)d
+(to)q(ols,)i(including)g(all)f(earlier)j(v)o(ersions)f(of)f(F)m(unnel-)177
+760 y(W)m(eb,)h(whic)o(h)g(cop)o(y)g(their)h(free)g(text)g(directly)f(to)g
+(the)h(do)q(cumen)o(tation)e(\014le,)h(the)h(justi\014cation)f(b)q(eing)g
+(that)g(the)177 810 y(programmer)d(can)j(use)g(the)g(full)e(p)q(o)o(w)o(er)h
+(of)g(the)h(t)o(yp)q(esetter)h(language)e(to)g(describ)q(e)i(the)f(program.)i
+(The)e(disad-)177 859 y(v)n(an)o(tages)h(of)f(doing)g(this)h(are)g(\014rst)h
+(that)f(the)g(programmer)e(is)i(required)g(to)g(kno)o(w)f(the)i(t)o(yp)q
+(esetting)g(language)177 909 y(and)h(second)h(that)f(the)g(input)g(\014le)g
+(b)q(ecomes)g(t)o(yp)q(esetter)i(dep)q(enden)o(t.)25 b(F)m(unnelW)m(eb)16
+b(a)o(v)o(oids)e(these)k(problems)177 959 y(b)o(y)c(knobbling)e(the)j(free)g
+(text)f(b)q(e)h(default.)177 1034 y(Ho)o(w)o(ev)o(er,)e(F)m(unnelW)m(eb)g(do)
+q(es)h(pro)o(vide)f(a)f(trap)q(do)q(or)i(for)e(those)i(who)f(w)o(an)o(t)g
+(their)g(free)h(text)g(to)f(b)q(e)g(fed)g(directly)177 1084
+y(to)h(T)251 1093 y(E)274 1084 y(X.)f(T)m(o)h(op)q(en)g(the)g(trap)q(do)q
+(or,)g(simply)e(include)i(the)g(follo)o(wing)d(pragma)h(somewhere)j(in)e(y)o
+(our)h(input)f(\014le.)177 1201 y Fl(@p)22 b(typesetter)d(=)j(tex)177
+1319 y Fr(See)15 b(Section)f(3.11.2)e(for)i(more)f(information.)177
+1394 y(F)m(unnelW)m(eb)d(lea)o(v)o(es)h(the)h(degree)g(to)e(whic)o(h)h(the)g
+(user)h(wishes)g(to)e(bind)h(a)f(particular)h(do)q(cumen)o(t)f(to)h(a)f
+(particular)177 1444 y(t)o(yp)q(esetter)15 b(up)e(to)f(the)i(user.)k(In)13
+b(some)f(cases,)h(the)h(extra)f(t)o(yp)q(esetting)g(p)q(o)o(w)o(er)g(ma)o(y)e
+(comp)q(ensate)i(for)f(the)h(lac)o(k)177 1493 y(of)h(p)q(ortabilit)o(y)m(.)k
+(Ho)o(w)o(ev)o(er,)d(as)f(a)g(rule,)h(it)f(is)g(b)q(est)i(to)e(a)o(v)o(oid)f
+(t)o(yp)q(esetter-sp)q(ec)q(i\014c)k(commands,)12 b(so)j(as)f(to)g(allo)o(w)
+177 1543 y(y)o(our)j(input)g(\014les)h(to)f(b)q(e)g(formatted)f(at)h(a)g
+(later)h(date)f(for)g(di\013eren)o(t)h(t)o(yp)q(esetters.)31
+b(F)m(unnelW)m(eb)16 b(includes)i(a)177 1593 y(n)o(um)o(b)q(er)c(of)g(its)g
+(o)o(wn)h(t)o(yp)q(esetter)h(commands)d(so)h(as)h(to)f(supp)q(ort)i(t)o(yp)q
+(esetter-indep)q(enden)o(t)i(input)c(\014les.)20 b(The)177
+1643 y(follo)o(wing)12 b(sections)k(describ)q(e)g(some)d(of)h(these)i
+(commands.)h(In)e(particular,)e(the)j(next)e(section)i(describ)q(es)g(the)177
+1693 y(most)f(p)q(o)o(w)o(erful)g(F)m(unnelW)m(eb)g(t)o(yp)q(esetting)h
+(directiv)o(es)h(whic)o(h)e(allo)o(w)f(the)i(user)h(to)e(structure)j(the)e
+(do)q(cumen)o(t)177 1742 y(hierarc)o(hically)m(.)177 1885 y
+Fd(1.7.3)55 b(Hierarc)n(hical)18 b(Structure)177 1987 y Fr(The)h(tree)h
+(structure)g(is)f(one)f(of)g(the)h(most)e(e\013ectiv)o(e)j(structuring)g(to)q
+(ols)e(that)g(exists,)i(deriving)e(its)g(p)q(o)o(w)o(er)177
+2037 y(from)13 b(the)i(principal)f(of)g(divide)h(and)f(conquor.)21
+b(So)14 b(e\013ectiv)o(e)i(is)f(it)f(that)h(the)g(in)o(ternal)f(organization)
+g(of)g(most)177 2087 y(tec)o(hnical)j(b)q(o)q(oks)g(are)h(tree)g(structures)h
+(whic)o(h)e(are)h(concisely)f(summarized)e(in)i(the)g(table)g(of)f(con)o(ten)
+o(ts.)29 b(In)177 2136 y(con)o(trast,)14 b(computer)e(programs)g(are)i
+(usually)e(presen)o(ted)j(as)e(\015at)g(sequences)j(of)c(text)i(to)f(b)q(e)g
+(consumed)g(b)o(y)g(an)177 2186 y(anon)o(ymous)f(compiler.)177
+2261 y(In)20 b(order)h(to)e(bring)h(program)e(do)q(cumen)o(tation)h(up)h(to)f
+(the)i(structural)g(sophistication)e(commonplace)e(in)177 2311
+y(tec)o(hnical)12 b(b)q(o)q(oks,)g(F)m(unnelW)m(eb)f(pro)o(vides)g(\014v)o(e)
+h(lev)o(els)g(of)e(section)j(headings)e(implemen)o(ted)e(b)o(y)j(the)g(\014v)
+o(e)g(sp)q(ecial)177 2361 y(sequences)j Fl(@A)p Fr(,)c Fl(@B)p
+Fr(,)g Fl(@C)p Fr(,)g Fl(@D)p Fr(,)h(and)g Fl(@E)p Fr(.)f(These)i(m)o(ust)e
+(alw)o(a)o(ys)h(app)q(ear)g(at)g(the)h(start)g(of)e(a)h(line.)17
+b Fl(@A)12 b Fr(is)g(the)g(highest)177 2411 y(lev)o(el)21 b(section)g(\(e.g.)
+f(lik)o(e)g(L)617 2406 y Fk(a)636 2411 y Fr(T)659 2423 y(E)683
+2411 y(X's)g Fl(\\chapter)p Fr(\))g(and)g Fl(@E)h Fr(is)f(the)i(lo)o(w)o(est)
+e(lev)o(el)h(section)g(\(e.g.)f(lik)o(e)g(L)1824 2406 y Fk(a)1843
+2411 y Fr(T)1866 2423 y(E)1890 2411 y(X's)177 2461 y Fl(\\subsubsubsection)p
+Fr(\).)30 b(Section)19 b(headings)g(can)g(app)q(ear)g(an)o(ywhere)h(in)e(the)
+h(free)h(text)g(of)e(a)g(F)m(unnelW)m(eb)177 2510 y(input)c(\014le)g(\(i.e.)f
+(an)o(ywhere)h(except)i(inside)e(a)f(macro)g(de\014nition\).)177
+2586 y(Eac)o(h)j(section)g(heading)f(in)g(a)g(F)m(unnelW)m(eb)g(do)q(cumen)o
+(t)f(has)i(an)f(asso)q(ciated)h(name.)21 b(The)16 b(name)e(of)h(a)g(section)
+177 2635 y(can)i(b)q(e)f(pro)o(vided)h(explicitly)e(b)o(y)h(supplying)f(it)h
+(delimited)f(b)o(y)h Fl(@<)f Fr(and)h Fl(@>)g Fr(immediately)d(after)j(the)h
+(section)177 2685 y(sequence)e(\(e.g.)e Fl(@A)p Fr(\),)f(or)h(implicitly)d(b)
+o(y)i(not)h(pro)o(viding)f(an)h(explicit)f(name,)g(in)g(whic)o(h)h(case)h
+(the)g(section)f(tak)o(es)177 2735 y(the)e(name)f(of)g(the)h(\014rst)g(macro)
+f(de\014ned)h(b)q(et)o(w)o(een)h(the)g(section)f(header)g(in)g(question)f
+(and)h(the)g(follo)o(wing)d(section)177 2785 y(header.)18 b(An)12
+b(error)h(is)e(generated)i(if)e(a)g(section)h(has)g(not)f(b)q(een)i(giv)o(en)
+e(an)h(explicit)f(name)f(and)h(do)q(es)i(not)e(con)o(tain)177
+2835 y(an)o(y)j(macro)e(de\014nitions.)18 b(Here)d(are)g(some)e(example)f
+(headings:)1042 2940 y(34)p eop
+%%Page: 35 36
+35 35 bop 177 42 a Fl(@A@<Feed)20 b(the)h(Penguins)g(and)g(Save)g(the)g
+(World@>)177 91 y(@B@<Feed)f(the)h(Penguins@>)177 141 y(@C@<Feed)f(the)h
+(little)g(penguins@>)177 191 y(@C@<Feed)f(the)h(big)h(penguins@>)177
+241 y(@B@<Save)e(the)h(World@>)177 291 y(@C@<Save)f(Europe@>)177
+340 y(@C@<Save)g(Africa@>)177 440 y(@C)i(This)f(heading)f(hasn't)g(been)h
+(given)g(an)h(explicit)e(name,)g(but)i(will)f(inherit)f(the)177
+490 y(name)h(\\p{Save)f(the)i(rest)f(of)g(the)g(world})g(from)g(the)g(macro)g
+(definition)e(below.)177 589 y(@$@<Save)h(the)h(rest)g(of)h(the)f
+(world@>@Z==@{...@)o(})177 706 y Fr(The)16 b(feature)h(of)e(ha)o(ving)g
+(unnamed)f(sections)j(inherit)f(the)g(name)f(of)g(the)h(\014rst)h(macro)e
+(de\014ned)h(within)f(their)177 756 y(scop)q(e)f(is)f(presen)o(t)h(b)q
+(ecause)g(a)f(common)c(st)o(yle)k(of)f(writing)g(in)g(F)m(unnelW)m(eb)h(is)f
+(to)h(ha)o(v)o(e)f(one)h(section)g(p)q(er)h(macro)177 806 y(de\014nition.)26
+b(Because,)19 b(under)e(this)g(st)o(yle,)g(eac)o(h)g(section)g(describ)q(es)i
+(a)d(single)h(macro,)e(it)i(usually)e(turns)j(out)177 855 y(that)12
+b(the)h(macro)e(name)g(mak)o(es)g(a)h(go)q(o)q(d)g(name)f(for)h(the)h
+(section)g(to)q(o.)k(The)c(inheritance)g(mec)o(hanism)c(prev)o(en)o(ts)177
+905 y(duplication)k(of)g(the)i(name.)177 980 y(Apart)d(from)e(the)i
+(requiremen)o(t)g(that)g(eac)o(h)g(section)g(ha)o(v)o(e)g(an)f(explicit)g(or)
+h(implicit)d(name)i(and)g(that)h(its)g(sp)q(ecial)177 1030
+y(sequence)21 b(app)q(ear)e(at)f(the)h(start)g(of)f(a)g(line,)h(the)g(only)f
+(other)h(restriction)g(on)g(section)g(headings)f(is)h(that)f(a)177
+1080 y(section)c(heading)e(at)h(lev)o(el)f Fn(n)h Fr(cannot)g(app)q(ear)g
+(immediately)c(after)k(a)g(section)g(heading)g(at)g(lev)o(el)f
+Fn(n)7 b Fq(\000)g Fr(1)13 b(or)g(less.)177 1129 y(In)k(other)g(w)o(ords,)f
+(the)h(hierarc)o(h)o(y)g(cannot)g(b)q(e)g(brok)o(en.)26 b(F)m(or)16
+b(example,)f(an)h Fl(@C)g Fr(cannot)h(app)q(ear)f(after)h(an)f
+Fl(@A)177 1179 y Fr(heading)e(unless)g(there)i(is)d(an)h(in)o(terv)o(ening)g
+Fl(@B)f Fr(heading.)177 1296 y Fl(@A@<The)21 b(Top)g(Heading@>)177
+1346 y(@C@<Level)f(C)i(here)f(is)g(not)g(allowed)g(after)f(an)i(A)f(and)g
+(will)g(cause)g(an)h(error@>)177 1462 y Fr(This)14 b(rule)g(extends)i(to)e
+(the)h(start)f(of)g(the)g(\014le;)g(if)f(there)j(are)e(an)o(y)g(headings)g
+(at)g(all,)e(the)j(\014rst)g(one)f(m)o(ust)f(b)q(e)i(an)177
+1512 y Fl(@A)f Fr(heading.)j(The)e(follo)o(wing)c(\014le,)i(while)h(short,)g
+(is)f(in)h(error.)177 1628 y Fl(This)21 b(FunnelWeb)f(input)h(file)g(is)g(in)
+h(error)e(because)h(its)g(first)g(section)f(heading)177 1678
+y(is)i(at)f(level)g(C)g(rather)g(than)g(level)g(A.)177 1728
+y(@C@<2@>)177 1869 y Fd(1.7.4)55 b(Understanding)19 b(the)f(Prin)n(ted)h(Do)r
+(cumen)n(tation)177 1971 y Fr(T)o(yp)q(e)g(in)f(the)h(follo)o(wing)c(\014le,)
+k(and)g(use)g(F)m(unnelW)m(eb)f(and)g(T)1173 1980 y(E)1196
+1971 y(X)g(to)h(generate)g(the)g(corresp)q(onding)g(prin)o(ted)177
+2021 y(do)q(cumen)o(tation.)177 2137 y Fl(@A@<Table)h(of)h(Contents@>)177
+2237 y(@t)h(table_of_conten)o(ts)177 2337 y(@A@<Macros)e(for)h(Moral)g
+(Support@>)177 2436 y(The)g(following)f(macro)h(contain)f(comments)h(that)f
+(provide)h(moral)g(support)f(in)h(the)177 2486 y(output)g(code.)177
+2586 y(@$@<Programmer's)e(Cheer@>@M==@{)177 2635 y(--)j(Shift)e(to)i(the)f
+(left!)177 2685 y(--)h(Shift)e(to)i(the)f(right!)177 2735 y(--)h(Pop)f(up,)g
+(push)g(down!)177 2785 y(--)h(Byte!)e(Byte!)h(Byte!)177 2835
+y(--)h(\(From)e("The)h(New)g(Hacker's)g(Dictionary"\).)1042
+2940 y Fr(35)p eop
+%%Page: 36 37
+36 36 bop 177 42 a Fl(@})177 141 y(The)21 b(next)g(macro)g(is)g(similar)g
+(but)g(is)g(distributed)f(throughout)g(the)h(program.)177 191
+y(@$@<Hacker's)e(Cheer@>+=@{@+--)g(Pointer)i(to)g(the)g(left@+@})177
+291 y(@A@<An)g(Extremely)f(Imperative)f(Stack)i(Abstraction@>)177
+390 y(@B@<Define)f(the)h(Stack@>)177 440 y(@$@<Hacker's)e(Cheer@>+=@{--)h
+(Pointer)g(to)h(the)g(right@+@})177 490 y(@$@<Stack)f(Type@>@Z==@{type)f
+(stack)h(=)i(record)e(...)i(end;@})177 589 y(@B@<Push)e(the)h(Stack@>)177
+639 y(@$@<Hacker's)e(Cheer@>+=@{--)h(Hack)h(that)g(code@+@})177
+689 y(@$@<Push)f(Procedure@>@Z==@{@-)177 739 y(procedure)g(push\(var)g
+(b:stack;)g(v:value\);)g(@<Programmer's)f(Cheer@>)i({...}@})177
+839 y(@B@<Pop)g(the)g(Stack@>)177 888 y(@$@<Hacker's)e(Cheer@>+=@{--)h
+(Tight!)g(Tight!)h(Tight!@+@})177 938 y(@$@<Pop)g(Procedure@>@Z==)o(@{@-)177
+988 y(procedure)f(pop\(var)g(b:stack\);)g(@<Programmer's)f(Cheer@>)i({...}@})
+177 1088 y(@B@<Rough)f(the)h(Stack)g(Up)g(a)h(Bit@>)177 1137
+y(@$@<Hacker's)d(Cheer@>+=@{--)h(\(RNW,)g(04-Jan-1991\).@+@})177
+1187 y(@$@<Rough)g(Procedure@>@Z==@{@)o(-)177 1237 y(procedure)g(rough\(var)g
+(b:stack\);)g(@<Hacker's)g(Cheer@>)g({...}@})177 1337 y(@O@<dummy.txt@>==@)o
+({dumm)o(y@+@})177 1525 y Fr(An)15 b(examination)e(of)h(the)i(prin)o(ted)f
+(do)q(cumen)o(tation)f(rev)o(eals)i(a)f(lot)f(ab)q(out)h(ho)o(w)g(F)m(unnelW)
+m(eb's)f(presen)o(tation)177 1574 y(w)o(orks.)177 1678 y(First,)f(notice)g
+(ho)o(w)g(the)g Fl(@t)g Fr(t)o(yp)q(esetter)i(directiv)o(e)f(at)e(the)i(top)f
+(of)f(the)h(\014le)g(has)g(caused)h(a)f(table)g(of)f(con)o(ten)o(ts)i(to)177
+1728 y(app)q(ear.)24 b(This)15 b(is)h(one)f(of)g(F)m(unnelW)m(eb's)g(t)o(yp)q
+(esetting)i(features)f(and)g(is)f(discussed)j(in)d(a)g(later)h(section.)23
+b(The)177 1777 y(table)14 b(of)f(con)o(ten)o(ts)i(sho)o(ws)f(that)g(the)h
+(sections)g(ha)o(v)o(e)f(b)q(een)h(n)o(um)o(b)q(ered)e(hierarc)o(hically)m(.)
+177 1881 y(No)o(w)18 b(tak)o(e)h(a)f(lo)q(ok)g(at)g(the)h(t)o(yp)q(eset)i
+(macro)c(de\014nitions.)32 b(Most)19 b(imp)q(ortan)o(t)e(are)i(the)g(n)o(um)o
+(b)q(ers)f(in)g(square)177 1931 y(brac)o(k)o(ets)h(that)f(follo)o(w)e(eac)o
+(h)i(macro)f(name.)28 b(As)19 b(w)o(ell)e(as)h(n)o(um)o(b)q(ering)e(the)i
+(headings)g Fm(hier)n(ar)n(chic)n(al)r(ly)p Fr(,)f(F)m(un-)177
+1980 y(nelW)m(eb)e Fm(indep)n(endently)h Fr(n)o(um)o(b)q(ers)f(the)g(macro)f
+(de\014nitions)h Fm(se)n(quential)r(ly)p Fr(.)21 b(The)16 b(\014rst)g(macro)d
+(de\014nition)i(\(for)177 2030 y(\\Programmer's)h(Cheer"\))j(is)e(n)o(um)o(b)
+q(ered)h(1.)30 b(The)19 b(second)g(\(for)e(\\Hac)o(k)o(er's)i(Cheer"\))g(is)f
+(n)o(um)o(b)q(ered)f(2)h(and)177 2080 y(so)f(on.)27 b(Note)17
+b(that)g(it)f(is)h(not)f(macros)g(that)h(are)g(n)o(um)o(b)q(ered,)g(but)g
+(macro)f(de\014nitions.)26 b(The)18 b(distinction)e(is)177
+2130 y(necessary)e(b)q(ecause)g(some)d(macros)g(\(suc)o(h)i(as)f(the)h(\\Hac)
+o(k)o(er's)f(Cheer")h(macro\))e(are)h(additiv)o(e.)17 b(It)12
+b(is)g(imp)q(ortan)o(t)177 2180 y(to)k(realize)g(that)f(there)i(is)f(no)f
+(relationship)g(b)q(et)o(w)o(een)i(the)f(n)o(um)o(b)q(ers)g(of)f(the)h
+(headings)f(and)h(the)g(n)o(um)o(b)q(ers)f(of)177 2229 y(the)g(macro)d
+(de\014nitions.)177 2333 y(No)o(w)h(tak)o(e)g(a)f(lo)q(ok)g(at)h(the)g(notes)
+h(b)q(eneath)f(the)h(b)q(o)q(dy)f(of)f(eac)o(h)h(macro)f(de\014nition.)17
+b(All)12 b(macro)g(de\014nitions)g(are)177 2383 y(follo)o(w)o(ed)i(b)o(y)i(a)
+f(note)h(indicating)e(the)j(de\014nitions)e(in)g(whic)o(h)h(the)g(macro)e(is)
+i(called.)23 b(Additiv)o(e)15 b(macros)g(ha)o(v)o(e)177 2432
+y(an)f(additional)e(list,)h(listing)g(the)h(de\014nitions)g(in)f(whic)o(h)h
+(they)h(are)f(de\014ned.)177 2536 y(Finally)m(,)20 b(tak)o(e)g(a)g(lo)q(ok)f
+(at)i(the)g(macro)e Fm(c)n(al)r(l)h Fr(of)f(\\Programmer's)f(Cheer")j(in)f
+(section)h(3.2)f(of)f(the)i(prin)o(ted)177 2586 y(do)q(cumen)o(tation.)d
+(Macro)d(calls)f(are)g(set)h(in)f(slan)o(ted)h(roman)d(\(so)j(that)f(they)h
+(can)g(b)q(e)f(distinguished)h(from)d(the)177 2635 y Fl(tt)22
+b(font)13 b Fr(co)q(de\))j(and)e(are)h(follo)o(w)o(ed)e(b)o(y)h(the)h(n)o(um)
+o(b)q(er)f(of)g(the)h(de\014ning)g(macro)e(de\014nition.)20
+b(In)14 b(this)h(case,)g(the)177 2685 y(macro)d(w)o(as)h(de\014ned)h(in)e
+(de\014nition)h(1.)k(F)m(urther)d(do)o(wn,)e(the)i(call)e(to)h(the)h(\\Hac)o
+(k)o(er's)f(Cheer")h(macro)d(indicates)177 2735 y(that)h(the)h(macro)e(w)o
+(as)h(de\014ned)h(in)f(de\014nition)f(2.)18 b(In)12 b(fact)g(the)g(macro)f
+(is)h(additiv)o(e)g(and)f(de\014nition)h(2)g(is)g(just)g(the)177
+2785 y(\014rst)g(of)e(man)o(y)f(de\014nitions.)17 b(T)m(o)10
+b(list)h(all)f(de\014nitions)g(in)h(a)f(call)h(to)f(an)h(additiv)o(e)f(macro)
+g(w)o(ould)g(b)q(e)i(unnecessarily)177 2835 y(messy)m(.)1042
+2940 y(36)p eop
+%%Page: 37 38
+37 37 bop 177 42 a Fd(1.7.5)55 b(Literals)17 b(and)j(Emphasis)177
+144 y Fr(When)d(writing)f(ab)q(out)h(program)e(co)q(de,)j(it)f(is)g(often)g
+(desirable)g(to)g(b)q(e)g(able)g(to)g(indicate)f(that)h(a)g(particular)177
+194 y(w)o(ord)11 b(or)g(phrase)h(b)q(e)g(t)o(yp)q(eset)h(in)d(the)i(same)e
+(manner)g(as)h(the)h(co)q(de)g(b)q(eing)f(discussed.)19 b(F)m(or)11
+b(example,)f(one)h(migh)o(t)177 244 y(talk)16 b(ab)q(out)h(the)g(v)n(ariable)
+e Fl(topval)h Fr(or)g(the)i(pro)q(cedure)g Fl(stack)p 1202
+244 14 2 v 15 w(pop)e Fr(and)g(wish)h(for)f(them)g(to)g(b)q(e)i(t)o(yp)q
+(eset)g(as)177 294 y(they)d(are)f(in)f(this)i(sen)o(tence.)20
+b(This,)13 b(of)h(course,)h(is)e(simple)g(to)h(do)f(using)h(T)1355
+302 y(E)1378 294 y(X)g(macros,)f(but)h(use)h(of)e(the)i(\(more)177
+343 y(general\))h(F)m(unnelW)m(eb)f(t)o(yp)q(esetting)h(directiv)o(es)g(to)g
+(do)f(the)h(same)e(w)o(ork)h(has)h(the)g(added)f(b)q(ene\014t)i(of)e(k)o
+(eeping)177 393 y(the)g(do)q(cumen)o(t)e(p)q(ortable)h(to)g(other)g(t)o(yp)q
+(esetters.)177 469 y(F)m(unnelW)m(eb)g(pro)o(vides)h(t)o(w)o(o)f(in-text)g(t)
+o(yp)q(e)h(mo)q(di\014cation)e(constructs:)21 b Fl(@)p Fq(f)p
+Fl(...@)p Fq(g)13 b Fr(and)h Fl(@/...@/)f Fr(where)j Fn(:)7
+b(:)g(:)13 b Fr(is)177 518 y(ra)o(w)i(text.)20 b(The)15 b Fl(@)p
+Fq(f)p Fl(...@)p Fq(g)e Fr(construct)j(sets)g(the)g(enclosed)f(text)g(in)f
+(the)i(same)d(manner)h(as)h(the)g(text)g(of)f(macro)177 568
+y(de\014nitions)c(is)g(set.)18 b(The)11 b Fl(@/...@/)d Fr(construct)k
+(emphasises)e(its)h(enclosed)g(text)g(in)e(some)h(t)o(yp)q(esetter-dep)q
+(ende)q(n)o(t)177 618 y(fashion.)17 b(T)o(ypically)c(the)h(emphasised)g(text)
+g(is)g(set)h(in)e(italics.)177 693 y(Here)i(is)f(an)g(example)e(of)i(ho)o(w)f
+(these)i(constructs)h(migh)o(t)c(b)q(e)j(used:)177 812 y Fl(The)21
+b(following)f(procedure)g(@{put_sloth@})f(writes)i(the)g(@{sloth@})f
+(variable)g(to)177 861 y(the)h(output)g(file.)g(Note:)f(@/The)h(output)g
+(file)g(must)g(be)g(opened)g(for)g(writing)177 911 y(at)h(this)f(point)f(or)i
+(the)f(program)f(will)h(crash!@/)177 1055 y Fd(1.7.6)55 b(Adding)19
+b(a)g(Header)f(P)n(age)177 1157 y Fr(F)m(unnelW)m(eb)h(pro)o(vides)h(a)f(few)
+h(t)o(yp)q(esetter-indep)q(enden)o(t)j(t)o(yp)q(esetting)e(constructs)g(whic)
+o(h)f(are)g(sp)q(eci\014cally)177 1207 y(designed)14 b(for)f(the)g
+(construction)i(of)d(header)i(pages.)k(These)d(constructs)g(are)e(usually)g
+(b)q(est)h(placed)f(at)g(the)h(top)177 1257 y(of)e(y)o(our)f(input)h(\014le,)
+g(but)h(can)f(b)q(e)h(placed)f(an)o(ywhere)h(the)f(do)q(cumen)o(t)g(if)f
+(desired)i(to)f(create)i(header)f(pages)f(righ)o(t)177 1307
+y(through.)24 b(The)16 b(t)o(w)o(o)f(main)f(restrictions)j(on)e(these)i
+(constructs)h(is)e(that)g(the)g Fl(@t)f Fr(m)o(ust)g(start)h(at)g(the)g
+(start)g(of)177 1356 y(a)h(line)f(\(whic)o(h)h(cannot)g(con)o(tain)f(commen)o
+(ts\),)f(and)i(that)g(the)g(constructs)i(cannot)e(app)q(ear)g(inside)g(a)f
+(macro)177 1406 y(de\014nition.)i(Here)d(is)f(what)f(the)i(top)f(of)f(an)h
+(input)f(\014le)h(migh)o(t)e(lo)q(ok)h(lik)o(e:)177 1524 y
+Fl(@t)22 b(vskip)e(40)i(mm)177 1574 y(@t)g(title)e(titlefont)g(centre)h
+("Hairy)f(Wombat")177 1624 y(@t)i(title)e(titlefont)g(centre)h("Simulation")
+177 1674 y(@t)h(vskip)e(10)i(mm)177 1723 y(@t)g(title)e(smalltitlefont)f
+(centre)i("A)g(Program)f(in)i(Six)f(Parts")177 1773 y(@t)h(title)e
+(smalltitlefont)f(centre)i("Simulating)e(the)i(Life)g(of)h(Some)f(Hairy)g
+(Wombats")177 1823 y(@t)h(vskip)e(20)i(mm)177 1873 y(@t)g(title)e(normalfont)
+g(left)h("By)g(Zqitzypbuswapzra)e(Ypongtatoslrtzz")177 1923
+y(@t)j(new_page)177 1973 y(@t)g(table_of_conten)o(ts)177 2022
+y(@t)g(new_page)177 2140 y Fr(The)14 b Fl(@t)e Fr(at)h(the)h(start)g(of)e
+(eac)o(h)i(line)e(indicates)i(that)f(eac)o(h)g(en)o(tire)h(line)f(is)g(a)g(t)
+o(yp)q(esetter)i(directiv)o(e.)j(The)c Fl(vskip)177 2190 y
+Fr(directiv)o(e)i(instructs)h(F)m(unnelW)m(eb)e(to)h(skip)f(some)g(v)o
+(ertical)g(space)i(\(measured)f(in)f(milli)o(m)o(etres\).)22
+b(The)16 b Fl(title)177 2240 y Fr(directiv)o(e)f(instructs)h(F)m(unnelW)m(eb)
+e(to)h(p)q(osition)f(a)g(string)g(of)g(text)i(on)e(a)g(single)g(line)g(of)g
+(its)h(o)o(wn.)20 b(Options)14 b(are)177 2290 y(pro)o(vided)i(for)g(fon)o(t)f
+(and)h(alignmen)o(t.)23 b(The)16 b(\014rst)h(w)o(ord)f(after)g
+Fl(title)f Fr(is)h(the)h(fon)o(t)e(whic)o(h)h(can)h(b)q(e)f(one)h(of)e(\(in)
+177 2340 y(decreasing)j(order)f(of)e(size\))j Fl(titlefont)p
+Fr(,)c Fl(smalltitlefont)p Fr(,)g(and)i Fl(normalfont)p Fr(.)23
+b(The)17 b(second)g(w)o(ord)g(after)177 2389 y Fl(title)d Fr(is)i(the)g
+(desired)g(alignmen)o(t)d(of)i(the)h(text.)23 b(The)16 b(options)f(here)h
+(are)g Fl(left)p Fr(,)f Fl(right)p Fr(,)f(and)h Fl(centre)p
+Fr(.)21 b(The)177 2439 y Fl(new)p 246 2439 V 15 w(page)16 b
+Fr(directiv)o(e)g(instructs)i(F)m(unnelW)m(eb)d(to)h(skip)g(to)g(a)g(new)h
+(page.)25 b(Finally)m(,)14 b(the)j Fl(table)p 1704 2439 V 14
+w(of)p 1762 2439 V 15 w(contents)177 2489 y Fr(directiv)o(e)e(instructs)g(F)m
+(unnelW)m(eb)e(to)h(insert)h(a)e(table)h(of)f(con)o(ten)o(ts)i(at)f(that)g(p)
+q(oin)o(t)f(in)h(the)g(text.)177 2632 y Fd(1.7.7)55 b(Commen)n(ts)177
+2735 y Fr(A)14 b(F)m(unnelW)m(eb)g(commen)o(t)d(commences)i(with)h(the)h
+Fl(@!)j Fr(sequence)e(and)d(con)o(tin)o(ues)i(up)f(to,)f(but)h(not)g
+(including,)177 2785 y(the)h(end)f(of)g(line)g(mark)o(er)f(at)h(the)g(end)h
+(of)e(the)i(line)f(that)g(the)h(commen)o(t)c(sequence)17 b(is)d(on.)k(Commen)
+o(ts)12 b(can)i(b)q(e)177 2835 y(placed)g(on)g(an)o(y)f(line)h(except)h
+Fl(@i)f Fr(include,)f Fl(@p)g Fr(pragma,)f(and)i Fl(@t)f Fr(t)o(yp)q(esetter)
+j(directiv)o(e)f(lines.)1042 2940 y(37)p eop
+%%Page: 38 39
+38 38 bop 177 42 a Fr(The)17 b(text)f(follo)o(wing)e(the)j(F)m(unnelW)m(eb)e
+(commen)o(t)f(sequence)k Fl(@!)25 b Fr(will)15 b(not)h(app)q(ear)g(in)g(the)g
+(pro)q(duct)h(\014les)g(or)177 91 y(the)c(do)q(cumen)o(tation)e(\014le.)17
+b(It)12 b(is)g(only)g(for)f(the)i(ey)o(es)g(of)f(those)h(who)e(b)q(other)i
+(to)f(lo)q(ok)g(at)g(the)g(original)f Fl(.fw)g Fr(input)177
+141 y(\014le.)18 b(T)o(ypically)12 b(F)m(unnelW)m(eb)i(commen)o(ts)e(are)i
+(used)h(to)e(describ)q(e)j(the)e(w)o(a)o(y)g(in)f(whic)o(h)h(particular)f(F)m
+(unnelW)m(eb)177 191 y(constructs)j(are)e(b)q(eing)g(used.)19
+b(Example:)177 304 y Fl(@!)j(This)f(macro)f(is)i(really)e(revolting.)g
+(Please)g(forgive)h(me.)g(I)h(had)f(to)g(do)h(it!)177 354 y(@$@<Revolt)e
+(Me@>==@{@-)177 404 y(@#X@\(@#Y@\(@#Z@,@"@)o(#Z@"@)o(\)=6@,)o(Teapo)o(t@,@")o
+(@#Q@)o(\(45@\))o(@"@,T)o(iger@)o(\)@})177 564 y Fi(1.8)70
+b(A)23 b(Complete)d(Example)177 679 y Fr(T)m(o)c(\014nish)h(o\013)f(the)h(c)o
+(hapter,)h(a)e(complete)g(example)f(of)h(a)h(F)m(unnelW)m(eb)f(input)g
+(\014le)h(is)f(presen)o(ted.)28 b(Although)177 729 y(unrealistically)13
+b(short,)h(it)f(giv)o(es)h(a)g(b)q(etter)h(idea)f(of)f(what)h(a)f(t)o(ypical)
+g(F)m(unnelW)m(eb)h Fl(.fw)f Fr(\014le)h(lo)q(oks)f(lik)o(e.)177
+842 y Fl(@!----------------)o(-----)o(-----)o(-----)o(-----)o(---!)177
+892 y(@!)43 b(Start)21 b(of)g(FunnelWeb)f(Example)h(.fw)g(File)43
+b(!)177 942 y(@!----------------)o(-----)o(-----)o(-----)o(-----)o(---!)177
+1041 y(@t)22 b(vskip)e(40)i(mm)177 1091 y(@t)g(title)e(titlefont)g(centre)h
+("Powers:")177 1141 y(@t)h(title)e(titlefont)g(centre)h("An)g(Example)f(of")
+177 1191 y(@t)i(title)e(titlefont)g(centre)h("A)g(Short")177
+1241 y(@t)h(title)e(titlefont)g(centre)h("FunnelWeb)f(.fw)h(File")177
+1290 y(@t)h(vskip)e(10)i(mm)177 1340 y(@t)g(title)e(smalltitlefont)f(centre)i
+("by)g(Ross)g(Williams")177 1390 y(@t)h(title)e(smalltitlefont)f(centre)i
+("26)g(January)f(1992")177 1440 y(@t)i(vskip)e(20)i(mm)177
+1490 y(@t)g(table_of_conten)o(ts)177 1589 y(@A@<FunnelWeb)d(Example)i
+(Program@>)177 1689 y(This)43 b(program)20 b(writes)43 b(out)21
+b(each)43 b(of)21 b(the)43 b(first)21 b(@{p@})42 b(powers)21
+b(of)43 b(the)21 b(first)43 b(@{n@})177 1739 y(integers.)20
+b(These)43 b(constant)20 b(parameters)g(are)h(located)42 b(here)21
+b(so)g(that)g(they)43 b(are)21 b(easy)g(to)177 1789 y(change.)177
+1888 y(@$@<Constants@>==@)o({@-)177 1938 y(n)h(:)f(constant)f(natural)h(:=)g
+(10;)109 b(--)21 b(How)g(many)g(numbers?)f(\(Ans:)h([1,n]\).)177
+1988 y(p)h(:)f(constant)f(natural)h(:=)43 b(5;)109 b(--)21
+b(How)g(many)g(powers?)42 b(\(Ans:)21 b([1,p]\).@})177 2087
+y(@B)h(Here)f(is)43 b(the)21 b(outline)f(of)i(the)43 b(program.)20
+b(This)h(FunnelWeb)f(file)42 b(generates)20 b(a)i(single)177
+2137 y(Ada)f(output)g(file)43 b(called)20 b(@{Power.ada@}.)f(The)i(main)g
+(program)g(consists)42 b(of)21 b(a)g(loop)g(that)177 2187 y(iterates)f(once)h
+(for)g(each)g(number)g(to)g(be)h(written)e(out.)177 2287 y
+(@O@<Power.ada@>==@)o({@-)177 2337 y(@<Pull)h(in)g(packages@>)177
+2436 y(procedure)f(example)g(is)243 2486 y(@<Constants@>)177
+2536 y(begin)h(--)g(example)243 2586 y(for)g(i)g(in)h(1..n)f(loop)308
+2635 y(@<Write)f(out)h(the)h(first)e(p)i(powers)f(of)g(i)g(on)h(a)f(single)g
+(line@>)243 2685 y(end)g(loop;)177 2735 y(end)g(example;)177
+2785 y(@})1042 2940 y Fr(38)p eop
+%%Page: 39 40
+39 39 bop 177 42 a Fl(@B)22 b(In)f(this)g(section,)42 b(we)21
+b(pull)g(in)h(the)f(packages)f(that)h(this)g(program)42 b(needs)21
+b(to)g(run.)g(In)177 91 y(fact,)g(all)g(we)g(need)g(is)h(the)f(IO)g(package)g
+(so)g(that)g(we)g(can)h(write)e(out)i(the)f(results.)f(To)h(use)177
+141 y(the)g(IO)h(package,)e(we)h(first)g(of)g(all)h(need)42
+b(to)22 b(haul)f(it)g(in)g(\(@{with)g(text_io@}\))e(and)j(then)177
+191 y(we)g(need)f(to)g(make)g(all)g(its)g(identifiers)f(visible)g(at)h(the)h
+(top)f(level)g(\(@{use)f(text_io@}\).)177 291 y(@$@<Pull)g(in)i
+(packages@>==@{wi)o(th)d(text_io;)h(use)h(text_io;@})177 390
+y(@B)h(Here)f(is)43 b(the)21 b(bit)g(that)g(writes)g(out)43
+b(the)21 b(first)f(@{p@})h(powers)g(of)43 b(@{i@}.)20 b(The)i(power)177
+440 y(values)43 b(are)f(calculated)g(incrementally)f(in)i(@{ip@})f(to)i
+(avoid)e(the)h(use)g(of)g(the)177 490 y(exponentiation)19 b(operator.)177
+589 y(@$@<Write)h(out)h(the)g(first)g(p)h(powers)e(of)i(i)f(on)h(a)f(single)g
+(line@>==@{@-)177 639 y(declare)243 689 y(ip)g(:)h(natural)e(:=)h(1;)177
+739 y(begin)243 789 y(for)g(power)f(in)i(1..p)f(loop)308 839
+y(ip:=ip*i;)308 888 y(put\(natural'image)o(\(ip\))d(&)k(")g("\);)243
+938 y(end)f(loop;)243 988 y(new_line;)177 1038 y(end;@})177
+1137 y(@!----------------)o(-----)o(-----)o(-----)o(-----)o(---!)177
+1187 y(@!)65 b(End)21 b(of)h(FunnelWeb)e(Example)g(.fw)h(File)65
+b(!)177 1237 y(@!----------------)o(-----)o(-----)o(-----)o(-----)o(---!)177
+1399 y Fi(1.9)70 b(Summary)177 1515 y Fr(This)17 b(c)o(hapter)h(has)f(pro)o
+(vided)g(an)g(in)o(tro)q(duction)g(to)g(F)m(unnelW)m(eb)f(and)h(a)g(tutorial)
+f(that)i(co)o(v)o(ers)f(most)f(of)h(its)177 1565 y(features.)h(F)m(unnelW)m
+(eb's)11 b(functionalit)o(y)f(can)h(b)q(e)h(split)f(in)o(to)g(t)o(w)o(o)g
+(parts:)17 b(a)11 b(macro)f(prepro)q(cessor,)k(and)d(supp)q(ort)177
+1615 y(for)h(t)o(yp)q(esetting.)18 b(The)13 b(reader)g(should)f(b)q(e)g(a)o
+(w)o(are)g(that)g(the)h(examples)e(in)g(this)h(c)o(hapter,)h(constructed)h
+(as)e(they)177 1664 y(w)o(ere)h(to)e(demonstrate)g(particular)g(features)i
+(of)e(F)m(unnelW)m(eb,)g(do)g(not)g(presen)o(t)i(a)e(realistic)h(picture)g
+(of)f(the)h(b)q(est)177 1714 y(use)j(of)f(the)h(to)q(ol.)k(Only)14
+b(the)h(\014nal)f(example)f(of)h(this)h(c)o(hapter)g(comes)f(close.)20
+b(The)15 b(reader)h(should)e(study)h(this)177 1764 y(last)g(example)f
+(carefully)h(and)g(then)h(write)f(some)f(real)h(programs)f(using)h(F)m
+(unnelW)m(eb)g(b)q(efore)h(pro)q(ceeding)g(to)177 1814 y(Chapter)c(2)f(whic)o
+(h)g(pro)o(vides)g(more)f(adv)n(anced)h(information.)k(A)o(t)c(this)g(stage)h
+(it)e(do)q(es)i(not)f(particularly)f(matter)177 1864 y(exactly)i(ho)o(w)e(y)o
+(ou)h(use)h(F)m(unnelw)o(eb,)g(as)f(ev)o(ery)o(one)h(dev)o(elops)g(their)f(o)
+o(wn)g(st)o(yle)h(an)o(yw)o(a)o(y)m(.)j(The)d(imp)q(ortan)o(t)d(thing)177
+1914 y(is)14 b(to)g(try)g(it.)1042 2940 y(39)p eop
+%%Page: 40 41
+40 40 bop 1042 2940 a Fr(40)p eop
+%%Page: 41 42
+41 41 bop 177 373 a Fj(Chapter)34 b(2)177 602 y Fp(F)-10 b(unnelW)g(eb)41
+b(Hin)m(ts)177 838 y Fr(Whereas)12 b(Chapter)f(1)g(pro)o(vides)g(an)f(in)o
+(tro)q(duction)h(to)g(F)m(unnelW)m(eb)f(and)g(Chapter)i(3)e(a)h
+(de\014nition,)f Fm(this)h Fr(c)o(hapter)177 888 y(con)o(tains)i(hin)o(ts)g
+(ab)q(out)f(ho)o(w)g(F)m(unnelW)m(eb)h(can)g(b)q(e)g(used.)19
+b(This)12 b(c)o(hapter)i(probably)e(should)g(not)h(b)q(e)g(read)h(un)o(til)
+177 938 y(the)j(reader)g(has)f(already)g(commenced)f(using)h(F)m(unnelW)m
+(eb,)g(or)g(at)f(the)i(v)o(ery)g(least,)f(tried)g(out)g(some)g(of)f(the)177
+987 y(examples)f(in)h(Chapter)h(1.)21 b(Those)15 b(who)g(\014nd)g(themselv)o
+(es)h(using)e(F)m(unnelW)m(eb)h(frequen)o(tly)g(should)g(read)h(this)177
+1037 y(c)o(hapter)f(at)f(some)f(stage)h(so)g(as)g(to)g(ensure)h(that)f(they)h
+(are)f(getting)g(the)g(most)f(out)h(of)f(it.)177 1108 y(Most)19
+b(of)f(the)h(examples)f(in)g(this)h(c)o(hapter)h(ha)o(v)o(e)e(b)q(een)i
+(placed)f(in)f(the)h(F)m(unnelW)m(eb)g(regression)h(test)f(suite)177
+1157 y(whic)o(h)14 b(should)g(b)q(e)g(a)o(v)n(ailable)e(in)h(a)h(directory)g
+(called)g Fl(/fwdir/tests/)p Fr(.)h(The)f(\014les)h(to)e(examine)g(are)h
+Fl(hi01.fw)177 1207 y Fr(through)g Fl(hi10.fw)p Fr(.)177 1363
+y Fi(2.1)70 b(Macro)24 b(Names)177 1475 y Fr(When)17 b(using)f(F)m(unnelW)m
+(eb,)g(the)h(c)o(hoice)g(of)f(macro)f(names)h(can)g(b)q(e)h(as)g(imp)q(ortan)
+o(t)e(to)h(the)h(readabilit)o(y)e(of)h(a)177 1525 y(program)d(as)h(the)h(c)o
+(hoice)g(of)f(program)f(iden)o(ti\014ers,)h(and)g(it)g(is)h(imp)q(ortan)o(t)d
+(that)j(the)g(user)g(kno)o(w)f(the)h(range)f(of)177 1574 y(options)g(a)o(v)n
+(ailable.)295 1645 y Fo(Names)i(are)f(case)h(sensitiv)o(e)d(and)i(exact)g
+(matc)o(hing:)i Fr(Macro)c(names)g(are)h(case)h(sensitiv)o(e)295
+1695 y(and)e(are)f(matc)o(hed)g(exactly)m(.)17 b(The)c(strings)g(used)g(as)g
+(a)f(macro)f(name)g(at)h(the)h(p)q(oin)o(t)f(of)g(de\014nition)295
+1744 y(and)i(call)f(m)o(ust)g(b)q(e)h Fm(identic)n(al)g Fr(for)g(the)g
+(connection)h(to)e(b)q(e)i(made.)295 1815 y Fo(Names)e(can)f(con)o(tain)f(an)
+o(y)h(prin)o(tabl)o(e)e(c)o(haracter:)16 b Fr(F)m(unnelW)m(eb)10
+b(is)h(less)h(restrictiv)o(e)g(ab)q(out)295 1865 y(its)19 b(macro)d(names)i
+(than)g(most)f(programming)e(languages)i(are)i(ab)q(out)f(their)h(iden)o
+(ti\014ers.)32 b(A)295 1914 y(F)m(unnelW)m(eb)15 b(macro)e(name)h(can)h(con)o
+(tain)g(an)o(y)f(sequence)j(of)e(prin)o(table)f(c)o(haracters,)j(including)
+295 1964 y(blanks)12 b(and)f(punctuation.)18 b(Names)11 b(can)h(start)g(and)g
+(end)g(with)f(an)o(y)h(c)o(haracter.)18 b(Names)11 b(cannot)295
+2014 y(cross)k(line)f(b)q(oundaries.)k(The)d(follo)o(wing)c(are)j(all)f
+(legal)g(macro)f(names:)352 2115 y Fl(@<This)20 b(macro)h(expands)f(to)i
+(some)f(really)f(bad)h(code@>)352 2165 y(@<@>)352 2215 y(@<453)f(#$)i(\045&#)
+f(--===~~1">>>@>)352 2265 y(@<<@>)352 2314 y(@<<>@>)352 2364
+y(@<a)g(b)g(c)h(d)f(e)h(f)g(g@>)352 2414 y(@<)152 b(!)108 b(@>)352
+2464 y(@<??)20 b(...@>)352 2514 y(@<"Who's)g(been)h(hacking)f(MY)h(program")f
+(said)h(Father)g(Bear.@>)352 2564 y(@<Update)f(the)h(maximum)f(and)h(return)g
+(for)g(more)g(data@>)295 2665 y Fo(Names)16 b(m)o(ust)d(b)q(e)i(no)g(more)f
+(than)g(a)i(maxim)o(um)d(limit)g(in)h(length:)i Fr(Names)c(can)i(b)q(e)g(no)
+295 2714 y(longer)e(than)h(a)f(prede\014ned)i(maxim)o(um)8
+b(length.)17 b(Curren)o(tly)c(this)f(length)h(cannot)f(b)q(e)i(mo)q
+(di\014ed.)177 2785 y(T)o(ypically)m(,)8 b(macro)h(names)g(will)f(consist)j
+(of)e(a)h(short)g(English)g(phrase)g(or)g(sen)o(tence)i(that)e(describ)q(es)i
+(the)f(con)o(ten)o(ts)177 2835 y(of)i(the)i(macro.)1042 2940
+y(41)p eop
+%%Page: 42 43
+42 42 bop 177 42 a Fi(2.2)70 b(Quic)n(k)22 b(Names)177 157
+y Fr(Sometimes)14 b(a)i(particular)g(macro)g(m)o(ust)f(b)q(e)i(used)g
+(extremely)f(often.)25 b(When)17 b(this)f(happ)q(ens)h(it)f(is)g(desirable)
+177 207 y(to)e(mak)o(e)f(the)i(macro's)e(name)g(as)h(short)h(as)f(p)q
+(ossible.)20 b(The)15 b(shortest)g(ordinary)f(F)m(unnelW)m(eb)g(macro)f(name)
+g(is)177 257 y(the)h(empt)o(y)f(name)g(\\)p Fl(@<@>)p Fr(",)f(whic)o(h)h(is)h
+(four)f(c)o(haracters)j(long.)h(Single-c)o(haracter)d(names)f(are)h(\014v)o
+(e)g(c)o(haracters)177 307 y(long.)177 381 y(T)m(o)h(cater)i(for)e(the)h
+(cases)h(where)g(really)e(short)h(names)f(are)h(needed,)h(F)m(unnelW)m(eb)e
+(pro)o(vides)h(a)f Fo(quic)o(k)i(name)177 431 y Fr(syn)o(tax)c(that)h(allo)o
+(ws)e(one-c)o(haracter)i(macro)e(names)h(to)g(b)q(e)h(sp)q(eci\014ed)g(in)f
+(t)o(w)o(o)g(less)h(c)o(haracters.)19 b(Quic)o(k)14 b(names)177
+481 y(tak)o(e)20 b(the)h(form)d(of)i(the)h(sp)q(ecial)f(c)o(haracter,)i
+(follo)o(w)o(ed)d(b)o(y)h(a)g(hash)g(\()p Fl(#)p Fr(\))g(follo)o(w)o(ed)e(b)o
+(y)i(a)g(single)g(c)o(haracter.)177 531 y(Examples:)177 647
+y Fl(@#A)109 b(@#|)f(@#&)g(@#m)177 763 y Fr(This)17 b(form)d(of)i(macro)f
+(name)h(has)g(the)h(same)f(syn)o(tactic)h(functionalit)o(y)e(as)i(an)f
+(ordinary)g(name)f(and)h(can)h(b)q(e)177 813 y(substituted)g(wherev)o(er)g
+(an)f(ordinary)f(name)g(can)g(b)q(e.)24 b(In)16 b(fact)g(quic)o(k)f(names)g
+(liv)o(e)g(in)g(the)h(same)f(namespace)177 863 y(as)g(ordinary)g(macro)e
+(names.)21 b(F)m(or)15 b(example)e(the)j(quic)o(kname)d Fl(@#A)i
+Fr(is)f(the)i Fm(same)g(name)g Fr(\(refers)g(to)f(the)h(same)177
+913 y(macro\))d(as)h(the)g(ordinary)g(name)f Fl(@<A@>)p Fr(.)177
+988 y(Because)g(quic)o(k)d(names)g(lo)q(ok)g(syn)o(tactically)g(\\op)q(en")h
+(\(i.e.)f(they)h(do)g(not)f(ha)o(v)o(e)h(a)g(closing)p Fl(@>)e
+Fr(as)i(ordinary)g(names)177 1037 y(do\),)i(it)h(is)g(b)q(est)h(to)f(a)o(v)o
+(oid)e(them)h(except)i(where)g(a)f(macro)f(m)o(ust)g(b)q(e)h(called)g(v)o
+(ery)g(often.)177 1200 y Fi(2.3)70 b(F)-6 b(unnelW)g(eb)22
+b(the)h(Martinet)177 1315 y Fr(There)13 b(are)g(man)o(y)d(w)o(a)o(ys)i(in)g
+(whic)o(h)g(a)g(macro)f(prepro)q(cessor)j(can)f(cause)g(unexp)q(ected)h
+(di\016culties.)j(F)m(unnelW)m(eb)177 1365 y(seeks)g(to)d(a)o(v)o(oid)g(man)o
+(y)f(of)h(these)j(problems)d(b)o(y)g(p)q(erforming)g(a)g(n)o(um)o(b)q(er)g
+(of)h(c)o(hec)o(ks.)22 b(This)15 b(section)h(describ)q(es)177
+1415 y(some)d(of)g(the)i(c)o(hec)o(ks)g(that)f(F)m(unnelW)m(eb)f(p)q
+(erforms.)295 1490 y Fo(T)l(railing)h(blanks)h(in)g(the)h(input)e(\014le:)k
+Fr(T)m(railing)12 b(blanks)i(are)h(usually)f(not)g(dangerous,)g(but)295
+1540 y(F)m(unnelW)m(eb)19 b(disallo)o(ws)e(them)i(an)o(yw)o(a)o(y)m(.)31
+b(All)18 b(trailing)g(blanks)g(in)h(the)g Fm(input)h Fr(\()p
+Fl(.fw)e Fr(\014le\))h(are)295 1589 y(\015agged)d(as)h(errors)g(b)o(y)f(F)m
+(unnelW)m(eb.)25 b(F)m(unnelW)m(eb)15 b(do)q(es)i(not)f(\015ag)g(trailing)f
+(blanks)h(in)g(an)o(y)f(of)295 1639 y(its)f(output)g(\014les.)295
+1714 y Fo(Input)19 b(line)f(length:)24 b Fr(F)m(unnelW)m(eb)17
+b(has)g(a)h(maxim)n(um)13 b(input)18 b(line)f(length.)29 b(If)17
+b(F)m(unnelW)m(eb)295 1764 y(reads)h(an)e(input)h(line)f(longer)g(than)h
+(this)f(length,)h(it)f(\015ags)h(the)g(line)f(with)g(an)h(error)g(message.)
+295 1813 y(The)e(maxim)n(um)9 b(length)14 b(can)g(b)q(e)h(c)o(hanged)f(using)
+g(a)f(pragma)f(\(see)k(Chapter)e(3\).)295 1888 y Fo(Pro)q(duct)k(\014le)h
+(line)f(length:)23 b Fr(F)m(unnelW)m(eb)16 b(w)o(atc)o(hes)i(the)g(length)g
+(of)e(output)i(lines)f(and)g(all)295 1938 y(output)h(lines)f(longer)g(than)h
+(the)g(limit)c(are)k(\015agged)f(with)g(error)h(messages.)29
+b(The)18 b(maxim)n(um)295 1988 y(length)h(can)g(b)q(e)g(c)o(hanged)h(using)e
+(a)h(pragma)d(\(see)21 b(Chapter)e(3\).)33 b(That)18 b(F)m(unnelW)m(eb)g(p)q
+(olices)295 2038 y(output)c(lines)f(is)h(v)o(ery)f(imp)q(ortan)o(t.)j(Some)d
+(programs)f(can)i(b)q(eha)o(v)o(e)f(v)o(ery)h(strangely)g(if)e(they)i(get)295
+2087 y(an)i(input)g(line)g(that)g(is)h(to)q(o)f(long)f(\(e.g.)h(F)m(ortran)g
+(compilers)f(can)h(simply)f(ignore)h(text)g(past)h(a)295 2137
+y(certain)e(column!\))i(and)d(once)h(F)m(unnelW)m(eb)e(starts)i(expanding)f
+(macros)f(using)h(inden)o(tation,)f(it)295 2187 y(is)h(sometimes)e(not)i(ob)o
+(vious)f(ho)o(w)h(wide)f(the)i(pro)q(duct)g(\014le)f(will)e(b)q(e.)295
+2262 y Fo(Con)o(trol)j(c)o(haracters:)20 b Fr(The)c(presence)h(of)e(con)o
+(trol)g(c)o(haracters)i(in)d(a)h(text)h(\014le)f(can)g(result)h(in)295
+2312 y(some)11 b(confusing)g(b)q(eha)o(viour)h(do)o(wnstream)f(when)h(the)g
+(\014le)g(is)f(presen)o(ted)j(to)d(v)n(arious)g(programs.)295
+2361 y(Unfortunately)m(,)i(some)f(text)i(editors)g(allo)o(w)e(con)o(trol)h(c)
+o(haracters)i(to)f(b)q(e)g(inserted)g(in)o(to)f(the)h(text)295
+2411 y(rather)i(to)q(o)g(easily)m(,)e(and)h(it)g(is)g(all)f(to)q(o)h(easy)h
+(to)f(b)q(e)h(tripp)q(ed)g(up.)23 b(F)m(unnelW)m(eb)15 b(prev)o(en)o(ts)h
+(these)295 2461 y(problems)e(b)o(y)g(\015agging)f(with)i(diagnostics)f(all)f
+(non-end-of-line)h(con)o(trol)g(c)o(haracters)j(detected)295
+2511 y(in)f(the)h(input)f(\()p Fl(.fw)p Fr(\))g(\014le)h(\(ev)o(en)g(T)m
+(ABs\).)26 b(The)17 b(result)g(is)f(that)h(the)g(user)g(is)g(guaran)o(teed)g
+(that)295 2561 y(pro)q(duct)e(\014les)f(generated)h(from)d(F)m(unnelW)m(eb)h
+(con)o(tain)h(no)f(unin)o(ten)o(tional)g(con)o(trol)g(c)o(haracters.)295
+2610 y(This)g(said,)g(F)m(unnelW)m(eb)f(do)q(es)i(allo)o(w)d(the)j(insertion)
+f(of)g(con)o(trol)f(c)o(haracters)j(in)e(the)g(output)h(\014le)295
+2660 y(b)o(y)g(explicitly)f(sp)q(ecifying)h(them)f(in)g(the)i(text)f(using)g
+(a)f Fl(@^)h Fr(con)o(trol)f(sequence.)295 2735 y Fo(Num)o(b)q(er)j(of)g(in)o
+(v)o(o)q(cations:)h Fr(F)m(unnelW)m(eb)d(c)o(hec)o(ks)i(the)f(n)o(um)o(b)q
+(er)f(of)g(times)f(that)i(eac)o(h)g(macro)295 2785 y(is)j(called)f(and)g
+(issues)i(an)e(error)i(if)d(the)j(total)d(is)i(not)f(one.)29
+b(The)18 b Fl(@Z)g Fr(\(for)f(zero\))h(and)g Fl(@M)f Fr(\(for)295
+2835 y(man)o(y\))12 b(macro)h(attributes)i(can)f(b)q(e)g(used)h(to)f(b)o
+(ypass)g(these)h(c)o(hec)o(ks.)1042 2940 y(42)p eop
+%%Page: 43 44
+43 43 bop 295 42 a Fo(Recursion:)28 b Fr(Because)21 b(F)m(unnelW)m(eb)e(do)q
+(es)h(not)g(pro)o(vide)f(an)o(y)g(conditional)f(constructs,)23
+b(all)295 91 y(recursiv)o(ely)17 b(de\014ned)g(macros)e(m)o(ust,)g(b)o(y)g
+(de\014nition,)h(expand)g(in\014nitely)m(,)1483 76 y Fg(1)1516
+91 y Fr(and)g(are)g(therefore)295 141 y(unacceptable.)37 b(F)m(unnelW)m(eb)20
+b(p)q(erforms)f Fm(static)h Fr(c)o(hec)o(ks)h(to)f(detect)h(recursion,)h
+(detecting)f(it)295 191 y(b)q(efore)13 b(macro)d(expansion)i(commences.)k
+(The)d(user)f(need)h(not)f(fear)g(that)g(F)m(unnelW)m(eb)f(will)f(lo)q(c)o(k)
+295 241 y(up)k(or)g(sp)q(ew)h(forth)f(if)f(a)g(recursiv)o(e)j(macro)c(is)i
+(acciden)o(tally)f(sp)q(eci\014ed.)177 399 y Fi(2.4)70 b(Fiddling)21
+b(With)h(End)i(of)f(Lines)177 512 y Fr(One)13 b(of)f(the)h(\014ddly)f(asp)q
+(ects)j(of)c(programming)e(with)j(F)m(unnelW)m(eb)g(is)h(coping)f(with)g(end)
+h(of)f(lines.)17 b(If)12 b(y)o(ou)g(w)o(an)o(t)177 562 y(y)o(our)17
+b(pro)q(duct)h(\014le)e(to)h(b)q(e)h(w)o(ell)e(inden)o(ted)h(without)g(m)o
+(ultiple)d(blank)i(lines)h(or)g(co)q(de)g(run-ons,)h(y)o(ou)e(ha)o(v)o(e)h
+(to)177 612 y(sp)q(end)e(a)f(little)f(time)f(w)o(orking)h(out)h(ho)o(w)g(the)
+g(end)h(of)e(line)g(mark)o(ers)h(get)g(mo)o(v)o(ed)e(around.)177
+684 y(The)k(rule)g(to)f(remem)o(b)q(er)g(is)g(that,)g(disregarding)h(the)g
+(e\013ects)h(of)e(sp)q(ecial)h(sequences)i(within)c(a)h(macro)g(b)q(o)q(dy)m
+(,)177 733 y Fm(the)i(b)n(o)n(dy)g(of)g(a)g(macr)n(o)f(c)n(onsists)h(of)g
+(exactly)g(the)f(text)h(b)n(etwe)n(en)g(the)f(op)n(ening)i
+Fl(@)p Fq(f)e Fm(and)i(the)f(closing)f Fl(@)p Fq(g)p Fr(.)24
+b(This)177 783 y(text)15 b(includes)f(end)g(of)g(line)f(mark)o(ers.)177
+855 y(If)h(for)f(example)g(y)o(ou)g(call)g(a)h(macro)f(in)g(a)h(sequence)i
+(of)d(co)q(de)p Fn(:)7 b(:)g(:)177 961 y Fl(while)21 b(the_walrus_is_sle)o
+(epy)e(do)243 1011 y(begin)243 1061 y(writeln\('zzzzzz)o(z'\);)243
+1111 y(@<Wake)h(up)h(the)h(walrus@>)243 1161 y(writeln\('Umphar)o(umpha)o
+(...'\))o(;)243 1211 y(end;)177 1317 y Fr(where)15 b Fl(<wake)21
+b(up)g(the)h(walrus>)12 b Fr(is)i(de\014ned)h(as)f(follo)o(ws)177
+1423 y Fl(@$@<Wake)20 b(up)i(the)f(walrus@>==@{)177 1473 y
+(wake_up_the_walrus)o(\(the_)o(walru)o(s\);)177 1523 y(@})177
+1629 y Fr(then)15 b(when)f Fl(<Wake)21 b(up)g(the)g(walrus>)13
+b Fr(is)h(expanded)g(y)o(ou)g(will)e(get)177 1736 y Fl(while)21
+b(the_walrus_is_sle)o(epy)e(do)243 1786 y(begin)243 1835 y(writeln\("zzzzzz)o
+(z"\);)243 1935 y(wake_up_the_wal)o(rus\(t)o(he_wa)o(lrus\))o(;)243
+2035 y(writeln\("Umphar)o(umpha)o(..."\))o(;)243 2085 y(end;)177
+2191 y Fr(The)13 b(blank)f(lines)h(w)o(ere)g(in)o(tro)q(duced)h(b)o(y)e(the)i
+(end)f(on)f(line)h(mark)o(ers)f(included)h(in)f(the)h(de\014nition)f(of)g
+Fl(<Wake)21 b(up)177 2241 y(the)g(walrus>)p Fr(.)e(A)c(go)q(o)q(d)f(solution)
+f(to)i(this)g(problem)e(is)h(to)h(suppress)h(the)f(end)g(of)f(line)h(mark)o
+(ers)e(b)o(y)i(de\014ning)177 2291 y(the)g(macro)d(as)i(follo)o(ws)177
+2397 y Fl(@$@<Wake)20 b(up)i(the)f(walrus@>==@{@-)177 2447
+y(wake_up_the_walrus)o(\(the_)o(walru)o(s\);@})177 2553 y Fr(This)14
+b(is)g(the)g(usual)g(form)e(of)h(macro)g(de\014nitions)h(in)f(F)m(unnelW)m
+(eb)h(\014les.)177 2625 y(In)g(additiv)o(e)f(macros,)g(this)h(format)e(do)q
+(es)j(not)f(w)o(ork)f(prop)q(erly)i(b)q(ecause)g(the)g(end)g(of)e(line)g
+(that)h(is)g(suppressed)177 2675 y(b)o(y)f(the)h(trailing)d
+Fl(@)p Fq(g)i Fr(do)q(es)h(not)f(get)g(replaced)i(b)o(y)d(the)i(end)g(of)e
+(line)h(at)g(the)h(end)f(of)g(the)h(macro)e(in)o(v)o(o)q(cation.)k(F)m(or)177
+2725 y(example)d(the)h(de\014nition)p 177 2757 709 2 v 223
+2783 a Ff(1)241 2795 y Fh(A)f(sp)q(ecial)f(case)g(exists)g(where)h(there)e
+(is)i(recursion)e(but)h(no)h(con)o(ten)o(t.)18 b(In)12 b(this)h(case,)f(the)h
+(expansion)d(is)j(\014nite)f(\(the)g(empt)o(y)177 2835 y(string\))e(ev)o(en)g
+(though)g(the)h(op)q(eration)e(of)i(expanding)d(is)k(in\014nite.)h(F)m
+(unnelW)m(eb)d(do)q(es)g(not)h(treat)f(this)h(case)g(sp)q(ecially)m(.)1042
+2940 y Fr(43)p eop
+%%Page: 44 45
+44 44 bop 177 42 a Fl(@$@<Wake)20 b(up)i(the)f(walrus@>+=@{@-)177
+91 y(wake_up_the_walrus)o(_once)o(\(the_)o(walru)o(s\);@})177
+205 y Fr(later)14 b(follo)o(w)o(ed)e(b)o(y)177 318 y Fl(@$@<Wake)20
+b(up)i(the)f(walrus@>+=@{@-)177 368 y(wake_up_the_walrus)o(_agai)o(n\(the)o
+(_walr)o(us\);@)o(})177 482 y Fr(is)14 b(equiv)n(alen)o(t)f(to)h(the)g
+(single)g(de\014nition)177 595 y Fl(@$@<Wake)20 b(up)i(the)f(walrus@>==@{@-)
+177 645 y(wake_up_the_walrus)o(_once)o(\(the_)o(walru)o(s\);wa)o(ke_u)o
+(p_the)o(_walr)o(us_ag)o(ain\(t)o(he_wa)o(lrus)o(\);@})177
+759 y Fr(Putting)14 b(the)h(trailing)e Fl(@)p Fq(g)h Fr(on)g(a)g(new)h(line)f
+(at)g(the)h(end)g(of)f(the)g(macro)g(\(except)h(for)f(the)h(last)g
+(de\014nition)e(part\))177 809 y(solv)o(es)h(the)h(problem.)177
+922 y Fl(@$@<Wake)20 b(up)i(the)f(walrus@>+=@{@-)177 972 y
+(wake_up_the_walrus)o(_once)o(\(the_)o(walru)o(s\);)177 1022
+y(@})177 1135 y Fr(later)14 b(follo)o(w)o(ed)e(b)o(y)177 1249
+y Fl(@$@<Wake)20 b(up)i(the)f(walrus@>+=@{@-)177 1299 y(wake_up_the_walrus)o
+(_agai)o(n\(the)o(_walr)o(us\);@)o(})177 1412 y Fr(is)14 b(equiv)n(alen)o(t)f
+(to)h(the)g(single)g(de\014nition)177 1526 y Fl(@$@<Wake)20
+b(up)i(the)f(walrus@>==@{@-)177 1576 y(wake_up_the_walrus)o(_once)o(\(the_)o
+(walru)o(s\);)177 1625 y(wake_up_the_walrus)o(_agai)o(n\(the)o(_walr)o
+(us\);@)o(})177 1739 y Fr(Managing)12 b(end)i(of)f(line)g(mark)o(ers)g(is)g
+(tric)o(ky)m(,)g(but)h(once)g(y)o(ou)f(establish)g(a)h(con)o(v)o(en)o(tion)f
+(for)g(coping)g(with)g(them,)177 1789 y(the)i(problem)d(disapp)q(ears)j(in)o
+(to)e(the)i(bac)o(kground.)177 1950 y Fi(2.5)70 b(F)-6 b(udging)24
+b(Conditionals)177 2065 y Fr(As)13 b(a)g(macro)e(prepro)q(cessor,)k(the)e
+(facilit)o(y)e(that)i(F)m(unnelW)m(eb)f(most)g(ob)o(viously)f(lac)o(ks)h(is)h
+(a)f(conditional)f(facilit)o(y)177 2115 y(\(suc)o(h)19 b(as)e(C's)h
+Fl(#ifdef)p Fr(\).)28 b(It)18 b(migh)o(t,)e(therefore,)k(come)c(as)i(a)f
+(surprise)i(to)f(kno)o(w)f(that)h(the)g(\014rst)h(v)o(ersion)e(of)177
+2164 y(F)m(unnelW)m(eb)g(actually)g(had)g(a)g(built)g(in)g(conditional)g
+(facilit)o(y)m(.)26 b(The)18 b(facilit)o(y)e(allo)o(w)o(ed)h(the)h
+(programmer)d(to)177 2214 y(sp)q(ecify)f(a)e(construct)i(that)f(w)o(ould)f
+(select)i(from)d(one)i(of)g(a)f(n)o(um)o(b)q(er)g(of)g(macro)g(expressions)i
+(dep)q(ending)g(on)e(the)177 2264 y(v)n(alue)h(of)h(a)f(con)o(trolling)g
+(macro)f(expression.)177 2338 y(In)i(three)h(y)o(ears)g(the)f(construct)i(w)o
+(as)e(nev)o(er)g(used.)177 2412 y(The)f(reason)g(w)o(as)f(that)h(conditional)
+e(constructs)j(could)e(b)q(e)i(fudged)e(nearly)g(as)h(easily)f(as)g(they)h
+(could)f(b)q(e)h(used.)177 2462 y(Because)j(of)e(this,)f(the)i(in)o(built)e
+(conditional)f(feature)j(w)o(as)f(remo)o(v)o(ed)f(in)h(the)h(curren)o(t)g(v)o
+(ersion)f(of)g(F)m(unnelW)m(eb.)177 2512 y(Not)e(only)e(did)h(this)h
+(simplify)c(the)k(program,)e(but)h(is)h(also)e(allo)o(w)o(ed)h(recursiv)o(e)h
+(macros)f(to)g(b)q(e)h(detected)i(through)177 2561 y(static)g(analysis)g
+(rather)g(than)g(during)g(macro)e(expansion.)177 2635 y(There)18
+b(are)g(t)o(w)o(o)e(basic)h(w)o(a)o(ys)g(to)g(fudge)g(a)f(conditional.)26
+b(First,)18 b(the)f(commen)o(t)e(facilit)o(y)h(of)g(the)h(target)h(pro-)177
+2685 y(gramming)11 b(language)i(ma)o(y)f(b)q(e)j(emplo)o(y)o(ed.)i(F)m(or)c
+(example,)g(in)g(Ada,)h(commen)o(ts)e(commence)h(with)h(\\)p
+Fl(--)p Fr(")f(and)177 2735 y(terminate)g(at)h(the)h(end)f(of)g(the)g(line.)k
+(Using)c(this)g(fact,)g(it)f(is)h(easy)h(to)e(construct)j(macros)d(that)h
+(can)g(b)q(e)h(called)177 2785 y(at)d(the)g(start)h(of)e(eac)o(h)h(target)g
+(line)g(and)f(whic)o(h)h(turn)g(on)g(and)f(o\013)h(the)g(lines)g(so)g(mark)o
+(ed)e(b)o(y)i(de\014ning)g(the)g(macro)177 2835 y(to)i(b)q(e)g(the)h(empt)o
+(y)e(string)h(\(ON\))g(or)g(the)h(commen)o(t)c(sym)o(b)q(ol)h(\()p
+Fl(--)p Fr(\))i(\(OFF\).)g(F)m(or)g(example:)1042 2940 y(44)p
+eop
+%%Page: 45 46
+45 45 bop 177 42 a Fl(@A@<Debug)20 b(Macro@>)177 141 y(The)h(following)f
+(macro)h(determines)f(whether)g(debug)h(code)g(will)g(be)g(included)f(in)i
+(the)177 191 y(program.)e(All)h(lines)g(of)h(debug)e(code)h(commence)f(with)h
+(a)h(call)f(to)g(this)g(macro)g(and)g(so)177 241 y(we)h(can)f(turn)g(all)g
+(that)g(code)g(on)g(or)h(off)f(here)g(by)g(defining)f(this)h(macro)g(to)g(be)
+h(either)177 291 y(empty)f(or)g(the)g(single-line)f(comment)g(symbol)h
+(\(\\p{--}\).)f(Note)h(the)g(use)g(of)h(a)177 340 y(quick)f(macro)g(name.)177
+440 y(@$@#D@M==@{@})106 b(@!)22 b(Turns)f(the)g(debug)g(code)f(ON.)177
+490 y(@!)i(Use)f(this)g(definition)e(to)j(turn)f(the)g(debug)g(code)g(OFF:)g
+(@$@#D==@{--@})177 589 y(...)g(then)g(later)g(in)g(the)h(file...)177
+689 y(@$@<Sloth)e(incrementing)f(loop@>==@{@-)177 739 y(while)i(sloth<walrus)
+e(loop)243 789 y(@#D)i(assert\(sloth<wal)o(rus,")o(AWK!)d
+(sloth>=walrus!!!!!!)o(!"\);)243 839 y(@#D)j(assert\(timer<tim)o(ermax)o
+(,"AWK)o(!)e(timer>=timermax!!)o(!"\);)243 888 y(inc\(sloth\);)177
+938 y(end)i(loop@})177 1051 y Fr(The)16 b(other)f(w)o(a)o(y)f(to)h(fudge)g(a)
+f(conditional)g(is)h(to)g(de\014ne)g(a)g(macro)f(with)g(a)h(single)g
+(parameter.)20 b(A)15 b(call)f(to)h(the)177 1101 y(macro)g(is)g(then)i(wrapp)
+q(ed)g(around)e(all)g(the)h(conditional)f(co)q(de)i(in)e(the)h(program.)23
+b(The)16 b(macro)f(can)h(then)g(b)q(e)177 1151 y(de\014ned)f(to)f(presen)o(t)
+h(or)f(ignore)g(the)g(co)q(de)h(of)e(its)h(argumen)o(t.)j(F)m(or)d(example:)
+177 1263 y Fl(@A@<Debug)20 b(Macro@>)177 1363 y(The)h(following)f(macro)h
+(determines)f(whether)g(debug)h(code)g(will)g(be)g(included)f(in)i(the)177
+1413 y(program.)e(All)h(debug)g(code)g(is)h(wrapped)e(by)h(a)h(call)f(to)g
+(this)g(macro)g(and)g(so)177 1463 y(we)h(can)f(turn)g(all)g(the)g(debug)g
+(code)g(on)g(or)h(off)f(here)g(by)g(defining)f(this)h(macro)g(to)g(be)177
+1513 y(either)g(empty)f(or)i(its)f(parameter.)177 1612 y
+(@$@#D@\(@1@\)@M==@{@)o(1@})106 b(@!)21 b(Turns)g(the)g(debug)g(code)g(ON.)
+177 1662 y(@!)h(Use)f(this)g(definition)e(to)j(turn)f(the)g(debug)g(code)g
+(OFF:)g(@$@#D@\(@1@\)==@{@)o(})177 1762 y(...)g(then)g(later)g(in)g(the)h
+(file...)177 1861 y(@$@<Sloth)e(incrementing)f(loop@>==@{@-)177
+1911 y(while)i(sloth<walrus)e(loop)243 1961 y(@#D@\(assert\(slo)o(th<wa)o
+(lrus,)o("AWK!)f(sloth>=walrus!!!!!)o(!!"\);)352 2011 y(assert\(timer<ti)o
+(merma)o(x,"AW)o(K!)h(timer>=timermax!)o(!!"\);)o(@\))243 2060
+y(inc\(sloth\);)177 2110 y(end)i(loop@})177 2223 y Fr(In)16
+b(languages)g(that)g(allo)o(w)f(m)o(ulti-li)o(ne)f(commen)o(ts)g(\(e.g.)i(C)g
+(with)g Fl(/*)f Fr(and)h Fl(*/)p Fr(\),)g(commen)o(ts)f(can)h(b)q(e)h(used)g
+(to)177 2273 y(eliminate)12 b(the)j(conditioned)e(co)q(de)i(rather)g(than)f
+(absence.)19 b(F)m(or)14 b(example:)177 2386 y Fl(@$@#D@\(@1@\)@M==@{/)o(*)19
+b(@1)i(*/@})87 b(@!)21 b(Comments)f(out)h(the)h(debug)e(code)177
+2499 y Fr(\(Note:)i(If)15 b(this)h(example)e(w)o(ere)j(ev)o(er)f(actually)f
+(used,)h(the)h(programmer)c(w)o(ould)i(ha)o(v)o(e)g(to)g(b)q(e)i(careful)e
+(not)h(to)177 2548 y(place)e(commen)o(ts)e(in)i(the)g(argumen)o(t)f(co)q(de.)
+19 b(Nested)c(commen)o(ts)d(in)i(C)g(are)g(non-p)q(ortable.\))177
+2622 y(The)f(parameterized)f(macro)f(idea)g(can)i(b)q(e)f(generalized)h(to)f
+(supp)q(ort)h(the)f(c)o(hoice)h(of)e(more)g(than)h(one)g(m)o(utually)177
+2672 y(exclusiv)o(e)j(alternativ)o(e.)i(F)m(or)d(example:)177
+2785 y Fl(@A)22 b(This)f(module)f(contains)g(non-portable)g(code)g(that)h
+(must)g(execute)g(on)g(Hewlett)177 2835 y(Packard,)f(Sun,)h(and)g(DEC)h
+(workstations.)d(The)i(following)f(FunnelWeb)g(macro)h(is)1042
+2940 y Fr(45)p eop
+%%Page: 46 47
+46 46 bop 177 42 a Fl(defined)21 b(to)g(choose)f(between)h(these)g(three.)f
+(The)h(first)g(parameter)f(is)h(the)h(HP)f(code,)177 91 y(the)g(second)g(is)g
+(the)g(Sun)h(code,)e(and)i(the)f(third)f(is)i(the)f(DEC)g(code.)g(Whichever)
+177 141 y(parameter)f(constitutes)g(the)h(body)g(of)g(this)g(macro)g
+(determines)f(which)177 191 y(machine)h(the)g(code)g(is)g(being)g
+(targeted\\note{Di)o(ction)o(ary)e(says)i(only)g(one)g(t)177
+241 y(in)h(targeted.})d(for.)177 340 y(@$@<Machine)h(specific)g
+(code@>@\(@3@\)@M==@)o({@1@)o(})41 b(@!)21 b(Configure)f(for)h(HP.)177
+440 y(...then)g(later)f(in)i(the)f(file...)177 540 y(@<Machine)f(specific)g
+(code@>@\()177 589 y(@"get_command_line)o(\(coml)o(ine\)@)o(")237
+b(@,)21 b(@!)h(HP.)177 639 y(@"scan_command_lin)o(e\(128)o(,coml)o(ine\);)o
+(@")106 b(@,)21 b(@!)h(Sun.)177 689 y(@"dcl_get_command_)o(line\()o(comli)o
+(ne,25)o(6\);@")40 b(@\))21 b(@!)h(DEC.)177 793 y Fr(Of)13
+b(course,)g(this)g(could)f(also)g(b)q(e)h(p)q(erformed)f(using)h(three)h
+(separate)f(macros.)k(The)c(main)d(adv)n(an)o(tage)i(of)g(using)177
+842 y(a)j(single)g(macro)g(is)g(that)g(the)i(m)o(utual)c(exclusivit)o(y)i(is)
+g(enforced.)24 b(Also,)15 b(b)q(ecause)i(F)m(unnelW)m(eb)e(ensures)j(that)177
+892 y(the)d(n)o(um)o(b)q(er)f(of)g(formal)e(and)j(actual)f(parameters)h(are)g
+(the)g(same,)e(this)i(metho)q(d)f(lessens)i(the)f(c)o(hance)g(that)g(a)177
+942 y(mac)o(hine)e(will)f(b)q(e)j(forgotten)f(in)f(some)g(places.)177
+1099 y Fi(2.6)70 b(Changing)23 b(the)f(Strength)i(of)f(Headings)177
+1211 y Fr(F)m(unnelW)m(eb)18 b(pro)o(vides)g(\014v)o(e)g(heading)g(lev)o
+(els:)26 b Fl(@A)p Fr(,)17 b Fl(@B)p Fr(,)g Fl(@C)p Fr(,)g
+Fl(@D)p Fr(,)h(and)f Fl(@E)h Fr(to)g(whic)o(h)g(it)f(binds)i(\014v)o(e)f
+(di\013eren)o(t)177 1261 y(t)o(yp)q(ographical)e(strengths.)28
+b(These)17 b(bindings)f(are)h(static;)h(a)f(lev)o(el)f Fl(@A)g
+Fr(heading)g(will)f(alw)o(a)o(ys)h(b)q(e)h(t)o(yp)q(eset)h(in)177
+1311 y(a)e(particular)g(fon)o(t)g(size)h(regardless)h(of)e(the)g(size)i(of)d
+(the)i(do)q(cumen)o(t.)25 b(The)17 b(fon)o(t)f(sizes)h(ha)o(v)o(e)f(b)q(een)i
+(preset)g(to)177 1361 y(b)q(e)f(\\reasonable")e(for)h(a)f(range)h(of)f(do)q
+(cumen)o(t)h(sizes,)h(but)f(ma)o(y)d(b)q(e)k(inappropriate)e(for)h(v)o(ery)g
+(small)d(or)j(large)177 1410 y(do)q(cumen)o(ts.)177 1482 y(F)m(unnelW)m(eb)d
+(do)q(es)h(not)f(curren)o(tly)h(pro)o(vide)g(an)f(\\o\016cial")e(w)o(a)o(y)i
+(\(e.g.)f(a)h(pragma\))f(to)h(c)o(hange)h(the)g(t)o(yp)q(esetting)177
+1531 y(strength)f(of)f(headings.)17 b(This)12 b(feature)g(migh)o(t)e(b)q(e)j
+(added)f(in)f(later)h(v)o(ersions.)18 b(Mean)o(while,)12 b(a)f(hac)o(k)h(is)g
+(a)o(v)n(ailable)177 1581 y(that)17 b(will)e(do)h(the)i(job,)e(pro)o(viding)f
+(that)i(y)o(ou)f(do)h(not)f(mind)f(the)i(hac)o(k)g(b)q(eing)g(T)1490
+1590 y(E)1513 1581 y(X-sp)q(eci\014c)h(and)e(probably)177 1631
+y(F)m(unnelW)m(eb-v)o(ersion)e(sp)q(eci\014c.)177 1702 y(Inside)g(the)h(set)f
+(of)f(T)504 1711 y(E)528 1702 y(X)g(macro)g(de\014nitions)g(that)h(F)m
+(unnelW)m(eb)f(writes)i(at)e(the)i(top)e(of)h(ev)o(ery)g(do)q(cumen)o(tation)
+177 1752 y(\014le)d(are)h(\014v)o(e)f(\\library")f(de\014nitions)h
+Fl(fwliba)p Fn(:)c(:)g(:)m Fl(fwlibe)j Fr(whic)o(h)h(pro)o(vide)g(\014v)o(e)g
+(di\013eren)o(t)h(t)o(yp)q(esetting)g(strengths)177 1802 y(for)j(headings.)23
+b(Near)16 b(the)h(end)f(of)f(the)h(set)g(of)f(de\014nitions,)h(F)m(unnelW)m
+(eb)f(binds)g(these)i(macros)e(to)g(\014v)o(e)h(other)177 1851
+y(macros)i Fl(fwseca)p Fn(:)7 b(:)g(:)n Fl(fwsece)17 b Fr(whic)o(h)i(are)h
+(in)o(v)o(ok)o(ed)e(directly)i(in)e(the)i(generated)g(T)1511
+1860 y(E)1535 1851 y(X)f(co)q(de)h(to)f(t)o(yp)q(eset)h(the)177
+1901 y(headings.)177 2005 y Fl(\\def\\fwseca#1#2{\\f)o(wliba)o({#1}{)o(#2}})
+177 2055 y(\\def\\fwsecb#1#2{\\f)o(wlibb)o({#1}{)o(#2}})177
+2104 y(\\def\\fwsecc#1#2{\\f)o(wlibc)o({#1}{)o(#2}})177 2154
+y(\\def\\fwsecd#1#2{\\f)o(wlibd)o({#1}{)o(#2}})177 2204 y
+(\\def\\fwsece#1#2{\\f)o(wlibe)o({#1}{)o(#2}})177 2308 y Fr(This)10
+b(means)g(that)h(the)g(t)o(yp)q(esetting)g(strength)h(of)d(the)i(headings)g
+(in)f(a)g(F)m(unnelW)m(eb)g(do)q(cumen)o(t)g(can)g(b)q(e)h(c)o(hanged)177
+2357 y(b)o(y)j(rede\014ning)g(these)i(macros)d(at)g(the)i(top)f(of)f(a)h(F)m
+(unnelW)m(eb)f(do)q(cumen)o(t.)k(F)m(or)d(example:)177 2461
+y Fl(@p)22 b(typesetter)d(=)j(tex)177 2511 y(\\def\\fwseca#1#2{\\f)o(wlibc)o
+({#1}{)o(#2}})177 2614 y Fr(w)o(ould)10 b(set)h Fl(@A)f Fr(headings)g(at)h
+(the)f(same)g(strength)i(as)e(the)h(default)f(strength)i(of)d
+Fl(@C)h Fr(headings.)17 b(The)11 b Fl(typesetter)177 2664 y
+Fr(directiv)o(e)k(is)e(necessary)j(to)e(ensure)h(that)f(the)g(T)935
+2673 y(E)958 2664 y(X)g(con)o(trol)g(sequences)i(get)e(through)g(to)g(the)g
+(do)q(cumen)o(tation)177 2714 y(\014le)g(un\014ltered.)177
+2785 y(The)g(follo)o(wing)d(will)h(tone)i(do)o(wn)f(all)f(headings)h(b)o(y)g
+(t)o(w)o(o)g(lev)o(els)h(\(with)f(the)h Fl(@D)f Fr(and)g Fl(@E)g
+Fr(lev)o(els)h(b)q(eing)f(allo)q(cated)177 2835 y(the)i(default)e
+Fl(@E)h Fr(t)o(yp)q(esetting)g(strength)i(b)q(ecause)f(there)g(is)f(nothing)f
+(w)o(eak)o(er\).)1042 2940 y(46)p eop
+%%Page: 47 48
+47 47 bop 177 42 a Fl(@p)22 b(typesetter)d(=)j(tex)177 91 y
+(\\def\\fwseca#1#2{\\f)o(wlibc)o({#1}{)o(#2}})177 141 y
+(\\def\\fwsecb#1#2{\\f)o(wlibd)o({#1}{)o(#2}})177 191 y
+(\\def\\fwsecc#1#2{\\f)o(wlibe)o({#1}{)o(#2}})177 241 y
+(\\def\\fwsecd#1#2{\\f)o(wlibe)o({#1}{)o(#2}})177 291 y
+(\\def\\fwsece#1#2{\\f)o(wlibe)o({#1}{)o(#2}})177 408 y Fr(These)17
+b(de\014nitions)f(a\013ect)g(only)f(the)h(headings)f(that)h(follo)o(w)e
+(them,)g(and)i(so)f(they)h(should)g(b)q(e)g(placed)g(at)f(the)177
+458 y(top)f(of)f(the)i(F)m(unnelW)m(eb)e(input)h(\014le.)177
+622 y Fi(2.7)70 b(E\016ciency)21 b(Notes)177 739 y Fr(The)14
+b(follo)o(wing)e(notes)i(are)h(w)o(orth)f(k)o(eeping)f(in)h(mind)e(when)i
+(using)g(F)m(unnelW)m(eb.)295 814 y Fo(Memory:)j Fr(When)12
+b(F)m(unnelW)m(eb)f(pro)q(cesses)j(an)d(input)g(\014le,)g(it)g(reads)h(the)g
+(en)o(tire)g(input)f(\014le,)h(and)295 864 y(all)i(the)h(included)g(\014les)g
+(in)o(to)g(memory)m(.)920 849 y Fg(2)957 864 y Fr(This)g(organization)e(do)q
+(es)j(not)f(p)q(ose)g(a)g(constrain)o(t)g(on)295 914 y(mac)o(hines)e(with)h
+(large)f(memories,)e(but)j(could)g(presen)o(t)h(a)f(problem)e(on)i(the)g
+(smaller)f(mac)o(hines)295 964 y(suc)o(h)i(as)f(the)g(PC.)295
+1039 y Fo(Sp)q(eed:)j Fr(F)m(unnelW)m(eb)12 b(is)g(not)g(a)g(slo)o(w)g
+(program.)k(Ho)o(w)o(ev)o(er,)c(it)g(is)g(not)h(particularly)e(fast)h
+(either.)295 1089 y(If)17 b(the)g(sp)q(eed)h(at)f(whic)o(h)g(F)m(unnelW)m(eb)
+f(runs)h(is)g(imp)q(ortan)o(t)e(to)i(y)o(ou,)f(then)i(the)f(thing)f(to)h(k)o
+(eep)295 1138 y(in)e(mind)d(is)j(that)g(F)m(unnelW)m(eb)f(has)h(b)q(een)h
+(optimized)d(to)i(deal)f(e\016cien)o(tly)h(with)f(large)g(slabs)h(of)295
+1188 y(text.)23 b(F)m(unnelW)m(eb)15 b(treats)h(input)f(\014les)g(as)h(a)f
+(sequence)i(of)e(text)g(slabs)h(and)f(sp)q(ecial)g(sequences)295
+1238 y(\(e.g.)i Fl(@+)p Fr(\))h(and)f(whenev)o(er)i(it)e(hits)h(a)g(sp)q
+(ecial)g(sequence,)i(it)d(has)h(to)f(stop)h(and)g(think.)29
+b(Th)o(us,)295 1288 y(while)19 b(a)f(ten)h(megab)o(yte)f(text)i(slab)e(w)o
+(ould)g(b)q(e)h(manipulated)e(as)i(a)g(single)f(tok)o(en,)i(in)e(a)h(few)295
+1338 y(milliseconds,)11 b(a)i(similar)e(ten)j(megab)o(yte)e(c)o(h)o(unk)h
+(\014lled)g(with)f(sp)q(ecial)i(sequences)h(w)o(ould)e(tak)o(e)g(a)295
+1388 y(lot)j(longer.)25 b(If)16 b(F)m(unnelW)m(eb)f(is)h(running)g(slo)o(wly)
+m(,)f(lo)q(ok)g(to)h(see)i(if)d(the)i(input)f(con)o(tains)g(a)g(high)295
+1437 y(densit)o(y)e(of)f(sp)q(ecial)h(sequences.)21 b(This)13
+b(can)h(sometimes)e(happ)q(en)i(if)f(F)m(unnelW)m(eb)g(is)g(b)q(eing)h(used)
+295 1487 y(as)f(a)f(bac)o(k)o(end)h(macro)e(pro)q(cessor)j(and)f(its)f(input)
+g(is)h(b)q(eing)f(generated)i(automatically)9 b(b)o(y)k(some)295
+1537 y(other)i(program.)295 1612 y Fo(Macro)i(expansion:)h
+Fr(When)d(tangling)e(\(expanding)i(macros\),)e(F)m(unnelW)m(eb)h(nev)o(er)i
+(expands)295 1662 y(a)11 b(macro)f(expression)i(in)o(to)e(memory;)f(it)h(alw)
+o(a)o(ys)g(writes)i(it)f(to)f(the)i(pro)q(duct)g(\014le)f(as)g(it)f(go)q(es.)
+18 b(This)295 1712 y(is)10 b(a)h(p)q(o)o(w)o(erful)e(fact,)i(b)q(ecause)h(it)
+e(means)f(that)i(y)o(ou)f(can)g(write)h(macros)e(con)o(taining)h(an)g
+(unlimited)295 1762 y(amoun)o(t)h(of)h(text,)h(and)f(pass)h(suc)o(h)g(macros)
+f(as)h(parameters)f(to)h(other)g(macros)e(without)h(b)q(ecom-)295
+1812 y(ing)j(concerned)j(ab)q(out)e(o)o(v)o(er\015o)o(wing)f(some)g(kind)g
+(of)h(bu\013er)h(memory)m(.)k(In)16 b(short,)g(F)m(unnelW)m(eb)295
+1861 y(do)q(es)f(not)f(imp)q(ose)e(an)o(y)i(limits)d(on)j(the)h(size)f(of)f
+(macro)g(b)q(o)q(dies)h(or)g(their)h(expansions.)177 2025 y
+Fi(2.8)70 b(In)n(teractiv)n(e)21 b(Mo)r(de)177 2142 y Fr(As)15
+b(w)o(ell)e(as)i(ha)o(ving)e(a)h(command)d(line)j(in)o(terface)h(with)f(lots)
+g(of)g(options,)f(F)m(unnelW)m(eb)h(also)g(pro)o(vides)g(a)g(com-)177
+2192 y(mand)c(language)h(and)g(a)h(mo)q(de)e(\(\\in)o(teractiv)o(e)i(mo)q
+(de"\))e(in)i(whic)o(h)f(commands)e(in)i(the)i(language)d(can)i(b)q(e)g(t)o
+(yp)q(ed)177 2242 y(in)o(teractiv)o(ely)m(.)26 b(The)17 b(F)m(unnelW)m(eb)f
+(command)e(in)o(terpreter)19 b(w)o(as)d(created)i(primarily)d(to)h(supp)q
+(ort)i(regression)177 2292 y(testing,)c(but)g(can)g(also)f(b)q(e)i(useful)f
+(to)g(F)m(unnelW)m(eb)f(users.)177 2367 y(F)m(unnelW)m(eb's)d(command)d(in)o
+(terpreter)12 b(reads)f(one)f(command)d(p)q(er)k(line)f(and)g(can)g(read)g(a)
+g(stream)g(of)f(commands)177 2417 y(either)j(from)e(a)h(text)h(\014le,)f(or)h
+(from)d(the)j(console.)18 b(The)12 b(in)o(terpreter)h(can)e(understand)i(o)o
+(v)o(er)e(t)o(w)o(en)o(t)o(y)h(commands.)177 2466 y(See)17
+b(Chapter)f(3)f(for)g(a)g(full)f(list.)22 b(Ho)o(w)o(ev)o(er,)16
+b(most)e(of)h(them)g(w)o(ere)h(designed)g(to)f(supp)q(ort)i(regression)f
+(testing)177 2516 y(and)e(will)e(not)i(b)q(e)h(of)e(use)i(to)e(the)i(casual)f
+(user.)177 2592 y(The)g(commands)e(that)i(are)g(of)f(greatest)j(use)e(to)g
+(the)h(casual)e(user)i(are:)286 2709 y Fl(!)327 b(-)21 b(Comment.)g(Ignores)f
+(the)h(whole)g(line.)286 2759 y(EXECUTE)f(fn)131 b(-)21 b(Execute)g(the)g
+(specified)f(file.)p 177 2796 709 2 v 223 2823 a Ff(2)241 2835
+y Fh(If)11 b(a)g(\014le)g(is)h(included)d Fc(n)j Fh(times,)e(F)m(unnelW)m(eb)
+g(k)o(eeps)g Fc(n)i Fh(copies)e(in)h(memory)m(.)1042 2940 y
+Fr(47)p eop
+%%Page: 48 49
+48 48 bop 286 42 a Fl(FW)22 b(options)129 b(-)21 b(Invoke)g(FunnelWeb-proper)
+d(once.)286 91 y(SET)j(options)108 b(-)21 b(Sets)g(options.)286
+141 y(SHOW)261 b(-)21 b(Displays)g(currently)e(active)i(options.)286
+191 y(TRACE)g(ON)174 b(-)21 b(Turns)g(command)g(tracing)f(ON.)286
+241 y(QUIT)261 b(-)21 b(Quits)g(FunnelWeb.)177 373 y Fr(T)m(o)16
+b(distinguish)h(here)h(b)q(et)o(w)o(een)g(in)o(v)o(o)q(cations)e(of)g(the)i
+(F)m(unnelW)m(eb)e(program)f(and)i(F)m(unnelW)m(eb)f(runs)i(inside)177
+423 y(the)c(shell,)g(w)o(e)g(call)f(the)h(latter)g Fo(F)l(unnelW)l(eb)f(prop)
+q(er)p Fr(.)k(The)d(\\)p Fl(FW)p Fr(")e(command)f(in)o(v)o(ok)o(es)j(F)m
+(unnelW)m(eb)f(prop)q(er)177 473 y(with)h(the)g(sp)q(eci\014ed)h(options)f
+(whic)o(h)f(tak)o(e)h(the)h(same)d(syn)o(tax)i(as)g(they)g(do)g(on)f(the)i
+(command)c(line.)17 b(The)e(only)177 523 y(restriction)g(is)f(that)g(none)g
+(of)g(the)g(action)g(options)f(can)i(b)q(e)f(turned)h(on)f(except)h(\\)p
+Fl(+F)p Fr(")e(whic)o(h)h(m)o(ust)f(b)q(e)i(turned)177 572
+y(on.)177 654 y(The)e(\\)p Fl(SET)p Fr(")f(command)e(has)j(the)h(same)e(syn)o
+(tax)g(as)h(the)h(\\)p Fl(FW)p Fr(")e(command)e(except)k(that)f(it)g(do)q(es)
+g(not)g(allo)o(w)e Fm(any)177 703 y Fr(action)i(options)g(to)g(b)q(e)h(sp)q
+(eci\014ed.)19 b(It's)14 b(sole)f(e\013ect)i(is)e(to)g(set)i(default)d
+(option)h(v)n(alues)g(for)g(the)h(rest)g(of)f(the)h(run.)177
+785 y(The)g(\\)p Fl(SHOW)p Fr(")f(command)e(displa)o(ys)i(the)i(curren)o(t)g
+(default)f(options.)177 866 y(By)e(default,)g(F)m(unnelW)m(eb)f(do)q(es)i
+(not)f(ec)o(ho)h(the)f(commands)e(that)i(it)f(pro)q(cesses)k(in)d(a)f
+(script.)19 b(The)12 b(\\)p Fl(TRACE)20 b(ON)p Fr(")177 916
+y(command)11 b(turns)k(on)f(suc)o(h)g(tracing.)177 997 y(These)j(commands)12
+b(can)k(b)q(e)f(com)o(bined)f(to)h(streamline)f(the)i(use)g(of)f(F)m(unnelW)m
+(eb.)21 b(F)m(or)15 b(example,)e(y)o(ou)i(migh)o(t)177 1047
+y(wish)f(to)g(create)h(a)f(script)g(called)g Fl(typeset.fws)d
+Fr(to)j(pro)q(cess)i(a)d(whole)h(group)g(of)f(\014les.)177
+1179 y Fl(trace)21 b(on)177 1229 y(!This)g(script)f(typesets)h(the)g(whole)g
+(program.)177 1279 y(!)h(Set)f(no)g(listing)g(file,)f(no)i(product)e(files,)h
+(but)g(specify)f(a)i(documentation)d(file)177 1328 y(!)j(and)f(specify)f(the)
+h(directory)f(into)h(which)g(it)g(should)g(be)g(placed.)177
+1378 y(set)g(-L)h(-O)f(+T/usr/ross/typese)o(t/)177 1428 y(fw)h(prog1)177
+1478 y(fw)g(prog2)177 1528 y(fw)g(prog3)177 1578 y(fw)g(prog4)177
+1710 y Fr(There)12 b(are)e(a)g(few)h(w)o(a)o(ys)f(in)f(whic)o(h)i(this)f
+(script)h(can)g(b)q(e)f(run.)18 b(The)10 b(simplest)g(is)g(simply)e(to)i(sp)q
+(ecify)h(it)f(in)g(the)h(\\)p Fl(+X)p Fr(")177 1760 y(option)g(of)f(a)h(F)m
+(unnelW)m(eb)g(in)o(v)o(o)q(cation.)16 b(F)m(unnelW)m(eb)11
+b(shellscripts)h(default)f(to)g(\\)p Fl(<current)p 1621 1760
+14 2 v 14 w(directory>)p Fr(")e(and)177 1810 y(\\)p Fl(.fws)p
+Fr(".)177 1942 y Fl(fw)22 b(+xtypeset)177 2074 y Fr(The)14
+b(second)h(alternativ)o(e)f(is)g(to)g(en)o(ter)h(in)o(teractiv)o(e)f(mo)q
+(de.)177 2207 y Fl(fw)22 b(+k)177 2339 y Fr(F)m(rom)12 b(there,)j(y)o(ou)e
+(can)h(execute)i(the)f(script)f(using:)177 2472 y Fl(execute)21
+b(typeset)177 2604 y Fr(In)o(teractiv)o(e)13 b(mo)q(de)e(could)h(b)q(e)h(v)o
+(ery)f(useful)g(to)g(those)h(with)f(m)o(ultiple-windo)o(w)d(w)o(orkstations.)
+17 b(The)c(user)g(could)177 2654 y(create)f(a)f(windo)o(w)e(con)o(taining)h
+(an)g(in)o(teractiv)o(e)h(session)h(of)e(F)m(unnelW)m(eb,)g(and)g(then)i
+(switc)o(h)f(b)q(et)o(w)o(een)h(windo)o(ws,)177 2704 y(editing,)h(and)h
+(executing)g(F)m(unnelW)m(eb)g(prop)q(er)h(and)e(other)i(programs.)177
+2785 y(If)c(y)o(ou)f(\014nd)i(y)o(ourself)f(using)f(the)i(command)c(in)o
+(terpreter)13 b(a)e(lot,)g(b)q(e)g(sure)h(to)f(read)h(ab)q(out)f(the)g(other)
+h(commands)177 2835 y(that)i(are)g(a)o(v)n(ailable)e(in)h(Chapter)i(3.)1042
+2940 y(48)p eop
+%%Page: 49 50
+49 49 bop 177 42 a Fi(2.9)70 b(Setting)21 b(Up)i(Default)f(Options)177
+159 y Fr(If)14 b(y)o(ou)h(do)f(not)h(lik)o(e)f(F)m(unnelW)m(eb's)g(default)g
+(settings)i(for)e(its)h(command)d(line)i(options,)g(there)i(are)f(a)f(n)o(um)
+o(b)q(er)177 209 y(of)f(w)o(a)o(ys)h(in)f(whic)o(h)h(y)o(ou)g(can)g(c)o
+(hange)g(them.)295 284 y Fo(De\014ne)e(an)h(\\alias":)k Fr(Use)12
+b(y)o(our)g(op)q(erating)f(system)h(\\)p Fl(alias)p Fr(")e(facilit)o(y)g(to)i
+(create)h(an)e(alias)g(for)295 334 y(F)m(unnelW)m(eb)i(con)o(taining)f(the)h
+(desired)i(options.)i(F)m(unnelW)m(eb)12 b(pro)q(cesses)k(options)d(from)e
+(left)i(to)295 384 y(righ)o(t,)g(so)h(y)o(ou)g(can)g(o)o(v)o(erride)g(these)h
+(defaults)f(later)g(if)f(y)o(ou)h(wish.)295 460 y Fo(Create)k(a)f(script)f
+(called)g(\\)p Fl(fwinit.fws)p Fo(":)j Fr(When)d(F)m(unnelW)m(eb)f(starts)h
+(up,)f(it)g(executes)j(a)295 510 y(script)12 b(called)e(\\)p
+Fl(fwinit.fws)p Fr(")f(if)h(suc)o(h)h(a)g(script)g(exists)h(in)e(the)i
+(curren)o(t)g(directory)m(.)17 b(Y)m(ou)11 b(can)g(use)295
+560 y(this)j(fact)f(to)h(set)g(options)f(b)q(efore)i(the)f(run)g(of)f(F)m
+(unnelW)m(eb)g(prop)q(er)h(b)o(y)f(creating)h(suc)o(h)h(a)e(script)295
+609 y(and)i(placing)e(a)i(single)f(\\)p Fl(set)p Fr(")f(command)f(in)i(it)h
+(con)o(taining)e(the)i(desired)h(options.)k(The)15 b(main)295
+659 y(trouble)f(with)f(this)h(approac)o(h)f(is)g(that)h(the)g(options)f(in)g
+(the)h Fl(set)f Fr(command)d(will)i(b)q(e)i(pro)q(cessed)295
+709 y Fm(after)d Fr(the)h(command)d(line)i(options,)g(whic)o(h)h(means)e
+(that)i(y)o(ou)f(w)o(on't)g(b)q(e)h(able)f(to)h(o)o(v)o(erride)f(them)295
+759 y(on)j(the)g(command)e(line.)177 835 y(F)m(or)h(example,)f(y)o(ou)h(migh)
+o(t)f(b)q(e)i(in)o(v)o(olv)o(ed)e(more)h(with)g(presen)o(ting)h(programs)f
+(than)g(with)g(running)h(them,)e(and)177 884 y(w)o(an)o(t)f(F)m(unnelW)m(eb)g
+(to)h(generate)h(a)e(do)q(cumen)o(tation)f(\014le)i(b)o(y)f(default,)g(but)h
+(not)g(to)f(pro)q(duce)i(listing)d(or)i(pro)q(duct)177 934
+y(\014les)i(b)o(y)g(default.)k(In)c(Unix)f(y)o(ou)h(could)f(do)h(this)g
+(with:)177 1053 y Fl(alias)21 b(fw)g(fw)h(-L)f(-O)g(+T)177
+1219 y Fi(2.10)70 b(F)-6 b(unnelW)g(eb)23 b(and)g(Mak)n(e)177
+1336 y Fr(The)11 b(Unix)g Fl(Make)e Fr(program)g(allo)o(ws)h(a)g(set)i(of)e
+(dep)q(endencies)j(b)q(et)o(w)o(een)f(a)e(set)i(of)e(\014les)h(to)g(b)q(e)g
+(describ)q(ed,)i(and)d(then)177 1386 y(uses)16 b(these)f(dep)q(endencies)i
+(to)d(con)o(trol)g(the)h(w)o(a)o(y)f(in)g(whic)o(h)g(the)h(\014les)g(are)f
+(created)i(and)e(up)q(dated.)20 b(T)o(ypically)m(,)177 1436
+y Fl(Make)13 b Fr(is)g(used)i(to)e(con)o(trol)g(the)i(pro)q(cess)g(of)e
+(transforming)f(a)h(collection)g(of)g(source)i(co)q(de)f(\014les)g(to)f(one)h
+(or)g(more)177 1485 y(executable)j(\014les.)24 b(As)16 b(the)g(use)g(of)f(F)m
+(unnelW)m(eb)g(implies)f(an)h(extra)h(stage)h(to)e(this)h(pro)q(cess,)h(it)e
+(is)h(natural)f(to)177 1535 y(include)e(the)f(transformation)f(of)g
+Fl(.fw)h Fr(\014les)h(to)f(source)h(co)q(de)g(\014les)g(as)f(part)h(of)e(the)
+i Fl(Make)f Fr(pro)q(cess.)19 b(This)12 b(is)g(easy)177 1585
+y(to)i(do,)f(but)h(the)h(user)g(should)e(b)q(e)i(a)o(w)o(are)f(of)f(one)h
+(asp)q(ect)h(of)e(F)m(unnelW)m(eb)h(whic)o(h)g(can)g(cause)h(problems.)177
+1661 y(It)d(is)g(often)h(useful,)f(when)g(using)g(F)m(unnelW)m(eb,)g(to)g
+(create)h(a)f(F)m(unnelW)m(eb)g Fl(.fw)f Fr(\014le)i(that)f(generates)i(more)
+d(than)177 1711 y(one)j(pro)q(duct)g(\014le.)k(That)13 b(is,)g(a)g(single)g
+Fl(.fw)g Fr(\014le)h(ma)o(y)d(ha)o(v)o(e)i(man)o(y)f(macro)g(de\014nitions)h
+(connected)j(to)d(pro)q(duct)177 1760 y(\014les)g(so)g(that)f(when)h(the)g(F)
+m(unnelW)m(eb)f Fl(.fw)g Fr(\014le)g(is)h(pro)q(cessed)h(b)o(y)f(F)m(unnelW)m
+(eb,)e(sev)o(eral)i(\014les)g(are)g(created.)19 b(F)m(or)177
+1810 y(example,)d(this)g(facilit)o(y)f(has)i(b)q(een)g(used)h(to)e(great)h
+(e\013ect)h(to)f(place)f(the)h(description)h(of)e(an)g(Ada)g(pac)o(k)n(age's)
+177 1860 y(pac)o(k)n(age)e(sp)q(eci\014cation)g(\014le)g(and)g(pac)o(k)n(age)
+f(b)q(o)q(dy)h(\014le)g(in)g(the)g(same)f(F)m(unnelW)m(eb)g
+Fl(.fw)h Fr(\014le.)177 1936 y(The)j(use)h(of)e(m)o(ultiple)e(pro)q(duct)k
+(\014les,)f(ho)o(w)o(ev)o(er,)h(pro)o(v)o(ok)o(es)e(a)h(problem)e(with)h(dep)
+q(endencies.)29 b(Supp)q(ose)18 b(for)177 1986 y(example)9
+b(that)h(a)g(F)m(unnelW)m(eb)g Fl(prog.fw)e Fr(pro)q(duces)k(t)o(w)o(o)d(pro)
+q(duct)j(\014les)e Fl(proc.spec)e Fr(\(a)i(pac)o(k)n(age)g(sp)q
+(eci\014cation\))177 2035 y(and)16 b Fl(prog.body)f Fr(\(a)h(pac)o(k)n(age)f
+(b)q(o)q(dy\).)26 b(If)16 b(the)g(pac)o(k)n(age)g(is)g(accessed)j(in)d(the)g
+(w)o(a)o(y)g(that)g(pac)o(k)n(ages)g(normally)177 2085 y(are,)j(it)e(will)f
+(b)q(e)i(quite)f(common)e(for)i(the)h(programmer)d(to)j(w)o(an)o(t)f(to)g(mo)
+q(dify)e(the)j(pac)o(k)n(age)g(b)q(o)q(dy)f(without)177 2135
+y(mo)q(difying)12 b(the)j(program)e(sp)q(eci\014cation.)20
+b(So)14 b(the)i(programmer)c(will)h(edit)h(the)i Fl(prog.fw)d
+Fr(\014le)h(to)g(c)o(hange)h(the)177 2185 y(pac)o(k)n(age)c(b)q(o)q(dy)m(.)17
+b(The)12 b(result)g(of)e(running)h(this)h(through)f(F)m(unnelW)m(eb)g(will)f
+(b)q(e)i(the)g(desired)g(new)g(pac)o(k)n(age)f(b)q(o)q(dy)177
+2235 y(\014le.)23 b(Ho)o(w)o(ev)o(er,)16 b(F)m(unnelW)m(eb)f(will)f(also)h
+(pro)q(duce)i(a)e(new)h(pac)o(k)n(age)f(sp)q(eci\014cation)h(pro)q(duct)h
+(\014le)e Fm(even)i(though)177 2285 y(it)d(may)h(b)n(e)f(identic)n(al)g(to)g
+(the)h(pr)n(evious)f(version!)k Fr(The)c(result)g(is)f(that)g(the)h(newly)f
+(created)i(\(with)e(a)g(recen)o(t)i(\014le)177 2334 y(date\))h(sp)q
+(eci\014cation)h(pac)o(k)n(age)e(\014le)g(could)h(pro)o(v)o(ok)o(e)f(a)g(h)o
+(uge)h(remak)o(e)f(of)g(m)o(uc)o(h)f(of)h(the)i(program)d(in)h(whic)o(h)g(it)
+177 2384 y(resides.)177 2460 y(T)m(o)j(solv)o(e)h(the)g(problem,)f(F)m
+(unnelW)m(eb)h(includes)g(a)g(command)d(line)i(option)g(\()p
+Fl(D)h Fr(for)f(Delete\),)j(whic)o(h)d(when)177 2510 y(turned)f(on)f(\(using)
+g(\\)p Fl(+D)p Fr("\))g(causes)h(F)m(unnelW)m(eb)f(to)g(suppress)i(pro)q
+(duct)f(and)f(do)q(cumen)o(tation)f(\014les)h(that)g(are)177
+2560 y(iden)o(tical)c(to)h(the)g(previously)f(existing)h(v)o(ersions)g(of)f
+(the)h(same)f(\014les.)18 b(F)m(or)12 b(example,)f(if,)h(during)g(a)g(F)m
+(unnelW)m(eb)177 2609 y(run,)h(a)g(macro)e(w)o(as)i(connected)i(to)e(a)f(pro)
+q(duct)i(\014le)f(called)f Fl(x.dat)p Fr(,)g(and)h(the)g(macro)f(expanded)h
+(to)g Fm(exactly)g Fr(the)177 2659 y(same)g(text)h(as)f(is)h(con)o(tained)f
+(in)g Fl(x.dat)f Fr(then)i(F)m(unnelW)m(eb)f(w)o(ould)g(simply)e
+Fm(never)k(write)e(the)i(pr)n(o)n(duct)f(\014le)p Fr(,)f(the)177
+2709 y(\014le)h Fl(x.dat)f Fr(w)o(ould)g(b)q(e)h(un)o(touc)o(hed)h(and,)e(as)
+h(a)g(result,)g(no)g(further)g Fl(Make)f Fr(propagations)h(w)o(ould)f(tak)o
+(e)h(place.)177 2785 y(F)m(unnelW)m(eb)e(implemen)o(ts)f(this)i(feature)g(b)o
+(y)g(writing)f(eac)o(h)h(pro)q(duct)h(\014le)f(to)f(a)h(temp)q(orary)f
+(\014le)h(with)f(a)h(temp)q(o-)177 2835 y(rary)j(\014le)f(name.)21
+b(It)15 b(then)h(compares)f(the)h(temp)q(orary)e(\014le)h(with)g(the)h
+(target)g(\014le.)22 b(If)15 b(the)h(t)o(w)o(o)e(are)i(iden)o(tical,)1042
+2940 y(49)p eop
+%%Page: 50 51
+50 50 bop 177 42 a Fr(it)18 b(deletes)h(the)f(temp)q(orary)f(\014le.)30
+b(If)17 b(the)h(t)o(w)o(o)f(are)i(di\013eren)o(t)f(it)g(deletes)h(the)f
+(target)g(\014le)g(and)g(renames)f(the)177 91 y(temp)q(orary)c(\014le)h(to)g
+(the)g(target)h(\014le.)177 165 y(Use)c(of)f(the)h Fl(D)f Fr(facilit)o(y)e
+(means)i(that)g(the)h(programmer)d(need)j(not)f(b)q(e)h(punished)g(\(b)o(y)f
+(extra)h Fl(Make)e Fr(propagations\))177 215 y(for)14 b(describing)g(more)f
+(than)h(one)g(pro)q(duct)h(\014le)f(in)f(the)i(same)e(F)m(unnelW)m(eb)g
+(\014le.)177 376 y Fi(2.11)70 b(The)23 b(Dangers)g(of)g(F)-6
+b(unnelW)g(eb)177 492 y Fr(Lik)o(e)15 b(man)o(y)e(to)q(ols)i(that)g(are)h
+(general)f(and)g(\015exible,)g(F)m(unnelW)m(eb)g(can)g(b)q(e)h(used)g(in)f(a)
+g(v)n(ariet)o(y)f(of)h(w)o(a)o(ys,)g(b)q(oth)177 541 y(go)q(o)q(d)h(and)h
+(bad.)26 b(One)18 b(of)e(the)h(original)e(app)q(eals)i(of)f(the)h(literate)g
+(approac)o(h)g(to)f(programming)d(for)k(Kn)o(uth,)177 591 y(the)h(in)o(v)o
+(en)o(tor)f(of)f(literate)i(programmi)o(ng,)d(w)o(as)i(that)g(it)g(allo)o(ws)
+f(the)i(programmer)d(to)i(describ)q(e)i(the)e(target)177 641
+y(program)12 b(b)q(ottom)g(up,)h(top)g(do)o(wn,)g(size)h(to)f(side,)g(or)h(c)
+o(haotically)e(if)g(desired.)19 b(The)14 b(\015exibilit)o(y)e(that)h(this)h
+(st)o(yle)177 691 y(of)h(programmi)o(ng)d(lea)o(v)o(es)j(m)o(uc)o(h)f(ro)q
+(om)f(for)i(bad)g(do)q(cumen)o(tation)e(as)i(w)o(ell)g(as)g(go)q(o)q(d)f(do)q
+(cumen)o(tation.)20 b(Y)m(ears)177 741 y(of)c(exp)q(erience)j(with)e(F)m
+(unnelW)m(eb)f(has)h(rev)o(ealed)g(the)h(follo)o(wing)c(st)o(ylistic)i
+(pitfalls)g(whic)o(h)g(the)i(exp)q(erienced)177 791 y(F)m(unnelW)m(eb)c(user)
+h(should)e(tak)o(e)h(care)h(to)f(a)o(v)o(oid.)952 775 y Fg(3)295
+865 y Fo(Spaghetti)h(organization:)j Fr(By)e(far)f(the)h(w)o(orst)g(problem)e
+(that)h(arises)h(in)f(connection)h(with)295 914 y(the)k(literate)e(st)o(yle)h
+(o)q(ccurs)h(where)g(the)g(programmer)c(has)j(used)g(the)h(literate)f(to)q
+(ol)f(to)g(com-)295 964 y(pletely)f(scram)o(ble)e(the)i(program)d(so)j(that)f
+(the)h(program)d(is)i(describ)q(ed)i(and)e(la)o(y)o(ed)g(out)g(in)g(an)295
+1014 y(unordered,)j(undisciplined)e(\\stream)f(of)g(consciousness".)29
+b(In)17 b(suc)o(h)h(cases)g(the)g(programmer)295 1064 y(ma)o(y)11
+b(b)q(e)i(using)g(the)g(literate)g(st)o(yle)f(as)h(a)f(crutc)o(h)i(to)f(a)o
+(v)o(oid)e(ha)o(ving)g(to)i(think)f(ab)q(out)h(structuring)295
+1114 y(the)i(presen)o(tation.)295 1188 y Fo(Boring)h(organization:)i
+Fr(A)o(t)d(the)h(other)g(extreme,)f(a)g(program)f(ma)o(y)f(b)q(e)j(organized)
+f(in)g(suc)o(h)295 1238 y(a)h(strict)g(w)o(a)o(y)g(that)f(it)h(is)g(essen)o
+(tially)f(laid)g(out)h(in)f(the)i(order)f(most)f(\\desired")h(b)o(y)g(the)g
+(target)295 1287 y(programming)c(language.)21 b(F)m(or)15 b(example,)f(eac)o
+(h)i(macro)e(migh)o(t)f(con)o(tain)i(a)g(single)g(pro)q(cedure,)295
+1337 y(with)g(all)e(the)i(macros)f(b)q(eing)h(called)f(b)o(y)h(a)f(macro)g
+(connected)i(to)f(a)f(\014le)h(at)f(the)i(top.)k(In)15 b(man)o(y)295
+1387 y(cases)20 b(a)f(b)q(oring)f(structure)j(ma)o(y)c(b)q(e)i(en)o(tirely)g
+(appropriate,)h(but)f(the)g(programmer)e(should)295 1437 y(b)q(e)h(w)o(arned)
+f(that)f(it)h(is)f(easy)h(to)g(slip)f(in)o(to)g(suc)o(h)i(a)e(normativ)o(e)f
+(st)o(yle,)i(largely)f(forgetting)g(the)295 1487 y(descriptiv)o(e)f
+(structural)g(p)q(o)o(w)o(er)f(that)g(F)m(unnelW)m(eb)g(pro)o(vides.)295
+1561 y Fo(P)o(o)q(or)h(random)f(access:)k Fr(Using)c(F)m(unnelW)m(eb,)e(it)h
+(is)h(quite)f(p)q(ossible)h(to)f(write)h(programs)e(lik)o(e)295
+1611 y(no)o(v)o(els)j(|)f(to)g(b)q(e)h(read)g(from)e(co)o(v)o(er)i(to)f(co)o
+(v)o(er.)21 b(Sometimes)13 b(the)i(story)g(is)f(v)o(ery)h(exciting,)f(with)
+295 1660 y(data)i(structures)j(making)13 b(dashing)j(triumphs)f(and)h
+(optimized)f(co)q(de)i(bringing)e(the)h(story)h(to)295 1710
+y(a)d(satisfying)e(conclusion.)18 b(These)d(programs)e(can)g(b)q(e)i(w)o
+(orks)e(of)g(art.)18 b(Unfortunately)m(,)13 b(without)295 1760
+y(careful)e(construction,)h(suc)o(h)f(\\no)o(v)o(el-programs")d(can)j(b)q
+(ecome)f(v)o(ery)h(hard)g(to)f(access)j(randomly)295 1810 y(b)o(y)18
+b(\(sa)o(y\))h(a)f(main)o(tenance)f(programmer)g(who)h(wishes)h(only)e(to)i
+(div)o(e)f(in)g(and)g(\014x)g(a)g(sp)q(eci\014c)295 1860 y(problem.)f(If)d
+(the)g(en)o(tire)h(program)d(is)i(scram)o(bled)f(for)g(sequen)o(tial)h(exp)q
+(osition,)f(it)h(can)g(b)q(e)h(hard)295 1909 y(to)f(\014nd)h(the)f(parts)h
+(relating)f(to)g(a)g(single)g(function.)k(Someho)o(w)13 b(a)h(balance)g(m)o
+(ust)f(b)q(e)i(struc)o(k)g(in)295 1959 y(the)h(do)q(cumen)o(t)f(b)q(et)o(w)o
+(een)h(the)g(needs)h(of)d(the)i(sequen)o(tial)f(and)g(of)g(the)h
+(random-access)f(reader.)295 2009 y(This)f(balance)g(will)e(dep)q(end)k(on)d
+(the)i(in)o(tended)f(use)h(of)e(the)i(program.)295 2083 y Fo(T)l(o)q(o-in)o
+(terdep)q(end)o(en)n(t)g(do)q(cumen)o(tati)o(on:)k Fr(Sometimes,)13
+b(when)j(editing)f(a)g(program)f(writ-)295 2133 y(ten)j(using)g(F)m(unnelW)m
+(eb,)f(one)h(kno)o(ws)f(ho)o(w)g(to)g(mo)q(dify)f(the)i(program,)e(but)h(one)
+h(is)g(unsure)g(of)295 2183 y(ho)o(w)f(to)h(up)q(date)g(the)g(surrounding)f
+(do)q(cumen)o(tation!)25 b(The)16 b(do)q(cumen)o(tation)g(ma)o(y)e(b)q(e)j(w)
+o(o)o(v)o(en)295 2233 y(in)o(to)e(suc)o(h)g(a)g(net)o(w)o(ork)h(of)e(facts)h
+(that)h(it)e(seems)i(that)f(c)o(hanging)f(a)h(small)e(piece)i(of)g(co)q(de)h
+(could)295 2282 y(in)o(v)n(alidate)g(man)o(y)f(pieces)k(of)d(do)q(cumen)o
+(tation)g(scattered)k(throughout)d(the)h(do)q(cumen)o(t.)27
+b(The)295 2332 y(do)q(cumen)o(tation)12 b(b)q(ecomes)h(a)g(big)g(tar)g(pit)g
+(in)f(whic)o(h)h(mo)o(v)o(emen)o(t)e(is)i(imp)q(ossible.)j(F)m(or)c(example,)
+295 2382 y(if)18 b(y)o(ou)g(ha)o(v)o(e)g(talk)o(ed)g(ab)q(out)h(a)f
+(particular)g(data)g(structure)j(in)o(v)n(arian)o(t)c(throughout)h(a)g(do)q
+(cu-)295 2432 y(men)o(t,)f(c)o(hanging)f(that)h(in)o(v)n(arian)o(t)e(in)i(a)f
+(small)f(w)o(a)o(y)h(could)h(mean)f(ha)o(ving)g(to)h(up)q(date)g(all)f(the)
+295 2482 y(do)q(cumen)o(tation)i(without)g(touc)o(hing)h(m)o(uc)o(h)f(co)q
+(de.)33 b(In)19 b(suc)o(h)h(cases,)h(the)e(do)q(cumen)o(tation)f(is)295
+2531 y(to)q(o)c(in)o(terdep)q(enden)o(t.)21 b(This)14 b(could)g(b)q(e)h
+(symptomatic)c(of)j(an)f(excessibly)j(in)o(terconnected)g(pro-)295
+2581 y(gram,)g(or)g(of)g(an)h(excessiv)o(ely)h(v)o(erb)q(ose)g(or)e(redundan)
+o(t)i(do)q(cumen)o(ting)d(st)o(yle.)27 b(In)17 b(an)o(y)f(case,)i(a)295
+2631 y(balance)13 b(m)o(ust)f(b)q(e)h(struc)o(k)h(b)q(et)o(w)o(een)h(the)e
+(con)o(v)o(ersational)f(st)o(yle)h(that)g(encourages)i(redundancy)295
+2681 y(\(b)o(y)c(men)o(tioning)d(things)j(man)o(y)e(times\))h(and)g(the)i
+(normalized)d(database)i(approac)o(h)f(where)i(eac)o(h)p 177
+2717 709 2 v 223 2744 a Ff(3)241 2756 y Fh(The)f(fact)g(that)g(these)g
+(faults)f(are)h(listed)g(here)g(do)q(es)f(not)h(mean)g(that)g(the)g(author)f
+(has)h(eliminated)d(them)j(in)g(his)h(o)o(wn)f(w)o(ork.)177
+2795 y(Rather,)d(it)g(is)g(mainly)f(the)h(author's)e(o)o(wn)i(mistak)o(es)f
+(that)g(ha)o(v)o(e)h(resulted)e(in)i(this)g(list)g(b)q(eing)f(compiled.)12
+b(The)c(author)f(immediate)o(ly)177 2835 y(confesses)j(to)h(sev)o(eral)f(of)h
+(the)g(faults)f(listed)g(here,)h(most)f(notably)f(that)i(of)g(P)o(a)o(vlo)o
+(v)f(do)q(cumen)o(tat)o(ion)o(.)1042 2940 y Fr(50)p eop
+%%Page: 51 52
+51 51 bop 295 42 a Fr(fact)17 b(is)f(giv)o(en)g(at)g(only)g(one)g(p)q(oin)o
+(t,)g(and)h(the)g(reader)g(is)g(left)f(to)g(\014gure)h(out)f(the)h
+(implications)295 91 y(throughout)d(the)h(do)q(cumen)o(t.)295
+164 y Fo(P)o(a)o(vlo)o(v)d(do)q(cumen)o(tation:)i Fr(By)f(placing)e(so)h(m)o
+(uc)o(h)f(emphasis)g(on)h(the)g(do)q(cumen)o(tation,)f(F)m(un-)295
+214 y(nelW)m(eb)16 b(naturally)g(pro)o(vides)h(slots)f(where)i(do)q(cumen)o
+(tation)d(\\should")h(go.)25 b(F)m(or)17 b(example,)e(a)295
+264 y(F)m(unnelW)m(eb)h(user)i(ma)o(y)d(feel)h(that)h(there)h(ma)o(y)c(b)q(e)
+j(a)g(rather)g(unpleasan)o(t)g(gap)f(b)q(et)o(w)o(een)i(a)e
+Fl(@C)295 314 y Fr(mark)o(er)g(and)h(the)g(follo)o(wing)d(macro.)25
+b(In)17 b(man)o(y)e(cases)j Fm(no)f Fr(commen)o(tary)e(is)h(needed)i(and)f
+(the)295 363 y(zone)c(is)f(b)q(etter)i(left)e(blank)g(rather)h(than)g(b)q
+(eing)f(\014lled)g(with)g(the)h(kind)e(of)h(uninformativ)o(e)e(w)o(a\017e)295
+413 y(one)17 b(often)h(\014nds)f(\014lling)e(the)j(slots)f(of)g(structured)i
+(do)q(cumen)o(tation)d(written)h(according)g(to)g(a)295 463
+y(military)10 b(standards)k(\(e.g.)e(MIL-STD-2167A\).)1067
+448 y Fg(4)1097 463 y Fr(The)h(lesson)h(is)e(to)h(add)g(do)q(cumen)o(tation)e
+(only)295 513 y(when)h(it)e(adds)i(something.)j(The)d(lesson)f(in)g(Strunk)g
+(and)g(White)p Fo([Strunk79])e Fr(\(p.)i(23\))f(holds)h(for)295
+563 y(program)i(do)q(cumen)o(tation)f(as)i(it)g(do)q(es)g(for)g(other)g
+(writing:)k(\\Vigorous)13 b(writing)g(is)h(concise.)19 b(A)295
+613 y(sen)o(tence)14 b(should)d(con)o(tain)g(no)f(unnecessary)k(w)o(ords,)d
+(a)g(paragraph)g(no)g(unnecessary)j(sen)o(tences,)295 662 y(for)h(the)g(same)
+f(reason)h(that)f(a)h(dra)o(wing)f(should)g(ha)o(v)o(e)g(no)h(unnecessary)i
+(lines)d(and)h(a)f(mac)o(hine)295 712 y(no)g(unnecessary)i(parts.)j(This)13
+b(requires)j(not)d(that)h(the)h(writer)f(mak)o(e)f(all)f(his)i(sen)o(tences)j
+(short,)295 762 y(or)d(that)f(he)h(a)o(v)o(oid)f(all)f(detail)h(and)g(treat)i
+(his)e(sub)r(jects)j(only)c(in)h(outline,)g(but)h(that)f(ev)o(ery)i(w)o(ord)
+295 812 y(tell.".)295 885 y Fo(Duplicate)10 b(do)q(cumen)o(tation)o(:)15
+b Fr(Where)d(the)g(programmer)d(is)i(generating)g(pro)q(duct)h(\014les)g
+(that)295 935 y(m)o(ust)17 b(exist)g(on)g(their)h(o)o(wn)f(within)f(the)i(en)
+o(tire)g(programming)c(en)o(vironmen)o(t)i(\(e.g.)h(the)h(case)295
+984 y(of)f(a)h(programmer)d(in)j(a)f(team)g(who)h(is)f(using)h(F)m(unnelW)m
+(eb)f(for)g(his)h(o)o(wn)g(b)q(ene\014t)h(but)f(m)o(ust)295
+1034 y(generate)c(\(sa)o(y\))f(commen)o(ted)e(Ada)i(sp)q(eci\014cation)g(pac)
+o(k)n(age)f(\014les\))i(there)g(is)e(a)h(tendency)h(for)e(the)295
+1084 y(commen)o(ts)k(in)h(the)h(target)f(co)q(de)h(to)g(duplicate)f(the)h
+(commen)o(tary)d(in)i(the)h(F)m(unnelW)m(eb)f(text.)295 1134
+y(This)11 b(ma)o(y)e(or)i(ma)o(y)e(not)i(b)q(e)h(a)f(problem,)f(dep)q(ending)
+h(on)g(the)h(exact)f(situation.)17 b(Ho)o(w)o(ev)o(er,)11 b(if)g(this)295
+1184 y(is)g(happ)q(ening,)g(it)g(is)f(certainly)h(w)o(orth)g(the)h
+(programmer)c(sp)q(ending)k(some)e(time)g(deciding)g(if)g(one)295
+1233 y(or)j(other)g(of)f(the)h(F)m(unnelW)m(eb)f(or)h(inline-comm)o(en)o(t)d
+(do)q(cumen)o(tation)i(should)g(b)q(e)h(discarded.)19 b(In)295
+1283 y(man)o(y)11 b(cases,)j(a)e(mixture)g(can)g(b)q(e)i(used,)f(with)f(the)h
+(F)m(unnelW)m(eb)f(do)q(cumen)o(tation)g(referring)h(the)295
+1333 y(reader)i(to)f(the)h(inline)e(commen)o(ts)f(where)j(they)f(are)g
+(presen)o(t.)20 b(F)m(or)14 b(example:)177 1443 y Fl(@A)22
+b(Here)f(is)g(the)g(header)g(comment)f(for)h(the)g(list)g(package)g
+(specification.)177 1493 y(The)g(reader)g(should)f(read)h(these)g(comments)f
+(carefully)g(as)i(they)f(define)f(a)i(list.)177 1542 y(There)f(is)g(no)h
+(need)f(to)g(duplicate)f(the)h(comments)f(in)i(this)f(text.)177
+1642 y(@$@<Specification)d(package)j(header)f(comments@>==@{@-)177
+1692 y(--)i(LIST)f(PACKAGE)177 1742 y(--)h(============)177
+1792 y(--)g(*)f(A)h(LIST)f(consists)f(of)h(zero)g(or)h(more)f(ITEMS.)177
+1841 y(--)h(*)f(The)g(items)g(are)g(numbered)f(1)i(to)f(N)h(where)f(N)g(is)h
+(the)f(number)f(of)i(items)f(in)g(the)g(list.)177 1891 y(--)h(*)f(If)h(the)f
+(list)g(is)g(non-empty,)f(item)h(1)g(is)h(called)e(the)h(HEAD)g(of)h(the)f
+(list.)177 1941 y(--)h(*)f(If)h(the)f(list)g(is)g(non-empty,)f(item)h(N)g(is)
+h(called)e(the)h(TAIL)g(of)h(the)f(list.)177 1991 y(--)h(...)177
+2041 y(@})295 2150 y Fo(Ov)o(erdo)q(cumen)o(tin)o(g:)c Fr(Another)e(evil)f
+(that)g(can)g(arise)h(when)f(using)g(F)m(unnelW)m(eb)g(is)g(to)g(o)o(v)o(er-)
+295 2200 y(do)q(cumen)o(t)j(the)h(target)g(program.)29 b(In)19
+b(some)e(of)h(Kn)o(uth's)g(earlier)h(\(e.g.)e(1984\))h(examples)f(of)295
+2250 y(literate)11 b(programming,)d(eac)o(h)j(v)n(ariable)f(is)h(giv)o(en)f
+(its)h(o)o(wn)f(description)i(and)e(eac)o(h)i(piece)g(of)e(co)q(de)295
+2300 y(has)16 b(a)f(detailed)g(explanation.)22 b(This)16 b(lev)o(el)f(of)g
+(analysis,)f(while)h(justi\014ed)h(for)f(tric)o(ky)h(tracts)g(of)295
+2350 y(co)q(de,)d(is)f(probably)g(not)g(w)o(arran)o(ted)h(for)f(most)f(of)h
+(the)h(co)q(de)g(that)f(constitutes)i(most)d(programs.)295
+2400 y(Suc)o(h)18 b(o)o(v)o(er-commen)o(ting)d(can)j(ev)o(en)g(ha)o(v)o(e)f
+(the)h(detrimen)o(tal)f(a\013ect)h(of)f(obscuring)h(the)g(co)q(de,)295
+2449 y(making)11 b(it)h(hard)h(to)g(understand)h(b)q(ecause)h(it)d(is)h(so)g
+(scattered)i(\(see)f(\\spaghetti)f(organization")295 2499 y(earlier\).)18
+b(It)12 b(is)g(up)g(to)g(the)h(user)g(to)f(decide)h(when)f(a)g(stretc)o(h)i
+(of)d(just)i(a)e(few)i(lines)f(of)f(co)q(de)i(should)295 2549
+y(b)q(e)i(pulled)e(to)h(bits)g(and)g(analysed)f(and)h(when)h(it)e(is)h
+(clearer)h(to)f(lea)o(v)o(e)f(it)h(alone.)295 2622 y(In)i(the)g(case)g(where)
+h(there)g(are)e(a)h(few)f(rather)h(tric)o(ky)g(lines)f(of)g(co)q(de,)h(a)f
+(detailed)h(explanation)295 2672 y(ma)o(y)10 b(b)q(e)j(appropriate.)k(The)12
+b(follo)o(wing)e(example)g(con)o(tains)i(a)f(solution)g(to)h(a)g(problem)e
+(outlined)295 2722 y(in)k(section)g(16.3)f(of)g(the)h(b)q(o)q(ok)g(\\The)g
+(Science)h(of)e(Programming")d(b)o(y)k(Da)o(vid)e(Gries)p Fo([Gries81])295
+2771 y Fr(.)p 177 2796 709 2 v 223 2823 a Ff(4)241 2835 y Fh(Note:)j(This)c
+(is)h(not)e(a)i(criticism)d(of)i(2167A,)g(only)f(of)i(the)e(w)o(a)o(y)i(it)f
+(is)h(sometimes)d(used.)1042 2940 y Fr(51)p eop
+%%Page: 52 53
+52 52 bop 177 42 a Fl(@C@<Calculation)19 b(of)i(the)g(longest)g(plateau)f(in)
+h(array)g(b@>)177 141 y(This)g(section)f(contains)h(a)g(solution)f(to)i(a)f
+(problem)g(outlined)f(in)h(section)g(16.3)f(of)177 191 y(the)h(book)g(@/The)g
+(Science)f(of)i(Programming@/)d(by)i(David)g(Gries[Gries81].)177
+291 y(@D)h(Given)e(a)i(sorted)e(array)h(@{b[1..N]@})f(of)h(integers,)f(we)h
+(wish)g(to)h(determine)e(the)177 340 y(@/length@/)g(of)h(the)g(longest)g(run)
+g(of)g(identically)f(valued)g(elements)h(in)g(the)g(array.)177
+390 y(This)g(problem)f(is)i(defined)e(by)i(the)f(following)f(precondition)f
+(and)i(postcondition.)177 490 y(@$@<Precondition@>)o(==@{/)o(*)e(Pre:)i
+(sorted\(b\).)f(*/@})177 540 y(@$@<Postcondition@)o(>==@{)o(@-)177
+589 y(/*)i(Post:)e(sorted\(b\))g(and)h(p)h(is)f(the)h(length)e(of)h(the)h
+(longest)e(run)h(in)h(b[1..N].)e(*/@})177 689 y(@D)i(We)f(approach)f(a)i
+(solution)e(to)h(the)g(problem)g(by)g(deciding)f(to)i(try)f(the)g(approach)f
+(of)177 739 y(scanning)g(through)h(the)g(array)g(one)g(element)f(at)h(a)h
+(time)f(maintaining)f(a)h(useful)177 789 y(invariant)f(through)g(each)h
+(iteration.)f(A)i(loop)f(variable)177 839 y(array)g(index)g(@{i@})f(is)i
+(created)e(for)h(this)g(purpose.)f(The)i(bound)e(function)h(is)177
+888 y(@{N-i@}.)f(Here)h(is)h(the)f(invariant.)177 988 y(@$@<Invariant@>==@)o
+({@-)177 1038 y(/*)h(Invariant:)d(sorted\(b\))h(and)h(1<=i<=N)g(and)239
+b(*/)177 1088 y(/*)261 b(p)22 b(is)f(len)g(of)h(longest)e(run)h(in)h
+(b[1..i].)e(*/@})177 1187 y(@D)i(Establishing)d(the)i(invariant)f(above)h(in)
+g(the)g(initial,)f(degenerate)g(case)h(is)g(easy.)177 1287
+y(@$@<Establish)e(the)i(plateau)g(loop)g(invariant)f(initially@>==@{i)o(=1;)f
+(p=1;@})177 1386 y(@D)j(At)f(this)g(stage,)f(we)i(have)f(the)g(following)f
+(loop)h(structure.)f(Note)h(that)g(when)f(both)177 1436 y(the)h(invariant)f
+(and)h(@{i)h(!=)f(N@})g(are)g(true,)g(the)g(postcondition)e(holds)i(and)g
+(the)g(loop)177 1486 y(can)g(terminate.)177 1586 y(@$@<Set)g(p)g(to)g(the)h
+(length)e(of)i(the)f(longest)f(plateau)g(in)i(sorted)e(array)h
+(b[1..N]@>==@{@-)177 1636 y(@<Precondition@>)177 1685 y(@<Establish)f(the)h
+(plateau)f(loop)h(invariant)f(initially@>)177 1735 y(while)h(\(i)g(!=)h(N\))
+221 1785 y({)243 1835 y(@<Invariant@>)243 1885 y(@<Loop)e(body@>)221
+1934 y(})177 1984 y(@<Postcondition@>)177 2034 y(@})177 2134
+y(@D)i(Now)f(there)f(remains)h(only)g(the)g(loop)g(body)g(whose)g(sole)g
+(task)g(is)g(to)g(increase)f(@{i@})177 2183 y(\(and)h(so)h(decrease)e(the)h
+(value)g(of)g(the)g(bound)g(function\))f(while)h(maintaining)e(the)177
+2233 y(invariant.)h(If)h(@{p@})g(is)g(the)h(length)e(of)i(the)f(longest)f
+(run)177 2283 y(seen)h(so)h(far)f(\(i.e.)f(in)i(b[1..i]\),)e(then,)h(because)
+f(the)h(array)g(is)g(sorted,)177 2333 y(the)g(extension)f(of)i(our)f(array)g
+(range)f(to)177 2383 y(@{b[1..i+1]@})f(can)i(only)g(result)g(in)g(an)h
+(increase)e(in)h(@{p@})g(if)g(the)h(new)f(element)177 2433
+y(terminates)f(a)h(run)h(of)f(length)g(@{p+1@}.)f(The)h(increase)f(can)h(be)h
+(at)f(most)g(1.)g(Because)177 2482 y(the)g(array)g(is)g(sorted,)g(we)g(need)
+177 2532 y(only)g(compare)f(the)i(endpoints)e(of)h(this)g(possible)f(run)h
+(to)h(see)f(if)g(it)h(exists.)e(This)177 2582 y(is)i(performed)d(as)j(shown)f
+(below.)177 2682 y(@$@<Loop)f(body@>==@{i++;)f(if)j(\(b[i])e(!=)i(b[i-p]\))e
+(p++;@})295 2827 y Fr(Where)15 b(the)f(co)q(de)h(is)f(more)f(ob)o(vious,)f
+(it)i(is)g(often)g(b)q(etter)h(to)f(let)g(the)g(co)q(de)h(sp)q(eak)g(for)e
+(itself.)1042 2940 y(52)p eop
+%%Page: 53 54
+53 53 bop 177 42 a Fl(@C)22 b(The)f(following)f(function)g(compares)g(two)h
+(C~strings)f(and)h(returns)g(TRUE)g(iff)g(they)177 91 y(are)g(identical.)177
+191 y(@$@<Function)e(comp@>==@{@-)177 241 y(bool)i(comp\(p,q\))177
+291 y(char)g(*p,*q;)177 340 y({)199 390 y(while)g(\(TRUE\))243
+440 y({)264 490 y(if)h(\(*p)f(!=)g(*q)43 b(\))22 b(return)f(FALSE;)264
+540 y(if)h(\(*p)f(==)g('\\0'\))g(return)g(TRUE;)264 589 y(p++;)g(q++;)243
+639 y(})177 689 y(})177 739 y(@})177 932 y Fi(2.12)70 b(Wholistic)20
+b(Debugging)177 1062 y Fr(Surprising)f(though)f(it)g(ma)o(y)e(b)q(e,)k(F)m
+(unnelW)m(eb)e(has)g(a)h(k)o(ey)f(role)g(to)h(pla)o(y)e(in)h(the)h
+Fm(debugging)h Fr(of)d(programs.)177 1112 y(Long)12 b(exp)q(erience)i(in)e
+(programming)d(has)k(led)f(me)f(to)h(the)h(concept)h(of)e Fo(wholistic)f
+(debugging)p Fr(.)j(When)f(most)177 1162 y(programmers)g(detect)j(a)e(bug,)g
+(their)g(\014rst)h(reaction)g(seems)g(to)f(b)q(e)h(to)f(jump)f(in)o(to)h(the)
+h(debugger)g(where)g(they)177 1212 y(often)f(sp)q(end)h(man)o(y)e(hours)h
+(stepping)h(through)f(endless)h(stretc)o(hes)i(of)c(co)q(de)i(and)f
+(generally)g(w)o(asting)f(a)h(lot)f(of)177 1261 y(time.)177
+1346 y(In)j(con)o(trast,)g(m)o(y)d(\014rst)j(reaction)g(when)g(I)f(detect)i
+(a)e(bug)h(is)f(to)g(realize)h(that)f Fm(the)h(c)n(o)n(de)h(must)f(not)h(b)n
+(e)f(in)g(go)n(o)n(d)177 1396 y(enough)j(shap)n(e)g(if)f(such)g(a)g(bug)h(c)n
+(an)f(arise.)28 b Fr(The)18 b(presence)i(of)d(the)h(bug)f(is)g(tak)o(en)g(as)
+h(symptomatic)c(of)j(the)177 1446 y(lac)o(k)g(of)f(general)i(health)f(of)f
+(the)i(co)q(de.)29 b(If)17 b(that)g(bug)g(o)q(ccurred,)i(wh)o(y)e(not)g
+(another?)28 b(In)18 b(resp)q(onse)h(to)e(this)177 1495 y(realization,)12
+b(m)o(y)f(reaction)i(is)g(not)g(to)g(en)o(ter)h(the)f(debugger,)g(but)h
+(rather)f(to)g(return)h(to)f(the)g(original)e(co)q(de)j(and)177
+1545 y(tend)k(it)e(lik)o(e)h(a)f(garden,)i(adding)e(more)g(commen)o(ts,)f
+(rew)o(orking)i(the)h(grott)o(y)e(bits,)i(adding)e(assertions,)i(and)177
+1595 y(lo)q(oking)d(for)h(faults.)26 b(In)16 b(man)o(y)f(cases,)j(the)f
+(searc)o(h)h(for)e(faults)g(do)q(es)h(not)f(ev)o(en)h(cen)o(tre)i(on)d(the)h
+(sp)q(eci\014c)h(bug)177 1645 y(that)c(arose,)g(but)g(do)q(es)h(tend)f(to)g
+(fo)q(cus)g(on)g(the)h(area)f(of)f(co)q(de)i(where)g(the)f(bug)g(is)g(lik)o
+(ely)e(to)i(b)q(e.)177 1729 y(The)h(result)g(is)f(often)g(that)h(the)g
+(original)d(bug)i(is)h(lo)q(cated)f(more)f(quic)o(kly)h(than)g(it)g(w)o(ould)
+f(ha)o(v)o(e)i(b)q(een)g(had)f(the)177 1779 y(debugger)i(b)q(een)h(in)o(v)o
+(olv)o(ed.)k(But)16 b(ev)o(en)f(if)g(it)g(isn't,)g(there)h(are)g(other)g(b)q
+(ene\014ts.)24 b(A)15 b(programmer)e(who)i(en)o(ters)177 1829
+y(the)g(debugger)f(ma)o(y)e(sta)o(y)i(there)i(for)d(hours)h(and)g(still)f
+(not)h(\014nd)g(the)h(bug.)j(The)c(result)h(is)e(frustration)h(and)g(no)177
+1879 y(p)q(ositiv)o(e)c(gain)g(at)g(all.)15 b(In)c(con)o(trast,)g(b)o(y)f
+(tending)g(to)g(the)h(co)q(de,)h(the)f(programmer)d(is)i(making)e(forw)o(ard)
+i(progress)177 1929 y(at)15 b(all)f(times)h(\(the)h(co)q(de)g(is)f(constan)o
+(tly)g(impro)o(ving\))e(ev)o(en)j(if)f(the)h(bug)f(is)g(not)g(immediately)d
+(found.)22 b(A)o(t)15 b(the)177 1979 y(end)i(of)e(ten)i(hours,)g(the)g
+(programmer)d(can)i(at)g(least)g(feel)h(that)f(the)h(co)q(de)g(is)f(\\ten)g
+(hours)h(b)q(etter",)g(whereas)177 2028 y(the)e(debugger)h(freak)e(will)f
+(lik)o(ely)g(feel)i(defeated.)21 b(All)13 b(this)i(mak)o(es)e(co)q(de)i
+(tending)g(b)q(etter)h(psyc)o(hologically)d(as)177 2078 y(w)o(ell)g(as)h(a)g
+(more)f(e\016cien)o(t)h(approac)o(h)g(to)g(debugging.)177 2163
+y(I)19 b(call)f(this)h(tec)o(hnique)g(wholistic)f(debugging,)h(for)f(it)h(is)
+f(lik)o(e)g(the)i(di\013erence)g(b)q(et)o(w)o(een)g(con)o(v)o(en)o(tional)e
+(and)177 2213 y(wholistic)d(medicine.)20 b(Go)15 b(to)g(a)f(con)o(v)o(en)o
+(tional)g(do)q(ctor)i(with)f(a)f(headac)o(he)i(and)f(he)h(migh)o(t)d(send)j
+(o\013)f(for)f(head)177 2262 y(X-ra)o(ys,)20 b(p)q(erform)e(allergy)g(tests)i
+(and)f(p)q(erform)f(man)o(y)f(other)i(debugging)f(activities.)33
+b(Go)18 b(to)h(a)f(wholistic)177 2312 y(do)q(ctor)e(with)f(the)g(same)f
+(problem)g(and)h(he)h(migh)o(t)d(lo)q(ok)h(to)h(see)h(if)e(y)o(ou)h(are)g
+(\014t,)g(assess)i(y)o(our)e(men)o(tal)e(health,)177 2362 y(and)i(ask)h(y)o
+(ou)f(if)f(y)o(our)i(marriage)d(is)j(w)o(orking.)21 b(Both)16
+b(approac)o(hes)g(are)g(appropriate)f(at)h(di\013eren)o(t)g(times.)22
+b(In)177 2412 y(programming,)10 b(the)k(wholistic)g(approac)o(h)f(is)h(not)g
+(used)h(enough.)177 2605 y Fi(2.13)70 b(Examples)22 b(of)h(F)-6
+b(unnelW)g(eb)23 b(Applications)177 2735 y Fr(Despite)16 b(\(or)g(p)q(erhaps)
+g(b)q(ecause)i(of)s(\))d(its)g(\015exibilit)o(y)f(and)h(simplicit)o(y)m(,)e
+(F)m(unnelW)m(eb)i(can)g(b)q(e)i(applied)d(to)i(quite)177 2785
+y(a)f(n)o(um)o(b)q(er)f(of)h(di\013eren)o(t)h(text)g(pro)q(cessing)g(and)f
+(do)q(cumen)o(ting)f(problems.)21 b(This)15 b(section)h(describ)q(es)h(some)d
+(of)177 2835 y(the)h(more)e(in)o(teresting)h(real)g(problems)f(that)h(F)m
+(unnelW)m(eb)f(has)h(solv)o(ed.)1042 2940 y(53)p eop
+%%Page: 54 55
+54 54 bop 177 42 a Fd(2.13.1)55 b(Analyzing)19 b(the)f(Monster)g(P)n
+(ostscript)h(Header)f(File)177 141 y Fr(During)c(m)o(y)e(Ph.D.)h
+(candidature,)h(I)g(determined)g(at)g(one)g(p)q(oin)o(t)g(that)g(it)g(w)o
+(ould)f(b)q(e)i(v)o(ery)f(desirable)g(to)g(auto-)177 191 y(matically)f
+(insert)j(diagrams)d(from)h(the)i Fm(MacDr)n(aw)g Fr(program)e(on)h(m)o(y)f
+(Macin)o(tosh)h(in)o(to)g(T)1627 200 y(E)1650 191 y(X)g Fl(insert)p
+Fr(ions)f(in)177 240 y(m)o(y)e(thesis.)20 b(This)14 b(w)o(ould)f(allo)o(w)f
+(diagrams)g(to)i(\015oat)f(around)h(with)g(the)h(text)f(and)g(b)q(e)h(prin)o
+(ted)f(automatically)177 290 y(rather)k(than)f(ha)o(ving)g(to)g(b)q(e)g(prin)
+o(ted)h(separately)g(and)f(stuc)o(k)h(in)f(with)g(real)g(glue.)27
+b(On)18 b(the)g(face)f(of)g(it,)g(the)177 340 y(problem)c(seemed)i(inheren)o
+(tly)g(solv)n(able)e(as)i(the)g(Macin)o(tosh)g(could)f(generate)i(P)o
+(ostScript)f(for)f(eac)o(h)h(diagram)177 390 y(and)f(this)g(P)o(ostScript)h
+(could)e(presumably)g(b)q(e)i(inserted)g(in)o(to)e(the)h(P)o(ostScript)h
+(generated)g(using)f(T)1768 399 y(E)1791 390 y(X.)177 462 y(The)19
+b(only)e(trouble)h(w)o(as)g(that)g(the)h(Macin)o(tosh)f(P)o(ostScript)h(co)q
+(de)g(for)f(the)g(diagrams)f(relied)h(on)g(an)g(Apple)177 512
+y(P)o(ostScript)d(header)f(\014le.)k(This)c(mean)o(t)f(that)g(the)i(header)g
+(\014le)e(had)h(to)f(b)q(e)i(included)f(at)f(the)i(start)f(of)f(the)i(T)1895
+521 y(E)1918 512 y(X)177 562 y(P)o(ostScript)d(if)d(the)j(inserted)g(P)o
+(ostScript)f(for)f(the)h(diagrams)e(w)o(as)i(to)f(w)o(ork.)17
+b(Unfortunately)m(,)10 b(merely)g(including)177 612 y(the)17
+b(header)g(\014le)f(at)g(the)g(top)g(didn't)f(w)o(ork,)h(and)g(it)g(turned)h
+(out)e(that)i(a)e(rather)i(detailed)f(analysis)f(of)h(some)177
+662 y(parts)d(of)e(the)h(Apple)g(header)h(\014le)f(w)o(as)g(required)h(in)e
+(order)i(to)e(p)q(erform)g(the)i(necessary)h(surgery)f(on)e(the)i(header)177
+712 y(\014le)h(to)f(mak)o(e)f(it)h(w)o(ork.)18 b(This)13 b(analysis)g(w)o(as)
+g(sev)o(erely)i(aggra)o(v)n(ated)e(b)o(y)g(the)h(fact)g(that)f(the)h(P)o
+(ostScript)h(header)177 761 y(\014le)f(w)o(as)g(virtually)e(unreadable.)18
+b(Basically)13 b(it)h(w)o(as)f(ab)q(out)h(50K)g(of)f(in)o(terw)o(o)o(v)o(en)g
+(de\014nitions,)h(that)g(lo)q(ok)o(ed)f(as)177 811 y(if)f(it)g(had)g(b)q(een)
+i(run)f(through)f(a)g(w)o(ord)h(pro)q(cessor.)19 b(There)14
+b(w)o(as)e(no)g(w)o(a)o(y)g(that)h(the)g(co)q(de)g(could)f(b)q(e)i(understo)q
+(o)q(d)177 861 y(clearly)g(without)f(some)g(kind)g(of)h(reformatting.)i(Tw)o
+(o)d(other)i(asp)q(ects)g(of)e(the)i(problem)d(further)j(complicated)177
+911 y(the)g(analysis:)239 1019 y Fq(\017)21 b Fr(The)12 b(de\014nitions)h(of)
+e(in)o(terest)i(\(i.e.)f(the)g(ones)h(causing)f(the)h(problems\))e(w)o(ere)i
+(scattered)h(throughout)e(the)281 1069 y(\014le.)239 1150 y
+Fq(\017)21 b Fr(Man)o(y)c(de\014nitions)h(could)g(not)g(b)q(e)h(mo)o(v)o(ed.)
+28 b(F)m(or)18 b(one)g(or)g(more)f(reasons)i(\(e.g.)e(to)h(k)o(eep)h(a)e
+(de\014nition)281 1200 y(within)e(the)h(activ)n(ation)f(of)g(a)h(particular)f
+(dictionary)h Fl(begin)e Fr(and)i Fl(end)p Fr(\))f(it)h(w)o(ould)f(ha)o(v)o
+(e)h(b)q(een)h(un)o(wise)281 1250 y(to)d(mo)o(v)o(e)e(the)i(de\014nitions)g
+(of)g(in)o(terest)h(to)e(the)i(same)e(p)q(oin)o(t)g(in)h(the)g(\014le.)177
+1358 y(In)f(fact)g(the)h(\014le)f(w)o(as)g(so)g(messy)g(and)g(complicated)f
+(that,)g(as)i(a)e(rule,)h(it)g(had)g(to)g(b)q(e)h(handled)f(with)f(kid)h(glo)
+o(v)o(es.)177 1408 y(It)h(w)o(ould)f(ha)o(v)o(e)h(b)q(een)h(un)o(wise)f(to)g
+(re-arrange)g(the)h(de\014nitions)f(or)g(to)f(insert)i(commen)o(ts.)177
+1481 y(T)m(o)j(m)o(y)f(surprise,)k(F)m(unnelW)m(eb)d(pro)o(vided)g(an)h
+(unexp)q(ected)i(solution)c(to)i(the)g(problem.)31 b(First)19
+b(I)g(replaced)177 1531 y(all)e(o)q(ccurrences)j(of)d(the)i
+Fl(@)e Fr(in)g(the)h(header)h(\014le)f(with)f Fl(@@)p Fr(.)29
+b(Second,)19 b(I)e(placed)h(the)g(en)o(tire)h(header)f(\014le)g(in)f(a)177
+1580 y(F)m(unnelW)m(eb)d(macro)f(de\014nition)h(connected)j(to)d(a)g(pro)q
+(duct)h(\014le.)20 b(I)14 b(then)i(pro)q(cessed)g(the)f(\014le)g(and)f(c)o
+(hec)o(k)o(ed)i(to)177 1630 y(mak)o(e)f(sure)i(that)g(the)f(pro)q(duct)i
+(\014le)e(w)o(as)g(iden)o(tical)g(to)g(the)h(original)d(\014le.)25
+b(By)17 b(doing)e(all)g(this)h(I)g(had)h(placed)177 1680 y(the)f(header)g
+(\014le)g(under)g(F)m(unnelW)m(eb)e(con)o(trol.)22 b(I)16 b(then)f(left)g
+(the)h(macro)e(de\014nition)h(largely)g(un)o(touc)o(hed,)h(but)177
+1730 y(replaced)21 b(the)f(P)o(ostScript)g(de\014nitions)f(of)g(in)o(terest)i
+(with)e(F)m(unnelW)m(eb)g(macro)f(calls,)i(mo)o(ving)d(the)j(actual)177
+1780 y(P)o(ostScript)15 b(de\014nitions)f(in)o(to)f(F)m(unnelW)m(eb)g(macro)g
+(de\014nitions)h(at)g(the)g(end)g(of)g(the)g(F)m(unnelW)m(eb)g(\014le.)177
+1888 y Fl(@O@<LaserHeader.ps)o(@>==@)o({@-)177 1938 y(Unreadable)20
+b(Postscript)g(code)177 1988 y(@<Print)h(routine@>)177 2038
+y(Unreadable)f(Postscript)g(code)177 2087 y(@<Zap)h(routine@>)177
+2137 y(Unreadable)f(Postscript)g(code)177 2187 y(@})177 2287
+y(@A)i(This)f(routine)f(looks)h(as)g(if)g(it)h(does)f(this,)f(but)i(really)e
+(is)i(does)f(that,)177 2337 y(blah,)g(blah)g(blah.)177 2436
+y(@$@<Print)f(routine@>==@{@-)177 2486 y(/print)h({)g(push)g(pop)g(pop)h
+(push)f(turn)g(around)f(and)h(jump)g(up)h(and)f(down)g(and)g(print)g(it})g
+(def)177 2536 y(@})177 2635 y(@A)h(This)f(routine)f(zaps)h(the...)177
+2735 y(@$@<Zap)g(routine@>==@{@-)177 2785 y(/zap)g({)h(push)f(pop)g(pop)g
+(push)g(turn)g(around)g(and)g(jump)g(up)g(and)g(down)g(and)g(print)g(it})g
+(def)177 2835 y(@})1042 2940 y Fr(54)p eop
+%%Page: 55 56
+55 55 bop 177 42 a Fr(Use)19 b(of)f(F)m(unnelW)m(eb)g(mean)o(t)f(that)h(I)g
+(w)o(as)h(able)f(to)g(pluc)o(k)g(out)g(the)h(de\014nitions)f(of)g(in)o
+(terest)h(\(a)f(v)o(ery)h(small)177 91 y(part)g(of)e(the)i(whole)g(\014le\))f
+(and)g(collect)h(them)f(as)g(a)g(group)g(at)h(the)g(end)f(of)g(the)h(\014le)g
+(where)g(they)g(could)f(b)q(e)177 141 y(studied.)g(Because)13
+b(eac)o(h)f(de\014nition)e(w)o(as)i(safely)e(con)o(tained)i(in)e(a)h(macro,)f
+(it)h(w)o(as)g(p)q(ossible)g(to)g(write)h(a)f(detailed)177
+191 y(commen)o(tary)i(of)i(eac)o(h)g(routine)h(without)e(fear)i(of)e
+(a\013ecting)i(the)f(\014nal)g(P)o(ostScript)h(co)q(de)g(in)e(an)o(y)h(w)o(a)
+o(y)f(at)h(all.)177 241 y(Once)h(this)f(analysis)e(w)o(as)i(completed,)f(it)g
+(w)o(as)g(p)q(ossible)h(to)g(p)q(erform)e(surgery)j(on)e(the)i(o\013ending)e
+(P)o(ostScript)177 291 y(de\014nitions)k(in)f(an)h(extremely)f(con)o(trolled)
+h(w)o(a)o(y)m(.)28 b(In)18 b(particular,)g(the)h(F)m(unnelW)m(eb)e(input)g
+(\014le)h(serv)o(ed)h(as)f(a)177 340 y(rep)q(ository)f(for)g(all)e(the)i
+(di\013eren)o(t)h(v)o(ersions)f(of)f(particular)g(routines)h(that)g(w)o(ere)g
+(tried)g(in)g(order)g(to)f(get)h(the)177 390 y(de\014nitions)g(to)g(w)o(ork.)
+27 b(A)17 b(new)g(\()p Fo(Z)p Fr(ero\))h(macro)d(w)o(as)i(created)i(for)d
+(eac)o(h)i(v)o(ersion)f(of)f(eac)o(h)i(de\014nition,)e(and)h(a)177
+440 y(commen)o(tary)12 b(of)h(ho)o(w)h(it)f(p)q(erformed)h(added)g(ab)q(o)o
+(v)o(e)f(it.)177 516 y(This)e(case)g(demonstrates)h(that)e(F)m(unnelW)m(eb)g
+(is)h(an)g(extremely)f(p)q(o)o(w)o(erful)g(to)q(ol)g(for)g(dissecting)i(and)e
+(do)q(cumen)o(t-)177 566 y(ing)15 b(cryptic)h(text)g(\014les.)22
+b(Through)16 b(the)g(use)g(of)e(macros,)h(particular)g(parts)h(of)e(the)i
+(\014le)g(can)f(b)q(e)h(isolated)f(and)177 616 y(discussed)i(without)e
+(a\013ecting)g(the)h(\014nal)f(pro)q(duct)h(\014le)f(in)g(an)o(y)f(w)o(a)o(y)
+m(.)21 b(In)15 b(the)h(example)e(ab)q(o)o(v)o(e,)h(only)f(a)h(small)177
+665 y(part)d(of)f(the)i(\014le)e(w)o(as)h(analysed,)f(the)i(rest)g(b)q(eing)e
+(left)h(as)g(a)f(blob,)g(but)h(in)g(the)g(general)g(case,)h(a)e(cryptic)h
+(text)h(\014le)177 715 y(could)i(b)q(e)g(inserted)h(in)o(to)e(F)m(unnelW)m
+(eb)g(and)h(then)g(incremen)o(tally)e(dissected)k(\(and)e(p)q(ossibly)f(mo)q
+(di\014ed\))g(un)o(til)177 765 y(the)k(result)g(is)g(a)f(fully)f(do)q(cumen)o
+(ted)h(literate)h(program.)27 b(That)17 b(this)g(can)h(b)q(e)g(done)f
+(without)g(a\013ecting)h(the)177 815 y(actual)c(pro)q(duct)g(\014le)g
+(demonstrates)h(the)f(high)f(degree)j(of)d(descriptiv)o(e)i(con)o(trol)e
+(that)h(F)m(unnelW)m(eb)g(pro)o(vides.)177 960 y Fd(2.13.2)55
+b(Making)19 b(Ada)g(ADTs)g(more)e(A)177 1063 y Fr(Lik)o(e)c(man)o(y)f(mo)q
+(dern)g(programming)e(languages,)j(Ada)g(pro)o(vides)h(mec)o(hanisms)d(for)i
+(hiding)f(information)f(and)177 1113 y(structure.)25 b(In)16
+b(particular,)f(Ada)g(pro)o(vides)h(a)f Fo(pac)o(k)m(age)h
+Fr(facilit)o(y)d(that)j(allo)o(ws)e(the)i(programmer)e(to)h(declare)177
+1163 y(ob)r(jects)g(in)e(a)g(pac)o(k)n(age)h(de\014nition)f(and)g(de\014ne)i
+(them)e(in)g(a)g(corresp)q(onding)i(pac)o(k)n(age)e(b)q(o)q(dy)m(.)k(This)d
+(w)o(orks)f(w)o(ell)177 1213 y(for)h(functions)g(and)g(pro)q(cedures.)20
+b(Ho)o(w)o(ev)o(er,)14 b(in)g(the)g(case)h(of)f(t)o(yp)q(es,)g(implemen)o
+(tation)d(issues)k(\(in)e(particular,)177 1262 y(the)h(need)h(to)e(kno)o(w)g
+(the)h(size)h(of)e(exp)q(orted)h(t)o(yp)q(es\))h(ha)o(v)o(e)e(led)h(the)g
+(designers)h(of)d(Ada)i(to)f(force)h(the)g(placemen)o(t)177
+1312 y(of)f(priv)n(ate)g(t)o(yp)q(e)g(de\014nitions)g(in)g(the)h
+(de\014nition)e(pac)o(k)n(age)h(rather)h(than)f(the)h(implemen)o(tatio)o(n)c
+(pac)o(k)n(age.)18 b(This)177 1362 y(means)12 b(that)h(some)g(implem)o(en)o
+(tation)d(details)j(are)g(presen)o(t)i(in)d(the)i(pac)o(k)n(age)f
+(de\014nition)f(for)h(all)f(to)h(see.)19 b(While)177 1412 y(not)i(actually)e
+(dangerous)i(\(the)h(user)g(of)d(the)j(pac)o(k)n(age)e(cannot)h(mak)o(e)e
+(use)i(of)f(the)h(information)d(without)177 1462 y(recourse)d(to)d(\\Chapter)
+h(13")f(of)g(the)i(Ada)e(Language)g(Reference)j(Man)o(ual)p
+Fo([DOD83])p Fr(\),)c(this)h(asp)q(ect)i(of)e(Ada)h(is)177
+1512 y(certainly)h(unpleasan)o(t.)177 1588 y(During)9 b(the)i(dev)o(elopmen)o
+(t)e(of)h(some)f(Ada)h(programs,)f(F)m(unnelW)m(eb)g(w)o(as)h(used)h(to)f
+(solv)o(e)g(this)g(problem.)15 b(Instead)177 1637 y(of)j(creating)i(a)e
+(separate)i(\014le)f(for)g(the)g(pac)o(k)n(age)g(sp)q(eci\014cation)h(and)e
+(pac)o(k)n(age)h(b)q(o)q(dy)m(,)g(a)g(single)f(F)m(unnelW)m(eb)177
+1687 y(\014le)h(w)o(as)f(created)i(con)o(taining)d(t)o(w)o(o)h(sections,)i
+(one)f(for)f(the)h(eac)o(h)g(pac)o(k)n(age)f(part.)31 b(The)19
+b(\\priv)n(ate")f(part)g(of)177 1737 y(the)h(pac)o(k)n(age)f(sp)q
+(eci\014cation)h(w)o(as)f(then)g(mo)o(v)o(ed)f(\(using)h(a)g(F)m(unnelW)m(eb)
+f(macro)g(de\014nition\))h(to)g(the)h(section)177 1787 y(describing)f(the)h
+(pac)o(k)n(age)e(b)q(o)q(dy)m(.)29 b(Readers)18 b(who)g(wished)g(only)e(to)i
+(read)g(the)g(pac)o(k)n(age)g(sp)q(eci\014cation)g(could)177
+1837 y(read)13 b(only)e(the)i(\014rst)g(part,)f(whic)o(h)g(con)o(tained)g(a)g
+(fully)e(do)q(cumen)o(ted)j(description)f(not)g(con)o(taining)f(the)i(priv)n
+(ate)177 1886 y(de\014nition.)177 2031 y Fd(2.13.3)55 b(Multiple)18
+b(Language)g(Systems)177 2135 y Fr(With)10 b(the)h(prev)n(alence)h(of)e(op)q
+(en)h(systems)g(and)f(m)o(ulti-v)o(endor)f(computing,)g(it)h(is)g(often)h
+(necessary)i(to)d(construct)177 2185 y(systems)20 b(consisting)g(of)f
+(programs)f(written)i(in)g(a)f(n)o(um)o(b)q(er)g(of)g(di\013eren)o(t)i
+(programmi)o(ng)c(languages)i(for)g(a)177 2234 y(n)o(um)o(b)q(er)c(of)f
+(di\013eren)o(t)j(systems.)22 b(F)m(or)15 b(example,)f(a)h(particular)g
+(functionalit)o(y)f(migh)o(t)f(b)q(e)j(implemen)o(ted)d(b)o(y)i(a)177
+2284 y(shellscript)k(\(in)o(v)o(ok)o(ed)e(b)o(y)g(the)h(user\))h(that)f
+(calls)f(a)h(C)f(program)f(that)i(mak)o(es)f(a)g(net)o(w)o(ork)h(connection)h
+(to)e(a)177 2334 y(P)o(ascal)e(program)f(that)h(queries)h(a)f(database.)23
+b(Quite)15 b(often)h(all)e(these)i(programs)e(m)o(ust)h(conspire)h(closely)f
+(to)177 2384 y(execute)k(their)e(function.)25 b(In)17 b(the)g(normal)d(case,)
+k(they)f(m)o(ust)f(b)q(e)h(written)g(separately)m(.)26 b(F)m(unnelW)m(eb)16
+b(allo)o(ws)177 2434 y(them)d(to)h(b)q(e)g(written)h(as)f(a)f(whole.)177
+2510 y(By)19 b(creating)f(a)g(single)g(F)m(unnelW)m(eb)g(\014le)g(that)g
+(creates)i(man)o(y)c(pro)q(duct)j(\014les)g(in)f(di\013eren)o(t)h(languages,)
+f(the)177 2559 y(programmer)c(can)i(describ)q(e)i(the)e(in)o(teraction)g(b)q
+(et)o(w)o(een)i(the)e(di\013eren)o(t)h(programs)e(in)g(an)o(y)h(manner)f
+(desired.)177 2609 y(F)m(urthermore,)f(b)q(ecause)i(the)e(di\013eren)o(t)h
+(pro)q(duct)g(\014les)g(are)g(all)d(created)k(in)e(the)g(same)g(\\text)g
+(space")h(\(i.e.)e(in)h(a)177 2659 y(single)g(F)m(unnelW)m(eb)f(\014le\),)h
+(it)f(is)h(easy)g(for)g(them)f(to)h(share)g(information.)177
+2735 y(F)m(or)h(example,)e(in)i(one)g(real)g(application)e(F)m(unnelW)m(eb)i
+(w)o(as)g(used)g(to)g(create)i(a)d(system)h(for)g(prin)o(ting)f(\014les)h(on)
+177 2785 y(a)i(laser)h(prin)o(ter)g(connected)i(to)d(a)g(remote)g(V)m(ax)g
+(Unix)g(mac)o(hine)g(from)e(a)j(lo)q(cal)e(V)m(ax)h(VMS)h(mac)o(hine.)27
+b(The)177 2835 y(system)18 b(consisted)h(of)f(t)o(w)o(o)g(\014les:)27
+b(a)18 b(VMS)g(DCL)g(command)d(pro)q(cedure)20 b(to)e(run)h(on)f(the)g(lo)q
+(cal)g(no)q(de,)h(and)1042 2940 y(55)p eop
+%%Page: 56 57
+56 56 bop 177 42 a Fr(a)16 b(Unix)h(shellscript)g(to)f(run)h(on)g(the)g
+(remote)f(no)q(de.)27 b(The)17 b(user,)h(b)o(y)e(giving)f(the)i(prin)o(t)g
+(command,)d(in)o(v)o(ok)o(ed)177 91 y(the)h(lo)q(cal)f(VMS)h(command)d(pro)q
+(cedure,)17 b(whic)o(h)d(in)g(turn)i(\014red)f(up)g(the)g(remote)g(Unix)f
+(shellscript.)21 b(The)15 b(t)o(w)o(o)177 141 y(scripts)g(then)g(co)q(op)q
+(erated)g(to)f(transfer)h(the)f(\014les)g(to)g(b)q(e)h(prin)o(ted)f(and)g
+(prin)o(t)f(them.)177 215 y(In)e(addition)f(to)h(its)g(usual)f(do)q(cumen)o
+(tation)g(p)q(o)o(w)o(ers,)i(F)m(unnelW)m(eb)e(assisted)i(in)e(the)i
+(creation)f(of)g(this)g(system)f(in)177 265 y(t)o(w)o(o)i(sp)q(ecial)g(w)o(a)
+o(ys.)17 b(First,)c(it)e(allo)o(w)o(ed)g(pieces)i(of)f(co)q(de)h(from)d(the)j
+(t)o(w)o(o)e(di\013eren)o(t)j(command)9 b(pro)q(cedures)14
+b(to)e(b)q(e)177 315 y(partially)g(in)o(terw)o(o)o(v)o(en)h(in)g(a)g
+(description)h(of)f(their)g(in)o(teraction.)18 b(This)13 b(is)h(just)f(not)g
+(p)q(ossible)h(with)f(commen)o(ts.)177 364 y(Second,)19 b(it)e(facilitated)g
+(the)h(use)h(of)e(shared)i(information.)26 b(F)m(or)17 b(example,)g(under)i
+(some)d(conditions,)i(eac)o(h)177 414 y(\014le)d(to)f(b)q(e)h(prin)o(ted)g(w)
+o(ould)f(b)q(e)h(renamed)f(and)h(copied)f(to)h(the)g(remote)f(system)g(using)
+h(a)f(particular)g(constan)o(t)177 464 y(\014lename)h(\(e.g.)g(\\)p
+Fl(printfile.tmp)p Fr("\).)20 b(F)m(unnelW)m(eb)15 b(allo)o(w)o(ed)g(this)g
+(constan)o(t)i(\014lename)d(to)i(b)q(e)g(included)g(in)f(a)177
+514 y(single)i(macro)e(de\014nition)i(whic)o(h)g(w)o(as)g(in)o(v)o(ok)o(ed)f
+(in)g(the)i(de\014nition)e(of)h(eac)o(h)g(of)f(the)i(scripts.)28
+b(This)17 b(ensured)177 564 y(that)d(the)h(t)o(w)o(o)e(scripts)i(used)g(the)f
+(same)f(name.)177 677 y Fl(@A)22 b(The)f(following)f(macro)g(contains)h(the)g
+(temporary)f(file)h(name)g(used)g(to)g(allow)g(the)177 726
+y(two)g(shellscripts)f(to)h(transfer)f(each)h(file)g(to)g(be)h(printed.)177
+826 y(@$@<printfile@>@M=)o(=@{pr)o(intme)o(.txt@)o(})177 926
+y(@A)g(Here)f(are)g(the)g(scripts)f(for)h(the)h(local)e(VMS)h(node)g(and)h
+(the)f(remote)f(UNIX)h(node.)177 1025 y(@O@<vmscommandproc)o(edure)o(.com@)o
+(>==@{)o(@-)177 1075 y(DCL)g(commands)177 1125 y(copy)g(@<printfile@>)e
+(unixnode::)177 1175 y(DCL)i(commands)177 1225 y(@})177 1324
+y(@O@<unixshellscrip)o(t@>==)o(@{@-)177 1374 y(unix)g(commands)177
+1424 y(print)g(@<printfile@>)177 1474 y(unix)g(commands)177
+1523 y(@})177 1636 y Fr(In)13 b(the)h(case)g(of)e(the)i(prin)o(ting)e
+(system,)h(the)h(en)o(tire)f(system)g(w)o(as)g(describ)q(ed)i(and)e
+(de\014ned)h(in)f(a)f(single)h(F)m(unnel-)177 1686 y(W)m(eb)h
+Fl(.fw)g Fr(\014le.)19 b(In)c(larger)f(systems)g(con)o(taining)g(man)o(y)e(F)
+m(unnelW)m(eb)i Fl(.fw)f Fr(\014les)i(for)f(man)o(y)f(di\013eren)o(t)i(mo)q
+(dules)177 1736 y(in)e(man)o(y)e(di\013eren)o(t)i(languages,)g(the)g(same)f
+(tric)o(k)h(can)g(b)q(e)h(pulled)e(b)o(y)h(placing)f(F)m(unnelW)m(eb)g(macro)
+g(de\014nitions)177 1786 y(for)g(shared)h(v)n(alues)e(in)o(to)h(F)m(unnelW)m
+(eb)f(include)h(\014les.)18 b(F)m(or)11 b(example,)g(a)h(suite)g(of)f
+(implemen)o(tations)e(of)j(net)o(w)o(ork)177 1836 y(no)q(des,)18
+b(with)f(eac)o(h)h(implem)o(en)o(tation)c(b)q(eing)j(in)g(a)g(di\013eren)o(t)
+h(programmi)o(ng)c(language)i(for)h(a)g(di\013eren)o(t)h(tar-)177
+1885 y(get)d(mac)o(hine,)e(could)i(all)e(share)i(a)g(table)f(of)g
+(con\014guration)h(constan)o(ts)g(de\014ned)h(in)e(macros)g(in)g(a)g(F)m
+(unnelW)m(eb)177 1935 y(include)g(\014le.)177 2009 y(In)h(summary)m(,)c(F)m
+(unnelW)m(eb's)k(macro)e(and)i(include)g(\014le)f(mec)o(hanisms)f(pro)o(vide)
+i(a)f(simple)g(w)o(a)o(y)g(for)g(programs)177 2059 y(written)f(in)f
+(di\013eren)o(t)i(languages)e(to)g(share)h(information.)i(This)d(reduces)j
+(redundancy)f(b)q(et)o(w)o(een)f(the)h(systems)177 2109 y(and)g(hence)h(the)g
+(c)o(hance)g(of)e(inconsistencies)i(arising.)177 2248 y Fd(2.13.4)55
+b(The)19 b(Case)g(of)g(the)f(Small)f(F)-5 b(unction)177 2349
+y Fr(Often,)14 b(when)f(programming,)d(there)k(is)f(a)g(need)h(for)f(a)g(co)q
+(de)h(abstraction)g(facilit)o(y)d(that)j(op)q(erates)g(at)f(the)h(text)177
+2399 y(lev)o(el.)26 b(If)17 b(the)g(statemen)o(t)g(\\)p Fl(a:=3;)p
+Fr(")f(o)q(ccurs)j(often,)e(it)f(ma)o(y)f(b)q(e)i(b)q(est)h(simply)d(to)h
+(rep)q(eat)i(it)f(v)o(erbatim.)25 b(If)16 b(a)177 2449 y(sequence)e(of)d(one)
+g(h)o(undred)h(statemen)o(ts)g(is)f(rep)q(eated)j(often,)d(it)g(is)g(normal)f
+(to)h(remo)o(v)o(e)f(the)i(co)q(de)h(to)e(a)g(function)177
+2498 y(and)j(replace)h(the)g(o)q(ccurrences)i(b)o(y)c(a)h(function)g(call.)j
+(Ho)o(w)o(ev)o(er,)d(in)g(b)q(et)o(w)o(een)h(these)h(t)o(w)o(o)d(extremes)i
+(are)f(cases)177 2548 y(where)i(a)f(particular)f(sequence)k(of)c(co)q(de)i
+(is)e(long)g(enough)h(and)g(app)q(ears)h(often)f(enough)g(to)f(b)q(e)i
+(troublesome,)177 2598 y(but)e(whic)o(h)g(is)g(b)q(ound)g(so)g(messily)e(to)i
+(its)g(en)o(vironmen)o(t)f(as)h(to)f(mak)o(e)g(a)g(function)h(call)f(cum)o(b)
+q(ersome.)177 2672 y(F)m(or)d(example,)g(the)h(follo)o(wing)d(line)i(of)h
+(statemen)o(ts)f(\(referring)i(to)e(\014v)o(e)h(v)n(ariables)f(declared)i
+Fm(lo)n(c)n(al)e Fr(to)h(a)f(function\))177 2722 y(migh)o(t)i(app)q(ear)i
+(ten)h(times)e(in)g(a)h(function:)177 2835 y Fl(a=b*3.14159;)19
+b(c=d)j(\045)f(256;)g(e=e+1;)1042 2940 y Fr(56)p eop
+%%Page: 57 58
+57 57 bop 177 42 a Fr(No)o(w)11 b(the)h(\\normal")d(rule)j(of)f(programmi)o
+(ng)e(sa)o(ys)i(that)h(these)h(statemen)o(ts)f(should)f(b)q(e)h(placed)g(in)f
+(a)g(pro)q(cedure)177 91 y(\(also)h(called)h(a)f(\\function")g(in)h(the)g(C)g
+(programmi)o(ng)d(language)i(used)h(in)g(this)f(example\),)g(but)h(here)h
+(\014v)o(e)f(lo)q(cal)177 141 y(v)n(ariables)j(are)h(used.)27
+b(Use)17 b(of)f(a)g(pro)q(cedure)i(\(function\))f(w)o(ould)e(result)j(in)e(a)
+g(pro)q(cedure)i(de\014nition)e(lo)q(oking)177 191 y(something)d(lik)o(e:)177
+284 y Fl(void)21 b(frobit\(a,b,c,d,e\))177 334 y(float)g(*a,b;)177
+384 y(int)g(*c,d;)177 434 y(unsigned)f(*e;)177 484 y({*a=b)h(<<)g(8;)h(*c=d)f
+(\045)g(256;)g(*e=*e+1;})177 577 y Fr(and)14 b(a)f(pro)q(cedure)j(call)d
+(something)g(lik)o(e)177 671 y Fl(frobit\(&a,b,&c,d,&)o(e\);)177
+764 y Fr(This)h(migh)o(t)d(b)q(e)j(w)o(ork)n(able)f(in)g(a)g(language)f(that)
+i(allo)o(w)o(ed)e(formal)f(parameters)j(to)f(b)q(e)h(sp)q(eci\014ed)h(to)f(b)
+q(e)g(b)q(ound)177 814 y(only)d(to)h(particular)f(v)n(ariables.)17
+b(Similarl)o(y)m(,)8 b(it)k(migh)o(t)d(b)q(e)k(p)q(ossible)e(to)h(a)o(v)o
+(oid)e(the)j(parameter)e(list)g(in)g(languages)177 864 y(that)17
+b(supp)q(ort)h(lo)q(cal)e(pro)q(cedures)j(that)e(can)g(access)i(non-lo)q(cal)
+d(v)n(ariables)g(\(suc)o(h)i(as)e(P)o(ascal\).)28 b(Ho)o(w)o(ev)o(er,)17
+b(in)177 914 y(our)12 b(example)f(here,)i(in)e(the)i(C)f(programmi)o(ng)d
+(language,)i(these)i(options)f(are)g(not)g(a)o(v)n(ailable,)e(and)i(so)g(w)o
+(e)g(m)o(ust)177 964 y(either)i(create)h(a)d(function)h(with)g(\014v)o(e)g
+(parameters,)g(or)g(use)h(the)f(C)g(macro)f(prepro)q(cessor)k(\(the)e(b)q
+(est)g(solution\).)177 1013 y(F)m(unnelW)m(eb)d(pro)o(vides)g(the)h(same)f
+(macro)f(facilit)o(y)f(for)i(languages)g(that)g(do)g(not)h(ha)o(v)o(e)f(a)g
+(built-in)f(prepro)q(cessor.)177 1082 y(In)j(particularly)g(sp)q(eed-stresse)
+q(d)j(applications,)c(the)i(programmer)d(ma)o(y)g(b)q(e)j(reluctan)o(t)g(to)f
+(remo)o(v)o(e)g(co)q(de)h(to)f(a)177 1131 y(pro)q(cedure)j(b)q(ecause)g(of)d
+(the)h(pro)q(cedure-call)h(o)o(v)o(erhead.)k(F)m(unnelW)m(eb)13
+b(macros)g(can)h(help)g(there)h(to)q(o.)177 1200 y(In)e(summary)m(,)d(there)k
+(sometimes)d(arises)j(in)f(programmi)o(ng)d(situations)j(where)h(the)f(cost)h
+(of)e(de\014ning)h(a)g(pro)q(ce-)177 1249 y(dure)f(is)e(higher)h(than)g(the)h
+(b)q(ene\014ts)g(it)f(will)e(b)q(esto)o(w.)18 b(Commo)o(n)8
+b(reasons)k(for)f(this)f(are)i(the)f(run-time)f(pro)q(cedure)177
+1299 y(o)o(v)o(erhead)j(and)g(the)g(messy)f(binding)g(problems)f(caused)j(b)o
+(y)f(remo)o(ving)d(target)j(co)q(de)h(from)d(its)h(target)i(con)o(text.)177
+1349 y(F)m(unnelW)m(eb)g(can)g(help)g(in)g(these)h(situations)f(b)o(y)g(allo)
+o(wing)e(the)i(programmer)e(to)i(de\014ne)h(a)f(text)h(macro.)i(This)177
+1399 y(a)o(v)o(oids)e(all)g(the)h(problems)f(and)g(pro)o(vides)h(an)g
+(additional)e(incen)o(tiv)o(e)i(for)f(the)i(programmer)c(to)j(describ)q(e)h
+(the)177 1449 y(piece)e(of)e(co)q(de)i(so)f(isolated.)177 1580
+y Fd(2.13.5)55 b(When)19 b(Commen)n(ts)d(are)j(Bad)177 1676
+y Fr(In)d(the)h(\\go)q(o)q(d)f(old)f(da)o(ys")h(of)g(small)e(mac)o(hine)h
+(memories)f(and)i(in)o(terpreted)i(BASIC,)e(programmers)f(w)o(ould)177
+1725 y(eliminate)f(the)i(\\)p Fl(REM)p Fr(")e(statemen)o(ts)h(\(commen)o
+(ts\))f(from)g(their)i(BASIC)g(programs)e(so)h(as)h(to)f(sa)o(v)o(e)h(space)g
+(and)177 1775 y(increase)e(execution)g(sp)q(eed.)19 b(Whilst)13
+b(this)g(w)o(as)g(ob)o(viously)e(an)i(appalling)e(programming)f(practice,)j
+(the)h(small)177 1825 y(memories)e(and)i(slo)o(w)f(micropro)q(cessors)i
+(often)f(made)e(this)i(tempting,)e(if)h(not)h(necessary)m(.)177
+1893 y(Thankfully)m(,)9 b(times)h(ha)o(v)o(e)h(c)o(hanged)h(since)f(then,)h
+(and)f(most)f(co)q(de)i(is)f(no)o(w)f(compiled)g(rather)i(than)f(in)o
+(terpreted.)177 1943 y(Ho)o(w)o(ev)o(er,)19 b(from)e(time)f(to)i(time)f(one)h
+(still)f(runs)i(in)o(to)f(an)f(en)o(vironmen)o(t)g(or)h(situation,)g(or)h(sp)
+q(ecial-purp)q(ose)177 1993 y(language,)i(where)h(commen)o(ts)d(are)i(either)
+g(una)o(v)n(ailable)e(\(no)h(commen)o(t)f(feature\))i(or)g(undesirable.)39
+b(Here)177 2043 y(F)m(unnelW)m(eb)12 b(can)h(b)q(e)g(used)g(to)g(fully)e(do)q
+(cumen)o(t)h(the)h(co)q(de)g(without)f(resulting)h(in)f(an)o(y)g(commen)o(ts)
+e(in)i(the)h(\014nal)177 2092 y(co)q(de)i(at)f(all.)i(F)m(or)e(example:)239
+2186 y Fq(\017)21 b Fr(Commen)o(ts)15 b(in)h(frequen)o(tly)i(used)g
+Fl(.h)e Fr(header)i(\014les)g(in)e(C)h(programs)f(can)h(ha)o(v)o(e)g(a)g
+(signi\014can)o(t)f(impact)281 2236 y(on)f(compilation)d(sp)q(eed.)23
+b(Often)16 b(suc)o(h)f(header)i(\014les)e(are)g(fairly)f(cryptic)i(and)f
+(really)f(ough)o(t)h(to)g(b)q(e)g(w)o(ell)281 2286 y(commen)o(ted,)d(but)i
+(their)g(authors)g(are)h(reluctan)o(t)f(to.)239 2362 y Fq(\017)21
+b Fr(Commen)o(ts)16 b(are)k(undesirable)f(in)f(P)o(ostScript)i(header)g
+(\014les)f(that)g(m)o(ust)f(b)q(e)h(transferred)i(rep)q(eatedly)281
+2412 y(along)13 b(comm)o(unicati)o(ons)e(c)o(hannels)k(\(e.g.)e(the)i(Apple)f
+(Macin)o(tosh)g(LaserW)m(riter)g(header)h(\014le\).)239 2488
+y Fq(\017)21 b Fr(In)o(terpreted)16 b(programs)d(in)g(em)o(b)q(edded)h
+(systems.)239 2565 y Fq(\017)21 b Fr(Hand)14 b(written)g(mac)o(hine)f(co)q
+(de)h(in)g(hex)g(dump)f(form)f(could)i(b)q(e)g(commen)o(ted.)239
+2642 y Fq(\017)21 b Fr(A)16 b(programmer)d(ma)o(y)g(wish)j(to)f(annotate)g(a)
+h(text)g(data)f(\014le)g(con)o(taining)g(lists)g(of)g(n)o(um)o(b)q(ers)g
+(that)h(is)f(to)281 2691 y(b)q(e)e(fed)f(in)o(to)g(a)f(statistical)h(program)
+f(that)h(do)q(es)h(not)f(pro)o(vide)g(an)o(y)g(commen)o(t)e(facilit)o(y)g
+(for)i(its)g(input)g(\014le.)177 2785 y(In)g(all)f(these)i(situations,)e(F)m
+(unnelW)m(eb)h(allo)o(ws)e(full)h(in)o(tegrated)h(do)q(cumen)o(tation)e
+(without)i(an)o(y)f(impact)g(on)g(the)177 2835 y(\014nal)i(co)q(de.)1042
+2940 y(57)p eop
+%%Page: 58 59
+58 58 bop 177 42 a Fd(2.13.6)55 b(Do)r(cumen)n(ts)17 b(That)i(Share)g(T)-5
+b(ext)177 144 y Fr(F)m(unnelW)m(eb)13 b(is)g(v)o(ery)h(useful)g(when)g
+(preparing)f(m)o(ultiple)f(do)q(cumen)o(ts)h(that)h(m)o(ust)e(share)i(large)f
+(slabs)h(of)f(iden-)177 194 y(tical)g(text)i(that)f(are)g(b)q(eing)g(constan)
+o(tly)g(mo)q(di\014ed.)177 270 y(F)m(or)g(example)e(someone)h(preparing)h(t)o
+(w)o(o)g(sligh)o(tly)e(di\013eren)o(t)j(user)g(man)o(uals)d(for)h(t)o(w)o(o)g
+(sligh)o(tly)g(di\013eren)o(t)i(audi-)177 319 y(ences)h(migh)o(t)c(w)o(an)o
+(t)h(the)h(man)o(uals)e(to)i(share)h(large)e(slabs)h(of)f(text,)h(while)g
+(still)f(allo)o(wing)e(di\013erences)16 b(b)q(et)o(w)o(een)177
+369 y(them.)i(The)d(follo)o(wing)c(example)i(sho)o(ws)h(ho)o(w)g(this)g(can)h
+(b)q(e)f(done.)20 b(The)14 b(co)q(de)h(is)f(cluttered,)h(but)g(this)f
+(clutter)177 419 y(w)o(ould)f(not)h(b)q(e)h(a)e(problem)g(if)g(the)h(lumps)f
+(of)g(text)h(w)o(ere)h(mo)q(derately)e(large.)177 537 y Fl
+(@O@<manual1.txt@>=)o(=@{@<)o(M1@>@)o(+@})177 587 y(@O@<manual2.txt@>=)o
+(=@{@<)o(M2@>@)o(+@})177 687 y(@$@<M1@>+=@{@<T1@>)o(@})177
+736 y(@$@<M2@>+=@{@<T1@>)o(@})177 786 y(@$@<T1@>@M==@{Firs)o(t)19
+b(lump)i(of)g(text)g(shared)g(by)g(both)g(documents.@+@})177
+886 y(@$@<M1@>+=@{Text)e(for)i(first)g(document@+@})177 936
+y(@$@<M2@>+=@{Text)e(for)i(second)f(document@+@})177 1035 y
+(@$@<M1@>+=@{@<T2@>)o(@})177 1085 y(@$@<M2@>+=@{@<T2@>)o(@})177
+1135 y(@$@<T2@>@M==@{Seco)o(nd)f(lump)i(of)g(text)g(shared)g(by)g(both)g
+(documents.@+@})177 1253 y Fr(An)16 b(alternativ)o(e)g(approac)o(h,)f(whic)o
+(h)h(migh)o(t)e(w)o(ork)h(b)q(etter)i(in)f(situations)f(where)i(there)g(are)f
+(man)o(y)e(small)g(dif-)177 1303 y(ferences)k(b)q(et)o(w)o(een)f(the)f(t)o(w)
+o(o)f(do)q(cumen)o(ts)h(rather)g(than)g(a)f(few)h(large)f(ones,)i(is)e(to)h
+(de\014ne)g(a)g(macro)e(with)h(t)o(w)o(o)177 1353 y(argumen)o(ts,)c(one)h
+(for)f(eac)o(h)h(pro)q(duct)g(\014le)g(do)q(cumen)o(t.)17 b(W)m(rite)11
+b(the)h(do)q(cumen)o(t)f(from)f(top)h(to)h(b)q(ottom,)e(but)i(place)177
+1403 y(all)h(stretc)o(hes)j(that)e(di\013er)g(b)q(et)o(w)o(een)i(the)e(t)o(w)
+o(o)g(do)q(cumen)o(ts)f(in)h(a)f(macro)g(call.)177 1521 y Fl(@!)22
+b(Set)f(the)g(definition)f(of)h(@#D)g(to)177 1571 y(@!)87 b(@1)21
+b(to)h(create)e(the)h(shareholders)f(report.)177 1621 y(@!)87
+b(@2)21 b(to)h(create)e(the)h(customers)f(report.)177 1670
+y(@$@#D@\(@2@\)@M==@{@)o(1@})177 1770 y(@O@<report.txt@>==)o(@{@-)177
+1820 y(1992)h(ANNUAL)g(REPORT)f(TO)i(@#D@\(Shareholder)o(s@,C)o(ustom)o
+(ers@\))177 1870 y(==================)o(====@)o(#D@\(=)o(=====)o(=====)o
+(=@,=)o(=====)o(===@\))177 1919 y(This)f(has)g(been)g(a)h(very)f(good)g(year)
+g(for)g(The)g(Very)g(Big)g(Corporation)f(of)h(America.)177
+1969 y(With)g(your)g(help,)g(we)g(have)g(been)g(able)g(to)h(successfully)177
+2019 y(@#D@\(@"screw)d(the)j(customers)e(for)h(every)g(cent)f(they)h
+(have@"@,)286 2069 y(@"knock)f(the)i(shareholders)d(into)i(submission)f(to)h
+(bring)g(you)g(lower)g(prices@"@\).)177 2119 y(With)g(gross)g(earnings)f
+(approaching)g(six)h(trillion)f(dollars,)g(we)h(have)g(been)g(able)g(to)177
+2168 y(@#D@\(@"increase)e(dividends@"@,)286 2218 y(@"lower)h(prices@"@\).)177
+2268 y(We)i(expect)e(to)h(have)g(an)h(even)f(better)f(year)h(next)g(year.)177
+2318 y(@})177 2436 y Fr(One)c(application)f(where)h(text)g(sharing)g(can)f(b)
+q(e)i(particularly)d(useful)i(is)f(in)g(the)i(preparation)e(of)g(computer)177
+2486 y(do)q(cumen)o(tation)10 b(con)o(taining)g(examples.)17
+b(F)m(or)11 b(example,)f(a)h(b)q(o)q(ok)g(describing)g(a)g(new)h(programming)
+c(language)177 2536 y(migh)o(t)j(b)q(e)j(full)d(of)i(examples)f(of)g(small)f
+(programs)h(written)h(in)g(the)h(language)e(whic)o(h)h(the)g(user)h(migh)o(t)
+d(w)o(an)o(t)i(to)177 2586 y(try)g(without)g(ha)o(ving)f(to)h(t)o(yp)q(e)g
+(them)f(all)g(in.)17 b(The)d(\\default")e(approac)o(h)h(of)f(k)o(eeping)h(a)g
+(cop)o(y)g(of)f(the)i(examples)177 2635 y(in)f(the)h(text)g(of)e(the)i(b)q(o)
+q(ok)f(and)g(another)h(cop)o(y)f(in)g(separate)h(\014les)g(is)f(cum)o(b)q
+(ersome)f(and)h(error)i(prone,)e(b)q(ecause)177 2685 y(b)q(oth)h(\014les)g
+(ha)o(v)o(e)g(to)g(b)q(e)g(up)q(dated)h(whenev)o(er)g(an)e(example)g(is)h(c)o
+(hanged.)k(A)c(more)f(sophisticated)h(approac)o(h)g(is)177
+2735 y(to)d(store)g(eac)o(h)g(example)e(in)i(a)f(separate)i(\014le,)e(and)h
+(then)g(use)g(the)h(\\include)e(\014le")g(facilit)o(y)f(of)h(the)h(w)o(ord)g
+(pro)q(cessor)177 2785 y(to)k(include)g(eac)o(h)h(example)e(in)h(the)g(text.)
+23 b(This)15 b(is)g(a)g(b)q(etter)h(solution,)e(but)i(su\013ers)h(from)c(a)i
+(few)g(dra)o(wbac)o(ks.)177 2835 y(First,)i(when)f(editing)g(the)h(b)q(o)q
+(ok)f(in)g(a)f(w)o(ord)h(pro)q(cessor,)j(the)d(examples)g(in)f(the)i(b)q(o)q
+(ok)f(will)f(not)h(b)q(e)g(directly)1042 2940 y(58)p eop
+%%Page: 59 60
+59 59 bop 177 42 a Fr(accessible)19 b(or)f(visible.)29 b(T)m(o)17
+b(see)i(an)e(example,)g(the)h(writer)g(w)o(ould)f(ha)o(v)o(e)h(to)f(op)q(en)i
+(the)f(\014le)g(con)o(taining)e(the)177 91 y(example)11 b(in)g(a)h(separate)h
+(windo)o(w.)k(This)12 b(could)f(b)q(ecome)h(tedious)g(if)g(the)g(text)h(con)o
+(tained)f(man)o(y)e(examples,)h(as)177 141 y(man)o(y)h(texts)j(do.)i(F)m
+(urthermore,)c(there)i(is)f(a)f(risk)h(that)f(some)g(example)f(\014les)i
+(will)f(b)q(e)h(included)g(in)f(the)h(wrong)177 191 y(place.)k(Second,)12
+b(b)q(ecause)i(the)e(b)q(o)q(ok)g(is)f(dep)q(enden)o(t)j(on)d(the)i(included)
+e(\014les,)i(the)f(b)q(o)q(ok)f(will)g(end)h(up)g(consisting)177
+241 y(of)h(a)h(directory)h(of)e(a)h(h)o(undred)g(or)g(more)f(\014les)h
+(instead)g(of)g(just)g(a)f(few.)177 316 y(An)g(alternativ)o(e)f(solution)g
+(is)g(to)h(construct)h(a)e(single)h(F)m(unnelW)m(eb)f Fl(.fw)f
+Fr(\014le)i(that,)f(when)h(pro)q(cessed,)i(pro)q(duces)177
+366 y(b)q(oth)h(the)g(b)q(o)q(ok)g(\014le)g(and)f(the)i(example)d(\014les.)24
+b(This)16 b(solution)f(assumes)g(that)h(the)g(b)q(o)q(ok)g(consists)h(of)e(a)
+g(text)177 416 y(\014le)f(con)o(taining)f(commands)e(for)j(a)f(t)o(yp)q
+(esetter)k(suc)o(h)d(as)g(T)1112 425 y(E)1135 416 y(X.)177
+534 y Fl(@O@<Book.tex@>==@{)o(@#B@})177 633 y(@$@#B+=@{@-)177
+683 y(The)21 b(first)g(step)g(to)g(learning)g(the)g(object)f(oriented)g
+(AdaCgol++)g(language)h(is)g(to)g(examine)177 733 y(a)h(hello)f(world)f
+(program.)177 832 y(\\start{verbatim})177 882 y(@<Ex1@>)177
+932 y(\\finish{verbatim})177 982 y(@})177 1081 y(@$@<Ex1@>==@{read)e
+(iopack@+Enter)i(!World~!)g(!Hello~!)g(ex)h(pr)h(flu)f(X[1]@})177
+1131 y(@O@<Ex1.c@>==@{@<E)o(x1@>@)o(})177 1231 y(@$@#B+=@{@-)177
+1281 y(To)h(understand)d(the)i(program,)g(think)f(of)i(the)f(execution)f
+(state)h(as)g(a)h(plate)e(of)i(cheese...)177 1331 y(@})177
+1448 y Fr(Most)12 b(of)f(the)h(\014le)f(will)f(consist)i(of)f(part)h
+(de\014nitions)f(of)g(the)h(additiv)o(e)f(macro)f Fl(@#B)p
+Fr(.)h(The)h(de\014nition)f(is)g(\\brok)o(en")177 1498 y(to)j(allo)o(w)e(a)i
+(macro)e(de\014nition,)h(wherev)o(er)j(an)e(example)e(app)q(ears.)177
+1573 y(The)e(example)f(ab)q(o)o(v)o(e)g(is)g(a)h(little)f(messy)g(b)q(ecause)
+i(F)m(unnelW)m(eb)e(do)q(es)i(not)e(allo)o(w)f(macros)h(connected)i(to)f(pro)
+q(duct)177 1623 y(\014les)18 b(to)f(b)q(e)h(called,)f(and)g(it)g(do)q(es)h
+(not)f(ha)o(v)o(e)g(text)h(expressions)h(that)e(write)g(to)h(an)f(pro)q(duct)
+h(\014le)f(as)g(w)o(ell)g(as)177 1673 y(ev)n(aluating)d(to)h(text.)22
+b(Nev)o(ertheless,)17 b(it)e(presen)o(ts)i(a)e(fairly)f(clean)h(solution)f
+(to)h(the)h(problem)e(of)g(k)o(eeping)h(the)177 1723 y(example)e(programs)f
+(in)i(a)f(computing)g(text)h(up)g(to)g(date.)177 1866 y Fd(2.13.7)55
+b(Generics)177 1968 y Fr(It)13 b(is)g(w)o(ell)f(kno)o(wn)h(that)g(generics)h
+(in)f(programmi)o(ng)d(languages)i(are)i(closely)f(aligned)f(with)g(textual)h
+(substitu-)177 2018 y(tion.)j(In)11 b(fact,)f(a)g(go)q(o)q(d)g(w)o(a)o(y)g
+(to)g(understand)i(the)f(generic)g(facilit)o(y)e(of)g(a)h(new)h(programming)c
+(language)i(is)i(to)f(ask)177 2068 y(oneself)15 b(the)g(question)g(\\In)f
+(what)g(w)o(a)o(y)g(do)q(es)h(this)g(generic)g(facilit)o(y)e(di\013er)i(from)
+d(simple)h(text)i(substitution?")177 2118 y(The)j(di\013erences,)j(if)16
+b(an)o(y)m(,)h(t)o(ypically)g(ha)o(v)o(e)g(to)g(do)h(with)f(the)h
+(di\013erence)i(in)d(scoping)g(b)q(et)o(w)o(een)i(textual)f(and)177
+2168 y(in)o(telligen)o(t)d(substitution)g(and)h(whether)h(the)f(generic)g(co)
+q(de)h(is)e(shared)i(or)e(copied)h(b)o(y)g(the)g(implemen)o(tati)o(on.)177
+2217 y(In)e(most)f(cases)i(the)f(di\013erences)j(are)d(quite)g(minor.)177
+2293 y(Because)h(generic)g(facilities)d(are)h(so)h(closely)f(aligned)f(with)h
+(text)h(substitution,)f(it)g(is)g(p)q(ossible)h(to)f(use)h(F)m(unnel-)177
+2343 y(W)m(eb's)i(parameterized)g(macros)g(to)g(pro)o(vide)g(generics)h(in)f
+(programmi)o(ng)d(languages)j(that)g(do)g(not)g(supp)q(ort)177
+2392 y(generics.)27 b(Simply)14 b(write)j(a)f(F)m(unnelW)m(eb)f(macro)h
+(whose)h(parameters)f(are)h(the)g(parameters)f(of)g(the)h(generic)177
+2442 y(and)d(whose)g(b)q(o)q(dy)g(is)g(the)h(generic)f(ob)r(ject.)177
+2518 y(The)i(follo)o(wing)d(F)m(unnelW)m(eb)j(\014le)f(giv)o(es)h(an)f
+(example)g(of)g(a)g(fully)g(w)o(ork)o(ed)g(V)m(ax)g(P)o(ascal)h(generic)h
+(set)f(pac)o(k)n(age)177 2567 y(implemen)o(ted)d(using)i(F)m(unnelW)m(eb)f
+(parameterized)h(macros.)21 b(The)15 b(pac)o(k)n(age)g(w)o(as)g(written)g(b)o
+(y)g(Barry)h(Dwy)o(er)177 2617 y(of)c(the)i(Computer)d(Science)k(Departmen)o
+(t)d(of)g(the)h(Univ)o(ersit)o(y)g(of)f(Adelaide)g(in)h(1987)e(and)i(w)o(as)f
+(emailed)f(to)i(me)177 2667 y(on)j(11)f(No)o(v)o(em)o(b)q(er)f(1987.)23
+b(The)16 b(generic)g(pac)o(k)n(age)f(pro)o(vides)h(a)f(set)i(abstraction)f
+(implemen)o(ted)d(using)i(link)o(ed)177 2717 y(lists.)j(Note)c(the)h(clev)o
+(er)g(use)f(of)g(the)g(instan)o(tiation)f(parameters)h(in)f(t)o(yp)q(e,)h
+(function,)f(and)h(pro)q(cedure)i(names.)177 2835 y Fl(@$@<Generic)k(Set)h
+(Module@>@\(@2@\)==@)o({@-)1042 2940 y Fr(59)p eop
+%%Page: 60 61
+60 60 bop 177 42 a Fl(@!)22 b(@1)f(is)g(the)g(base)g(type,)g(@2)h(is)f(the)g
+(set)g(type.)177 91 y([inherit)f(\('@1'\),)h(environment)e(\('@2'\)])177
+191 y(module)i(@2;)177 291 y(type)43 b(@2)21 b(=)h(^@2Record;)308
+340 y(@2Record)e(=)i(record)373 390 y(Member:)f(@1;)373 440
+y(Next:)g(@2;)373 490 y(end;)177 589 y(procedure)f(Null@2)h(\(var)g(Result:)f
+(@2\);)177 639 y(begin)h(new)g(\(Result\);)177 689 y(Result^.Member)e(:=)i
+(\(-)h(MaxInt\)::@1;)177 739 y(Result^.Next)d(:=)j(nil)f(end;)177
+839 y(function)f(IsNull@2)g(\(S:)i(@2\):)f(boolean;)177 888
+y(begin)g(IsNull@2)f(:=)h(S^.Member::integer)e(=)i(-)h(MaxInt)e(end;)177
+988 y(procedure)g(ForEach@1)g(\(S:)h(@2;)g(procedure)f(DoIt)h(\(i:)g(@1\)\);)
+177 1038 y(var)65 b(ThisS,)20 b(NextS:)h(@2;)177 1088 y(begin)g(ThisS)g(:=)g
+(S;)177 1137 y(while)g(ThisS^.Member::in)o(teger)d(<>)k(-)f(MaxInt)g(do)243
+1187 y(begin)f(NextS)h(:=)g(ThisS^.Next;)243 1237 y(DoIt)g(\(ThisS^.Member\))
+o(;)243 1287 y(ThisS)f(:=)i(NextS)e(end;)177 1337 y(end;)177
+1436 y(function)g(First@1)h(\(S:)g(@2\):)g(@1;)177 1486 y(begin)g(First@1)f
+(:=)i(S^.Member)e(end;)177 1586 y(function)g(Is@1InSet)g(\(i:)h(@1;)h(S:)f
+(@2\):)g(boolean;)243 1636 y(procedure)e(TestEquals)h(\(j:)h(@1\);)243
+1685 y(begin)f(if)i(Equal@1)e(\(i,)h(j\))h(then)f(Is@1InSet)e(:=)j(true;)f
+(end;)177 1735 y(begin)g(Is@1InSet)f(:=)h(false;)g(ForEach@1)f(\(S,)h
+(TestEquals\);)e(end;)177 1835 y(function)h(Includes@2)g(\(S1,)h(S2:)g(@2\):)
+g(boolean;)177 1885 y(var)g(Result:)g(boolean;)243 1934 y(procedure)e
+(TestIfInS1)h(\(i:)h(@1\);)243 1984 y(begin)f(if)i(Result)e(then)h(if)h(not)f
+(Is@1InSet)f(\(i,)h(S1\))g(then)g(Result)g(:=)g(false;)f(end;)177
+2034 y(begin)h(Result)f(:=)i(true;)177 2084 y(ForEach@1)e(\(S2,)h
+(TestIfInS1\);)177 2134 y(Includes@2)f(:=)h(Result)g(end;)177
+2233 y(function)f(Disjoint@2s)g(\(S1,)h(S2:)g(@2\):)g(boolean;)177
+2283 y(var)g(Result:)g(boolean;)243 2333 y(procedure)e(TestIfInS1)h(\(i:)h
+(@1\);)243 2383 y(begin)f(if)i(Result)e(then)h(if)h(Is@1InSet)e(\(i,)h(S1\))g
+(then)g(Result)f(:=)i(false;)e(end;)177 2433 y(begin)h(Result)f(:=)i(true;)
+177 2482 y(ForEach@1)e(\(S2,)h(TestIfInS1\);)177 2532 y(Disjoint@2s)f(:=)h
+(Result)g(end;)177 2632 y(function)f(Equal@2)h(\(S1,)g(S2:)g(@2\):)g
+(boolean;)177 2682 y(begin)177 2731 y(Equal@2)g(:=)g(Includes@2)f(\(S1,)h
+(S2\))g(and)g(Includes@2)f(\(S2,)h(S1\);)177 2781 y(end;)1042
+2940 y Fr(60)p eop
+%%Page: 61 62
+61 61 bop 177 42 a Fl(procedure)20 b(Insert@1)g(\(i:)h(@1;)h(var)f(S:)g
+(@2\);)177 91 y(var)65 b(This,)21 b(Pred,)f(Succ:)h(@2;)177
+141 y(begin)177 191 y(if)h(not)f(Is@1InSet)f(\(i,)h(S\))g(then)243
+241 y(begin)243 291 y(Pred)g(:=)g(nil;)g(Succ)g(:=)g(S;)243
+340 y(while)f(Succ^.Member::integ)o(er)f(>)i(i::integer)f(do)h(begin)308
+390 y(Pred)g(:=)g(Succ;)g(Succ)g(:=)g(Succ^.Next)f(end;)243
+440 y(if)h(Succ^.Member::int)o(eger)d(<)k(i::integer)e(then)h(begin)308
+490 y(new)g(\(This\);)f(This^.Next)g(:=)i(Succ;)e(This^.Member)g(:=)h(i;)308
+540 y(if)g(Pred)g(<>)h(nil)f(then)g(Pred^.Next)f(:=)h(This)g(else)g(S)g(:=)h
+(This;)308 589 y(end;)243 639 y(end;)177 689 y(end;)177 789
+y(procedure)e(Insert@1s)g(\(S1:)h(@2;)g(var)g(S2:)h(@2\);)177
+839 y(var)65 b(This,)21 b(Pred,)f(Succ:)h(@2;)243 888 y(procedure)e(Add@1)i
+(\(i:)g(@1\);)243 938 y(begin)f(Insert@1)g(\(i,)i(S2\))f(end;)177
+988 y(begin)177 1038 y(ForEach@1)f(\(S1,)h(Add@1\);)177 1088
+y(end;)177 1187 y(procedure)f(Remove@1)g(\(i:)h(@1;)h(var)f(S:)g(@2\);)177
+1237 y(var)65 b(Pred,)21 b(This:)f(@2;)177 1287 y(begin)177
+1337 y(Pred)h(:=)h(nil;)e(This)h(:=)h(S;)177 1386 y(while)f(not)g(Equal@1)f
+(\(This^.Member,)f(i\))j(do)f(begin)243 1436 y(Pred)g(:=)g(This;)g(This)g(:=)
+g(This^.Next)f(end;)177 1486 y(if)i(Pred)f(<>)g(nil)g(then)g(Pred^.Next)f(:=)
+h(This^.Next)f(else)h(S)g(:=)h(This^.Next;)177 1536 y(Dispose)f(\(This\);)177
+1586 y(end;)177 1685 y(procedure)f(Dispose@2)g(\(var)h(S:)g(@2\);)177
+1735 y(var)65 b(Old:)21 b(@2;)177 1785 y(begin)177 1835 y(while)g(S)h(<>)f
+(nil)g(do)g(begin)g(Old)g(:=)h(S;)f(S)h(:=)f(S^.Next;)f(Dispose)h(\(Old\))f
+(end;)177 1885 y(end;)177 1984 y(end.)177 2034 y(@})177 2134
+y(@O@<NaryTreeSet.pa)o(s@>==)o(@{@-)221 2183 y(@<Generic)g(Set)h
+(Module@>@\(@"NaryT)o(ree@")o(@,@")o(NaryT)o(reeSe)o(t@"@\))o(@})177
+2233 y(@O@<NaryTreeSetSet)o(.pas@)o(>==@{)o(@-)221 2283 y(@<Generic)f(Set)h
+(Module@>@\(@"NaryT)o(reeSe)o(t@"@)o(,@"Na)o(ryTre)o(eSetS)o(et@"@)o(\)@})177
+2408 y Fr(A)12 b(great)h(adv)n(an)o(tage)e(of)g(the)i(approac)o(h)f
+(re\015ected)i(in)e(the)g(ab)q(o)o(v)o(e)g(example)f(is)h(that)g(it)g(allo)o
+(ws)e(the)j(programmer)177 2458 y(to)f(construct)i(a)d(generic)i(ob)r(ject)g
+(in)f(a)f(language)h(that)g(do)q(es)g(not)g(supply)g(generics,)h
+Fm(with)g(c)n(omplete)g(typ)n(esafety.)177 2507 y Fr(This)g(con)o(trasts)h
+(to)e(the)i(approac)o(h)e(that)h(migh)o(t)e(b)q(e)i(used)h(in)e(a)h(language)
+f(suc)o(h)h(as)g(C)g(where)h(the)f(programmer)177 2557 y(migh)o(t)e(c)o(ho)q
+(ose)i(to)g(construct)h(a)e(\\generic")h(pac)o(k)n(age)f(b)o(y)h
+(parameterizing)f(a)g(pac)o(k)n(age)g(with)g(p)q(oin)o(ters)i(to)e
+Fl(void)p Fr(.)177 2607 y(The)i(resulting)f(pac)o(k)n(age)g(is)g(p)q(o)o(w)o
+(erful)g(but)g(extremely)g(un)o(t)o(yp)q(esafe.)18 b(Suc)o(h)c(a)f(generic)h
+(list)e(pac)o(k)n(age)h(is)g(used)h(in)177 2657 y(the)f(co)q(de)h(of)e(F)m
+(unnelW)m(eb)g(itself)g(and)h(caused)h(no)e(end)h(of)f(problems,)g(as)g(the)i
+(compiler)d(had)h(no)h(w)o(a)o(y)f(of)g(telling)177 2707 y(if)19
+b(p)q(oin)o(ters)h(to)f(the)h(correctly)h(t)o(yp)q(ed)f(ob)r(ject)g(w)o(ere)h
+(b)q(eing)e(handed)h(to)g(the)g(correct)h(list-ob)r(ject/function)177
+2757 y(com)o(bination.)177 2835 y(The)e(ma)r(jor)f(disadv)n(an)o(tage)g(of)g
+(the)h(text)h(generic)g(approac)o(h)e(is)h(that)g(it)g(causes)h(the)f(co)q
+(de)h(of)e(the)i(generic)1042 2940 y(61)p eop
+%%Page: 62 63
+62 62 bop 177 42 a Fr(ob)r(ject)19 b(to)f(b)q(e)h(duplicated)f(once)h(for)e
+(eac)o(h)i(instan)o(tiation.)29 b(Dep)q(ending)19 b(on)f(the)g(n)o(um)o(b)q
+(er)g(and)g(size)h(of)e(the)177 91 y(instan)o(tiations,)c(this)h(ma)o(y)d(or)
+j(ma)o(y)e(not)i(b)q(e)h(acceptable.)177 166 y(Where)22 b(the)f(duplication)f
+(of)g(co)q(de)h(is)g(unacceptable,)i(a)d(h)o(ybrid)h(approac)o(h)f(ma)o(y)f
+(b)q(e)i(tak)o(en.)39 b(As)21 b(in)f(the)177 216 y(C)c(example,)e(the)i
+(programmer)d(could)i(write)h(a)f(single)g(generic)h(pac)o(k)n(age)f(using)g
+(p)q(oin)o(ters)h(to)g Fl(void)e Fr(or)i(some)177 266 y(other)g(un)o(t)o(yp)q
+(esafe)g(mec)o(hanism.)j(Then)d(the)g(programmer)d(creates)k(a)e(F)m(unnelW)m
+(eb)f(generic)i(pac)o(k)n(age)f(whose)177 315 y(functions)g(do)f(nothing)f
+(more)h(than)g(call)g(the)h(functions)f(of)g(the)h(un)o(t)o(yp)q(esafe)g(pac)
+o(k)n(age,)f(and)g(whose)h(t)o(yp)q(es)g(do)177 365 y(nothing)f(more)g(than)g
+(con)o(tain)g(the)h(t)o(yp)q(es)h(of)d(the)j(un)o(t)o(yp)q(esafe)f(pac)o(k)n
+(age.)k(This)c(solution)e(in)o(v)o(olv)o(es)h(the)h(use)g(of)177
+415 y(un)o(t)o(yp)q(esafe)i(programmi)o(ng,)c(but)j(this)g(is)g(a)g
+(one-o\013)g(and)g(if)f(done)h(carefully)g(and)g(correctly)m(,)g(the)h
+(result)g(can)177 465 y(b)q(e)e(a)e(t)o(yp)q(esafe)i(generic)g(pac)o(k)n(age)
+e(in)o(v)o(olving)f(minim)o(al)e(co)q(de)15 b(duplication.)177
+627 y Fi(2.14)70 b(Summary)177 743 y Fr(This)16 b(c)o(hapter)h(has)f(describ)
+q(ed)i(some)d(of)h(the)g(\014ner)h(asp)q(ects)h(of)d(the)i(use)g(of)e(F)m
+(unnelW)m(eb.)24 b(Throughout,)16 b(the)177 793 y(p)q(o)o(w)o(er)f(and)f
+(danger)g(of)g(F)m(unnelW)m(eb)f(as)h(a)g(general)h(text-rearranging)f
+(prepro)q(cessor)j(has)d(b)q(een)i(emphasised.)177 843 y(F)m(unnelW)m(eb)g
+(can)g(b)q(e)h(used)g(b)q(oth)f(to)g(mak)o(e)e(programs)h(more)g(readable)h
+(or)g(more)f(obscure.)26 b(It)16 b(is)g(up)g(to)g(the)177 892
+y(programmer)c(to)h(ensure)j(that)e(F)m(unnelW)m(eb)f(is)h(used)h(prop)q
+(erly)m(.)1042 2940 y(62)p eop
+%%Page: 63 64
+63 63 bop 177 372 a Fj(Chapter)34 b(3)177 598 y Fp(F)-10 b(unnelW)g(eb)41
+b(De\014nition)177 858 y Fi(3.1)70 b(In)n(tro)r(duction)177
+968 y Fr(This)15 b(purp)q(ose)h(of)e(this)h(c)o(hapter)g(is)g(to)g(pro)o
+(vide)f(a)h(complete)f(and)g(consisten)o(t)i(de\014nition)f(of)f(the)h(F)m
+(unnelW)m(eb)177 1018 y(input)h(language)e(and)i(the)g(b)q(eha)o(viour)f(of)g
+(the)h(F)m(unnelW)m(eb)f(program.)22 b(Usually)m(,)14 b(a)i(c)o(hapter)g(suc)
+o(h)h(as)e(this)h(is)177 1068 y(called)c(a)g(\\reference)i(man)o(ual",)9
+b(but)j(this)g(c)o(hapter)h(is)f(in)o(tended)g(to)g(go)g(further)g(b)o(y)g
+(actually)f(de\014ning)h(the)h(lan-)177 1118 y(guage)f(and)f(program.)16
+b(This)c(c)o(hapter)g(tak)o(es)g(precedence)j(o)o(v)o(er)d(all)e(other)j(c)o
+(hapters)g(and)e(all)g(implemen)o(tatio)o(ns)177 1167 y(of)i(F)m(unnelW)m
+(eb.)18 b(If)13 b(an)h(implemen)o(tation)c(con)o(tradicts)15
+b(this)f(c)o(hapter,)g(then)h(the)g(implem)o(en)o(tation)c(is)j(wrong.)177
+1236 y(This)j(is)g(the)h(c)o(hapter)h(that)e(y)o(ou)g(should)g(turn)g(if)g(y)
+o(ou)g(\014nd)g(y)o(ourself)g(asking)g(a)g(sp)q(eci\014c)h(question)g(ab)q
+(out)f(a)177 1286 y(sp)q(eci\014c)g(asp)q(ect)f(of)f(F)m(unnelW)m(eb.)21
+b(In)15 b(man)o(y)e(cases)k(it)e(will)e(b)q(e)j(con)o(v)o(enien)o(t)g(to)e
+(access)j(this)f(c)o(hapter)g(through)177 1336 y(the)f(index.)177
+1490 y Fi(3.2)70 b(Notation)177 1600 y Fr(A)17 b(particular)g(v)n(arian)o(t)f
+(of)g(EBNF)i(\(Extended)g(Bac)o(h)o(us)g(Naur)f(F)m(orm\))e(will)h(b)q(e)h
+(used)h(to)f(describ)q(e)i(the)e(F)m(un-)177 1649 y(nelW)m(eb)h(syn)o(tax.)32
+b(In)18 b(this)g(v)n(arian)o(t,)g(literal)g(strings)g(are)h(delimited)e(b)o
+(y)h(double)g(quotes)h(\(e.g.)f Fl("string")p Fr(\),)177 1699
+y(optional)d(constructs)j(b)o(y)f(square)g(brac)o(k)o(ets)g(\(e.g.)f
+Fl([optional])p Fr(\),)e(and)j(constructs)h(rep)q(eated)g(zero)f(or)g(more)
+177 1749 y(times)i(b)o(y)g(braces)i(\(e.g.)e Fq(f)p Fl(zeroormore)p
+Fq(g)p Fr(\).)33 b(Constructs)21 b(to)e(b)q(e)h(rep)q(eated)i(a)d(\014xed)h
+(n)o(um)o(b)q(er)f(of)g(times)f(are)177 1799 y(enclosed)g(in)e(braces)h
+(follo)o(w)o(ed)e(b)o(y)i(a)f(decimal)e(n)o(um)o(b)q(er)i(indicating)g(the)h
+(n)o(um)o(b)q(er)e(of)h(times)g(to)g(b)q(e)h(rep)q(eated)177
+1849 y(\(e.g.)d Fq(f)p Fl(sixtimes)p Fq(g)p Fl(6)p Fr(\).)19
+b(Constructs)e(to)e(b)q(e)g(rep)q(eated)i(one)e(or)g(more)f(times)g(are)h
+(enclosed)h(in)f(braces)h(and)f(fol-)177 1899 y(lo)o(w)o(ed)e(b)o(y)h(a)f
+Fl(+)h Fr(\(e.g.)f Fq(f)p Fl(oneormore)p Fq(g)p Fl(+)p Fr(\).)j(The)e
+(traditional)e(BNF)j(\\)p Fl(::=)p Fr(")d(is)i(replaced)h(b)o(y)e(the)i
+(visually)d(simpler)177 1948 y(\\)p Fl(=)p Fr(".)17 b(The)e(traditional)d
+(BNF)j(angle)e(brac)o(k)o(ets)i(are)f(abandoned.)177 2017 y(Although)c(F)m
+(unnelW)m(eb)g(allo)o(ws)f(the)i(sp)q(ecial)g(c)o(haracter)g(to)g(b)q(e)g(c)o
+(hanged)f(using)h(the)g(construct)h(\\)p Fn(<)p Fr(sp)q(ecial)p
+Fn(>)p Fr(=",)177 2067 y(use)19 b(of)f(\\)p Fn(<)p Fr(sp)q(ecial)p
+Fn(>)p Fr(")h(to)f(refer)h(to)g(F)m(unnelW)m(eb's)e(sp)q(ecial)i(c)o
+(haracter)h(is)e(cum)o(b)q(ersome)f(and)h(abstract.)33 b(T)m(o)177
+2117 y(simplify)17 b(the)i(presen)o(tation,)i(the)f(default)f(sp)q(ecial)g(c)
+o(haracter)i(\\)p Fl(@)p Fr(")d(is)h(used)h(throughout)g(this)f(c)o(hapter)h
+(to)177 2167 y(represen)o(t)c(the)f(sp)q(ecial)f(c)o(haracter.)177
+2320 y Fi(3.3)70 b(T)-6 b(erminology)177 2430 y Fr(A)14 b(sp)q(eci\014c)i
+(terminology)c(has)i(arisen)h(for)f(dealing)f(with)h(F)m(unnelW)m(eb.)k(Some)
+13 b(particularly)g(useful)i(examples)177 2480 y(are:)295 2549
+y Fo(Journal)10 b(\014le:)16 b Fr(An)11 b(output)g(\014le)g(con)o(taining)f
+(a)g(cop)o(y)h(of)f(the)i(output)f(sen)o(t)g(to)g(the)h(user's)f(console)295
+2599 y(during)j(an)h(in)o(v)o(o)q(cation)e(of)h(F)m(unnelW)m(eb.)19
+b(In)c(other)g(systems,)f(this)h(\014le)g(is)f(sometimes)f(called)h(a)295
+2649 y(\\log)f(\014le".)295 2718 y Fo(Pro)q(duct)19 b(\014le:)24
+b Fr(An)18 b(output)g(\014le,)g(generated)h(b)o(y)e(the)h(T)m(angle)f(comp)q
+(onen)o(t)g(of)g(F)m(unnelW)m(eb,)295 2767 y(that)d(con)o(tains)g(the)h
+(expansion)e(of)h(the)g(macros)f(in)h(the)g(input)g(\014le.)1368
+2752 y Fg(1)p 177 2796 709 2 v 223 2823 a Ff(1)241 2835 y Fh(Other)d(names)f
+(considered)e(for)j(this)g(w)o(ere:)k(generated)9 b(\014le,)i(expanded)d
+(\014le,)j(result)f(\014le,)h(program)e(\014le,)i(and)f(tangle)g(\014le.)1042
+2940 y Fr(63)p eop
+%%Page: 64 65
+64 64 bop 177 42 a Fr(A)14 b(complete)f(list)g(of)g(all)f(the)j(sp)q(ecial)f
+(F)m(unnelW)m(eb)f(terminology)e(app)q(ears)k(in)e(the)h(glossary)m(.)j(Be)e
+(sure)f(to)g(refer)177 91 y(to)g(it)f(if)g(an)o(y)h(of)f(the)i(terms)e(used)i
+(are)f(unclear.)177 250 y Fi(3.4)70 b(An)23 b(Arc)n(hitectural)d(Ov)n(erview)
+177 363 y Fr(An)e(understanding)f(of)g(the)h(in)o(ternals)f(of)g(F)m(unnelW)m
+(eb)f(assists)j(with)d(understanding)i(its)f(op)q(eration)h(\()p
+Fo(Fig-)177 413 y(ure)d(3)p Fr(\).)177 485 y(During)h(a)h(single)g(run,)g(F)m
+(unnelW)m(eb)g(reads)h(and)e(pro)q(cesses)k(a)d(single)f(input)h(\014le)g
+(called)g(the)g Fo(input)g(\014le)f Fr(or)177 535 y(the)e Fo(F)l(unnelW)l(eb)
+f(\014le)p Fr(.)k(The)d(\014le)g(is)f(pro)q(cessed)j(b)o(y)d(passing)h(it)f
+(through)h(a)f(series)i(of)e(stages)h(called)g Fo(phases)p
+Fr(.)177 585 y(The)19 b(result)f(is)g(that)g(some)g Fo(output)g(\014les)e
+Fr(are)j(generated.)32 b(A)18 b Fo(journal)g(\014le)f Fr(is)h(generated)h
+(con)o(taining)e(a)177 635 y(cop)o(y)h(of)g(the)g(messages)g(that)h(app)q
+(ear)f(on)g(the)h(console)f(during)g(the)g(F)m(unnelW)m(eb)g(run.)31
+b(A)18 b Fo(listing)f(\014le)g Fr(is)177 685 y(created)d(con)o(taining)e(a)h
+(summary)d(of)i(the)i(run,)f(including)e(an)o(y)i(error)g(messages.)18
+b(A)13 b Fo(do)q(cumen)o(tation)c Fr(\014le)k(is)177 734 y(generated)j(con)o
+(taining)d(t)o(yp)q(esetter)j(commands)c(that)j(when)f(fed)h(in)o(to)e(a)h(t)
+o(yp)q(esetter)j(program)12 b(will)h(result)i(in)177 784 y(prin)o(ted)f(do)q
+(cumen)o(tation.)i(Finally)m(,)11 b(one)j(or)f(more)f Fo(pro)q(duct)h
+(\014les)f Fr(are)i(generated)g(con)o(taining)f(the)g(result)h(of)177
+834 y(unscram)o(bling)e(the)j(macro)d(de\014nitions)i(of)g(the)g(input)g
+(\014le.)177 906 y(These)h(\014les)g(need)g(not)f(all)f(b)q(e)h(generated)i
+(on)d(an)o(y)h(particular)g(F)m(unnelW)m(eb)f(run.)19 b(Whether)c(eac)o(h)g
+(output)f(\014le)177 956 y(app)q(ears)h(is)f(con)o(trolled)f(b)o(y)h(command)
+d(line)i(options.)373 1103 y Fl(.fw)21 b(Input)g(File)g(\(FunnelWeb)f(file\))
+635 1153 y(V)526 1202 y(+---------+)390 b(\\)526 1252 y(|)21
+b(Scanner)g(|)392 b(|)526 1302 y(+---------+)e(|)635 1352 y(V)501
+b(|)526 1402 y(+--------+)412 b(|)526 1451 y(|)21 b(Parser)g(|)414
+b(|)526 1501 y(+--------+)e(|)635 1551 y(V)501 b(|)526 1601
+y(+----------+)368 b(>-------+--------)o(----+)526 1651 y(|)21
+b(Analyser)g(|)370 b(|)152 b(|)262 b(|)526 1701 y(+----------+)368
+b(|)152 b(|)262 b(|)635 1750 y(V)501 b(|)152 b(|)262 b(|)373
+1800 y(+-----------+------)o(-----)o(-+)215 b(|)152 b(V)262
+b(V)373 1850 y(V)523 b(V)218 b(|)152 b(|)262 b(|)286 1900 y(+--------+)325
+b(+-------+)129 b(|)152 b(|)262 b(|)286 1950 y(|)22 b(Tangle)e(|)327
+b(|)22 b(Weave)e(|)131 b(|)152 b(|)262 b(|)286 1999 y(+--------+)325
+b(+-------+)129 b(/)152 b(|)262 b(|)373 2049 y(|)523 b(|)392
+b(|)262 b(|)373 2099 y(V)523 b(V)392 b(V)262 b(V)243 2149 y(Product)20
+b(Files)195 b(Documentation)19 b(File)86 b(Listing)21 b(File)43
+b(Journal)20 b(File)343 2290 y Fh(F)m(unnelW)m(eb)9 b(pro)q(cesses)g(eac)o(h)
+g(input)g(\014le)h(in)h(a)f(sequence)e(of)j(phases.)i(If)e(an)f(error)f(o)q
+(ccurs)g(during)g(a)i(phase,)e(no)281 2340 y(subsequen)o(t)g(phases)h(are)h
+(executed.)673 2431 y Fo(Figure)j(3)p Fr(:)k(F)m(unnelW)m(eb's)13
+b(pro)q(cessing)i(phases.)177 2541 y(The)f(phases)h(are)g(brie\015y)f
+(describ)q(ed)i(b)q(elo)o(w.)295 2613 y Fo(The)e(Scanner)c
+Fr(reads)j(the)g(input)f(\014le,)g(expands)h(and)f(reads)h(in)e(include)i
+(\014les,)f(scans)h(the)g(input)295 2663 y(stream,)k(pro)q(cesses)i(pragmas)d
+(and)g(t)o(yp)q(esetter)j(directiv)o(es,)f(and)f(parses)h(all)e(the)h(F)m
+(unnelW)m(eb)295 2713 y(sp)q(ecial)d(sequences.)21 b(The)14
+b(result)h(is)f(a)f(list)h(of)f(tok)o(ens)h(that)g(is)g(handed)g(to)g(the)h
+(parser.)295 2785 y Fo(The)k(P)o(arser)d Fr(reads)i(the)g(scanner's)g(tok)o
+(en)f(list)g(and)g(parses)h(it,)f(constructing)h(a)f(do)q(cumen)o(t)295
+2835 y(list)d(and)f(a)h(macro)f(table.)18 b(whic)o(h)13 b(are)i(passed)g(to)e
+(later)h(phases.)1042 2940 y(64)p eop
+%%Page: 65 66
+65 65 bop 295 42 a Fo(The)20 b(Analyser)c Fr(examines)g(the)i(macro)e(table)i
+(generated)g(b)o(y)f(the)h(parser)h(and)e(p)q(erforms)g(a)295
+91 y(n)o(um)o(b)q(er)12 b(of)f(c)o(hec)o(ks)j(of)d(the)i(macro)e(structures)k
+(that)d(the)h(parser)g(could)f(not)g(mak)o(e)f(on)h(its)g(single)295
+141 y(pass.)17 b(F)m(or)10 b(example,)f(the)h(analyser)g(detects)i(and)e
+(\015ags)g(un)o(used)h(macros)e(and)h(recursiv)o(e)h(macros.)295
+191 y(The)k(analyser)f(forms)e(the)j(\014nal)e(stage)h(of)f(F)m(unnelW)m
+(eb's)h(fron)o(t-end)g(pro)q(cessing.)295 260 y Fo(T)l(angle)g
+Fr(expands)g(certain)h(macros)f(in)g(the)h(macro)e(table)h(to)g(generate)i
+(one)e(or)g(more)g(pro)q(duct)295 309 y(\014les.)295 378 y
+Fo(W)l(ea)o(v)o(e)g Fr(uses)h(the)g(do)q(cumen)o(t)e(list)g(to)h(generate)h
+(a)f(do)q(cumen)o(tation)f(\014le.)177 447 y(A)i(single)g(run)h(through)f
+(these)i(phases)f(constitutes)h(a)e(single)g(in)o(v)o(o)q(cation)e(of)i
+Fo(F)l(unnelW)l(eb)g(prop)q(er)p Fr(.)20 b(Most)177 496 y(in)o(v)o(o)q
+(cations)d(of)h(the)h Fo(F)l(unnelW)l(eb)f(program)e Fr(will)h(consist)i
+(only)e(of)g(a)h(single)g(execution)h(of)e(F)m(unnelW)m(eb)177
+546 y(prop)q(er.)h(Ho)o(w)o(ev)o(er,)12 b(F)m(unnelW)m(eb)f(also)g(pro)o
+(vides)g(a)g(command)e(shell)i(that)g(pro)o(vides)h(man)o(y)d(useful)j
+(commands,)177 596 y(including)j(a)g(command)f(to)h(in)o(v)o(ok)o(e)g(F)m
+(unnelW)m(eb)g(prop)q(er.)25 b(Discussion)16 b(of)f(the)i(command)c(shell)i
+(is)h(deferred)177 646 y(un)o(til)d(Section)h(3.15.)177 799
+y Fi(3.5)70 b(Diagnostics)177 909 y Fr(During)16 b(execution,)h(F)m(unnelW)m
+(eb)f(pro)q(ceeds)j(cautiously)d(with)g(eac)o(h)h(of)f(its)g(phases,)i(only)e
+(pro)q(ceeding)h(with)177 959 y(the)i(next)g(phase)f(if)g(the)g(previous)h
+(phase)g(has)f(b)q(een)h(successful.)33 b(This)18 b(means)f(that,)i(when)f
+(debugging)g(a)177 1009 y(F)m(unnelW)m(eb)d(\014le,)h(y)o(ou)f(ma)o(y)e
+(\014nd)j(that)g(the)g(n)o(um)o(b)q(er)f(of)g(errors)i Fm(incr)n(e)n(ases)e
+Fr(after)h(y)o(ou)f(\014x)g(some)g(of)g(them,)g(as)177 1059
+y(y)o(ou)f(will)e(b)q(e)i(exp)q(osing)g(y)o(ourself)g(to)g(the)g(next)h(F)m
+(unnelW)m(eb)e(phase.)177 1127 y(F)m(unnelW)m(eb)i(emplo)o(ys)g(\014v)o(e)h
+(lev)o(els)g(of)f(diagnostics)h(at)f(di\013eren)o(t)i(lev)o(els)f(of)f(sev)o
+(erit)o(y)m(.)24 b(Sev)o(erit)o(y)17 b(is)e(de\014ned)i(in)177
+1177 y(terms)d(of)f(the)i(lev)o(el)e(of)g(activit)o(y)g(at)h(whic)o(h)g(the)g
+(diagnostic)g(causes)h(F)m(unnelW)m(eb)e(to)h(ab)q(ort.)295
+1246 y Fo(W)l(arning:)i Fr(A)c(w)o(arning)f(do)q(es)h(not)g(cause)h(F)m
+(unnelW)m(eb)e(to)g(terminate)g(or)h(curtail)f(its)h(op)q(eration)295
+1295 y(in)h(an)o(y)f(w)o(a)o(y)m(,)f(but)i(serv)o(es)h(merely)e(to)h(w)o(arn)
+f(the)i(user)g(of)e(particular)g(conditions)h(that)f(migh)o(t)f(b)q(e)295
+1345 y(symptomatic)g(of)j(deep)q(er)h(problems.)295 1414 y
+Fo(Error:)k Fr(An)c(error)h(causes)f(F)m(unnelW)m(eb)f(to)h(terminate)f(pro)q
+(cessing)h(of)f(the)h(curren)o(t)h(input)f(\014le)295 1464
+y(at)d(the)g(end)g(of)f(the)h(curren)o(t)h(phase.)18 b(F)m(or)11
+b(example,)g(if)f(an)i(error)g(o)q(ccurs)h(during)f(scanning,)f(F)m(un-)295
+1514 y(nelW)m(eb)k(will)f(con)o(tin)o(ue)i(scanning)f(\(and)g(p)q(ossibly)g
+(generate)i(further)f(scanning)f(diagnostics\),)295 1563 y(but)f(will)f(not)h
+(in)o(v)o(ok)o(e)f(the)h(parser.)295 1632 y Fo(Sev)o(ere)h(Error:)k
+Fr(A)c(sev)o(ere)h(error)f(\(or)f(\\sev)o(ere")i(for)e(short\))h(is)f(the)h
+(same)e(as)i(an)f(error)h(except)295 1682 y(that)f(F)m(unnelW)m(eb)g
+(terminates)f(the)i(curren)o(t)g(phase)g(imm)o(ediately)m(.)295
+1750 y Fo(F)l(atal)d(Error:)k Fr(A)11 b(fatal)e(error)j(causes)g(F)m(unnelW)m
+(eb)e(not)h(only)f(to)g(terminate)h(the)g(curren)o(t)h(phase)295
+1800 y(and)h(run)g(imm)o(ediately)m(,)c(but)k(also)f(to)g(terminate)g(total)g
+(F)m(unnelW)m(eb)g(pro)q(cessing)i(immediately)l(.)295 1850
+y(A)g(sev)o(ere)i(error)f(will)d(not)i(cause)h(a)e(F)m(unnelW)m(eb)g(script)i
+(to)f(terminate,)f(but)h(a)f(fatal)g(error)i(will.)295 1900
+y(A)f(fatal)f(error)i(causes)g(F)m(unnelW)m(eb)e(to)h(return)h(con)o(trol)f
+(to)g(the)g(op)q(erating)g(system.)295 1969 y Fo(Assertion)e(Error:)17
+b Fr(An)c(assertion)g(error)h(o)q(ccurs)g(if)e(F)m(unnelW)m(eb)g(detects)i
+(an)f(in)o(ternal)f(incon-)295 2018 y(sistency)m(,)h(in)f(whic)o(h)g(case)h
+(F)m(unnelW)m(eb)e(terminates)h(immediately)d(and)j(ungracefully)m(.)k(Suc)o
+(h)d(an)295 2068 y(error)j(can)g(o)q(ccur)g(only)e(if)h(there)h(are)g(bugs)f
+(in)g(F)m(unnelW)m(eb.)22 b(With)14 b(luc)o(k,)h(suc)o(h)h(errors)g(will)e(b)
+q(e)295 2118 y(extremely)g(rare.)177 2187 y(F)m(unnelW)m(eb)c(indicates)g
+(the)h(lev)o(el)e(of)h(sev)o(erit)o(y)h(of)e(eac)o(h)i(diagnostic)e(that)h
+(it)g(issues)h(b)o(y)f(starting)g(eac)o(h)g(diagnostic)177
+2236 y(either)h(with)f(the)h(full)e(name)g(of)h(the)h(sev)o(erit)o(y)f(lev)o
+(el)g(or)h(with)f(just)g(the)h(\014rst)g(letter)g(of)f(the)h(sev)o(erit)o(y)f
+(lev)o(el)g(follo)o(w)o(ed)177 2286 y(b)o(y)k(a)f(colon.)177
+2355 y(F)m(unnelW)m(eb)f(con)o(v)o(eys)h(the)f(presence)j(or)d(absence)i(of)d
+(diagnostics)h(at)g(the)h(op)q(erating)f(system)g(lev)o(el)g(b)o(y)g(return-)
+177 2405 y(ing)g Fl(EXIT)p 336 2405 14 2 v 15 w(SUCCESS)f Fr(status)i(if)f
+(no)g(diagnostics)g(o)q(ccurred)i(during)f(the)g(run)f(and)h
+Fl(EXIT)p 1552 2405 V 15 w(FAILURE)e Fr(status)i(if)f(one)177
+2454 y(or)i(more)f(diagnostics)h(\(including)f(w)o(arnings\))g(o)q(ccurred)j
+(during)d(the)i(run.)1378 2439 y Fg(2)177 2608 y Fi(3.6)70
+b(T)n(yp)r(esetter)21 b(Indep)r(endence)177 2718 y Fr(One)16
+b(of)f(the)g(design)h(goals)e(of)g(F)m(unnelW)m(eb)h(w)o(as)g(to)g(pro)o
+(vide)g(a)g Fm(tar)n(get-language)g Fr(indep)q(enden)o(t)i(literate)e(pro-)
+177 2768 y(gramming)9 b(system.)18 b(This)12 b(goal)g(has)h(b)q(een)h(ac)o
+(hiev)o(ed)f(simply)e(b)o(y)i(treating)f(the)i(text)f(written)h(to)e(the)i
+(pro)q(duct)p 177 2796 709 2 v 223 2823 a Ff(2)241 2835 y Fh(F)m(rom)c(the)h
+(sym)o(b)q(ols)f(of)h(the)g(ANSI)h(standard)d(C)j(library)e
+Fe(stdlib.h)p Fh(.)i(See)f Fb([Kernighan88])p Fh(,)g(p.252.)1042
+2940 y Fr(65)p eop
+%%Page: 66 67
+66 66 bop 177 42 a Fr(\014le)15 b(as)g(homogeneous)f(and)h(t)o(yp)q(esetting)
+h(it)f(in)g Fl(tt)21 b(font)p Fr(.)g(A)15 b(secondary)h(goal)e(w)o(as)h(to)g
+(pro)o(vide)g(a)f Fm(typ)n(esetter)177 91 y Fr(indep)q(enden)o(t)i(literate)f
+(programming)d(system.)21 b(By)15 b(this)g(is)f(mean)o(t)g(that)h(it)f(b)q(e)
+i(p)q(ossible)f(to)g(create)h(F)m(unnel-)177 141 y(W)m(eb)d(input)g(\014les)h
+(that)f(do)g(not)h(con)o(tain)e(t)o(yp)q(esetter-sp)q(e)q(ci\014c)k
+(commands.)g(T)m(o)c(a)h(lesser)i(exten)o(t)f(this)g(goal)e(has)177
+191 y(also)h(b)q(een)i(ac)o(hiev)o(ed.)177 272 y(The)h(di\016cult)o(y)f(with)
+h(pro)o(viding)f(t)o(yp)q(esetter-indep)q(enden)o(t)k(t)o(yp)q(esetting)e(is)
+f(that)f(eac)o(h)i(desired)g(t)o(yp)q(esetting)177 322 y(feature)d(m)o(ust)e
+(b)q(e)h(recreated)j(in)c(a)h(t)o(yp)q(esetter-indep)q(enden)o(t)j(F)m
+(unnelW)m(eb)d(t)o(yp)q(esetting)h(construct)g(that)f(F)m(un-)177
+372 y(nelW)m(eb)f(can)f(translate)i(in)o(to)e(whatev)o(er)h(t)o(yp)q
+(esetting)h(language)d(is)i(b)q(eing)g(targeted)g(b)o(y)g(W)m(ea)o(v)o(e.)k
+(T)m(ak)o(en)c(to)f(the)177 422 y(extreme,)j(this)g(w)o(ould)g(result)h(in)e
+(F)m(unnelW)m(eb)h(pro)o(viding)f(the)i(full)e(syn)o(tactic)i(and)f(seman)o
+(tic)f(p)q(o)o(w)o(er)h(of)g(T)1883 431 y(E)1906 422 y(X,)177
+472 y(but)k(with)e(a)h(more)f(generic,)j(F)m(unnelW)m(eb-sp)q(eci\014c)f(syn)
+o(tax.)27 b(This)17 b(w)o(as)g(unfeasible)g(in)g(the)h(time)d(a)o(v)n
+(ailable,)177 521 y(and)f(undesirable)g(as)g(w)o(ell.)177 603
+y(The)22 b(compromise)e(struc)o(k)i(in)g(the)g(F)m(unnelW)m(eb)f(design)h(is)
+f(to)h(pro)o(vide)f(a)h(set)g(of)f(primitiv)o(e)f(t)o(yp)q(esetter-)177
+653 y(indep)q(enden)o(t)15 b(t)o(yp)q(esetting)f(features)h(that)f(are)g
+(implem)o(en)o(ted)e(b)o(y)h(F)m(unnelW)m(eb.)k(These)e(are)f(the)g
+Fo(t)o(yp)q(esetter)177 702 y(directiv)o(es)p Fr(.)32 b(If)20
+b(the)g(user)h(is)e(prepared)i(to)f(restrict)h(to)e(these)i(directiv)o(es,)h
+(then)e(the)h(user's)f(F)m(unnelW)m(eb)177 752 y(do)q(cumen)o(t)c(will)f(b)q
+(e)h(b)q(oth)h(target-language)e(and)h(t)o(yp)q(esetter)j(indep)q(enden)o(t.)
+26 b(Ho)o(w)o(ev)o(er,)17 b(if)e(the)i(user)g(wishes)177 802
+y(to)f(use)h(the)f(more)f(sophisticated)i(features)g(of)e(the)i(target)f(t)o
+(yp)q(esetting)h(system,)f(the)g(user)h(can)g(sp)q(ecify)f(the)177
+852 y(t)o(yp)q(esetter)g(in)d(a)h(\\)p Fl(typesetter)p Fr(")d(pragma)h(and)h
+(then)i(place)e(t)o(yp)q(esetter)k(commands)11 b(in)i(the)h(free)h(text)f(of)
+f(the)177 902 y(F)m(unnelW)m(eb)i(do)q(cumen)o(t)g(where)i(they)f(will)e(b)q
+(e)i(passed)g(v)o(erbatim)e(to)h(the)h(do)q(cumen)o(tation)f(\014le.)22
+b(The)16 b(c)o(hoice)177 952 y(of)d(the)i(trade-o\013)f(b)q(et)o(w)o(een)i(t)
+o(yp)q(esetter)g(indep)q(endence)g(and)e(t)o(yp)q(esetting)g(p)q(o)o(w)o(er)h
+(is)e(left)h(to)g(the)g(user.)177 1033 y(This)g(said,)f(exp)q(erience)k(with)
+c(F)m(unnelW)m(eb)h(V1)g(o)o(v)o(er)g(a)f(three)j(y)o(ear)e(p)q(erio)q(d,)g
+(indicates)g(that)g(the)h(t)o(yp)q(esetting)177 1083 y(facilities)e(pro)o
+(vided)h(b)o(y)f(F)m(unnelW)m(eb)h(are)g(su\016cien)o(t)g(for)g(most)f(do)q
+(cumen)o(tation.)177 1266 y Fi(3.7)70 b(Command)22 b(Line)g(In)n(terface)177
+1400 y Fd(3.7.1)55 b(In)n(v)n(oking)19 b(F)-5 b(unnelW)g(eb)177
+1511 y Fr(When)14 b(a)f(user)i(in)o(v)o(ok)o(es)e(F)m(unnelW)m(eb)g(at)g(the)
+h(op)q(erating)g(system)f(command)e(lev)o(el,)h(the)j(user)f(m)o(ust)f(pro)o
+(vide)g(a)177 1561 y(command)g(line)j(instructing)g(F)m(unnelW)m(eb)g(what)g
+(to)g(do.)24 b(T)o(ypically)14 b(an)i(op)q(erating)g(system)g(command)d(line)
+177 1610 y(consists)h(of)e(a)h Fm(verb)g Fr(indicating)e(that)i(a)g
+(particular)g(program)e(should)i(b)q(e)g(run,)g(follo)o(w)o(ed)f(b)o(y)g(a)h
+(list)f(of)h(options.)177 1660 y(F)m(or)h(example:)177 1793
+y Fl($)22 b(rename)e(file1)h(file2)177 1926 y Fr(In)f(this)f(case,)j(the)e(v)
+o(erb)g(is)f Fl(rename)f Fr(and)i(the)g(command)c(line)k(options)f(are)h
+Fl(file1)g(file2)p Fr(.)34 b(The)20 b(en)o(tire)177 1976 y(command)11
+b(line)j(b)q(egins)g(with)f(the)i Fl($)f Fr(and)f(ends)i(with)f(the)g
+Fl(2)p Fr(.)177 2057 y(Op)q(erating)d(systems)g(di\013er)g(greatly)f(in)g
+(the)h(depth)g(with)g(whic)o(h)f(they)h(pro)q(cess)h(their)f(command)d
+(lines,)j(ranging)177 2107 y(from)d(systems)i(that)g(simply)d(pass)j(the)h
+(en)o(tire)f(command)d(line)i(string)h(to)f(the)i(in)o(v)o(ok)o(ed)d(program)
+g(\(e.g.)i(MSDOS\))177 2157 y(through)k(to)g(systems)g(that)f(p)q(erform)g
+(complete)h(command)d(line)i(parsing)g(\(e.g.)h(VMS\).)f(Syn)o(tax)h(con)o(v)
+o(en)o(tions)177 2207 y(v)n(ary)g(considerably)m(.)177 2288
+y(So)k(as)g(to)g(ac)o(hiev)o(e)h(maxim)n(um)13 b(p)q(ortabilit)o(y)k(and)h
+(consistency)i(of)d(in)o(v)o(o)q(cation)g(across)i(di\013eren)o(t)g
+(platforms,)177 2338 y(F)m(unnelW)m(eb)g(reads)h(its)f(command)e(line)h(as)i
+(a)f(ra)o(w)g(string)g(and)g(p)q(erforms)g(all)f(its)h(o)o(wn)g(parsing.)34
+b(This)19 b(is)177 2388 y(p)q(ortable)12 b(b)q(ecause,)i(at)d(the)i(v)o(ery)f
+(least,)g(all)f(op)q(erating)g(systems)h(allo)o(w)f(in)o(v)o(ok)o(ed)g
+(programs)f(access)k(to)e(the)g(ra)o(w)177 2438 y(command)f(line.)177
+2519 y(The)j(command)e(v)o(erb)i(used)h(to)e(in)o(v)o(ok)o(e)g(F)m(unnelW)m
+(eb)h(should)g(b)q(e)g(\\)p Fl(fw)p Fr(".)177 2652 y Fl(FunnelWeb_verb)19
+b(=)43 b("fw")177 2785 y Fr(If)14 b(this)g(v)o(erb)h(is)f(not)g(a)o(v)n
+(ailable,)d(some)i(alternativ)o(es)h(are)h(\\)p Fl(funweb)p
+Fr(",)d(\\)p Fl(fun)p Fr(",)g(and)i(\\)p Fl(funnelweb)p Fr(".)i(The)f(v)o
+(erbs)177 2835 y Fl(web)e Fr(or)h Fl(fweb)f Fr(should)h(b)q(e)g(a)o(v)o
+(oided)f(as)h(they)h(are)f(the)h(names)e(of)g(other)h(literate)h(programmi)o
+(ng)c(systems.)1042 2940 y(66)p eop
+%%Page: 67 68
+67 67 bop 177 42 a Fd(3.7.2)55 b(Command)17 b(Line)h(Argumen)n(ts)177
+158 y Fr(F)m(ollo)o(wing)c(the)j(v)o(erb)g(is)g(the)g(b)q(o)q(dy)g(of)f(the)h
+(command)d(line)i(whic)o(h)g(F)m(unnelW)m(eb)g(parses)i(in)o(to)e(zero)h(or)g
+(more)177 208 y Fo(argumen)o(ts)12 b Fr(separated)j(b)o(y)e(runs)i(of)e(one)h
+(or)g(more)f(blanks.)177 350 y Fl(FunnelWeb_command_)o(line)18
+b(=)k(FunnelWeb_verb)d({{")i("}+)g(argument})177 493 y Fr(Because)e(some)c
+(op)q(erating)h(systems)h(con)o(v)o(ert)g(their)g(command)d(line)i(to)g(upp)q
+(er)h(case)h(b)q(efore)f(handing)f(it)g(to)177 543 y(the)h(in)o(v)o(ok)o(ed)f
+(program,)f(F)m(unnelW)m(eb)h(has)h(b)q(een)h(constructed)g(so)f(as)g(to)f(b)
+q(e)h Fm(insensitive)g Fr(to)f(the)h(case)h(of)e(its)177 593
+y(command)9 b(line)i(argumen)o(ts.)16 b(Ho)o(w)o(ev)o(er,)c(when)g(dealing)f
+(in)o(ternally)f(with)i(argumen)o(ts,)e(F)m(unnelW)m(eb)h Fm(pr)n(eserves)177
+642 y Fr(the)k(case)h(of)e(its)h(command)c(line)k(argumen)o(ts)e(so)i(that)g
+(it)f(will)f(b)q(e)i(able)g(to)f(op)q(erate)i(with)e(op)q(erating)h(systems)
+177 692 y(\(suc)o(h)g(as)f(Unix\))g(whose)g(\014le)g(names)f(are)h(case)h
+(dep)q(enden)o(t.)177 777 y(A)d(v)n(alid)d(F)m(unnelW)m(eb)i(argumen)o(t)f
+(consists)j(of)d(a)h Fo(sign)p Fr(,)f(an)h(iden)o(tifying)f
+Fo(letter)p Fr(,)f(and)i(an)g(optional)f Fo(string)f Fr(with)177
+827 y(no)14 b(spaces)h(separating)f(them.)177 970 y Fl(argument)42
+b(=)22 b(sign)f(id_letter)f([non_blank_stri)o(ng])177 1020
+y(sign)130 b(=)22 b("+")f(|)g("-")h(|)f("=")177 1069 y(id_letter)f(=)i("B")f
+(|)g("C")h(|)f("D")g(|)h("F")f(|)h("H")f(|"I")g(|)g("J")h(|)f("K")g(|)439
+1119 y("L")g(|)g("O")h(|)f("Q")g(|)h("S")f(|)h("T")f(|)g("W")h(|)f("X")177
+1262 y Fr(In)14 b(addition)f(there)i(is)f(a)f(sp)q(ecial)h(form)f(of)g
+(argumen)o(t)g(that)h(do)q(es)g(not)g(b)q(egin)g(with)f(a)h(sign.)177
+1404 y Fl(argument)20 b(=)i(non_blank_string_)o(not_b)o(eginn)o(ing_)o(with_)
+o(+_=_o)o(r_-)177 1547 y Fr(This)14 b(form)e(is)i(exactly)g(equiv)n(alen)o(t)
+f(to)h(the)g(same)f(string)h(with)g(\\)p Fl(+F)p Fr(")f(prep)q(ended)j(to)d
+(it.)177 1632 y(The)e(seman)o(tic)f(e\013ect)i(of)e(these)i(argumen)o(ts)d
+(is)i(de\014ned)g(in)f(terms)g(of)g Fo(options)e Fr(whic)o(h)j(are)f(the)h
+(in)o(ternal)g(param-)177 1682 y(eters)17 b(of)e(F)m(unnelW)m(eb)g(and)g
+(whic)o(h)g(corresp)q(ond)i(closely)f(with)f(the)h(set)g(of)f(legal)f
+(command)f(line)i(argumen)o(ts.)177 1732 y(F)m(unnelW)m(eb)g(has)g(a)g
+(prede\014ned)i(set)f(of)e(options)h(eac)o(h)g(iden)o(ti\014ed)g(b)o(y)g(an)g
+(iden)o(tifying)f(letter)i(ha)o(ving)e(t)o(w)o(o)g(at-)177
+1781 y(tributes:)22 b(a)14 b Fm(string)p Fr(,)h(and)g(a)f Fm(b)n(o)n(ole)n
+(an)p Fr(.)23 b(The)15 b(b)q(o)q(olean)g(determines)g(whether)i(an)e(option)f
+(is)h(turned)h Fm(on)g Fr(or)f Fm(o\013)p Fr(.)177 1831 y(The)f(string)g(con)
+o(tains)g(additional)e(information)f(dep)q(ending)k(on)e(the)i(option.)177
+1916 y(When)e(F)m(unnelW)m(eb)f(starts)i(up,)e(its)h(options)g(ha)o(v)o(e)f
+(prede\014ned)j(default)d(v)n(alues.)17 b(F)m(unnelW)m(eb)12
+b(then)i(parses)g(its)177 1966 y(command)g(line)i(sequen)o(tially)g(from)e
+(left)i(to)h(righ)o(t)f(executing)h(the)g(e\013ect)h(of)e(eac)o(h)h(argumen)o
+(t)e(on)h(the)h(argu-)177 2016 y(men)o(t's)d(corresp)q(onding)h(option.)20
+b(The)15 b(sign)f(and)h(the)g(string)f(comp)q(onen)o(ts)h(of)f(the)h(argumen)
+o(t)e(are)i(pro)q(cessed)177 2066 y Fm(indep)n(endently)p Fr(.)31
+b(A)18 b(sign)f(of)h Fl(+)f Fr(turns)i(the)f(option)f(on.)30
+b(A)18 b(sign)f(of)g Fl(-)h Fr(turns)g(the)h(option)e(o\013.)29
+b(A)18 b(sign)g(of)f Fl(=)177 2116 y Fr(lea)o(v)o(es)f(the)h(option's)e(b)q
+(o)q(olean)h(attribute)g(unc)o(hanged.)25 b(The)16 b(argumen)o(t)f(string)h
+(replaces)h(the)g(string)f(of)f(the)177 2166 y(corresp)q(onding)h(option,)e
+(unless)h(the)h(argumen)o(t)d(string)i(is)g(empt)o(y)m(,)e(in)h(whic)o(h)h
+(case)h(the)f(option)f(string)h(is)g(not)177 2215 y(c)o(hanged.)177
+2301 y(Because)20 b(F)m(unnelW)m(eb)d(pro)q(cesses)j(its)e(command)d(line)j
+(argumen)o(ts)f(from)f(left)h(to)h(righ)o(t,)g(a)f(later)h(argumen)o(t)177
+2350 y(can)e(cancel)h(the)g(e\013ect)h(of)d(an)h(earlier)g(one.)25
+b(F)m(or)16 b(example)f Fl(fw)21 b(+t)g(-t)16 b Fr(will)f(result)h(in)g(the)h
+Fl(t)f Fr(option)f(ending)177 2400 y(up)k Fm(o\013)p Fr(.)32
+b(This)18 b(allo)o(ws)f(users)j(to)e(set)h(up)f(their)h(o)o(wn)f(default)g
+(argumen)o(ts)g(b)o(y)g(de\014ning)g(a)g(sym)o(b)q(ol)f(in)g(their)177
+2450 y(op)q(erating)c(system's)g(command)d(language.)17 b(F)m(or)c(example,)e
+(a)i(Unix)f(user)j(who)d(w)o(an)o(ts)h(F)m(unnelW)m(eb)g(to)g(delete)177
+2500 y(all)e(iden)o(tical)h(output)g(\014les)g(and)g(create)i(a)e(do)q(cumen)
+o(tation)f(\014le)h(on)g(eac)o(h)h(run)f(with)g(a)g(default)g
+Fl(.typ)f Fr(extension)177 2550 y(could)j(simply)e(place)i(the)g(follo)o
+(wing)e(de\014nition)h(in)g(their)i(\\)p Fl(.login)p Fr(")d(\014le.)177
+2692 y Fl(alias)21 b(fw)g(fw)h(+d)f(+t.typ)177 2835 y Fr(These)15
+b(default)f(options)f(can)h(then)h(later)f(b)q(e)g(easily)g(o)o(v)o(erridden)
+g(on)g(the)g(command)d(line.)1042 2940 y(67)p eop
+%%Page: 68 69
+68 68 bop 177 42 a Fd(3.7.3)55 b(Options)177 146 y Fr(F)m(unnelW)m(eb's)14
+b(options)h(are)g(in)o(ternal)f(parameters)h(whic)o(h)g(can)g(b)q(e)g(mo)q
+(di\014ed)e(b)o(y)i(corresp)q(onding)h(argumen)o(ts)177 196
+y(on)e(F)m(unnelW)m(eb's)f(command)e(line.)18 b(A)c(description)g(of)g(eac)o
+(h)g(argumen)o(t)f(and)g(option)h(follo)o(ws.)295 273 y Fo(B1)p
+Fn(:)7 b(:)g(:)o Fo(B6:)36 b(T)l(racedumps:)31 b Fr(These)22
+b(six)e(options)h(ha)o(v)o(e)f(b)q(een)i(pro)o(vided)e(to)h(assist)g(in)f
+(the)295 323 y(debugging)e(and)h(testing)g(of)f(F)m(unnelW)m(eb.)32
+b(They)19 b(determine)g(whic)o(h)f(of)g(six)h(p)q(ossible)g(trace)295
+373 y(dumps)g(are)h(to)f(b)q(e)h(written)g(to)f(the)i(listing)d(\014le.)35
+b(Only)19 b(the)h(b)q(o)q(olean)f(attributes)h(of)f(these)295
+423 y(options)14 b(are)g(ev)o(er)h(used.)k(The)14 b(six)g(dumps)f(are)h(iden)
+o(ti\014ed)g(b)o(y)g(the)g(digits)f Fl(1..6)g Fr(as)h(follo)o(ws:)228
+545 y(1.)20 b(Dump)12 b(a)i(hexdump)f(of)g(eac)o(h)i(mapp)q(ed)d(input)i(and)
+g(include)g(\014le.)228 632 y(2.)20 b(Dump)12 b(the)j(global)d(line)h(list)h
+(created)h(b)o(y)f(the)g(scanner.)228 720 y(3.)20 b(Dump)12
+b(the)j(tok)o(en)f(list)f(created)j(b)o(y)d(the)i(scanner.)228
+807 y(4.)20 b(Dump)12 b(the)j(macro)d(table)i(created)i(b)o(y)d(the)i
+(parser.)228 895 y(5.)20 b(Dump)12 b(the)j(do)q(cumen)o(t)e(list)h(created)h
+(b)o(y)f(the)g(parser.)228 983 y(6.)20 b(Dump)12 b(a)i(table)g(summarizing)c
+(CPU)15 b(and)e(real)h(time)f(usage.)295 1105 y(Because)18
+b(these)e(options)f(are)h(so)g(closely)f(related,)h(a)f(hac)o(k)g(has)h(b)q
+(een)h(pulled)e(to)g(enable)g(them)295 1154 y(to)h(all)g(to)g(b)q(e)h(con)o
+(trolled)f(b)o(y)g(the)h Fl(B)f Fr(argumen)o(t.)24 b(The)17
+b(string)f(argumen)o(t)g(to)g(the)h Fl(B)f Fr(argumen)o(t)295
+1204 y(determines)f(whic)o(h)f(of)f(the)i(six)f(options)g(are)g(to)g(b)q(e)h
+(a\013ected)g(b)o(y)f(the)h(sign.)j(Examples:)g Fl(+B134)295
+1254 y Fr(turns)d(on)f(options)f Fl(B1)p Fr(,)g Fl(B3)p Fr(,)g(and)h
+Fl(B4)p Fr(.)j Fl(-B1)d Fr(turns)g(o\013)g(option)f Fl(B1)p
+Fr(.)18 b Fl(Default:)i(-B123456)p Fr(.)295 1331 y Fo(B7:)h(Determini)o(sm:)
+15 b Fr(If)d(the)h Fl(B7)f Fr(option)g(is)g(turned)h(on,)f(F)m(unnelW)m(eb)g
+(suppresses)j(the)e(output)295 1381 y(of)g(an)o(ything)g(non-deterministic,)g
+(or)h(mac)o(hine)e(dep)q(enden)o(t.)20 b(This)14 b(assists)g(in)g(regression)
+h(test-)295 1431 y(ing.)23 b(Only)16 b(the)g(b)q(o)q(olean)f(attribute)h(is)g
+(used)h(in)e(this)h(option.)22 b(This)16 b(option)f(is)g(con)o(trolled)h(b)o
+(y)295 1481 y(the)e Fl(B7)f Fr(argumen)o(t)g(whic)o(h)g(falls)f(under)i(the)g
+(same)f(argumen)o(t)f(syn)o(tax)i(as)f(the)h(other)g Fl(B)f
+Fr(options.)295 1530 y(Examples:)k Fl(+B7)p Fr(,)c Fl(-B7)p
+Fr(.)k Fl(Default:)j(-B7)p Fr(.)295 1607 y Fo(C:)e(Listing)13
+b(File)i(Con)o(text:)k Fr(The)c Fl(C)f Fr(option)g(is)g(alw)o(a)o(ys)g
+(turned)h(on)g(and)f(cannot)h(b)q(e)g(turned)295 1657 y(o\013.)24
+b(Its)16 b(only)f(attribute)h(is)g(a)g(n)o(um)o(b)q(er)f(whic)o(h)g
+(determines)h(the)h(n)o(um)o(b)q(er)e(of)g(lines)h(of)f(con)o(text)295
+1707 y(that)j(the)g(lister)g(will)e(place)h(around)h(lines)f(\015agged)g
+(with)g(diagnostics)g(in)g(the)i(listing)d(\014le)h(\(if)295
+1757 y(a)f(listing)e(\014le)i(is)g(written\).)24 b(A)16 b(v)n(alue)f(of)h
+(100)f(indicates)h(in\014nite)f(con)o(text)i(whic)o(h)f(means)f(that)295
+1807 y(the)j(en)o(tire)f(listing)e(\014le)i(will)e(b)q(e)i(written)h(out)e
+(if)g(a)g(single)g(diagnostic)g(o)q(ccurs.)28 b(The)17 b(v)n(alue)f(of)295
+1856 y(this)g(n)o(um)o(b)q(er)f(can)h(b)q(e)g(sp)q(eci\014ed)i(b)o(y)d(sp)q
+(ecifying)h(it)f(as)h(a)f(string)h(of)f(decimal)f(digits)h(to)h(the)g
+Fl(+C)295 1906 y Fr(argumen)o(t.)h(Examples:)g Fl(+C100)p Fr(,)12
+b Fl(+C10)p Fr(.)18 b Fl(Default:)i(+C2)p Fr(.)295 1983 y Fo(D:)f(Delete)e
+(Iden)o(tical)f(Output)h(Files:)22 b Fr(Only)16 b(the)h(b)q(o)q(olean)g
+(attribute)g(of)e(this)i(option)f(is)295 2033 y(used.)23 b(When)15
+b(turned)h(on,)f(the)h(option)e(causes)i(the)g(suppression)h(\(deletion\))e
+(of)f(pro)q(duct)i(\014les)295 2083 y(and)j(do)q(cumen)o(tation)f(\014les)i
+(\(but)g(not)f(listing)f(or)h(journal)g(\014les\))g(that)h(are)f(iden)o
+(tical)g(to)g(the)295 2133 y(curren)o(tly)14 b(existing)f(\014les)h(of)f(the)
+g(same)g(name.)j(F)m(or)d(example,)f(if)g(F)m(unnelW)m(eb)h(is)g(instructed)i
+(to)295 2182 y(generate)d Fl(stack.h)e Fr(as)h(an)g(pro)q(duct)h(\014le,)f
+(and)f(the)i(text)f(to)g(b)q(e)h(written)f(to)g Fl(stack.h)f
+Fr(is)g(iden)o(tical)295 2232 y(to)i(the)h(curren)o(tly)g(existing)f
+Fl(stack.h)p Fr(,)f(then)i(F)m(unnelW)m(eb)e(will)g(simply)f(not)i(write)h
+(an)o(y)f(pro)q(duct)295 2282 y(\014le,)h(lea)o(ving)e(the)i(curren)o(tly)h
+(existing)e Fl(stack.h)f Fr(as)i(it)f(is)h(\(and)g(in)f(particular)g(lea)o
+(ving)g(the)h(\014le's)295 2332 y(date)e(attribute)g(the)g(same\).)17
+b(This)10 b(prev)o(en)o(ts)i(unnecessary)h Fl(make)c Fr(propagations.)16
+b(F)m(or)10 b(example,)295 2382 y(in)16 b(a)f(C)h(program,)e(if)h
+Fl(stack.fw)f Fr(is)i(a)f(F)m(unnelW)m(eb)h(input)f(\014le)h(that)g
+(generates)i Fl(stack.h)c Fr(and)295 2432 y Fl(stack.c)p Fr(,)9
+b(a)h(mo)q(di\014cation)d(to)j Fl(stack.fw)e Fr(that)i(a\013ects)h
+Fl(stack.c)e Fr(but)h(do)q(es)h(not)e(a\013ect)i Fl(stack.h)295
+2481 y Fr(will)f(not)i(pro)o(v)o(ok)o(e)f(the)i(recompilation)c(of)i(mo)q
+(dules)g(that)h Fl(#include)20 b(stack.h)p Fr(,)10 b(so)i(long)e(as)i(the)295
+2531 y(in)o(terv)o(ening)i(F)m(unnelW)m(eb)f(run)i(has)f Fl(+D)f
+Fr(set.)19 b(Examples:)e Fl(-D)p Fr(,)c Fl(+D)p Fr(.)g Fl(Default:)20
+b(-D)p Fr(.)295 2608 y Fo(F:)f(F)l(unnelW)l(eb)d(Input)h(File:)22
+b Fr(If)16 b(this)g(option)g(is)g(turned)h(on,)f(F)m(unnelW)m(eb)g(pro)q
+(cesses)j(the)295 2658 y(input)h(\014le)h(whose)f(name)f(is)h(sp)q(eci\014ed)
+i(b)o(y)e(the)h(option)f(string.)37 b(Examples:)29 b Fl(+Fsloth.fw)p
+Fr(,)295 2708 y Fl(+Fwalrus)p Fr(,)12 b Fl(-F)p Fr(.)h Fl(Default:)20
+b(-F)p Fr(.)295 2785 y Fo(H:)h(Displa)o(y)c(Help)i(Message:)26
+b Fr(If)17 b(this)g(option)g(is)g(turned)i(on,)e(F)m(unnelW)m(eb)g(displa)o
+(ys)g(the)295 2835 y(message)d(sp)q(eci\014ed)h(b)o(y)e(the)h(argumen)o(t)e
+(string.)18 b(Eac)o(h)c(message)g(has)f(a)g(name.)k(The)d(main)e(help)1042
+2940 y(68)p eop
+%%Page: 69 70
+69 69 bop 295 42 a Fr(message)16 b(is)g(called)f(\\)p Fl(menu)p
+Fr(")g(and)h(con)o(tains)g(a)f(list)h(of)f(the)h(other)h(help)f(messages.)24
+b(Examples:)295 91 y Fl(+Hregistration)p Fr(,)11 b Fl(+Hoptions)p
+Fr(.)16 b Fl(Default:)k(-Hmenu)p Fr(.)295 165 y Fo(I:)c(Include)e(default)g
+(\014le)g(sp)q(eci\014cation:)i Fr(This)e(option)f(is)h(alw)o(a)o(ys)e
+(turned)j(on)f(and)f(cannot)295 215 y(b)q(e)j(turned)g(o\013.)22
+b(Its)16 b(string)f(attribute)h(is)f(used)h(as)f(the)h(default)f(\014le)g(sp)
+q(eci\014cation)h(for)f(include)295 265 y(\014les.)j(Usually)12
+b(this)g(option)g(is)g(used)h(to)f(sp)q(ecify)h(a)f(directory)h(from)e(whic)o
+(h)h(include)g(\014les)h(should)295 315 y(b)q(e)i(obtained.)j(Examples:)e
+Fl(=I/usr/dave/includes)o(/)p Fr(.)f Fl(Default:)20 b(+I)p
+Fr(.)295 388 y Fo(J:)d(Journal)d(File:)19 b Fr(If)14 b(this)g(option)g(is)g
+(turned)i(on,)e(F)m(unnelW)m(eb)g(generates)i(a)e(journal)g(\014le.)20
+b(A)295 438 y(journal)15 b(\014le)h(con)o(tains)g(a)g(log)f(of)g(all)g(the)i
+(console)f(input)g(and)g(output)g(to)g(F)m(unnelW)m(eb)f(during)295
+488 y(a)h(single)g(in)o(v)o(o)q(cation)f(of)h(the)h(F)m(unnelW)m(eb)f
+(program)f(\(Note:)23 b(The)17 b Fl(Q)f Fr(option)f(do)q(es)i(not)g(a\013ect)
+295 538 y(this.\).)23 b(The)16 b(journal)f(\014le)g(is)h(particularly)f
+(useful)g(for)g(examining)f(what)h(happ)q(ened)i(during)e(a)295
+588 y(F)m(unnelW)m(eb)e(shell)h(run.)k(The)d(string)e(attribute)i(is)e(the)i
+(name)d(of)h(the)h(journal)f(\014le.)18 b(Examples:)295 638
+y Fl(+Jjournfile)p Fr(,)11 b Fl(-J)p Fr(.)i Fl(Default:)20
+b(-J)p Fr(.)295 711 y Fo(K:)g(Keyb)q(oard:)k Fr(If)16 b(this)h(option)f(is)g
+(turned)i(on,)e(F)m(unnelW)m(eb)g(en)o(ters)i(an)f(in)o(teractiv)o(e)g(mo)q
+(de)295 761 y(in)i(whic)o(h)g(the)h(user)h(can)e(en)o(ter)h(F)m(unnelW)m(eb)f
+(shell)g(commands)e(in)o(teractiv)o(ely)m(.)34 b(The)20 b(string)295
+811 y(attribute)15 b(is)e(un)o(used.)19 b(Examples:)e Fl(+K)p
+Fr(,)c Fl(-K)p Fr(.)g Fl(Default:)20 b(-K)p Fr(.)295 885 y
+Fo(L:)d(Listing)d(File:)k Fr(If)c(this)h(option)e(is)i(turned)g(on,)f(F)m
+(unnelW)m(eb)g(generates)i(a)f(listing)e(\014le)i(con-)295
+935 y(taining)e(a)g(summary)e(of)i(a)h(run)g(on)f(F)m(unnelW)m(eb)h(prop)q
+(er.)k(The)d(string)e(argumen)o(t)g(is)h(the)g(name)295 985
+y(of)g(the)g(listing)f(\014le)h(to)f(b)q(e)i(created.)k(Examples:)e
+Fl(+L)p Fr(,)c Fl(-L)p Fr(,)g Fl(+Llisting.lis)p Fr(.)j Fl(Default:)k(-L)p
+Fr(.)295 1058 y Fo(O:)e(Pro)q(duct)d(Files:)k Fr(If)c(this)g(option)f(is)h
+(turned)h(on,)e(F)m(unnelW)m(eb)h(generates)h(a)f(pro)q(duct)h(\014le)295
+1108 y(for)e(eac)o(h)h(macro)e(in)g(the)i(input)f(\014le)g(that)g(is)g(b)q
+(ound)g(to)g(an)g(output)h(\014le.)j(The)d(string)f(attribute)295
+1158 y(con)o(tributes)22 b(to)e(the)h(name)e(of)h(the)h(pro)q(duct)g
+(\014les.)38 b(This)20 b(option)g(is)g(con)o(trolled)g(b)o(y)g(the)h
+Fl(O)295 1208 y Fr(argumen)o(t)d(b)q(ecause)j(pro)q(duct)e(\014les)g(used)h
+(to)f(b)q(e)g(called)g(\\)p Fo(O)p Fr(utput)g(\014les"\).)33
+b(Examples:)27 b Fl(-O)p Fr(,)295 1258 y Fl(+O/usr/dave/product)o(/)p
+Fr(.)15 b Fl(Default:)20 b(+O)p Fr(.)295 1332 y Fo(Q:)15 b(Quiet:)h
+Fr(If)c(this)g(option)g(is)g(turned)i(on,)e(F)m(unnelW)m(eb)f(suppresses)16
+b(all)11 b(output)h(to)h(the)g(screen)295 1381 y(\(standard)k(output\))f
+(unless)g(one)g(or)g(more)f(errors)i(o)q(ccur,)g(in)e(whic)o(h)h(case)h(a)e
+(single)h(line)f(sum-)295 1431 y(marizing)d(the)i(errors)h(is)e(sen)o(t)i(to)
+e(standard)h(output)g(at)f(the)i(end)f(of)f(the)h(run.)k(If)13
+b(this)h(option)f(is)295 1481 y(turned)j(o\013,)e(F)m(unnelW)m(eb)g(writes)h
+(to)g(the)g(console)g(in)f(its)g(normal)f(garrulous)h(w)o(a)o(y)m(.)19
+b(The)c(string)295 1531 y(attribute)g(is)e(un)o(used)i(in)f(this)g(option.)j
+(Examples:)g Fl(-Q)p Fr(,)c Fl(+Q)p Fr(.)g Fl(Default:)20 b(-Q)p
+Fr(.)295 1605 y Fo(S:)13 b(Screen:)k Fr(If)11 b(this)h(option)f(is)g(turned)i
+(on,)e(F)m(unnelW)m(eb)h(writes)g(all)e(diagnostics)i(to)f(the)i(screen)295
+1654 y(\(standard)i(output\))g(as)g(w)o(ell)f(as)g(to)h(the)g(listing)f
+(\014le.)20 b(By)14 b(default,)g(they)h(are)g(sen)o(t)h(only)e(to)g(the)295
+1704 y(listing)i(\014le.)28 b(This)17 b(option)g(has)g(a)g(single)f(n)o
+(umerical)g(attribute)i(that)f(can)g(b)q(e)h(sp)q(eci\014ed)h(as)e(a)295
+1754 y(decimal)10 b(string)i(in)g(the)g(string)g(comp)q(onen)o(t)f(of)g(the)h
+Fl(S)g Fr(argumen)o(t.)k(The)c(n)o(um)o(b)q(er)f(is)h(the)g(n)o(um)o(b)q(er)
+295 1804 y(of)g(lines)f(of)h(con)o(text)g(that)g(should)g(surround)g(eac)o(h)
+h(diagnostic)e(sen)o(t)i(to)e(the)i(screen.)19 b(Examples:)295
+1854 y Fl(-S)p Fr(,)13 b Fl(+S6)p Fr(,)g Fl(+S0)p Fr(.)k Fl(Default:)j(-S)p
+Fr(.)295 1928 y Fo(T:)e(Do)q(cumen)o(tation)c(\014le:)20 b
+Fr(If)14 b(this)i(option)1034 1913 y Fg(3)1067 1928 y Fr(is)e(turned)j(on,)d
+(F)m(unnelW)m(eb)h(generates)i(a)d(do)q(c-)295 1977 y(umen)o(tation)f(\014le)
+i(in)g(T)657 1986 y(E)680 1977 y(X)g(format.)k(The)c(string)g(argumen)o(t)f
+(con)o(tributes)i(to)f(the)g(name)f(of)g(the)295 2027 y(do)q(cumen)o(tation)g
+(\014le)h(to)g(b)q(e)g(created.)23 b(By)15 b(default)f(this)h(option)f(is)h
+(turned)h(o\013,)f(as)f(exp)q(erience)295 2077 y(has)h(sho)o(wn)f(that)g
+(most)f(F)m(unnelW)m(eb)h(runs)g(are)h(made)e(during)h(program)e(dev)o
+(elopmen)o(t;)h(do)q(cu-)295 2127 y(men)o(tation)f(runs)j(o)q(ccur)g(far)f
+(more)e(rarely)m(.)18 b(Examples:)f Fl(-T)p Fr(,)c Fl(+Tsloth.tex)p
+Fr(.)j Fl(Default:)k(-T)p Fr(.)295 2201 y Fo(W:)e(Width)e(of)g(Pro)q(duct)g
+(Files:)j Fr(If)c(this)g(option)f(is)h(turned)h(on,)f(a)g(limit)d(is)j
+(placed)g(on)g(the)295 2250 y(length)f(of)g(lines)g(in)g(pro)q(duct)h
+(\014les)g(generated)g(during)f(the)h(run.)20 b(Lines)14 b(that)g(breac)o(h)i
+(the)e(limit)295 2300 y(are)k(\015agged)f(with)g(error)h(messages.)28
+b(This)17 b(option)g(has)g(a)g(single)g(n)o(umerical)f(attribute)i(that)295
+2350 y(can)c(b)q(e)h(sp)q(eci\014ed)h(as)e(a)f(decimal)g(string)h(in)f(the)i
+(string)f(comp)q(onen)o(t)f(of)h(the)g Fl(W)g Fr(argumen)o(t.)j(The)295
+2400 y(n)o(um)o(b)q(er)f(is)h(the)h(sp)q(eci\014ed)g(maxim)n(um)13
+b(width.)26 b(This)17 b(option)f(is)h(one)g(of)f(t)o(w)o(o)h(limits)d(that)j
+(are)295 2450 y(placed)i(on)f(the)h(width)f(of)f(pro)q(duct)i(\014les.)32
+b(The)18 b(other)h(limit)d(is)i(an)g(attribute)g(of)g(the)h(input)295
+2500 y(\014le)c(that)f(defaults)h(to)g(80)f(c)o(haracters,)i(but)e(can)h(b)q
+(e)g(raised)g(or)g(lo)o(w)o(ered)g(using)f(an)g(output)h(line)295
+2549 y(length)f(pragma.)i(The)d(width)h(that)f(is)g(enforced)i(is)e(the)h(lo)
+o(w)o(er)f(of)g(this)g(v)n(alue)g(and)g(the)i(v)n(alue)d(of)295
+2599 y(the)j Fl(W)e Fr(option)h(\(if)f(turned)i(on\).)j(Examples:)e
+Fl(-W)p Fr(,)d Fl(+W100)p Fr(.)k Fl(Default:)j(-W80)p Fr(.)295
+2673 y Fo(X:)f(Execute:)i Fr(If)16 b(this)f(option)g(is)h(turned)g(on,)g(F)m
+(unnelW)m(eb)f(executes)i(the)g(F)m(unnelW)m(eb)e(shell)295
+2723 y(script)g(\014le)f(sp)q(eci\014ed)h(b)o(y)f(the)g(string)g(attribute.)
+19 b(Examples:)e Fl(+Xmaster)p Fr(,)11 b Fl(-X)p Fr(.)i Fl(Default:)21
+b(-X)p Fr(.)p 177 2757 709 2 v 223 2783 a Ff(3)241 2795 y Fh(This)c(option)f
+(is)h(con)o(trolled)d(b)o(y)j(the)f Fe(T)i Fh(command)c(line)i(argumen)o(t)f
+(b)q(ecause)g(do)q(cumen)o(tati)o(on)f(\014les)j(used)f(to)h(b)q(e)g(called)
+177 2835 y(t)o(yp)q(esetter)9 b(\014les.)1042 2940 y Fr(69)p
+eop
+%%Page: 70 71
+70 70 bop 177 42 a Fi(3.8)70 b(File)21 b(Name)h(Inheritance)177
+157 y Fr(During)10 b(a)h(single)f(run)h(of)f(F)m(unnelW)m(eb,)g(F)m(unnelW)m
+(eb)h(can)g(pro)q(duce)g(man)o(y)e(di\013eren)o(t)j(output)f(\014les.)17
+b(As)11 b(it)g(w)o(ould)177 207 y(b)q(e)i(v)o(ery)g(tedious)g(to)f(ha)o(v)o
+(e)g(to)g(sp)q(ecify)h(the)g(name)f(of)f(eac)o(h)i(of)f(these)i(\014les)f
+(explicitly)e(eac)o(h)i(time)e(F)m(unnelW)m(eb)h(is)177 257
+y(run,)g(F)m(unnelW)m(eb)e(pro)o(vides)i(a)f(system)g(of)f(defaults)h(that)g
+(allo)o(ws)f(the)i(user)g(to)f(sp)q(ecify)h(the)g(minim)n(um)7
+b(required)177 306 y(to)15 b(successfully)i(complete)d(the)i(run.)23
+b(T)m(o)14 b(do)h(this)h(F)m(unnelW)m(eb)e(allo)o(ws)g(\014le)i(sp)q
+(eci\014cations)g(to)f(inherit)g(\014elds)177 356 y(from)d(one)i(another.)177
+430 y(F)m(unnelW)m(eb)k(structures)j(\014lenames)d(in)o(to)g(three)i
+(\014elds)f(whic)o(h)f(are)h(inherited)g(indep)q(enden)o(tly)m(.)32
+b(The)19 b(\014elds)177 480 y(are:)f Fo(directory)p Fr(,)11
+b Fo(name)p Fr(,)h(and)h Fo(extension)p Fr(.)i(On)e(systems)g(ha)o(ving)f
+(other)i(\014elds)f(\(e.g.)g Fm(network)g(no)n(de)p Fr(,)h
+Fm(devic)n(e)177 530 y(name)p Fr(\),)d(the)g(extra)g(\014elds)g(are)g
+(considered)g(to)f(b)q(e)h(part)g(of)e(the)i(directory)g(\014eld.)17
+b(V)m(ersion)11 b(n)o(um)o(b)q(ers)f(are)g(ignored.)177 580
+y(A)k(\014eld)g(can)g(inherit)g(a)g(v)n(alue)f(if)g(its)h(curren)o(t)h(v)n
+(alue)e(is)h(the)h(empt)o(y)d(string.)177 654 y(The)i(follo)o(wing)e(table)i
+(giv)o(es)f(the)i(full)d(inheritance)j(sc)o(heme)f(used)h(in)e(F)m(unnelW)m
+(eb.)p 402 733 1323 2 v 401 783 2 50 v 427 768 a(Script)p 579
+783 V 70 w(Input)p 743 783 V 64 w(Include)p 925 783 V 50 w(Journal)p
+1112 783 V 50 w(List)p 1290 783 V 108 w(Do)q(cumen)o(t)p 1526
+783 V 49 w(Pro)q(duct)p 1723 783 V 402 785 1323 2 v 401 834
+2 50 v 579 834 V 743 834 V 769 819 a Fl(@i)p 925 834 V 1112
+834 V 1290 834 V 1526 834 V 739 w(@o)p 1723 834 V 401 884 V
+427 869 a(+x)p 579 884 V 134 w(+f)p 743 884 V 120 w(+i)p 925
+884 V 138 w(+j)p 1112 884 V 143 w(+l)p 1290 884 V 134 w(+t)p
+1526 884 V 192 w(+o)p 1723 884 V 401 934 V 427 919 a Fr(\\)p
+Fl(.fws)p Fr(")p 579 934 V 48 w(\\)p Fl(.fw)p Fr(")p 743 934
+V 56 w(\\)p Fl(.fwi)p Fr(")p 925 934 V 52 w(\\)p Fl(.jrn)p
+Fr(")p 1112 934 V 57 w(\\)p Fl(.lis)p Fr(")p 1290 934 V 48
+w(\\)p Fl(.tex)p Fr(")p 1526 934 V 1723 934 V 401 984 V 579
+984 V 743 984 V 769 969 a Fl(+f)p 925 984 V 138 w(+f)p 1112
+984 V 143 w(+f)p 1290 984 V 134 w(+f)p 1526 984 V 1723 984
+V 401 1034 V 427 1019 a Fr(DefDir)p 579 1034 V 55 w(Defdir)p
+743 1034 V 50 w(Defdir)p 925 1034 V 68 w(Defdir)p 1112 1034
+V 73 w(Defdir)p 1290 1034 V 64 w(Defdir)p 1526 1034 V 122 w(Defdir)p
+1723 1034 V 402 1035 1323 2 v 177 1133 a(The)g(table)g(is)f(arranged)h(with)f
+(items)g(of)g(highest)g(priorit)o(y)g(at)h(the)g(top.)k(The)c(\\)p
+Fl(+<letter>)p Fr(")d(cells)j(refer)h(to)e(the)177 1183 y(\014le)h(sp)q
+(eci\014cation)h(supplied)g(in)e(the)i(giv)o(en)f(command)d(line)j(argumen)o
+(t.)k(\\)p Fl(+F)p Fr(")12 b(is)h(the)h(name)e(of)g(the)i(input)f(\014le.)177
+1233 y(\\Defdir")k(refers)i(to)f(the)g(default)f(directory)i(sp)q
+(eci\014cation)f(pro)o(vided)g(b)o(y)f(the)h(op)q(erating)g(system.)29
+b(Empt)o(y)177 1283 y(cells)14 b(do)g(not)g(con)o(tribute.)177
+1357 y(The)g(follo)o(wing)d(example)i(sho)o(ws)h(ho)o(w)f(the)h(table)g(is)f
+(used.)19 b(Supp)q(ose)c(that)f(the)g(user)h(in)o(v)o(ok)o(ed)e(F)m(unnelW)m
+(eb)g(as)177 1407 y(follo)o(ws:)177 1522 y Fl(fw)22 b(/usr/ross/work/)o
+(sloth)o(.fw)d(+twalrus)177 1636 y Fr(T)m(o)g(w)o(ork)g(out)g(what)h(the)g
+(do)q(cumen)o(tation)e(\014le)i(should)f(b)q(e)h(called,)g(F)m(unnelW)m(eb)f
+(starts)i(with)e(the)h(empt)o(y)177 1686 y(string)d(and)g(then)h(w)o(orks)f
+(do)o(wn)g(the)h(Do)q(cumen)o(t)e(column)f(of)i(the)h(table.)27
+b(The)18 b(top)f(en)o(try)g(is)g(empt)o(y)f(so)i(w)o(e)177
+1736 y(ignore)g(it)f(and)g(pro)q(ceed)j(to)d(the)i(second)f(en)o(try)h(whic)o
+(h)e(consists)i(of)e(\\)p Fl(+T)p Fr(".)f(The)i(user)h(sp)q(eci\014ed)g(the)g
+(string)177 1786 y(\\)p Fl(walrus)p Fr(")d(as)i(the)g(v)n(alue)f(of)g(this)h
+(option,)f(and)h(as)g(our)f(curren)o(t)i(\(empt)o(y\))e(string)h(do)q(es)h
+(not)e(ha)o(v)o(e)h(a)f(name)177 1836 y(\014eld,)d(w)o(e)g(insert)h(the)g
+(string)f(\\)p Fl(walrus)p Fr(")e(in)o(to)i(the)h(name)d(\014eld,)i
+(resulting)g(in)g(the)h(string)f(\\)p Fl(walrus)p Fr(".)j(Mo)o(ving)177
+1886 y(do)o(wn)d(to)g(the)h(next)f(ro)o(w,)g(w)o(e)g(encoun)o(ter)i(the)f
+(constan)o(t)f(string)h(\\)p Fl(.tex)p Fr(".)i(This)d(string)g(consists)h(of)
+f(an)g(empt)o(y)177 1935 y(directory)j(and)e(name)g(\014eld,)h(but)g(a)f(\\)p
+Fl(.tex)p Fr(")g(\014le)h(extension.)24 b(As)16 b(our)g(curren)o(t)h(string)f
+(\\)p Fl(walrus)p Fr(",)e(do)q(es)j(not)177 1985 y(already)f(ha)o(v)o(e)g(a)g
+(\014le)h(extension)g(\(i.e.)e(the)i(\014le)f(extension)h(\014eld)g(of)e(our)
+i(curren)o(t)g(string)g(is)f(empt)o(y\),)f(w)o(e)i(add)177
+2035 y(in)f(\\)p Fl(.tex)p Fr(",)f(resulting)h(in)g(the)h(string)f(\\)p
+Fl(walrus.tex)p Fr(".)22 b(Next)17 b(w)o(e)f(encoun)o(ter)i(the)f(\\)p
+Fl(+F)p Fr(")e(\014eld)h(whic)o(h)g(is)g(the)177 2085 y(input)c(\014lename)f
+(\\)p Fl(/usr/ross/work/slo)o(th.fw)o Fr(")e(consisting)k(of)e(a)h(directory)
+h(\014eld)g(\\)p Fl(/usr/ross/work)o(/)p Fr(",)c(a)177 2135
+y(name)k(\014eld)i(\\)p Fl(sloth)p Fr(",)d(and)j(a)f(\014le)g(extension)h
+(\014eld)g(\\)p Fl(.fw)p Fr(".)j(Our)d(\\)p Fl(walrus.tex)p
+Fr(")d(string)i(already)g(has)h(name)177 2184 y(and)f(\014le)g(extension)h
+(\014elds,)e(but)i(its)f(directory)g(\014eld)g(is)g(empt)o(y)m(,)e(and)i(so)g
+(w)o(e)g(add)g(in)f(the)i(directory)g(\014eld)f(from)177 2234
+y(the)f(input)g(\014le)g(sp)q(eci\014cation,)g(resulting)g(in)f(the)h(string)
+g(\\)p Fl(/usr/ross/work/w)o(alrus)o(.tex)o Fr(".)i(Finally)m(,)10
+b(w)o(e)j(hit)177 2284 y(the)i(default)f(directory)i(sp)q(eci\014cation,)f
+(whic)o(h)f(is)h(\(sa)o(y\))f(\\)p Fl(/usr/ross/play/)p Fr(".)j(Ho)o(w)o(ev)o
+(er,)d(as)h(the)g(directory)177 2334 y(\014eld)f(of)f(our)h(w)o(alrus)g
+(string)g(is)g(already)f(full,)f(it)i(has)g(no)g(e\013ect.)177
+2408 y(In)j(general,)f(there)i(is)f(no)f(need)h(to)g(remem)o(b)q(er)e(the)i
+(exact)g(details)g(of)e(F)m(unnelW)m(eb's)h(\014lename)g(inheritance.)177
+2458 y(The)e(imp)q(ortan)o(t)f(thing)g(is)h(to)g(kno)o(w)f(that)h(it)f
+(exists,)h(and)g(to)g(use)h(it.)177 2620 y Fi(3.9)70 b(F)-6
+b(unnelW)g(eb)22 b(Startup)177 2735 y Fr(F)m(unnelW)m(eb's)c(command)d(line)j
+(options)f(can)i(b)q(e)f(divided)g(in)o(to)f(t)o(w)o(o)h(groups.)31
+b Fo(Action)19 b(options)d Fr(instruct)177 2785 y(F)m(unnelW)m(eb)j(to)g(p)q
+(erforms)g(some)g(sort)h(of)f(indep)q(enden)o(t)i(action)e(suc)o(h)h(as)f
+(pro)q(cessing)i(a)e(\014le.)35 b Fo(Ordinary)177 2835 y(options)11
+b Fr(merely)i(mo)q(dify)f(the)i(w)o(a)o(y)g(in)f(whic)o(h)h(F)m(unnelW)m(eb)f
+(executes)j(the)f(actions.)1042 2940 y(70)p eop
+%%Page: 71 72
+71 71 bop 177 42 a Fr(The)13 b(four)e(action)h(options)g(are:)17
+b Fl(+F)p Fr(,)11 b Fl(+K)p Fr(,)h Fl(+X)p Fr(,)f(and)g Fl(+H)p
+Fr(.)h(F)m(or)f(F)m(unnelW)m(eb)h(to)g(b)q(e)g(successfully)i(in)o(v)o(ok)o
+(ed,)d(at)h(least)177 91 y(one)17 b(action)f(option)g(m)o(ust)g(b)q(e)h(sp)q
+(eci\014ed.)28 b(If)16 b(zero)i(action)e(options)g(are)i(sp)q(eci\014ed,)g(F)
+m(unnelW)m(eb)e(terminates)177 141 y(with)e(failure)f(status.)19
+b(If)14 b(more)f(than)h(one)g(action)g(option)f(is)h(sp)q(eci\014ed,)h(F)m
+(unnelW)m(eb)e(p)q(erforms)h(the)g(sp)q(eci\014ed)177 191 y(actions)g(in)g(a)
+f(prede\014ned)j(order.)177 259 y(Assuming)e(that)h(the)g(user)h(has)f(sp)q
+(eci\014ed)h(at)f(least)g(one)g(action,)f(the)h(order)h(in)e(whic)o(h)h
+(actions)g(are)g(executed)177 309 y(is)f(as)g(follo)o(ws:)295
+377 y Fo(Initializati)o(on)i(script:)24 b Fr(F)m(unnelW)m(eb)17
+b(starts)h(b)o(y)f(lo)q(oking)f(in)h(the)h(curren)o(t)h(directory)f(for)f(a)
+295 427 y(\014le)e(called)g(\\)p Fl(fwinit.fws)p Fr(".)k(If)14
+b(it)h(do)q(esn't)g(\014nd)h(one,)f(it)f(do)q(esn't)i(raise)f(an)o(y)f
+(error.)23 b(If)14 b(it)h(do)q(es)295 477 y(\014nd)e(one,)g(it)f(executes)j
+(it)d(as)h(a)f(F)m(unnelW)m(eb)h(shellscript.)18 b(Initialization)10
+b(scripts)k(are)f(useful)g(for)295 527 y(setting)g(up)e(F)m(unnelW)m(eb)h
+(options)f(\(e.g.)g(using)h(the)g(\\)p Fl(set)p Fr(")f(command)e(without)j
+(ha)o(ving)e(to)i(t)o(yp)q(e)295 577 y(them)h(eac)o(h)i(time\).)295
+645 y Fo(Execute)e(argumen)o(t)e(script:)k Fr(If)c(a)g(shellscript)h(has)g(b)
+q(een)g(sp)q(eci\014ed)h(using)e(the)h(\\)p Fl(+X)p Fr(")f(option,)295
+695 y(F)m(unnelW)m(eb)j(executes)i(it.)295 763 y Fo(Pro)q(cess)k(input)d
+(\014le:)25 b Fr(If)17 b(the)i(user)f(has)g(sp)q(eci\014ed)h(an)f(input)f
+(\014le)h(using)f(the)h(\\)p Fl(+F)p Fr(")f(option,)295 813
+y(then)e(this)f(is)g(pro)q(cessed)i(next)e(\(b)o(y)g(F)m(unnelW)m(eb)f(prop)q
+(er\).)295 881 y Fo(Displa)o(y)k(help)g(message:)24 b Fr(If)16
+b(the)h(user)h(requested,)h(using)d(the)i(\\)p Fl(+H)p Fr(")d(option,)i(that)
+f(a)h(help)295 931 y(message)d(b)q(e)g(displa)o(y)o(ed,)f(the)i(message)e(is)
+h(displa)o(y)o(ed)f(at)h(this)g(time.)295 999 y Fo(In)o(teractiv)o(e)f(mo)q
+(de:)18 b Fr(If)13 b(the)g(user)i(sp)q(eci\014ed)g(the)e(\\)p
+Fl(+K)p Fr(")g(option,)f(F)m(unnelW)m(eb)h(en)o(ters)h(in)o(terac-)295
+1049 y(tiv)o(e)g(\(k)o(eyb)q(oard\))g(mo)q(de.)177 1117 y(F)m(unnelW)m(eb)e
+(pro)q(cesses)j(these)f(actions)e(in)g(the)h(ab)q(o)o(v)o(e)f(order)i
+(regardless)f(of)f(the)h(order)g(in)f(whic)o(h)g(they)h(app)q(ear)177
+1167 y(on)h(the)g(command)d(line.)177 1236 y(It)17 b(ma)o(y)e(b)q(e)i(hard)g
+(to)g(see)g(ho)o(w)g(some)f(of)g(these)i(actions)f(migh)o(t)d(b)q(e)k(com)o
+(bined.)25 b(Nev)o(ertheless,)19 b(F)m(unnelW)m(eb)177 1285
+y(allo)o(ws)e(this.)31 b(F)m(or)18 b(example,)g(a)g(user)h(migh)o(t)d(wish)i
+(to)g(pro)q(cess)i(a)e(batc)o(h)h(of)f(\014les)g(as)g(sp)q(eci\014ed)i(in)e
+(a)g(script)177 1335 y(\(\\)p Fl(+Xscript.fws)p Fr("\),)13
+b(b)q(e)j(reminded)f(of)g(the)h(in)o(teractiv)o(e)f(commands)e(a)o(v)n
+(ailable)h(\(\\)p Fl(+Hcommand)p Fr("\),)f(and)i(then)177 1385
+y(en)o(ter)d(in)o(teractiv)o(e)g(mo)q(de)e(so)h(as)g(to)g(b)q(e)h(able)e(to)h
+(repro)q(cess)j(\014les)d(for)g(whic)o(h)g(F)m(unnelW)m(eb)f(rep)q(orted)j
+(errors)f(\(after)177 1435 y(correcting)j(the)g(errors)g(in)e(a)h(di\013eren)
+o(t)h(w)o(orkstation)e(windo)o(w\).)177 1588 y Fi(3.10)70 b(Scanner)177
+1697 y Fr(The)16 b(scanner)h(reads)f(in)f(the)h(input)f(\014le)g(and)g(pro)q
+(duces)i(a)e(list)g(of)g(tok)o(ens)h(whic)o(h)f(it)g(hands)g(on)o(to)g(the)h
+(parser.)177 1747 y(In)c(addition,)f(some)h(input)g(constructs)i(ma)o(y)d
+(cause)i(the)g(scanner)h(to)e(mo)q(dify)e(some)h(of)h(F)m(unnelW)m(eb's)g
+(options.)177 1879 y Fd(3.10.1)55 b(Basic)19 b(Input)g(File)e(Pro)r(cessing)
+177 1974 y Fr(In)d(order)h(to)f(read)h(in)f(an)g(input)g(\014le)g(or)g
+(include)h(\014le,)f(the)g(scanner)i(calls)e(a)g(submo)q(dule)f(called)h(the)
+h Fo(mapp)q(er)177 2024 y Fr(that)d(reads)g(a)f(\014le)h(in)f(and)g(creates)j
+(a)d(con)o(tiguous)g(cop)o(y)h(of)f(it)g(in)g(memory)m(.)j(The)e(scanner)h
+(then)f(p)q(erforms)f(three)177 2074 y(c)o(hec)o(ks)18 b(on)e(the)h(\014le,)g
+(the)g(\014rst)g(\(\014le)g(termination\))e(of)h(whic)o(h)g(is)g(p)q
+(erformed)g(b)q(efore)i(scanning)e(commences,)177 2124 y(and)e(the)g(other)h
+(t)o(w)o(o)e(of)h(whic)o(h)f(tak)o(e)h(place)g(during)g(scanning)g(b)q(efore)
+g(eac)o(h)h(line)e(is)h(scanned.)295 2192 y Fo(File)c(T)l(ermination)o(:)k
+Fr(The)c(\014rst)g(c)o(hec)o(k)h(the)f(scanner)h(mak)o(es)d(is)h(whether)i
+(the)f(\014le)g(is)f(terminated)295 2242 y(prop)q(erly)m(.)19
+b(A)14 b(\014le)g(is)g(considered)i(to)e(b)q(e)g(prop)q(erly)h(terminated)e
+(if)h(it)f(either)i(con)o(tains)f(no)g(lines,)295 2291 y(or)j(if)f(the)h
+(last)g(line)f(in)g(the)i(\014le)e(is)h(terminated)f(b)o(y)h(an)f
+(end-of-line)g(mark)o(er.)26 b(If)16 b(the)h(scanner)295 2341
+y(detects)i(that)e(an)f(input)g(\014le)h(is)g(not)f(prop)q(erly)h
+(terminated,)f(it)h(adds)f(an)h(end-of-line)f(mark)o(er)295
+2391 y(itself)e(\(to)g(the)g(cop)o(y)g(in)f(memory)f(only\).)295
+2459 y Fo(Unprin)o(tab)o(le)i(Characters:)21 b Fr(The)16 b(second)h(c)o(hec)o
+(k)f(the)g(scanner)h(mak)o(es)d(is)i(for)f(unprin)o(table)295
+2509 y(c)o(haracters)j(\(ASCI)q(I)f(0{31)e(and)h(127{255)f(\(except)j(for)e
+(EOL\(10\)\)\))h(whic)o(h)f(it)g(\015ags)g(as)g(errors)295
+2559 y(and)e(replaces)h(b)o(y)f(question)g(marks.)295 2627
+y Fo(Line)22 b(Lengths:)31 b Fr(The)21 b(third)g(c)o(hec)o(k)g(the)h(scanner)
+g(mak)o(es)d(is)i(input)g(line)f(length.)38 b(When)295 2677
+y(F)m(unnelW)m(eb)18 b(starts)g(up,)h(a)e(default)h(maxim)n(um)c(input)j
+(line)h(length)g(of)f(80)g(is)h(set.)31 b(This)17 b(can)295
+2727 y(b)q(e)22 b(c)o(hanged)f(dynamically)d(during)i(scanning)h(using)f(a)h
+Fl(@p)g(maximum)p 1461 2727 14 2 v 14 w(input)p 1585 2727 V
+15 w(line)p 1688 2727 V 15 w(length)295 2777 y Fr(pragma.)c(If)c(the)i(n)o
+(um)o(b)q(er)e(of)g(c)o(haracters)j(on)e(a)f(line)h(\(not)g(including)f(the)h
+(end)h(of)e(line)g(mark)o(er\))295 2827 y(exceeds)j(this)e(limit,)d(F)m
+(unnelW)m(eb)i(generates)j(an)d(error.)1042 2940 y(71)p eop
+%%Page: 72 73
+72 72 bop 177 42 a Fd(3.10.2)55 b(Sp)r(ecial)18 b(Sequences)177
+144 y Fr(The)11 b(scanner)g(scans)g(the)g(input)e(\014le)h(from)f(top)h(to)g
+(b)q(ottom,)e(left)i(to)g(righ)o(t,)g(treating)g(the)h(input)f(as)g(ordinary)
+f(text)177 194 y(\(to)14 b(b)q(e)g(handed)g(directly)f(to)h(the)g(parser)g
+(as)g(a)f(text)h(tok)o(en\))g(unless)g(it)f(encoun)o(ters)i(the)f
+Fo(sp)q(ecial)g(c)o(haracter)1931 179 y Fg(4)177 244 y Fr(whic)o(h)i(in)o
+(tro)q(duces)h(a)f Fo(sp)q(ecial)h(sequence)p Fr(.)23 b(Th)o(us,)17
+b(the)f(scanner)i(partitions)d(the)i(input)f(\014le)g(in)o(to)f(ordinary)177
+293 y(text)g(and)e(sp)q(ecial)i(sequences.)177 411 y Fl(input_file)20
+b(=)h({ordinary_text)e(|)j(special_sequence})177 529 y Fr(Up)q(on)11
+b(startup,)g(the)g(sp)q(ecial)g(c)o(haracter)h(is)e Fl(@)p
+Fr(,)h(but)g(it)f(can)g(b)q(e)i(c)o(hanged)e(using)h(the)g
+Fn(<)p Fr(sp)q(ecial)p Fn(>)p Fl(=)p Fn(<)p Fr(new)p 1781 529
+13 2 v 16 w(sp)q(ecial)p Fn(>)177 579 y Fr(sp)q(ecial)k(sequence.)22
+b(Rather)15 b(than)g(using)f Fn(<)p Fr(sp)q(ecial)p Fn(>)i
+Fr(whenev)o(er)g(the)f(sp)q(ecial)g(c)o(haracter)h(app)q(ears,)f(this)g(do)q
+(c-)177 629 y(umen)o(t)j(uses)j(the)f(default)e(sp)q(ecial)i(c)o(haracter)g
+(\\)p Fl(@)p Fr(")f(to)g(represen)o(t)i(the)f(curren)o(t)h(sp)q(ecial)e(c)o
+(haracter.)35 b(More)177 679 y(imp)q(ortan)o(tly)m(,)13 b(F)m(unnelW)m(eb's)i
+(error)h(messages)g(all)e(use)i(the)g(default)g(sp)q(ecial)f(c)o(haracter)i
+(in)e(their)h(error)h(mes-)177 728 y(sages)e(ev)o(en)f(if)f(the)i(sp)q(ecial)
+f(c)o(haracter)h(has)f(b)q(een)h(c)o(hanged.)177 804 y(An)i(o)q(ccurrence)i
+(of)c(the)i(sp)q(ecial)g(c)o(haracter)g(in)f(the)h(input)f(\014le)g(in)o(tro)
+q(duces)i(a)e(sp)q(ecial)g(sequence.)28 b(The)16 b(kind)177
+853 y(of)e(sp)q(ecial)g(sequence)i(is)e(determined)g(b)o(y)g(the)h(c)o
+(haracter)h(follo)o(wing)11 b(the)k(sp)q(ecial)f(c)o(haracter.)20
+b(Only)14 b(prin)o(table)177 903 y(c)o(haracters)i(can)e(follo)o(w)e(the)i
+(sp)q(ecial)g(c)o(haracter.)177 979 y(The)j(follo)o(wing)c(list)j(giv)o(es)g
+(all)e(the)j(p)q(ossible)f(c)o(haracters)i(that)e(can)h(follo)o(w)d(the)i(sp)
+q(ecial)h(c)o(haracter,)g(and)f(the)177 1028 y(legalit)o(y)c(of)g(eac)o(h)i
+(sequence.)20 b(The)13 b(\014rst)h(column)e(giv)o(es)g(the)i(ASCI)q(I)f(n)o
+(um)o(b)q(er)g(of)f(eac)o(h)i(ASCI)q(I)f(c)o(haracter.)19 b(The)177
+1078 y(second)12 b(column)e(giv)o(es)g(the)i(sp)q(ecial)f(sequence)i(for)e
+(that)g(c)o(haracter.)19 b(The)11 b(next)h(column)d(con)o(tains)i(one)g(of)f
+(three)177 1128 y(c)o(haracters:)25 b(\\)p Fl(-)p Fr(")16 b(means)g(that)h
+(the)g(sequence)i(is)d(illegal.)24 b(\\)p Fl(S)p Fr(")16 b(indicates)h(that)g
+(the)g(sequence)i(is)d(a)g Fo(simple)177 1178 y(sequence)i
+Fr(\(with)i(no)f(attributes)h(or)g(side)f(e\013ects\))j(that)d(app)q(ears)i
+(exactly)e(as)h(sho)o(wn)f(and)g(is)h(con)o(v)o(erted)177 1228
+y(directly)f(in)o(to)e(a)h(tok)o(en)h(and)f(fed)g(to)g(the)h(parser.)33
+b(Finally)m(,)17 b(\\)p Fl(C)p Fr(")g(indicates)i(that)f(the)h(sp)q(ecial)f
+(sequence)j(is)177 1278 y(complex,)12 b(p)q(ossibly)i(ha)o(ving)f(a)g(follo)o
+(wing)e(syn)o(tax)j(or)g(pro)q(ducing)g(funn)o(y)g(side)g(e\013ects.)177
+1395 y Fl(ASC)43 b(SEQ)g(COMMENT)177 1445 y(-----------------)177
+1495 y(000)152 b(\\)177 1545 y(016)174 b(|)21 b(Unprintable)f(characters)g
+(and)h(hence)g(illegal)f(specials.)177 1595 y(031)152 b(/)177
+1644 y(032)43 b(@)87 b(-)22 b(Illegal)e(\(space\).)177 1694
+y(033)43 b(@!)65 b(C)22 b(Comment.)177 1744 y(034)43 b(@")65
+b(S)22 b(Parameter)e(delimeter.)177 1794 y(035)43 b(@#)65 b(C)22
+b(Short)e(name)h(sequence.)177 1844 y(036)43 b(@$)65 b(S)22
+b(Start)e(of)i(macro)f(definition.)177 1894 y(037)43 b(@\045)65
+b(-)22 b(Illegal.)177 1943 y(038)43 b(@&)65 b(-)22 b(Illegal.)177
+1993 y(039)43 b(@')65 b(-)22 b(Illegal.)177 2043 y(040)43 b(@\()65
+b(S)22 b(Open)f(parameter)f(list.)177 2093 y(041)43 b(@\))65
+b(S)22 b(Close)e(parameter)g(list.)177 2143 y(042)43 b(@*)65
+b(-)22 b(Illegal.)177 2192 y(043)43 b(@+)65 b(C)22 b(Insert)e(newline.)177
+2242 y(044)43 b(@,)65 b(S)22 b(Parameter)e(separator.)177 2292
+y(045)43 b(@-)65 b(C)22 b(Suppress)e(end)h(of)g(line)g(marker.)177
+2342 y(046)43 b(@.)65 b(-)22 b(Illegal.)177 2392 y(047)43 b(@/)65
+b(S)22 b(Open)f(or)g(close)g(emphasised)f(text.)177 2441 y(048)43
+b(@0)65 b(-)22 b(Illegal.)177 2491 y(049)43 b(@1)65 b(S)22
+b(Formal)e(parameter)g(1.)177 2541 y(050)43 b(@2)65 b(S)22
+b(Formal)e(parameter)g(2.)177 2591 y(051)43 b(@3)65 b(S)22
+b(Formal)e(parameter)g(3.)177 2641 y(052)43 b(@4)65 b(S)22
+b(Formal)e(parameter)g(4.)p 177 2678 709 2 v 223 2705 a Ff(4)241
+2716 y Fh(This)10 b(sort)g(of)h(c)o(haracter)d(is)j(often)e(referred)g(to)h
+(as)h(the)f(\\escap)q(e)f(c)o(haracter")e(or)k(the)f(\\con)o(trol)e(c)o
+(haracter")g(in)i(other)g(systems.)177 2756 y(Ho)o(w)o(ev)o(er,)15
+b(as)f(there)g(is)g(great)g(p)q(oten)o(tial)e(to)i(confuse)f(these)g(names)g
+(with)i(the)e(\\escap)q(e")g(c)o(haracter)f(\(ASCI)q(I)i(27\))g(and)g(ASCI)q
+(I)177 2795 y(\\con)o(trol")d(c)o(haracters,)g(the)h(term)g(\\sp)q(ecial")f
+(has)i(b)q(een)f(c)o(hosen)g(instead.)18 b(This)c(results)e(in)g(the)h(terms)
+f Fa(sp)n(e)n(cial)k(char)n(acter)f Fh(and)177 2835 y Fa(sp)n(e)n(cial)f(se)n
+(quenc)n(e)p Fh(.)1042 2940 y Fr(72)p eop
+%%Page: 73 74
+73 73 bop 177 42 a Fl(053)43 b(@5)65 b(S)22 b(Formal)e(parameter)g(5.)177
+91 y(054)43 b(@6)65 b(S)22 b(Formal)e(parameter)g(6.)177 141
+y(055)43 b(@7)65 b(S)22 b(Formal)e(parameter)g(7.)177 191 y(056)43
+b(@8)65 b(S)22 b(Formal)e(parameter)g(8.)177 241 y(057)43 b(@9)65
+b(S)22 b(Formal)e(parameter)g(9.)177 291 y(058)43 b(@:)65 b(-)22
+b(Illegal.)177 340 y(059)43 b(@;)65 b(-)22 b(Illegal.)177 390
+y(060)43 b(@<)65 b(S)22 b(Open)f(macro)f(name.)177 440 y(061)43
+b(@=)65 b(C)22 b(Set)f(special)f(character.)177 490 y(062)43
+b(@>)65 b(S)22 b(Close)e(macro)h(name.)177 540 y(063)43 b(@?)65
+b(-)22 b(Illegal.)e(Reserved)g(for)h(future)g(use.)177 589
+y(064)43 b(@@)65 b(C)22 b(Insert)e(special)h(character)f(into)g(text.)177
+639 y(065)43 b(@A)65 b(S)22 b(New)f(section)f(\(level)h(1\).)177
+689 y(066)43 b(@B)65 b(S)22 b(New)f(section)f(\(level)h(2\).)177
+739 y(067)43 b(@C)65 b(S)22 b(New)f(section)f(\(level)h(3\).)177
+789 y(068)43 b(@D)65 b(S)22 b(New)f(section)f(\(level)h(4\).)177
+839 y(069)43 b(@E)65 b(S)22 b(New)f(section)f(\(level)h(5\).)177
+888 y(070)43 b(@F)65 b(-)22 b(Illegal.)177 938 y(071)43 b(@G)65
+b(-)22 b(Illegal.)177 988 y(072)43 b(@H)65 b(-)22 b(Illegal.)177
+1038 y(073)43 b(@I)65 b(C)22 b(Include)e(file.)177 1088 y(074)43
+b(@J)65 b(-)22 b(Illegal.)177 1137 y(075)43 b(@K)65 b(-)22
+b(Illegal.)177 1187 y(076)43 b(@L)65 b(-)22 b(Illegal.)177
+1237 y(077)43 b(@M)65 b(S)22 b(Tag)f(macro)g(as)g(being)g(allowed)f(to)h(be)h
+(called)e(many)h(times.)177 1287 y(078)43 b(@N)65 b(-)22 b(Illegal.)177
+1337 y(079)43 b(@O)65 b(S)22 b(New)f(macro)g(attached)f(to)h(product)f(file.)
+h(Has)g(to)h(be)f(at)h(start)e(of)i(line.)177 1386 y(080)43
+b(@P)65 b(C)22 b(Pragma.)177 1436 y(081)43 b(@Q)65 b(-)22 b(Illegal.)177
+1486 y(082)43 b(@R)65 b(-)22 b(Illegal.)177 1536 y(083)43 b(@S)65
+b(-)22 b(Illegal.)177 1586 y(084)43 b(@T)65 b(C)22 b(Typesetter)d(directive.)
+177 1636 y(085)43 b(@U)65 b(-)22 b(Illegal.)177 1685 y(086)43
+b(@V)65 b(-)22 b(Illegal.)177 1735 y(087)43 b(@W)65 b(-)22
+b(Illegal.)177 1785 y(088)43 b(@X)65 b(-)22 b(Illegal.)177
+1835 y(089)43 b(@Y)65 b(-)22 b(Illegal.)177 1885 y(090)43 b(@Z)65
+b(S)22 b(Tags)f(macro)f(as)i(being)f(allowed)f(to)h(be)h(called)e(zero)h
+(times.)177 1934 y(091)43 b(@[)65 b(-)22 b(Illegal.)e(Reserved)g(for)h
+(future)g(use.)177 1984 y(092)43 b(@\\)65 b(-)22 b(Illegal.)177
+2034 y(093)43 b(@])65 b(-)22 b(Illegal.)e(Reserved)g(for)h(future)g(use.)177
+2084 y(094)43 b(@^)65 b(C)22 b(Insert)e(control)h(character)f(into)g(text)177
+2134 y(095)43 b(@_)65 b(-)22 b(Illegal.)177 2183 y(096)43 b(@`)65
+b(-)22 b(Illegal.)177 2233 y(097)43 b(@a)65 b(\\)177 2283 y(109)43
+b(@m)87 b(|)21 b(Identical)f(to)i(@A..@Z.)177 2333 y(122)43
+b(@z)65 b(/)177 2383 y(123)43 b(@{)65 b(S)22 b(Open)f(macro)f(body/Open)g
+(literal)h(directive.)177 2433 y(124)43 b(@|)65 b(-)22 b(Illegal.)177
+2482 y(125)43 b(@})65 b(S)22 b(Close)e(macro)h(body/Close)f(literal)g
+(directive.)177 2532 y(126)43 b(@~)65 b(-)22 b(Illegal.)177
+2582 y(127)f(to)h(255)f(are)g(not)g(standard)f(printable)g(ASCII)h
+(characters)f(and)h(are)g(illegal.)177 2685 y Fr(The)11 b(most)e(imp)q(ortan)
+o(t)f(thing)i(to)g(remem)o(b)q(er)g(ab)q(out)g(the)h(scanner)g(is)f(that)h
+Fm(nothing)h(happ)n(ens)h(unless)f(the)f(sp)n(e)n(cial)177
+2735 y(char)n(acter)17 b(is)g(se)n(en.)27 b Fr(There)18 b(are)e(no)h(funn)o
+(y)f(sequences)j(that)e(will)e(cause)i(strange)h(things)e(to)h(happ)q(en.)26
+b(The)177 2785 y(b)q(est)16 b(w)o(a)o(y)e(to)g(view)h(a)f(F)m(unnelW)m(eb)g
+(do)q(cumen)o(t)g(at)h(the)g(scanner)h(lev)o(el)e(is)g(as)h(a)f(b)q(o)q(dy)h
+(of)f(text)h(punctuated)h(b)o(y)177 2835 y(sp)q(ecial)e(sequences)j(that)d
+(serv)o(e)h(to)f(structure)i(the)e(text)h(at)e(a)h(higher)g(lev)o(el.)1042
+2940 y(73)p eop
+%%Page: 74 75
+74 74 bop 177 42 a Fr(The)18 b(remaining)d(description)j(of)f(the)h(scanner)h
+(consists)f(of)f(a)g(detailed)g(description)h(of)f(the)h(e\013ect)h(of)d(eac)
+o(h)177 91 y(complex)d(sp)q(ecial)h(sequence.)177 243 y Fd(3.10.3)55
+b(Setting)18 b(the)g(Sp)r(ecial)g(Character)177 349 y Fr(The)e(sp)q(ecial)f
+(c)o(haracter)h(can)f(b)q(e)h(set)f(using)g(the)h(sequence)h
+Fn(<)p Fr(sp)q(ecial)p Fn(>)p Fl(=)p Fn(<)p Fr(newsp)q(ecialc)o(har)p
+Fn(>)p Fr(.)23 b(F)m(or)15 b(example,)177 399 y Fl(@=#)e Fr(w)o(ould)g(c)o
+(hange)i(the)f(sp)q(ecial)g(c)o(haracter)h(to)f(a)g(hash)g(\()p
+Fl(#)p Fr(\))f(c)o(haracter.)20 b(The)14 b(sp)q(ecial)g(c)o(haracter)h(ma)o
+(y)d(b)q(e)j(set)177 449 y(to)d(an)o(y)f(prin)o(table)g(ASCI)q(I)h(c)o
+(haracter)h(except)g(the)g(blank)e(c)o(haracter)i(\(i.e.)e(an)o(y)g(c)o
+(haracter)i(in)e(the)i(ASCI)q(I)f(range)177 498 y([33)p Fn(;)7
+b Fr(126]\).)15 b(In)d(normal)f(use,)i(it)f(should)g(not)g(b)q(e)h(necessary)
+i(to)d(c)o(hange)h(the)g(sp)q(ecial)f(c)o(haracter)i(of)e(F)m(unnelW)m(eb,)
+177 548 y(and)17 b(it)f(is)h(probably)f(b)q(est)i(to)e(a)o(v)o(oid)g(c)o
+(hanging)g(the)h(sp)q(ecial)g(c)o(haracter)h(so)f(as)g(not)f(to)h(confuse)g
+(F)m(unnelW)m(eb)177 598 y(readers)g(conditioned)f(to)f(the)i
+Fl(@)e Fr(c)o(haracter.)25 b(Ho)o(w)o(ev)o(er,)16 b(the)h(feature)f(is)g(v)o
+(ery)g(useful)f(where)i(the)g(text)f(b)q(eing)177 648 y(prepared)f(con)o
+(tains)f(man)o(y)e Fl(@)i Fr(c)o(haracters)h(\(e.g.)f(a)f(list)h(of)f(in)o
+(ternet)i(electronic)g(mail)c(addresses\).)177 799 y Fd(3.10.4)55
+b(Inserting)18 b(the)g(Sp)r(ecial)g(Character)h(in)n(to)f(the)g(T)-5
+b(ext)177 905 y Fr(The)13 b(sp)q(ecial)f(sequence)j Fn(<)p
+Fr(sp)q(ecial)p Fn(>)p Fl(@)e Fr(inserts)g(the)g(sp)q(ecial)g(c)o(haracter)g
+(in)o(to)f(the)h(text)f(as)h(if)e(it)h(w)o(ere)h(not)g(sp)q(ecial)177
+955 y(at)h(all.)k(The)c Fl(@)g Fr(of)f(this)i(sequence)h(has)e(nothing)g(to)f
+(do)h(with)g(the)h(curren)o(t)g(sp)q(ecial)g(c)o(haracter.)20
+b(If)14 b(the)g(curren)o(t)177 1005 y(sp)q(ecial)e(c)o(haracter)h(is)e
+Fl(P)h Fr(then)g(the)g(sequence)i Fl(P@)d Fr(will)f(insert)j(a)e
+Fl(P)g Fr(in)o(to)g(the)h(text.)18 b(Example:)e Fl(@@#@=#@#@#=@@@)177
+1055 y Fr(translates)f(to)f Fl(@#@#@)p Fr(.)177 1206 y Fd(3.10.5)55
+b(Inserting)18 b(Arbitrary)g(Characters)h(in)n(to)g(the)f(T)-5
+b(ext)177 1313 y Fr(While)13 b(F)m(unnelW)m(eb)h(do)q(es)h(not)f(tolerate)g
+(unprin)o(table)g(c)o(haracters)i(in)d(the)i(input)f(\014le)g(\(except)h(for)
+f(the)h(end)f(of)177 1362 y(line)f(c)o(haracter\),)h(it)e(do)q(es)i(allo)o(w)
+d(the)i(user)h(to)f(sp)q(ecify)h(that)e(unprin)o(table)h(c)o(haracters)i(app)
+q(ear)e(in)f(the)i(pro)q(duct)177 1412 y(\014le.)k(The)c Fl(@^)f
+Fr(sequence)j(inserts)f(a)e(single)g(c)o(haracter)i(of)e(the)i(user's)f(c)o
+(ho)q(osing)g(in)o(to)f(the)h(text.)k(The)c(c)o(haracter)177
+1462 y(can)19 b(b)q(e)g(sp)q(eci\014ed)i(b)o(y)d(giving)f(its)i(ASCI)q(I)g(n)
+o(um)o(b)q(er)f(in)g(one)h(of)f(four)h(bases:)28 b(binary)m(,)19
+b(o)q(ctal,)g(decimal,)f(and)177 1512 y(hexadecimal.)f(Here)e(is)f(the)g(syn)
+o(tax:)177 1636 y Fl(control_sequence)19 b(=)i("@^")g(char_spec)177
+1686 y(char_spec)173 b(=)21 b(binary)g(|)g(octal)g(|)h(decimal)e(|)i
+(hexadecimal)177 1736 y(binary)239 b(=)21 b(\("b")g(|)h("B"\))282
+b("\(")21 b({binary_digit}8)41 b("\)")177 1786 y(octal)261
+b(=)21 b(\("o")g(|)h("O")f(|)h("q")f(|)g("Q"\))g("\(")g({octal_digit}3)63
+b("\)")177 1835 y(decimal)217 b(=)21 b(\("d")g(|)h("D"\))282
+b("\(")21 b({decimal_digit}3)e("\)")177 1885 y(hexadecimal)129
+b(=)21 b(\("h")g(|)h("H")f(|)h("x")f(|)g("X"\))g("\(")g({hex_digit}2)107
+b("\)")177 1935 y(binary_digit)g(=)21 b("0")g(|)h("1")177 1985
+y(octal_digit)129 b(=)21 b(binary_digit)f(|)h("2")g(|)h("3")f(|)h("4")f(|)g
+("5")h(|)f("6")g(|)h("7")177 2035 y(decimal_digit)85 b(=)21
+b(octal_digit)f(|)h("8")h(|)f("9")177 2085 y(hex_digit)173
+b(=)21 b(decimal_digit)e(|)j("A")f(|)h("B")f(|)g("C")h(|)f("D")g(|)h("E")f(|)
+h("F")896 2134 y(|)g("a")f(|)h("b")f(|)g("c")h(|)f("d")g(|)h("e")f(|)h("f")
+177 2259 y Fr(Example:)177 2383 y Fl(@!)g(Unix)f(Make)f(requires)h(that)g
+(productions)e(commence)h(with)h(tab)g(characters.)177 2433
+y(@^D\(009\)prog.o)e(<-)i(prog.c)177 2557 y Fr(Note)16 b(that)g(the)g
+(decimal)e(\\)p Fl(9)p Fr(")h(is)g(expressed)j(with)d(leading)g(zeros)i(as)e
+(\\)p Fl(009)p Fr(".)22 b(F)m(unnelW)m(eb)15 b(requires)i(a)e(\014xed)177
+2607 y(n)o(um)o(b)q(er)e(of)g(digits)g(for)g(eac)o(h)h(base.)19
+b(Eigh)o(t)13 b(digits)g(for)g(base)h(t)o(w)o(o,)f(three)i(digits)e(for)g
+(base)h(ten,)g(three)h(digits)e(for)177 2657 y(base)i(eigh)o(t)e(and)h(t)o(w)
+o(o)f(digits)h(for)f(base)i(sixteen.)177 2735 y(F)m(unnelW)m(eb)h(treats)h
+(the)g(c)o(haracter)g(resulting)f(from)e(a)i Fl(@^)g Fr(sequence)i(as)e
+(ordinary)g(text)g(in)g(ev)o(ery)h(sense.)26 b(If)177 2785
+y(y)o(our)13 b(input)h(\014le)f(con)o(tains)h(man)o(y)d(instances)k(of)e(a)g
+(particular)h(con)o(trol)f(c)o(haracter,)h(y)o(ou)g(can)f(pac)o(k)n(age)g(it)
+h(up)f(in)177 2835 y(a)h(macro)e(lik)o(e)i(an)o(y)f(other)h(text.)19
+b(In)14 b(particular,)f(quic)o(k)h(names)f(can)h(b)q(e)g(used)h(to)f(great)g
+(e\013ect:)1042 2940 y(74)p eop
+%%Page: 75 76
+75 75 bop 177 42 a Fl(@!)22 b(Unix)f("Make")f(requires)g(that)h(productions)f
+(commence)g(with)h(tab)g(characters.)177 91 y(@!)h(So)f(we)g(define)g(a)g
+(macro)g(with)g(a)h(quick)f(name)f(as)i(a)f(tab)h(character.)177
+141 y($@#T@{@^D\(009\)@})177 191 y(@!)g(And)f(use)g(it)g(in)h(our)f
+(productions.)177 241 y(@#Tprog.o)f(<-)h(prog.c)177 291 y(@#Ta.out)f(<-)i
+(prog.o)177 399 y Fr(W)m(arning:)c(If)c(y)o(ou)f(insert)j(a)e(Unix)g(newline)
+g(c)o(haracter)i(\(decimal)c(10\))i(in)o(to)g(the)h(text,)f(F)m(unnelW)m(eb)g
+(will)f(treat)177 448 y(this)i(as)f(an)h(end)g(of)f(line)g(sequence)j
+(regardless)f(of)e(what)g(the)h(c)o(haracter)h(sequence)h(for)d(end)h(of)f
+(line)g(is)h(on)f(the)177 498 y(mac)o(hine)h(up)q(on)i(whic)o(h)f(it)h(is)f
+(running.)26 b(Unix)16 b(EOL)h(is)f(F)m(unnelW)m(eb's)g(in)o(ternal)g
+(represen)o(tation)i(for)e(end)h(of)177 548 y(line.)h(Th)o(us,)13
+b(in)h(the)g(curren)o(t)h(v)o(ersion)f(of)g(F)m(unnelW)m(eb,)e(inserting)i(c)
+o(haracter)i(10)d(in)o(to)g(the)h(text)h(is)e(imp)q(ossible)177
+598 y(unless)h(this)f(also)f(happ)q(ens)i(to)f(b)q(e)h(the)f(c)o(haracter)h
+(used)g(b)o(y)f(the)h(op)q(erating)e(system)h(to)g(mark)e(the)j(end)f(of)g
+(line.)177 736 y Fd(3.10.6)55 b(Commen)n(ts)177 835 y Fr(When)17
+b(F)m(unnelW)m(eb)f(encoun)o(ters)i(the)g Fl(@!)26 b Fr(sequence)18
+b(during)f(its)f(left-to-righ)o(t)g(scan)h(of)f(the)h(line,)f(it)g(thro)o(ws)
+177 885 y(a)o(w)o(a)o(y)c(the)i(rest)h(of)e(the)h(line)f(\(including)f(the)i
+(EOL\))g(without)f(analysing)f(it)h(further.)19 b(Commen)o(ts)11
+b(can)i(app)q(ear)177 934 y(in)h(an)o(y)f(line)g(except)j(\\)p
+Fl(@i)p Fr(",)c(\\)p Fl(@t)p Fr(",)h(and)g(\\)p Fl(@p)p Fr(")g(lines.)177
+1007 y(F)m(unnelW)m(eb)f(commen)o(ts)f(can)i(b)q(e)g(used)h(to)e(insert)i
+(commen)o(ts)d(in)o(to)g(y)o(our)i(input)f(\014le)h(that)g(will)e(neither)i
+(app)q(ear)177 1057 y(in)f(the)h(pro)q(duct)g(\014les)f(nor)g(in)g(the)h(do)q
+(cumen)o(tation)e(\014le,)h(but)g(will)f(b)q(e)i(solely)e(for)h(the)h(b)q
+(ene\014t)g(of)f(those)h(reading)177 1106 y(and)h(editing)f(the)i(input)e
+(\014le)h(directly)m(.)k(Example:)177 1215 y Fl(@!)k(I)f(have)g(used)g(a)h
+(quick)e(macro)h(for)g(this)g(definition)f(as)h(it)h(will)f(be)g(used)g
+(often.)177 1264 y(@$@#C@{--@})177 1372 y Fr(Because)d(commen)o(ts)d(are)i
+(de\014ned)g(to)g(include)f(the)h(end-of-line)f(mark)o(er,)f(care)i(m)o(ust)f
+(b)q(e)h(tak)o(en)f(when)h(they)177 1422 y(are)d(b)q(eing)g(added)h(or)e
+(remo)o(v)o(ed)g(within)h(the)g(text)h(of)e(macro)f(b)q(o)q(dies.)19
+b(F)m(or)13 b(example)g(the)i(text)f(fragmen)o(t)177 1530 y
+Fl(for)21 b(\(i=0;i<MAXVAL;i++\))127 b(@!)22 b(Print)f(out)g(a[0..MAXVAL-1].)
+243 1580 y(printf\("\045u\\n",a)o([i]\);)177 1688 y Fr(will)13
+b(expand)h(to)177 1796 y Fl(for)21 b(\(i=0;i<MAXVAL;i++\))193
+b(printf\("\045u\\n",a[)o(i]\);)177 1904 y Fr(This)19 b(problem)f(really)g
+(has)i(no)e(solution;)j(if)d(F)m(unnelW)m(eb)h(commen)o(ts)e(w)o(ere)j
+(de\014ned)g(to)f(omit)e(the)j(end)f(of)177 1954 y(line)14
+b(mark)o(er,)g(the)h(expanded)h(text)f(w)o(ould)f(con)o(tain)g(trailing)f
+(blanks!)20 b(As)c(it)e(is,)g(F)m(unnelW)m(eb)g(commen)o(ts)f(are)177
+2004 y(designed)18 b(to)f(supp)q(ort)h(single)f(line)g(commen)o(ts)f(whic)o
+(h)h(can)g(b)q(e)h(inserted)h(and)e(remo)o(v)o(ed)f(as)h(a)g(line)g(without)
+177 2054 y(causing)d(trouble.)k(F)m(or)c(example:)177 2162
+y Fl(@!)22 b(Print)e(out)h(a[0..MAXVAL-1].)177 2212 y(for)g
+(\(i=0;i<MAXVAL;i++\))243 2261 y(printf\("\045u\\n",a)o([i]\);)177
+2369 y Fr(If)13 b(y)o(ou)g(w)o(an)o(t)g(a)g(commen)o(t)f(construct)j(that)e
+(do)q(es)h(not)g(enclose)g(the)g(end)g(of)f(line)g(mark)o(er,)f(com)o(bine)g
+(the)i(insert)177 2419 y(end)h(of)e(line)g(construct)j Fl(@+)d
+Fr(with)h(the)g(commen)o(t)e(construct)k Fl(@!)i Fr(as)c(in)177
+2527 y Fl(for)21 b(\(i=0;i<MAXVAL;i++\))127 b(@+@!)21 b(Print)g(out)g
+(a[0..MAXVAL-1].)243 2577 y(printf\("\045u\\n",a)o([i]\);)177
+2685 y Fr(F)m(unnelW)m(eb)d(commen)o(ts)f(should)h(really)g(only)g(b)q(e)h
+(used)g(to)g(commen)o(t)d(the)j(F)m(unnelW)m(eb)f(constructs)j(b)q(eing)177
+2735 y(used)d(in)e(the)h(input)f(\014le.)26 b(Commen)o(ts)14
+b(on)j(the)g(target)g(co)q(de)g(are)g(b)q(est)h(placed)e(in)g(commen)o(ts)f
+(in)h(the)h(target)177 2785 y(language)d(or)h(in)f(the)h(do)q(cumen)o(ting)f
+(text)i(surrounding)f(the)g(macro)e(de\014nitions.)21 b(In)15
+b(the)g(example)f(ab)q(o)o(v)o(e,)g(a)177 2835 y(C)g(commen)o(t)e(w)o(ould)h
+(ha)o(v)o(e)g(b)q(een)j(more)c(appropriate.)1042 2940 y(75)p
+eop
+%%Page: 76 77
+76 76 bop 177 42 a Fd(3.10.7)55 b(Quic)n(k)19 b(Names)177 148
+y Fr(F)m(unnelW)m(eb)13 b(pro)o(vides)g(a)f Fo(quic)o(k)i(name)e
+Fr(syn)o(tax)h(as)g(an)g(alternativ)o(e,)f(for)h(macros)f(whose)h(name)f
+(consists)i(of)e(a)177 198 y(single)f(c)o(haracter,)h(to)e(the)i(angle)e
+(brac)o(k)o(et)h(syn)o(tax)g(usually)f(used)i(\(e.g.)e Fl(@<Sloth@>)p
+Fr(\).)15 b(A)c(quic)o(k)f(name)g(sequence)177 248 y(consists)15
+b(of)e Fl(@#)p Fn(x)g Fr(where)j Fn(x)p Fr(,)d(the)h(name)f(of)g(the)i
+(macro,)d(can)i(b)q(e)g(an)o(y)g(prin)o(table)f(c)o(haracter)j(except)f
+(space.)177 374 y Fl(quick_name)20 b(=)h("@#")g(non_space_printable)177
+499 y Fr(The)14 b(result)g(is)f(iden)o(tical)f(to)h(the)h(equiv)n(alen)o(t)e
+(ordinary)h(name)f(syn)o(tax,)h(but)g(is)g(shorter.)19 b(F)m(or)13
+b(example,)e Fl(@#X)i Fr(is)177 549 y(equiv)n(alen)o(t)i(to)h
+Fl(@<X@>)p Fr(.)22 b(This)16 b(shorter)h(w)o(a)o(y)e(of)g(writing)g(one-c)o
+(haracter)j(macro)c(names)h(is)h(more)e(con)o(v)o(enien)o(t)177
+599 y(where)g(a)f(macro)f(m)o(ust)g(b)q(e)h(used)h(v)o(ery)f(often.)18
+b(F)m(or)12 b(example,)g(the)h(macro)f(calls)h(in)f(the)i(follo)o(wing)c
+(fragmen)o(t)h(of)177 649 y(an)j(Ada)g(program)e(are)i(a)g(little)f(clumsy)m
+(.)177 775 y Fl(@!)22 b(Define)e(@<D@>)h(as)g("")h(to)f(turn)g(on)g(debug)g
+(code)g(and)g("--")g(to)h(turn)f(it)g(off.)177 824 y(@$@<D@>@{--@})177
+874 y(@<D@>assert\(b>3\);)177 924 y(@<D@>if)g(x>7)g(then)g(write\("error"\))e
+(end)i(if)177 1050 y Fr(The)14 b(calls)g(can)g(b)q(e)h(shortened)g(using)f
+(the)g(alternativ)o(e)g(syn)o(tax.)177 1175 y Fl(@!)22 b(Define)e(@#|)h(as)h
+("")f(to)g(turn)g(on)h(debug)f(code)f(and)i("--")f(to)g(turn)g(it)g(off.)177
+1225 y(@$@#|@{--@})177 1275 y(@#|assert\(b>3\);)177 1325 y(@#|if)g(x>7)g
+(then)g(write\("error"\))e(end)i(if)177 1478 y Fd(3.10.8)55
+b(Inserting)18 b(End)h(of)g(Line)e(Mark)n(ers)177 1585 y Fr(An)11
+b(end)g(of)f(line)g(mark)o(er/c)o(haracter)h(can)g(b)q(e)g(inserted)h(in)o
+(to)e(the)h(text)h(using)e(the)h Fl(@+)g Fr(sequence.)19 b(This)10
+b(is)h(exactly)177 1635 y(equiv)n(alen)o(t)k(to)h(a)g(real)g(end)g(of)g(line)
+f(in)h(the)g(text)h(at)e(the)i(p)q(oin)o(t)e(where)j(it)d(o)q(ccurs.)26
+b(While)15 b(this)h(feature)h(ma)o(y)177 1684 y(sound)12 b(rather)h(useless,)
+h(it)d(is)h(v)o(ery)h(useful)f(for)g(la)o(ying)e(out)i(the)g(input)g(\014le.)
+18 b(F)m(or)11 b(example,)g(the)i(follo)o(wing)c(input)177
+1734 y(data)14 b(for)f(a)h(database)g(program)177 1860 y Fl(Animal)21
+b(=)g(Kangaroo)177 1910 y(Size)65 b(=)21 b(Medium)177 1959
+y(Speed)43 b(=)21 b(Fast)177 2059 y(Animal)g(=)g(Sloth)177
+2109 y(Size)65 b(=)21 b(Medium)177 2159 y(Speed)43 b(=)21 b(Slow)177
+2258 y(Animal)g(=)g(Walrus)177 2308 y(Size)65 b(=)21 b(Big)177
+2358 y(Speed)43 b(=)21 b(Medium)177 2484 y Fr(can)14 b(b)q(e)h(con)o(v)o
+(erted)g(in)o(to)177 2609 y Fl(Animal)21 b(=)g(Kangaroo)42
+b(@+Size)21 b(=)g(Medium)43 b(@+Speed)20 b(=)i(Fast)86 b(@+)177
+2659 y(Animal)21 b(=)g(Sloth)108 b(@+Size)21 b(=)g(Medium)43
+b(@+Speed)20 b(=)i(Slow)86 b(@+)177 2709 y(Animal)21 b(=)g(Walrus)86
+b(@+Size)21 b(=)g(Big)109 b(@+Speed)20 b(=)i(Medium)42 b(@+)177
+2835 y Fr(whic)o(h)14 b(is)g(easier)g(to)g(read,)g(and)g(more)f(easily)g
+(allo)o(ws)g(comparisons)f(b)q(et)o(w)o(een)k(records.)1042
+2940 y(76)p eop
+%%Page: 77 78
+77 77 bop 177 42 a Fd(3.10.9)55 b(Suppressing)19 b(End)g(of)g(Line)e(Mark)n
+(ers)177 137 y Fr(End)e(of)g(line)f(mark)o(ers)h(can)g(b)q(e)g(suppressed)j
+(b)o(y)c(the)i Fl(@-)e Fr(sequence.)24 b(A)15 b(single)f(o)q(ccurrence)k(of)c
+(a)h Fl(@-)g Fr(sequence)177 187 y(serv)o(es)20 b(to)e(suppress)i(only)e(the)
+g(end)h(of)f(line)f(mark)o(er)h(follo)o(wing)d(it)j(and)g(m)o(ust)f(app)q
+(ear)i Fm(exactly)f Fr(b)q(efore)h(the)177 237 y(end)e(of)f(line)h(mark)o(er)
+e(to)i(b)q(e)g(suppressed.)29 b(No)17 b(trailing)e(spaces,)j
+Fl(@!)27 b Fr(commen)o(ts,)15 b(or)h(an)o(y)h(other)g(c)o(haracters)177
+287 y(are)e(p)q(ermitted)g(b)q(et)o(w)o(een)h(a)e Fl(@-)g Fr(sequence)j(and)d
+(the)h(end)g(of)f(line)g(that)h(it)f(is)h(supp)q(osed)h(to)e(suppress.)22
+b(The)15 b Fl(@-)177 337 y Fr(sequence)i(is)d(useful)g(for)g(constructing)h
+(long)f(output)g(lines)g(without)g(them)g(ha)o(ving)f(to)h(app)q(ear)h(in)f
+(the)g(input.)177 386 y(It)e(can)h(also)e(b)q(e)i(used)g(in)e(the)i(same)e(w)
+o(a)o(y)h(as)g(the)g Fl(@+)g Fr(w)o(as)g(used)h(in)f(the)g(previous)h
+(section)g(to)f(assist)g(in)g(exp)q(osing)177 436 y(the)17
+b(structure)i(of)c(output)i(text)g(without)e(a\013ecting)i(the)g(output)f
+(text)h(itself.)25 b(Finally)m(,)15 b(it)h(is)g(in)o(v)n(aluable)e(for)177
+486 y(suppressing)h(the)g(EOL)f(after)g(the)h(op)q(ening)e(macro)g(text)i
+Fl(@)p Fq(f)e Fr(construct.)20 b(F)m(or)13 b(example:)177 583
+y Fl(@$@<Walrus@>@{@-)177 633 y(I)22 b(am)f(the)g(walrus!@})177
+729 y Fr(is)14 b(equiv)n(alen)o(t)f(to)177 826 y Fl(@$@<Walrus@>@{I)19
+b(am)i(the)g(walrus!@})177 922 y Fr(The)14 b(commen)o(t)d(construct)k(\()p
+Fl(@!)p Fr(\))j(can)13 b(also)g(b)q(e)g(used)h(to)f(suppress)i(end)f(of)f
+(lines.)k(Ho)o(w)o(ev)o(er,)d(the)f Fl(@-)g Fr(construct)177
+972 y(should)i(b)q(e)g(preferred)i(for)d(this)h(purp)q(ose)h(as)e(it)h(mak)o
+(es)e(explicit)i(the)g(programmer's)d(in)o(ten)o(t)j(to)f(suppress)j(the)177
+1022 y(end)e(of)e(line.)177 1155 y Fd(3.10.10)55 b(Include)18
+b(Files)177 1251 y Fr(F)m(unnelW)m(eb)12 b(pro)o(vides)h(an)g(include)g
+(\014le)f(facilit)o(y)f(with)i(a)f(maxim)o(um)c(depth)13 b(of)f(10.)18
+b(When)13 b(F)m(unnelW)m(eb)f(sees)i(a)177 1301 y(line)g(of)f(the)i(form)d
+Fl(@i)21 b(<filename>)p Fr(,)12 b(it)i(replaces)h(the)g(en)o(tire)f(line)g
+(\(including)f(the)i(EOL\))f(with)g(the)h(con)o(ten)o(ts)177
+1350 y(of)c(the)h(sp)q(eci\014ed)h(include)f(\014le.)17 b(F)m(unnelW)m(eb's)
+11 b(include)g(\014le)h(facilit)o(y)e(is)h(in)o(tended)h(to)g(op)q(erate)g
+(at)f(the)i(line)e(lev)o(el.)177 1400 y(If)k(the)h(last)f(line)g(of)f(the)i
+(include)g(\014le)f(is)g(not)g(terminated)g(b)o(y)g(an)g(EOL,)g(F)m(unnelW)m
+(eb)g(issues)h(a)f(w)o(arning)g(and)177 1450 y(in)o(terts)g(one)f(\(in)f(the)
+i(cop)o(y)f(in)f(memory\).)177 1519 y(The)g Fl(@i)g Fr(construct)h(is)f
+(illegal)e(if)h(it)g(app)q(ears)i(an)o(ywhere)f(except)i(at)d(the)i(start)f
+(of)f(a)h(line.)k(The)c(construct)i(m)o(ust)177 1569 y(b)q(e)e(follo)o(w)o
+(ed)e(b)o(y)h(a)g(single)g(blank.)17 b(The)c(\014le)f(name)f(is)h(de\014ned)i
+(to)e(b)q(e)h(ev)o(erything)g(b)q(et)o(w)o(een)g(the)g(blank)f(and)g(the)177
+1619 y(end)j(of)e(the)h(line)g(\(no)g(commen)o(ts)e(\()p Fl(@!)p
+Fr(\))18 b(please!\).)g(Example:)f(If)c(the)i(input)e(\014le)h(is)177
+1715 y Fl("Uh)21 b(Oh,)h(It's)e(the)i(Fuzz.)e(We're)h(busted!")f(said)h(Baby)
+g(Bear.)177 1765 y(@i)h(mr_plod.txt)177 1815 y("Quick!)f(Flush)f(the)h(stash)
+g(down)g(the)g(dunny)g(and)g(let's)g(split.")f(said)h(Father)g(Bear.)177
+1912 y Fr(and)14 b(there)h(is)f(a)f(\014le)h(called)g Fl(mr)p
+672 1912 14 2 v 15 w(plod.txt)e Fr(con)o(taining)177 2008 y
+Fl("'Ello,)21 b('Ello,)f('Ello!)h(What's)f(all)h(this)g('ere)g(then?")g(Mr)g
+(Plod)g(exclaimed.)177 2105 y Fr(then)15 b(the)f(scanner)h(translates)g(the)g
+(input)e(\014le)h(in)o(to)177 2201 y Fl("Uh)21 b(Oh,)h(It's)e(the)i(Fuzz.)e
+(We're)h(busted!")f(said)h(Baby)g(Bear.)177 2251 y("'Ello,)g('Ello,)f('Ello!)
+h(What's)f(all)h(this)g('ere)g(then?")g(Mr)g(Plod)g(exclaimed.)177
+2301 y("Quick!)g(Flush)f(the)h(stash)g(down)g(the)g(dunny)g(and)g(let's)g
+(split.")f(said)h(Father)g(Bear.)177 2398 y Fr(As)14 b(a)g(p)q(oin)o(t)f(of)g
+(terminology)m(,)d(F)m(unnelW)m(eb)k(calls)f(the)h(original)e(input)i(\014le)
+f(the)i Fo(input)e(\014le)f Fr(and)h(calls)h(include)177 2447
+y(\014les)g(and)g(their)g(included)g(\014les)h Fo(include)e(\014les)p
+Fr(.)177 2516 y(The)g(include)f(\014le)g(construct)i(op)q(erates)g(at)e(a)g
+(v)o(ery)g(lo)o(w)g(lev)o(el.)17 b(An)12 b(include)h(line)e(can)i(app)q(ear)f
+(an)o(ywhere)h(in)f(the)177 2566 y(input)i(\014le)g(regardless)h(of)e(the)i
+(con)o(text)f(of)f(the)i(surrounding)f(lines.)177 2635 y(F)m(unnelW)m(eb)d
+(sets)i(the)g(sp)q(ecial)f(c)o(haracter)h(to)e(the)i(default)e(\()p
+Fl(@)p Fr(\))h(at)g(the)g(start)g(of)f(eac)o(h)i(include)e(\014le)h(and)g
+(restores)177 2685 y(it)h(to)g(its)f(previous)i(v)n(alue)e(at)h(the)g(end)h
+(of)e(the)i(include)f(\014le.)k(This)c(allo)o(ws)f(macro)g(libraries)g(to)h
+(b)q(e)h(constructed)177 2735 y(and)e(included)f(that)h(are)g(indep)q(enden)o
+(t)h(of)e(the)h(prev)n(ailing)e(sp)q(ecial)h(c)o(haracter)i(at)f(the)g(p)q
+(oin)o(t)f(of)g(inclusion.)16 b(The)177 2785 y(same)g(go)q(es)h(for)f(the)h
+(input)f(line)g(length)g(limit)e(whic)o(h)i(is)h(reset)h(to)e(the)h(default)f
+(v)n(alue)g(at)g(the)h(start)g(of)f(eac)o(h)177 2835 y(include)e(\014le)g
+(and)g(restored)h(to)f(its)g(previous)g(v)n(alue)f(afterw)o(ards.)1042
+2940 y(77)p eop
+%%Page: 78 79
+78 78 bop 177 42 a Fd(3.10.11)55 b(Pragmas)177 143 y Fr(Most)19
+b(to)q(ols)g(ha)o(v)o(e)f(to)h(supp)q(ort)g(some)f(essen)o(tial,)i(but)f
+(rather)h(inelegan)o(t)e(features.)33 b(In)19 b(F)m(unnelW)m(eb)f(these)177
+193 y(messy)c(bits)g(ha)o(v)o(e)f(all)g(b)q(een)i(stu\013ed)g(in)o(to)e(the)i
+(scanner's)g Fo(pragma)e Fr(\(for)h Fm(pr)n(agma)p Fr(tic\))g(construct.)177
+268 y(A)h(pragma)e(consists)j(of)e(a)h(single)f(line)g(of)g(input)h
+(\(including)f(the)h(EOL\))h(commencing)c(with)j Fl(@p)p Fr(.)20
+b(This)15 b(m)o(ust)177 318 y(b)q(e)g(follo)o(w)o(ed)e(b)o(y)h(a)g(single)g
+(space,)g(and)g(then)h(the)g(pragma)e(v)o(erb.)19 b(This)14
+b(m)o(ust)g(b)q(e)g(follo)o(w)o(ed)f(b)o(y)h(a)g(sequence)i(of)177
+368 y(zero)f(or)f(more)f(argumen)o(ts)g(separated)i(b)o(y)f(one)g(or)g(more)e
+(spaces.)20 b(F)m(our)13 b(pragmas)g(are)h(a)o(v)n(ailable)177
+485 y Fl(pragma)21 b(=)g(pragma_ident)f(|)h(pragma_mill)f(|)h(pragma_moll)f
+(|)h(pragma_typesetter)177 602 y Fr(The)14 b(follo)o(wing)e(syn)o(tax)i
+(de\014nitions)f(assist)i(in)e(de\014ning)h(the)h(pragmas.)177
+719 y Fl(s)174 b(=)22 b({")f("}+)177 768 y(ps)152 b(=)22 b(\("@p")f(|)g
+("@P"\))g(")h(")177 818 y(number)64 b(=)22 b({)f(decimal_digit)f(}+)177
+868 y(numorinf)g(=)i(number)e(|)i("infinity")177 985 y Fr(The)14
+b(argumen)o(ts)g(to)f(pragmas)g(are)h(case-sensitiv)o(e)h(and)f(m)o(ust)f(b)q
+(e)h(sp)q(eci\014ed)i(in)d(lo)o(w)o(er)h(case.)177 1060 y(Pragmas)f(are)h
+(pro)q(cessed)i(and)d(consumed)h(en)o(tirely)g(b)o(y)f(the)i(scanner.)k(The)
+14 b(parser)h(nev)o(er)g(sees)g(them)e(and)h(so)177 1110 y(they)i(can)f(pla)o
+(y)f(no)h(part)h(in)e(the)i(parser)g(lev)o(el)f(syn)o(tax.)22
+b(As)15 b(a)g(result,)h(pragma)d(lines)i(can)g(app)q(ear)h(an)o(ywhere)177
+1160 y(in)g(the)g(en)o(tire)g(input)g(\014le)g(regardless)h(of)e(the)h
+(surrounding)g(con)o(text)h(\(e.g.)e(ev)o(en)i(in)e(the)h(middle)e(of)h(a)h
+(macro)177 1209 y(de\014nition\).)i(The)c(sole)g(e\013ect)i(of)d(a)h(pragma)e
+(is)h(to)h(mo)q(dify)e(some)h(in)o(ternal)g(parameter)h(of)f(F)m(unnelW)m
+(eb.)177 1284 y(The)h(follo)o(wing)e(sections)j(describ)q(e)g(the)g(four)e(F)
+m(unnelW)m(eb)h(pragmas.)177 1418 y Fo(3.10.11.1)48 b(Inden)o(tation)177
+1520 y Fr(When)18 b(F)m(unnelW)m(eb)g(expands)g(a)g(macro,)f(it)g(can)h(do)g
+(so)g(in)f(t)o(w)o(o)h(w)o(a)o(ys.)29 b(First)18 b(it)g(can)g(treat)h(the)f
+(text)g(it)g(is)177 1570 y(pro)q(cessing)e(as)e(a)g(one-dimensional)e(stream)
+i(of)g(text,)h(and)f(merely)f(insert)i(the)g(b)q(o)q(dy)g(of)f(the)h(macro)e
+(in)h(place)177 1620 y(of)d(the)g(macro)f(call.)17 b(Second,)12
+b(it)e(can)i(treat)g(the)f(text)h(of)f(the)g(macro)f(as)h(a)g(t)o(w)o(o)g
+(dimensional)e(ob)r(ject)j(and)f(inden)o(t)177 1670 y(eac)o(h)k(line)f(of)g
+(the)h(macro)f(b)q(o)q(dy)g(b)o(y)g(the)i(amoun)o(t)c(that)j(the)g(macro)e
+(call)h(itself)g(w)o(as)h(inden)o(ted.)20 b(Consider)15 b(the)177
+1719 y(follo)o(wing)c(macros.)177 1836 y Fl(@$@<Loop)20 b(Structure@>@{@-)177
+1886 y(i=1;)177 1936 y(while)h(\(i<=N\))243 1986 y(@<Loop)f(body@>)177
+2036 y(endwhile)177 2085 y(@})177 2185 y(@$@<Loop)g(body@>@{@-)177
+2235 y(a[i]:=0;)177 2285 y(i:=i+1;@})177 2402 y Fr(Under)15
+b(the)f(regime)f(of)h Fo(no)h(inden)o(tati)o(on)10 b Fr(the)15
+b(lo)q(op)e(structure)j(macro)c(expands)j(to:)177 2518 y Fl(i=1;)177
+2568 y(while)21 b(\(i<=N\))243 2618 y(a[i]:=0;)177 2668 y(i:=i+1;)177
+2718 y(endwhile)177 2835 y Fr(Under)15 b(the)f(regime)f(of)h
+Fo(blank)g(inden)o(tati)o(on)c Fr(the)15 b(lo)q(op)e(structure)j(macro)d
+(expands)h(to:)1042 2940 y(78)p eop
+%%Page: 79 80
+79 79 bop 177 42 a Fl(i=1;)177 91 y(while)21 b(\(i<=N\))243
+141 y(a[i]:=0;)243 191 y(i:=i+1;)177 241 y(endwhile)177 363
+y Fr(The)11 b Fl(indentation)d Fr(pragma)h(determines)h(whic)o(h)h(of)f
+(these)i(t)o(w)o(o)d(regimes)h(will)f(b)q(e)i(used)h(to)e(expand)h(the)g
+(macros)177 413 y(when)k(constructing)f(the)h(pro)q(duct)g(\014les.)j(The)c
+(syn)o(tax)g(of)g(the)g(pragma)e(is:)177 535 y Fl(pragma_ident)19
+b(=)j(ps)f("indentation")f(s)h("=")g(s)h(\("blank")e(|)i("none"\))177
+658 y Fr(Its)15 b(t)o(w)o(o)e(forms)f(lo)q(ok)h(lik)o(e)g(this:)177
+780 y Fl(@p)22 b(indentation)d(=)j(blank)177 830 y(@p)g(indentation)d(=)j
+(none)177 952 y Fr(In)13 b(the)h(curren)o(t)h(v)o(ersion)f(of)e(F)m(unnelW)m
+(eb,)h(the)h(inden)o(tation)e(regime)g(is)i(an)f(attribute)g(that)h(is)f
+(attac)o(hed)h(to)f(an)177 1002 y(en)o(tire)g(run)g(of)e(T)m(angle;)h(it)g
+(is)g(not)g(p)q(ossible)h(to)f(bind)g(it)g(to)g(particular)g(pro)q(duct)h
+(\014les)g(or)f(to)g(particular)g(macros.)177 1052 y(As)h(a)e(result,)i(it)e
+(do)q(esn't)i(matter)e(where)i(inden)o(tation)f(pragmas)e(o)q(ccur)j(in)f
+(the)g(input)g(\014le)g(or)g(ho)o(w)f(man)o(y)f(there)177 1102
+y(are)k(so)g(long)f(as)h(they)h(are)f(all)f(the)h(same.)j(By)d(default)g(F)m
+(unnelW)m(eb)f(uses)i(blank)f(inden)o(tation.)177 1242 y Fo(3.10.11.2)48
+b(Maxim)o(um)15 b(Input)f(Line)g(Length)177 1348 y Fr(F)m(unnelW)m(eb)19
+b(generates)i(an)e(error)h(for)f(eac)o(h)h(input)f(line)g(that)g(exceeds)j(a)
+d(certain)h(maxim)n(um)15 b(n)o(um)o(b)q(er)j(of)177 1397 y(c)o(haracters.)i
+(A)o(t)13 b(the)h(start)g(of)f(the)h(pro)q(cessing)h(of)d(eac)o(h)i(input)f
+(\014le)h(and)f(eac)o(h)h(include)f(\014le,)g(this)h(maxim)n(um)9
+b(is)177 1447 y(set)15 b(to)f(a)g(default)g(v)n(alue)g(of)f(80.)19
+b(Ho)o(w)o(ev)o(er,)14 b(the)h(maxim)n(um)10 b(can)15 b(b)q(e)g(c)o(hanged)f
+(using)g(a)g(maxim)n(um)c(input)k(line)177 1497 y(length)g(pragma.)177
+1619 y Fl(pragma_mill)20 b(=)h(ps)h("maximum_input_l)o(ine_l)o(engt)o(h")d(s)
+i("=")h(s)f(numorinf)177 1742 y Fr(The)15 b(maxim)n(um)10 b(input)k(line)f
+(length)i(can)f(b)q(e)h(v)n(aried)f Fm(dynamic)n(al)r(ly)g
+Fr(throughout)g(the)h(input)f(\014le.)19 b(Eac)o(h)14 b(maxi-)177
+1792 y(m)o(um)7 b(input)i(line)g(length)h(pragma's)e(scop)q(e)i(co)o(v)o(ers)
+h(the)f(line)f(follo)o(wing)e(the)j(pragma)e(through)i(to)f(and)h(including)
+177 1841 y(the)17 b(next)g(maxim)n(um)12 b(input)k(line)g(length)h(pragma,)d
+(but)j(not)f(co)o(v)o(ering)g(an)o(y)g(in)o(terv)o(ening)g(include)h
+(\014les.)26 b(A)o(t)177 1891 y(the)14 b(start)g(of)f(an)g(include)h(\014le,)
+f(F)m(unnelW)m(eb)g(resets)i(the)f(maxim)o(um)9 b(input)k(line)g(length)g(to)
+h(the)g(default)f(v)n(alue.)177 1941 y(It)h(restores)i(it)e(to)f(its)h
+(previous)g(v)n(alue)g(at)f(the)i(end)f(of)g(the)g(include)g(\014le.)177
+2018 y(This)k(pragma)f(is)h(useful)g(for)g(detecting)i(text)f(that)f(has)h
+(stra)o(y)o(ed)g(o\013)f(the)h(righ)o(t)f(side)g(of)g(the)h(screen)h(when)177
+2068 y(editing.)25 b(If)16 b(y)o(ou)f(use)i(F)m(unnelW)m(eb,)f(and)g(set)i
+(the)e(maxim)o(um)c(input)k(line)f(length)i(to)f(b)q(e)h(the)f(width)g(of)g
+(y)o(our)177 2118 y(editing)g(windo)o(w,)g(y)o(ou)g(will)e(nev)o(er)k(b)q(e)f
+(caugh)o(t)f(b)o(y)m(,)g(for)g(example,)f(o\013-screen)j(op)q(ening)e(commen)
+o(t)f(sym)o(b)q(ols.)177 2168 y(Y)m(ou)d(can)g(also)f(b)q(e)i(sure)g(that)f
+(y)o(our)g(source)h(text)f(can)h(b)q(e)f(prin)o(ted)h(ra)o(w,)e(if)g
+(necessary)m(,)j(without)d(lines)h(wrapping)177 2218 y(around.)177
+2358 y Fo(3.10.11.3)48 b(Maxim)o(um)15 b(Output)e(File)h(Line)h(Length)177
+2463 y Fr(As)e(w)o(ell)e(as)i(k)o(eeping)f(an)g(ey)o(e)h(on)f(input)g(line)g
+(lengths,)g(F)m(unnelW)m(eb)g(also)g(k)o(eeps)h(an)f(ey)o(e)h(on)f(the)h
+(line)f(lengths)g(of)177 2513 y(pro)q(duct)f(\014les)f(and)g(\015ags)g(all)f
+(lines)h(longer)g(than)g(a)f(certain)i(limit)c(with)j(error)h(messages.)17
+b(Unlik)o(e)9 b(the)i(maxim)n(um)177 2563 y(input)17 b(line)f(length,)h(whic)
+o(h)g(can)g(v)n(ary)f(dynamically)e(throughout)j(the)g(input)g(\014le,)g(the)
+g(maxim)n(um)c(pro)q(duct)177 2613 y(\014le)18 b(line)e(length)i(remains)e
+(\014xed)i(throughout)f(the)h(generation)g(of)f(all)f(the)i(pro)q(duct)g
+(\014les.)29 b(The)18 b(maxim)n(um)177 2662 y(pro)q(duct)d(\014le)f(line)f
+(length)h(pragma)d(allo)o(ws)i(this)h(v)n(alue)f(to)g(b)q(e)i(set.)k(If)13
+b(there)i(is)f(more)e(than)i(one)g(suc)o(h)h(pragma)177 2712
+y(in)f(an)f(input)h(\014le,)f(the)i(pragmas)d(m)o(ust)h(all)g(sp)q(ecify)h
+(the)h(same)e(v)n(alue.)177 2835 y Fl(pragma_moll)20 b(=)h(ps)h
+("maximum_output_)o(line_)o(leng)o(th")d(s)i("=")g(s)h(numorinf)1042
+2940 y Fr(79)p eop
+%%Page: 80 81
+80 80 bop 177 42 a Fr(The)14 b(default)g(v)n(alue)f(is)h(80)f(c)o(haracters.)
+177 126 y(This)h(pragma)f(is)h(only)f(one)i(of)f(t)o(w)o(o)f(constrain)o(ts)i
+(on)f(the)h(length)f(of)g(the)h(lines)f(of)g(the)h(pro)q(duct)g(\014les.)20
+b(The)14 b Fl(+W)177 176 y Fr(command)e(line)j(option)f(also)g(con)o
+(tributes.)22 b(The)15 b(actual)f(v)n(alue)h(that)f(F)m(unnelW)m(eb)h(uses)h
+(is)e(the)i(minim)n(um)10 b(of)177 226 y(the)15 b(limits)c(sp)q(eci\014ed)16
+b(in)d(the)i(command)c(line)i(and)h(pragmas.)177 310 y(F)m(unnelW)m(eb)i(do)q
+(es)h(not)f(monitor)e(the)j(length)f(of)g(the)h(lines)f(of)f(its)h(other)h
+(output)g(\014les)f(\(journal)g(\014le,)g(listing)177 360 y(\014le,)e(do)q
+(cumen)o(tation)e(\014le\).)177 524 y Fo(3.10.11.4)48 b(T)o(yp)q(esetter)177
+639 y Fr(The)22 b Fl(typesetter)d Fr(pragma)g(allo)o(ws)h(the)i(user)h(to)e
+(sp)q(ecify)h(whether)g(the)g(input)f(\014le)g(is)g(supp)q(osed)i(to)e(b)q(e)
+177 689 y(t)o(yp)q(esetter-indep)q(ende)q(n)o(t,)15 b(or)c(whether)j(it)d
+(con)o(tains)h(commands)d(in)j(a)f(particular)h(t)o(yp)q(esetter)i(language.)
+i(The)177 739 y(pragma)c(has)i(the)h(follo)o(wing)c(syn)o(tax.)177
+879 y Fl(pragma_typesetter)18 b(=)k(ps)f("typesetter")f(s)h("=")g(s)h
+(\("none")e(|)i("tex"\))177 1020 y Fr(The)14 b(t)o(w)o(o)g(forms)e(of)i(the)g
+(pragma)e(lo)q(ok)h(lik)o(e)g(this.)177 1161 y Fl(@)22 b(typesetter)d(=)j
+(none)177 1210 y(@)g(typesetter)d(=)j(tex)177 1351 y Fr(A)17
+b(source)h(\014le)f(can)g(con)o(tain)f(more)g(than)h(one)g(t)o(yp)q(esetter)i
+(pragma,)c(but)i(they)h(m)o(ust)d(all)h(sp)q(ecify)h(the)h(same)177
+1401 y(v)n(alue.)g(The)c(default)f(is)h Fl(none)p Fr(.)j(The)e(t)o(yp)q
+(esetter)h(setting)e(a\013ects)h(t)o(w)o(o)f(things:)295 1485
+y Fo(Handling)k(of)h(free)f(text:)25 b Fr(If)17 b(the)g(t)o(yp)q(esetter)j
+(is)d(not)g Fl(none)p Fr(,)g(W)m(ea)o(v)o(e)f(writes)i(the)g(free)g(text)295
+1535 y Fm(dir)n(e)n(ctly)c Fr(to)i(the)g(do)q(cumen)o(tation)e(\014le)h
+(without)g(c)o(hanging)g(it)f(whatso)q(ev)o(er.)24 b(This)15
+b(means)g(that)295 1585 y(if)d(\(sa)o(y\))g Fl(\\centerline)e
+Fr(app)q(ears)j(in)f(the)h(input)f(\014le,)g(it)g(will)f(copied)i(directly)f
+(to)g(the)h(do)q(cumen-)295 1635 y(tation)k(\014le.)27 b(If)17
+b(the)h(t)o(yp)q(esetter)h(is)e Fl(none)p Fr(,)f(W)m(ea)o(v)o(e)h(in)o
+(tercepts)i(an)o(y)d(c)o(haracters)j(or)e(sequences)295 1685
+y(that)g(migh)o(t)d(ha)o(v)o(e)i(a)g(sp)q(ecial)g(meaning)f(to)h(the)h
+(target)f(t)o(yp)q(esetter)j(and)d(replaces)i(them)d(with)295
+1734 y(t)o(yp)q(esetter)h(commands)11 b(to)i(t)o(yp)q(eset)i(the)f(sequences)
+i(so)d(that)h(they)g(will)e(app)q(ear)i(as)f(they)h(do)f(in)295
+1784 y(the)k(input.)26 b(F)m(or)16 b(example,)f(if)g(the)i(t)o(yp)q(esetter)i
+(is)d Fl(none)g Fr(and)g(the)h(target)g(t)o(yp)q(esetter)i(is)d(T)1765
+1793 y(E)1788 1784 y(X,)295 1834 y(then)h(if)d Fl($)i Fr(\(the)g(T)581
+1843 y(E)604 1834 y(X)g(\\mathematics)d(mo)q(de")h(c)o(haracter\))j(app)q
+(ears)g(in)e(the)h(input)f(\014le,)h(it)f(will)295 1884 y(b)q(e)g(b)q(e)f
+(written)h(to)e(the)i(do)q(cumen)o(tation)e(\014le)g(as)h Fl(\\$)p
+Fr(.)295 1968 y Fo(Restrictions)f(on)j(the)g(target)f(t)o(yp)q(esetter:)i
+Fr(A)o(t)e(a)f(later)g(date,)h(di\013eren)o(t)g(w)o(ea)o(v)o(e)g(mo)q(dules)
+295 2018 y(migh)o(t)d(b)q(e)j(incorp)q(orated)g(in)o(to)f(F)m(unnelW)m(eb)g
+(to)g(cater)h(for)f(a)g(v)n(ariet)o(y)g(of)f(di\013eren)o(t)i(t)o(yp)q
+(esetters.)295 2068 y(If)k(this)f(happ)q(ens,)j(it)d(will)g(b)q(e)h(imp)q
+(ortan)o(t)e(to)i(ensure)h(that)f(t)o(yp)q(esetter-sp)q(eci\014c)j(source)e
+(\014les)295 2118 y(\(i.e.)e Fl(typesetter)e Fq(6)p Fr(=)j
+Fl(none)p Fr(\))e(are)i(not)g(pro)q(cessed)h(with)e(di\013eren)o(t)i(target)f
+(t)o(yp)q(esetters.)34 b(F)m(or)295 2168 y(example,)18 b(a)g(user)h(migh)o(t)
+d(inno)q(cen)o(tly)i(attempt)f(to)h(generate)i(a)e Fl(troff)f
+Fr(do)q(cumen)o(tation)g(\014le)295 2217 y(from)f(a)h(F)m(unnelW)m(eb)g
+(source)i(\014le)e(con)o(taining)f(a)h Fl(typesetter)j(=)i(tex)16
+b Fr(\(and)i(b)o(y)f(implication)295 2267 y(T)318 2276 y(E)341
+2267 y(X)j(con)o(trol)f(sequences\).)36 b(The)20 b(pragma)d(could)i(also)g(b)
+q(e)h(useful)f(for)g(catc)o(hing)g(t)o(yp)q(esetter)295 2317
+y(clashes)12 b(in)f(source)h(and)f(include)g(\014les.)18 b(The)11
+b(setting)h Fl(none)e Fr(is)h(sp)q(ecial)g(b)q(ecause)i(it)d(is)h(guaran)o
+(teed)295 2367 y(to)j(w)o(ork)g(with)f(an)o(y)h(future)g(target)g(t)o(yp)q
+(esetter.)177 2451 y(The)i(aim)d(of)h(all)g(this)h(is)g(to)g(ensure)h(that)g
+(an)o(y)e(t)o(yp)q(esetter)j(dep)q(endency)h(is)d(correctly)h(pro)q(claimed.)
+k(Because)177 2501 y Fl(none)12 b Fr(is)h(the)h(default)f(t)o(yp)q(esetter,)i
+(a)e(user)h(who)f(creates)i(a)e(source)i(\014le)e(without)g(a)f
+Fl(typesetter)20 b(=)i(x)13 b Fr(pragma)177 2551 y(will)d(so)q(on)i(\014nd)g
+(that)g(the)h(con)o(trol)e(sequences)j(they)f(are)f(inserting)g(in)o(to)f
+(the)h(source)h(do)q(cumen)o(t)f(are)g(app)q(earing)177 2601
+y(v)o(erbatim)i(in)h(the)g(prin)o(ted)h(do)q(cumen)o(tation!)21
+b(In)15 b(order)h(to)f(activ)n(ate)g(these)h(sequences,)i(they)e(will)d(b)q
+(e)j(forced)177 2651 y(to)e(add)g(a)f Fl(typesetter)f Fr(pragma,)g(th)o(us)i
+(making)d(the)k(dep)q(endency)h(explicit.)177 2735 y(It)f(ma)o(y)d(seem)j
+(strange)g(to)f(place)h(the)g Fl(typesetter)d Fr(setting)j(facilit)o(y)e
+(within)h(a)g(pragma)f(\()p Fl(@p)p Fr(\))h(when)h(there)h(is)177
+2785 y(a)e(separate)i(t)o(yp)q(esetting)g(construct)g(\()p
+Fl(@t)p Fr(\).)k(This)15 b(has)g(b)q(een)g(done)g(to)g(sustain)g(the)g(rule)g
+(of)f(th)o(um)o(b)f(that)i(sa)o(ys)177 2835 y(that)f(pragmas)e(do)i(not)g
+(participate)g(in)f(the)i(parser-lev)o(el)f(syn)o(tax,)g(but)g(t)o(yp)q
+(esetter)i(directiv)o(es)f(do.)1042 2940 y(80)p eop
+%%Page: 81 82
+81 81 bop 177 42 a Fd(3.10.12)55 b(F)-5 b(reestanding)19 b(T)n(yp)r(esetter)d
+(Directiv)n(es)177 141 y Fr(F)m(unnelW)m(eb)c(pro)o(vides)g(t)o(w)o(o)g
+(kinds)g(of)g(t)o(yp)q(esetter)j(directiv)o(e)e(to)f(assist)h(the)f(user)i
+(to)e(pro)q(duce)h(do)q(cumen)o(tation.)177 191 y(These)j(are)e
+Fo(inline)d Fr(and)j Fo(freestanding)o Fr(.)i(Unlik)o(e)e(pragmas,)e(eac)o(h)
+j(of)f(these)h(categories)g(of)f(directiv)o(e)h(partic-)177
+241 y(ipates)g(in)f(the)h(parser-lev)o(el)h(syn)o(tax)e(and)h(can)g(app)q
+(ear)g(only)e(in)i(certain)g(con)o(texts)g(\(see)h(the)g(parser)f(section\).)
+177 291 y(Inline)f(directiv)o(es)i(are)f(designed)g(to)f(b)q(e)h(used)h
+(within)e(paragraphs)g(to)h(alter)f(the)h(lo)q(ok)f(of)g(the)h(enclosed)h
+(text.)177 341 y(F)m(reestanding)f(t)o(yp)q(esetter)i(directiv)o(es)f(are)f
+(designed)h(to)e(app)q(ear)i(on)e(lines)h(of)f(their)h(o)o(wn)f(and)h(ha)o(v)
+o(e)g(a)f(bigger)177 390 y(t)o(yp)q(ographical)f(impact.)177
+463 y(The)18 b(syn)o(tax)f(of)f(freestanding)i(t)o(yp)q(esetter)i(directiv)o
+(es)e(is)f(almost)e(iden)o(tical)i(to)g(that)g(of)f(pragmas.)27
+b(All)16 b(the)177 513 y(same)11 b(syn)o(tax)i(rules)f(apply)g(\(except)i
+(that)e(the)h(actual)e(k)o(eyw)o(ords)i(are)f(di\013eren)o(t\).)19
+b(The)13 b(follo)o(wing)c(subsections)177 563 y(describ)q(e)16
+b(the)e(four)g(t)o(yp)q(esetter)i(directiv)o(es)f(a)o(v)n(ailable.)177
+673 y Fl(ftd)21 b(=)h(ftd_newpage)d(|)j(ftd_toc)e(|)i(ftd_vskip)e(|)h
+(ftd_title)177 723 y(ts)43 b(=)22 b("@t)f(")177 853 y Fo(3.10.12.1)48
+b(New)17 b(P)o(age)177 953 y Fr(The)d(new)h(page)f(pragma)e(is)h(a)h(t)o(yp)q
+(esetting)h(pragma)d(with)h(the)i(follo)o(wing)c(syn)o(tax.)177
+1063 y Fl(ftd_newpage)20 b(=)h(ts)h("new_page")177 1174 y Fr(It)14
+b(only)f(form)f(lo)q(oks)i(lik)o(e)f(this.)177 1284 y Fl(@t)22
+b(new_page)177 1394 y Fr(Its)15 b(sole)f(e\013ect)i(is)e(to)g(cause)i(a)e
+(\\skip)g(to)g(a)g(new)g(page")g(command)e(to)i(b)q(e)h(inserted)h(in)o(to)d
+(the)i(do)q(cumen)o(tation)177 1444 y(\014le.)21 b(The)15 b(new)h(page)e
+(command)f(is)h(suc)o(h)i(that)f(if)f(the)h(t)o(yp)q(esetter)i(is)e(already)g
+(at)f(the)i(top)e(of)h(a)f(page,)h(it)f(will)177 1494 y(skip)g(to)g(the)g
+(top)g(of)f(the)i(next)f(page.)177 1624 y Fo(3.10.12.2)48 b(T)l(able)15
+b(of)g(Con)o(ten)o(ts)177 1724 y Fr(The)f(new)h(page)f(pragma)e(is)h(a)h(t)o
+(yp)q(esetting)h(pragma)d(with)h(the)i(follo)o(wing)c(syn)o(tax.)177
+1834 y Fl(ftd_toc)21 b(=)g(ts)g("table_of_contents")177 1944
+y Fr(It)14 b(only)f(form)f(lo)q(oks)i(lik)o(e)f(this.)177 2055
+y Fl(@t)22 b(table_of_conten)o(ts)177 2165 y Fr(Its)16 b(sole)f(e\013ect)h
+(is)f(to)g(instruct)h(W)m(ea)o(v)o(e)f(to)f(insert)i(a)f(table)g(of)f(con)o
+(ten)o(ts)i(at)f(this)g(p)q(oin)o(t)g(in)f(the)i(prin)o(ted)g(do)q(cu-)177
+2215 y(men)o(tation.)g(This)e(pragma)e(do)q(es)j(not)f(skip)f(to)h(a)g(top)g
+(of)f(a)g(new)i(page)f(\014rst.)177 2345 y Fo(3.10.12.3)48
+b(V)l(ertical)14 b(Skip)177 2445 y Fr(The)e(v)o(ertical)f(skip)g(pragma)f(is)
+h(a)g(t)o(yp)q(esetting)i(pragma)c(that)j(instructs)g(W)m(ea)o(v)o(e)f(to)g
+(insert)i(a)e(sp)q(eci\014ed)i(amoun)o(t)177 2495 y(of)g(v)o(ertical)h(space)
+h(in)o(to)e(the)i(do)q(cumen)o(tation.)i(The)d(pragma)e(has)i(the)g(follo)o
+(wing)e(syn)o(tax.)177 2605 y Fl(ftd_vskip)20 b(=)i(ts)f("vskip")f(s)i
+(number)f(s)g("mm")177 2715 y Fr(F)m(or)14 b(example:)177 2825
+y Fl(@t)22 b(vskip)e(26)i(mm)1042 2940 y Fr(81)p eop
+%%Page: 82 83
+82 82 bop 177 42 a Fo(3.10.12.4)48 b(Title)177 147 y Fr(The)14
+b(title)g(pragma)e(is)i(a)f(t)o(yp)q(esetting)i(pragma)d(with)i(the)g(follo)o
+(wing)e(syn)o(tax.)177 269 y Fl(ftd_title)20 b(=)i(ts)f("title")f(s)i(font)f
+(s)h(alignment)d(text)177 319 y(font)130 b(=)22 b("normalfont")d(|)j
+("titlefont")d(|)j("smalltitlefont")177 369 y(alignment)e(=)i("left")e(|)i
+("centre")e(|)i("right")177 419 y(text)130 b(=)22 b("""")f({printable_char})d
+("""")177 541 y Fr(It's)f(e\013ect)i(is)d(to)h(instruct)h(W)m(ea)o(v)o(e)e
+(to)h(insert)h(a)e(single)h(line)f(in)o(to)g(the)i(prin)o(ted)f(do)q(cumen)o
+(tation)f(con)o(taining)177 591 y(the)e(sp)q(eci\014ed)i(text)e(set)g(in)f
+(the)i(sp)q(eci\014ed)g(fon)o(t)e(and)g(aligned)g(in)g(the)h(sp)q(eci\014ed)i
+(manner.)h(The)d(double)f(quotes)177 641 y(delimiting)g(the)j(text)g(are)f
+(for)h(sho)o(w)f(only;)g(if)f(y)o(ou)h(w)o(an)o(t)g(to)g(put)h(a)f(double)g
+(quote)h(in)f(the)h(string,)f(y)o(ou)g(don't)177 691 y(need)g(to)f(double)g
+(them.)177 768 y(Here)h(is)f(an)g(example)e(of)i(the)g(pragma.)177
+890 y Fl(@t)22 b(title)e(smalltitlefont)f(centre)i("How)g(to)g(Flip)g(a)h
+(Bit")177 1039 y Fd(3.10.13)55 b(Scanner/P)n(arser)20 b(In)n(terface)177
+1144 y Fr(If)12 b(the)g(scanner)i(terminates)d(without)h(an)o(y)f(errors,)i
+(con)o(trol)f(is)g(passed)h(to)f(the)g(parser.)19 b(The)12
+b(parser)h(parses)g(the)177 1194 y(tok)o(en)h(list)f(generated)i(b)o(y)f(the)
+g(scanner.)19 b(The)c(tok)o(en)e(list)h(consists)g(of)f(text)i(scraps,)f
+(freestanding)g(t)o(yp)q(esetter)177 1244 y(directiv)o(es,)h(and)e(sp)q
+(ecial)h(sequence)i(tok)o(ens.)177 1321 y(The)g(user)g(should)f(b)q(ear)h(in)
+e(mind)f(that)j Fm(the)g(sc)n(anner)g(\014nishes)h(running)f(b)n(efor)n(e)g
+(the)g(p)n(arser)f(starts)g(running.)177 1371 y Fr(This)g(means)g(that)g(the)
+g(scanner)i(cannot)e(b)q(e)h(in\015uenced)g(in)f(an)o(y)g(w)o(a)o(y)f(b)o(y)h
+(higher)g(order)h(structures)i(suc)o(h)e(as)177 1421 y(the)d(parser)g(migh)o
+(t)d(parse.)18 b(F)m(or)12 b(example,)f(it)g(is)h(imp)q(ossible)f(to)h(write)
+g(a)g(F)m(unnelW)m(eb)f(macro)g(to)h(include)g(a)g(\014le,)177
+1471 y(or)i(insert)h(a)e Fl(vskip)g Fr(pragma)f(in)o(to)h(the)i(input)e
+(text.)177 1641 y Fi(3.11)70 b(P)n(arser)177 1760 y Fr(By)19
+b(the)f(time)f(the)i(parser)g(starts,)h(the)f(scanner)h(has)e(completely)f
+(terminated.)30 b(A)o(t)18 b(this)h(p)q(oin)o(t,)f(it)g(is)g(not)177
+1810 y(p)q(ossible)d(for)f(an)o(y)g(more)f(\014les)i(to)f(b)q(e)h(included,)f
+(and)h(sp)q(ecial)f(c)o(haracters)j(are)d(no)h(longer)f(presen)o(t)i(to)e
+(confuse)177 1860 y(things.)29 b(All)17 b(that)h(remains)e(is)i(a)f(list)g
+(of)g Fo(text)j(tok)o(ens)p Fr(,)c Fo(sp)q(ecial)j(tok)o(ens)p
+Fr(,)e(and)g Fo(t)o(yp)q(esetter)h(directiv)o(e)177 1910 y(tok)o(ens)p
+Fr(.)f(T)m(ext)c(tok)o(ens)i(consist)f(en)o(tirely)g(of)f(sequences)j(of)e
+(prin)o(table)f(c)o(haracters)j(and)d(end)h(of)g(line)f(mark)o(ers.)177
+1959 y(Sp)q(ecial)g(tok)o(ens)h(represen)o(t)h(the)f(sp)q(ecial)f(sequences)j
+(that)d(the)h(scanner)g(found)f(in)f(the)i(input)f(\014le.)18
+b(T)o(yp)q(esetter)177 2009 y(directiv)o(e)12 b(tok)o(ens)h(represen)o(t)h
+(the)e(freestanding)g(t)o(yp)q(esetter)i(directiv)o(es)f(that)f(the)g
+(scanner)h(encoun)o(tered.)19 b(The)177 2059 y(parser)13 b(consumes)f(the)g
+(tok)o(en)g(list)g(and)f(builds)h(a)f(macro)g(table)g(that)h(is)g(later)g
+(used)g(to)g(generate)h(pro)q(duct)g(\014les.)177 2109 y(It)h(also)f
+(constructs)j(a)e(do)q(cumen)o(t)f(list)h(that)g(is)f(used)i(to)f(generate)h
+(the)g(do)q(cumen)o(tation)d(\014le.)177 2186 y(The)i(syn)o(tax)g(rules)h
+(app)q(earing)f(in)f(the)h(follo)o(wing)e(sections)j(refer)g(to)e(the)i(tok)o
+(en)f(list.)177 2335 y Fd(3.11.1)55 b(High)19 b(Lev)n(el)e(Structure)177
+2440 y Fr(A)o(t)c(the)g(highest)g(lev)o(el,)f(the)h(F)m(unnelW)m(eb)f(parser)
+i(parses)f(the)h(input)e(\014le)g(\(tok)o(en)h(list\))f(in)o(to)g(a)h
+(sequence)h(of)e(text)177 2490 y(scraps,)j(macro)d(de\014nitions,)i(and)g(t)o
+(yp)q(esetter)i(directiv)o(es.)177 2613 y Fl(input_file)k(=)h({text)g(|)h
+(macro)f(|)g(directive})177 2735 y Fr(All)f(three)i(of)e(these)i(kinds)f(of)f
+(comp)q(onen)o(ts)g(con)o(tribute)h(to)g(the)g(do)q(cumen)o(tation)e(\014le,)
+j(but)f(only)f(macro)177 2785 y(de\014nitions)15 b(con)o(tribute)g(to)f(the)h
+(pro)q(duct)h(\014les.)k(If)14 b(all)g(the)h(free)g(text)g(and)g(directiv)o
+(es)g(w)o(ere)h(remo)o(v)o(ed)d(from)g(a)177 2835 y(F)m(unnelW)m(eb)h(input)f
+(\014le,)h(the)g(pro)q(duct)h(\014les)f(w)o(ould)f(not)h(b)q(e)h(a\013ected.)
+1042 2940 y(82)p eop
+%%Page: 83 84
+83 83 bop 177 42 a Fd(3.11.2)55 b(F)-5 b(ree)19 b(T)-5 b(ext)177
+142 y Fo(F)l(ree)18 b(text)e Fr(is)g(an)o(y)f(text)i(that)g(is)f(not)g(part)g
+(of)g(a)g(macro)f(de\014nition)g(or)i(a)f(directiv)o(e.)25
+b(A)16 b(scrap)i(of)d(free)i(text)177 192 y(consists)j(of)d(a)h(sequence)j
+(of)d(items)f(dra)o(wn)h(from)f(the)i(follo)o(wing)d(list:)26
+b(non-sp)q(ecial)18 b(prin)o(table)g(c)o(haracters,)177 241
+y(insert-eol)f(sp)q(ecial)g(sequences,)j(insert)d(sp)q(ecial)g(c)o(haracter)h
+(sp)q(ecial)f(sequences,)i(insert)f(arbitrary)e(c)o(haracter)177
+291 y(sp)q(ecial)e(sequence.)177 403 y Fl(free_text)129 b(=)22
+b(ordinary_text)177 452 y(ordinary_text)41 b(=)22 b({ordinary_char)d(|)i(eol)
+g(|)h(text_special}+)177 502 y(text_special)63 b(=)22 b("@+")f(|)g("@@")g(|)h
+("@^")f(char_spec)177 552 y(ordinary_char)41 b(=)22 b(")f(".."~"-special)177
+664 y Fr(An)14 b(example)f(of)g(some)g(rather)i(messy)e(free)i(text)g(is)e
+(as)h(follo)o(ws:)177 775 y Fl(This@@)21 b(is)g(a)h(very@+)e(messy)177
+825 y(@^D\(009\)chunk)f(of)j(text)f(indeed.)177 875 y(But)g(FunnelWeb)f
+(still)h(views)g(it)g(as)177 925 y(a)h(single)e(chunk)h(of)g(text.)177
+1036 y Fr(F)m(unnelW)m(eb)16 b(nev)o(er)h(sees)i(t)o(w)o(o)c(text)j(c)o(h)o
+(unks)f(next)g(to)f(eac)o(h)h(other)g(in)f(the)h(input;)g(they)g(are)g(alw)o
+(a)o(ys)e(merged)177 1086 y(in)o(to)e(a)h(single)f(text)i(tok)o(en.)177
+1159 y(The)j(free)f(text)h(in)f(an)g(input)f(\014le)h(do)q(es)h(not)f
+(a\013ect)h(the)g(pro)q(duct)g(\014les.)28 b(Ho)o(w)o(ev)o(er,)17
+b(b)o(y)g(default,)g(it)g(app)q(ears)177 1209 y(in)g(the)g(prin)o(ted)h(do)q
+(cumen)o(tation)e(exactly)h(as)g(it)f(is)h(giv)o(en)g(in)f(the)i(input)f
+(\014le,)g(except)i(that)e(it)f(is)h(\014lled)g(and)177 1259
+y(justi\014ed)d(in)o(to)g(paragraphs.)177 1332 y(An)o(y)20
+b(prin)o(table)f(c)o(haracter)i(or)e(particular)g(sequence)j(of)d(c)o
+(haracters)i(ma)o(y)d(app)q(ear)i(in)f(the)h(free)g(text)g(of)f(a)177
+1382 y(do)q(cumen)o(t.)30 b(F)m(unnelW)m(eb)18 b(ensures)i(that)e(they)g
+(will)f(app)q(ear)h(exactly)h(as)f(giv)o(en)f(in)h(the)g(input)g(\014le,)h
+(ev)o(en)g(if)177 1432 y(they)c(happ)q(en)g(to)f(b)q(e)g(escap)q(e)i(c)o
+(haracters)g(or)e(commands)e(in)i(the)g(target)h(t)o(yp)q(esetter.)21
+b(Ho)o(w)o(ev)o(er,)14 b(F)m(unnelW)m(eb)177 1482 y(also)j(pro)o(vides)h(a)g
+(sp)q(ecial)g(mo)q(de)e(that)i(allo)o(ws)f(this)g(censoring)i(to)e(b)q(e)i(o)
+o(v)o(erridden.)30 b(See)18 b(Section)g(for)g(more)177 1532
+y(information.)177 1671 y Fd(3.11.3)55 b(T)n(yp)r(esetter)17
+b(Directiv)n(es)177 1771 y Fr(F)m(unnelW)m(eb)e(pro)o(vides)h(a)g(v)n(ariet)o
+(y)f(of)g(t)o(yp)q(esetter)j(directiv)o(es)e(to)g(assist)g(the)g(user)h(to)f
+(t)o(yp)q(eset)h(the)f(do)q(cumen)o(t)177 1821 y(in)h(a)g(t)o(yp)q
+(esetter-indep)q(ende)q(n)o(t)j(w)o(a)o(y)m(.)28 b(These)18
+b(are)g(divided)f(in)o(to)g Fo(freestandin)o(g)g(t)o(yp)q(esetter)h(directiv)
+o(es)177 1871 y Fr(\(ftd\))c(and)g Fo(inline)f(t)o(yp)q(esetter)h(directiv)o
+(es)d Fr(\(itd\).)18 b(The)d(in)o(ternal)f(syn)o(tax)g(of)f(the)i
+(freestanding)f(t)o(yp)q(esetter)177 1920 y(directiv)o(es)g(has)g(already)f
+(b)q(een)h(discussed)h(in)e(the)h(scanner)h(section.)j(The)c(follo)o(wing)d
+(syn)o(tax)i(rule)g(de\014nes)i(the)177 1970 y(con)o(text)g(in)e(whic)o(h)h
+(these)h(constructs)h(can)e(app)q(ear.)177 2082 y Fl(directive)20
+b(=)i(ftd)f(|)g(itd)177 2131 y(itd)152 b(=)22 b(section)e(|)i(literal)e(|)i
+(emphasis)177 2243 y Fr(The)14 b(remainder)g(of)f(this)h(section)h(describ)q
+(es)h(the)e(inline)f(t)o(yp)q(esetter)j(directiv)o(es.)177
+2374 y Fo(3.11.3.1)48 b(Section)177 2474 y Fr(The)19 b(section)f(directiv)o
+(e)h(pro)o(vides)f(a)f(w)o(a)o(y)h(for)f(the)i(user)g(to)e(structure)j(the)f
+(program)d(and)i(do)q(cumen)o(tation)177 2524 y(in)o(to)e(a)g(hierarc)o
+(hical)h(tree)h(structure,)g(just)f(as)g(in)f(most)f(large)i(do)q(cumen)o
+(ts.)26 b(A)16 b(section)i(construct)g(consists)177 2574 y(of)f(a)g
+(case-insensitiv)o(e)h(iden)o(tifying)e(letter,)j(whic)o(h)e(determines)h
+(the)g(absolute)f(lev)o(el)g(of)g(the)h(section)g(in)f(the)177
+2623 y(do)q(cumen)o(t,)c(and)h(an)f(optional)g(section)i(name,)d(whic)o(h)i
+(has)g(exactly)g(the)g(same)f(syn)o(tax)h(as)g(a)f(macro)g(name.)177
+2735 y Fl(section)64 b(=)22 b("@")f(levelchar)f([name])177
+2785 y(levelchar)g(=)i("A")f(|)g("B")h(|)f("C")g(|)h("D")f(|)h("E")f(|)439
+2835 y("a")g(|)g("b")h(|)f("c")g(|)h("d")f(|)h("e")1042 2940
+y Fr(83)p eop
+%%Page: 84 85
+84 84 bop 177 42 a Fr(The)15 b(section)f(construct)i(is)e(not)g(quite)g
+(\\inline")f(as)h(it)g(m)o(ust)f(app)q(ear)h(only)f(at)h(the)h(start)g(of)e
+(a)h(line.)k(Ho)o(w)o(ev)o(er,)177 91 y(unlik)o(e)10 b(the)h(\\)p
+Fl(@i)p Fr(",)f(\\)p Fl(@p)p Fr(",)g(and)g(\\)p Fl(@t)p Fr(")g(constructs,)j
+(it)d(do)q(es)h(not)g(consume)f(the)h(remainder)f(of)g(the)h(line)g
+(\(although)177 141 y(it)j(w)o(ould)f(b)q(e)h(silly)f(to)h(place)g(an)o
+(ything)f(on)g(the)i(same)e(line)g(an)o(yw)o(a)o(y\).)177 218
+y(F)m(unnelW)m(eb)d(pro)o(vides)h(\014v)o(e)g(lev)o(els)g(of)f(sections,)i
+(ranging)e(from)f(the)i(highest)g(lev)o(el)f(of)h Fl(A)f Fr(\(lik)o(e)g(a)h
+(L)1691 213 y Fk(a)1710 218 y Fr(T)1733 231 y(E)1756 218 y(X)g(c)o(hapter\))
+177 268 y(to)k(the)h(lo)o(w)o(est)g(lev)o(el)f(of)g Fl(E)g
+Fr(\(lik)o(e)g(a)g(L)752 263 y Fk(a)771 268 y Fr(T)794 281
+y(E)817 268 y(X)h(subsubsubsection\).)25 b(F)m(unnelW)m(eb)14
+b(input)i(\014les)f(need)i(not)e(con)o(tain)177 318 y(an)o(y)e(sections)i(at)
+e(all,)f(but)i(if)f(they)h(do,)f(the)h(\014rst)g(section)h(m)o(ust)d(b)q(e)i
+(at)g(lev)o(el)f Fl(A)p Fr(,)g(and)g(follo)o(wing)e(sections)k(m)o(ust)177
+368 y(not)i(skip)g(hierarc)o(hical)g(lev)o(els)h(\(e.g.)e(an)h
+Fl(@D)g Fr(cannot)g(follo)o(w)f(an)h Fl(@C)p Fr(\).)f(F)m(unnelW)m(eb)h
+(generates)i(an)e(error)h(if)e(a)177 418 y(lev)o(el)e(is)f(skipp)q(ed.)177
+495 y(All)c(section)i Fm(must)f Fr(ha)o(v)o(e)g(names)f(asso)q(ciated)i(with)
+e(them,)h(but)g(for)g(con)o(v)o(enience,)h(the)g(section)g(name)d(is)i
+(optional)177 545 y(if)16 b(the)i(section)g(con)o(tains)f(one)g(or)g(more)g
+(macro)e(de\014nitions)j(\(i.e.)e(at)h(least)g(one)g(macro)f(de\014nition)h
+(app)q(ears)177 594 y(b)q(et)o(w)o(een)i(the)f(section)g(construct)h(in)e
+(question)g(and)h(the)g(next)g(section)g(construct)h(in)e(the)g(input)h
+(\014le.\).)28 b(In)177 644 y(this)19 b(case,)g(the)g(section)g
+Fm(inherits)f Fr(the)h(name)e(of)h(the)h(\014rst)g(macro)e(de\014ned)i(in)f
+(the)h(section.)32 b(This)18 b(feature)177 694 y(streamlines)c(the)g(input)g
+(\014le,)f(a)o(v)o(oiding)f(duplicate)i(name)f(inconsistencies.)177
+771 y(An)o(y)g(sequence)i(of)d(prin)o(table)g(c)o(haracters)j(can)e(b)q(e)g
+(used)h(in)e(the)i(section)f(name,)e(ev)o(en)j(the)f(target)h(t)o(yp)q
+(esetter's)177 821 y(escap)q(e)i(sequence)g(\(e.g.)d(in)g(T)643
+830 y(E)667 821 y(X,)g(\\)p Fl(\\)p Fr("\).)177 898 y(The)h(follo)o(wing)e
+(example)g(demonstrates)j(the)f(section)h(construct.)177 1021
+y Fl(@A@<Life)20 b(Simulation@>)177 1120 y(This)h(is)h(the)f(main)g
+(simulation)e(module)i(for)g(planet)g(earth,)f(simulated)g(down)h(to)g(the)
+177 1170 y(molecular)f(level.)h(This)g(is)g(a)h(REALLY)e(big)h(program.)f(I)i
+(mean)f(really)g(big.)g(I)g(mean,)177 1220 y(if)h(you)f(thought)f(the)h
+(X-Windows)f(source)h(code)g(was)g(big,)g(you're)f(in)i(for)f(a)h(shock...)
+177 1320 y(@B)g(We)f(start)g(by)g(looking)f(at)i(the)f(code)g(for)g(six)g
+(legged)g(stick)g(insects)f(as)h(they)177 1370 y(form)g(a)h(good)f(example)f
+(of)h(a)h(typical)e(object-oriented)f(animal)i(implementation.)177
+1469 y(@$@<Six)g(Legged)f(Stick)h(Insects@>@{@-)177 1519 y(slsi.creep;)f
+(slsi.crawl;)f(slsi.creep;@})177 1641 y Fr(In)c(the)h(ab)q(o)o(v)o(e)f
+(example,)e(the)j(name)e(for)g(the)i(lev)o(el)f(A)g(section)h(is)f(pro)o
+(vided)g(explicitly)m(,)e(while)i(the)g(name)f(for)177 1691
+y(the)h(lev)o(el)e(B)h(section)h(will)d(b)q(e)j(inherited)f(from)e(the)j
+(macro)e(name.)177 1832 y Fo(3.11.3.2)48 b(Literal)13 b(Directiv)o(e)177
+1937 y Fr(Exp)q(erience)j(has)d(sho)o(wn)h(that)g(one)f(of)g(the)h(most)f
+(common)e(t)o(yp)q(esetting)j(requiremen)o(t)g(is)f(that)h(of)f(b)q(eing)g
+(able)177 1987 y(to)j(t)o(yp)q(eset)h(small)d(program)g(fragmen)o(ts)g(in)i
+(the)g(middle)e(of)h(the)i(do)q(cumen)o(ting)d(free)j(text.)24
+b(T)o(ypically)14 b(there)177 2037 y(is)g(a)g(frequen)o(t)h(need)g(to)f
+(refer)h(to)f(program)f(iden)o(ti\014ers,)h(and)g(it)g(assists)h(the)g
+(reader)g(to)f(ha)o(v)o(e)g(suc)o(h)h(iden)o(ti\014ers)177
+2087 y(t)o(yp)q(eset)g(in)d(the)i(same)e(manner)g(as)h(the)h(program)d(text)j
+(in)e(the)i(macro)d(de\014nition.)18 b(F)m(unnelW)m(eb)12 b(V1)h(de\014ned)h
+(a)177 2136 y(T)200 2145 y(E)223 2136 y(X)f(macro)f(for)h(this)g(\(called)g
+Fl(p)p Fr(\))g(that)g(simply)e(t)o(yp)q(eset)j(its)f(argumen)o(t)f(in)h
+Fl(tt)21 b(font)p Fr(.)c(This)c(pro)o(v)o(ed)g(so)g(useful,)177
+2186 y(that)h(the)h(facilit)o(y)d(has)i(b)q(een)h(made)e(t)o(yp)q
+(esetter-indep)q(enden)o(t)k(in)c(F)m(unnelW)m(eb)h(V3.)177
+2263 y(T)m(o)f(sp)q(ecify)h(that)f(some)g(text)h(b)q(e)g(t)o(yp)q(eset)h(in)e
+Fl(tt)21 b(font)p Fr(,)12 b(enclose)j(the)f(text)g(in)f(curly)g(brace)i(sp)q
+(ecial)e(sequences)177 2313 y(as)h(follo)o(ws.)177 2436 y Fl(literal)21
+b(=)g("@{")g(ordinary_text)e("@}")177 2558 y Fr(As)10 b(in)g(macro)e(names,)h
+(section)i(names,)e(and)h(macro)e(b)q(o)q(dies,)j(the)f(text)g(con)o(tained)g
+(within)f(the)h(literal)f(construct)177 2608 y(is)16 b(protected)j(b)o(y)d(F)
+m(unnelW)m(eb)g(from)f(an)o(y)h(non-literal)f(in)o(terpretation)i(b)o(y)f
+(the)h(t)o(yp)q(esetter)i(and)d(the)h(user)h(is)177 2658 y(free)d(to)e
+(enclose)i Fm(any)f Fr(text)g(co)o(v)o(ered)h(b)o(y)e(the)h(de\014nition)f
+Fl(ordinary)p 1252 2658 14 2 v 14 w(text)p Fr(.)k(F)m(unnelW)m(eb)c(guaran)o
+(tees)i(that,)e(no)177 2708 y(matter)f(what)h(the)g(text)g(is,)f(it)g(will)g
+(b)q(e)h(t)o(yp)q(eset)h(in)e Fl(tt)21 b(font)12 b Fr(exactly)h(as)f(it)h
+(app)q(ears.)18 b(Ho)o(w)o(ev)o(er,)13 b(the)g(text)g(will)177
+2757 y(b)q(e)i(\014lled)e(and)h(justi\014ed)g(in)o(to)f(a)h(paragraph)f(as)h
+(usual.)177 2835 y(Here)h(is)f(an)g(example)e(of)i(the)g(use)h(of)e(the)i
+(construct:)1042 2940 y(84)p eop
+%%Page: 85 86
+85 85 bop 177 42 a Fl(@C)22 b(The)f(@{WOMBAT@})e(\(Waste)i(Of)g(Money,)g
+(Brains,)f(And)h(Time\))g(function)177 91 y(calls)g(the)g(@{kangaroo@})e
+(input)i(function)f(which)h(has)g(been)177 141 y(known)g(to)g(cause)g
+(keybounce.)177 191 y(This)g(keybounce)f(can)h(be)h(dampened)e(using)h(the)g
+(@{wet_sloth@})e(subsystem.)177 322 y Fo(3.11.3.3)48 b(Emphasis)14
+b(Directiv)o(e)177 422 y Fr(The)g(emphasis)e(directiv)o(e)i(is)f(v)o(ery)h
+(similar)d(to)i(the)h(literal)e(directiv)o(e)i(except)h(that)e(it)g(causes)i
+(its)e(argumen)o(t)f(to)177 472 y(b)q(e)h(t)o(yp)q(eset)i(in)d(an)g
+(emphasised)h(manner)e(\(e.g.)i(italics\).)k(Lik)o(e)12 b(the)h(literal)f
+(directiv)o(e,)h(the)g(emphasis)f(directiv)o(e)177 522 y(protects)k(its)e
+(text)g(argumen)o(t.)177 633 y Fl(emphasise)20 b(=)i("@/")f(ordinary_text)e
+("@/")177 745 y Fr(Example:)177 857 y Fl(@C)j(What)f(you)g(@/really@/)e
+(need,)i(of)h(course,)e(is)h(a)h(@/great@/,)e(@/big@/,)177
+906 y(network)h(with)f(packets)h(just)g(flying)f(@/everywhere@/.)177
+956 y(This)h(section)f(implements)g(an)i(interface)177 1006
+y(to)g(such)f(a)g(@/humungeous@/)e(network.)177 1145 y Fd(3.11.4)55
+b(Macros)177 1245 y Fr(The)19 b(third)f(category)h(of)e(construct)j(app)q
+(earing)e(at)g(the)h(highest)f(syn)o(tactic)h(lev)o(el)f(in)f(a)h(F)m(unnelW)
+m(eb)g(input)177 1295 y(\014le)e(is)f(the)h(macro)e(de\014nition.)23
+b(A)15 b(macro)f(de\014nition)i(binds)f(a)g(unique)h Fo(macro)h(name)e
+Fr(to)g(a)h Fo(macro)h(b)q(o)q(dy)177 1345 y Fr(con)o(taining)e(an)g
+Fo(expression)e Fr(consisting)j(of)f(text,)h(calls)f(to)h(other)g(macros,)e
+(and)i(formal)d(parameters.)23 b(The)177 1395 y(syn)o(tax)14
+b(for)g(a)f(macro)g(de\014nition)g(is)h(as)g(follo)o(ws:)177
+1507 y Fl(macro)21 b(=)h(\("@O")e(|)i("@$"\))f(name)g([formal_paramet)o
+(er_li)o(st])352 1556 y(["@Z"])f(["@M"])h(["==")f(|)i("+="])f("@{")g
+(expression)e("@}")177 1668 y Fr(The)i(complexit)o(y)d(of)h(the)i(macro)d
+(de\014nition)i(syn)o(tax)g(is)g(mostly)e(to)i(enable)g(the)h(user)g(to)e
+(attac)o(h)h(v)n(arious)177 1718 y(attributes)d(to)f(the)g(macro.)23
+b(If)16 b(the)g(user)h(c)o(ho)q(oses)g Fl(@O)p Fr(,)e(then)i(the)f(macro)f
+(cannot)h(b)q(e)h(called,)f(but)g(is)f(instead)177 1768 y(attac)o(hed)g(to)f
+(a)g(pro)q(duct)h(\014le.)k(If)14 b(the)h(user)h(c)o(ho)q(oses)f
+Fl(@$)p Fr(,)e(then)i(the)g(macro)e(is)h(an)g(ordinary)g(macro)f
+(de\014nition)177 1817 y(that)h(is)g(not)g(attac)o(hed)g(to)g(a)f(\014le.)177
+1891 y(By)g(default,)f(a)g(non-\014le)g(macro)f(m)o(ust)g(b)q(e)i(in)o(v)o
+(ok)o(ed)f(exactly)g(once)h(b)o(y)f(one)h(other)g(macro.)j(Macros)d(that)g
+(aren't)177 1941 y(are)19 b(\015agged)e(with)h(errors)i(b)o(y)d(the)i(F)m
+(unnelW)m(eb)f(analyser.)30 b(Ho)o(w)o(ev)o(er,)19 b(if)e(the)i(user)g(uses)g
+(the)g Fl(@Z)f Fr(sequence)177 1990 y(in)f(the)h(macro)e(de\014nition,)h(the)
+h(macro)e(is)h(then)h(p)q(ermitted)f(to)g(b)q(e)h(in)o(v)o(ok)o(ed)f(zero)h
+(times,)e(as)i(w)o(ell)e(as)i(once.)177 2040 y(Similarly)l(,)13
+b(if)i(the)i(user)g(uses)g(the)g Fl(@M)e Fr(sequence)j(in)e(the)g(macro)f
+(de\014nition,)h(the)g(macro)f(is)h(p)q(ermitted)f(to)h(b)q(e)177
+2090 y(called)f(man)o(y)e(times)h(as)h(w)o(ell)f(as)h(once.)22
+b(If)15 b(b)q(oth)g Fl(@Z)f Fr(and)h Fl(@M)g Fr(are)g(presen)o(t)h(then)g
+(the)g(macro)d(is)i(p)q(ermitted)g(to)177 2140 y(b)q(e)g(in)o(v)o(ok)o(ed)e
+(zero,)h(one,)g(or)f(man)o(y)f(times.)177 2213 y(The)j(purp)q(ose)g(of)e
+(enforcing)h(the)h(default)f(\\exactly)g(one)g(call")f(rule)i(is)f(to)f
+(\015ag)h(pieces)h(of)f(co)q(de)h(that)f(the)h(user)177 2263
+y(ma)o(y)d(ha)o(v)o(e)i(de\014ned)g(in)g(a)f(macro)g(but)h(not)f(ho)q(ok)o
+(ed)h(in)o(to)f(the)h(rest)h(of)e(the)i(program.)h(Exp)q(erience)g(sho)o(ws)e
+(that)177 2313 y(this)k(is)f(a)g(common)e(error.)29 b(Similarly)m(,)14
+b(it)j(can)h(b)q(e)g(dangerous)g(to)f(m)o(ultiply)e(in)o(v)o(ok)o(e)i(a)g
+(macro)f(in)o(tended)i(to)177 2363 y(b)q(e)h(in)o(v)o(ok)o(ed)e(only)h(once.)
+31 b(F)m(or)18 b(example,)g(it)f(ma)o(y)g(b)q(e)h(dangerous)h(to)f(in)o(v)o
+(ok)o(e)f(a)h(scrap)h(of)f(non-idemp)q(oten)o(t)177 2413 y(initialization)12
+b(co)q(de)j(in)e(t)o(w)o(o)h(di\013eren)o(t)h(parts)g(of)f(the)g(main)e
+(function)i(of)g(a)g(program!)j(Ho)o(w)o(ev)o(er,)d(F)m(unnelW)m(eb)177
+2462 y(will)h(not)i(generate)h(an)f(error)g(if)f(a)h(macro)e(without)h
+Fl(@M)h Fr(is)f(called)h(b)o(y)f(another)h(macro)f(that)h(is)f(called)h(more)
+177 2512 y(than)d(once.)177 2586 y(If)f(the)h(text)g(string)g
+Fl(==)f Fr(\(or)h(nothing\))e(follo)o(ws)g(the)i(macro)f(name,)f(the)i
+(expression)g(that)g(follo)o(ws)e(is)h(the)h(en)o(tire)177
+2635 y(text)j(of)e(the)i(macro)e(b)q(o)q(dy)m(.)24 b(If)15
+b(the)i(text)g(string)f Fl(+=)f Fr(follo)o(ws)g(the)h(macro)f(name,)g(then)i
+(more)e(than)h(one)g(suc)o(h)177 2685 y(de\014nition)d(is)f(allo)o(w)o(ed)g
+(\(but)h(not)g(required\))h(in)e(the)i(do)q(cumen)o(t)e(and)h(the)h(b)q(o)q
+(dy)f(of)f(the)h(macro)f(consists)i(of)e(the)177 2735 y(concatenation)17
+b(of)g(all)e(suc)o(h)j(expressions)g(in)e(the)i(order)f(in)g(whic)o(h)f(they)
+i(o)q(ccur)g(in)e(the)h(input)g(\014le.)27 b(Suc)o(h)17 b(a)177
+2785 y(macro)12 b(is)g(said)h(to)f(b)q(e)i(additiv)o(e)d(and)i(is)g
+Fo(additiv)o(el)o(y)f(de\014ned)p Fr(.)j(Th)o(us)e(a)g(macro)e(b)q(o)q(dy)i
+(can)g(either)g(b)q(e)h(de\014ned)177 2835 y(in)g(one)h(place)g(using)f(one)h
+(de\014nition)f(\(using)g Fl(==)p Fr(\))g(or)h(it)f(can)h(b)q(e)g
+Fm(distribute)n(d)f Fr(throughout)g(the)h(input)g(\014le)f(in)g(a)1042
+2940 y(85)p eop
+%%Page: 86 87
+86 86 bop 177 42 a Fr(sequence)15 b(of)c(one)i(or)f(more)f(macro)g
+(de\014nitions)h(\(using)g Fl(+=)p Fr(\).)17 b(If)12 b(neither)h
+Fl(==)f Fr(and)g Fl(+=)g Fr(are)h(presen)o(t,)g(F)m(unnelW)m(eb)177
+91 y(assumes)h(a)g(default)f(of)g Fl(==)p Fr(.)177 169 y(Macros)g(attac)o
+(hed)g(to)f(pro)q(duct)h(\014les)f(cannot)h(b)q(e)f(additiv)o(ely)f
+(de\014ned.)19 b(Additiv)o(ely)11 b(de\014ned)i(macros)f(can)g(ha)o(v)o(e)177
+218 y(parameter)h(lists)g(and)f Fl(@Z)h Fr(and)g Fl(@M)f Fr(attributes,)i
+(but)f(these)h(m)o(ust)e(b)q(e)i(sp)q(eci\014ed)g(only)e(in)h(the)g(\014rst)h
+(de\014nition)e(of)177 268 y(the)j(macro.)h(Ho)o(w)o(ev)o(er,)e
+Fl(+=)g Fr(m)o(ust)f(app)q(ear)h(in)f(eac)o(h)i(de\014nition.)177
+409 y Fo(3.11.4.1)48 b(Names)177 514 y Fr(Names)16 b(are)g(used)i(to)e(iden)o
+(tify)f(macros)g(and)i(sections.)26 b(A)16 b(name)f(consists)j(of)d(a)h
+(sequence)j(of)c(from)g(zero)i(to)177 564 y(80)12 b(prin)o(table)h(c)o
+(haracters,)h(including)e(the)h(blank)f(c)o(haracter.)20 b(End)13
+b(of)f(line)g(c)o(haracters)j(are)e(not)g(p)q(ermitted)f(in)177
+613 y(names.)19 b(Names)13 b(are)i(case)g(sensitiv)o(e;)g(t)o(w)o(o)f
+(di\013eren)o(t)h(macros)e(are)i(p)q(ermitted)f(to)g(ha)o(v)o(e)h(names)e
+(that)h(di\013er)h(in)177 663 y(case)g(only)m(.)h(Lik)o(e)e(free)g(text,)g
+(names)e(are)i(t)o(yp)q(eset)h(b)o(y)f(F)m(unnelW)m(eb)f(and)g(are)h(safe)g
+(from)e(misin)o(terpretation)g(b)o(y)177 713 y(the)17 b(target)f(t)o(yp)q
+(esetter.)27 b(F)m(or)16 b(example,)f(it)h(is)g(quite)g(acceptable)h(to)f
+(use)h(the)g(macro)d(name)h Fl(@<\\medskip@>)177 763 y Fr(ev)o(en)g(if)e(the)
+h(target)h(t)o(yp)q(esetter)h(is)e(T)764 772 y(E)787 763 y(X.)177
+885 y Fl(name)130 b(=)22 b("@<")f(name_text)f("@>")177 935
+y(name_text)g(=)i({ordinary_char)d(|)i(text_special})177 1076
+y Fo(3.11.4.2)48 b(F)l(ormal)15 b(P)o(arameter)f(Lists)177
+1181 y Fr(F)m(unnelW)m(eb)f(allo)o(ws)e(macros)h(to)h(ha)o(v)o(e)g(up)g(to)g
+(nine)g(macro)e(parameters,)i(named)f Fl(@1)p Fr(,)g Fl(@2)p
+Fr(,)g Fn(:)7 b(:)g(:)o Fr(,)13 b Fl(@9)p Fr(.)k(If)12 b(a)h(macro)177
+1230 y(do)q(es)f(not)g(ha)o(v)o(e)f(a)g(formal)e(parameter)i(list,)g(it)g(is)
+h(de\014ned)g(to)f(ha)o(v)o(e)h(no)f(parameters,)g(and)h(an)f(actual)g
+(parameter)177 1280 y(list)k(m)o(ust)g(not)g(app)q(ear)h(at)f(the)h(p)q(oin)o
+(t)f(of)g(call.)22 b(If)15 b(a)h(macro)e(has)i(a)f(formal)e(parameter)i
+(list,)g(it)g(is)g(de\014ned)i(to)177 1330 y(ha)o(v)o(e)g(one)h(or)f(more)f
+(parameters,)h(and)h(a)e(corresp)q(onding)j(actual)d(parameter)h(m)o(ust)f(b)
+q(e)i(supplied)f(for)g(eac)o(h)177 1380 y(formal)12 b(parameter,)h(at)g(the)i
+(p)q(oin)o(t)e(of)h(call.)177 1457 y(Because)19 b(F)m(unnelW)m(eb)c
+(parameters)i(ha)o(v)o(e)f(predictable)h(names,)f(the)h(only)f(information)d
+(that)k(a)f(formal)e(pa-)177 1507 y(rameter)e(list)g(need)i(con)o(v)o(ey)e
+(is)g Fm(how)i(many)f Fr(parameters)f(a)g(macro)f(has.)18 b(F)m(or)12
+b(this)g(reason)h(a)f(formal)e(parameter)177 1557 y(list)19
+b(tak)o(es)g(the)h(form)d(of)i(the)g(highest)h(n)o(um)o(b)q(ered)e(formal)f
+(parameter)i(desired,)i(enclosed)f(in)f(paren)o(theses)177
+1606 y(sequences.)177 1729 y Fl(formal_parameter_l)o(ist)g(=)i("@\(")g
+(formal_parameter)e("@\)".)177 1779 y(formal_parameter)g(=)i("@1")g(|)h("@2")
+f(|)g("@3")g(|)h("@4")f(|)g("@5")g(|)591 1828 y("@6")g(|)h("@7")f(|)g("@8")g
+(|)h("@9")177 1977 y Fd(3.11.5)55 b(Expressions)177 2082 y
+Fr(Expressions)19 b(are)e(F)m(unnelW)m(eb's)f(most)g(p)q(o)o(w)o(erful)h
+(form)e(of)i(expressing)h(a)e(text)i(string.)28 b(Macro)17
+b(b)q(o)q(dies)g(are)177 2132 y(de\014ned)e(as)f(expressions.)20
+b(Actual)14 b(parameters)g(consist)g(of)f(expressions.)177
+2209 y(An)i(expression)h(consists)g(of)e(a)g(sequence)j(of)d(zero)i(or)e
+(more)g(expression)i(elemen)o(ts.)21 b(An)14 b(expression)i(elemen)o(t)177
+2259 y(can)i(b)q(e)g(ordinary)e(text,)j(a)e(macro)f(call,)h(or)g(a)g(formal)e
+(parameter)i(of)f(the)i(macro)e Fm(de\014nition)i Fr(in)f(whic)o(h)g(the)177
+2309 y(formal)12 b(parameter)h(o)q(ccurs.)177 2431 y Fl(expression)20
+b(=)h({ordinary_text)e(|)j(macro_call)e(|)h(formal_parameter})177
+2580 y Fd(3.11.6)55 b(Macro)19 b(Calls)177 2685 y Fr(A)d(macro)e(call)h
+(consists)i(of)e(a)g(name)g(optionally)e(follo)o(w)o(ed)h(b)o(y)i(an)f
+(actual)g(parameter)h(list.)22 b(The)16 b(n)o(um)o(b)q(er)f(of)177
+2735 y(parameters)j(in)f(the)h(actual)g(parameter)f(list)g(m)o(ust)g(b)q(e)h
+(the)h(same)d(as)i(the)g(n)o(um)o(b)q(er)f(of)h(formal)d(parameters)177
+2785 y(sp)q(eci\014ed)j(in)d(the)h(de\014nition)g(of)f(the)i(macro.)22
+b(If)16 b(the)g(macro)f(has)h(no)g(formal)d(parameter)i(list,)h(its)g(call)f
+(m)o(ust)177 2835 y(ha)o(v)o(e)f(no)g(actual)f(parameter)h(list.)1042
+2940 y(86)p eop
+%%Page: 87 88
+87 87 bop 177 42 a Fl(macro_call)260 b(=)21 b(name)g([actual_parameter_)o
+(list])177 91 y(actual_parameter_l)o(ist)e(=)i("@\(")g(actpar)g({)g("@,")g
+(actpar)g(})g("@\)")177 141 y(actpar)348 b(=)21 b(expression)f(|)700
+191 y(\()i(whitespace)e("@""")g(expression)g("@""")h(whitespace)e(\))177
+241 y(whitespace)260 b(=)21 b({")h(")f(|)h(eol})177 335 y Fr(F)m(unnelW)m(eb)
+15 b(allo)o(ws)f(parameters)h(to)h(b)q(e)f(passed)i(directly)m(,)e(or)g
+(delimited)f(b)o(y)h(sp)q(ecial)g(double)h(quotes.)22 b(Eac)o(h)177
+385 y(form)15 b(is)h(useful)g(under)h(di\013eren)o(t)g(circumstances.)26
+b(Direct)17 b(sp)q(eci\014cation)g(is)f(useful)g(where)i(the)f(parameters)177
+435 y(are)d(short)g(and)f(can)h(b)q(e)g(all)f(placed)g(on)h(one)f(line.)18
+b(Double)13 b(quoted)h(parameters)f(allo)o(w)f(whitespace)j(on)e(either)177
+485 y(side)19 b(\(that)g(is)g(not)g(considered)h(part)f(of)f(the)i
+(parameter\))e(and)h(are)g(useful)g(for)g(la)o(ying)e(out)h(rather)i(messy)
+177 535 y(parameters.)e(Here)d(are)g(examples)e(of)g(the)h(t)o(w)o(o)g
+(forms.)177 629 y Fl(@<Generic)20 b(Loop@>@\()243 679 y(@"x:=1;@")41
+b(@,)243 729 y(@"x<=10;@")19 b(@,)243 779 y(@"print)h("x=\045u,)g
+(x^2=\045u",x,x*x;)243 828 y(x:=x+1;@+@")177 878 y(@\))177
+978 y(@<Colours@>@\(red@,)o(green)o(@,blu)o(e@,ye)o(llow@)o(\))177
+1072 y Fr(As)15 b(sho)o(wn,)e(the)h(t)o(w)o(o)g(forms)e(ma)o(y)g(b)q(e)j
+(mixed)d(within)h(the)i(same)e(parameter)g(list.)177 1141 y(Exp)q(erience)j
+(has)e(sho)o(wn)g(that)g(the)g(v)n(ast)g(ma)r(jorit)o(y)e(of)h(macros)g(ha)o
+(v)o(e)h(no)f(parameters.)177 1273 y Fd(3.11.7)55 b(F)-5 b(ormal)18
+b(P)n(arameters)177 1368 y Fr(F)m(ormal)d(parameters)i(can)h(app)q(ear)g(in)f
+(the)h(expressions)h(forming)c(macro)h(b)q(o)q(dies)h(in)g(accordance)i(with)
+e(the)177 1418 y(syn)o(tax)k(rules)g(de\014ned)h(ab)q(o)o(v)o(e.)38
+b(A)21 b(formal)d(parameter)j(expands)g(to)g(the)g(text)h(of)e(the)h
+(expansion)g(of)f(its)177 1468 y(corresp)q(onding)c(actual)f(parameter.)21
+b(There)16 b(is)f(nothing)f(prev)o(en)o(ting)i(a)f(formal)d(parameter)j(b)q
+(eing)g(pro)o(vided)177 1518 y(as)g(part)h(of)e(an)h(expression)h(that)g
+(forms)d(an)i(actual)g(parameter.)21 b(In)16 b(that)f(happ)q(ens,)h(the)f
+(formal)e(parameter)177 1568 y(is)i(b)q(ound)h(to)f(the)h(actual)f(parameter)
+f(of)h(the)h(calling)e(macro,)g(not)h(the)h(called)f(macro.)21
+b(After)16 b(the)f(follo)o(wing)177 1618 y(de\014nitions,)177
+1712 y Fl(@$@<One@>@\(@1@\)=@{)o(A)k(walrus)i(in)g(@1)g(is)h(a)f(walrus)g(in)
+g(vain.@})177 1762 y(@$@<Two@>@\(@1@\)=@{)o(@<One)o(@>@\(S)o(@1n@\))o(@})177
+1856 y Fr(the)15 b(call)177 1951 y Fl(@<Two@>@\(pai@\))177
+2045 y Fr(will)e(result)h(in)g(the)g(expansion)177 2140 y Fl(A)22
+b(walrus)e(in)i(Spain)e(is)i(a)f(walrus)g(in)g(vain.)177 2272
+y Fd(3.11.8)55 b(Macros)19 b(are)g(Static)177 2368 y Fr(In)f(F)m(unnelW)m
+(eb,)g(the)g(actions)g(of)g Fm(macr)n(o)g(de\014nition)h Fr(and)e
+Fm(macr)n(o)i(exp)n(ansion)g Fr(o)q(ccur)g(during)e(t)o(w)o(o)h(separate)177
+2417 y(phases)13 b(\(parser)h(and)e(tangle\))g(and)g(cannot)g(b)q(e)h(in)o
+(terlea)o(v)o(ed.)18 b(As)12 b(a)g(result,)h(the)g(F)m(unnelW)m(eb)e(macro)g
+(facilit)o(y)g(is)177 2467 y(completely)i(static.)18 b(It)c(is)g(not)g(p)q
+(ossible)g(for)f(one)h(macro)f(to)h(de\014ne)h(another)f(while)f(the)i
+(\014rst)f(macro)f(is)h(b)q(eing)177 2517 y(expanded;)k(eac)o(h)f(m)o(ust)e
+(b)q(e)i(de\014ned)h(statically)m(.)24 b(It)17 b(is)f(not)g(p)q(ossible)h(to)
+f(de\014ne)i(a)e(macro)f(to)h(ev)o(en)h(assist)g(in)177 2567
+y(the)g(de\014nition)e(of)g(other)i(macros.)23 b(Because)18
+b(the)e(scanner,)h(parser,)g(analyser,)f(and)g(tangler)g(phases)h(are)f(all)
+177 2617 y(in)o(v)o(ok)o(ed)e(sequen)o(tially)m(,)f(there)i(is)f(no)h(ro)q
+(om)d(for)i(feedbac)o(k)h(of)f(de\014nitions)g(b)q(et)o(w)o(een)i(di\013eren)
+o(t)f(lev)o(els)f(\(e.g.)g(the)177 2666 y(user)h(cannot)f(de\014ne)h(a)f
+(macro)e(for)i(the)g Fl(vskip)f Fr(pragma\).)177 2735 y(This)k(lac)o(k)f(of)g
+(p)q(o)o(w)o(er)h(is)f(fully)f(in)o(ten)o(tional.)25 b(By)17
+b(totally)e(excluding)i(the)g(more)f(incomprehensible)g(w)o(a)o(ys)g(in)177
+2785 y(whic)o(h)d(a)h(general)f(purp)q(ose)i(macro)d(prepro)q(cessor)k(can)d
+(b)q(e)h(used,)g(F)m(unnelW)m(eb)f(pro)o(vides)h(de\014nite)g(guaran)o(tees)
+177 2835 y(to)g(the)g(reader)h(of)f(its)g(input)f(\014les:)1042
+2940 y(87)p eop
+%%Page: 88 89
+88 88 bop 239 42 a Fq(\017)21 b Fr(F)m(unnelW)m(eb)15 b(guaran)o(tees)h(that)
+f(a)g(piece)h(of)e(text)i(do)q(es)g(not)f(con)o(tain)g(a)g(macro)f(call)g
+(unless)i(it)f(con)o(tains)281 91 y(the)f(sp)q(ecial)h(c)o(haracter)g(follo)o
+(w)o(ed)d(b)o(y)i Fn(<)g Fr(or)g Fl(#)p Fr(.)239 177 y Fq(\017)21
+b Fr(F)m(unnelW)m(eb)13 b(allo)o(ws)g(calls)g(to)h(b)q(e)h(made)d(to)i
+(macros)f(that)h(are)g(de\014ned)h(later)f(in)g(the)g(input)g(\014le.)177
+343 y Fi(3.12)70 b(Analyser)177 460 y Fr(The)14 b(e\013ect)g(of)e(the)i
+(parser)g(is)f(to)g(construct)h(a)f(macro)e(table)i(con)o(taining)f(a)h
+(represen)o(tation)h(of)e(all)g(the)i(macros)177 510 y(de\014ned)19
+b(within)e(the)i(do)q(cumen)o(t,)f(and)f(a)h(do)q(cumen)o(t)f(list)h(whic)o
+(h)f(con)o(tains)h(a)g(complete)f(represen)o(tation)i(of)177
+560 y(the)f(en)o(tire)h(do)q(cumen)o(t.)28 b(If)18 b(there)h(are)f(no)f
+(error)i(diagnostics)e(\(or)h(w)o(orse\))g(at)g(the)g(end)g(of)f(the)h
+(parser)h(run,)177 610 y(F)m(unnelW)m(eb)11 b(in)o(v)o(ok)o(es)h(the)g
+(analyser)g(whic)o(h)f(tests)j(for)d(the)h(follo)o(wing)d(conditions)j(and)f
+(\015ags)h(them)f(with)g(errors)177 659 y(if)i(they)i(arise.)239
+778 y Fq(\017)21 b Fr(No)14 b(macros)f(de\014ned)i(in)e(the)i(input)e
+(\014le.)239 864 y Fq(\017)21 b Fr(No)14 b(macros)f(connected)i(to)f(output)g
+(\014les.)239 949 y Fq(\017)21 b Fr(Call)13 b(of)g(an)h(unde\014ned)h(macro.)
+239 1035 y Fq(\017)21 b Fr(Call)13 b(ha)o(ving)f(the)j(wrong)e(n)o(um)o(b)q
+(er)h(of)f(parameters.)239 1120 y Fq(\017)21 b Fr(Call)13 b(of)g(a)g(macro)g
+(that)h(is)g(connected)h(to)f(an)g(output)g(\014le.)239 1205
+y Fq(\017)21 b Fr(No)14 b(calls)f(made)g(to)h(a)f(macro)g(without)g(the)i
+Fl(@Z)e Fr(option.)239 1291 y Fq(\017)21 b Fr(More)14 b(than)g(one)g(call)f
+(made)g(to)h(a)f(macro)g(without)h(the)g Fl(@M)f Fr(option.)239
+1376 y Fq(\017)21 b Fr(Directly)14 b(or)g(indirectly)f(recursiv)o(ely)i
+(de\014ned)g(macros.)239 1461 y Fq(\017)21 b Fr(Unnamed)13
+b(sections)i(that)f(con)o(tain)f(no)h(macro)f(de\014nitions.)177
+1581 y(F)m(unnelW)m(eb)i(p)q(erforms)f(a)h(static)g(analysis)g(to)f(detect)j
+(recursion.)23 b(Unfortunately)m(,)14 b(the)i(recursion)g(detection)177
+1630 y(algorithm)i(\015ags)i(all)f(macros)g(that)h(ha)o(v)o(e)g(an)g
+(in\014nite)g(expansion)g(rather)h(than)g(just)f(all)f(macros)g(with)h(a)177
+1680 y(recursiv)o(e)15 b(de\014nition.)i(If)c(A)g(calls)g(B,)g(and)g(B)g
+(calls)g(C,)g(and)g(C)g(calls)f(B,)h(then)h(F)m(unnelW)m(eb)f(will)e(\015ag)i
+(A)g(as)g(w)o(ell)177 1730 y(as)h(B)g(and)g(C.)f(It)h(is)g(hop)q(ed)h(that)e
+(this)h(problem)f(will)f(b)q(e)j(\014xed)f(in)g(a)f(later)h(v)o(ersion.)177
+1806 y(Because)j(F)m(unnelW)m(eb)d(do)q(es)h(not)f(pro)o(vide)h(an)o(y)f
+(kind)g(of)g(conditional)f(feature,)i(the)g(prev)o(en)o(tion)g(of)f
+(recursion)177 1856 y(do)q(es)h(not)f(represen)o(t)i(a)d(curtailmen)o(t)g(of)
+g(expressiv)o(e)j(p)q(o)o(w)o(er.)177 1932 y(Macros)f(ma)o(y)d(b)q(e)i(in)o
+(v)o(ok)o(ed)f(recursiv)o(ely)m(,)h(but)g(ma)o(y)e(not)i(b)q(e)g(recursiv)o
+(e.)20 b(Th)o(us:)177 2051 y Fl(@<Sloth@>@\(@<Sloth)o(@>@\(W)o(alrus)o
+(@\)@\))106 b(@!)21 b(LEGAL)64 b(recursive)20 b(invocation.)177
+2150 y(@$@<Teapot@>==@{@<)o(Teapo)o(t@>@})193 b(@!)21 b(ILLEGAL)f(recursive)g
+(definition.)177 2316 y Fi(3.13)70 b(T)-6 b(angle)177 2434
+y Fr(If)17 b(the)g(scanner,)i(parser,)f(and)f(analyser)g(ha)o(v)o(e)g
+(successfully)h(\(i.e.)e(with)h(no)f(errors,)j(sev)o(ere)f(errors,)h(or)e
+(fatal)177 2484 y(errors\))j(completed,)f(and)f(the)h(T)m(angle)f(option)g
+(\()p Fl(+O)p Fr(\))g(is)g(turned)i(on)e(\(it)h(is)f(b)o(y)g(default\),)h
+(then)h(the)f(T)m(angle)177 2533 y(comp)q(onen)o(t)12 b(of)h(F)m(unnelW)m(eb)
+f(is)h(in)o(v)o(ok)o(ed)f(to)g(generate)j(the)e(pro)q(duct)h(\014les)f(sp)q
+(eci\014ed)i(in)d(the)h Fl(@O)g Fr(macros)f(of)g(the)177 2583
+y(input)i(\014le.)177 2659 y(The)j(op)q(eration)f(of)f(T)m(angle)g(is)h(v)o
+(ery)h(simple.)23 b(Eac)o(h)16 b Fl(@O)g Fr(macro)f(is)h(expanded)g(and)g
+(written)h(to)f(a)g(\014le)g(of)f(the)177 2709 y(same)f(name.)20
+b(As)15 b(there)i(are)e(a)f(\014nite)h(n)o(um)o(b)q(er)g(of)f(macros,)g(and)g
+(the)i(analyser)f(guaran)o(tees)h(that)f(the)g(macro)177 2759
+y(structure)h(is)e(non-recursiv)o(e,)h(T)m(angle)e(is)g(guaran)o(teed)i(to)e
+(terminate.)177 2835 y(Three)i(remaining)d(p)q(oin)o(ts)i(are)g(w)o(orth)g
+(discussing.)1042 2940 y(88)p eop
+%%Page: 89 90
+89 89 bop 228 42 a Fr(1.)20 b(T)m(angle)12 b(expands)h(macros)g(using)f
+(blank)g(inden)o(tation)h(unless)g(the)h(user)g(has)f(sp)q(eci\014ed)i
+(otherwise)f(in)e(an)281 91 y(inden)o(tation)h(pragma)f(in)i(the)g(input)g
+(\014le)g(\(see)h(Section)f(3.10.11.1\).)228 167 y(2.)20 b(T)m(angle)d(k)o
+(eeps)j(trac)o(k)f(of)e(the)i(length)g(of)f(the)h(lines)f(that)g(it)g(is)h
+(writing)e(and)i(issues)g(an)f(error)i(if)d(an)o(y)281 217
+y(line)d(of)f(an)o(y)h(pro)q(duct)h(\014le)f(that)g(it)g(generates)i(is)d
+(longer)h(than)g(the)h(maxim)n(um)o(.)h(The)e(maxim)n(um)c(is)k(the)281
+266 y(minim)n(um)9 b(of)j(a)h(v)n(alue)g(defaulted)g(or)g(sp)q(eci\014ed)i
+(in)d(the)i(input)f(\014le)g(\(Section)h(3.10.11.3\),)c(and)j(the)g(v)n(alue)
+281 316 y(\(if)g(an)o(y\))h(pro)o(vided)f(b)o(y)h(the)h Fl(+w)e
+Fr(command)e(line)j(argumen)o(t)e(\(Section)j(3.7.3\).)228
+392 y(3.)20 b(It)14 b(is)f(w)o(orth)g(the)i(user)f(obtaining)e(some)h
+(understanding)h(of)f(the)h(resources)i(that)e(F)m(unnelW)m(eb)f(requires)281
+441 y(to)h(p)q(erform)f(its)h(task.)177 531 y(When)c(F)m(unnelW)m(eb's)g
+(scanner)h(executes,)i(it)c(reads)i(eac)o(h)f(\014le)g(in)o(to)g(memory)d
+(where)k(it)f(is)g(k)o(ept)g(for)g(the)g(duration)177 581 y(of)h(the)h(run.)
+18 b(Th)o(us,)12 b(there)g(m)o(ust)f(b)q(e)h(ro)q(om)e(in)h(memory)e(for)i
+(the)h(en)o(tire)h(input)e(\014le,)g(including)g(all)f(include)i(\014les.)177
+631 y(While)k(this)h(approac)o(h)g(ma)o(y)e(seem)i(exp)q(ensiv)o(e)h(in)e
+(memory)m(,)f(it)h(is)h(almost)e(necessary)k(in)e(order)g(to)g(supp)q(ort)177
+680 y(forw)o(ard)c(references.)20 b(T)m(o)12 b(merely)g(scan)h(the)h(input)e
+(\014le,)h(recording)g(the)h(macro)d(names,)h(but)h(lea)o(ving)f(the)h(text)
+177 730 y(on)h(disk,)f(w)o(ould)g(require)i(man)o(y)d(random)g(access)k(disk)
+e(seeks.)177 797 y(In)h(con)o(trast,)h(F)m(unnelW)m(eb)f(nev)o(er)h(builds)e
+(an)h(in)o(ternal)g(represen)o(tation)i(of)d(the)i(pro)q(duct)g(\014le.)22
+b(Instead,)15 b(eac)o(h)177 847 y(piece)e(of)e(output)h(is)f(written)h
+(immediately)c(to)k(the)g(pro)q(duct)h(\014le.)k(This)11 b(means)g(that)h(as)
+g(long)e(as)i(the)g(input)g(\014le)177 897 y(\014ts)j(in)e(memory)m(,)e(the)j
+(pro)q(duct)h(\014le)f(can)g(b)q(e)h(arbitrarily)e(large.)18
+b(It)c(also)f(means)h(that)g(users)h(need)g(not)f(fear)g(to)177
+947 y(de\014ne)g(or)f(call)f(macros)g(that)h(they)g(kno)o(w)f(will)g(expand)h
+(to)f(megab)o(ytes)g(of)h(text.)18 b(Nor)13 b(need)g(they)h(fear)f(placing)
+177 997 y(a)j(call)g(to)g(suc)o(h)h(a)f(macro)f(as)h(part)g(of)g(an)g(actual)
+g(parameter.)25 b(F)m(unnelW)m(eb)15 b(do)q(es)i(not)g(ev)o(er)g(expand)f
+(actual)177 1046 y(parameters)j(in)o(ternally)m(.)31 b(In)18
+b(fact,)i(it)e(do)q(es)h(not)g(expand)g(them)f(un)o(til)f(it)i(hits)f(the)i
+(corresp)q(onding)f(formal)177 1096 y(parameter)13 b(during)g(its)g
+(expansion)g(of)g(the)h(called)e(macro.)17 b(A)o(t)c(that)g(p)q(oin)o(t,)g
+(it)g(lo)q(oks)f(up)i(the)f Fm(expr)n(ession)h Fr(\(not)177
+1146 y(the)h(expansion)e(of)h(the)g(expression\))h(for)f(the)g(corresp)q
+(onding)h(actual)f(parameter,)f(and)h(starts)h(expanding)e(it.)177
+1297 y Fi(3.14)70 b(W)-6 b(ea)n(v)n(e)177 1405 y Fr(If)17 b(the)g(scanner,)i
+(parser,)f(and)f(analyser)g(ha)o(v)o(e)g(successfully)h(\(i.e.)e(with)h(no)f
+(errors,)j(sev)o(ere)f(errors,)h(or)e(fatal)177 1455 y(errors\))g(completed,)
+e(and)g(the)h(W)m(ea)o(v)o(e)f(option)f(\()p Fl(+T)p Fr(\))h(is)h(turned)g
+(on)f(\(it)g(is)g Fm(o\013)h Fr(b)o(y)f(default\),)g(then)h(the)g(W)m(ea)o(v)
+o(e)177 1505 y(comp)q(onen)o(t)c(of)g(F)m(unnelW)m(eb)f(is)i(in)o(v)o(ok)o
+(ed)e(to)h(generate)i(a)e(text)h(\014le)g(in)e(the)i(format)e(of)h(a)g
+(particular)g(t)o(yp)q(esetter.)177 1555 y(The)f(result,)h(when)f(fed)g
+(through)g(the)h(particular)e(t)o(yp)q(esetter)j(and)e(prin)o(ted,)g(is)g(a)f
+(fully)g(t)o(yp)q(eset)i(represen)o(tation)177 1605 y(of)h(the)i(en)o(tire)g
+(input)e(\014le)h(complete)f(with)h(cross)h(referencing)g(information.)177
+1735 y Fd(3.14.1)55 b(T)-5 b(arget)19 b(T)n(yp)r(esetter)177
+1829 y Fr(Curren)o(tly)m(,)14 b(F)m(unnelW)m(eb)g(pro)q(duces)i(do)q(cumen)o
+(tation)d(\014les)i(in)f(the)h(format)d(of)i(only)g(one)g(t)o(yp)q(esetter)j
+(|)d(T)1883 1838 y(E)1906 1829 y(X.)177 1879 y(Ho)o(w)o(ev)o(er,)f(the)h(W)m
+(ea)o(v)o(e)e(pac)o(k)n(age)h(of)f(F)m(unnelW)m(eb)g(is)h(fairly)f(small,)e
+(and)j(it)f(is)h(hop)q(ed)g(that)g(it)g(can)g(b)q(e)h(rewritten)177
+1928 y(so)f(as)f(to)g(pro)o(vide)g(a)g(collection)g(of)g(t)o(yp)q(esetter)i
+(mo)q(dules)d(from)g(whic)o(h)h(the)h(user)g(will)e(b)q(e)i(able)f(to)g(c)o
+(ho)q(ose)h(using)177 1978 y(a)h(command)d(line)i(argumen)o(t.)177
+2108 y Fd(3.14.2)55 b(Cross)20 b(Reference)c(Num)n(b)r(ering)177
+2202 y Fr(When)h(F)m(unnelW)m(eb)g(pro)q(duces)i(its)e(t)o(yp)q(eset)h(do)q
+(cumen)o(tation,)e(it)h Fm(numb)n(ers)g Fr(eac)o(h)h(section)g(and)e(eac)o(h)
+i(macro)177 2252 y(de\014nition)e(and)h(cross)h(references)h(the)f(macro)d
+(de\014nitions.)27 b(The)17 b(exact)g(sc)o(heme)g(used)h(has)e(b)q(een)i
+(carefully)177 2302 y(though)o(t)c(out.)k(Ho)o(w)o(ev)o(er,)c(as)g(it)f(can)h
+(b)q(e)h(a)e(little)g(confusing)h(to)g(the)g(b)q(eginner,)g(it)g(is)g
+(explained)f(here)i(in)f(full.)177 2369 y(The)d(most)f(imp)q(ortan)o(t)f
+(thing)h(is)h(that)g(there)h(is)e Fm(no)j(r)n(elation)d Fr(b)q(et)o(w)o(een)i
+(the)f(macro)f(n)o(um)o(b)q(ering)f(and)i(the)g(section)177
+2419 y(n)o(um)o(b)q(ering.)28 b(In)17 b(Kn)o(uth's)h(W)m(eb)f(there)i(are)f
+(only)f(section)h(n)o(um)o(b)q(ers.)29 b(In)18 b(F)m(unnelW)m(eb,)f(the)h(n)o
+(um)o(b)q(ering)e(of)177 2469 y(sections)f(and)f(macros)f(is)h(separated.)177
+2536 y(In)h(F)m(unnelW)m(eb,)f Fm(se)n(ctions)h Fr(are)h(n)o(um)o(b)q(ered)e
+(hierarc)o(hically)h(in)f(ascending)h(order.)22 b(F)m(or)15
+b(example,)e(the)j(second)177 2586 y(lev)o(el-C)i(section)i(of)e(the)i(third)
+e(lev)o(el-B)h(section)h(of)e(the)h(\014rst)h(lev)o(el-A)e(section)i(is)f(n)o
+(um)o(b)q(ered)f(\\1.3.2".)31 b(In)177 2635 y(con)o(trast,)17
+b Fm(macr)n(o)f(de\014nitions)h Fr(are)f(n)o(um)o(b)q(ered)g(sequen)o(tially)
+f(in)h(ascending)g(order.)24 b(F)m(or)16 b(example,)f(the)h(\014rst)177
+2685 y(macro)c(de\014nition)h(is)g(n)o(um)o(b)q(er)f(1,)g(the)i(second)g(is)f
+(n)o(um)o(b)q(er)g(2,)f(and)h(so)g(on.)18 b(Note)13 b(that)g(it)g(is)g
+Fm(macr)n(o)h(de\014nitions)177 2735 y Fr(that)k(are)g(n)o(um)o(b)q(ered,)g
+(not)f Fm(macr)n(os)p Fr(.)29 b(This)17 b(distinction)h(is)f(necessary)j(b)q
+(ecause)f(additiv)o(e)e(macros)f(\(i.e.)h(the)177 2785 y(ones)f(with)e
+Fl(+=)p Fr(\))g(can)h(b)q(e)h(de\014ned)g(b)o(y)e(a)h(collection)f(of)g
+(partial)g(de\014nitions)h(scattered)i(throughout)e(the)g(input)177
+2835 y(\014le.)j(A)c(single)g(additiv)o(e)f(macro)f(ma)o(y)g(b)q(e)j
+(de\014ned)g(in)e(de\014nitions)h(5,)f(67,)g(128,)g(and)h(153.)1042
+2940 y(89)p eop
+%%Page: 90 91
+90 90 bop 177 42 a Fi(3.15)70 b(F)-6 b(unnelW)g(eb)23 b(Shell)177
+167 y Fd(3.15.1)55 b(In)n(tro)r(duction)177 269 y Fr(One)19
+b(of)f(the)h(goals)e(of)g(F)m(unnelW)m(eb)h(is)g(that)g(it)g(m)o(ust)f(b)q(e)
+i(extremely)f(p)q(ortable.)31 b(Huge)19 b(e\013orts,)h(desp)q(erate)177
+319 y(actions,)e(and)g(great)g(sacri\014ces)h(w)o(ere)f(made)f(in)g(the)h
+(name)f(of)g(p)q(ortabilit)o(y)m(.)27 b(F)m(or)17 b(example,)g(F)m(unnelW)m
+(eb)g(is)177 369 y(written)e(in)e(C.)177 444 y(An)i(equally)e(imp)q(ortan)o
+(t)g(goal)g(w)o(as)i(that)f(of)g(correctness)k(and)c(reliabilit)o(y)m(.)j(T)m
+(o)d(this)h(end,)f(it)g(w)o(as)h(determined)177 494 y(that)d(a)f(large)g
+(automated)f(suite)i(of)f(test)h(programs)e(b)q(e)i(prepared)h(to)e(assist)h
+(in)f(regression)i(testing.)k(Preparing)177 544 y(the)e(test)g(suite)f(w)o
+(as)g(tedious,)g(but)g(ac)o(hiev)n(able.)j(Automating)12 b(it)h(p)q(ortably)h
+(w)o(as)g(more)f(di\016cult.)177 619 y(The)h(di\016cult)o(y)e(faced)i(w)o(as)
+f(that)g(if)f(F)m(unnelW)m(eb)h(w)o(as)g(implemen)o(ted)e(in)i(the)g(form)f
+(of)g(a)h(utilit)o(y)f(that)h(could)g(b)q(e)177 669 y(in)o(v)o(ok)o(ed)h
+(from)g(the)h(op)q(erating)g(system)g(command)e(language,)h(the)h(only)g(w)o
+(a)o(y)f(to)h(set)h(up)f(regression)h(testing)177 719 y(w)o(as)11
+b(in)f(the)h(command)d(language)i(of)g(the)h(op)q(erating)g(system)f(of)g
+(the)h(target)g(mac)o(hine)f(\(shellscripts)i(for)e(UNIX,)177
+769 y(DCL)h(for)h(VMS,)f(batc)o(h)h(\014les)g(for)f(MSDOS,)g(and)g
+Fm(nothing)i Fr(on)e(the)h(Macin)o(tosh\).)18 b(The)12 b(h)o(uge)f(v)n
+(ariation)f(in)h(these)177 819 y(command)i(languages)i(led)g(to)g(the)h
+(conclusion)g(that)f(either)h(the)g(automation)d(of)i(regression)i(testing)f
+(w)o(ould)177 868 y(ha)o(v)o(e)i(to)h(b)q(e)g(rewritten)h(on)e(eac)o(h)h
+(target)g(mac)o(hine,)f(or)g(a)g(small)f(command)e(language)j(w)o(ould)g(ha)o
+(v)o(e)g(to)g(b)q(e)177 918 y(created)g(within)d(F)m(unnelW)m(eb.)24
+b(In)17 b(the)f(end,)h(the)g(t)o(win)e(goals)h(of)f(p)q(ortabilit)o(y)g(and)h
+(regression)h(testing)g(w)o(ere)177 968 y(considered)g(so)f(imp)q(ortan)o(t)e
+(that)i(a)f(small)e(command)g(shell)j(w)o(as)f(constructed)j(inside)e(F)m
+(unnelW)m(eb.)22 b(This)16 b(is)177 1018 y(called)e(the)g Fo(F)l(unnelW)l(eb)
+g(command)h(shell)p Fr(,)c(or)i(just)i(\\the)f(shell")f(for)h(short.)177
+1093 y(By)i(default,)f(when)i(F)m(unnelW)m(eb)e(is)g(in)o(v)o(ok)o(ed,)g(it)h
+(do)q(es)g(not)g(en)o(ter)h(its)e(shell.)24 b(If)15 b(just)h(giv)o(en)f(the)h
+(name)f(of)g(an)177 1143 y(input)c(\014le,)f(it)g(will)f(simple)g(pro)q(cess)
+k(the)e(input)f(\014le)h(in)f(the)h(normal)e(manner)g(and)i(then)g
+(terminate.)16 b(T)m(o)10 b(instruct)177 1193 y(F)m(unnelW)m(eb)g(to)g(in)o
+(v)o(ok)o(e)f(its)h(shell,)g(the)g Fl(+K)g Fr(or)g Fl(+X)g
+Fr(command)d(line)i(option)h(m)o(ust)f(b)q(e)h(sp)q(eci\014ed)i(when)e(F)m
+(unnelW)m(eb)177 1243 y(is)i(in)o(v)o(ok)o(ed)g(from)f(the)i(op)q(erating)f
+(system.)17 b(It)c(is)f(also)g(in)o(v)o(ok)o(ed)g(up)q(on)g(startup)h(if)f
+(the)h(\014le)f Fl(fwinit.fws)f Fr(exists.)177 1318 y(Most)16
+b(F)m(unnelW)m(eb)f(users)i(will)d(nev)o(er)j(need)g(to)e(use)h(the)h(shell)e
+(and)h(need)g(not)g(ev)o(en)g(kno)o(w)f(ab)q(out)h(it.)23 b(There)177
+1368 y(are)14 b(four)g(main)e(uses)j(of)e(the)i(shell:)228
+1486 y(1.)20 b(As)14 b(a)g(to)q(ol)f(to)h(supp)q(ort)g(automated)f
+(regression)i(testing.)228 1570 y(2.)20 b(As)d(a)f(dev)o(elopmen)o(t)f(to)q
+(ol)g(on)h(mac)o(hines)g(that)g(do)g(not)g(ha)o(v)o(e)g(a)g(built)g(in)g
+(shell)g(\(e.g.)f(the)i(Macin)o(tosh\).)281 1620 y(The)d(shell)g(can)g(b)q(e)
+h(used)f(to)g(pro)q(cess)i(whole)e(groups)g(of)f(\014les)h(automatically)m(.)
+228 1705 y(3.)20 b(As)c(a)f(con)o(v)o(enience.)24 b(A)16 b(user)h(w)o(orking)
+d(on)h(a)h(m)o(ulti-tasking,)c(m)o(ulti-windo)o(w)g(w)o(orkstation)j(ma)o(y)f
+(wish)281 1754 y(to)g(k)o(eep)h(an)f(in)o(teractiv)o(e)g(session)h(of)f(F)m
+(unnelW)m(eb)g(going)f(in)g(one)i(windo)o(w)e(rather)i(than)f(ha)o(ving)f(to)
+h(run)281 1804 y(up)g(the)g(utilit)o(y)f(eac)o(h)h(time)f(it)g(is)h
+(required.)228 1889 y(4.)20 b(As)15 b(a)g(con)o(v)o(enien)o(t)g(v)o(ehicle)g
+(for)g(enclosing)g(utilities.)20 b(The)15 b(F)m(unnelW)m(eb)g(shell)g(con)o
+(tains)g(useful)g(general)281 1938 y(purp)q(ose)g(commands)c(suc)o(h)k(as)f
+(the)h(di\013erences)h(command)11 b Fl(diff)p Fr(.)177 2082
+y Fd(3.15.2)55 b(Return)18 b(Statuses)177 2184 y Fr(The)g(hierarc)o(h)o(y)f
+(of)g(diagnostics)g(describ)q(ed)i(in)d(Section)i(3.5)e(is)h(also)g(used)h
+(in)e(the)i(shell)f(commands.)25 b(Eac)o(h)177 2234 y(shell)14
+b(command)d(returns)k(a)f(status)h(whic)o(h)f(can)g(a\013ect)h(further)f(pro)
+q(cessing.)295 2309 y Fo(Success)f Fr(status)i(is)f(the)g(normal)e(command)f
+(return)k(status.)295 2385 y Fo(W)l(arning)f Fr(status)j(is)e(returned)j(if)d
+(some)f(minor)g(problem)h(arose)h(with)f(the)i(execution)f(of)f(the)295
+2435 y(command.)295 2510 y Fo(Error)h Fr(status)h(is)g(returned)h(if)e(a)g
+(signi\014can)o(t)h(problem)e(arises)i(during)f(the)i(execution)f(of)f(the)
+295 2560 y(command.)23 b(Ho)o(w)o(ev)o(er,)17 b(unlik)o(e)f(a)g(sev)o(ere)j
+(error,)e(it)f(do)q(es)h Fm(not)g Fr(cause)h(termination)c(of)i(the)h(en-)295
+2610 y(closing)d(shellscript.)295 2685 y Fo(Sev)o(ere)23 b(error)c
+Fr(status)j(is)f(returned)h(if)e(a)g(problem)g(arises)h(during)g(the)g
+(execution)h(of)e(the)295 2735 y(command)c(that)j(prev)o(en)o(ts)h(the)f
+(command)d(from)h(deliv)o(ering)h(on)g(its)h(\\promise".)30
+b(A)19 b(sev)o(ere)295 2785 y(error)12 b(causes)g(F)m(unnelW)m(eb)e(to)g(ab)q
+(ort)h(the)g(script)g(\(and)g(an)o(y)f(stac)o(k)o(ed)h(scripts\))h(to)e(the)h
+(in)o(teractiv)o(e)295 2835 y(lev)o(el.)18 b(\(Ho)o(w)o(ev)o(er,)c(the)g
+Fl(tolerate)f Fr(command)e(allo)o(ws)h(this)i(to)g(b)q(e)h(temp)q(orarily)d
+(o)o(v)o(erridden\).)1042 2940 y(90)p eop
+%%Page: 91 92
+91 91 bop 295 42 a Fo(F)l(atal)15 b(error)c Fr(status)j(is)f(returned)i(if)d
+(a)h(problem)f(arises)h(that)g(is)g(so)h(serious)f(that)g(execution)h(of)295
+91 y(F)m(unnelW)m(eb)c(cannot)g(con)o(tin)o(ue.)17 b(A)10 b(fatal)f(error)i
+(causes)g(F)m(unnelW)m(eb)e(to)h(ab)q(ort)g(to)g(the)h(op)q(erating)295
+141 y(system)j(lev)o(el.)295 219 y Fo(Assertion)i(error)e Fr(status)j(is)f
+(nev)o(er)g(returned.)26 b(If)15 b(an)h(assertion)g(error)h(o)q(ccurs,)g(F)m
+(unnelW)m(eb)295 269 y(b)q(om)o(bs)d(out)g(ungracefully)g(to)g(the)h(op)q
+(erating)g(system.)k(Assertion)d(errors)f(should)g(nev)o(er)g(hap-)295
+319 y(p)q(en.)k(If)13 b(they)i(do,)e(then)i(there)g(is)f(a)f(bug)h(in)f(F)m
+(unnelW)m(eb.)177 397 y(T)m(o)k(b)q(e)i(precise,)h(the)f(status)f(returned)i
+(b)o(y)e(eac)o(h)g(command)e(is)h(a)h(v)o(ector)h(of)e(n)o(um)o(b)q(ers)h(b)q
+(eing)g(the)g(n)o(um)o(b)q(er)177 447 y(of)d(eac)o(h)h(of)f(the)h(di\013eren)
+o(t)g(kinds)f(of)g(diagnostic)g(generated)i(b)o(y)e(the)h(command.)k(Usually)
+14 b(only)h(one)g(kind)g(of)177 497 y(diagnostic)d(is)g(generated.)19
+b(Ho)o(w)o(ev)o(er,)13 b(the)g Fl(fw)f Fr(command)e(and)i(a)g(few)h(of)f(the)
+h(other)g(commands)d(can)i(generate)177 546 y(more)k(than)h(one)g(kind)f(of)h
+(diagnostic.)26 b(These)18 b(status)g(v)o(ectors)g(are)f(summed)e(in)o
+(ternally)h(where)i(they)g(ma)o(y)177 596 y(later)13 b(b)q(e)h(accessed)h
+(using)e(the)g Fl(status)f Fr(command.)j(Ho)o(w)o(ev)o(er,)e(the)h(curren)o
+(t)g(diagnostic)e(state)i(ev)n(ap)q(orates)g(as)177 646 y(so)q(on)g(as)g(the)
+h(next)f(command)d(is)j(encoun)o(tered.)177 798 y Fd(3.15.3)55
+b(Command)17 b(Line)h(Length)177 904 y Fr(The)c(maxim)o(um)9
+b(length)14 b(of)f(a)h(shell)g(command)d(line)i(is)h(guaran)o(teed)g(to)g(b)q
+(e)h(at)e(least)h(300)g(c)o(haracters.)177 1056 y Fd(3.15.4)55
+b(String)19 b(Substitution)177 1162 y Fr(Most)f(command)c(shells)k(pro)o
+(vide)f(some)g(form)f(of)g(string)i(substitution)g(so)f(as)h(to)f(pro)o(vide)
+g(some)g(degree)h(of)177 1212 y(parameterization.)j(The)16
+b(F)m(unnelW)m(eb)f(shell)g(pro)o(vides)h(36)e(di\013eren)o(t)j(string)e(v)n
+(ariables)g(named)f Fl($0..$9)g Fr(and)177 1262 y Fl($A..$Z)i
+Fr(\(case)i(insensitiv)o(e\).)28 b(Eac)o(h)17 b(v)n(ariable)f(can)i(hold)e(a)
+h(string)g(con)o(taining)f(an)o(y)g(sequence)k(of)c(prin)o(table)177
+1312 y(c)o(haracters)g(and)e(can)g(b)q(e)g(as)g(long)f(as)h(a)g(command)d
+(line.)177 1390 y(The)k Fl(define)e Fr(command)e(allo)o(ws)i(the)h(user)i(to)
+e(assign)f(a)h(v)n(alue)g(to)g(these)h(v)n(ariables.)j(The)d
+Fl(define)e Fr(command)177 1439 y(tak)o(es)i(t)o(w)o(o)e(argumen)o(ts.)18
+b(The)c(\014rst)h(is)f(the)h(digit)e(or)h(letter)h(of)e(the)i(v)n(ariable)e
+(to)g(b)q(e)i(de\014ned.)20 b(The)14 b(second)h(is)f(a)177
+1489 y(double)f(quote)h(delimited)e(string)h(b)q(eing)g(the)h(string)g(v)n
+(alue)e(to)i(b)q(e)g(assigned)f(to)g(the)h(v)n(ariable.)j(If)c(y)o(ou)g(w)o
+(an)o(t)g(to)177 1539 y(include)h(a)g(double)f(quote)i(c)o(haracter)g(within)
+e(the)i(string,)e(y)o(ou)g(don't)h(need)h(to)e(double)h(it.)177
+1617 y(Examples:)177 1742 y Fl(define)21 b(3)g("/root/usr/usrs/use)o(rs/us)o
+(ers5/)o(this)o(user/)o(workd)o(ir/fw)o(dir/t)o(estdi)o(r")177
+1792 y(define)g(M)g("/user/local/rubbis)o(h/bin)o(/fw")177
+1841 y(define)g(Q)g("You)g(don't)g(need)g(to)g(double")g(double)f(quotes")177
+1966 y Fr(Only)13 b(the)h(iden)o(tifying)d(c)o(haracter)k(of)d(the)i(v)n
+(ariable)e(b)q(eing)h(assigned)g(is)g(used)h(in)f(the)g(de\014nition.)18
+b(This)13 b(syn)o(tax)177 2016 y(is)18 b(a)g(simple)f(w)o(a)o(y)g(of)h(prev)o
+(en)o(ting)g(the)h(v)n(ariable)e(from)f(b)q(eing)j(substituted)g(b)q(efore)g
+(it)f(has)g(a)g(c)o(hance)h(to)f(b)q(e)177 2066 y(de\014ned!)177
+2144 y(The)c(follo)o(wing)e(p)q(oin)o(ts)i(clean)g(up)g(the)g(remaining)e
+(seman)o(tic)h(details:)239 2268 y Fq(\017)21 b Fr(There)16
+b(is)f(only)g(one)g(set)h(of)f(v)n(ariables)f(and)h(they)h(are)f(global)f(to)
+h(all)f(shellscripts.)23 b(There)16 b(are)g Fm(no)g(lo)n(c)n(al)281
+2318 y(variables)p Fr(.)239 2408 y Fq(\017)21 b Fr(When)f(a)h(shellscript)g
+(is)f(in)o(v)o(ok)o(ed)f(using)h(the)h Fl(execute)e Fr(command,)g(the)i
+(substitution)f(v)n(ariables)g Fl(0)281 2458 y Fr(through)14
+b Fl(9)g Fr(are)g(a\013ected.)19 b(See)c(Section)f(3.15.7.9)e(for)h(more)g
+(details.)239 2547 y Fq(\017)21 b Fr(If)13 b(y)o(ou)h(w)o(an)o(t)f(to)h
+(include)g(a)g(dollar)e(sign)i(c)o(haracter)h(in)f(a)f(command)e(use)k(\\)p
+Fl($$)p Fr(".)239 2637 y Fq(\017)21 b Fr(F)m(unnelW)m(eb)14
+b(also)g(de\014nes)h(\\)p Fl($/)p Fr(")f(whic)o(h)g(translates)h(to)g(the)g
+(c)o(haracter)g(that)g(separates)h(directory)f(and)281 2687
+y(\014le)21 b(name)g(\014elds)g(in)g(\014le)h(names)f(on)g(the)h(host)g(mac)o
+(hine.)39 b(F)m(or)21 b(example:)32 b(Sun=\\)p Fl(/)p Fr(",)22
+b(V)m(ax=\\)p Fl(])p Fr(",)281 2737 y(Mac=\\)p Fl(:)p Fr(",)13
+b(PC=\\)p Fl(\\)p Fr(".)239 2827 y Fq(\017)21 b Fr(Substitution)14
+b(is)f(not)h(p)q(erformed)g(recursiv)o(ely)m(.)1042 2940 y(91)p
+eop
+%%Page: 92 93
+92 92 bop 177 42 a Fd(3.15.5)55 b(Ho)n(w)20 b(a)f(Command)e(Line)g(is)i(Pro)r
+(cessed)177 158 y Fr(When)13 b(F)m(unnelW)m(eb)f(reads)i(in)e(a)h(command)d
+(line)i(\(from)f(the)j(console)f(or)g(a)f(script)i(\014le\),)f(it)f(pro)q
+(cesses)j(it)e(in)f(the)177 208 y(follo)o(wing)f(sequence:)228
+350 y(1.)20 b(The)14 b(command)c(line)j(is)h(c)o(hec)o(k)o(ed)g(for)f
+(non-prin)o(table)g(c)o(haracters.)20 b(If)13 b(there)h(are)g(an)o(y)m(,)e
+(they)i(are)g(\015agged)281 400 y(with)f(a)h(sev)o(ere)i(error.)228
+504 y(2.)k(All)11 b(dollar)f(string)i(substitution)g(v)n(ariables)f(in)g(the)
+i(command)c(line)i(are)h(replaced)h(b)o(y)e(their)h(corresp)q(ond-)281
+554 y(ing)j(string.)25 b(The)17 b(command)c(line)j(is)f(pro)q(cessed)k(from)
+14 b(left)i(to)g(righ)o(t.)24 b(Substitutions)17 b(are)f(p)q(erformed)281
+604 y(non)e(recursiv)o(ely)m(.)228 708 y(3.)20 b(A)o(t)9 b(this)h(p)q(oin)o
+(t,)f(if)g(the)h(line)f(is)g(empt)o(y)m(,)g(or)g(consists)i(en)o(tirely)e(of)
+g(blanks,)h(it)f(is)g(ignored)h(and)f(the)h(in)o(terpreter)281
+757 y(mo)o(v)o(es)j(to)g(the)i(next)f(line.)228 861 y(4.)20
+b(A)14 b(sev)o(ere)h(error)g(is)f(generated)h(if)e(the)i(line)e(at)h(this)g
+(stage)g(b)q(egins)g(with)g(a)g(blank.)228 965 y(5.)20 b(If)13
+b(the)i(\014rst)g(c)o(haracter)g(of)e(the)i(line)e(is)h(\\)p
+Fl(!)p Fr(",)e(the)j(line)e(is)h(a)g(commen)o(t)d(line)j(and)g(is)f(ignored.)
+228 1069 y(6.)20 b(The)e(run)g(of)g(non-blanks)f(commencing)e(at)j(the)h
+(start)f(of)f(the)i(line)e(is)h(compared)f(case-insensitiv)o(ely)281
+1119 y(to)e(eac)o(h)h(of)f(the)i(legal)d(command)f(v)o(erbs.)24
+b(If)15 b(the)h(command)d(is)j(illegal,)d(a)j(sev)o(ere)h(error)f(is)g
+(generated,)281 1169 y(otherwise)f(the)f(command)d(is)j(pro)q(cessed.)177
+1343 y Fd(3.15.6)55 b(Options)177 1459 y Fr(The)14 b(F)m(unnelW)m(eb)g(shell)
+g(main)o(tains)d(three)k(sets)g(of)f(command)d(line)i(options.)228
+1602 y(1.)20 b(The)10 b(set)g(of)f(options)g(resulting)g(from)f(applying)g
+(the)i(op)q(erating)f(system)g(lev)o(el)g(command)e(line)i(argumen)o(ts)281
+1652 y(to)14 b(the)g(default)g(option)f(settings.)228 1756
+y(2.)20 b(A)14 b(set)h(of)e(shell)h(options)f(that)h(prev)n(ail)f(during)h
+(the)g(shell)g(in)o(v)o(o)q(cation.)228 1860 y(3.)20 b(The)14
+b(set)h(of)e(option)g(v)n(alues)h(activ)o(e)g(during)g(a)f(particular)h(in)o
+(v)o(o)q(cation)e(of)i(F)m(unnelW)m(eb)f(prop)q(er.)177 2002
+y(When)i(F)m(unnelW)m(eb)f(is)g(in)o(v)o(ok)o(ed)f(from)g(the)i(op)q(erating)
+f(system)g(with)g(just)h Fl(+F)p Fr(,)e(only)h(the)h(\014rst)g(of)f(these)h
+(three)177 2052 y(sets)k(comes)e(in)o(to)g(existence.)30 b(If)18
+b(the)g(user)g(in)o(v)o(ok)o(es)f(the)h(F)m(unnelW)m(eb)f(shell,)h(the)g
+(shell)g(options)f(come)f(in)o(to)177 2102 y(existence)j(and)e(are)h
+(initialized)d(with)i(the)h(v)n(alue)e(of)h(the)h(\014rst)f(set.)29
+b(These)19 b(shell)e(options)f(are)i(used)g(as)f(the)177 2151
+y(default)d(for)g(all)f(subsequen)o(t)j Fl(fw)d Fr(commands.)k(Ho)o(w)o(ev)o
+(er,)d(they)h(can)f(b)q(e)h(altered)g(using)f(the)h(script)g(command)177
+2201 y Fl(set)p Fr(.)i(If)11 b(a)h Fl(fw)f Fr(command)e(executed)14
+b(in)d(a)g(shell)h(con)o(tains)g(additional)e(command)f(line)i(options,)g
+(these)i(o)o(v)o(erride)177 2251 y(the)i(shell)e(options)h(for)f(that)h(run,)
+g(but)g(do)g(not)g(c)o(hange)g(the)g(shell)g(options.)k(An)c(example)f(follo)
+o(ws:)177 2393 y Fl($)22 b(fw)f(+k)h(+t)261 b(!)21 b(Original)f(invocation)g
+(of)h(FunnelWeb)f(from)h(OS.)657 2443 y(!)g(Shell)g(options)f(are)h(now)h
+(default)e(with)h("+t".)177 2493 y(FunnelWeb>fw)e(sloth)87
+b(!)21 b(Equivalent)f(to)h(fw)h(sloth)e(+t.)177 2543 y(FunnelWeb>set)f(-l)131
+b(!)21 b(Change)g(the)g(l)h(shell)e(option.)177 2593 y(FunnelWeb>fw)f(sloth)i
+(+q)h(!)f(Equivalent)f(to)h(fw)h(sloth)e(+t)i(-l)f(+q.)177
+2642 y(FunnelWeb>fw)e(sloth)87 b(!)21 b(Equivalent)f(to)h(fw)h(sloth)e(+t)i
+(-l.)177 2785 y Fr(The)14 b(existence)h(of)d(the)i(shell)f(option)f(set)i
+(means)e(that)h(the)h(user)g(can)f(set)h(up)f(a)g(set)h(of)f(defaults)g(to)g
+(b)q(e)g(applied)177 2835 y(to)h(all)f Fl(fw)g Fr(commands)e(issued)k(within)
+e(the)i(shell.)1042 2940 y(92)p eop
+%%Page: 93 94
+93 93 bop 177 42 a Fd(3.15.7)55 b(Shell)18 b(Commands)177 136
+y Fr(This)c(section)h(describ)q(es)h(eac)o(h)e(of)f(the)i(F)m(unnelW)m(eb)e
+(shell)h(commands.)h(The)g(syn)o(tax)f(is:)177 226 y Fl(shell_command)19
+b(=)j(absent)64 b(|)22 b(codify)e(|)i(compare)e(|)i(define)e(|)i(diff)86
+b(|)22 b(diffsummary)d(|)526 276 y(diffzero)h(|)i(eneo)64 b(|)22
+b(execute)e(|)i(exists)e(|)i(fixeols)e(|)i(help)173 b(|)526
+326 y(here)108 b(|)22 b(quit)64 b(|)22 b(set)108 b(|)22 b(show)64
+b(|)22 b(skipto)42 b(|)22 b(status)129 b(|)526 376 y(tolerate)20
+b(|)i(trace)42 b(|)22 b(write)64 b(|)22 b(writeu)177 425 y(s)g(=)f({")h("}+)
+177 516 y Fr(As)d(a)e(rule,)i(F)m(unnelW)m(eb)f(shell)g(commands)d(return)20
+b(sev)o(ere)f(status)g(if)e(their)i(argumen)o(ts)e(are)h(syn)o(tactically)177
+566 y(incorrect)d(or)f(if)f(they)i(are)f(unable)g(to)f(successfully)j(op)q
+(erate)e(on)g(argumen)o(t)f(\014les.)177 688 y Fo(3.15.7.1)48
+b(Absen)o(t)177 782 y Fr(The)19 b Fl(absent)d Fr(command)g(p)q(erforms)h(no)h
+(action)g(except)i(to)d(return)j(a)e(status.)31 b(If)18 b(the)g(\014le)h(sp)q
+(eci\014ed)g(in)f(its)177 832 y(argumen)o(t)13 b(do)q(esn't)h(exist)h(it)e
+(returns)i(success)i(status,)d(otherwise)h(it)e(returns)j(sev)o(ere)f
+(status.)177 922 y Fl(Syntax)21 b(:)g(absent)g(=)g("absent")g(s)g(filename)
+177 972 y(Example:)f(absent)h(result.out)177 1062 y Fr(This)16
+b(command)d(is)i(useful)h(in)f(regression)i(testing)f(for)f(making)e(sure)k
+(that)f(F)m(unnelW)m(eb)f Fm(hasn)l('t)g Fr(pro)q(duced)i(a)177
+1112 y(particular)d(output)g(\014le.)177 1234 y Fo(3.15.7.2)48
+b(Co)q(dify)177 1329 y Fr(The)14 b Fl(codify)f Fr(command)e(tak)o(es)j(t)o(w)
+o(o)f(argumen)o(ts:)k(an)d(input)g(\014le)f(and)h(an)f(output)h(\014le.)k(It)
+c(reads)h(eac)o(h)f(line)f(of)177 1378 y(the)g(input)g(\014le)g(and)f(writes)
+h(a)g(corresp)q(onding)g(line)g(to)f(the)h(output)g(\014le.)18
+b(The)13 b(corresp)q(onding)h(line)e(consists)h(of)177 1428
+y(a)e(C)g(macro)f(call)g(con)o(taining)g(a)g(string)h(con)o(taining)f(the)i
+(input)f(line.)16 b(The)c(command)c(con)o(v)o(erts)k(all)e(bac)o(kslashes)177
+1478 y(in)j(input)h(lines)f(to)g(double)h(bac)o(kslashes)g(so)g(as)f(to)g(a)o
+(v)o(oid)g(un)o(w)o(an)o(ted)g(in)o(terpretations)h(b)o(y)g(the)g(C)f
+(compiler.)k(It)177 1528 y(also)c(con)o(v)o(erts)i(double)f(quotes)h(in)e
+(the)i(line)e(to)h(bac)o(kslashed)g(double)g(quotes.)177 1618
+y Fl(Syntax)21 b(:)g(codify)g(=)g("codify")g(s)g(filename)f(s)i(filename)177
+1668 y(Example:)e(codify)h(header.tex)f(header.c)177 1758 y
+Fr(The)14 b(follo)o(wing)e(example)g(demonstrates)j(the)f(transformation.)177
+1849 y Fl(Input)43 b(Line:)20 b(\\def\\par{\\leavevmode)o(\\endg)o(raf})o
+(\045)f(A)j("jolly)e(good)h(hack".)177 1899 y(Output)g(Line:)f
+(WX\("\\\\def\\\\par{\\\\lea)o(vevmo)o(de\\\\)o(endgr)o(af}\045)e(A)k
+(\\"jolly)e(good)h(hack\\"."\);)177 1989 y Fr(The)c Fl(codify)e
+Fr(command)f(w)o(as)i(in)o(tro)q(duced)h(to)g(assist)f(in)g(the)h(dev)o
+(elopmen)o(t)f(of)g(F)m(unnelW)m(eb.)25 b(It)16 b(is)h(used)g(to)177
+2039 y(con)o(v)o(ert)f(longish)e(text)i(\014les)f(in)o(to)f(C)h(co)q(de)h(to)
+f(write)h(them)e(out.)21 b(The)16 b(C)f(co)q(de)h(is)f(then)h(included)f
+(within)f(the)177 2089 y(F)m(unnelW)m(eb)h(C)g(program.)20
+b(F)m(or)14 b(example,)g(the)h(set)h(of)f(T)1088 2098 y(E)1111
+2089 y(X)g(de\014nitions)g(that)g(app)q(ears)h(at)f(the)h(top)f(of)f(ev)o
+(ery)177 2139 y(do)q(cumen)o(tation)e(\014le)i(w)o(as)f Fl(codif)p
+Fr(ied)f(and)i(inserted)g(in)o(to)f(the)h(F)m(unnelW)m(eb)f(co)q(de)h(so)f
+(that)h(F)m(unnelW)m(eb)f(w)o(ould)177 2188 y(not)h(ha)o(v)o(e)g(to)f(lo)q
+(ok)g(for)h(a)f(\014le)h(con)o(taining)f(the)i(de\014nitions)f(at)f(run)h
+(time.)177 2311 y Fo(3.15.7.3)48 b(Compare)177 2405 y Fr(The)17
+b Fl(compare)f Fr(command)d(tak)o(es)18 b(t)o(w)o(o)e(\014lename)f(argumen)o
+(ts)h(and)h(p)q(erforms)f(a)h(binary)f(comparison)f(of)h(the)177
+2455 y(t)o(w)o(o)e(\014les.)19 b(If)14 b(the)h(\014les)f(are)h(iden)o(tical,)
+e(success)k(status)e(is)f(returned.)20 b(If)14 b(they)h(are)f(di\013eren)o
+(t,)h(sev)o(ere)h(status)f(is)177 2504 y(returned.)20 b(No)14
+b(information)d(ab)q(out)i(the)i(manner)e(in)g(whic)o(h)h(the)h(\014les)f
+(di\013er)g(is)g(con)o(v)o(ey)o(ed.)177 2595 y Fl(Syntax)21
+b(:)g(compare)g(=)g("compare")f(s)i(filename)e(s)h(filename)177
+2645 y(Example:)f(compare)h(result.txt)e(answer.txt)177 2735
+y Fr(The)14 b Fl(compare)e Fr(command)f(w)o(as)i(created)j(as)d(the)h(main)e
+(c)o(hec)o(king)i(mec)o(hanism)d(for)i(regression)i(testing.)j(Ho)o(w-)177
+2785 y(ev)o(er,)12 b(its)e(binary)g(output)h(w)o(as)f(so)q(on)g(found)g(to)h
+(b)q(e)g(un)o(w)o(ork)n(able)e(and)i(the)g(more)e(sophisticated)i
+Fl(diff)f Fr(command)177 2835 y(w)o(as)k(added)g(so)g(that)g(the)h(actual)e
+(di\013erences)j(b)q(et)o(w)o(een)g(the)e(\014les)g(could)g(b)q(e)g
+(examined.)1042 2940 y(93)p eop
+%%Page: 94 95
+94 94 bop 177 42 a Fo(3.15.7.4)48 b(De\014ne)177 141 y Fr(The)12
+b Fl(define)e Fr(command)e(assigns)k(a)f(v)n(alue)g(to)g(a)g(shell)g(string)g
+(substitution)h(v)n(ariable.)k(The)c Fl(define)e Fr(command)177
+191 y(tak)o(es)15 b(t)o(w)o(o)e(argumen)o(ts.)18 b(The)c(\014rst)h(is)f(the)h
+(digit)e(or)h(letter)h(of)e(the)i(v)n(ariable)e(to)g(b)q(e)i(de\014ned.)20
+b(The)14 b(second)h(is)f(a)177 241 y(double)f(quote)h(delimited)e(string)h(b)
+q(eing)g(the)h(string)g(v)n(alue)e(to)i(b)q(e)g(assigned)f(to)g(the)h(v)n
+(ariable.)j(If)c(y)o(ou)g(w)o(an)o(t)g(to)177 291 y(include)h(a)g(double)f
+(quote)i(c)o(haracter)g(within)e(the)i(string,)e(y)o(ou)g(don't)h(need)h(to)e
+(double)h(it.)177 401 y Fl(Syntax)43 b(:)21 b(define)g(=)g("define")f(s)i
+(letter)f(s)g("""")g(text)g("""")177 450 y(Examples:)f(define)h(3)g
+("/usr/usrs/thisuser)o(/wor)o(kdir/)o(fwdir)o(/test)o(dir")395
+500 y(define)g(M)g("/user/local/rubbis)o(h/bi)o(n/fw")395 550
+y(define)g(Q)g("You)g(don't)g(need)g(to)g(double")g(double)f(quotes")177
+660 y Fr(The)f(command)d(in)o(terpreter)21 b(expands)e(the)g(command)d(line)i
+(b)q(efore)h(it)g(executes)h(the)g Fl(define)d Fr(command.)177
+710 y(This)h(means)f(that)g(y)o(ou)h(can)f(de\014ne)i(string)f(substitution)g
+(v)n(ariables)f(in)g(terms)g(of)h(eac)o(h)g(other)g(with)f(static)177
+760 y(binding.)177 833 y(The)d Fl(define)f Fr(command)e(w)o(as)i(in)o(tro)q
+(duced)i(to)e(allo)o(w)f(the)j(parameterization)d(of)i(the)g(directories)h
+(in)o(v)o(olv)o(ed)d(in)177 882 y(regression)j(testing.)177
+955 y(See)g(Section)f(3.15.4)e(for)i(more)f(details.)177 1086
+y Fo(3.15.7.5)48 b(Di\013)177 1185 y Fr(The)16 b Fl(diff)f
+Fr(command)e(reads)k(in)e(t)o(w)o(o)g(text)i(\014les)f(and)f
+Fm(app)n(ends)i Fr(a)f(rep)q(ort)g(to)g(a)g(log)e(\014le)i(con)o(taining)f(a)
+g(list)g(of)177 1235 y(the)h(di\013erences)h(b)q(et)o(w)o(een)f(the)f(t)o(w)o
+(o)g(input)f(\014les.)21 b(If)15 b(the)g(log)f(\014le)h(do)q(es)g(not)g
+(already)g(exist,)g(an)f(empt)o(y)g(one)h(is)177 1285 y(created)h(\014rst.)
+177 1395 y Fl(Syntax)43 b(:)21 b(diff)g(=)h("diff")e(s)i(filename)e(s)i
+(filename)e(s)h(filename)f(s)i(["ABORT"])177 1445 y(Examples:)e(diff)h
+(result.tex)f(answer.tex)g(diff.log)395 1494 y(diff)h($Otest23.out)e
+($Atest23.out)h($Ldiff.log)f(ABORT)177 1604 y Fr(The)i Fl(diff)f
+Fr(command)e(p)q(erforms)i(a)g(full)f(line-based)i(di\013erences)i(op)q
+(eration.)37 b(It)21 b(will)e(iden)o(tify)h(di\013eren)o(t)177
+1654 y(sections)15 b(in)f(a)f(\014le,)h(ev)o(en)g(if)f(they)i(are)f(of)f
+(di\013ering)h(length.)177 1727 y(The)19 b(implem)o(en)o(tation)c(of)j(the)g
+Fl(diff)f Fr(command)f(is)i(quite)g(complicated.)29 b(T)m(o)17
+b(b)q(e)i(sure)g(that)f(it)g(is)g(at)g(least)177 1777 y(getting)e(its)h
+(same/di\013eren)o(t)f(pro)q(clamation)e(righ)o(t,)i(the)h
+Fl(diff)f Fr(command)d(p)q(erforms)j(a)g(binary)g(comparison)177
+1827 y(as)e(an)g(extra)g(c)o(hec)o(k.)177 1900 y(The)g(follo)o(wing)e(p)q
+(oin)o(ts)i(describ)q(e)h(the)g(rules)f(for)g(determining)e(the)j(result)g
+(status.)228 2010 y(1.)20 b Fl(diff)13 b Fr(ab)q(orts)h(with)g(a)f(sev)o(ere)
+j(error)f(if)e(the)h(log)f(\014le)h(cannot)g(b)q(e)h(op)q(ened)g(or)e
+(created)j(for)d(app)q(ending.)228 2091 y(2.)20 b(An)14 b(ordinary)f(error)i
+(is)f(generated)h(if)e(either)i(or)f(b)q(oth)g(of)f(the)i(input)e(\014les)i
+(cannot)f(b)q(e)g(op)q(ened.)228 2172 y(3.)20 b(If,)15 b(at)h(the)g(end)h(of)
+e(the)h(run,)g(the)h(t)o(w)o(o)e(input)g(\014les)i(ha)o(v)o(e)e(not)h(b)q
+(een)h(pro)o(v)o(en)f(to)f(b)q(e)i(iden)o(tical,)e(and)g(the)281
+2222 y Fl(ABORT)e Fr(k)o(eyw)o(ord)h(is)f(presen)o(t,)i Fl(diff)e
+Fr(returns)j(sev)o(ere)f(status.)228 2303 y(4.)20 b Fl(diff)10
+b Fr(returns)j(success)h(status)e(if)f(none)g(of)g(the)h(ab)q(o)o(v)o(e)f
+(conditions)g(\(or)h(similar)c(conditions\))k(o)q(ccur,)g(ev)o(en)281
+2353 y(if)h(the)h(t)o(w)o(o)g(\014les)g(are)g(di\013eren)o(t.)177
+2463 y(The)k Fl(diff)f Fr(command)d Fm(app)n(ends)19 b Fr(its)f
+(di\013erences)h(rep)q(ort)g(rather)f(than)g(merely)e(writing)h(it.)28
+b(This)18 b(allo)o(ws)e(a)177 2513 y(regression)f(test)g(script)g(to)f(p)q
+(erform)f(a)g(series)j(of)d(regression)i(tests)g(and)f(pro)q(duce)h(a)f(rep)q
+(ort)h(for)e(the)i(user.)177 2586 y(The)e Fl(diff)e Fr(command)f(w)o(as)i
+(added)h(to)f(the)h(shell)f(after)g(it)g(had)g(b)q(ecome)g(apparen)o(t)h
+(that)f(the)h(simpler)e Fl(compare)177 2635 y Fr(command)h(w)o(as)i(not)h
+(yielding)e(enough)i(information.)i(Whereas)f(early)e(on,)g(regression)i
+(testing)f(w)o(as)g(treated)177 2685 y(mainly)8 b(as)i(a)f(to)q(ol)h(to)g
+(ensure)h(that)f(F)m(unnelW)m(eb)g(w)o(as)g(b)q(eing)g(p)q(orted)g(to)g
+(other)h(mac)o(hines)e(correctly)m(,)i(it)f(b)q(egan)g(to)177
+2735 y(place)j(an)f(increasing)h(role)g(during)f(dev)o(elopmen)o(t)g(in)g
+(iden)o(tifying)f(the)i(e\013ects)i(of)d(c)o(hanges)h(made)f(to)g(the)h(co)q
+(de.)177 2785 y(The)j Fl(diff)e Fr(command)f(supp)q(orts)j(this)f
+(application)f(of)h(regression)h(testing)g(b)o(y)f(pinp)q(oin)o(ting)f(the)i
+(di\013erences)177 2835 y(b)q(et)o(w)o(een)f(nearly-iden)o(tical)e(text)i
+(\014les.)1042 2940 y(94)p eop
+%%Page: 95 96
+95 95 bop 177 42 a Fo(3.15.7.6)48 b(Di\013summary)177 160 y
+Fr(The)16 b Fl(diffsummary)d Fr(command)g(writes)j(a)g(short)g(rep)q(ort)g
+(to)g(the)g(console)g(giving)e(the)i(n)o(um)o(b)q(er)f(of)g(di\013erence)177
+209 y(op)q(erations)20 b(that)f(ha)o(v)o(e)h(tak)o(en)f(place)h(and)f(ho)o(w)
+g(man)o(y)f(of)h(the)h(pairs)f(of)g(\014les)h(compared)f(w)o(ere)h(iden)o
+(tical.)177 259 y(Coun)o(ting)14 b(starts)h(at)f(the)h(most)e(recen)o(t)j
+(execution)f(of)f(a)g Fl(diffzero)e Fr(command,)g(or)i(if)f(there)j(has)f(b)q
+(een)g(none,)177 309 y(when)g(F)m(unnelW)m(eb)e(started)i(up.)177
+454 y Fl(Syntax)43 b(:)21 b(diffsummary)f(=)h("diffsummary")177
+504 y(Examples:)f(diffsummary)177 649 y Fr(The)15 b Fl(diffsummary)d
+Fr(command)g(w)o(as)i(added)h(so)f(as)g(to)h(allo)o(w)d(regression)k(testing)
+f(scripts)g(to)f(displa)o(y)g(a)g(sum-)177 699 y(mary)f(of)i(the)g(results)h
+(of)e(the)i(test.)22 b(If)14 b(the)i(summary)c(indicates)j(that)g(no)g(pair)f
+(of)g(\014les)h(di\013ered,)h(then)f(there)177 749 y(is)f(no)g(need)g(to)g
+(lo)q(ok)f(in)h(the)g Fl(diff)f Fr(log)g(\014le.)177 918 y
+Fo(3.15.7.7)48 b(Di\013zero)177 1036 y Fr(The)13 b Fl(diffzero)d
+Fr(command)g(zeros)j(the)g(di\013eren)o(t)g(summary)d(coun)o(ters)j(used)g(b)
+o(y)f(the)h Fl(diff)e Fr(and)h Fl(diffsummary)177 1086 y Fr(commands.)177
+1231 y Fl(Syntax)43 b(:)21 b(diffzero)f(=)i("diffzero")177
+1281 y(Examples:)e(diffzero)177 1426 y Fr(The)g Fl(diffzero)e
+Fr(command)f(w)o(as)j(added)g(so)g(as)g(to)f(allo)o(w)f(regression)j(testing)
+f(shellscripts)h(to)f(zero)g(their)177 1476 y(di\013erences)c(coun)o(ters)e
+(at)f(the)h(start)g(of)e(a)h(run.)18 b(This)13 b(allo)o(ws)f(testers)k(to)d
+(in)o(v)o(ok)o(e)f(the)i(same)e(regression)i(testing)177 1526
+y(script)h(t)o(wice)f(in)f(one)i(in)o(teractiv)o(e)f(session)h(without)e
+(receiving)h(an)g(in\015ated)g(di\013erences)i(summary)m(.)177
+1695 y Fo(3.15.7.8)48 b(Eneo)177 1814 y Fr(The)15 b Fl(eneo)e
+Fr(command)f(tak)o(es)j(one)f(\014lename)g(argumen)o(t.)k(If)c(the)h(\014le)f
+(do)q(es)h(not)g(exist,)f(no)g(action)g(is)h(tak)o(en.)k(If)177
+1863 y(the)14 b(\014le)f(do)q(es)h(exist,)f(it)g(is)f(deleted.)19
+b(In)13 b(b)q(oth)h(cases)g(success)i(status)d(is)g(returned.)20
+b(Ho)o(w)o(ev)o(er,)13 b(if)f(the)i(\014le)f(exists)177 1913
+y(and)h(cannot)g(b)q(e)g(deleted,)h Fl(eneo)e Fr(returns)i(sev)o(ere)h
+(status.)177 2058 y Fl(Syntax)43 b(:)21 b(eneo)g(=)h("eneo")e(s)i(filename)
+177 2108 y(Examples:)e(eneo)h(result.out)177 2253 y Fr(The)e
+Fl(eneo)e Fr(command)e(w)o(as)j(added)h(so)f(as)g(to)g(allo)o(w)f(regression)
+i(testing)g(scripts)g(to)f(ensure)i(that)e(existing)177 2303
+y(output)h(\014les)g(w)o(ere)h(not)f(presen)o(t)h(b)q(efore)g(pro)q(ceeding)g
+(with)e(a)h(test)h(run.)33 b(If)19 b(F)m(unnelW)m(eb)f(w)o(ere)i(to)f(fail)e
+(to)177 2353 y(generate)e(an)f(output)g(\014le,)f(it)h(w)o(ould)f(b)q(e)i
+(extremely)e(undesirable)h(for)g(the)h(old)e(v)o(ersion)h(to)f(b)q(e)i(used.)
+177 2439 y(ENEO)h(stands)h(for)e Fo(E)p Fr(stablish)g(the)h
+Fo(N)p Fr(on)g Fo(E)p Fr(xistence)h Fo(O)p Fr(f.)22 b(Most)16
+b(op)q(erating)f(systems)h(pro)o(vide)f(a)h(command)177 2489
+y(to)f(delete)h(\014les.)23 b(T)o(ypically)13 b(these)k(commands)c(are)i(v)o
+(erbs)h(suc)o(h)g(as)f(\\delete",)h(\\remo)o(v)o(e",)e(and)h(\\kill".)k(As)d
+(a)177 2539 y(consequence,)h(the)f(designers)g(of)e(delete)i(commands)d
+(usually)h(consider)i(the)f(command)e(to)h(ha)o(v)o(e)h(failed)f(if)g(it)177
+2589 y(fails)e(to)h(\014nd)g(the)g(\014le)g(to)g(b)q(e)g(deleted.)19
+b(Ho)o(w)o(ev)o(er,)13 b(in)g(m)o(y)e(exp)q(erience,)k(the)e(most)f(common)e
+(use)k(for)e(the)i(delete)177 2639 y(command)f(is)j(to)f Fm(establish)i(the)f
+(non-existenc)n(e)i(of)e Fr(one)g(or)g(more)e(\014les.)24 b(T)o(ypically)m(,)
+14 b(a)i(script)g(is)g(starting)g(up)177 2688 y(and)f(needs)i(to)e(clear)g
+(the)h(air)f(b)q(efore)h(getting)f(started.)23 b(If)15 b(the)h(\014les)f(are)
+h(there,)g(they)g(should)f(b)q(e)h(deleted;)h(if)177 2738 y(they)e(are)f
+(not,)f(then)i(that's)f(OK)g(to)q(o.)787 2723 y Fg(5)p 177
+2796 709 2 v 223 2823 a Ff(5)241 2835 y Fh(As)e(far)f(as)g(I)h(kno)o(w,)e
+(the)h Fe(eneo)g Fh(command)d(is)k(original.)1042 2940 y Fr(95)p
+eop
+%%Page: 96 97
+96 96 bop 177 42 a Fo(3.15.7.9)48 b(Execute)177 138 y Fr(The)20
+b Fl(execute)d Fr(command)f(causes)21 b(a)e(sp)q(eci\014ed)h(text)g(\014le)f
+(to)g(b)q(e)g(executed)i(as)e(a)g(F)m(unnelW)m(eb)g(shellscript.)177
+188 y(The)e(\014rst)h(argumen)o(t)d(is)i(the)g(name)f(of)g(the)h(script)g
+(\014le.)27 b(The)17 b(remaining)e(argumen)o(ts)h(are)h(assigned)g(to)f(the)
+177 237 y(substitution)i(v)n(ariables)f Fl($1)p Fr(,)g Fl($2)p
+Fr(,)g Fn(:)7 b(:)g(:)o Fr(,)18 b Fl($9)p Fr(.)28 b(Substitution)17
+b(v)n(ariables)g(in)g(the)h(range)g Fl($1)f Fr(to)g Fl($9)g
+Fr(that)h(do)f(not)177 287 y(corresp)q(ond)d(to)e(an)g(argumen)o(t)f(are)i
+(set)g(to)f(the)h(empt)o(y)e(string)h Fl("")p Fr(.)17 b Fl($0)12
+b Fr(is)g(set)h(to)f(the)h(empt)o(y)e(string)h(regardless.)177
+337 y(The)k(execute)h(command)12 b(can)k(b)q(e)f(used)h(recursiv)o(ely)m(,)g
+(allo)o(wing)d(shell)i(scripts)h(to)f(in)o(v)o(ok)o(e)f(eac)o(h)i(other.)23
+b(A)15 b(\014le)177 387 y(extension)g(default)e(of)h(\\)p Fl(.fws)p
+Fr(")e(\(F)m(unnelW)m(eb)i(Script\))g(applies)g(to)f(script)i(\014les.)177
+485 y Fl(Syntax)43 b(:)21 b(execute)f(=)i("execute")e(s)i(filename)e
+({argument_string)o(})177 534 y(Examples:)g(execute)g(megatest.fws)g
+(/usr/users/ross/)o(fwtes)o(t)f(!)395 584 y(execute)h(sloth)177
+682 y Fr(The)14 b(\014rst)h(example)e(ab)q(o)o(v)o(e)g(will)g(result)h(in)g
+(the)g(follo)o(wing)e(substitution)i(v)n(ariable)e(assignmen)o(ts.)177
+780 y Fl($0)22 b(=)f("")177 829 y($1)h(=)f("/usr/users/ross/f)o(wtest)o(")177
+879 y($2)h(=)f("!")177 929 y($3)h(=)f("")177 979 y(...)177
+1029 y($9)h(=)f("")177 1126 y Fr(It)16 b(should)f(b)q(e)g(stressed)j(that)d
+(there)i(are)f(no)f(lo)q(cal)f(v)n(ariables)h(in)g(the)g(F)m(unnelW)m(eb)g
+(command)e(language;)h(the)177 1176 y(v)n(ariables)f(ab)q(o)o(v)o(e)h(are)g
+(globally)e(mo)q(di\014ed.)177 1246 y(The)j Fl(execute)f Fr(command)e(w)o(as)
+i(added)h(to)g(allo)o(w)e(the)i(creation)h(of)e(sub-scripts)i(to)f(test)g(F)m
+(unnelW)m(eb)g(in)f(par-)177 1296 y(ticular)g(w)o(a)o(ys.)177
+1421 y Fo(3.15.7.10)48 b(Exists)177 1517 y Fr(The)19 b Fl(exists)d
+Fr(command)g(p)q(erforms)h(no)h(action)g(except)i(to)d(return)j(a)e(status.)
+31 b(If)18 b(the)g(\014le)h(sp)q(eci\014ed)g(in)f(its)177 1567
+y(argumen)o(t)13 b(exists)i(it)e(returns)i(success)i(status,)d(otherwise)h
+(it)e(returns)j(sev)o(ere)f(status.)177 1665 y Fl(Syntax)21
+b(:)g(exists)g(=)g("exists")g(s)g(filename)177 1714 y(Example:)f(exists)h
+(test6.fw)177 1812 y Fr(This)10 b(command)d(is)j(useful)g(in)g(regression)h
+(testing)f(for)g(ensuring)g(that)g(F)m(unnelW)m(eb)g(has)g(pro)q(duced)h(a)f
+(particular)177 1862 y(output)k(\014le.)177 1987 y Fo(3.15.7.11)48
+b(Fixeols)177 2083 y Fr(The)13 b Fl(fixeols)f Fr(command)e(tak)o(es)j(t)o(w)o
+(o)f(\014lename)g(argumen)o(ts:)k(an)d(input)f(\014le)h(and)g(an)f(output)h
+(\014le.)18 b(It)13 b(reads)g(in)177 2133 y(the)f(input)f(\014le)g(and)g
+(writes)h(it)e(to)h(the)h(output)f(\014le)g(c)o(hanging)g(all)e(the)j(end)g
+(of)e(line)h(con)o(trol)g(c)o(haracter)h(sequences)177 2183
+y(to)k(the)g(lo)q(cal)f(format.)22 b(It)15 b(can)h(also)f(tak)o(e)h(one)g
+(\014lename)f(argumen)o(t,)f(in)h(whic)o(h)h(case)h(it)e(replaces)i(the)f
+(target)177 2233 y(\014le)e(with)g(its)f(transformation.)177
+2331 y Fl(Syntax)43 b(:)21 b(fixeols)f(=)i("fixeols")e(s)i(filename)e([s)h
+(filename])177 2380 y(Examples:)f(fixeols)g(imported.hak)g(result.kln)395
+2430 y(fixeols)g(sloth.dat)177 2528 y Fr(The)12 b Fl(fixeols)e
+Fr(command)e(w)o(orks)k(b)o(y)f(parsing)g(the)h(input)f(\014le)g(in)o(to)g
+(alternating)f(runs)i(of)f(prin)o(table)g(c)o(haracters)177
+2578 y(\(ASCI)q(I)i(20)f(to)g(ASCI)q(I)h(126\))e(and)i(runs)g(of)e(non-prin)o
+(table)h(c)o(haracters)i(\(all)e(the)h(others\).)18 b(It)13
+b(then)g(parses)g(eac)o(h)177 2628 y(run)g(of)f(non-prin)o(table)f(c)o
+(haracters)j(from)d(left)h(to)g(righ)o(t)g(in)o(to)f(subruns)j(of)e(non-prin)
+o(tables)g(not)g(con)o(taining)f(the)177 2677 y(same)j(c)o(haracter)i(t)o
+(wice.)22 b(It)15 b(then)g(replaces)h(eac)o(h)g(subrun)g(with)e(a)h(nativ)o
+(e)f(EOL.)1479 2662 y Fg(6)1513 2677 y Fr(F)m(or)g(example,)f(if)i(a)f(nativ)
+o(e)177 2727 y(EOL)g(is)g Fl(X)p Fr(,)f(and)h Fl(ABCD)f Fr(are)h(non-prin)o
+(table)g(c)o(haracters,)h(and)f(the)g(\014le)g(to)g(b)q(e)g(con)o(v)o(erted)h
+(is)p 177 2757 709 2 v 223 2783 a Ff(6)241 2795 y Fh(Note:)j(A)13
+b(nativ)o(e)f(EOL)h(can)g(b)q(e)f(inserted)f(in)o(to)h(a)h(text)f(\014le)g
+(in)h(a)g(p)q(ortable)e(manner)f(simply)i(b)o(y)g(writing)g(\\)p
+Fe(\\n)p Fh(")g(to)h(the)f(text)177 2835 y(output)e(stream.)1042
+2940 y Fr(96)p eop
+%%Page: 97 98
+97 97 bop 177 42 a Fl(thisABisABCDanABAB)o(examp)o(leABC)o(CCof)18
+b(the)k(conversion.)177 173 y Fr(then)15 b Fl(fixeols)d Fr(w)o(ould)h(pro)q
+(duce)177 304 y Fl(thisXisXanXXexampl)o(eXXXo)o(f)19 b(the)i(conversion.)177
+435 y Fr(The)c Fl(fixeols)e Fr(command)f(w)o(as)j(devised)g(to)g(solv)o(e)f
+(the)i(problem)d(created)j(sometimes)d(when)i(text)g(\014les)g(are)177
+485 y(mo)o(v)o(ed)c(from)f(one)i(mac)o(hine)f(to)h(another)h(\(e.g.)e(with)h
+(the)h(k)o(ermit)e(program\))f(using)i(a)g(binary)g(transfer)h(mo)q(de)177
+534 y(rather)j(than)f(a)g(text)h(transfer)g(mo)q(de.)27 b(If)17
+b(suc)o(h)h(a)f(transfer)h(is)f(made,)f(and)h(the)h(text)g(\014le)f(line)g
+(termination)177 584 y(con)o(v)o(en)o(tions)f(di\013er)f(on)g(the)h(t)o(w)o
+(o)f(mac)o(hines,)f(one)i(can)f(wind)g(up)h(with)f(a)g(set)h(of)f(text)h
+(\014les)f(with)g(improp)q(erly)177 634 y(terminated)10 b(lines.)16
+b(This)10 b(can)g(cause)i(problems)d(on)h(a)f(n)o(um)o(b)q(er)h(of)f(fron)o
+(ts,)h(but)h(in)e(particular)h(a\013ects)i(regression)177 684
+y(testing)h(whic)o(h)f(relies)h(hea)o(vily)e(on)h(exact)h(comparisons)e(b)q
+(et)o(w)o(een)j(\014les.)k(The)12 b Fl(fixeols)f Fr(command)f(pro)o(vides)i
+(a)177 734 y(solution)g(to)h(this)g(problem)f(b)o(y)h(pro)o(viding)f(a)h(p)q
+(ortable)g(w)o(a)o(y)f(to)h(\\purify")f(text)i(\014les)f(whose)h(end)g(of)e
+(lines)h(ha)o(v)o(e)177 783 y(b)q(ecome)h(incorrect.)20 b(The)14
+b(regression)i(testing)e(scripts)h(all)e(apply)h Fl(fixeols)e
+Fr(to)i(their)g(input)g(and)g(output)g(\014les)177 833 y(b)q(efore)h(eac)o(h)
+f(test.)177 985 y Fo(3.15.7.12)48 b(Fw)177 1095 y Fr(The)12
+b Fl(fw)g Fr(command)d(allo)o(ws)h(F)m(unnelW)m(eb)i(prop)q(er)g(to)g(b)q(e)h
+(in)o(v)o(ok)o(ed)e(from)f(a)h(shell)h(script.)18 b(The)12
+b(syn)o(tax)g(is)g(almost)177 1145 y(iden)o(tical)h(to)h(the)h(syn)o(tax)e
+(with)h(whic)o(h)g(F)m(unnelW)m(eb)f(is)h(in)o(v)o(ok)o(ed)f(from)f(the)j(op)
+q(erating)e(system.)177 1276 y Fl(Syntax)43 b(:)21 b(fw)g(=)h("fw")f(s)h
+(ordinary_funnelw)o(eb_c)o(omman)o(d_lin)o(e)177 1325 y(Examples:)e(fw)h
+(sloth)g(+t)h(+d)395 1375 y(fw)f(-l)h(walrus)177 1506 y Fr(Some)13
+b(imp)q(ortan)o(t)f(p)q(oin)o(ts)i(ab)q(out)g(this)f Fl(fw)h
+Fr(command)d(are:)239 1637 y Fq(\017)21 b Fr(Options)14 b(are)g(inherited)h
+(from)d(the)i(default)g(shell)g(options.)239 1732 y Fq(\017)21
+b Fr(The)14 b Fl(F)g Fr(\(input)g(\014le)g(option\))f(m)o(ust)g(b)q(e)h
+(turned)h(on.)239 1827 y Fq(\017)21 b Fr(The)14 b Fl(K)p Fr(,)f
+Fl(H)p Fr(,)h(and)f Fl(X)h Fr(options)f(m)o(ust)g(b)q(e)i(turned)g(o\013.)239
+1922 y Fq(\017)21 b Fr(The)14 b Fl(J)g Fr(option)f(m)o(ust)g(b)q(e)h(turned)h
+(o\013.)239 2017 y Fq(\017)21 b Fr(The)14 b(options)g(sp)q(eci\014ed)h(in)f
+(a)f Fl(fw)h Fr(command)d(do)i(not)h(a\013ect)h(the)g(default)e(shell)h
+(options.)239 2112 y Fq(\017)21 b Fr(This)14 b(command)d(p)q(erforms)i(no)h
+(action)f(in)h(the)g(V)-5 b(AX)15 b(VMS)f(v)o(ersion)g(of)f(F)m(unnelW)m(eb.)
+177 2263 y Fo(3.15.7.13)48 b(Help)177 2373 y Fr(The)16 b Fl(help)f
+Fr(command)d(pro)o(vides)k(online)f(help)g(from)f(within)g(the)i(F)m(unnelW)m
+(eb)f(shell.)23 b(It)15 b(pro)o(vides)h(access)h(to)177 2423
+y(all)c(of)g(the)i(same)e(messages)h(that)f(the)i Fl(+H)e Fr(command)f(line)h
+(option)g(do)q(es.)177 2554 y Fl(Syntax)43 b(:)21 b(help)g(=)h("help")e([s)i
+(help_message_na)o(me])177 2604 y(Examples:)e(help)395 2654
+y(help)h(commands)177 2785 y Fr(If)14 b(no)h(message)f(name)g(is)g(giv)o(en,)
+g(the)h(default)g(message)f(is)h(displa)o(y)o(ed.)k(It)c(con)o(tains)g(a)f
+(list)g(of)g(the)h(other)h(help)177 2835 y(messages)e(and)g(their)g(names.)j
+(The)e(actual)e(messages)h(themselv)o(es)g(are)g(not)g(listed)g(here.)1042
+2940 y(97)p eop
+%%Page: 98 99
+98 98 bop 177 42 a Fo(3.15.7.14)48 b(Here)177 147 y Fr(The)19
+b Fl(here)e Fr(command)e(acts)j(as)g(a)g(target)g(for)g(the)g
+Fl(skipto)f Fr(command.)27 b(When)18 b(the)h(shell)f(in)o(terpreter)h(en-)177
+197 y(coun)o(ters)h(a)e Fl(skipto)g Fr(command,)e(it)i(ignores)h(all)e(the)i
+(follo)o(wing)d(commands)g(un)o(til)i(it)g(encoun)o(ters)i(a)f
+Fl(here)177 247 y Fr(command.)177 371 y Fl(Syntax)i(:)g(here)g(=)h("here")177
+421 y(Example:)e(here)177 545 y Fr(The)14 b Fl(skipto)p Fr(/)p
+Fl(here)c Fr(mec)o(hanism)h(w)o(as)i(created)i(to)e(allo)o(w)e(groups)i(of)g
+(regression)h(tests)h(to)e(b)q(e)g(skipp)q(ed)h(during)177
+595 y(debugging)f(without)h(ha)o(ving)f(to)h(commen)o(t)d(them)i(out.)18
+b(F)m(or)c(more)f(information,)d(see)15 b(Section)g(3.15.7.18.)177
+737 y Fo(3.15.7.15)48 b(Quit)177 843 y Fr(The)14 b Fl(quit)f
+Fr(command)e(terminates)i(F)m(unnelW)m(eb)g(immediately)d(and)k(returns)h
+(con)o(trol)e(to)h(the)g(op)q(erating)f(sys-)177 893 y(tem.)k(This)d(applies)
+g(regardless)h(of)e(the)i(depth)f(of)f(the)i(script)g(b)q(eing)e(executed.)
+177 1017 y Fl(Syntax)21 b(:)g(quit)g(=)h("quit")177 1067 y(Example:)e(quit)
+177 1209 y Fo(3.15.7.16)48 b(Set)177 1315 y Fr(The)15 b Fl(set)e
+Fr(command)f(mo)q(di\014es)h(the)i(default)f(shell)g(options.)k(F)m(or)c
+(example,)f Fl(set)21 b(+t)14 b Fr(sets)h(the)g Fl(+t)f Fr(option)f(for)177
+1365 y(all)g(subsequen)o(t)i(F)m(unnelW)m(eb)f(runs)g(within)g(the)g(shell)g
+(un)o(til)f(another)h(set)h(command)c(sets)k Fl(-t)p Fr(.)177
+1489 y Fl(Syntax)43 b(:)21 b(set)g(=)h("set")f(s)g(ordinary_funnelweb)o
+(_comm)o(and_l)o(ine)177 1539 y(Examples:)f(set)h(sloth)g(+t)g(+d)395
+1589 y(set)g(-lwalrus)177 1713 y Fr(The)c(restrictions)g(on)f(the)h
+Fl(set)e Fr(command)e(are)k(iden)o(tical)e(to)h(those)h(on)f(the)h
+Fl(fw)e Fr(command)e(except)18 b(that,)e(in)177 1763 y(addition,)c(the)j
+Fl(+F)e Fr(option)g(cannot)i(b)q(e)f(turned)h(on)f(in)f(the)i
+Fl(set)e Fr(command.)177 1840 y(The)f(set)h(command)c(is)j(useful)g(for)f
+(setting)i(option)e(defaults)h(b)q(efore)g(a)g(long)f(run)h(of)f(regression)i
+(tests.)19 b(It)12 b(could)177 1890 y(also)h(b)q(e)g(useful)h(to)f(set)h
+(default)f(options)f(in)h(a)g(F)m(unnelW)m(eb)f(shell)h(k)o(ept)h(b)o(y)f(a)g
+(user)h(in)f(a)f(w)o(orkstation)h(windo)o(w.)177 2033 y Fo(3.15.7.17)48
+b(Sho)o(w)177 2139 y Fr(The)14 b Fl(show)f Fr(command)e(displa)o(ys)j(the)g
+(curren)o(t)h(default)f(shell)f(options.)18 b(These)d(options)f(are)g(the)g
+(options)g(that)177 2189 y(subsequen)o(t)i Fl(fw)d Fr(commands)f(will)g
+(inherit.)177 2313 y Fl(Syntax)21 b(:)g(show)g(=)h("show")177
+2362 y(Example:)e(show)177 2505 y Fo(3.15.7.18)48 b(Skipto)177
+2611 y Fr(The)14 b Fl(skipto)f Fr(command)e(causes)k(the)g(shell)e(to)h
+(ignore)g(all)e(subsequen)o(t)k(commands)11 b(un)o(til)i(a)h
+Fl(here)f Fr(command)177 2661 y(is)h(encoun)o(tered.)177 2785
+y Fl(Syntax)43 b(:)21 b(skipto)g(=)g("skipto")177 2835 y(Examples:)f(skipto)
+1042 2940 y Fr(98)p eop
+%%Page: 99 100
+99 99 bop 177 42 a Fr(The)14 b Fl(skipto)p Fr(/)p Fl(here)c
+Fr(mec)o(hanism)h(w)o(as)i(created)i(to)e(allo)o(w)e(groups)i(of)g
+(regression)h(tests)h(to)e(b)q(e)g(skipp)q(ed)h(during)177
+91 y(debugging)c(without)f(ha)o(ving)g(to)h(commen)o(t)e(them)h(out.)17
+b(It)10 b(is)g(lik)o(e)f(a)h(cut)g(price)h Fl(goto)p Fr(.)16
+b(F)m(or)10 b(example,)f(supp)q(osing)177 141 y(that)15 b(there)h(w)o(ere)f
+(eigh)o(t)g(tests)h(and)e(that)h(y)o(ou)f(had)h(debugged)g(the)g(\014rst)h
+(\014v)o(e.)k(Y)m(ou)14 b(migh)o(t)f(w)o(an)o(t)h(to)h(skip)f(the)177
+191 y(\014rst)i(\014v)o(e)f(tests)h(so)g(that)f(y)o(ou)f(can)h(concen)o
+(trate)i(on)e(the)g(next)h(three.)22 b(The)16 b(follo)o(wing)c(co)q(de)k(sho)
+o(ws)f(ho)o(w)g(this)177 241 y(can)f(b)q(e)h(done.)177 359
+y Fl(skipto)177 409 y(execute)21 b(test)f(infile1)177 459 y(execute)h(test)f
+(infile2)177 509 y(execute)h(test)f(infile3)177 559 y(execute)h(test)f
+(infile4)177 608 y(execute)h(test)f(infile5)177 658 y(here)177
+708 y(execute)h(test)f(infile6)177 758 y(execute)h(test)f(infile7)177
+808 y(execute)h(test)f(infile8)177 926 y Fr(It)15 b(should)f(b)q(e)h
+(stressed)i(that)d(F)m(unnelW)m(eb)g(p)q(erforms)g(full)f(command)f(line)i
+(pro)q(cessing)h(including)f(the)h(dollar)177 976 y(substitutions)i(b)q
+(efore)g(testing)f(the)h(line)f(to)g(see)h(if)f(it)g(is)g Fl(here)p
+Fr(.)24 b(This)16 b(can)g(lead)g(to)g(non-ob)o(vious)f(problems.)177
+1026 y(F)m(or)f(example.)177 1144 y Fl(skipto)177 1194 y(!)22
+b(Test)f(the)g(Parser)177 1244 y(!)h(---------------)177 1294
+y(define)f(X)g("execute)f(parsertest.fws")177 1344 y($X)i(infile1)177
+1393 y($X)g(infile2)177 1443 y($X)g(infile3)177 1493 y($X)g(infile4)177
+1543 y($X)g(infile5)177 1593 y(here)177 1711 y Fr(The)14 b(ab)q(o)o(v)o(e)e
+(lo)q(oks)h(correct,)h(but,)f(b)q(ecause)i(the)e Fl(define)f
+Fr(command)e(isn't)j(executed)h(\(and)f Fl($X)g Fr(is)g(not)g(de\014ned\))177
+1761 y(the)h(subsequen)o(t)g Fl($X)f Fr(lines)g(result)g(in)g(a)f(leading)g
+(blanks)h(error.)18 b(The)c(problem)d(can)j(b)q(e)f(corrected)i(b)o(y)e
+(de\014ning)177 1811 y Fl($X)h Fr(b)q(efore)g(the)h Fl(skipto)d
+Fr(command.)177 1947 y Fo(3.15.7.19)48 b(Status)177 2050 y
+Fr(The)20 b Fl(status)e Fr(command)f(tak)o(es)i(t)o(w)o(o)g(forms.)33
+b(In)20 b(its)f(\014rst)h(form)e(in)h(whic)o(h)g(no)g(argumen)o(ts)g(are)g
+(giv)o(en,)h(it)177 2099 y(writes)13 b(out)f(the)h(n)o(um)o(b)q(er)e(of)h(w)o
+(arnings,)g(errors)h(and)f(sev)o(ere)i(errors)g(that)e(1\))g(w)o(ere)h
+(generated)h(b)o(y)e(the)g(previous)177 2149 y(command)j(and)j(2\))g(ha)o(v)o
+(e)f(b)q(een)i(generated)g(during)f(the)g(en)o(tire)h(shell)f(in)o(v)o(o)q
+(cation.)28 b(In)18 b(its)g(second)h(form)d(it)177 2199 y(tak)o(es)d(from)d
+(one)j(to)f(three)h(argumen)o(ts)f(eac)o(h)g(of)g(whic)o(h)g(sp)q(eci\014es)i
+(a)e(diagnostic)g(sev)o(erit)o(y)h(and)f(a)g(n)o(um)o(b)q(er.)k(The)177
+2249 y Fl(status)e Fr(command)e(compares)j(eac)o(h)g(of)g(these)h(n)o(um)o(b)
+q(ers)f(with)g(the)g(n)o(um)o(b)q(er)g(of)f(that)h(diagnostic)f(generated)177
+2299 y(b)o(y)g(the)g(previous)h(command)c(and)i(generates)j(a)d(sev)o(ere)j
+(error)f(if)e(they)h(di\013er.)177 2417 y Fl(Syntax)43 b(:)21
+b(status)g(=)g("status")f({s)i(\("w"|"e"|"s"\))d(num}0..3)177
+2467 y(Examples:)h(status)395 2517 y(status)h(w1)g(e5)g(s1)395
+2567 y(status)g(w4)395 2616 y(status)g(s1)g(e2)177 2735 y Fr(The)15
+b Fl(status)d Fr(command)g(w)o(as)h(in)o(tro)q(duced)i(to)f(test)h(the)g
+(status)f(results)i(of)d(commands)f(during)h(their)i(debug-)177
+2785 y(ging.)i(It)c(is)g(also)f(useful)h(for)g(c)o(hec)o(king)h(to)e(see)j
+(that)e(the)g(righ)o(t)g(n)o(um)o(b)q(er)f(of)h(diagnostics)f(ha)o(v)o(e)h(b)
+q(een)h(generated)177 2835 y(at)g(particular)g(p)q(oin)o(ts)f(in)h(test)h
+(scripts.)1042 2940 y(99)p eop
+%%Page: 100 101
+100 100 bop 177 42 a Fo(3.15.7.20)48 b(T)l(olerate)177 141
+y Fr(The)15 b Fl(tolerate)e Fr(command)f(instructs)k(the)f(shell)f(not)g(to)h
+(ab)q(ort)f(pro)q(cessing)i(of)e(the)h(script)g(if)f(the)h(next)g(com-)177
+191 y(mand)c(generates)k(one)e(or)g(more)f(w)o(arnings,)g(errors,)i(or)f(sev)
+o(ere)h(errors.)19 b(F)m(or)13 b(the)g(purp)q(oses)i(of)d(this)h(command,)177
+241 y(a)g(blank)f(line)h(coun)o(ts)g(as)h(a)e(command,)e(so)j(b)q(e)h(sure)g
+(to)f(place)g(the)h Fl(tolerate)d Fr(command)g(imm)o(ediately)f(ab)q(o)o(v)o
+(e)177 291 y(the)15 b(command)c(ab)q(out)j(whic)o(h)f(y)o(ou)h(wish)f(to)h(b)
+q(e)h(toleran)o(t.)177 401 y Fl(Syntax)21 b(:)g(tolerate)f(=)i("tolerate")177
+451 y(Example:)e(tolerate)177 561 y Fr(The)15 b(tolerate)f(command)d(w)o(as)j
+(in)o(tro)q(duced)h(to)e(allo)o(w)g(F)m(unnelW)m(eb)g(\(i.e.)g(the)i
+Fl(fw)e Fr(command\))e(to)j(b)q(e)h(tested)g(in)177 611 y(a)f(script)g(under)
+h(conditions)f(whic)o(h)f(w)o(ould)h(normally)d(cause)k(it)e(to)h(ab)q(ort)g
+(the)g(script.)177 741 y Fo(3.15.7.21)48 b(T)l(race)177 841
+y Fr(The)13 b Fl(trace)e Fr(command)e(turns)k(on)f(or)g(o\013)g(command)d
+(tracing)j(during)g(script)h(execution.)18 b(By)12 b(default,)g(tracing)177
+891 y(is)i(turned)h(o\013.)177 1001 y Fl(Syntax)43 b(:)21 b(trace)g(=)g
+("trace")g([s)g(\("on")g(|)h("off"\)])177 1051 y(Examples:)e(trace)h(on)395
+1101 y(trace)g(off)177 1211 y Fr(The)14 b Fl(trace)f Fr(command)e(w)o(as)j
+(in)o(tro)q(duced)h(to)f(assist)g(in)f(the)i(debugging)e(of)h(regression)h
+(test)g(scripts.)177 1342 y Fo(3.15.7.22)48 b(W)l(rite)177
+1441 y Fr(The)15 b Fl(write)e Fr(command)f(accepts)k(a)e(double-quoted)h
+(argumen)o(t)e(and)h(writes)i(it)e(follo)o(w)o(ed)f(b)o(y)h(an)g(EOL)h(to)f
+(the)177 1491 y(console)k(\(standard)g(output\).)29 b(There)19
+b(is)e(no)g(need)h(to)g(double)f(an)o(y)g(double)g(quotes)h(o)q(ccurring)g
+(within)f(the)177 1541 y(string.)177 1651 y Fl(Syntax)43 b(:)21
+b(write)g(=)g("write")g(s)g(string)177 1701 y(Examples:)f(write)h("Now)g
+(about)g(to)g(start)g(the)g(next)g(test.")395 1751 y(write)g("You)g(don't)g
+(need)g(to)g(")h(double)e(enclosed)g(double)h(quotes.")177
+1861 y Fr(The)13 b Fl(write)f Fr(command)d(w)o(as)k(added)f(so)h(as)g(to)f
+(allo)o(w)f(regression)j(testing)e(scripts)i(to)e(inform)f(the)i(user)g(of)f
+(their)177 1911 y(progress.)177 2041 y Fo(3.15.7.23)48 b(W)l(riteu)177
+2141 y Fr(The)14 b Fl(writeu)e Fr(command)e(is)j(iden)o(tical)g(to)g(the)h
+Fl(write)e Fr(command)e(except)15 b(that)e(it)g(underlines)h(the)g(text)g(on)
+f(an)177 2191 y(additional)f(follo)o(wing)f(output)k(line.)177
+2301 y Fl(Syntax)43 b(:)21 b(writeu)g(=)g("writeu")f(s)i(string)177
+2351 y(Examples:)e(writeu)h("Test)f(6")177 2511 y Fi(3.16)70
+b(Concluding)22 b(Remarks)177 2625 y Fr(This)d(c)o(hapter)i(de\014nes)f(the)g
+(seman)o(tics)f(of)f(the)i(F)m(unnelW)m(eb)f(program.)32 b(As)20
+b(stated)g(at)f(the)h(start)g(of)f(this)177 2675 y(c)o(hapter,)g(this)f(do)q
+(cumen)o(t)f(tak)o(es)h(precedence)i(o)o(v)o(er)e(the)g(F)m(unnelW)m(eb)f
+(program.)27 b(While)17 b(the)h(de\014nition)f(of)177 2725
+y(F)m(unnelW)m(eb)12 b(in)h(this)g(c)o(hapter)g(is)g(reasonably)g(solid,)e
+(it)i(is)f(far)h(from)e(w)o(atertigh)o(t,)h(and)h(it)f(is)h(hop)q(ed)g(that)g
+(it)g(can)177 2774 y(b)q(e)g(tigh)o(tened)g(further)g(in)f(future)h(v)o
+(ersions.)18 b(All)12 b(constructiv)o(e)i(criticism)d(will)g(b)q(e)i
+(gratefully)e(receiv)o(ed)j(b)o(y)e(the)177 2824 y(author)i(Ross)g(William)o
+(s)d(\()p Fl(ross@spam.adelaide.)o(edu.a)o(u)p Fr(\).)1032
+2940 y(100)p eop
+%%Page: 101 102
+101 101 bop 177 376 a Fj(Chapter)34 b(4)177 607 y Fp(F)-10
+b(unnelW)g(eb)41 b(Installation)177 846 y Fr(This)14 b(c)o(hapter)h(describ)q
+(es)h(ho)o(w)d(to)h(obtain,)f(compile,)e(and)j(install)f(F)m(unnelW)m(eb.)k
+(Y)m(ou)d(will)e(need:)239 955 y Fq(\017)21 b Fr(FTP)14 b(access)i(to)e(the)g
+(in)o(ternet)h Fm(or)e Fr(a)h(F)m(unnelW)m(eb)f(distribution)h(kit)f(on)h
+(disk.)239 1037 y Fq(\017)21 b Fr(A)d(Sun,)h(VMS)g(V)-5 b(AX,)18
+b(Macin)o(tosh,)h(or)f(PC)h Fm(or)f Fr(lots)g(of)f(extra)i(time)e(to)h(p)q
+(ort)h(F)m(unnelW)m(eb)e(to)h(a)g(new)281 1086 y(platform.)239
+1168 y Fq(\017)j Fr(Ab)q(out)15 b(four)f(megab)o(ytes)g(of)g(free)h(disk)f
+(space.)21 b(Y)m(ou)14 b(migh)o(t)e(b)q(e)j(able)g(to)f(install)f(it)h(with)h
+(less,)f(but)h(four)281 1217 y(megab)o(ytes)f(is)h(safe.)21
+b(The)15 b(distribution)f(kit)h(itself)f(is)h(ab)q(out)f(t)o(w)o(o)h(and)f(a)
+h(half)f(megab)o(ytes.)20 b(If)14 b(y)o(ou)g(are)281 1267 y(short)d(on)g
+(space,)h(y)o(ou)f(can)g(thro)o(w)g(a)o(w)o(a)o(y)f(ev)o(erything)h(after)g
+(installation)e(except)k(the)e(binary)g(executable)281 1317
+y(whic)o(h)j(will)e(consume)i(ab)q(out)f(half)g(a)h(megab)o(yte.)239
+1398 y Fq(\017)21 b Fr(A)14 b(C)g(compiler.)239 1479 y Fq(\017)21
+b Fr(An)16 b(acquain)o(tance)h(with)f(the)h(C)f(programming)d(language)j(and)
+g(the)h(abilit)o(y)d(to)j(compile)d(and)i(link)g(C)281 1529
+y(programs)d(on)g(y)o(our)h(mac)o(hine.)239 1610 y Fq(\017)21
+b Fr(Elemen)o(tary)13 b(systems)h(programming)c(kno)o(wledege)k(for)g(y)o
+(our)g(mac)o(hine.)239 1692 y Fq(\017)21 b Fr(Ab)q(out)14 b(an)g(hour.)177
+1802 y(Y)m(ou)f(will)f Fm(not)i Fr(need)g(an)o(y)f(sort)h(of)f(system)g
+(privileges)h(to)f(install)f(F)m(unnelW)m(eb,)h(unless)h(y)o(ou)f(w)o(an)o(t)
+g(the)h(F)m(unnel-)177 1851 y(W)m(eb)g(command)d Fl(fw)i Fr(to)h(b)q(e)g
+(automatically)d(a)o(v)n(ailable)h(to)i(ev)o(ery)o(one)g(on)g(y)o(our)g(mac)o
+(hine)e(as)i(w)o(ell)f(as)h(y)o(ourself.)177 2011 y Fi(4.1)70
+b(Obtaining)22 b(a)h(Cop)n(y)g(of)h(F)-6 b(unnelW)g(eb)177
+2125 y Fr(The)14 b(simplest)f(w)o(a)o(y)h(to)f(obtain)g(a)h(cop)o(y)g(of)f(F)
+m(unnelW)m(eb)h(is)f(b)o(y)h(anon)o(ymous)e(FTP)i(from:)243
+2235 y Fl(Machine)63 b(:)22 b(sirius.itd.adelaid)o(e.edu)o(.au)c
+([IP=129.127.40.3].)243 2285 y(Directory)h(:)j(~pub/funnelweb/)62
+b(\(or)22 b(a)f(directory)f(of)h(similar)g(name\).)177 2395
+y Fr(It)d(is)f(not)g(clear)h(at)f(the)h(time)e(of)h(writing)g(whether)h(F)m
+(unnelW)m(eb)f(will)f(b)q(e)i(presen)o(ted)h(as)f(a)f(\\)p
+Fl(.tar)p Fr(")f(\014le,)i(or)177 2444 y(as)e(a)g(directory)h(tree,)g(or)f(b)
+q(oth.)25 b(Just)17 b(sni\013)f(around)g(and)g(use)g(y)o(our)g(common)d
+(sense.)27 b(Tw)o(o)15 b(p)q(oin)o(ts)h(deserv)o(e)177 2494
+y(atten)o(tion)e(ho)o(w)o(ev)o(er:)228 2604 y(1.)20 b(Be)15
+b(sure)g(to)f(use)h(the)f Fm(text)g Fr(transfer)h(mo)q(de)e(whenev)o(er)j(y)o
+(ou)d(transfer)i(ra)o(w)f(F)m(unnelW)m(eb)g(\014les.)19 b(Ho)o(w)o(ev)o(er,)
+281 2654 y(y)o(ou)13 b(should)h(use)h Fm(binary)f Fr(mo)q(de)e(for)i(T)m(AR)f
+(\014les)h(and)g(other)h(conglomerate)d(represen)o(tations.)228
+2735 y(2.)20 b(If)13 b(y)o(ou)g(ha)o(v)o(e)g(to)g(transfer)i(the)f(\014les)f
+(individually)m(,)d(don't)j(lump)f(all)g(the)i(F)m(unnelW)m(eb)f(\014les)g
+(in)o(to)g(a)g(single)281 2785 y(directory)m(.)20 b(Refer)14
+b(to)h(the)g(sections)g(that)f(follo)o(w)f(for)h(information)d(on)j(the)h
+(directory)g(tree)h(y)o(ou)e(should)281 2835 y(create)h(to)f(receiv)o(e)h
+(the)g(F)m(unnelW)m(eb)e(\014les.)1032 2940 y(101)p eop
+%%Page: 102 103
+102 102 bop 177 42 a Fr(If)13 b(anon)o(ymous)f(FTP)h(is)g(not)h(a)o(v)n
+(ailable)d(to)i(y)o(ou,)f(con)o(tact)i(the)g(author)f(for)g(up-to-date)h
+(information)c(on)j(other)177 91 y(c)o(hannels)i(of)e(distribution.)243
+207 y Fl(Name:)42 b(Dr)21 b(Ross)g(N.)h(Williams)243 257 y(Email:)e
+(ross@spam.adelaide)o(.edu.)o(au)243 307 y(Snail:)g(16)h(Lerwick)g(Avenue,)f
+(Hazelwood)g(Park)h(5066,)g(Australia.)177 468 y Fi(4.2)70
+b(Establishing)21 b(The)i(Directory)f(T)-6 b(ree)177 584 y
+Fr(A)o(t)15 b(this)g(stage,)f(w)o(e)h(will)e(assume)h(that)h(y)o(ou)f(ha)o(v)
+o(e)h(someho)o(w)e(obtained)h(a)h(set)g(of)f(\014les)h(that)g(are)g(supp)q
+(osed)h(to)177 634 y(b)q(e)f(F)m(unnelW)m(eb,)f(and)h(that)f(they)i(are)f
+(sitting)f(on)g(a)h(disk)f(on)h(the)g(mac)o(hine)e(on)i(whic)o(h)f(y)o(ou)g
+(wish)h(to)f(compile)177 684 y(and)g(install)f(F)m(unnelW)m(eb.)177
+758 y(The)f(\014rst)g(thing)f(y)o(ou)f(ha)o(v)o(e)h(to)g(do)g(is)h(to)f(mak)o
+(e)e(sure)k(that)e(the)h(F)m(unnelW)m(eb)e(directory)i(tree)h(has)e(b)q(een)i
+(correctly)177 808 y(unpac)o(k)o(ed.)19 b(The)14 b(directory)h(tree)g(should)
+e(lo)q(ok)g(lik)o(e)g(this.)243 924 y Fl(fwdir)151 b(-)22 b(Root)f(FunnelWeb)
+f(directory.)308 973 y(admin)86 b(-)22 b(Administrative)d(files.)308
+1023 y(answers)42 b(-)22 b(Answers)e(to)h(test)g(suite.)308
+1073 y(hackman)42 b(-)22 b(FunnelWeb)e(Hacker's)g(Manual.)308
+1123 y(results)42 b(-)22 b(For)f(test)g(results.)308 1173 y(scripts)42
+b(-)22 b(Test)f(scripts.)308 1222 y(sources)42 b(-)22 b(Source)e(code.)308
+1272 y(tests)86 b(-)22 b(Test)f(suite.)308 1322 y(userman)42
+b(-)22 b(FunnelWeb)e(User's)g(Manual.)177 1438 y Fr(The)e(follo)o(wing)d
+(sections)j(describ)q(e)i(the)e(con)o(ten)o(ts)g(of)f(eac)o(h)h(directory)g
+(in)f(alphab)q(etical)g(order.)29 b(Chec)o(k)18 b(the)177 1488
+y(con)o(ten)o(ts)g(to)f(mak)o(e)e(sure)j(that)f(y)o(ou)g(ha)o(v)o(e)f(ev)o
+(erything.)28 b(Do)16 b(not)h(b)q(ecome)g(fussed)h(if)e(y)o(our)g
+(con\014guration)h(is)177 1537 y(not)d(quite)f(as)h(sp)q(eci\014ed)h(as)e(it)
+g(is)h(v)o(ery)g(easy)g(for)f(installation)e(guides)j(suc)o(h)g(as)g(this)f
+(one)h(to)g(go)f(out)g(of)g(date)h(as)177 1587 y(minor)g(last)h(min)o(ute)f
+(c)o(hanges)i(and)g(up)q(dates)g(are)g(made)f(to)g(the)h(distribution)f(kit.)
+22 b(Chec)o(k)17 b(the)f(source)h(from)177 1637 y(whic)o(h)d(y)o(ou)f
+(obtained)h(the)g(kit,)f(and)h(if)f(it)h(is)f(di\013eren)o(t)i(to)q(o,)e(pro)
+q(ceed.)177 1778 y Fd(4.2.1)55 b(Admin)18 b(Directory)177 1879
+y Fr(The)c Fl(admin)e Fr(directory)i(con)o(tains)f(administrativ)o(e)e
+(\014les)j(to)f(do)g(with)g(licensing)g(and)g(suc)o(h.)18 b(It)c(is)f(also)f
+(a)h(catc)o(h-)177 1929 y(all)e(directory)i(for)e(\014les)i(that)f(don't)f(b)
+q(elong)h(an)o(ywhere)g(else.)18 b(A)o(t)12 b(the)h(time)e(of)g(writing,)g
+(it)h(is)f(not)h(clear)h(exactly)177 1979 y(what)h(will)e(b)q(e)j(in)e(the)i
+Fl(admin)e Fr(directory)m(.)18 b(Wh)o(y)13 b(not)h(tak)o(e)g(a)g(lo)q(ok?)177
+2120 y Fd(4.2.2)55 b(Answ)n(ers)20 b(Directory)177 2221 y Fr(The)13
+b Fl(answers)f Fr(directory)h(con)o(tains)g(the)g(\\correct)h(answ)o(ers")g
+(to)f(all)e(the)j(regression)g(testing)f(input)f(\014les.)18
+b(The)177 2271 y(regression)d(test)g(scripts)g(compare)e(these)j(\014les)e
+(to)g(the)g(\014les)g(generated)i(in)d(the)i Fl(results)d Fr(directory)m(.)
+177 2386 y Fl(an01.lis)20 b(...)h(an04.lis)177 2436 y(ex01.lis)f(...)h
+(ex16.lis)177 2486 y(ex01.out)f(...)h(ex10.out)177 2536 y(ex11.tex)f(...)h
+(ex16.tex)177 2586 y(generate.lis)177 2635 y(hi01.lis)f(...)h(hi10.lis)177
+2685 y(hi01.out)f(...)h(hi05.out)177 2735 y(hi06a.out)177 2785
+y(hi06b.out)177 2835 y(hi07a.out)1032 2940 y Fr(102)p eop
+%%Page: 103 104
+103 103 bop 177 42 a Fl(hi07b.out)177 91 y(hi08.out)20 b(...)h(hi10.out)177
+141 y(pr01.lis)f(...)h(pr10.lis)177 191 y(sc01.lis)f(...)h(sc29.lis)177
+241 y(tg01.lis)f(...)h(tg09.lis)177 291 y(tg01.out)f(...)h(tg09.out)177
+340 y(wv01.lis)f(...)h(wv06.lis)177 390 y(wv01.tex)f(...)h(wv06.tex)177
+532 y Fd(4.2.3)55 b(Hac)n(kman)18 b(Directory)177 634 y Fr(The)c
+Fl(hackman)f Fr(directory)i(con)o(tains)e(the)i Fl(.tex)e Fr(\014les)h(that)g
+(mak)o(e)e(up)i(the)h Fm(F)m(unnelWeb)h(Hacker's)e(Manual)p
+Fr(.)177 750 y Fl(h_ch0.tex)107 b(-)22 b(Preface,)e(etc.)177
+800 y(h_ch1.tex)107 b(-)22 b(Design.)177 850 y(h_ch2.tex)107
+b(-)22 b(Implementation.)177 900 y(h_ch3.tex)107 b(-)22 b(Modification.)177
+949 y(h_ch4.tex)107 b(-)22 b(Future.)177 999 y(h_cha.tex)107
+b(-)22 b(Appendices.)177 1049 y(h_manual.tex)41 b(-)22 b(Main)f(TeX)g(file.)
+177 1166 y Fr(See)15 b(the)f(commen)o(t)e(at)h(the)i(top)e(of)h
+Fl(h)p 769 1166 14 2 v 15 w(manual.tex)e Fr(\014le)h(for)h(instructions)g(on)
+g(ho)o(w)f(to)h(t)o(yp)q(eset)h(and)f(prin)o(t)f(the)177 1216
+y Fm(F)m(unnelWeb)j(Hacker's)f(Manual)p Fr(.)177 1290 y(There)j(is)e(no)h
+(need)g(to)g(read)g(or)g(prin)o(t)f(the)h Fm(F)m(unnelWeb)i(Hacker's)e
+(Manual)g Fr(unless)h(y)o(ou)e(in)o(tend)h(to)f(mo)q(dify)177
+1340 y(F)m(unnelW)m(eb.)177 1482 y Fd(4.2.4)55 b(Results)18
+b(Directory)177 1584 y Fr(The)f Fl(results)f Fr(directory)h(exists)g(as)g(a)g
+(target)g(directory)g(for)g(the)g(output)g(\014les)g(generated)h(b)o(y)e(F)m
+(unnelW)m(eb)177 1633 y(during)d(regression)i(testing.)j(This)13
+b(directory)h(is)g(distributed)f(empt)o(y)g(and)g(should)g(b)q(e)h(empt)o(y)e
+(at)h(the)h(start)g(of)177 1683 y(regression)i(testing.)22
+b(Ho)o(w)o(ev)o(er,)15 b(it)f(is)h(p)q(ermissible)f(for)h(the)g
+Fl(results)e Fr(directory)j(to)f(con)o(tain)f(\014les)h(generated)177
+1733 y(during)i(a)f(previous)h(test)h(run,)g(as)f(the)g(regression)h(testing)
+g(scripts)g(delete)g(sp)q(eci\014c)g(un)o(w)o(an)o(ted)f(\014les)g(b)q(efore)
+177 1783 y(eac)o(h)e(test)g(an)o(yw)o(a)o(y)m(.)177 1925 y
+Fd(4.2.5)55 b(Scripts)19 b(Directory)177 2026 y Fr(The)h Fl(scripts)e
+Fr(directory)i(stores)h(the)f(F)m(unnelW)m(eb)f(command)e(shell)i(scripts)i
+(that)e(are)h(used)g(to)g(p)q(erform)177 2076 y(regression)15
+b(testing.)177 2193 y Fl(master.fws)85 b(-)22 b(The)f(master)g(test)g
+(script.)f(This)h(is)g(the)g(one)h(you)f(run.)177 2243 y(test_gen.fws)41
+b(-)22 b(Script)e(to)i(generate)e(certain)g(tricky)h(input)g(files.)177
+2292 y(test_l.fws)85 b(-)22 b(Test)f(FunnelWeb)f(with)h(+L.)177
+2342 y(test_ld.fws)63 b(-)22 b(Test)f(FunnelWeb)f(with)h(+L)g(+B...)177
+2392 y(test_lo.fws)63 b(-)22 b(Test)f(FunnelWeb)f(with)h(+L)g(+O.)177
+2442 y(test_lo2.fws)41 b(-)22 b(Test)f(FunnelWeb)f(with)h(+L)g(+O)g(\(two)g
+(output)g(files\).)177 2492 y(test_lot.fws)41 b(-)22 b(Test)f(FunnelWeb)f
+(with)h(+L)g(+O)g(+T.)177 2541 y(test_lt.fws)63 b(-)22 b(Test)f(FunnelWeb)f
+(with)h(+L)g(+T.)177 2683 y Fd(4.2.6)55 b(Sources)19 b(Directory)177
+2785 y Fr(The)g Fl(sources)d Fr(directory)j(con)o(tains)f Fm(al)r(l)f
+Fr(of)g(the)i(C)f(source)h(\014les)f(required)h(to)f(build)f(a)h(F)m(unnelW)m
+(eb)f(binary)177 2835 y(executable.)i(In)14 b(the)h(follo)o(wing)c(list,)i
+(\014les)h(giv)o(en)g(without)f(an)h(extension)g(represen)o(t)j(b)q(oth)d
+Fl(.c)f Fr(and)h Fl(.h)f Fr(\014les.)1032 2940 y(103)p eop
+%%Page: 104 105
+104 104 bop 177 42 a Fl(analyse)151 b(-)22 b(The)f(analyser.)177
+91 y(as)261 b(-)22 b(Assertions.)177 141 y(clock)195 b(-)22
+b(A)f(clock)g(abstraction.)177 191 y(command)151 b(-)22 b(The)f(shell)g
+(command)f(interpreter.)177 241 y(data)217 b(-)22 b(Shared)e(data)h
+(structures)f(and)h(global)g(variables.)177 291 y(dump)217
+b(-)22 b(Functions)e(to)h(dump)g(internal)f(data)h(structures.)177
+340 y(environ.h)107 b(-)22 b(Lightweight)d(machine-dependent,)f
+(program-independent)g(header.)177 390 y(help)217 b(-)22 b(Module)e(to)i
+(write)f(out)g(help)g(messages.)177 440 y(help_gnu)129 b(-)22
+b(Function)e(to)h(write)g(out)g(the)g(GNU)h(license.)177 490
+y(help_gnu.txt)41 b(-)22 b(The)f(GNU)g(license)g(in)g(text)g(form.)177
+540 y(help_gnu.ctx)41 b(-)22 b(The)f(GNU)g(license)g(in)g(C)h(code)e(form.)
+177 589 y(list)217 b(-)22 b(A)f(list)g(abstraction.)177 639
+y(lister)173 b(-)22 b(Module)e(to)i(manage)e(the)i(listing)e(file.)177
+689 y(machin)173 b(-)22 b(Module)e(to)i(hold)f(machine-dependen)o(t,)e
+(program-dependent)f(stuff.)177 739 y(main.c)173 b(-)22 b(The)f(main\(\))g
+(program.)177 789 y(mapper)173 b(-)22 b(Module)e(to)i(read)f(files)g(into)f
+(memory.)177 839 y(memory)173 b(-)22 b(Memory)e(management.)177
+888 y(misc)217 b(-)22 b(Miscellaneous)d(functions.)177 938
+y(option)173 b(-)22 b(Command)e(line)h(option)g(processing.)177
+988 y(parser)173 b(-)22 b(The)f(parser.)177 1038 y(scanner)151
+b(-)22 b(The)f(scanner.)177 1088 y(section)151 b(-)22 b(A)f(section)g(number)
+f(abstraction.)177 1137 y(style.h)151 b(-)22 b(A)f(machine-independent,)d
+(program-independen)o(t)h(header)i(file.)177 1187 y(table)195
+b(-)22 b(A)f(table)g(abstraction.)177 1237 y(tangle)173 b(-)22
+b(The)f(tangler.)177 1287 y(texhead)151 b(-)22 b(Module)e(to)i(write)f(out)g
+(TeX)g(header)f(in)i(documentation)d(files.)177 1337 y(texhead.ctx)63
+b(-)22 b(The)f(TeX)g(header)g(in)g(C)h(code)f(form.)177 1386
+y(texhead.tex)63 b(-)22 b(The)f(TeX)g(header)g(in)g(TeX)g(form.)177
+1436 y(weave)195 b(-)22 b(The)f(weaver.)177 1486 y(writfile)129
+b(-)22 b(Output)e(abstraction.)177 1594 y Fr(The)13 b(\\)p
+Fl(.txt)p Fr(",)f(and)g(\\)p Fl(.tex)p Fr(")g(\014les)h(do)f(not)h
+(participate)g(in)f(the)i(compilation,)c(but)j(are)g(considered)h(part)f(of)f
+(the)177 1644 y(source)17 b(co)q(de)g(as)f(they)g(w)o(ere)h(used)f(to)g
+(generate)h(the)f(\\)p Fl(.ctx)p Fr(")f(\014les.)24 b(The)16
+b(\\)p Fl(.ctx)p Fr(")e(\014les)j(are)f(included)g(b)o(y)f
+Fl(.c)177 1693 y Fr(\014les)f(of)g(the)g(same)f(name.)k(They)d(do)g(not)g
+(need)h(to)e(b)q(e)i(compiled)d(themselv)o(es.)177 1831 y Fd(4.2.7)55
+b(T)-5 b(ests)19 b(Directory)177 1930 y Fr(The)13 b Fl(tests)f
+Fr(directory)h(stores)h(all)d(the)i(input)f(\014les)h(of)f(the)h(regression)h
+(test)g(suite.)k(These)c(come)d(in)h(t)o(w)o(o)g(kinds:)177
+1980 y(F)m(unnelW)m(eb)k(input)g(\014les)h(with)f(extensions)i(of)e(\\)p
+Fl(.fw)p Fr(",)f(and)h(F)m(unnelW)m(eb)g(include)h(\014les)g(with)f
+(extensions)h(of)177 2030 y(\\)p Fl(.fwi)p Fr(".)177 2137 y
+Fl(FunnelWeb)j(Input)h(Files:)243 2187 y(an01.fw)f(...)h(an04.fw)86
+b(-)21 b(Analyser)g(tests.)243 2237 y(ex01.fw)f(...)h(ex16.fw)86
+b(-)21 b(Examples)g(from)f(the)i(tutorial)e(in)h(user)g(manual.)243
+2287 y(generate.fw)259 b(-)21 b(Generates)f(a)i(few)f(other)g(tricky)f(input)
+h(files.)243 2337 y(hi01.fw)f(...)h(hi10.fw)86 b(-)21 b(Examples)g(from)f
+(the)i(hints)e(chapter)h(in)g(user)g(manual.)243 2386 y(pr01.fw)f(...)h
+(pr10.fw)86 b(-)21 b(Parser)g(tests.)243 2436 y(sc01_note.fw)237
+b(-)21 b(A)h(note)f(explaining)f(absence)g(of)h(sc01.fw)243
+2486 y(sc02.fw)f(...)h(sc29.fw)86 b(-)21 b(Scanner)g(tests.)243
+2536 y(tg01.fw)f(...)h(tg09.fw)86 b(-)21 b(Tangler)g(tests.)243
+2586 y(wv01.fw)f(...)h(wv06.fw)86 b(-)21 b(Weaver)g(tests.)177
+2685 y(FunnelWeb)f(Include)g(Files:)243 2735 y(ex09a.fwi)243
+2785 y(sc13a.fwi)f(...)j(sc13f.fwi)243 2835 y(sc15a.fwi)1032
+2940 y Fr(104)p eop
+%%Page: 105 106
+105 105 bop 243 42 a Fl(tg08a.fwi)177 180 y Fd(4.2.8)55 b(Userman)18
+b(Directory)177 279 y Fr(The)c Fl(userman)f Fr(directory)i(con)o(tains)e(the)
+i Fl(.tex)e Fr(\014les)h(that)g(mak)o(e)e(up)i(the)h Fm(F)m(unnelWeb)h
+(User's)e(Manual)p Fr(.)177 388 y Fl(u_ch0.tex)107 b(-)22 b(Preface,)e(etc.)
+177 438 y(u_ch1.tex)107 b(-)22 b(Tutorial.)177 488 y(u_ch2.tex)107
+b(-)22 b(Hints.)177 538 y(u_ch3.tex)107 b(-)22 b(Definition.)177
+588 y(u_ch4.tex)107 b(-)22 b(Installation.)177 637 y(u_ch5.tex)107
+b(-)22 b(Administration.)177 687 y(u_cha.tex)107 b(-)22 b(Appendices.)177
+737 y(u_manual.tex)41 b(-)22 b(Main)f(TeX)g(file.)177 846 y
+Fr(See)15 b(the)f(commen)o(t)e(at)h(the)i(top)e(of)h Fl(u)p
+769 846 14 2 v 15 w(manual.tex)e Fr(\014le)h(for)h(instructions)g(on)g(ho)o
+(w)f(to)h(t)o(yp)q(eset)h(and)f(prin)o(t)f(the)177 896 y Fm(F)m(unnelWeb)j
+(User's)e(Manual)p Fr(.)177 1055 y Fi(4.3)70 b(Compiling)20
+b(F)-6 b(unnelW)g(eb)177 1169 y Fr(The)17 b(F)m(unnelW)m(eb)g(source)h(co)q
+(de)f(is)g(en)o(tirely)g(con)o(tained)g(within)f(the)h Fl(sources)e
+Fr(directory)m(.)27 b(Ho)o(w)o(ev)o(er,)18 b(some)177 1219
+y(simple)13 b(script)h(\014les)g(and)g(mak)o(e\014les)f(can)h(b)q(e)h(found)e
+(in)g(the)i Fl(admin)e Fr(directory)m(.)177 1292 y(F)m(unnelW)m(eb)j(con)o
+(tains)h(some)f(mac)o(hine-dep)q(enden)o(t)h(comp)q(onen)o(ts,)f(so)h(b)q
+(efore)g(compiling)d(F)m(unnelW)m(eb,)i(y)o(ou)177 1341 y(need)e(to)e(sp)q
+(ecify)h(y)o(our)g(mac)o(hine)e(in)h(the)i(source)g(\014le)e
+Fl(environ.h)p Fr(.)k(T)m(o)c(do)g(this,)h(edit)f(the)i Fl(environ.h)c
+Fr(\014le)j(and)177 1391 y(set)i(exactly)f(one)g(of)f(the)i(mac)o(hine)d
+(name)h Fl(#define)p Fr(s)g(to)h Fl(1)p Fr(.)j(F)m(or)d(example,)e(on)i(the)g
+(Sun)g(y)o(ou)g(should)f(set:)177 1500 y Fl(#define)21 b(MAC)g(0)177
+1550 y(#define)g(SUN)g(1)177 1600 y(#define)g(VMS)g(0)177 1650
+y(#define)g(PC)43 b(0)177 1759 y Fr(There)17 b(should)e(b)q(e)h(little)f
+(di\016cult)o(y)f(compiling)f(F)m(unnelW)m(eb)i(for)g(an)o(y)g(of)g(these)i
+(platforms.)k(If)15 b(the)h(mac)o(hine)177 1809 y(on)g(whic)o(h)g(y)o(ou)g
+(are)g(compiling)d(F)m(unnelW)m(eb)j(is)g(not)g(one)g(of)g(the)h(ones)f
+(listed)g(in)g(the)h Fl(environ.h)d Fr(\014le,)i(then)177 1859
+y(c)o(ho)q(ose)g(the)h(closest)f(one)g(y)o(ou)f(can.)23 b(T)m(ry)15
+b(the)h Fl(SUN)f Fr(if)g(y)o(ou)g(are)h(running)f(a)g(non-Sun)h(Unix.)22
+b(If)16 b(y)o(ou)f(run)g(in)o(to)177 1908 y(serious)g(di\016culties,)f(y)o
+(ou)f(will)g(ha)o(v)o(e)h(to)g(customize)g Fl(machin.h)e Fr(and)i
+Fl(machin.c)f Fr(for)h(y)o(our)g(mac)o(hine.)j(See)e(the)177
+1958 y(commen)o(ts)d(in)i(these)h(\014les)f(for)g(instructions)g(on)g(ho)o(w)
+g(to)f(do)h(this.)177 2031 y(Once)h(y)o(ou)f(ha)o(v)o(e)f(sp)q(eci\014ed)j(a)
+e(target)g(mac)o(hine,)e(compile)g(F)m(unnelW)m(eb)i(b)o(y)f(p)q(oin)o(ting)g
+(y)o(our)h(C)g(compiler)e(at)i(all)177 2081 y(the)j(\\)p Fl(.c)p
+Fr(")f(\014les)h(in)f(the)h Fl(sources)e Fr(directory)m(.)27
+b(The)17 b(\\)p Fl(.txt)p Fr(",)e(and)h(\\)p Fl(.tex)p Fr(")g(\014les)h(do)f
+(not)g(participate)h(in)f(the)177 2131 y(compilation,)11 b(but)j(app)q(ear)h
+(in)e(the)i Fl(sources)e Fr(directory)i(b)q(ecause)g(they)g(w)o(ere)g(used)g
+(to)f(generate)h(the)g(\\)p Fl(.ctx)p Fr(")177 2180 y(\014les.)21
+b(The)15 b(\\)p Fl(.ctx)p Fr(")e(\014les)i(are)g(included)g(b)o(y)g
+Fl(.c)f Fr(\014les)h(of)f(the)h(same)f(name)f(and)i(do)f(not)h(need)h(to)e(b)
+q(e)h(compiled)177 2230 y(separately)m(.)j(Link)c(the)g(results.)177
+2303 y(The)g(result)g(of)f(all)f(this)h(should)g(b)q(e)h(a)f(binary)g
+(executable)h(called)f Fl(fw)p Fr(,)g(or)g Fl(fw.exe)p Fr(,)f(or)h
+Fl(fw.xxx)f Fr(where)i Fl(.xxx)f Fr(is)177 2353 y(whatev)o(er)j(\014le)e
+(extension)h(is)g(appropriate)g(on)f(the)h(target)g(mac)o(hine.)k(Clean)c(up)
+f(the)h Fl(sources)f Fr(directory)h(b)o(y)177 2403 y(deleting)f(all)f(the)h
+(listing)f(and)h(ob)r(ject)g(\014les.)177 2562 y Fi(4.4)70
+b(T)-6 b(esting)22 b(F)-6 b(unnelW)g(eb)177 2676 y Fr(Once)13
+b(y)o(ou)d(ha)o(v)o(e)h(obtained)g(a)g(binary)g(executable,)h(y)o(ou)f
+(should)g(test)h(F)m(unnelW)m(eb)f(b)q(efore)h(making)c(it)j(a)o(v)n(ailable)
+177 2725 y(to)j(users.)19 b(T)m(o)14 b(do)f(this:)228 2835
+y(1.)20 b(Set)14 b(the)h(default)e(directory)i(to)f(b)q(e)g(the)h
+Fl(scripts)d Fr(directory)m(.)1032 2940 y(105)p eop
+%%Page: 106 107
+106 106 bop 228 42 a Fr(2.)20 b(Cop)o(y)14 b(the)i(F)m(unnelW)m(eb)e
+(executable)i(in)o(to)e(the)i(scripts)g(directory)g(\(or)f(b)q(e)g(able)g(to)
+g(in)o(v)o(ok)o(e)f(it)g(from)f(the)281 91 y(scripts)i(directory\).)228
+174 y(3.)20 b(Edit)d(the)h(script)g Fl(master.fws)p Fr(.)27
+b(Lo)q(cate)18 b(the)g(section)g(called)f(\\De\014ne)h(Sym)o(b)q(ol)d(F)m(or)
+i(the)h(Ro)q(ot)e(T)m(est)281 224 y(Directory")g(and)g(de\014ne)i(the)e
+Fl(R)g Fr(sym)o(b)q(ol)f(to)h(p)q(oin)o(t)g(to)g(the)g(F)m(unnelW)m(eb)g(ro)q
+(ot)g(directory)h Fl(fwdir)p Fr(.)24 b(The)281 274 y(examples)13
+b(in)g(the)i(commen)o(ts)d(in)h(the)i(script)f(should)g(mak)o(e)f(it)g(clear)
+h(what)g(is)g(required.)228 356 y(4.)20 b(In)o(v)o(ok)o(e)13
+b(F)m(unnelW)m(eb)h(to)f(execute)j(the)f(master)e(test)i(script)g(with)e(the)
+i(command)c(line)i Fl(fw)22 b(+xmaster)177 472 y Fr(The)16
+b Fl(master.fws)e Fr(script)j(should)e(run)h(for)g(a)f(few)h(min)o(utes.)23
+b(If)15 b(all)g(go)q(es)h(w)o(ell,)f(y)o(ou)h(will)e(\014nd)i(a)g
+(di\013erences)177 521 y(rep)q(ort)g(on)f(y)o(our)g(screen)i(rep)q(orting)f
+(zero)g(di\013erences.)24 b(If)14 b(this)h(happ)q(ens,)h(then)g(F)m(unnelW)m
+(eb)f(has)g(b)q(een)h(fully)177 571 y(tested)h(and)e(is)h(ready)g(to)f(b)q(e)
+h(made)e(a)o(v)n(ailable)f(to)j(users.)24 b(Y)m(ou)15 b(should)g(delete)h
+(all)e(the)i(\014les)g(in)f(the)h Fl(results)177 621 y Fr(directory)f(and)f
+(pro)q(ceed)h(to)f(the)g(next)h(section)f(on)g(installing)e(F)m(unnelW)m(eb)h
+(for)h(users.)177 695 y(If)e(there)i(w)o(ere)f(one)g(or)g(more)e
+(di\013erences,)k(y)o(ou)d(can)g(either)i(giv)o(e)e(up)g(and)g(con)o(tact)h
+(the)g(author,)g(or)f(attempt)g(to)177 745 y(\014x)j(the)g(co)q(de)h(y)o
+(ourself.)21 b(If)14 b(y)o(ou)g(decide)i(to)f(\014x)f(the)i(co)q(de)g(y)o
+(ourself,)e(start)h(with)g(the)g(di\013erences)i(log)d(\014le)h(and)177
+795 y(follo)o(w)d(y)o(our)i(nose.)k(Go)q(o)q(d)c(luc)o(k!)177
+957 y Fi(4.5)70 b(Installing)21 b(F)-6 b(unnelW)g(eb)177 1072
+y Fr(A)o(t)15 b(this)g(stage)g(y)o(ou)f(should)h(ha)o(v)o(e)g(a)f
+Fl(fwdir)g Fr(directory)h(tree)h(somewhere)f(in)g(y)o(our)f(\014le)h(system.)
+20 b(Its)c(con)o(ten)o(ts)177 1122 y(should)g(b)q(e)g(almost)d(iden)o(tical)i
+(to)h(the)g(directory)g(con)o(ten)o(ts)h(sp)q(eci\014ed)g(earlier)f(in)f
+(this)h(c)o(hapter)g(except)h(there)177 1172 y(should)d(no)o(w)f(b)q(e)i(an)e
+(additional)g(binary)g(executable)i(\014le)f(sitting)f(in)h(the)g
+Fl(scripts)f Fr(directory)m(.)177 1246 y(T)m(o)g(mak)o(e)g(F)m(unnelW)m(eb)g
+(a)o(v)n(ailable)f(to)h(users,)i(y)o(ou)f(should:)228 1361
+y(1.)20 b(Mak)o(e)14 b(the)g(en)o(tire)h(directory)g(tree)g(readable)f(to)g
+(all)e(users.)228 1444 y(2.)20 b(Mo)o(v)o(e)15 b(the)h(binary)f(executable)i
+(from)d(the)i(scripts)g(directory)g(to)g(the)g Fl(admin)e Fr(directory)i
+Fm(or)f Fr(cop)o(y)h(it)f(to)281 1494 y(somewhere)f(con)o(v)o(enien)o(t)g
+(suc)o(h)h(as)f(a)g Fl(/bin)f Fr(directory)m(.)228 1577 y(3.)20
+b(Set)d(up)f(a)g(sym)o(b)q(ol,)f(path,)i(or)f(command)e(of)h(some)h(kind)g(b)
+o(y)g(the)h(name)e(of)h Fl(fw)g Fr(that)g(\\p)q(oin)o(ts")g(to)g(the)281
+1626 y(binary)h(executable.)30 b(If)18 b(p)q(ossible,)g(set)g(this)g(up)g(so)
+f(that)h(the)g Fl(fw)f Fr(sym)o(b)q(ol)f(is)i(a)o(v)n(ailable)d(to)i(all)g
+(users.)281 1676 y(Alternativ)o(ely)m(,)j(y)o(ou)f(can)h(inform)d(in)o
+(terested)22 b(users)f(of)e(ho)o(w)g(they)h(can)g(add)g(a)f(command)e(to)i
+(their)281 1726 y Fl(login)13 b Fr(command)e(\014le)j(to)f(mak)o(e)g(the)h
+(command)d(a)o(v)n(ailable)h(to)i(them.)177 1841 y(If)i(y)o(ou)g(are)h(short)
+f(of)g(disk)g(space)h(or)g(ha)o(v)o(e)f(a)g(system)g(that)g(is)g(stressed)j
+(in)d(some)f(other)i(w)o(a)o(y)m(,)e(it)h(ma)o(y)e(b)q(e)j(of)177
+1891 y(assistance)g(to)f(y)o(ou)f(to)g(kno)o(w)g(that)h(F)m(unnelW)m(eb)f
+(has)h(b)q(een)h(constructed)h(so)d(that)h(its)g(binary)f(executable)i(is)177
+1941 y Fm(total)r(ly)d(self)g(c)n(ontaine)n(d)p Fr(.)19 b(The)14
+b(binary)e(executable)j(do)q(es)f(not)g(rely)f(on)g(an)o(y)g(other)i(\014les)
+e(to)h(op)q(erate.)k(Nor)c(do)q(es)177 1991 y(it)f(care)h(ab)q(out)f(its)g(p)
+q(osition)g(in)g(the)g(\014le)h(system.)j(In)c(fact,)g(all)f(that)h(is)g
+(really)g(required)h(to)f(use)h(F)m(unnelW)m(eb)f(is)177 2040
+y(the)g(binary)e(executable)i(and)f(the)h Fm(F)m(unnelWeb)h(User's)e(Manual)p
+Fr(.)19 b(Th)o(us,)12 b(if)f(y)o(ou)g(are)i(short)f(of)g(disk)f(space,)i(y)o
+(ou)177 2090 y(can)j(mo)o(v)o(e)f(the)i(binary)e(executable)j(to)d(y)o(our)h
+(\\)p Fl(/bin)p Fr(")f(directory)i(and)f(delete)h(the)g(en)o(tire)f(F)m
+(unnelW)m(eb)g(tree.)177 2140 y(Ho)o(w)o(ev)o(er,)e(making)d(the)k(tree)g(a)o
+(v)n(ailable)d(to)h(users)j(is)e(encouraged)g(b)q(ecause:)239
+2255 y Fq(\017)21 b Fr(It)14 b(allo)o(ws)f(users)i(to)f(cop)o(y)f(the)i(tree)
+g(and)f(install)f(it)g(on)h(another)g(mac)o(hine)f(without)g(b)q(othering)h
+(y)o(ou.)239 2338 y Fq(\017)21 b Fr(It)12 b(allo)o(ws)g(users)h(access)i(to)d
+(the)h(T)813 2347 y(E)836 2338 y(X)g(co)q(de)g(for)f(the)h
+Fm(F)m(unnelWeb)h(User's)f(Manual)g Fr(and)g(the)g Fm(F)m(unnelWeb)281
+2388 y(Hacker's)h(Manual)p Fr(.)239 2470 y Fq(\017)21 b Fr(It)13
+b(allo)o(ws)e(users)j(access)g(to)e(the)h(regression)h(test)g(suite.)k(This)
+12 b(ma)o(y)f(not)h(seem)h(imp)q(ortan)o(t,)d(but)j(it)f(could)281
+2520 y(b)q(e)k(v)o(ery)f(con)o(v)o(enien)o(t)h(for)f(the)h(user)g(as)f(the)h
+Fl(ex*)f Fr(and)g Fl(hi*)g Fr(\014les)g(of)g(the)h(regression)g(test)g(suite)
+g(con)o(tain)281 2570 y(most)f(of)h(the)g(examples)g(from)e(the)j
+Fm(F)m(unnelWeb)h(User's)e(Manual)p Fr(.)26 b(By)16 b(making)e(them)h(a)o(v)n
+(ailable)f(y)o(ou)281 2620 y(will)e(sa)o(v)o(e)i(users)i(the)e(trouble)g(of)g
+(t)o(yping)f(them)g(in.)177 2735 y(Finally)m(,)i(y)o(ou)h(should)h(\014ll)f
+(in)g(and)h(send)g(o\013)g(a)g(F)m(unnelW)m(eb)f(registration)h(form.)24
+b(This)17 b(allo)o(ws)f(me)f(to)i(get)g(a)177 2785 y(handle)g(on)g(the)g
+(size)h(and)f(needs)h(of)f(the)g(user)h(base,)g(and)f(y)o(ou)f(to)h(b)q(e)h
+(k)o(ept)f(informed)f(of)g(new)h(F)m(unnelW)m(eb)177 2835 y(releases)f
+(\(optional\).)h(See)d(Section)h(5.4)d(for)i(more)f(information.)1032
+2940 y(106)p eop
+%%Page: 107 108
+107 107 bop 177 42 a Fi(4.6)70 b(Prin)n(ting)22 b(Man)n(uals)177
+157 y Fr(F)m(unnelW)m(eb)d(comes)g(with)g(t)o(w)o(o)g(man)o(uals,)f(a)h
+Fm(F)m(unnelWeb)i(User's)e(Manual)h Fr(and)f(a)g Fm(F)m(unnelWeb)i(Hacker's)
+177 207 y(Manual)p Fr(.)k(Instructions)17 b(for)f(ho)o(w)f(to)h(t)o(yp)q
+(eset)h(and)f(prin)o(t)g(these)h(man)o(uals)d(app)q(ear)i(at)g(the)g(top)g
+(of)f(the)i(main)177 257 y(T)200 266 y(E)223 257 y(X)d(\014les)h(for)e(these)
+i(man)o(uals)d Fl(u)p 709 257 14 2 v 16 w(manual.tex)f Fr(and)j
+Fl(h)p 1059 257 V 16 w(manual.tex)p Fr(.)177 332 y(There)e(is)f(no)g(need)h
+(to)f(prin)o(t)g(the)h Fm(F)m(unnelWeb)h(Hacker's)f(Manual)g
+Fr(unless)f(y)o(ou)g(in)o(tend)g(to)g(mo)q(dify)e(F)m(unnelW)m(eb.)177
+381 y(Ho)o(w)o(ev)o(er,)k(y)o(ou)g(should)g(mak)o(e)f(a)h(few)g(copies)h(of)f
+(the)h Fm(F)m(unnelWeb)h(User's)e(Manual)h Fr(a)o(v)n(ailable)d(for)i(users,)
+i(or)e(at)177 431 y(least)i(let)f(them)f(kno)o(w)h(where)h(the)g(T)765
+440 y(E)788 431 y(X)f(source)i(for)e(the)h Fm(F)m(unnelWeb)h(User's)e(Manual)
+h Fr(is)f(k)o(ept)h(so)f(that)g(they)177 481 y(can)g(t)o(yp)q(eset)i(and)d
+(prin)o(t)h(it)g(themselv)o(es.)177 643 y Fi(4.7)70 b(Installation)21
+b(Problems?)177 759 y Fr(If)e(y)o(ou)g(run)g(in)o(to)g(an)o(y)g(problems)f
+(installing)f(F)m(unnelW)m(eb,)j(please)g(write)f(a)g(short)h(rep)q(ort)g
+(describing)g(the)177 809 y(problem)14 b(and)i(mail)d(it)i(to)g(the)h(author)
+g(Ross)f(Williams)e(\()p Fl(ross@spam.adelai)o(de.ed)o(u.au)o
+Fr(\).)21 b(I)15 b(ma)o(y)f(not)h(b)q(e)177 859 y(able)g(to)g(help)g(y)o(ou)f
+(with)h(it)f(immediately)l(,)e(but)j(I)g(certainly)g(w)o(an)o(t)g(to)f(kno)o
+(w)h(that)g(a)f(problem)g(exists)i(so)f(that)177 909 y(it)f(can)g(b)q(e)g
+(corrected)i(in)e(future)g(releases)i(of)d(F)m(unnelW)m(eb.)1032
+2940 y(107)p eop
+%%Page: 108 109
+108 108 bop 1032 2940 a Fr(108)p eop
+%%Page: 109 110
+109 109 bop 177 379 a Fj(Chapter)34 b(5)177 613 y Fp(F)-10
+b(unnelW)g(eb)41 b(Administration)177 881 y Fi(5.1)70 b(In)n(tro)r(duction)
+177 999 y Fr(Whether)21 b(a)e(computer)g(program)f(is)h(useful)h(dep)q(ends)h
+(not)f(just)f(on)g(the)i(functionalit)o(y)d(pro)o(vided)h(b)o(y)g(the)177
+1049 y(program,)13 b(but)i(also)g(on)g(the)g(totalit)o(y)f(of)g(the)i
+(culture)g(and)e(services)j(surrounding)e(it)g(suc)o(h)g(as)g(license)h
+(costs,)177 1098 y(the)j(qualit)o(y)e(of)h(do)q(cumen)o(tation,)f(presence)k
+(of)d(a)g(standard)h(and)f(so)g(on.)31 b(This)19 b(c)o(hapter)g(addresses)h
+(these)177 1148 y(issues)15 b(from)d(a)i(user)h(p)q(ersp)q(ectiv)o(e.)177
+1315 y Fi(5.2)70 b(The)22 b(User's)h(Commitme)o(n)n(t)d(T)-6
+b(o)24 b(F)-6 b(unnelW)g(eb)177 1434 y Fr(One)20 b(of)f(the)i(problems)d
+(that)i(migh)o(t)d(prev)o(en)o(t)k(p)q(oten)o(tial)e(users)i(from)c(using)j
+(F)m(unnelW)m(eb)f(is)g(the)h(lev)o(el)f(of)177 1483 y(commitm)o(en)o(t)14
+b(that)j(it)f(requires.)27 b(As)17 b(so)q(on)g(as)g(the)g(user)h(starts)f
+(creating)g(F)m(unnelW)m(eb)f Fl(.fw)g Fr(\014les,)h(the)h(user)177
+1533 y(b)q(ecomes)c(dep)q(enden)o(t)h(on)e(the)h(F)m(unnelW)m(eb)f(program,)f
+(as)h(the)h(\014les)g(so)f(created)i(will)d(b)q(ecome)i(unmanageable)177
+1583 y(if)i(the)h(F)m(unnelW)m(eb)f(program)f(w)o(ere)i(to)g(b)q(ecome)f(una)
+o(v)n(ailable)e(for)j(some)e(reason.)27 b(There)17 b(are)g(a)g(n)o(um)o(b)q
+(er)e(of)177 1633 y(w)o(a)o(ys)f(in)g(whic)o(h)h(computer)f(programs)f(can)i
+(b)q(ecome)f(una)o(v)n(ailable,)e(including)i(op)q(erating)g(system)h
+(upgrades,)177 1683 y(cop)o(yrigh)o(t)d(problems,)f(inabilit)o(y)f(to)h
+(\014x)h(bugs,)g(or)g(just)h(the)f(inabilit)o(y)e(of)h(the)i(program)d(to)i
+(b)q(e)h(p)q(orted)g(to)f(a)f(new)177 1732 y(target)k(platform.)177
+1809 y(The)j(fact)f(is)g(that)h(F)m(unnelW)m(eb)e(de\014nes)j(an)e(input)g
+(language)g(and)g(that)g(curren)o(tly)h(there)h(is)e(only)f(one)i(im-)177
+1859 y(plemen)o(tation)f(of)h(the)i(language.)32 b(Users)20
+b(will)d(only)h(write)i(programs)d(using)i(that)g(language)e(if)h(they)i
+(feel)177 1908 y(comfortable)12 b(ab)q(out)i(the)h(a)o(v)n(ailabili)o(t)o(y)c
+(of)i(its)h(implemen)o(tatio)o(n.)177 1985 y(I)i(ha)o(v)o(e)g(b)q(een)i
+(critically)d(a)o(w)o(are)h(of)g(these)i(issues)f(throughout)f(the)h(dev)o
+(elopmen)o(t)e(of)h(F)m(unnelW)m(eb)g(and)g(ha)o(v)o(e)177
+2034 y(tak)o(en)i(ev)o(ery)g(p)q(ossible)g(step)h(to)f(mak)o(e)e(F)m(unnelW)m
+(eb)h(a)h(solid)e(base)j(on)o(to)e(whic)o(h)h(to)f(build)g(programs.)28
+b(The)177 2084 y(follo)o(wing)11 b(p)q(oin)o(ts)j(describ)q(e)i(the)e
+(actions)g(I)g(ha)o(v)o(e)g(tak)o(en.)295 2161 y Fo(GNU)19
+b(license:)i Fr(F)m(unnelW)m(eb's)16 b(C)g(source)i(co)q(de)f(has)g(b)q(een)g
+(released)h(under)f(GNU)g(General)295 2210 y(Public)c(License)h(V)m(ersion)f
+(2.)18 b(This)13 b(means)f(that)h(the)h(source)g(co)q(de)g(to)f(F)m(unnelW)m
+(eb)f(will)g(alw)o(a)o(ys)295 2260 y(b)q(e)18 b(a)o(v)n(ailable)c(to)j(an)o
+(y)o(one)f(who)h(w)o(an)o(ts)g(it.)26 b(The)17 b(F)m(unnelW)m(eb)f(program)f
+(can)i(nev)o(er)h(b)q(e)g(tak)o(en)295 2310 y(a)o(w)o(a)o(y)13
+b(from)f(y)o(ou.)295 2386 y Fo(P)o(ortabili)o(t)n(y:)22 b Fr(F)m(unnelW)m(eb)
+17 b(has)g(b)q(een)h(designed)f(and)g(written)g(to)g(b)q(e)g(extremely)g(p)q
+(ortable.)295 2436 y(First,)g(all)e(F)m(unnelW)m(eb)h(really)g(do)q(es)h(is)f
+(read)h(and)g(write)f(text)h(\014les.)26 b(This)17 b(mak)o(es)e(it)h(easy)h
+(to)295 2486 y(mak)o(e)9 b(p)q(ortable.)17 b(Second,)11 b(F)m(unnelW)m(eb)f
+(is)g(written)g(in)g(the)h(C)f(programmi)o(ng)d(language)p
+Fo([ANSI])295 2536 y Fr(with)15 b(p)q(ortabilit)o(y)e(as)i(a)f(ma)r(jor)g
+(design)g(goal.)20 b(Third,)14 b(F)m(unnelW)m(eb)h(has)f(already)h(b)q(een)h
+(p)q(orted)295 2586 y(to)d(four)h(p)q(opular)e(platforms:)k(SunOS,)e(V)-5
+b(AX)14 b(VMS,)f(PC,)g(and)g(Macin)o(tosh)g(and)h(it)f(should)g(not)295
+2635 y(pro)o(v)o(e)j(hard)g(to)f(mo)o(v)o(e)f(it)h(to)h(others.)24
+b(F)m(ourth,)15 b(F)m(unnelW)m(eb)g(comes)h(with)f(a)g(h)o(uge)h(automated)
+295 2685 y(regression)g(test)f(suite.)20 b(This)14 b(mak)o(es)f(it)h(easy)h
+(to)f(pinp)q(oin)o(t)f(problems)g(when)i(it)f(is)g(mo)o(v)o(ed)f(to)h(a)295
+2735 y(new)f(platform.)j(P)o(ortabilit)o(y)11 b(is)h(imp)q(ortan)o(t)f(b)q
+(ecause,)k(ev)o(en)e(if)f Fm(you)h Fr(are)g(not)g(using)f(F)m(unnelW)m(eb)295
+2785 y(on)17 b(some)e(funn)o(y)h(platform,)f(y)o(ou)h(ma)o(y)e(w)o(an)o(t)j
+(to)f(send)h(a)g(computer)f(program)f(written)i(using)295 2835
+y(F)m(unnelW)m(eb)d(to)f(someone)h(who)f(do)q(es.)1032 2940
+y(109)p eop
+%%Page: 110 111
+110 110 bop 295 42 a Fo(Qualit)o(y:)27 b Fr(The)20 b(F)m(unnelW)m(eb)e
+(source)j(co)q(de)f(is)f(high)f(qualit)o(y)g(co)q(de.)35 b(Although)19
+b(it)f(has)i(not)295 91 y(b)q(een)13 b(formally)c(dev)o(elop)q(ed)j(under)g
+(an)o(y)f(particular)h(co)q(ding)f(standard,)h(it)f(is)h(w)o(ell)f(designed)h
+(and)295 141 y(do)q(cumen)o(ted.)18 b(Design)c(decisions)g(ha)o(v)o(e)g(not)g
+(b)q(een)h(tak)o(en)f(ligh)o(tly)m(.)295 216 y Fo(Do)q(cumen)o(tation:)20
+b Fr(F)m(unnelW)m(eb)c(is)g(w)o(ell)f(do)q(cumen)o(ted)h(b)o(y)g(this)h(man)o
+(ual)d(and)i(b)o(y)g(the)g Fm(F)m(un-)295 266 y(nelWeb)j(Hacker's)f(Manual)p
+Fr(.)29 b(This)17 b(is)g(imp)q(ortan)o(t)f(b)q(ecause)j(it)e(means)f(that)i
+(if)e(y)o(ou)h(w)o(an)o(t)g(to)295 316 y(send)c(someone)e(a)g(program)f
+(written)i(using)g(F)m(unnelW)m(eb,)f(y)o(ou)g(can)h(simply)d(p)q(oin)o(t)i
+(them)g(to)h(this)295 366 y(man)o(ual)c(rather)k(than)f(ha)o(ving)e(to)h
+(explain)g(it)h(all)e(y)o(ourself.)17 b(It)10 b(is)h(also)f(comforting)e(for)
+j(managers)295 415 y(who)j(are)h(con)o(trolling)e(source)i(co)q(de)g(to)f
+(kno)o(w)g(that)g(the)h(format)d(in)i(whic)o(h)g(the)g(source)i(co)q(de)f(is)
+295 465 y(written)g(is)e(w)o(ell-do)q(cumen)o(ted.)295 540
+y Fo(Standardizatio)o(n:)i Fr(Users)g(who)e(create)h(source)h(\014les)e
+(using)g(F)m(unnelW)m(eb)g(are)h(not)f(only)f(com-)295 590
+y(mitting)j(to)j(the)g(F)m(unnelW)m(eb)e(program;)h(they)h(are)g(also)f(in)o
+(v)o(esting)g(in)g(the)h(F)m(unnelW)m(eb)f(lan-)295 640 y(guage.)22
+b(If)14 b(F)m(unnelW)m(eb's)h(language)f(c)o(hanges)i(radically)d(for)i(some)
+f(reason,)i(then)g(this)f(in)o(v)o(est-)295 690 y(men)o(t)f(b)o(y)h(users)h
+(will)d(b)q(e)j(undermined.)k(T)m(o)14 b(protect)i(this)f(in)o(v)o(estmen)o
+(t,)f(I)h(in)o(tend)g(to)f(main)o(tain)295 740 y(an)g(\\o\016cial")e(v)o
+(ersion)j(of)e(F)m(unnelW)m(eb)h(whose)g(language)f(will)g(not)h(c)o(hange)h
+(radically)m(,)d(at)h(least)295 789 y(not)h(in)g(a)f(non)h(bac)o(kw)o(ard)g
+(compatible)e(manner.)177 864 y(It)17 b(is)f(m)o(y)f(hop)q(e)h(that)h(the)g
+(com)o(bination)d(of)i(these)h(factors)g(will)e(alleviate)g(an)o(y)h(fears)h
+(that)g(users)h(ma)o(y)c(ha)o(v)o(e)177 914 y(ab)q(out)g(committing)c(their)
+15 b(source)g(\014les)f(to)g(F)m(unnelW)m(eb.)177 1077 y Fi(5.3)70
+b(Do)r(cumen)n(tation)177 1194 y Fr(The)14 b(follo)o(wing)e(F)m(unnelW)m(eb)h
+(do)q(cumen)o(tation)g(is)h(a)o(v)n(ailable:)264 1311 y Fl("FunnelWeb)20
+b(User's)64 b(Manual":)20 b(Tutorial,)g(Hints,)h(Reference)f(Manual.)264
+1360 y("FunnelWeb)g(Hacker's)g(Manual":)g(Notes)h(on)g(Design)g(and)g
+(Implementation.)177 1477 y Fr(Ev)o(ery)o(one)14 b(in)o(v)o(olv)o(ed)e(with)h
+(F)m(unnelW)m(eb)f(should)h(read)h(the)g Fm(F)m(unnelWeb)h(User's)e(Manual)p
+Fr(.)19 b(It)13 b(con)o(tains)g(ev)o(ery-)177 1527 y(thing)h(y)o(ou)f(need)i
+(to)f(kno)o(w)f(ab)q(out)h(ho)o(w)f(to)h(use)h(F)m(unnelW)m(eb.)i(In)d(fact,)
+f(y)o(ou)h(are)g(reading)g(it)f(no)o(w!)177 1602 y(The)18 b
+Fm(F)m(unnelWeb)h(Hacker's)f(Manual)g Fr(is)f(for)g(those)h(who)f(w)o(an)o(t)
+g(to)g(install,)g(mo)q(dify)m(,)e(\014x,)i(\014ddle)h(with,)f(and)177
+1652 y(generally)d(hac)o(k)g(the)g(F)m(unnelW)m(eb)f(C)h(source)h(co)q(de.)
+177 1727 y(Both)h(of)e(these)j(man)o(uals)c(are)j(shipp)q(ed)g(with)e(the)i
+(F)m(unnelW)m(eb)f(distribution)g(kit,)f(and)h(should)g(b)q(e)h(a)o(v)n
+(ailable)177 1777 y(on)g(y)o(our)f(mac)o(hine)f(in)i(the)g(form)e(of)h(LaT)m
+(eX)g(text)i(\014les.)23 b(If)16 b(y)o(ou)f(cannot)h(\014nd)g(them,)f(y)o(ou)
+g(can)h(obtain)f(them)177 1827 y(from)d(the)j(F)m(unnelW)m(eb)e(FTP)h(arc)o
+(hiv)o(e)g(\(see)i(Section)e(5.11\).)177 1990 y Fi(5.4)70 b(Registration)177
+2106 y Fr(If)13 b(y)o(ou)g(install)g(or)g(use)i(F)m(unnelW)m(eb,)d(please)i
+(register)h(b)o(y)e(\014lling)f(in)h(and)h(returning)g(the)g(registration)f
+(form)f(in)177 2156 y Fo(Figure)i(4)p Fr(.)k(F)m(eel)c(free)h(to)e(expand)i
+(the)f(form)e(if)h(there)i(is)f(not)g(enough)g(ro)q(om.)177
+2231 y(Email)h(the)j(form)e(to)h Fl(ross@spam.adelaide)o(.edu.)o(au)p
+Fr(,)e(or)i(snail)g(mail)e(it)i(to)g(Ross)g(William)o(s,)f(16)g(Lerwic)o(k)
+177 2281 y(Av)o(en)o(ue,)c(Hazelw)o(o)q(o)q(d)f(P)o(ark)g(5066,)f(Australia.)
+17 b(Y)m(ou)11 b(ma)o(y)e(wish)i(to)g(mak)o(e)e(a)i(con)o(tribution)g(when)g
+(y)o(ou)g(register.)177 2331 y(See)k(Section)f(5.5)f(for)h(more)f
+(information.)177 2494 y Fi(5.5)70 b(Supp)r(ort)177 2610 y
+Fr(F)m(unnelW)m(eb)13 b(is)h(released)h(\\as)f(is")f(under)i(a)e(GNU)h
+(license,)g(and)g(no)f(formal)f(supp)q(ort)i(is)g(a)o(v)n(ailable.)i(Y)m(ou)d
+(ha)o(v)o(e)177 2660 y(the)20 b(righ)o(t)e(to)h(mak)o(e)e(c)o(hanges)j(to)f
+(F)m(unnelW)m(eb)f(and)h(to)g(use)h(the)f(mo)q(di\014ed)f(v)o(ersions)h
+(created)i(b)o(y)d(random)177 2710 y(programmers.)e(Ho)o(w)o(ev)o(er,)e(this)
+g(is)g(discouraged)g(\(see)h(Section)g(5.9\).)177 2785 y(In)h(fact)g(the)h
+(supp)q(ort)g(that)f(is)g(most)f(needed)i(is)f(y)o(our)g(\014nancial)f(supp)q
+(ort)i(for)f(the)g(F)m(unnelW)m(eb)g(dev)o(elop)q(ers!)177
+2835 y(It)h(has)g(tak)o(en)h Fm(months)f Fr(of)g(full-tim)o(e)e
+Fm(unp)n(aid)j Fr(w)o(ork)e(to)h(bring)g(F)m(unnelW)m(eb)g(to)f(y)o(ou)h(in)g
+(its)g(curren)o(t)h(form.)26 b(I)1032 2940 y(110)p eop
+%%Page: 111 112
+111 111 bop 264 602 a Fl(+------------------)o(----F)o(unnel)o(Web)19
+b(Registration)g(Form-------------)o(----)o(-----)o(+)264 652
+y(|)j(1.)f(Date:)1350 b(|)264 702 y(|)1547 b(|)264 751 y(|)22
+b(2.)f(Title)g(and)g(name:)1132 b(|)264 801 y(|)1547 b(|)264
+851 y(|)22 b(3.)f(Internet)f(email)h(address:)957 b(|)264 901
+y(|)1547 b(|)264 951 y(|)22 b(4.)f(Snail)g(mail)g(address:)1044
+b(|)264 1000 y(|)1547 b(|)264 1050 y(|)22 b(5.)f(Work)g(phone)g(number)g
+(\(country,area,n)o(umber)o(\):)585 b(|)264 1100 y(|)1547 b(|)264
+1150 y(|)22 b(6.)f(Which)g(category)f(of)i(FunnelWeb)e(user)g(best)h
+(describes)f(you?)326 b(|)264 1200 y(|)153 b(Latent)86 b(-)21
+b(Installed)f(FunnelWeb,)g(but)h(don't)g(intend)f(to)i(use)f(it.)86
+b(|)264 1250 y(|)153 b(Beginner)42 b(-)21 b(Haven't)g(used)g(FunnelWeb)e
+(much)i(yet;)g(have)g(an)h(open)f(mind.)f(|)264 1299 y(|)153
+b(Casual)86 b(-)21 b(Use)g(FunnelWeb)f(occasionally.)542 b(|)264
+1349 y(|)153 b(Convert)64 b(-)21 b(Use)g(FunnelWeb)f(to)i(do)f(most)g
+(programming.)324 b(|)264 1399 y(|)153 b(Fanatic)64 b(-)21
+b(FunnelWeb)f(has)h(become)g(a)g(way)h(of)f(life.)369 b(|)264
+1449 y(|)1547 b(|)264 1499 y(|)22 b(7.)f(What)g(changes)g(or)g(new)g
+(features)f(would)h(you)g(like)g(to)h(see)f(in)g(FunnelWeb?)63
+b(|)264 1548 y(|)1547 b(|)264 1598 y(|)g(|)264 1648 y(|)g(|)264
+1698 y(|)g(|)264 1748 y(|)g(|)264 1797 y(|)g(|)264 1847 y(|)22
+b(8.)f(Do)h(you)f(want)g(to)g(be)h(kept)f(informed)f(of)h(new)g(FunnelWeb)f
+(developments?)106 b(|)264 1897 y(|)1547 b(|)264 1947 y(+------------------)o
+(-----)o(-----)o(-----)o(----)o(-----)o(-----)o(-----)o(-----)o(-----)o(----)
+o(-----)o(+)343 2038 y Fh(T)m(o)433 b(register)e(as)h(a)281
+2088 y(F)m(unnelW)m(eb)13 b(user,)i(please)f(\014ll)g(in)h(this)f(form)g(and)
+g(email)f(it)i(to)g Fe(ross@spam.)o(ad)o(ela)o(ide)o(.ed)o(u.a)o(u)p
+Fh(,)e(or)h(snail)g(mail)281 2138 y(it)f(to)f(Ross)h(Williams,)e(16)i(Lerwic)
+o(k)f(Av)o(en)o(ue,)g(Hazelw)o(o)q(o)q(d)f(P)o(ark)h(5066,)g(Australia.)18
+b(Y)m(ou)13 b(ma)o(y)f(wish)g(to)h(mak)o(e)e(a)281 2188 y(con)o(tribution)d
+(when)j(y)o(ou)g(register.)i(See)e(Section)e(5.5)i(for)g(more)f(information.)
+650 2279 y Fo(Figure)k(4)p Fr(:)k(The)d(F)m(unnelW)m(eb)e(registration)h
+(form.)1032 2940 y(111)p eop
+%%Page: 112 113
+112 112 bop 177 42 a Fr(don't)15 b(w)o(an)o(t)f(to)h(incon)o(v)o(enience)g
+(users)i(who)d(install)g(F)m(unnelW)m(eb,)g(pla)o(y)g(with)g(it,)h(and)f
+(then)i(hardly)e(ev)o(er)i(use)177 91 y(it.)i(If)c(y)o(ou)g(are)g(in)g(this)g
+(category)m(,)f(please)i(register,)g(but)f(don't)g(b)q(other)h(con)o
+(tributing.)j(Ho)o(w)o(ev)o(er,)c(if)f(y)o(ou)h(\014nd)177
+141 y(that)h(F)m(unnelW)m(eb)f(has)h(b)q(ecome)g(a)f(useful)h(programming)c
+(to)q(ol,)j(a)g(con)o(tribution)h(of)f(some)g(p)q(ositiv)o(e)g(m)o(ultiple)
+177 191 y(of)f(US$50)h(w)o(ould)f(b)q(e)h(appreciated.)177
+266 y(T)m(o)f(mak)o(e)g(a)g(con)o(tribution,)g(send)i(pa)o(ymen)o(t)e(with)g
+(a)h(completed)f(registration)h(form)e(\(see)j(Section)g(5.4\))e(to:)243
+382 y Fl(Renaissance)19 b(Software)h(Pty)h(Ltd)243 432 y(Email:)f
+(ross@spam.adelaide)o(.edu.)o(au)243 482 y(Snail:)g(16)h(Lerwick)g(Avenue,)f
+(Hazelwood)g(Park)h(5066,)g(Australia.)177 598 y Fr(P)o(a)o(ymen)o(t)14
+b(can)h(b)q(e)g(b)o(y)g(p)q(ersonal)g(or)g(bank)g(c)o(heque)h(to)e(an)o(y)h
+(bank)g(in)f(the)h(w)o(orld)g(or)g(b)o(y)f(Visa)h(or)g(Mastercard.)177
+648 y(Please)j(giv)o(e)e(the)h(card)g(name,)f(n)o(um)o(b)q(er,)g(expiry)h
+(date,)g(and)g(the)g(amoun)o(t)e(to)h(b)q(e)i(paid)e(in)g(US)h(dollars.)26
+b(All)177 698 y(con)o(tributions)16 b(will)f(b)q(e)i(appreciated)g(and)f
+(will)f(encourage)i(further)g(F)m(unnelW)m(eb)f(dev)o(elopmen)o(t.)24
+b(Ho)o(w)o(ev)o(er,)177 748 y(no)14 b(undertaking)g(is)f(made)g(whatso)q(ev)o
+(er)i(ab)q(out)f(ho)o(w)f(the)i(money)d(will)h(b)q(e)h(used.)177
+910 y Fi(5.6)70 b(Cop)n(yrigh)n(t)177 1026 y Fr(The)14 b(F)m(unnelW)m(eb)g
+(program)e(is)i(Cop)o(yrigh)o(t)894 1025 y(c)883 1026 y Fq(\015)f
+Fr(1992)g(Ross)h(William)o(s.)177 1101 y(Ho)o(w)o(ev)o(er,)28
+b(F)m(unnelW)m(eb)d(has)g(b)q(een)i(released)f(b)o(y)f(the)h(author)g(and)f
+(cop)o(yrigh)o(t)f(o)o(wner)i(Ross)f(William)o(s)177 1151 y(\()p
+Fl(ross@spam.adelaide.)o(edu.a)o(u)p Fr(\))16 b(under)k(V)m(ersion)f(2)f(of)g
+(the)i(GNU)e(General)h(Public)g(License)h(published)177 1201
+y(b)o(y)14 b(the)g(F)m(ree)h(Soft)o(w)o(are)f(F)m(oundation.)i(Here)f(are)g
+(some)e(w)o(a)o(ys)g(that)h(y)o(ou)g(can)g(obtain)f(a)h(cop)o(y)f(of)h(this)g
+(license.)239 1317 y Fq(\017)21 b Fr(The)14 b(license)h(app)q(ears)g(as)f(an)
+f(app)q(endix)h(in)g(the)g Fm(F)m(unnelWeb)i(Hacker's)f(Manual)p
+Fr(.)239 1401 y Fq(\017)21 b Fr(If)13 b(y)o(ou)h(ha)o(v)o(e)g(a)f(w)o(orking)
+g(v)o(ersion)h(of)f(F)m(unnelW)m(eb,)g(in)o(v)o(ok)o(e)g(it)h(with)f
+Fl(fw)22 b(+hlicense)e(+jlicense.txt)p Fr(.)239 1484 y Fq(\017)h
+Fr(Lo)q(ok)13 b(in)h(the)g Fl(help)f Fr(mo)q(dule)g(of)g(the)h(F)m(unnelW)m
+(eb)g(source)h(co)q(de.)239 1567 y Fq(\017)21 b Fr(FTP)14 b(the)h(license)f
+(from)e Fl(prep.ai.mit.edu)f Fr(in)j Fl(/pub/gnu/COPYIN)o(G-2)p
+Fr(.)239 1650 y Fq(\017)21 b Fr(W)m(rite)13 b(to)h(the)h(F)m(ree)f(Soft)o(w)o
+(are)g(F)m(oundation,)e(Inc.,)h(675)h(Mass)g(Av)o(e,)g(Cam)o(bridge,)d(MA)j
+(02139,)e(USA.)177 1767 y(The)i(license)h(allo)o(ws)d(y)o(ou)i(to)f
+(redistribute)i(F)m(unnelW)m(eb)f(and/or)f(mo)q(dify)e(it)j(under)g(certain)h
+(conditions.)i(The)177 1817 y(license)e(do)q(es)g(not)f(co)o(v)o(er)h(the)g
+Fm(F)m(unnelWeb)h(User's)f(Manual)g Fr(and)f Fm(F)m(unnelWeb)i(Hacker's)f
+(Manual)g Fr(whic)o(h)f(are)177 1867 y(distributed)h(under)f(a)g(simpler)f
+(license)h(that)g(prohibits)g(c)o(hanges.)177 1941 y(Note:)23
+b(F)m(unnelW)m(eb)15 b(is)h(distributed)g(WITHOUT)g(ANY)g(W)-5
+b(ARRANTY;)15 b(without)h(ev)o(en)g(the)h(implied)c(w)o(ar-)177
+1991 y(ran)o(t)o(y)h(of)f(MER)o(CHANT)m(ABILITY)h(or)g(FITNESS)g(F)o(OR)g(A)g
+(P)m(AR)m(TICULAR)f(PURPOSE.)177 2154 y Fi(5.7)70 b(No)n(w)n(arran)n(t)n(y)
+177 2270 y Fr(Users)15 b(of)e(F)m(unnelW)m(eb)g(should)g(b)q(e)h(a)o(w)o(are)
+f(that)h(F)m(unnelW)m(eb)e(comes)h(with)g(no)h(w)o(arran)o(t)o(y)m(.)j(Here)d
+(is)g(an)f(extract)177 2320 y(from)e(the)i(GNU)f(General)g(Public)g(License)i
+(V)m(ersion)e(2,)g(under)h(whic)o(h)g(F)m(unnelW)m(eb)e(is)i(distributed.)18
+b(F)m(or)12 b(more)177 2369 y(information)f(see)k(Section)g(5.6.)308
+2486 y Fl(11.)21 b(BECAUSE)f(THE)i(PROGRAM)e(IS)h(LICENSED)f(FREE)h(OF)h
+(CHARGE,)e(THERE)h(IS)g(NO)h(WARRANTY)264 2536 y(FOR)g(THE)f(PROGRAM,)f(TO)h
+(THE)g(EXTENT)g(PERMITTED)f(BY)h(APPLICABLE)f(LAW.)43 b(EXCEPT)20
+b(WHEN)264 2586 y(OTHERWISE)g(STATED)h(IN)g(WRITING)g(THE)g(COPYRIGHT)f
+(HOLDERS)g(AND/OR)h(OTHER)f(PARTIES)264 2635 y(PROVIDE)h(THE)g(PROGRAM)f("AS)
+h(IS")h(WITHOUT)e(WARRANTY)g(OF)h(ANY)h(KIND,)e(EITHER)h(EXPRESSED)264
+2685 y(OR)h(IMPLIED,)e(INCLUDING,)g(BUT)h(NOT)g(LIMITED)f(TO,)h(THE)h
+(IMPLIED)e(WARRANTIES)g(OF)264 2735 y(MERCHANTABILITY)f(AND)i(FITNESS)g(FOR)g
+(A)g(PARTICULAR)f(PURPOSE.)42 b(THE)21 b(ENTIRE)g(RISK)g(AS)264
+2785 y(TO)h(THE)f(QUALITY)f(AND)h(PERFORMANCE)f(OF)h(THE)g(PROGRAM)g(IS)g
+(WITH)g(YOU.)43 b(SHOULD)20 b(THE)264 2835 y(PROGRAM)h(PROVE)f(DEFECTIVE,)g
+(YOU)h(ASSUME)g(THE)g(COST)g(OF)g(ALL)h(NECESSARY)e(SERVICING,)1032
+2940 y Fr(112)p eop
+%%Page: 113 114
+113 113 bop 264 42 a Fl(REPAIR)21 b(OR)g(CORRECTION.)308 141
+y(12.)g(IN)g(NO)h(EVENT)f(UNLESS)f(REQUIRED)g(BY)i(APPLICABLE)d(LAW)j(OR)f
+(AGREED)g(TO)g(IN)g(WRITING)264 191 y(WILL)g(ANY)g(COPYRIGHT)f(HOLDER,)h(OR)g
+(ANY)g(OTHER)g(PARTY)g(WHO)g(MAY)g(MODIFY)g(AND/OR)264 241
+y(REDISTRIBUTE)f(THE)h(PROGRAM)f(AS)i(PERMITTED)d(ABOVE,)i(BE)g(LIABLE)g(TO)g
+(YOU)h(FOR)f(DAMAGES,)264 291 y(INCLUDING)f(ANY)h(GENERAL,)g(SPECIAL,)f
+(INCIDENTAL)f(OR)j(CONSEQUENTIAL)d(DAMAGES)h(ARISING)264 340
+y(OUT)i(OF)f(THE)g(USE)g(OR)h(INABILITY)e(TO)h(USE)g(THE)g(PROGRAM)g
+(\(INCLUDING)e(BUT)j(NOT)f(LIMITED)264 390 y(TO)h(LOSS)f(OF)g(DATA)g(OR)g
+(DATA)g(BEING)g(RENDERED)f(INACCURATE)g(OR)h(LOSSES)g(SUSTAINED)f(BY)264
+440 y(YOU)i(OR)f(THIRD)g(PARTIES)f(OR)h(A)h(FAILURE)e(OF)i(THE)f(PROGRAM)f
+(TO)i(OPERATE)e(WITH)h(ANY)g(OTHER)264 490 y(PROGRAMS\),)f(EVEN)h(IF)g(SUCH)g
+(HOLDER)g(OR)g(OTHER)g(PARTY)g(HAS)g(BEEN)g(ADVISED)f(OF)i(THE)264
+540 y(POSSIBILITY)e(OF)h(SUCH)g(DAMAGES.)177 726 y Fi(5.8)70
+b(Distribution)177 853 y Fr(Users)15 b(of)d(F)m(unnelW)m(eb)h(should)f(b)q(e)
+i(a)o(w)o(are)f(that)g(they)h(can)f(distribute)g(the)h(program)e(freely)m(.)
+17 b(The)d(follo)o(wing)c(is)177 903 y(an)h(extract)h(from)e(the)i(GNU)f
+(General)g(Public)g(License)h(V)m(ersion)g(2,)f(under)h(whic)o(h)f(F)m
+(unnelW)m(eb)g(is)g(distributed.)308 1038 y Fl(1.)21 b(You)g(may)h(copy)f
+(and)g(distribute)f(verbatim)g(copies)g(of)i(the)f(Program's)264
+1088 y(source)g(code)g(as)g(you)g(receive)g(it,)g(in)g(any)g(medium,)g
+(provided)f(that)h(you)264 1138 y(conspicuously)e(and)j(appropriately)d
+(publish)h(on)h(each)g(copy)g(an)h(appropriate)264 1187 y(copyright)e(notice)
+h(and)g(disclaimer)f(of)h(warranty;)f(keep)h(intact)g(all)g(the)264
+1237 y(notices)g(that)g(refer)f(to)i(this)f(License)f(and)h(to)h(the)f
+(absence)f(of)i(any)f(warranty;)264 1287 y(and)h(give)e(any)i(other)e
+(recipients)g(of)i(the)f(Program)f(a)i(copy)f(of)g(this)g(License)264
+1337 y(along)g(with)g(the)g(Program.)264 1436 y(You)h(may)f(charge)f(a)i(fee)
+f(for)g(the)g(physical)f(act)i(of)f(transferring)e(a)j(copy,)f(and)264
+1486 y(you)h(may)f(at)g(your)g(option)g(offer)f(warranty)g(protection)g(in)i
+(exchange)e(for)h(a)g(fee.)177 1622 y Fr(The)14 b(license)h(also)e(allo)o(ws)
+g(y)o(ou)g(other)i(freedoms.)j(F)m(or)13 b(more)g(information)e(see)k
+(Section)f(5.6.)177 1808 y Fi(5.9)70 b(Mo)r(di\014cation)177
+1935 y Fr(F)m(unnelW)m(eb)16 b(is)g(distributed)g(under)h(a)f(GNU)g(license,)
+h(and)f(y)o(ou)g(are)g(free)h(to)f(mo)q(dify)e(the)j(source)g(co)q(de)g(and)
+177 1985 y(distribute)12 b(mo)q(di\014ed)e(copies)i(\(see)h(Section)f(5.6\).)
+k(Ho)o(w)o(ev)o(er,)c(there)h(are)e(go)q(o)q(d)g(reasons)i(wh)o(y)e(y)o(ou)g
+(should)g(a)o(v)o(oid)177 2034 y(doing)i(this.)228 2170 y(1.)20
+b(If)13 b(y)o(ou)g(distribute)h(mo)q(di\014ed)d(v)o(ersions)j(of)f(F)m
+(unnelW)m(eb,)f(y)o(ou)h(run)h(the)g(risk)f(of)g(creating)g(a)g(v)o(ersion)h
+(that)281 2220 y(will)e(div)o(erge)i(from)f(the)h(\\o\016cial")e(v)o(ersion)i
+(of)f(F)m(unnelW)m(eb)h(that)g(I)f(in)o(tend)h(to)g(main)o(tain.)228
+2318 y(2.)20 b(If)13 b(y)o(ou)f(release)i(a)f(v)o(ersion)g(of)g(F)m(unnelW)m
+(eb)f(with)h(a)f(c)o(hanged)i(input)f(language,)e(users)k(of)d(y)o(our)h(mo)q
+(di\014ed)281 2368 y(v)o(ersion)g(will)f(create)i(source)g(\014les)g(that)f
+(will)e(no)i(longer)g(w)o(ork)g(on)g(other)g(v)o(ersions)h(of)e(F)m(unnelW)m
+(eb.)17 b(The)281 2418 y(result)e(w)o(ould)e(b)q(e)h(c)o(haos.)177
+2553 y(F)m(or)d(these)i(reasons)g(I)e(request)j(that)d(y)o(ou)g(do)h(not)f
+(distribute)h(mo)q(di\014ed)e(v)o(ersions)j(of)e(F)m(unnelW)m(eb,)g
+(particularly)177 2603 y(v)o(ersions)19 b(with)g(a)f(mo)q(di\014ed)g
+(language.)31 b(Ho)o(w)o(ev)o(er,)20 b(if)e(y)o(ou)g(m)o(ust)g(distribute)h
+(a)f(v)o(ersion)h(with)g(a)f(mo)q(di\014ed)177 2653 y(language,)13
+b Fm(ple)n(ase)j(change)g(its)f(name)g Fr(\(i.e.)e(from)g(\\F)m(unnelW)m(eb")
+h(to)g(something)f(else\).)20 b(Please)c(also)d(allo)q(cate)177
+2702 y(a)19 b(new)h(\014le)f(extension)i(to)e(replace)h(\\)p
+Fl(.fw)p Fr(")e(as)i(the)g(extension)g(for)f(source)i(\014les)e(written)h(in)
+f(the)h(mo)q(di\014ed)177 2752 y(language.)177 2835 y(F)m(or)14
+b(more)f(information,)d(refer)15 b(to)f(the)g Fm(F)m(unnelWeb)i(Hacker's)f
+(Manual)p Fr(.)1032 2940 y(113)p eop
+%%Page: 114 115
+114 114 bop 177 42 a Fi(5.10)70 b(V)-6 b(ersions)177 157 y
+Fr(F)m(unnelW)m(eb)1502 b(w)o(as)177 207 y(created)19 b(in)f(1986)f(and)g(w)o
+(as)h(used)g(extensiv)o(ely)h(b)o(y)e(Ross)h(William)o(s)d(\()p
+Fl(ross@spam.adelaide.)o(edu.a)o(u)p Fr(\))g(for)177 257 y(three)k(y)o(ears.)
+29 b(Ho)o(w)o(ev)o(er,)18 b(V)m(ersion)g(1.0)e(w)o(as)h(written)h(in)f(Ada)h
+(and)f(w)o(as)g(not)g(v)o(ery)h(p)q(ortable)g(\(it)f(w)o(as)g(fairly)177
+307 y(V)-5 b(AX/VMS)16 b(sp)q(eci\014c\).)24 b(Da)o(vid)14
+b(Hulse)i(\()p Fl(dave@cs.adelaide.e)o(du.au)o Fr(\))d(to)q(ok)i(the)h
+(\014rst)g(step)g(to)o(w)o(ards)f(a)g(re-)177 357 y(lease)j(b)o(y)e
+(translating)g(the)i(Ada)e(co)q(de)i(in)o(to)e(C.)h(Ross)f(Williams)e(then)j
+(extensiv)o(ely)h(rew)o(ork)o(ed)f(the)h(C)e(co)q(de,)177 406
+y(making)c(it)h(robust)i(and)e(p)q(ortable,)h(adding)f(new)h(features,)h(and)
+f(p)q(olishing)e(it)i(to)f(its)h(curren)o(t)i(form.)199 523
+y Fl(Vers)43 b(Lang)f(Created)h(Released)63 b(Author)217 b(Copyright)129
+b(Licensing)199 572 y(----)43 b(----)f(-------)h(--------)63
+b(--------------)41 b(-------------)g(---------)199 622 y(V1.0)i(Ada)64
+b(1986)109 b(Never)129 b(Ross)43 b(Williams)f(Ross)21 b(Williams)199
+672 y(V2.0)43 b(C)108 b(1989)h(Never)129 b(David)21 b(Hulse)108
+b(Public)21 b(domain)42 b(No)21 b(restriction.)199 722 y(V3.0)43
+b(C)108 b(1992)h(May-1992)63 b(Ross)43 b(Williams)f(Ross)21
+b(Williams)42 b(GNU)21 b(release.)177 838 y Fr(This)14 b(man)o(ual)d(w)o(as)j
+(released)h(for:)286 954 y Fl(*)22 b(FunnelWeb)150 b(V3.0.)286
+1004 y(*)22 b(User's)e(Manual)64 b(V1.0.)286 1054 y(*)22 b(Hacker's)e(Manual)
+g(V1.0.)286 1104 y(*)i(TeX)f(Definitions)e(V1.0.)177 1266 y
+Fi(5.11)70 b(FTP)23 b(Arc)n(hiv)n(e)f(and)i(Author)177 1382
+y Fr(The)14 b(F)m(unnelW)m(eb)g(FTP)g(arc)o(hiv)o(e)g(is:)243
+1498 y Fl(Machine)63 b(:)22 b(sirius.itd.adelaid)o(e.edu)o(.au)c
+([IP=129.127.40.3].)243 1548 y(Directory)h(:)j(~pub/funnelweb/)62
+b(\(or)22 b(a)f(directory)f(of)h(similar)g(name\).)177 1664
+y Fr(The)14 b(author)g(of)g(F)m(unnelW)m(eb)f(and)h(this)g(man)o(ual)d(is:)
+243 1780 y Fl(Name:)42 b(Dr)21 b(Ross)g(N.)h(Williams)243 1830
+y(Email:)e(ross@spam.adelaide)o(.edu.)o(au)243 1880 y(Snail:)g(16)h(Lerwick)g
+(Avenue,)f(Hazelwood)g(Park)h(5066,)g(Australia.)177 1996 y
+Fr(I)11 b(in)o(tend)g(to)g(main)o(tain)d(an)i(\\o\016cial")f(v)o(ersion)i(of)
+f(F)m(unnelW)m(eb)h(whic)o(h)f(I)h(will)f(release)i(under)f(GNU)g(license)h
+(from)177 2046 y(time)d(to)h(time.)15 b(I)10 b(am)e(happ)o(y)i(to)g(receiv)o
+(e)h(constructiv)o(e)g(criticism)e(ab)q(out)h(F)m(unnelW)m(eb)g(and)f(its)h
+(do)q(cumen)o(tation.)177 2121 y(I)k(will)e(alw)o(a)o(ys)g(b)q(e)i(happ)o(y)f
+(to)h(receiv)o(e)h(mail)10 b(ab)q(out)k(F)m(unnelW)m(eb,)e(but)i(cannot)g
+(guaran)o(tee)g(that)f(I)h(will)e(b)q(e)i(able)177 2171 y(to)g(reply)g(to)g
+(it)f(immediately)l(.)1032 2940 y(114)p eop
+%%Page: 115 116
+115 115 bop 177 379 a Fj(App)s(endix)34 b(A)177 612 y Fp(Glossary)177
+854 y Fo(Analyser:)20 b Fr(A)15 b(comp)q(onen)o(t)f(of)h(the)g(F)m(unnelW)m
+(eb)g(program)e(that)i(c)o(hec)o(ks)i(the)e(macro)f(table)h(created)h(b)o(y)f
+(the)177 903 y(parser)g(for)f(errors.)19 b(F)m(or)14 b(example,)e(the)i
+(analyser)g(c)o(hec)o(ks)h(to)f(see)h(if)e(an)o(y)h(macro)e(without)i(a)f
+Fl(@Z)h Fr(has)g(not)g(b)q(een)177 953 y(called.)177 1029 y
+Fo(Argumen)o(t:)h Fr(A)d(string)f(delimited)f(b)o(y)h(blanks)g(app)q(earing)h
+(on)f(the)h(F)m(unnelW)m(eb)f(command)d(line.)17 b(Argumen)o(ts)177
+1079 y(are)d(used)h(to)f(con)o(trol)g(options.)177 1154 y Fo(Directiv)o(e:)j
+Fr(A)e(F)m(unnelW)m(eb)e(sp)q(ecial)i(sequence)i(or)d(co)q(op)q(erating)h
+(group)f(of)g(sp)q(ecial)g(sequences)j(that)e(do)f(not)177
+1204 y(form)e(part)i(of)g(a)f(macro)g(de\014nition.)18 b(A)13
+b(directiv)o(e)i(can)f(tak)o(e)g(the)g(form)f(of)g(a)g(pragma.)177
+1280 y Fo(Do)q(cumen)o(tation:)i Fr(Descriptiv)o(e)g(text.)177
+1355 y Fo(Do)q(cumen)o(tation)i(\014le:)25 b Fr(An)18 b(output)g(\014le,)h
+(pro)q(duced)g(b)o(y)f(the)g(W)m(ea)o(v)o(e)f(comp)q(onen)o(t)h(of)f(F)m
+(unnelW)m(eb,)h(that)177 1405 y(con)o(tains)c(t)o(yp)q(esetter)i(commands.)g
+(When)e(fed)g(in)o(to)f(the)i(appropriate)f(t)o(yp)q(esetter)i(program,)c
+(the)j(result)f(is)g(a)177 1455 y(t)o(yp)q(eset)i(image)11
+b(of)j(the)g(input)g(\014le.)177 1531 y Fo(F)l(ree)19 b(text:)24
+b Fr(The)17 b(text)h(in)e(an)h(input)g(\014le)g(that)g(remains)f(if)g(one)h
+(w)o(ere)h(to)e(remo)o(v)o(e)g(macro)g(de\014nitions)h(and)177
+1580 y(directiv)o(es.)177 1656 y Fo(F)l(unnelW)l(eb:)27 b Fr(This)19
+b(w)o(ord)f(has)i(a)e(n)o(um)o(b)q(er)g(of)h(di\013eren)o(t)h(meanings)d(all)
+h(p)q(ertaining)h(to)g(the)g(F)m(unnelW)m(eb)177 1706 y(system)g(of)g
+(programming.)32 b(1\))19 b(The)h(en)o(tire)g(system)g(of)f(programmi)o(ng)d
+(as)k(in)f(\\Ma)o(yb)q(e)h(F)m(unnelW)m(eb)f(can)177 1756 y(help.")k(2\))15
+b(The)h(computer)f(program)f(that)i(implem)o(en)o(ts)e(the)i(system)f(as)h
+(in)f(\\Run)g(it)g(through)g(F)m(unnelW)m(eb)177 1805 y(and)d(see)h(what)f
+(comes)f(out.")17 b(3\))12 b(The)g(language)f(implemen)o(ted)f(b)o(y)h(the)i
+(F)m(unnelW)m(eb)e(program)f(as)i(in)g(\\I)f(wrote)177 1855
+y(the)k(program)d(in)h(F)m(unnelW)m(eb.")18 b(or)13 b(\\I)h(wrote)g(the)h
+(program)d(in)i(Ada)f(using)h(F)m(unnelW)m(eb.".)177 1931 y
+Fo(F)l(unnelW)l(eb)g(\014le:)j Fr(A)d(\014le)g(whose)g(con)o(ten)o(ts)h(are)g
+(written)f(in)f(the)i(F)m(unnelW)m(eb)e(language.)177 2006
+y Fo(F)l(unnelW)l(eb)h(language:)j Fr(The)d(language)f(in)g(whic)o(h)h(F)m
+(unnelW)m(eb)f(input)h(\014les)g(are)h(written.)177 2082 y
+Fo(F)l(unnelW)l(eb)i(prop)q(er:)24 b Fr(Usually)m(,)16 b(when)h(F)m(unnelW)m
+(eb)g(is)g(in)o(v)o(ok)o(ed,)f(it)h(pro)q(cesses)j(a)c(single)h(input)g
+(\014le)g(and)177 2132 y(then)e(terminates.)i(Ho)o(w)o(ev)o(er,)d(it)f(also)g
+(has)h(a)g(command)d(language)i(mo)q(de)f(in)i(whic)o(h)f(it)h(is)f(p)q
+(ossible)h(to)g(in)o(v)o(ok)o(e)177 2182 y(\\F)m(unnelW)m(eb")g(man)o(y)e
+(times.)19 b(This)14 b(leads)h(to)f(confusion)g(b)q(et)o(w)o(een)i(\\F)m
+(unnelW)m(eb")d(the)i(outer)g(program)e(and)177 2232 y(\\F)m(unnelW)m(eb")19
+b(the)h(inner)g(program.)34 b(T)m(o)18 b(a)o(v)o(oid)h(this)g(confusion,)i
+(the)f(inner)g(F)m(unnelW)m(eb)f(is)h(sometimes)177 2281 y(referred)c(to)e
+(as)g(\\F)m(unnelW)m(eb)f(prop)q(er".)177 2357 y Fo(FW:)i Fr(An)f
+(abbreviation)f(for)g(\\F)m(unnelW)m(eb")g(that)h(is)g(used)h(wherev)o(er)g
+(appropriate.)177 2433 y Fo(Include)f(\014le:)j Fr(A)d(\014le)g(read)h(in)e
+(b)o(y)h(F)m(unnelW)m(eb)f(as)h(the)h(result)f(of)g(an)f(include)h(pragma)e
+(\()p Fl(@i)22 b(filename)p Fr(\).)177 2508 y Fo(Input)16 b(\014le:)k
+Fr(An)o(y)c(\014le)f(read)h(in)f(b)o(y)g(F)m(unnelW)m(eb.)22
+b(The)16 b(phrase)g(\\the)g(input)f(\014le")g(refers)i(to)f(the)g(ro)q(ot)f
+(input)177 2558 y(\014le)f(\(sp)q(eci\014ed)i(using)d(the)i
+Fl(+F)e Fr(option\).)177 2634 y Fo(Journal)h(\014le:)k Fr(An)c(output)g
+(\014le)g(con)o(taining)f(a)h(cop)o(y)f(of)h(the)g(output)h(sen)o(t)g(to)e
+(the)i(user's)g(console)f(during)g(an)177 2683 y(in)o(v)o(o)q(cation)f(of)g
+(F)m(unnelW)m(eb.)18 b(In)13 b(other)i(systems,)f(this)g(\014le)f(is)h
+(sometimes)e(called)i(a)f(\\log)g(\014le".)177 2759 y Fo(Listing)g(\014le:)k
+Fr(An)d(output)h(\014le)e(summarizing)e(the)k(result)f(of)g(pro)q(cessing)h
+(an)e(input)h(\014le.)177 2835 y Fo(Macro:)19 b Fr(A)14 b(binding)f(of)g(a)h
+(name)f(to)g(a)h(string.)1032 2940 y(115)p eop
+%%Page: 116 117
+116 116 bop 177 42 a Fo(Macro)14 b(de\014nition)o(:)h Fr(A)d(construct)i(app)
+q(earing)e(in)g(a)g(F)m(unnelW)m(eb)f(\014le)h(that)h(binds)f(a)g(name)f(to)h
+(a)f(text)i(string.)177 91 y(A)h(F)m(unnelW)m(eb)f(\014le)h(consists)h(of)f
+(a)f(series)i(of)f(macro)e(de\014nitions)i(surrounded)h(b)o(y)f(do)q(cumen)o
+(tary)f(text.)177 166 y Fo(Mapp)q(er:)18 b Fr(A)13 b(comp)q(onen)o(t)f(of)g
+(the)h(F)m(unnelW)m(eb)f(program)g(that)g(reads)i(in)e(the)i(input)e(\014le)h
+(and)g(creates)h(a)f(cop)o(y)177 216 y(of)g(it)h(in)f(memory)m(.)177
+291 y Fo(Option:)j Fr(An)e(parameter)f(in)o(ternal)f(to)i(the)f(F)m(unnelW)m
+(eb)g(program)f(whic)o(h)h(can)h(b)q(e)f(con)o(trolled)g(b)o(y)h(command)177
+340 y(line)g(argumen)o(ts)f(or)h(pragmas.)177 415 y Fo(Output)h(\014le:)21
+b Fr(An)o(y)15 b(\014le)g(written)h(b)o(y)f(F)m(unnelW)m(eb.)22
+b(This)16 b(includes)g(listing,)e(journal,)g(pro)q(duct,)i(and)g(do)q(cu-)177
+465 y(men)o(tation)e(\014les.)21 b(\(W)m(arning:)f(During)14
+b(most)g(of)g(F)m(unnelW)m(eb's)h(dev)o(elopmen)o(t)f(the)i(term)e(\\output)h
+(\014le")g(w)o(as)177 515 y(also)10 b(used)i(to)f(refer)h(to)f(what)g(are)g
+(no)o(w)f(called)h(\\pro)q(duct)h(\014les".)17 b(This)11 b(turned)g(out)g(to)
+g(b)q(e)h(extremely)e(confusing)177 565 y(and)j(so)h(the)f(term)g(\\pro)q
+(duct)h(\014le")f(w)o(as)g(in)o(v)o(en)o(ted)g(to)h(distinguish)e(the)i
+(generic)g(from)e(the)i(sp)q(eci\014c.)19 b(Ho)o(w)o(ev)o(er,)177
+614 y(as)14 b(this)g(w)o(as)g(a)f(late)h(mo)q(di\014cation,)d(y)o(ou)j(ma)o
+(y)e(\014nd)i(some)f(o)q(ccurrences)k(of)c(the)i(old)e(use)h(of)g(\\output)g
+(\014le".\).)177 689 y Fo(P)o(arser:)20 b Fr(A)15 b(comp)q(onen)o(t)f(of)h
+(the)h(F)m(unnelW)m(eb)e(program)g(that)h(pro)q(cesses)i(the)f(tok)o(en)f
+(list)g(generated)h(b)o(y)f(the)177 739 y(scanner)i(and)f(pro)q(duces)h(a)f
+(macro)e(table)i(and)f(a)h(do)q(cumen)o(t)f(list.)23 b(The)17
+b(parser)g(mainly)c(analyses)j(the)g(input)177 789 y(\014le)e(at)g(the)g(syn)
+o(tactic)h(lev)o(el,)e(but)h(also)f(do)q(es)i(some)e(ligh)o(t)o(w)o(eigh)o(t)
+f(seman)o(tic)h(c)o(hec)o(king)h(to)q(o.)177 863 y Fo(Pragma:)j
+Fr(Single-line)11 b(directiv)o(es)j(that)e(app)q(ears)h(in)f(F)m(unnelW)m(eb)
+f(\014les.)18 b(Pragmas)11 b(con)o(trol)h(ev)o(erything)h(from)177
+913 y(maxim)n(um)d(input)k(line)f(length)h(to)g(t)o(yp)q(esetter)i(dep)q
+(endence.)k(A)14 b(pragma)e(line)i(starts)h(with)e(\\)p Fl(@p)p
+Fr(".)177 988 y Fo(Prin)o(ted)18 b(do)q(cumen)o(tation:)25
+b Fr(Sheets)c(of)d(pap)q(er)i(resulting)e(from)g(actually)g(t)o(yp)q
+(esetting)h(and)g(prin)o(ting)f(a)177 1038 y(do)q(cumen)o(tation)13
+b(\014le.)177 1112 y Fo(Pro)q(duct)e(\014le:)k Fr(An)c(output)g(\014le,)g
+(generated)h(b)o(y)e(the)i(T)m(angle)d(comp)q(onen)o(t)h(of)g(F)m(unnelW)m
+(eb,)h(that)g(con)o(tains)f(the)177 1162 y(expansion)k(of)g(the)h(macros)e
+(in)h(the)h(input)f(\014le.)19 b(Note:)g(Other)d(names)d(considered)j(for)d
+(this)i(w)o(ere:)k(generated)177 1212 y(\014le,)14 b(expanded)g(\014le,)g
+(result)g(\014le,)g(program)e(\014le,)h(and)h(tangle)g(\014le.)177
+1287 y Fo(Scanner:)j Fr(A)d(comp)q(onen)o(t)e(of)h(the)h(F)m(unnelW)m(eb)f
+(program)f(that)i(scans)g(a)f(cop)o(y)h(of)e(the)j(input)e(\014le)g(in)g
+(memory)177 1337 y(and)h(generates)i(a)e(line)g(list)f(and)h(a)g(tok)o(en)g
+(list)g(to)g(b)q(e)h(fed)f(to)g(the)h(parser.)20 b(The)15 b(scanner)g(pro)q
+(cesses)i(the)e(input)177 1386 y(at)f(the)g(lexical)f(lev)o(el.)177
+1461 y Fo(Script:)k Fr(A)d(\014le)f(con)o(taining)g(F)m(unnelW)m(eb)h(shell)f
+(commands.)177 1536 y Fo(Shell:)i Fr(A)c(command)d(language)i(in)o(terpreter)
+j(built)d(in)o(to)g(the)i(F)m(unnelW)m(eb)e(program.)16 b(The)11
+b(in)o(terpreter)i(allo)o(ws)177 1586 y(the)19 b(user)f(to)g(in)o(v)o(ok)o(e)
+f(F)m(unnelW)m(eb)g(prop)q(er)i(man)o(y)d(times)h(during)g(a)h(single)f(in)o
+(v)o(o)q(cation)g(of)g(the)h(F)m(unnelW)m(eb)177 1636 y(program.)177
+1710 y Fo(Sp)q(ecial)12 b(c)o(haracter:)17 b Fr(A)c(distinguished)f(c)o
+(haracter)i(in)d(a)h(F)m(unnelW)m(eb)g(input)g(\014le)h(that)f(in)o(tro)q
+(duces)h(a)g(sp)q(ecial)177 1760 y(sequence.)32 b(By)19 b(default)e(the)i(sp)
+q(ecial)f(c)o(haracter)h(is)f(\\)p Fl(@)p Fr(".)29 b(Ho)o(w)o(ev)o(er,)19
+b(it)f(can)g(b)q(e)g(c)o(hanged)h(using)e(the)i(\\)p Fl(@=)p
+Fr(")177 1810 y(sp)q(ecial)14 b(sequence.)177 1885 y Fo(Sp)q(ecial)f
+(sequence:)k Fr(A)12 b(sp)q(ecial)h(sequence)i(is)e(a)f(construct)i(in)o(tro)
+q(duced)f(b)o(y)g(the)g(sp)q(ecial)g(c)o(haracter.)19 b(Sp)q(ecial)177
+1934 y(sequences)e(are)e(used)g(to)g(de\014ne)g(a)f(structure)j(in)d(a)g(F)m
+(unnelW)m(eb)g(input)g(\014le)g(that)h(exists)g(at)f(a)g(higher)h(lev)o(el)f
+(to)177 1984 y(the)k(surrounding)g(text.)29 b(A)17 b(F)m(unnelW)m(eb)g(input)
+g(\014le)g(ma)o(y)f(b)q(e)i(considered)h(to)e(b)q(e)h(a)f(sequence)i(of)e
+(text)h(and)177 2034 y(sp)q(ecial)c(sequences.)177 2109 y Fo(T)l(angle:)21
+b Fr(This)16 b(is)f(the)h(name)e(for)i(the)g(comp)q(onen)o(t)e(of)h(F)m
+(unnelW)m(eb)g(that)h(generates)h(one)f(or)f(more)g(pro)q(duct)177
+2159 y(\014les)f(con)o(taining)f(the)i(expansion)e(of)h(macros)f(in)g(the)i
+(input)e(\014le.)177 2233 y Fo(T)o(yp)q(esetting)h(directiv)o(e:)j
+Fr(A)e(F)m(unnelW)m(eb)f(directiv)o(e)h(whose)h(sole)e(e\013ect)i(is)f(to)f
+(mo)q(dify)f(the)i(w)o(a)o(y)f(in)g(whic)o(h)177 2283 y(the)h(input)e(\014le)
+h(is)g(represen)o(ted)j(in)c(the)i(do)q(cumen)o(tation)d(\014le.)177
+2358 y Fo(W)l(ea)o(v)o(e:)23 b Fr(This)16 b(is)f(the)i(name)e(for)g(the)i
+(comp)q(onen)o(t)e(of)g(F)m(unnelW)m(eb)h(that)g(generates)h(a)f(do)q(cumen)o
+(tation)f(\014le)177 2408 y(con)o(taining)e(t)o(yp)q(esetting)i(commands)c
+(represen)o(ting)16 b(the)e(input)g(\014le.)1032 2940 y(116)p
+eop
+%%Page: 117 118
+117 117 bop 177 378 a Fj(App)s(endix)34 b(B)177 610 y Fp(References)177
+851 y Fo([ANSI])21 b Fr(Australian)f(Standard)h(AS)f(3955-1991,)f
+(\\Programming)e(Languages)j(|)g(C",)g(\(ISBN:)g(0-7262-)177
+901 y(6970-0\),)c(12)h(July)g(1991.)27 b(Iden)o(tical)17 b(to:)24
+b(In)o(ternational)17 b(Standard)g(ISO/IEC)h(9899:)23 b(1990)16
+b(Programming)177 951 y(Languages)e(|)f(C.)177 1025 y Fo([ANZE])k
+Fr(\\Australia,)f(New)g(Zealand)g(Encyclop)q(edia",)g(En)o(try:)22
+b(\\F)m(unnel-w)o(eb)15 b(spiders",)i(V)m(ol)e(7,)g(pp.)h(564{)177
+1075 y(565,)d(Ba)o(y)h(Bo)q(oks,)f(Sydney)m(,)h(\(ISBN:)g(85835{127{7\),)d
+(1975.)177 1150 y Fo([BSI82])f Fr(British)h(Standards)g(Institute,)g(\\Sp)q
+(eci\014cation)g(for)f(Computer)g(Programmi)o(ng)e(Language)i(P)o(ascal",)177
+1200 y(Publication)15 b(BS6192:1982,)e(British)j(Standards)g(Institute,)h(P)m
+(.O.)e(Bo)o(x)g(372,)g(Milton)f(Keynes,)j(MK146LO,)177 1249
+y(1982.)177 1324 y Fo([Gries81])8 b Fr(Gries)i(D.,)f(\\The)h(Science)h(of)e
+(Programming)o(",)e(Springer-V)m(erlag,)j(\(ISBN:)g(0-387-90641-X\),)c(1981.)
+177 1399 y Fo([Humphries91])13 b Fr(Humphries)i(B,)g(\\Neglected)h(P)o(o)q
+(ems)f(and)g(Other)h(Creatures",)h(Angus)f(and)f(Rob)q(ertson,)177
+1449 y(Sydney)m(,)f(\(ISBN:)g(0-207-17212-9\),)c(1991.)177
+1523 y Fo([Kernighan88])15 b Fr(Kernighan)i(B.W.,)g(Ritc)o(hie)f(D.M.,)g
+(\\The)h(C)g(Programming)c(Language",)k(\(second)h(edi-)177
+1573 y(tion,\\ANSI)13 b(C"\),)g(Pren)o(tice)j(Hall,)c(\(ISBN:)i
+(0-13-110362-8\),)d(1988.)177 1648 y Fo([Kn)o(uth83])j Fr(Kn)o(uth)h(D.E.,)f
+(\\The)h(WEB)g(System)f(of)h(Structured)h(Do)q(cumen)o(tation",)d(\(W)m(eb)i
+(User)h(Man)o(ual,)177 1698 y(V)m(ersion)e(2.5,)f(No)o(v)o(em)o(b)q(er,)f
+(1983\),)h(Stanford)g(Univ)o(ersit)o(y)m(,)g(1983.)177 1773
+y Fo([Kn)o(uth84])f Fr(Kn)o(uth)j(D.E.,)d(\\The)i(T)767 1781
+y(E)790 1773 y(Xb)q(o)q(ok",)f(Addison-W)m(esley)m(,)g(\(ISBN:)h
+(0-201-13448-9\),)d(1984.)177 1847 y Fo([Kn)o(uth84])h Fr(Kn)o(uth)i(D.E.,)e
+(\\Literate)i(Programmi)o(ng",)c Fm(The)k(Computer)h(Journal)p
+Fr(,)e(V)m(ol.)e(27,)i(No.)g(2,)f(pp.)h(97-)177 1897 y(111,)g(1984.)k(Note:)h
+(The)d(author)e(of)h(this)g(man)o(ual)d(has)j(not)g(y)o(et)g(obtained)g(this)
+g(pap)q(er.)177 1972 y Fo([Lamp)q(ort86])h Fr(Lamp)q(ort)h(L.,)g(\\L)723
+1967 y Fk(a)742 1972 y Fr(T)765 1984 y(E)788 1972 y(X:)g(A)g(Do)q(cumen)o(t)g
+(Preparation)h(System",)f(Addison-W)m(esley)m(,)g(\(ISBN:)177
+2022 y(0-201-15790-X\),)11 b(1986.)177 2096 y Fo([Roso)o(vsky90])16
+b Fr(Roso)o(vsky)f(H.,)h(\\The)g(Univ)o(ersit)o(y:)23 b(An)16
+b(Owner's)h(Man)o(ual",)e(W.W.Norton)f(&)j(Compan)o(y)m(,)177
+2146 y(Inc.,)d(\(ISBN:)g(0-393-02782-1\),)c(1990.)177 2221
+y Fo([Smith91])16 b Fr(Smith)h(L.M.C.,)g(\\An)i(Annotated)f(Bibliograph)o(y)f
+(of)h(Literate)h(Programming)o(",)d(A)o(CM)i(SIG-)177 2271
+y(PLAN)c(Notices,)h(V)m(ol.)d(26,)h(No.)g(1,)g(Jan)o(uary)h(1991.)177
+2345 y Fo([Strunk79])d Fr(Strunk)i(W.,)f(White)g(E.B.,)h(\\The)g(Elemen)o(ts)
+f(of)g(St)o(yle",)g(Third)h(Edition,)f(MacMillan)f(Publish-)177
+2395 y(ing)i(Compan)o(y)m(,)e(New)k(Y)m(ork,)e(\(ISBN:)h(0-02-418200-1\),)c
+(1979.)177 2470 y Fo([USDOD83])17 b Fr(\\The)i(Programming)c(Language)j(Ada)g
+(Reference)i(Man)o(ual",)e(American)g(National)f(Stan-)177
+2520 y(dards)e(Institute)f(Inc,)g(ANSI/MIL-STD-1815A-1983,)d(1983.)1032
+2940 y(117)p eop
+%%Page: 118 119
+118 118 bop 177 279 a Fp(Index)177 487 y Fr(+=)15 b(tutorial)e(26)177
+537 y(+=)i(85)177 587 y(2167A)e(51)177 637 y(==)i(tutorial)e(26)177
+687 y(==)i(85)177 737 y(@!)f(37)177 787 y(@!)g(75)177 837 y(@")g(29)177
+886 y(@\()g(29)177 936 y(@\))g(29)177 986 y(@+)h(20)177 1036
+y(@+)g(76)177 1086 y(@,)f(29)177 1136 y(@-)g(23)177 1186 y(@-)g(77)177
+1236 y(@1...)f(28)177 1286 y(@1...)g(86)177 1336 y(@<)h(20)177
+1386 y(@=)h(20)177 1436 y(@>)f(20)177 1486 y(@A...)f(34)177
+1536 y(@braces)j(20)177 1586 y(@braces)g(37)177 1636 y(@circum\015ex)e(74)177
+1686 y(@dollar)f(22)177 1736 y(@hash)i(76)177 1786 y(@i)f(30)177
+1836 y(@i)g(77)177 1886 y(@M)g(tutorial)f(24)177 1935 y(@M)h(85)177
+1985 y(@O)h(20)177 2035 y(@O)g(22)177 2085 y(@slash)f(37)177
+2135 y(@Z)h(tutorial)e(24)177 2185 y(@Z)i(85)177 2235 y(absen)o(t)g(command)c
+(93)177 2285 y(abstract)k(data)e(t)o(yp)q(e)i(55)177 2335 y(abstraction)f(co)
+q(de)h(56)177 2385 y(abstraction)f(data)g(26)177 2435 y(abstraction)g(set)h
+(59)177 2485 y(abuse)g(commen)o(ts)d(57)177 2535 y(access)k(random)c(50)177
+2585 y(ac)o(kno)o(wledgemen)o(ts)h(11)177 2635 y(action)h(execution)g(order)h
+(71)177 2685 y(Action)f(options)g(70)177 2735 y(actual)g(parameters)g(29)177
+2785 y(Ada)g(11)177 2835 y(Ada)g(44)1136 487 y(Ada)f(49)1136
+537 y(Ada)g(51)1136 587 y(Ada)g(55)1136 637 y(additiv)o(e)g(macros)g(26)1136
+687 y(additiv)o(e)g(macro)f(26)1136 737 y(additiv)o(ely)g(de\014ned)j(85)1136
+787 y(Adelaide)e(Univ)o(ersit)o(y)h(59)1136 837 y(admin)d(directory)k(102)
+1136 886 y(administration)c(F)m(unnelW)m(eb)i(109)1136 936
+y(ADT)g(55)1136 986 y(alias)f(49)1136 1036 y(Analyser)i(115)1136
+1086 y(analyser)g(65)1136 1136 y(analyser)g(88)1136 1186 y(analysis)f(static)
+h(88)1136 1236 y(Andrew)g(T)m(rev)o(orro)o(w)g(13)1136 1286
+y(animal)d(p)q(o)q(em)i(30)1136 1336 y(ann)o(ual)g(rep)q(ort)h(58)1136
+1386 y(anon)o(ymous)e(ftp)h(101)1136 1436 y(ANSI)h(109)1136
+1486 y(ANSI)g(117)1136 1536 y(answ)o(ers)h(correct)g(102)1136
+1586 y(answ)o(ers)g(directory)f(102)1136 1636 y(ANZE)g(117)1136
+1686 y(ANZE)g(19)1136 1736 y(applications)e(F)m(unnelW)m(eb)i(53)1136
+1786 y(arbitrary)f(c)o(haracters)j(inserting)e(in)o(to)f(text)i(74)1136
+1836 y(arc)o(hitecture)g(seman)o(tic)e(64)1136 1886 y(arc)o(hiv)o(e)h(ftp)f
+(114)1136 1935 y(arc)o(hiv)o(e)h(F)m(unnelW)m(eb)f(114)1136
+1985 y(argumen)o(t)f(command)g(line)h(67)1136 2035 y(argumen)o(ts)g(67)1136
+2085 y(Argumen)o(t)g(115)1136 2135 y(assertion)h(sev)o(erit)o(y)h(65)1136
+2185 y(assertion)f(status)h(90)1136 2235 y(A)o(trax)f(robustus)g(19)1136
+2285 y(attributes)g(macro)f(85)1136 2335 y(author)h(con)o(tacting)f(114)1136
+2385 y(B)h(option)f(68)1136 2435 y(Barry)h(Dwy)o(er)g(11)1136
+2485 y(Barry)g(Dwy)o(er)g(59)1136 2535 y(Barry)g(Humphries)f(19)1136
+2585 y(BASIC)h(57)1136 2635 y(Begg)g(Jerem)o(y)g(11)1136 2685
+y(binding)f(problems)f(57)1136 2735 y(bindings)h(macro)g(22)1136
+2785 y(blank)g(inden)o(tation)g(78)1136 2835 y(blank)g(inden)o(tation)g(78)
+1032 2940 y(118)p eop
+%%Page: 119 120
+119 119 bop 177 42 a Fr(blanks)14 b(trailing)e(42)177 91 y(b)q(oring)i
+(organization)e(50)177 141 y(Brissenden)k(Roger)e(11)177 191
+y(BSI82)g(117)177 241 y(BSI82)g(15)177 291 y(BSI82)g(18)177
+341 y(C)g(header)h(57)177 391 y(C)f(option)f(68)177 441 y(C)h(prepro)q
+(cessor)i(20)177 490 y(C)e(prepro)q(cessor)i(57)177 540 y(calls)e(macro)e(86)
+177 590 y(calls)i(n)o(um)o(b)q(er)f(23)177 640 y(camera)g(p)q(o)q(em)g(30)177
+690 y(case)i(dep)q(endence)i(67)177 740 y(c)o(hanging)c(sp)q(ecial)h(c)o
+(haracter)i(31)177 790 y(c)o(haracters)g(con)o(trol)d(42)177
+840 y(c)o(haracters)j(non-prin)o(table)d(96)177 889 y(c)o(haracters)j(unprin)
+o(table)d(71)177 939 y(c)o(hec)o(ks)i(macro)e(88)177 989 y(c)o(heer)j(hac)o
+(k)o(er's)e(35)177 1039 y(c)o(heer)i(programmer's)11 b(35)177
+1089 y(co)q(de)k(abstraction)f(56)177 1139 y(co)q(de)h(explaining)d(17)177
+1189 y(co)q(de)j(gardening)e(53)177 1239 y(co)q(de)i(vs)f(do)q(cumen)o
+(tation)f(32)177 1288 y(co)q(dify)h(command)d(93)177 1338 y(command)g(absen)o
+(t)k(93)177 1388 y(command)c(co)q(dify)j(93)177 1438 y(command)d(compare)i
+(93)177 1488 y(command)e(de\014ne)k(91)177 1538 y(command)c(de\014ne)k(94)177
+1588 y(command)c(di\013summary)g(95)177 1638 y(command)g(di\013zero)k(95)177
+1687 y(command)c(di\013)j(94)177 1737 y(command)d(eneo)k(95)177
+1787 y(command)c(execute)16 b(96)177 1837 y(command)11 b(exists)k(96)177
+1887 y(command)c(\014xeols)j(96)177 1937 y(command)d(fw)j(97)177
+1987 y(command)d(help)j(97)177 2037 y(command)d(here)k(98)177
+2086 y(command)c(in)o(terpreter)16 b(47)177 2136 y(command)11
+b(length)j(91)177 2186 y(command)d(line)j(argumen)o(t)e(67)177
+2236 y(command)f(line)j(in)o(terface)g(66)177 2286 y(command)d(line)j
+(options)f(syn)o(tax)h(67)177 2336 y(command)d(line)j(parsing)f(66)177
+2386 y(command)e(line)j(pro)q(cessing)h(66)177 2436 y(command)c(line)j(pro)q
+(cessing)h(92)177 2486 y(command)c(line)j(syn)o(tax)g(67)177
+2535 y(command)d(options)j(92)177 2585 y(command)d(quit)j(98)177
+2635 y(command)d(set)k(48)177 2685 y(command)c(set)k(98)177
+2735 y(command)c(shell)j(F)m(unnelW)m(eb)f(90)177 2785 y(command)e(sho)o(w)j
+(48)177 2835 y(command)d(sho)o(w)j(98)1136 42 y(command)d(skipto)i(98)1136
+91 y(command)e(status)j(99)1136 141 y(command)d(tolerate)j(100)1136
+191 y(command)d(trace)k(on)e(48)1136 241 y(command)e(trace)k(100)1136
+291 y(command)c(v)o(erb)j(fw)g(66)1136 341 y(command)d(writeu)j(100)1136
+391 y(command)d(write)j(100)1136 441 y(commands)d(F)m(unnelW)m(eb)i(90)1136
+490 y(commands)e(shell)j(93)1136 540 y(commands)d(useful)j(47)1136
+590 y(commen)o(ts)e(abuse)i(57)1136 640 y(commen)o(ts)e(eliminating)f(57)1136
+690 y(commen)o(ts)h(F)m(unnelW)m(eb)h(75)1136 740 y(commen)o(ts)f(37)1136
+790 y(commitm)n(en)o(t)g(F)m(unnelW)m(eb)h(109)1136 840 y(compare)g(command)e
+(93)1136 889 y(compilers)h(F)m(ortran)i(42)1136 939 y(compiling)d(F)m(unnelW)
+m(eb)i(105)1136 989 y(complete)g(example)f(38)1136 1039 y(conditionals)g
+(fudging)h(44)1136 1089 y(console)h(output)g(suppress)i(69)1136
+1139 y(constructs)g(section)e(83)1136 1189 y(con)o(tacting)f(author)h(114)
+1136 1239 y(con)o(ten)o(ts)h(table)e(of)h(81)1136 1288 y(con)o(text)g
+(in\014nite)g(68)1136 1338 y(con)o(text)g(listing)f(\014le)h(68)1136
+1388 y(con)o(text)g(69)1136 1438 y(con)o(trol)f(c)o(haracters)j(inserting)e
+(in)o(to)f(text)i(74)1136 1488 y(con)o(trol)e(c)o(haracters)j(42)1136
+1538 y(con)o(trollabilit)o(y)11 b(18)1136 1588 y(cop)o(yrigh)o(t)i(F)m
+(unnelW)m(eb)g(112)1136 1638 y(cop)o(yrigh)o(t)g(notice)h(1)1136
+1687 y(correct)h(answ)o(ers)g(102)1136 1737 y(cross)g(reference)h(n)o(um)o(b)
+q(ering)d(89)1136 1787 y(cross)i(referencing)g(17)1136 1837
+y(cross)g(referencing)g(89)1136 1887 y(cryptic)f(text)h(\014les)f(55)1136
+1937 y(D)f(option)g(49)1136 1987 y(D)g(option)g(68)1136 2037
+y(dangers)h(F)m(unnelW)m(eb)g(50)1136 2086 y(data)f(abstraction)h(26)1136
+2136 y(Da)o(vid)e(Hulse)j(11)1136 2186 y(debugger)f(53)1136
+2236 y(debugging)f(wholistic)g(53)1136 2286 y(default)g(options)h(49)1136
+2336 y(default)f(options)h(92)1136 2386 y(default)f(sp)q(ecial)h(c)o
+(haracter)i(72)1136 2436 y(de\014ne)f(command)c(91)1136 2486
+y(de\014ne)k(command)c(94)1136 2535 y(de\014nition)i(F)m(unnelW)m(eb)g(63)
+1136 2585 y(de\014nition)g(macro)g(85)1136 2635 y(de\014nition)g(macro)g(87)
+1136 2685 y(delete)i(output)f(\014les)g(49)1136 2735 y(delete)h(output)f
+(option)f(68)1136 2785 y(delimiting)e(macro)h(parameter)i(87)1136
+2835 y(dep)q(endence)i(case)f(67)1032 2940 y(119)p eop
+%%Page: 120 121
+120 120 bop 177 42 a Fr(dep)q(endencies)17 b(\014le)c(49)177
+91 y(dev)o(elopmen)o(t)g(time)g(17)177 141 y(diagnostics)h(lev)o(els)g(of)f
+(65)177 191 y(diagnostics)h(65)177 241 y(dictionary)f(hac)o(k)o(er's)i(35)177
+291 y(di\013)f(command)d(94)177 341 y(di\013erences)16 b(\014le)e(94)177
+391 y(di\013summary)d(command)g(95)177 441 y(di\013zero)k(command)c(95)177
+490 y(directiv)o(e)k(emphasis)e(85)177 540 y(directiv)o(e)i(literal)e(84)177
+590 y(directiv)o(e)i(newpage)f(37)177 640 y(directiv)o(e)h(table)e(of)h(con)o
+(ten)o(ts)h(37)177 690 y(directiv)o(e)g(title)e(37)177 740
+y(directiv)o(e)i(vskip)e(37)177 790 y(directiv)o(es)i(t)o(yp)q(esetter)h(81)
+177 840 y(directiv)o(es)f(32)177 889 y(directiv)o(es)g(83)177
+939 y(Directiv)o(e)f(115)177 989 y(directory)h(admin)d(102)177
+1039 y(directory)j(answ)o(ers)g(102)177 1089 y(directory)g(hac)o(kman)d(103)
+177 1139 y(directory)j(results)g(103)177 1189 y(directory)g(scripts)g(103)177
+1239 y(directory)g(sources)g(103)177 1288 y(directory)g(tests)g(104)177
+1338 y(directory)g(tree)g(102)177 1388 y(directory)g(userman)e(105)177
+1438 y(directory)i(70)177 1488 y(Distribution)e(F)m(unnelW)m(eb)h(113)177
+1538 y(do)q(cumen)o(t)g(list)f(dump)g(68)177 1588 y(do)q(cumen)o(t)h(list)f
+(64)177 1638 y(do)q(cumen)o(tation)g(duplicate)h(51)177 1687
+y(do)q(cumen)o(tation)f(examples)g(58)177 1737 y(Do)q(cumen)o(tation)f
+(\014le)i(115)177 1787 y(do)q(cumen)o(tation)f(\014le)h(18)177
+1837 y(do)q(cumen)o(tation)f(F)m(unnelW)m(eb)g(110)177 1887
+y(do)q(cumen)o(tation)g(in)o(terdep)q(enden)o(t)j(50)177 1937
+y(do)q(cumen)o(tation)d(o)o(v)o(er)h(51)177 1987 y(do)q(cumen)o(tation)f(pa)o
+(vlo)o(v)f(51)177 2037 y(do)q(cumen)o(tation)h(vs)h(co)q(de)h(32)177
+2086 y(Do)q(cumen)o(tation)d(115)177 2136 y(do)q(cumen)o(tation)h(64)177
+2186 y(DOD83)g(55)177 2236 y(Donald)g(Kn)o(uth)h(11)177 2286
+y(Donald)f(Kn)o(uth)h(50)177 2336 y(Donald)f(Kn)o(uth)h(9)177
+2386 y(dump)f(do)q(cumen)o(t)g(list)h(68)177 2436 y(dump)f(global)f(line)h
+(list)h(68)177 2486 y(dump)f(macro)f(table)i(68)177 2535 y(dump)f(mapp)q(ed)g
+(\014le)h(68)177 2585 y(dump)f(option)g(68)177 2635 y(dump)g(times)g(68)177
+2685 y(dump)g(tok)o(en)h(list)f(68)177 2735 y(duplicate)h(do)q(cumen)o
+(tation)f(51)177 2785 y(Dwy)o(er)h(Barry)h(11)177 2835 y(Dwy)o(er)f(Barry)h
+(59)1136 42 y(EBNF)f(syn)o(tax)g(63)1136 91 y(editors)g(text)h(42)1136
+141 y(Edna)f(Ev)o(erage)g(19)1136 191 y(e\016ciency)g(F)m(unnelW)m(eb)g(47)
+1136 241 y(e\016ciency)g(notes)h(47)1136 291 y(eliminating)10
+b(commen)o(ts)j(57)1136 341 y(emphasis)g(construct)i(37)1136
+391 y(emphasis)e(directiv)o(e)h(85)1136 441 y(empt)o(y)e(name)h(42)1136
+490 y(end-of-line)g(\014ddling)g(with)g(43)1136 540 y(eneo)h(command)d(95)
+1136 590 y(EOL)j(\014ddling)f(with)g(43)1136 640 y(EOL)h(mark)o(ers)f
+(inserting)h(76)1136 690 y(EOL)g(mark)o(ers)f(suppressing)i(77)1136
+740 y(EOL)f(suppression)h(23)1136 790 y(error)f(sev)o(erit)o(y)h(65)1136
+840 y(error)f(status)h(90)1136 889 y(errors)g(shell)f(90)1136
+939 y(Ev)o(erage)g(Edna)g(19)1136 989 y(example)e(applications)h(F)m(unnelW)m
+(eb)g(53)1136 1039 y(example)f(complete)h(38)1136 1089 y(example)f
+(\014lename)h(inheritance)i(70)1136 1139 y(Example)d(F)m(unnelW)m(eb)h(38)
+1136 1189 y(examples)g(do)q(cumen)o(tation)f(58)1136 1239 y(executable)j(F)m
+(unnelW)m(eb)e(106)1136 1288 y(execute)i(command)c(96)1136
+1338 y(execute)k(script)g(option)e(69)1136 1388 y(execution)h(phases)h(64)
+1136 1438 y(exists)f(command)d(96)1136 1488 y(expansion)i(macro)g(30)1136
+1538 y(expansion)g(macro)g(47)1136 1588 y(expansion)g(macro)g(87)1136
+1638 y(explaining)f(co)q(de)j(17)1136 1687 y(expressions)g(macro)e(86)1136
+1737 y(expression)i(85)1136 1787 y(extension)f(70)1136 1837
+y(F)g(option)f(68)1136 1887 y(fatal)f(sev)o(erit)o(y)j(65)1136
+1937 y(fatal)d(status)j(90)1136 1987 y(\014ddling)e(with)g(end-of-line)g(43)
+1136 2037 y(\014ddling)g(with)g(EOL)h(43)1136 2086 y(\014elds)g(\014lename)f
+(70)1136 2136 y(\014le)h(dep)q(endencies)i(49)1136 2186 y(\014le)e
+(di\013erences)i(94)1136 2236 y(\014le)e(include)f(69)1136
+2286 y(\014le)h(journal)e(69)1136 2336 y(\014le)i(listing)e(69)1136
+2386 y(\014le)i(suppression)h(49)1136 2436 y(\014le)f(termination)e(71)1136
+2486 y(\014le)i(t)o(yp)q(eset)h(69)1136 2535 y(\014lename)d(\014elds)j(70)
+1136 2585 y(\014lename)d(inheritance)j(example)e(70)1136 2635
+y(\014lename)f(inheritance)j(70)1136 2685 y(\014les)f(header)h(57)1136
+2735 y(\014les)f(include)g(30)1136 2785 y(\014les)g(include)g(77)1136
+2835 y(\014les)g(input)g(47)1032 2940 y(120)p eop
+%%Page: 121 122
+121 121 bop 177 42 a Fr(\014xeols)14 b(command)d(96)177 91
+y(fon)o(t)i(size)i(46)177 141 y(formal)d(parameter)h(lists)h(86)177
+191 y(formal)e(parameters)i(28)177 241 y(formal)e(parameters)i(28)177
+291 y(formal)e(parameters)i(87)177 341 y(F)m(ortran)g(compilers)f(42)177
+391 y(F)m(ree)i(text)f(115)177 441 y(free)h(text)f(32)177 490
+y(F)m(ree)h(text)f(83)177 540 y(free)h(text)f(83)177 590 y(freestanding)h(t)o
+(yp)q(esetter)h(directiv)o(es)f(83)177 640 y(freestanding)g(81)177
+690 y(ftp)f(anon)o(ymous)e(101)177 740 y(ftp)i(arc)o(hiv)o(e)g(114)177
+790 y(fudging)f(conditionals)g(44)177 840 y(fudging)g(generics)i(59)177
+889 y(functions)f(small)e(56)177 939 y(F)m(unnel-w)o(eb)i(spider)h(19)177
+989 y(F)m(unnelW)m(eb)f(administration)d(109)177 1039 y(F)m(unnelW)m(eb)j
+(applications)e(53)177 1089 y(F)m(unnelW)m(eb)i(arc)o(hiv)o(e)f(114)177
+1139 y(F)m(unnelW)m(eb)h(command)d(shell)i(90)177 1189 y(F)m(unnelW)m(eb)h
+(command)d(shell)i(90)177 1239 y(F)m(unnelW)m(eb)h(commands)d(90)177
+1288 y(F)m(unnelW)m(eb)j(commen)o(ts)e(75)177 1338 y(F)m(unnelW)m(eb)i(commi)
+o(tm)o(en)o(t)e(109)177 1388 y(F)m(unnelW)m(eb)i(compiling)d(105)177
+1438 y(F)m(unnelW)m(eb)j(cop)o(yrigh)o(t)f(112)177 1488 y(F)m(unnelW)m(eb)h
+(dangers)g(50)177 1538 y(F)m(unnelW)m(eb)g(de\014nition)f(63)177
+1588 y(F)m(unnelW)m(eb)h(Distribution)f(113)177 1638 y(F)m(unnelW)m(eb)h(do)q
+(cumen)o(tation)e(110)177 1687 y(F)m(unnelW)m(eb)i(e\016ciency)g(47)177
+1737 y(F)m(unnelW)m(eb)g(example)e(applications)h(53)177 1787
+y(F)m(unnelW)m(eb)h(Example)e(38)177 1837 y(F)m(unnelW)m(eb)i(executable)h
+(106)177 1887 y(F)m(unnelW)m(eb)f(\014le)f(115)177 1937 y(F)m(unnelW)m(eb)h
+(\014le)f(64)177 1987 y(F)m(unnelW)m(eb)h(hin)o(ts)f(41)177
+2037 y(F)m(unnelW)m(eb)h(initialization)d(70)177 2086 y(F)m(unnelW)m(eb)j
+(installation)e(101)177 2136 y(F)m(unnelW)m(eb)i(installing)e(106)177
+2186 y(F)m(unnelW)m(eb)i(in)o(v)o(oking)e(66)177 2236 y(F)m(unnelW)m(eb)i
+(language)e(115)177 2286 y(F)m(unnelW)m(eb)i(license)g(112)177
+2336 y(F)m(unnelW)m(eb)g(martinet)e(42)177 2386 y(F)m(unnelW)m(eb)i(name)e
+(19)177 2436 y(F)m(unnelW)m(eb)i(obtaining)e(101)177 2486 y(F)m(unnelW)m(eb)i
+(o)o(v)o(erview)f(18)177 2535 y(F)m(unnelW)m(eb)h(o)o(v)o(erview)f(64)177
+2585 y(F)m(unnelW)m(eb)h(pitfalls)e(50)177 2635 y(F)m(unnelW)m(eb)i(program)e
+(65)177 2685 y(F)m(unnelW)m(eb)i(prop)q(er)g(115)177 2735 y(F)m(unnelW)m(eb)g
+(prop)q(er)g(48)177 2785 y(F)m(unnelW)m(eb)g(prop)q(er)g(65)177
+2835 y(F)m(unnelW)m(eb)g(registration)f(110)1136 42 y(F)m(unnelW)m(eb)g
+(rules)i(42)1136 91 y(F)m(unnelW)m(eb)e(running)h(66)1136 141
+y(F)m(unnelW)m(eb)f(shell)h(90)1136 191 y(F)m(unnelW)m(eb)f(startup)i(70)1136
+241 y(F)m(unnelW)m(eb)e(supp)q(ort)i(110)1136 291 y(F)m(unnelW)m(eb)e
+(testing)h(105)1136 341 y(F)m(unnelW)m(eb)f(t)o(w)o(o)g(main)f(asp)q(ects)k
+(21)1136 391 y(F)m(unnelW)m(eb)d(v)o(ersions)h(114)1136 441
+y(F)m(unnelW)m(eb)f(115)1136 490 y(fw)g(command)e(v)o(erb)k(66)1136
+540 y(fw)e(command)e(97)1136 590 y(fwinit.fws)h(49)1136 640
+y(fwinit.fws)g(71)1136 690 y(FW)h(115)1136 740 y(gardening)g(co)q(de)i(53)
+1136 790 y(generics)g(fudging)e(59)1136 840 y(generics)i(t)o(yp)q(esafe)f(61)
+1136 889 y(global)e(line)h(list)h(dump)e(68)1136 939 y(glossary)h(115)1136
+989 y(GNU)g(license)i(112)1136 1039 y(GNU)e(license)i(18)1136
+1089 y(GNU)e(license)i(9)1136 1139 y(go)q(o)q(d)e(old)g(da)o(ys)h(57)1136
+1189 y(Gries81)f(117)1136 1239 y(Gries81)g(51)1136 1288 y(H)h(option)f(68)
+1136 1338 y(hac)o(k)o(er's)h(c)o(heer)h(35)1136 1388 y(hac)o(k)o(er's)f
+(dictionary)f(35)1136 1438 y(Hac)o(k)o(ett)h(Simon)e(11)1136
+1488 y(hac)o(kman)g(directory)j(103)1136 1538 y(header)g(C)e(57)1136
+1588 y(header)i(\014le)e(p)q(ostscript)j(54)1136 1638 y(header)f(\014les)f
+(57)1136 1687 y(header)h(page)e(37)1136 1737 y(headings)h(section)g(34)1136
+1787 y(headings)g(strength)h(46)1136 1837 y(Hello)e(Northern)i(Hemisphere)f
+(Program)e(21)1136 1887 y(hello)h(w)o(orld)g(do)q(cumen)o(t)g(20)1136
+1937 y(help)h(command)d(97)1136 1987 y(help)j(option)f(68)1136
+2037 y(here)i(command)c(98)1136 2086 y(hierarc)o(hical)i(structure)j(34)1136
+2136 y(high)d(lev)o(el)g(syn)o(tax)h(82)1136 2186 y(hin)o(ts)f(F)m(unnelW)m
+(eb)h(41)1136 2236 y(Hulse)g(Da)o(vid)f(11)1136 2286 y(Humphries)g(Barry)h
+(19)1136 2336 y(Humphries91)f(117)1136 2386 y(Humphries91)g(19)1136
+2436 y(h)o(yp)q(ertext)i(15)1136 2486 y(I)e(option)h(69)1136
+2535 y(iden)o(ti\014ers)g(macro)f(41)1136 2585 y(include)h(\014le)f(option)h
+(69)1136 2635 y(include)g(\014les)g(recursiv)o(e)h(31)1136
+2685 y(include)f(\014les)g(30)1136 2735 y(include)g(\014les)g(77)1136
+2785 y(include)g(\014les)g(77)1136 2835 y(Include)g(\014le)g(115)1032
+2940 y(121)p eop
+%%Page: 122 123
+122 122 bop 177 42 a Fr(include)14 b(\014le)g(69)177 91 y(inden)o(tation)f
+(blank)h(78)177 141 y(inden)o(tation)f(macro)g(calls)h(25)177
+191 y(inden)o(tation)f(macro)g(expansion)h(78)177 241 y(inden)o(tation)f
+(none)i(78)177 291 y(indep)q(endence)h(language)d(18)177 341
+y(indep)q(endence)j(t)o(yp)q(esetter)h(18)177 391 y(indep)q(endence)f(t)o(yp)
+q(esetter)h(34)177 441 y(indep)q(endence)f(t)o(yp)q(esetter)h(65)177
+490 y(indep)q(endence)f(t)o(yp)q(esetter)h(80)177 540 y(in\014nite)d(con)o
+(text)g(68)177 590 y(inheritance)h(\014lename)d(70)177 640
+y(inheritance)j(section)f(name)f(35)177 690 y(initialization)e(F)m(unnelW)m
+(eb)j(70)177 740 y(initialization)d(script)k(49)177 790 y(initialization)c
+(script)k(71)177 840 y(inline)e(t)o(yp)q(esetter)j(directiv)o(es)f(83)177
+889 y(inline)e(81)177 939 y(input)h(\014le)g(option)f(68)177
+989 y(input)h(\014les)g(47)177 1039 y(Input)g(\014le)g(115)177
+1089 y(input)g(\014le)g(18)177 1139 y(input)g(\014le)g(64)177
+1189 y(input)g(\014le)g(77)177 1239 y(input)g(line)f(length)h(maxim)n(um)c
+(79)177 1288 y(input)k(line)f(length)h(pragma)e(79)177 1338
+y(input)i(line)f(length)h(42)177 1388 y(input)g(line)f(length)h(79)177
+1438 y(inserting)g(EOL)g(mark)o(ers)g(76)177 1488 y(inserting)g(in)o(to)f
+(text)i(arbitrary)f(c)o(haracters)h(74)177 1538 y(inserting)f(in)o(to)f(text)
+i(con)o(trol)e(c)o(haracters)j(74)177 1588 y(inserting)e(in)o(to)f(text)i(sp)
+q(ecial)f(c)o(haracter)h(74)177 1638 y(installation)d(F)m(unnelW)m(eb)i(101)
+177 1687 y(installation)e(problems)h(107)177 1737 y(installing)f(F)m(unnelW)m
+(eb)i(106)177 1787 y(in)o(teractiv)o(e)g(mo)q(de)f(47)177 1837
+y(in)o(teractiv)o(e)h(option)g(69)177 1887 y(in)o(terdep)q(enden)o(t)i(do)q
+(cumen)o(tation)d(50)177 1937 y(in)o(terface)i(command)c(line)i(66)177
+1987 y(in)o(terpreter)j(command)11 b(47)177 2037 y(in)o(tro)q(duction)j
+(tutorial)f(19)177 2086 y(in)o(visible)g(pragmas)f(78)177 2136
+y(in)o(v)o(o)q(cation)h(n)o(um)o(b)q(er)g(23)177 2186 y(in)o(v)o(o)q(cations)
+g(n)o(um)o(b)q(er)g(42)177 2236 y(in)o(v)o(oking)f(F)m(unnelW)m(eb)i(20)177
+2286 y(in)o(v)o(oking)e(F)m(unnelW)m(eb)i(66)177 2336 y(J)g(option)f(69)177
+2386 y(Jerem)o(y)h(Begg)g(11)177 2436 y(journal)f(\014le)h(option)f(69)177
+2486 y(Journal)h(\014le)g(115)177 2535 y(journal)f(\014le)h(64)177
+2585 y(journal)f(\014le)h(69)177 2635 y(K)g(option)f(69)177
+2685 y(Kernighan88)h(117)177 2735 y(Kernighan88)g(65)177 2785
+y(k)o(eyb)q(oard)g(mo)q(de)f(47)177 2835 y(k)o(eyb)q(oard)h(option)f(69)1136
+42 y(Kn)o(uth)h(Donald)f(11)1136 91 y(Kn)o(uth)h(Donald)f(50)1136
+141 y(Kn)o(uth)h(Donald)f(9)1136 191 y(Kn)o(uth83)g(117)1136
+241 y(Kn)o(uth83)g(17)1136 291 y(Kn)o(uth83)g(25)1136 341 y(Kn)o(uth83)g(25)
+1136 391 y(Kn)o(uth83)g(9)1136 441 y(Kn)o(uth84)g(117)1136
+490 y(Kn)o(uth84)g(117)1136 540 y(Kn)o(uth84)g(13)1136 590
+y(Kn)o(uth84)g(17)1136 640 y(Kn)o(uth84)g(18)1136 690 y(L)g(option)h(69)1136
+740 y(Lamp)q(ort86)e(117)1136 790 y(Lamp)q(ort86)g(13)1136
+840 y(language)h(indep)q(endence)j(18)1136 889 y(languages)d(m)o(ultiple)f
+(55)1136 939 y(laser)i(prin)o(ter)g(55)1136 989 y(LaT)m(eX)f(13)1136
+1039 y(LaT)m(eX)g(84)1136 1089 y(la)o(y)o(out)f(program)h(22)1136
+1139 y(la)o(y)o(out)f(program)h(28)1136 1189 y(length)g(command)f(91)1136
+1239 y(length)h(input)h(line)g(42)1136 1288 y(length)f(line)h(71)1136
+1338 y(length)f(output)i(line)e(42)1136 1388 y(letter)h(67)1136
+1438 y(lev)o(els)g(of)f(diagnostics)g(65)1136 1488 y(libraries)g(macro)g(31)
+1136 1538 y(license)h(F)m(unnelW)m(eb)g(112)1136 1588 y(license)g(GNU)g(112)
+1136 1638 y(license)g(GNU)g(18)1136 1688 y(license)g(GNU)g(9)1136
+1737 y(line)f(length)h(input)g(79)1136 1787 y(line)f(length)h(71)1136
+1837 y(line)f(termination)f(71)1136 1887 y(list)h(do)q(cumen)o(t)g(64)1136
+1937 y(list)g(options)h(68)1136 1987 y(list)f(shell)h(commands)d(93)1136
+2037 y(listing)h(\014le)i(con)o(text)h(68)1136 2087 y(listing)d(\014le)i
+(option)f(69)1136 2136 y(Listing)g(\014le)h(115)1136 2186 y(listing)e(\014le)
+i(64)1136 2236 y(listing)e(\014le)i(69)1136 2286 y(literal)f(construct)i(37)
+1136 2336 y(literal)e(directiv)o(e)h(84)1136 2386 y(literate)g(programmi)o
+(ng)d(to)q(ols)i(15)1136 2436 y(literate)h(programmi)o(ng,)c(facilities)j(15)
+1136 2486 y(literate)i(programming)o(,)d(most)i(signi\014can)o(t)h(b)q(ene-)
+1302 2535 y(\014t)f(17)1136 2585 y(literate)g(programmi)o(ng)d(15)1136
+2635 y(literate)j(programmi)o(ng)d(15)1136 2685 y(literate)j(programmi)o(ng)d
+(50)1136 2735 y(MacDra)o(w)i(54)1136 2785 y(Macin)o(tosh)h(13)1136
+2835 y(Macin)o(tosh)g(54)1032 2940 y(122)p eop
+%%Page: 123 124
+123 123 bop 177 42 a Fr(macro)13 b(attributes)i(85)177 91 y(macro)e(bindings)
+g(22)177 141 y(macro)g(b)q(o)q(dy)h(85)177 191 y(macro)f(calls)g(inden)o
+(tation)h(25)177 241 y(macro)f(calls)g(86)177 291 y(macro)g(c)o(hec)o(ks)i
+(88)177 341 y(macro)e(de\014nitions)h(32)177 391 y(Macro)g(de\014nition)g
+(116)177 441 y(macro)f(de\014nition)g(85)177 490 y(macro)g(de\014nition)g(87)
+177 540 y(macro)g(expansion)h(inden)o(tation)f(78)177 590 y(macro)g
+(expansion)h(30)177 640 y(macro)f(expansion)h(47)177 690 y(macro)f(expansion)
+h(87)177 740 y(macro)f(expressions)i(86)177 790 y(macro)e(facilities)g
+(tutorial)g(22)177 840 y(macro)g(iden)o(ti\014ers)h(41)177
+889 y(macro)f(libraries)g(31)177 939 y(macro)g(names)g(41)177
+989 y(macro)g(names)g(86)177 1039 y(macro)g(name)g(85)177 1089
+y(macro)g(parameter)g(delimiting)e(87)177 1139 y(macro)i(recursion)i(43)177
+1189 y(macro)e(recursion)i(88)177 1239 y(macro)e(table)h(dump)e(68)177
+1288 y(macro)h(table)h(64)177 1338 y(macros)f(additiv)o(e)g(26)177
+1388 y(macros)g(parameterized)h(28)177 1438 y(macros)f(simple)g(tutorial)g
+(22)177 1488 y(macros)g(static)h(87)177 1538 y(Macro)g(115)177
+1588 y(magic)e(tric)o(k)i(15)177 1638 y(main)o(tenance)f(programmer)f(50)177
+1687 y(mak)o(e)h(utilit)o(y)f(49)177 1737 y(man)o(uals)g(prin)o(ting)h(107)
+177 1787 y(mapp)q(ed)g(\014le)h(dump)f(68)177 1837 y(Mapp)q(er)i(116)177
+1887 y(mapp)q(er)e(71)177 1937 y(martinet)g(F)m(unnelW)m(eb)g(42)177
+1987 y(maxim)n(um)d(input)k(line)f(length)h(79)177 2037 y(maxim)n(um)c
+(output)k(\014le)g(line)f(length)h(pragma)e(79)177 2086 y(maxim)n(um)e
+(output)k(\014le)g(line)f(length)h(79)177 2136 y(maxim)n(um)c(pro)q(duct)15
+b(\014le)f(line)f(length)h(pragma)e(79)177 2186 y(maxim)n(um)e(pro)q(duct)15
+b(\014le)f(line)f(length)h(79)177 2236 y(medicine)f(wholistic)g(53)177
+2286 y(memory)f(use)i(of)g(30)177 2336 y(memory)e(47)177 2386
+y(MIL-STD-2167A)h(51)177 2436 y(monster)h(\014le)g(p)q(ostscript)h(54)177
+2486 y(m)o(ultiple)d(languages)h(55)177 2535 y(name)g(empt)o(y)g(42)177
+2585 y(name)g(F)m(unnelW)m(eb)g(19)177 2635 y(name)g(section)h(34)177
+2685 y(name)f(section)h(84)177 2735 y(names)f(macro)g(41)177
+2785 y(names)g(macro)g(86)177 2835 y(names)g(quic)o(k)h(42)1136
+42 y(names)f(quic)o(k)g(76)1136 91 y(names)g(section)h(86)1136
+141 y(names)f(86)1136 191 y(name)f(70)1136 241 y(new)i(page)g(pragma)e(81)
+1136 291 y(new)i(page)g(81)1136 341 y(newpage)g(directiv)o(e)g(37)1136
+391 y(no)f(inden)o(tation)h(78)1136 441 y(non-determinism)d(68)1136
+490 y(non-prin)o(table)i(c)o(haracters)j(96)1136 540 y(none)e(inden)o(tation)
+f(78)1136 590 y(notation)g(63)1136 640 y(notes)h(e\016ciency)h(47)1136
+690 y(notice)f(cop)o(yrigh)o(t)f(1)1136 740 y(no)o(v)o(els)g(50)1136
+790 y(n)o(um)o(b)q(er)g(calls)g(23)1136 840 y(n)o(um)o(b)q(er)g(in)o(v)o(o)q
+(cations)g(42)1136 889 y(n)o(um)o(b)q(er)g(in)o(v)o(o)q(cation)f(23)1136
+939 y(n)o(um)o(b)q(er)h(of)g(times)g(called)h(23)1136 989 y(n)o(um)o(b)q
+(ering)e(cross)j(reference)i(89)1136 1039 y(n)o(um)o(b)q(ering)12
+b(section)j(89)1136 1089 y(ob)r(ject)f(co)q(de)h(26)1136 1139
+y(obtaining)d(F)m(unnelW)m(eb)h(101)1136 1189 y(op)q(en)h(systems)g(55)1136
+1239 y(option)f(B)h(68)1136 1288 y(option)f(C)h(68)1136 1338
+y(option)f(delete)i(output)f(68)1136 1388 y(option)f(dump)f(68)1136
+1438 y(option)h(D)g(49)1136 1488 y(option)g(D)g(68)1136 1538
+y(option)g(execute)j(script)e(69)1136 1588 y(option)f(F)h(68)1136
+1638 y(option)f(help)h(68)1136 1687 y(option)f(H)h(68)1136
+1737 y(option)f(include)h(\014le)g(69)1136 1787 y(option)f(input)g(\014le)h
+(68)1136 1837 y(option)f(in)o(teractiv)o(e)h(69)1136 1887 y(option)f(I)h(69)
+1136 1937 y(option)f(journal)g(\014le)h(69)1136 1987 y(option)f(J)h(69)1136
+2037 y(option)f(k)o(eyb)q(oard)h(69)1136 2086 y(option)f(K)h(69)1136
+2136 y(option)f(listing)g(\014le)g(69)1136 2186 y(option)g(L)h(69)1136
+2236 y(option)f(quiet)h(69)1136 2286 y(option)f(Q)h(69)1136
+2336 y(option)f(screen)j(69)1136 2386 y(option)d(S)h(69)1136
+2436 y(option)f(t)o(yp)q(eset)i(69)1136 2486 y(option)e(T)h(69)1136
+2535 y(option)f(width)g(69)1136 2585 y(option)g(W)g(69)1136
+2635 y(option)g(X)h(69)1136 2685 y(options)f(command)e(92)1136
+2735 y(options)i(default)h(49)1136 2785 y(options)f(default)h(92)1136
+2835 y(options)f(list)h(68)1032 2940 y(123)p eop
+%%Page: 124 125
+124 124 bop 177 42 a Fr(options)14 b(setting)g(defaults)g(49)177
+91 y(options)g(syn)o(tax)g(67)177 141 y(options)g(tracedump)f(68)177
+191 y(options)h(67)177 241 y(options)g(68)177 291 y(Option)g(116)177
+341 y(order)h(action)e(execution)i(71)177 391 y(order)g(program)d(22)177
+441 y(ordering)i(program)e(15)177 490 y(Ordinary)i(options)g(70)177
+540 y(organization)f(b)q(oring)g(50)177 590 y(organization)g(spaghetti)h(50)
+177 640 y(output)g(\014le)g(line)g(length)f(maxim)o(um)c(79)177
+690 y(output)14 b(\014les)g(delete)h(49)177 740 y(output)f(\014les)g(18)177
+790 y(output)g(\014les)g(64)177 840 y(Output)h(\014le)f(116)177
+889 y(output)g(line)g(length)f(42)177 939 y(output)h(WEB)g(25)177
+989 y(o)o(v)o(er)g(do)q(cumen)o(tation)f(51)177 1039 y(o)o(v)o(erhead)h(pro)q
+(cedure)i(call)d(57)177 1089 y(o)o(v)o(erview)h(F)m(unnelW)m(eb)f(18)177
+1139 y(o)o(v)o(erview)h(F)m(unnelW)m(eb)f(64)177 1189 y(o)o(v)o(erview)h(t)o
+(yp)q(esetting)h(32)177 1239 y(OzT)m(eX)g(13)177 1288 y(pac)o(k)n(age)f(55)
+177 1338 y(parameter)g(list,)f(absen)o(t)h(29)177 1388 y(parameter)g(lists)g
+(formal)d(86)177 1438 y(parameterized)j(macros)f(28)177 1488
+y(parameters)h(actual)g(29)177 1538 y(parameters)g(formal)e(28)177
+1588 y(parameters)i(formal)e(28)177 1638 y(parameters)i(formal)e(87)177
+1687 y(P)o(arser)j(116)177 1737 y(parser)g(64)177 1787 y(parser)g(82)177
+1837 y(parsing)f(command)d(line)i(66)177 1887 y(P)o(ascal)h(15)177
+1937 y(P)o(ascal)g(25)177 1987 y(P)o(ascal)g(26)177 2037 y(P)o(ascal)g(57)177
+2086 y(P)o(ascal)g(59)177 2136 y(P)o(at)g(Scannel)g(29)177
+2186 y(pa)o(vlo)o(v)f(do)q(cumen)o(tation)f(51)177 2236 y(phases)j(execution)
+g(64)177 2286 y(phases)g(64)177 2336 y(PhD)f(thesis)h(54)177
+2386 y(pitfalls)e(F)m(unnelW)m(eb)g(50)177 2436 y(p)q(o)q(em)g(animal)e(30)
+177 2486 y(p)q(o)q(em)i(camera)g(30)177 2535 y(p)q(ortabilit)o(y)g(18)177
+2585 y(p)q(ostscript)i(header)g(\014le)f(54)177 2635 y(p)q(ostscript)h
+(monster)f(\014le)g(54)177 2685 y(P)o(ostScript)h(54)177 2735
+y(p)q(ostscript)g(57)177 2785 y(pragma)d(input)i(line)f(length)h(79)177
+2835 y(pragma)e(maxim)n(um)e(output)k(\014le)g(line)f(length)h(79)1136
+42 y(pragma)e(maxim)n(um)d(pro)q(duct)15 b(\014le)f(line)f(length)h(79)1136
+91 y(pragma)e(new)i(page)g(81)1136 141 y(pragma)e(table)h(of)h(con)o(ten)o
+(ts)h(81)1136 191 y(pragma)d(title)h(82)1136 241 y(pragma)f(t)o(yp)q(esetter)
+k(80)1136 291 y(pragma)c(vskip)h(81)1136 341 y(pragmas)f(in)o(visible)h(78)
+1136 391 y(pragmas)f(visible)h(78)1136 441 y(pragmas)f(78)1136
+490 y(Pragma)g(116)1136 540 y(pragma)g(25)1136 590 y(pragma)g(78)1136
+640 y(preface)j(9)1136 690 y(prepro)q(cessor)h(C)e(20)1136
+740 y(prepro)q(cessor)i(C)e(57)1136 790 y(presen)o(tation)g(notes)h(13)1136
+840 y(Prin)o(ted)f(do)q(cumen)o(tation)f(116)1136 889 y(prin)o(ter)h(laser)g
+(55)1136 939 y(prin)o(ting)f(man)o(uals)f(107)1136 989 y(prin)o(ting)h
+(system)g(55)1136 1039 y(problems)g(binding)f(57)1136 1089
+y(problems)h(installation)f(107)1136 1139 y(pro)q(cedure)j(call)f(o)o(v)o
+(erhead)g(57)1136 1189 y(pro)q(cessing)h(command)c(line)i(66)1136
+1239 y(pro)q(cessing)i(command)c(line)i(92)1136 1288 y(pro)q(duct)h(\014le)g
+(line)g(length)g(maxim)n(um)9 b(79)1136 1338 y(pro)q(duct)14
+b(\014le)g(width)g(69)1136 1388 y(pro)q(duct)g(\014les)h(18)1136
+1438 y(pro)q(duct)f(\014les)h(64)1136 1488 y(Pro)q(duct)g(\014le)e(116)1136
+1538 y(pro)q(duction)h(to)q(ol)f(19)1136 1588 y(program)f(la)o(y)o(out)h(22)
+1136 1638 y(program)f(la)o(y)o(out)h(28)1136 1687 y(program)f(ordering)i(15)
+1136 1737 y(program)e(order)j(22)1136 1787 y(programmer)c(main)o(tenance)i
+(50)1136 1837 y(programmer's)e(c)o(heer)k(35)1136 1887 y(programmi)o(ng)c
+(literate)j(50)1136 1937 y(Q)g(option)f(69)1136 1987 y(quic)o(k)g(names)g(42)
+1136 2037 y(quic)o(k)g(names)g(76)1136 2086 y(quic)o(k)g(name)g(42)1136
+2136 y(quic)o(k)g(name)g(76)1136 2186 y(quiet)h(option)f(69)1136
+2236 y(quit)g(command)e(98)1136 2286 y(random)h(access)k(50)1136
+2336 y(rec.h)o(umor.funn)o(y)c(29)1136 2386 y(recursion)j(macro)d(43)1136
+2436 y(recursion)j(macro)d(88)1136 2486 y(recursiv)o(e)j(include)f(\014les)g
+(31)1136 2535 y(references)i(117)1136 2585 y(referencing)f(cross)g(89)1136
+2635 y(registration)e(F)m(unnelW)m(eb)h(110)1136 2685 y(regression)h(testing)
+f(103)1136 2735 y(regression)h(testing)f(47)1136 2785 y(reliabilit)o(y)e(18)
+1136 2835 y(REM)h(statemen)o(t)h(57)1032 2940 y(124)p eop
+%%Page: 125 126
+125 125 bop 177 42 a Fr(rep)q(ort)15 b(ann)o(ual)e(58)177 91
+y(results)i(directory)g(103)177 141 y(return)g(status)g(65)177
+191 y(Roger)f(Brissenden)i(11)177 241 y(Roso)o(vsky90)d(117)177
+291 y(Roso)o(vsky90)g(17)177 341 y(Ross)h(William)o(s)d(1)177
+391 y(rule)j(simple)f(20)177 441 y(rules)i(F)m(unnelW)m(eb)e(42)177
+490 y(running)h(F)m(unnelW)m(eb)f(66)177 540 y(S)h(option)f(69)177
+590 y(Scannel)h(P)o(at)g(29)177 640 y(Scanner)h(116)177 690
+y(scanner)g(64)177 740 y(scanner)g(71)177 790 y(screen)h(option)d(69)177
+840 y(script)i(initialization)c(49)177 889 y(script)k(initialization)c(71)177
+939 y(script)k(startup)f(49)177 989 y(scripts)h(directory)g(103)177
+1039 y(Script)g(116)177 1089 y(section)g(constructs)h(83)177
+1139 y(section)f(headings)f(34)177 1189 y(section)h(name)d(inheritance)j(35)
+177 1239 y(section)g(names)e(86)177 1288 y(section)i(name)d(34)177
+1338 y(section)j(name)d(84)177 1388 y(section)j(n)o(um)o(b)q(ering)d(89)177
+1438 y(section)j(strength)g(46)177 1488 y(seman)o(tic)e(arc)o(hitecture)j(64)
+177 1538 y(sequences)h(sp)q(ecial)d(72)177 1588 y(set)h(abstraction)f(59)177
+1638 y(set)h(command)c(48)177 1687 y(set)k(command)c(98)177
+1737 y(setting)j(defaults)g(options)g(49)177 1787 y(setting)g(sp)q(ecial)h(c)
+o(haracter)g(74)177 1837 y(sev)o(ere)h(sev)o(erit)o(y)e(65)177
+1887 y(sev)o(ere)i(status)e(90)177 1937 y(sev)o(erit)o(y)h(assertion)f(65)177
+1987 y(sev)o(erit)o(y)h(error)g(65)177 2037 y(sev)o(erit)o(y)g(fatal)d(65)177
+2086 y(sev)o(erit)o(y)j(sev)o(ere)g(65)177 2136 y(sev)o(erit)o(y)g(w)o
+(arning)e(65)177 2186 y(sev)o(erit)o(y)i(65)177 2236 y(sharing)f(information)
+d(56)177 2286 y(sharing)j(text)g(58)177 2336 y(shark)g(white)g(p)q(oin)o(ter)
+g(19)177 2386 y(shell)g(commands)d(list)j(93)177 2436 y(shell)g(commands)d
+(93)177 2486 y(shell)j(errors)h(90)177 2535 y(shell)f(F)m(unnelW)m(eb)f(90)
+177 2585 y(shell)h(uses)h(90)177 2635 y(Shell)f(116)177 2685
+y(sho)q(oting)g(31)177 2735 y(sho)o(w)g(command)d(48)177 2785
+y(sho)o(w)j(command)d(98)177 2835 y(sign)j(67)1136 42 y(Simon)d(Hac)o(k)o
+(ett)k(11)1136 91 y(simple)d(macros)h(tutorial)g(22)1136 141
+y(simple)f(rule)i(20)1136 191 y(simple)e(sequence)k(72)1136
+241 y(simplicit)o(y)11 b(18)1136 291 y(size)j(fon)o(t)g(46)1136
+341 y(skip)f(v)o(ertical)h(81)1136 391 y(skipto)f(command)e(98)1136
+441 y(small)g(functions)j(56)1136 490 y(Smith91)d(117)1136
+540 y(Smith91)g(17)1136 590 y(snak)o(e)j(tiger)g(19)1136 640
+y(song)f(29)1136 690 y(sources)i(directory)g(103)1136 740 y(spacing)e(43)1136
+790 y(spaghetti)h(organization)e(50)1136 840 y(sp)q(ecial)i(c)o(haracter)h(c)
+o(hanging)e(31)1136 889 y(sp)q(ecial)h(c)o(haracter)h(default)f(72)1136
+939 y(sp)q(ecial)g(c)o(haracter)h(inserting)f(in)o(to)f(text)i(74)1136
+989 y(sp)q(ecial)f(c)o(haracter)h(setting)f(74)1136 1039 y(Sp)q(ecial)f(c)o
+(haracter)j(116)1136 1089 y(sp)q(ecial)e(c)o(haracter)h(20)1136
+1139 y(sp)q(ecial)f(c)o(haracter)h(72)1136 1189 y(sp)q(ecial)f(sequences)i
+(72)1136 1239 y(Sp)q(ecial)d(sequence)k(116)1136 1288 y(sp)q(ecial)d
+(sequence)i(20)1136 1338 y(sp)q(ecial)e(sequence)i(72)1136
+1388 y(sp)q(ecial)e(tok)o(ens)g(82)1136 1438 y(sp)q(eed)h(47)1136
+1488 y(spider)f(F)m(unnel-w)o(eb)g(19)1136 1538 y(startup)g(F)m(unnelW)m(eb)g
+(70)1136 1588 y(startup)g(script)h(49)1136 1638 y(statemen)o(t)e(REM)h(57)
+1136 1687 y(static)g(analysis)f(88)1136 1737 y(static)h(macros)f(87)1136
+1787 y(status)h(assertion)h(90)1136 1837 y(status)f(command)d(99)1136
+1887 y(status)j(error)h(90)1136 1937 y(status)f(fatal)f(90)1136
+1987 y(status)h(return)h(65)1136 2037 y(status)f(sev)o(ere)i(90)1136
+2086 y(status)e(success)j(90)1136 2136 y(status)d(w)o(arning)f(90)1136
+2186 y(stream)g(of)g(consciousness)j(50)1136 2236 y(strength)f(headings)f(46)
+1136 2286 y(strength)h(section)f(46)1136 2336 y(strength)h(t)o(yp)q(esetting)
+g(46)1136 2386 y(string)f(substitution)g(91)1136 2436 y(string)g
+(substitution)g(94)1136 2486 y(string)g(67)1136 2535 y(structure)i(hierarc)o
+(hical)d(34)1136 2585 y(structure)j(tree)f(83)1136 2635 y(Strunk79)e(117)1136
+2685 y(Strunk79)g(51)1136 2735 y(substitution)h(string)g(91)1136
+2785 y(substitution)g(string)g(94)1136 2835 y(success)i(status)f(90)1032
+2940 y(125)p eop
+%%Page: 126 127
+126 126 bop 177 42 a Fr(supp)q(ort)15 b(F)m(unnelW)m(eb)e(110)177
+91 y(suppress)j(console)e(output)g(69)177 141 y(suppressing)h(EOL)g(mark)o
+(ers)e(77)177 191 y(suppression)i(EOL)g(23)177 241 y(suppression)g(\014le)f
+(49)177 291 y(Sydney)g(19)177 341 y(syn)o(tax)g(command)d(line)j(options)f
+(67)177 391 y(syn)o(tax)h(command)d(line)j(67)177 441 y(syn)o(tax)g(EBNF)h
+(63)177 490 y(syn)o(tax)f(high)f(lev)o(el)h(82)177 540 y(syn)o(tax)g(options)
+g(67)177 590 y(system)g(prin)o(ting)f(55)177 640 y(T)h(option)f(69)177
+690 y(table)h(macro)f(64)177 740 y(table)h(of)f(con)o(ten)o(ts)i(directiv)o
+(e)g(37)177 790 y(table)f(of)f(con)o(ten)o(ts)i(pragma)d(81)177
+840 y(table)i(of)f(con)o(ten)o(ts)i(81)177 889 y(tabs)f(42)177
+939 y(T)m(angle)f(116)177 989 y(tangle)h(65)177 1039 y(tangle)g(88)177
+1089 y(T)m(angling)e(21)177 1139 y(target)j(t)o(yp)q(esetter)h(89)177
+1189 y(termination)c(\014le)i(71)177 1239 y(termination)e(line)i(71)177
+1288 y(terminology)e(63)177 1338 y(testing)i(F)m(unnelW)m(eb)g(105)177
+1388 y(testing)g(regression)i(103)177 1438 y(testing)e(regression)i(47)177
+1488 y(tests)f(directory)g(104)177 1538 y(text)g(editors)f(42)177
+1588 y(text)h(\014les)f(cryptic)h(55)177 1638 y(text)g(free)f(83)177
+1687 y(text)h(sharing)e(58)177 1737 y(text)i(tok)o(ens)f(82)177
+1787 y(T)m(eX)g(13)177 1837 y(T)m(eX)g(18)177 1887 y(T)m(eX)g(22)177
+1937 y(T)m(eX)g(54)177 1987 y(thesis)h(PhD)f(54)177 2037 y(tiger)g(snak)o(e)g
+(19)177 2086 y(time)f(dev)o(elopmen)o(t)g(17)177 2136 y(times)g(dump)g(68)177
+2186 y(title)h(directiv)o(e)g(37)177 2236 y(title)g(pragma)e(82)177
+2286 y(title)i(82)177 2336 y(tok)o(en)g(list)g(dump)e(68)177
+2386 y(tolerate)i(command)e(100)177 2436 y(to)q(ols)i(literate)g(programmi)o
+(ng)d(15)177 2486 y(trace)k(command)c(100)177 2535 y(trace)k(on)f(command)d
+(48)177 2585 y(tracedump)j(options)f(68)177 2635 y(trailing)g(blanks)g(42)177
+2685 y(tree)i(directory)g(102)177 2735 y(tree)g(structure)h(83)177
+2785 y(T)m(rev)o(orro)o(w)e(Andrew)h(13)177 2835 y(tutorial)e(+=)i(26)1136
+42 y(tutorial)e(==)h(26)1136 91 y(tutorial)f(@M)h(24)1136 141
+y(tutorial)f(@Z)h(24)1136 191 y(tutorial)f(in)o(tro)q(duction)g(19)1136
+241 y(tutorial)g(macro)f(facilities)h(22)1136 291 y(tutorial)g(macros)g
+(simple)f(22)1136 341 y(tutorial)h(simple)f(macros)h(22)1136
+391 y(tutorial)g(t)o(yp)q(esetting)i(32)1136 441 y(tutorial)e(15)1136
+490 y(tutorial)g(19)1136 540 y(t)o(w)o(elv)o(e)g(bugs)i(of)e(c)o(hristmas)g
+(29)1136 590 y(t)o(w)o(o)g(main)f(asp)q(ects)j(F)m(unnelW)m(eb)f(21)1136
+640 y(t)o(yp)q(esafe)g(generics)h(61)1136 690 y(t)o(yp)q(eset)g(\014le)f(69)
+1136 740 y(t)o(yp)q(eset)h(option)e(69)1136 790 y(t)o(yp)q(esetter)j
+(directiv)o(e)e(tok)o(ens)h(82)1136 840 y(t)o(yp)q(esetter)h(directiv)o(es)f
+(66)1136 889 y(t)o(yp)q(esetter)h(directiv)o(es)f(81)1136 939
+y(t)o(yp)q(esetter)h(indep)q(endence)g(18)1136 989 y(t)o(yp)q(esetter)g
+(indep)q(endence)g(34)1136 1039 y(t)o(yp)q(esetter)g(indep)q(endence)g(65)
+1136 1089 y(t)o(yp)q(esetter)g(indep)q(endence)g(80)1136 1139
+y(t)o(yp)q(esetter)g(indep)q(enden)o(t)f(34)1136 1189 y(t)o(yp)q(esetter)h
+(pragma)c(80)1136 1239 y(t)o(yp)q(esetter)k(target)e(89)1136
+1288 y(T)o(yp)q(esetting)g(directiv)o(e)h(116)1136 1338 y(t)o(yp)q(esetting)f
+(o)o(v)o(erview)g(32)1136 1388 y(t)o(yp)q(esetting)g(strength)i(46)1136
+1438 y(t)o(yp)q(esetting)e(tutorial)g(32)1136 1488 y(t)o(yp)q(esetting)g(13)
+1136 1538 y(t)o(yp)q(esetting)g(89)1136 1588 y(univ)o(ersities)g(17)1136
+1638 y(Univ)o(ersit)o(y)f(Adelaide)h(59)1136 1687 y(Unix)f(newline)h(75)1136
+1737 y(Unix)f(67)1136 1787 y(unprin)o(table)g(c)o(haracters)j(71)1136
+1837 y(USDOD83)d(117)1136 1887 y(use)h(of)g(memory)d(30)1136
+1937 y(useful)j(commands)d(47)1136 1987 y(userman)i(directory)i(105)1136
+2037 y(uses)g(shell)f(90)1136 2086 y(v)o(ersions)g(F)m(unnelW)m(eb)f(114)1136
+2136 y(v)o(ertical)g(skip)h(81)1136 2186 y(visible)f(pragmas)f(78)1136
+2236 y(vskip)h(directiv)o(e)i(37)1136 2286 y(vskip)e(pragma)f(81)1136
+2336 y(W)h(option)g(69)1136 2386 y(w)o(arning)g(sev)o(erit)o(y)h(65)1136
+2436 y(w)o(arning)f(status)h(90)1136 2486 y(w)o(arran)o(t)o(y)f(112)1136
+2535 y(W)m(ea)o(v)o(e)g(116)1136 2585 y(w)o(ea)o(v)o(e)h(65)1136
+2635 y(w)o(ea)o(v)o(e)g(89)1136 2685 y(W)m(ea)o(ving)e(21)1136
+2735 y(WEB)i(output)g(25)1136 2785 y(WEB)g(21)1136 2835 y(WEB)g(25)1032
+2940 y(126)p eop
+%%Page: 127 128
+127 127 bop 177 42 a Fr(W)m(eb)14 b(9)177 91 y(white)g(p)q(oin)o(ter)g(shark)
+g(19)177 141 y(wholistic)f(debugging)h(53)177 191 y(wholistic)f(debugging)h
+(53)177 241 y(wholistic)f(medicine)g(53)177 291 y(width)h(option)f(69)177
+340 y(width)h(pro)q(duct)h(\014le)e(69)177 390 y(William)o(s)f(Ross)h(1)177
+440 y(w)o(orkstations)h(48)177 490 y(w)o(orkstation)g(90)177
+540 y(write)g(command)d(100)177 589 y(writeu)j(command)e(100)177
+639 y(X)i(option)f(69)1032 2940 y(127)p eop
+%%Trailer
+end
+userdict /end-hook known{end-hook}if
+%%EOF
diff --git a/web/funnelAC/userman/u_manual.sin b/web/funnelAC/userman/u_manual.sin
new file mode 100644
index 0000000000..abee6744ad
--- /dev/null
+++ b/web/funnelAC/userman/u_manual.sin
@@ -0,0 +1,1020 @@
+\indexentry{+= tutorial}{26}
+\indexentry{+=}{85}
+\indexentry{2167A}{51}
+\indexentry{== tutorial}{26}
+\indexentry{==}{85}
+\indexentry{@!}{37}
+\indexentry{@!}{75}
+\indexentry{@"}{29}
+\indexentry{@(}{29}
+\indexentry{@)}{29}
+\indexentry{@+}{20}
+\indexentry{@+}{76}
+\indexentry{@,}{29}
+\indexentry{@-}{23}
+\indexentry{@-}{77}
+\indexentry{@1...}{28}
+\indexentry{@1...}{86}
+\indexentry{@<}{20}
+\indexentry{@=}{20}
+\indexentry{@>}{20}
+\indexentry{@A...}{34}
+\indexentry{@braces}{20}
+\indexentry{@braces}{37}
+\indexentry{@circumflex}{74}
+\indexentry{@dollar}{22}
+\indexentry{@hash}{76}
+\indexentry{@i}{30}
+\indexentry{@i}{77}
+\indexentry{@M tutorial}{24}
+\indexentry{@M}{85}
+\indexentry{@O}{20}
+\indexentry{@O}{22}
+\indexentry{@slash}{37}
+\indexentry{@Z tutorial}{24}
+\indexentry{@Z}{85}
+\indexentry{absent command}{93}
+\indexentry{abstract data type}{55}
+\indexentry{abstraction code}{56}
+\indexentry{abstraction data}{26}
+\indexentry{abstraction set}{59}
+\indexentry{abuse comments}{57}
+\indexentry{access random}{50}
+\indexentry{acknowledgements}{11}
+\indexentry{action execution order}{71}
+\indexentry{Action options}{70}
+\indexentry{actual parameters}{29}
+\indexentry{Ada}{11}
+\indexentry{Ada}{44}
+\indexentry{Ada}{49}
+\indexentry{Ada}{51}
+\indexentry{Ada}{55}
+\indexentry{additive macros}{26}
+\indexentry{additive macro}{26}
+\indexentry{additively defined}{85}
+\indexentry{Adelaide University}{59}
+\indexentry{admin directory}{102}
+\indexentry{administration FunnelWeb}{109}
+\indexentry{ADT}{55}
+\indexentry{alias}{49}
+\indexentry{Analyser}{115}
+\indexentry{analyser}{65}
+\indexentry{analyser}{88}
+\indexentry{analysis static}{88}
+\indexentry{Andrew Trevorrow}{13}
+\indexentry{animal poem}{30}
+\indexentry{annual report}{58}
+\indexentry{anonymous ftp}{101}
+\indexentry{ANSI}{109}
+\indexentry{ANSI}{117}
+\indexentry{answers correct}{102}
+\indexentry{answers directory}{102}
+\indexentry{ANZE}{117}
+\indexentry{ANZE}{19}
+\indexentry{applications FunnelWeb}{53}
+\indexentry{arbitrary characters inserting into text}{74}
+\indexentry{architecture semantic}{64}
+\indexentry{archive ftp}{114}
+\indexentry{archive FunnelWeb}{114}
+\indexentry{argument command line}{67}
+\indexentry{arguments}{67}
+\indexentry{Argument}{115}
+\indexentry{assertion severity}{65}
+\indexentry{assertion status}{90}
+\indexentry{Atrax robustus}{19}
+\indexentry{attributes macro}{85}
+\indexentry{author contacting}{114}
+\indexentry{B option}{68}
+\indexentry{Barry Dwyer}{11}
+\indexentry{Barry Dwyer}{59}
+\indexentry{Barry Humphries}{19}
+\indexentry{BASIC}{57}
+\indexentry{Begg Jeremy}{11}
+\indexentry{binding problems}{57}
+\indexentry{bindings macro}{22}
+\indexentry{blank indentation}{78}
+\indexentry{blank indentation}{78}
+\indexentry{blanks trailing}{42}
+\indexentry{boring organization}{50}
+\indexentry{Brissenden Roger}{11}
+\indexentry{BSI82}{117}
+\indexentry{BSI82}{15}
+\indexentry{BSI82}{18}
+\indexentry{C header}{57}
+\indexentry{C option}{68}
+\indexentry{C preprocessor}{20}
+\indexentry{C preprocessor}{57}
+\indexentry{calls macro}{86}
+\indexentry{calls number}{23}
+\indexentry{camera poem}{30}
+\indexentry{case dependence}{67}
+\indexentry{changing special character}{31}
+\indexentry{characters control}{42}
+\indexentry{characters non-printable}{96}
+\indexentry{characters unprintable}{71}
+\indexentry{checks macro}{88}
+\indexentry{cheer hacker's}{35}
+\indexentry{cheer programmer's}{35}
+\indexentry{code abstraction}{56}
+\indexentry{code explaining}{17}
+\indexentry{code gardening}{53}
+\indexentry{code vs documentation}{32}
+\indexentry{codify command}{93}
+\indexentry{command absent}{93}
+\indexentry{command codify}{93}
+\indexentry{command compare}{93}
+\indexentry{command define}{91}
+\indexentry{command define}{94}
+\indexentry{command diffsummary}{95}
+\indexentry{command diffzero}{95}
+\indexentry{command diff}{94}
+\indexentry{command eneo}{95}
+\indexentry{command execute}{96}
+\indexentry{command exists}{96}
+\indexentry{command fixeols}{96}
+\indexentry{command fw}{97}
+\indexentry{command help}{97}
+\indexentry{command here}{98}
+\indexentry{command interpreter}{47}
+\indexentry{command length}{91}
+\indexentry{command line argument}{67}
+\indexentry{command line interface}{66}
+\indexentry{command line options syntax}{67}
+\indexentry{command line parsing}{66}
+\indexentry{command line processing}{66}
+\indexentry{command line processing}{92}
+\indexentry{command line syntax}{67}
+\indexentry{command options}{92}
+\indexentry{command quit}{98}
+\indexentry{command set}{48}
+\indexentry{command set}{98}
+\indexentry{command shell FunnelWeb}{90}
+\indexentry{command show}{48}
+\indexentry{command show}{98}
+\indexentry{command skipto}{98}
+\indexentry{command status}{99}
+\indexentry{command tolerate}{100}
+\indexentry{command trace on}{48}
+\indexentry{command trace}{100}
+\indexentry{command verb fw}{66}
+\indexentry{command writeu}{100}
+\indexentry{command write}{100}
+\indexentry{commands FunnelWeb}{90}
+\indexentry{commands shell}{93}
+\indexentry{commands useful}{47}
+\indexentry{comments abuse}{57}
+\indexentry{comments eliminating}{57}
+\indexentry{comments FunnelWeb}{75}
+\indexentry{comments}{37}
+\indexentry{commitment FunnelWeb}{109}
+\indexentry{compare command}{93}
+\indexentry{compilers Fortran}{42}
+\indexentry{compiling FunnelWeb}{105}
+\indexentry{complete example}{38}
+\indexentry{conditionals fudging}{44}
+\indexentry{console output suppress}{69}
+\indexentry{constructs section}{83}
+\indexentry{contacting author}{114}
+\indexentry{contents table of}{81}
+\indexentry{context infinite}{68}
+\indexentry{context listing file}{68}
+\indexentry{context}{69}
+\indexentry{control characters inserting into text}{74}
+\indexentry{control characters}{42}
+\indexentry{controllability}{18}
+\indexentry{copyright FunnelWeb}{112}
+\indexentry{copyright notice}{1}
+\indexentry{correct answers}{102}
+\indexentry{cross reference numbering}{89}
+\indexentry{cross referencing}{17}
+\indexentry{cross referencing}{89}
+\indexentry{cryptic text files}{55}
+\indexentry{D option}{49}
+\indexentry{D option}{68}
+\indexentry{dangers FunnelWeb}{50}
+\indexentry{data abstraction}{26}
+\indexentry{David Hulse}{11}
+\indexentry{debugger}{53}
+\indexentry{debugging wholistic}{53}
+\indexentry{default options}{49}
+\indexentry{default options}{92}
+\indexentry{default special character}{72}
+\indexentry{define command}{91}
+\indexentry{define command}{94}
+\indexentry{definition FunnelWeb}{63}
+\indexentry{definition macro}{85}
+\indexentry{definition macro}{87}
+\indexentry{delete output files}{49}
+\indexentry{delete output option}{68}
+\indexentry{delimiting macro parameter}{87}
+\indexentry{dependence case}{67}
+\indexentry{dependencies file}{49}
+\indexentry{development time}{17}
+\indexentry{diagnostics levels of}{65}
+\indexentry{diagnostics}{65}
+\indexentry{dictionary hacker's}{35}
+\indexentry{diff command}{94}
+\indexentry{differences file}{94}
+\indexentry{diffsummary command}{95}
+\indexentry{diffzero command}{95}
+\indexentry{directive emphasis}{85}
+\indexentry{directive literal}{84}
+\indexentry{directive newpage}{37}
+\indexentry{directive table of contents}{37}
+\indexentry{directive title}{37}
+\indexentry{directive vskip}{37}
+\indexentry{directives typesetter}{81}
+\indexentry{directives}{32}
+\indexentry{directives}{83}
+\indexentry{Directive}{115}
+\indexentry{directory admin}{102}
+\indexentry{directory answers}{102}
+\indexentry{directory hackman}{103}
+\indexentry{directory results}{103}
+\indexentry{directory scripts}{103}
+\indexentry{directory sources}{103}
+\indexentry{directory tests}{104}
+\indexentry{directory tree}{102}
+\indexentry{directory userman}{105}
+\indexentry{directory}{70}
+\indexentry{Distribution FunnelWeb}{113}
+\indexentry{document list dump}{68}
+\indexentry{document list}{64}
+\indexentry{documentation duplicate}{51}
+\indexentry{documentation examples}{58}
+\indexentry{Documentation file}{115}
+\indexentry{documentation file}{18}
+\indexentry{documentation FunnelWeb}{110}
+\indexentry{documentation interdependent}{50}
+\indexentry{documentation over}{51}
+\indexentry{documentation pavlov}{51}
+\indexentry{documentation vs code}{32}
+\indexentry{Documentation}{115}
+\indexentry{documentation}{64}
+\indexentry{DOD83}{55}
+\indexentry{Donald Knuth}{11}
+\indexentry{Donald Knuth}{50}
+\indexentry{Donald Knuth}{9}
+\indexentry{dump document list}{68}
+\indexentry{dump global line list}{68}
+\indexentry{dump macro table}{68}
+\indexentry{dump mapped file}{68}
+\indexentry{dump option}{68}
+\indexentry{dump times}{68}
+\indexentry{dump token list}{68}
+\indexentry{duplicate documentation}{51}
+\indexentry{Dwyer Barry}{11}
+\indexentry{Dwyer Barry}{59}
+\indexentry{EBNF syntax}{63}
+\indexentry{editors text}{42}
+\indexentry{Edna Everage}{19}
+\indexentry{efficiency FunnelWeb}{47}
+\indexentry{efficiency notes}{47}
+\indexentry{eliminating comments}{57}
+\indexentry{emphasis construct}{37}
+\indexentry{emphasis directive}{85}
+\indexentry{empty name}{42}
+\indexentry{end-of-line fiddling with}{43}
+\indexentry{eneo command}{95}
+\indexentry{EOL fiddling with}{43}
+\indexentry{EOL markers inserting}{76}
+\indexentry{EOL markers suppressing}{77}
+\indexentry{EOL suppression}{23}
+\indexentry{error severity}{65}
+\indexentry{error status}{90}
+\indexentry{errors shell}{90}
+\indexentry{Everage Edna}{19}
+\indexentry{example applications FunnelWeb}{53}
+\indexentry{example complete}{38}
+\indexentry{example filename inheritance}{70}
+\indexentry{Example FunnelWeb}{38}
+\indexentry{examples documentation}{58}
+\indexentry{executable FunnelWeb}{106}
+\indexentry{execute command}{96}
+\indexentry{execute script option}{69}
+\indexentry{execution phases}{64}
+\indexentry{exists command}{96}
+\indexentry{expansion macro}{30}
+\indexentry{expansion macro}{47}
+\indexentry{expansion macro}{87}
+\indexentry{explaining code}{17}
+\indexentry{expressions macro}{86}
+\indexentry{expression}{85}
+\indexentry{extension}{70}
+\indexentry{F option}{68}
+\indexentry{fatal severity}{65}
+\indexentry{fatal status}{90}
+\indexentry{fiddling with end-of-line}{43}
+\indexentry{fiddling with EOL}{43}
+\indexentry{fields filename}{70}
+\indexentry{file dependencies}{49}
+\indexentry{file differences}{94}
+\indexentry{file include}{69}
+\indexentry{file journal}{69}
+\indexentry{file listing}{69}
+\indexentry{file suppression}{49}
+\indexentry{file termination}{71}
+\indexentry{file typeset}{69}
+\indexentry{filename fields}{70}
+\indexentry{filename inheritance example}{70}
+\indexentry{filename inheritance}{70}
+\indexentry{files header}{57}
+\indexentry{files include}{30}
+\indexentry{files include}{77}
+\indexentry{files input}{47}
+\indexentry{fixeols command}{96}
+\indexentry{font size}{46}
+\indexentry{formal parameter lists}{86}
+\indexentry{formal parameters}{28}
+\indexentry{formal parameters}{28}
+\indexentry{formal parameters}{87}
+\indexentry{Fortran compilers}{42}
+\indexentry{Free text}{115}
+\indexentry{free text}{32}
+\indexentry{Free text}{83}
+\indexentry{free text}{83}
+\indexentry{freestanding typesetter directives}{83}
+\indexentry{freestanding}{81}
+\indexentry{ftp anonymous}{101}
+\indexentry{ftp archive}{114}
+\indexentry{fudging conditionals}{44}
+\indexentry{fudging generics}{59}
+\indexentry{functions small}{56}
+\indexentry{Funnel-web spider}{19}
+\indexentry{FunnelWeb administration}{109}
+\indexentry{FunnelWeb applications}{53}
+\indexentry{FunnelWeb archive}{114}
+\indexentry{FunnelWeb command shell}{90}
+\indexentry{FunnelWeb command shell}{90}
+\indexentry{FunnelWeb commands}{90}
+\indexentry{FunnelWeb comments}{75}
+\indexentry{FunnelWeb commitment}{109}
+\indexentry{FunnelWeb compiling}{105}
+\indexentry{FunnelWeb copyright}{112}
+\indexentry{FunnelWeb dangers}{50}
+\indexentry{FunnelWeb definition}{63}
+\indexentry{FunnelWeb Distribution}{113}
+\indexentry{FunnelWeb documentation}{110}
+\indexentry{FunnelWeb efficiency}{47}
+\indexentry{FunnelWeb example applications}{53}
+\indexentry{FunnelWeb Example}{38}
+\indexentry{FunnelWeb executable}{106}
+\indexentry{FunnelWeb file}{115}
+\indexentry{FunnelWeb file}{64}
+\indexentry{FunnelWeb hints}{41}
+\indexentry{FunnelWeb initialization}{70}
+\indexentry{FunnelWeb installation}{101}
+\indexentry{FunnelWeb installing}{106}
+\indexentry{FunnelWeb invoking}{66}
+\indexentry{FunnelWeb language}{115}
+\indexentry{FunnelWeb license}{112}
+\indexentry{FunnelWeb martinet}{42}
+\indexentry{FunnelWeb name}{19}
+\indexentry{FunnelWeb obtaining}{101}
+\indexentry{FunnelWeb overview}{18}
+\indexentry{FunnelWeb overview}{64}
+\indexentry{FunnelWeb pitfalls}{50}
+\indexentry{FunnelWeb program}{65}
+\indexentry{FunnelWeb proper}{115}
+\indexentry{FunnelWeb proper}{48}
+\indexentry{FunnelWeb proper}{65}
+\indexentry{FunnelWeb registration}{110}
+\indexentry{FunnelWeb rules}{42}
+\indexentry{FunnelWeb running}{66}
+\indexentry{FunnelWeb shell}{90}
+\indexentry{FunnelWeb startup}{70}
+\indexentry{FunnelWeb support}{110}
+\indexentry{FunnelWeb testing}{105}
+\indexentry{FunnelWeb two main aspects}{21}
+\indexentry{FunnelWeb versions}{114}
+\indexentry{FunnelWeb}{115}
+\indexentry{fw command verb}{66}
+\indexentry{fw command}{97}
+\indexentry{fwinit.fws}{49}
+\indexentry{fwinit.fws}{71}
+\indexentry{FW}{115}
+\indexentry{gardening code}{53}
+\indexentry{generics fudging}{59}
+\indexentry{generics typesafe}{61}
+\indexentry{global line list dump}{68}
+\indexentry{glossary}{115}
+\indexentry{GNU license}{112}
+\indexentry{GNU license}{18}
+\indexentry{GNU license}{9}
+\indexentry{good old days}{57}
+\indexentry{Gries81}{117}
+\indexentry{Gries81}{51}
+\indexentry{H option}{68}
+\indexentry{hacker's cheer}{35}
+\indexentry{hacker's dictionary}{35}
+\indexentry{Hackett Simon}{11}
+\indexentry{hackman directory}{103}
+\indexentry{header C}{57}
+\indexentry{header file postscript}{54}
+\indexentry{header files}{57}
+\indexentry{header page}{37}
+\indexentry{headings section}{34}
+\indexentry{headings strength}{46}
+\indexentry{Hello Northern Hemisphere Program}{21}
+\indexentry{hello world document}{20}
+\indexentry{help command}{97}
+\indexentry{help option}{68}
+\indexentry{here command}{98}
+\indexentry{hierarchical structure}{34}
+\indexentry{high level syntax}{82}
+\indexentry{hints FunnelWeb}{41}
+\indexentry{Hulse David}{11}
+\indexentry{Humphries Barry}{19}
+\indexentry{Humphries91}{117}
+\indexentry{Humphries91}{19}
+\indexentry{hypertext}{15}
+\indexentry{I option}{69}
+\indexentry{identifiers macro}{41}
+\indexentry{include file option}{69}
+\indexentry{include files recursive}{31}
+\indexentry{include files}{30}
+\indexentry{include files}{77}
+\indexentry{include files}{77}
+\indexentry{Include file}{115}
+\indexentry{include file}{69}
+\indexentry{indentation blank}{78}
+\indexentry{indentation macro calls}{25}
+\indexentry{indentation macro expansion}{78}
+\indexentry{indentation none}{78}
+\indexentry{independence language}{18}
+\indexentry{independence typesetter}{18}
+\indexentry{independence typesetter}{34}
+\indexentry{independence typesetter}{65}
+\indexentry{independence typesetter}{80}
+\indexentry{infinite context}{68}
+\indexentry{inheritance filename}{70}
+\indexentry{inheritance section name}{35}
+\indexentry{initialization FunnelWeb}{70}
+\indexentry{initialization script}{49}
+\indexentry{initialization script}{71}
+\indexentry{inline typesetter directives}{83}
+\indexentry{inline}{81}
+\indexentry{input file option}{68}
+\indexentry{input files}{47}
+\indexentry{Input file}{115}
+\indexentry{input file}{18}
+\indexentry{input file}{64}
+\indexentry{input file}{77}
+\indexentry{input line length maximum}{79}
+\indexentry{input line length pragma}{79}
+\indexentry{input line length}{42}
+\indexentry{input line length}{79}
+\indexentry{inserting EOL markers}{76}
+\indexentry{inserting into text arbitrary characters}{74}
+\indexentry{inserting into text control characters}{74}
+\indexentry{inserting into text special character}{74}
+\indexentry{installation FunnelWeb}{101}
+\indexentry{installation problems}{107}
+\indexentry{installing FunnelWeb}{106}
+\indexentry{interactive mode}{47}
+\indexentry{interactive option}{69}
+\indexentry{interdependent documentation}{50}
+\indexentry{interface command line}{66}
+\indexentry{interpreter command}{47}
+\indexentry{introduction tutorial}{19}
+\indexentry{invisible pragmas}{78}
+\indexentry{invocation number}{23}
+\indexentry{invocations number}{42}
+\indexentry{invoking FunnelWeb}{20}
+\indexentry{invoking FunnelWeb}{66}
+\indexentry{J option}{69}
+\indexentry{Jeremy Begg}{11}
+\indexentry{journal file option}{69}
+\indexentry{Journal file}{115}
+\indexentry{journal file}{64}
+\indexentry{journal file}{69}
+\indexentry{K option}{69}
+\indexentry{Kernighan88}{117}
+\indexentry{Kernighan88}{65}
+\indexentry{keyboard mode}{47}
+\indexentry{keyboard option}{69}
+\indexentry{Knuth Donald}{11}
+\indexentry{Knuth Donald}{50}
+\indexentry{Knuth Donald}{9}
+\indexentry{Knuth83}{117}
+\indexentry{Knuth83}{17}
+\indexentry{Knuth83}{25}
+\indexentry{Knuth83}{25}
+\indexentry{Knuth83}{9}
+\indexentry{Knuth84}{117}
+\indexentry{Knuth84}{117}
+\indexentry{Knuth84}{13}
+\indexentry{Knuth84}{17}
+\indexentry{Knuth84}{18}
+\indexentry{L option}{69}
+\indexentry{Lamport86}{117}
+\indexentry{Lamport86}{13}
+\indexentry{language independence}{18}
+\indexentry{languages multiple}{55}
+\indexentry{laser printer}{55}
+\indexentry{LaTeX}{13}
+\indexentry{LaTeX}{84}
+\indexentry{layout program}{22}
+\indexentry{layout program}{28}
+\indexentry{length command}{91}
+\indexentry{length input line}{42}
+\indexentry{length line}{71}
+\indexentry{length output line}{42}
+\indexentry{letter}{67}
+\indexentry{levels of diagnostics}{65}
+\indexentry{libraries macro}{31}
+\indexentry{license FunnelWeb}{112}
+\indexentry{license GNU}{112}
+\indexentry{license GNU}{18}
+\indexentry{license GNU}{9}
+\indexentry{line length input}{79}
+\indexentry{line length}{71}
+\indexentry{line termination}{71}
+\indexentry{list document}{64}
+\indexentry{list options}{68}
+\indexentry{list shell commands}{93}
+\indexentry{listing file context}{68}
+\indexentry{listing file option}{69}
+\indexentry{Listing file}{115}
+\indexentry{listing file}{64}
+\indexentry{listing file}{69}
+\indexentry{literal construct}{37}
+\indexentry{literal directive}{84}
+\indexentry{literate programming tools}{15}
+\indexentry{literate programming, facilities}{15}
+\indexentry{literate programming, most significant benefit}{17}
+\indexentry{literate programming}{15}
+\indexentry{literate programming}{15}
+\indexentry{literate programming}{50}
+\indexentry{MacDraw}{54}
+\indexentry{Macintosh}{13}
+\indexentry{Macintosh}{54}
+\indexentry{macro attributes}{85}
+\indexentry{macro bindings}{22}
+\indexentry{macro body}{85}
+\indexentry{macro calls indentation}{25}
+\indexentry{macro calls}{86}
+\indexentry{macro checks}{88}
+\indexentry{macro definitions}{32}
+\indexentry{Macro definition}{116}
+\indexentry{macro definition}{85}
+\indexentry{macro definition}{87}
+\indexentry{macro expansion indentation}{78}
+\indexentry{macro expansion}{30}
+\indexentry{macro expansion}{47}
+\indexentry{macro expansion}{87}
+\indexentry{macro expressions}{86}
+\indexentry{macro facilities tutorial}{22}
+\indexentry{macro identifiers}{41}
+\indexentry{macro libraries}{31}
+\indexentry{macro names}{41}
+\indexentry{macro names}{86}
+\indexentry{macro name}{85}
+\indexentry{macro parameter delimiting}{87}
+\indexentry{macro recursion}{43}
+\indexentry{macro recursion}{88}
+\indexentry{macro table dump}{68}
+\indexentry{macro table}{64}
+\indexentry{macros additive}{26}
+\indexentry{macros parameterized}{28}
+\indexentry{macros simple tutorial}{22}
+\indexentry{macros static}{87}
+\indexentry{Macro}{115}
+\indexentry{magic trick}{15}
+\indexentry{maintenance programmer}{50}
+\indexentry{make utility}{49}
+\indexentry{manuals printing}{107}
+\indexentry{mapped file dump}{68}
+\indexentry{Mapper}{116}
+\indexentry{mapper}{71}
+\indexentry{martinet FunnelWeb}{42}
+\indexentry{maximum input line length}{79}
+\indexentry{maximum output file line length pragma}{79}
+\indexentry{maximum output file line length}{79}
+\indexentry{maximum product file line length pragma}{79}
+\indexentry{maximum product file line length}{79}
+\indexentry{medicine wholistic}{53}
+\indexentry{memory use of}{30}
+\indexentry{memory}{47}
+\indexentry{MIL-STD-2167A}{51}
+\indexentry{monster file postscript}{54}
+\indexentry{multiple languages}{55}
+\indexentry{name empty}{42}
+\indexentry{name FunnelWeb}{19}
+\indexentry{name section}{34}
+\indexentry{name section}{84}
+\indexentry{names macro}{41}
+\indexentry{names macro}{86}
+\indexentry{names quick}{42}
+\indexentry{names quick}{76}
+\indexentry{names section}{86}
+\indexentry{names}{86}
+\indexentry{name}{70}
+\indexentry{new page pragma}{81}
+\indexentry{new page}{81}
+\indexentry{newpage directive}{37}
+\indexentry{no indentation}{78}
+\indexentry{non-determinism}{68}
+\indexentry{non-printable characters}{96}
+\indexentry{none indentation}{78}
+\indexentry{notation}{63}
+\indexentry{notes efficiency}{47}
+\indexentry{notice copyright}{1}
+\indexentry{novels}{50}
+\indexentry{number calls}{23}
+\indexentry{number invocations}{42}
+\indexentry{number invocation}{23}
+\indexentry{number of times called}{23}
+\indexentry{numbering cross reference}{89}
+\indexentry{numbering section}{89}
+\indexentry{object code}{26}
+\indexentry{obtaining FunnelWeb}{101}
+\indexentry{open systems}{55}
+\indexentry{option B}{68}
+\indexentry{option C}{68}
+\indexentry{option delete output}{68}
+\indexentry{option dump}{68}
+\indexentry{option D}{49}
+\indexentry{option D}{68}
+\indexentry{option execute script}{69}
+\indexentry{option F}{68}
+\indexentry{option help}{68}
+\indexentry{option H}{68}
+\indexentry{option include file}{69}
+\indexentry{option input file}{68}
+\indexentry{option interactive}{69}
+\indexentry{option I}{69}
+\indexentry{option journal file}{69}
+\indexentry{option J}{69}
+\indexentry{option keyboard}{69}
+\indexentry{option K}{69}
+\indexentry{option listing file}{69}
+\indexentry{option L}{69}
+\indexentry{option quiet}{69}
+\indexentry{option Q}{69}
+\indexentry{option screen}{69}
+\indexentry{option S}{69}
+\indexentry{option typeset}{69}
+\indexentry{option T}{69}
+\indexentry{option width}{69}
+\indexentry{option W}{69}
+\indexentry{option X}{69}
+\indexentry{options command}{92}
+\indexentry{options default}{49}
+\indexentry{options default}{92}
+\indexentry{options list}{68}
+\indexentry{options setting defaults}{49}
+\indexentry{options syntax}{67}
+\indexentry{options tracedump}{68}
+\indexentry{options}{67}
+\indexentry{options}{68}
+\indexentry{Option}{116}
+\indexentry{order action execution}{71}
+\indexentry{order program}{22}
+\indexentry{ordering program}{15}
+\indexentry{Ordinary options}{70}
+\indexentry{organization boring}{50}
+\indexentry{organization spaghetti}{50}
+\indexentry{output file line length maximum}{79}
+\indexentry{output files delete}{49}
+\indexentry{output files}{18}
+\indexentry{output files}{64}
+\indexentry{Output file}{116}
+\indexentry{output line length}{42}
+\indexentry{output WEB}{25}
+\indexentry{over documentation}{51}
+\indexentry{overhead procedure call}{57}
+\indexentry{overview FunnelWeb}{18}
+\indexentry{overview FunnelWeb}{64}
+\indexentry{overview typesetting}{32}
+\indexentry{OzTeX}{13}
+\indexentry{package}{55}
+\indexentry{parameter list, absent}{29}
+\indexentry{parameter lists formal}{86}
+\indexentry{parameterized macros}{28}
+\indexentry{parameters actual}{29}
+\indexentry{parameters formal}{28}
+\indexentry{parameters formal}{28}
+\indexentry{parameters formal}{87}
+\indexentry{Parser}{116}
+\indexentry{parser}{64}
+\indexentry{parser}{82}
+\indexentry{parsing command line}{66}
+\indexentry{Pascal}{15}
+\indexentry{Pascal}{25}
+\indexentry{Pascal}{26}
+\indexentry{Pascal}{57}
+\indexentry{Pascal}{59}
+\indexentry{Pat Scannel}{29}
+\indexentry{pavlov documentation}{51}
+\indexentry{phases execution}{64}
+\indexentry{phases}{64}
+\indexentry{PhD thesis}{54}
+\indexentry{pitfalls FunnelWeb}{50}
+\indexentry{poem animal}{30}
+\indexentry{poem camera}{30}
+\indexentry{portability}{18}
+\indexentry{postscript header file}{54}
+\indexentry{postscript monster file}{54}
+\indexentry{PostScript}{54}
+\indexentry{postscript}{57}
+\indexentry{pragma input line length}{79}
+\indexentry{pragma maximum output file line length}{79}
+\indexentry{pragma maximum product file line length}{79}
+\indexentry{pragma new page}{81}
+\indexentry{pragma table of contents}{81}
+\indexentry{pragma title}{82}
+\indexentry{pragma typesetter}{80}
+\indexentry{pragma vskip}{81}
+\indexentry{pragmas invisible}{78}
+\indexentry{pragmas visible}{78}
+\indexentry{pragmas}{78}
+\indexentry{Pragma}{116}
+\indexentry{pragma}{25}
+\indexentry{pragma}{78}
+\indexentry{preface}{9}
+\indexentry{preprocessor C}{20}
+\indexentry{preprocessor C}{57}
+\indexentry{presentation notes}{13}
+\indexentry{Printed documentation}{116}
+\indexentry{printer laser}{55}
+\indexentry{printing manuals}{107}
+\indexentry{printing system}{55}
+\indexentry{problems binding}{57}
+\indexentry{problems installation}{107}
+\indexentry{procedure call overhead}{57}
+\indexentry{processing command line}{66}
+\indexentry{processing command line}{92}
+\indexentry{product file line length maximum}{79}
+\indexentry{product file width}{69}
+\indexentry{product files}{18}
+\indexentry{product files}{64}
+\indexentry{Product file}{116}
+\indexentry{production tool}{19}
+\indexentry{program layout}{22}
+\indexentry{program layout}{28}
+\indexentry{program ordering}{15}
+\indexentry{program order}{22}
+\indexentry{programmer maintenance}{50}
+\indexentry{programmer's cheer}{35}
+\indexentry{programming literate}{50}
+\indexentry{Q option}{69}
+\indexentry{quick names}{42}
+\indexentry{quick names}{76}
+\indexentry{quick name}{42}
+\indexentry{quick name}{76}
+\indexentry{quiet option}{69}
+\indexentry{quit command}{98}
+\indexentry{random access}{50}
+\indexentry{rec.humor.funny}{29}
+\indexentry{recursion macro}{43}
+\indexentry{recursion macro}{88}
+\indexentry{recursive include files}{31}
+\indexentry{references}{117}
+\indexentry{referencing cross}{89}
+\indexentry{registration FunnelWeb}{110}
+\indexentry{regression testing}{103}
+\indexentry{regression testing}{47}
+\indexentry{reliability}{18}
+\indexentry{REM statement}{57}
+\indexentry{report annual}{58}
+\indexentry{results directory}{103}
+\indexentry{return status}{65}
+\indexentry{Roger Brissenden}{11}
+\indexentry{Rosovsky90}{117}
+\indexentry{Rosovsky90}{17}
+\indexentry{Ross Williams}{1}
+\indexentry{rule simple}{20}
+\indexentry{rules FunnelWeb}{42}
+\indexentry{running FunnelWeb}{66}
+\indexentry{S option}{69}
+\indexentry{Scannel Pat}{29}
+\indexentry{Scanner}{116}
+\indexentry{scanner}{64}
+\indexentry{scanner}{71}
+\indexentry{screen option}{69}
+\indexentry{script initialization}{49}
+\indexentry{script initialization}{71}
+\indexentry{script startup}{49}
+\indexentry{scripts directory}{103}
+\indexentry{Script}{116}
+\indexentry{section constructs}{83}
+\indexentry{section headings}{34}
+\indexentry{section name inheritance}{35}
+\indexentry{section names}{86}
+\indexentry{section name}{34}
+\indexentry{section name}{84}
+\indexentry{section numbering}{89}
+\indexentry{section strength}{46}
+\indexentry{semantic architecture}{64}
+\indexentry{sequences special}{72}
+\indexentry{set abstraction}{59}
+\indexentry{set command}{48}
+\indexentry{set command}{98}
+\indexentry{setting defaults options}{49}
+\indexentry{setting special character}{74}
+\indexentry{severe severity}{65}
+\indexentry{severe status}{90}
+\indexentry{severity assertion}{65}
+\indexentry{severity error}{65}
+\indexentry{severity fatal}{65}
+\indexentry{severity severe}{65}
+\indexentry{severity warning}{65}
+\indexentry{severity}{65}
+\indexentry{sharing information}{56}
+\indexentry{sharing text}{58}
+\indexentry{shark white pointer}{19}
+\indexentry{shell commands list}{93}
+\indexentry{shell commands}{93}
+\indexentry{shell errors}{90}
+\indexentry{shell FunnelWeb}{90}
+\indexentry{shell uses}{90}
+\indexentry{Shell}{116}
+\indexentry{shooting}{31}
+\indexentry{show command}{48}
+\indexentry{show command}{98}
+\indexentry{sign}{67}
+\indexentry{Simon Hackett}{11}
+\indexentry{simple macros tutorial}{22}
+\indexentry{simple rule}{20}
+\indexentry{simple sequence}{72}
+\indexentry{simplicity}{18}
+\indexentry{size font}{46}
+\indexentry{skip vertical}{81}
+\indexentry{skipto command}{98}
+\indexentry{small functions}{56}
+\indexentry{Smith91}{117}
+\indexentry{Smith91}{17}
+\indexentry{snake tiger}{19}
+\indexentry{song}{29}
+\indexentry{sources directory}{103}
+\indexentry{spacing}{43}
+\indexentry{spaghetti organization}{50}
+\indexentry{special character changing}{31}
+\indexentry{special character default}{72}
+\indexentry{special character inserting into text}{74}
+\indexentry{special character setting}{74}
+\indexentry{Special character}{116}
+\indexentry{special character}{20}
+\indexentry{special character}{72}
+\indexentry{special sequences}{72}
+\indexentry{Special sequence}{116}
+\indexentry{special sequence}{20}
+\indexentry{special sequence}{72}
+\indexentry{special tokens}{82}
+\indexentry{speed}{47}
+\indexentry{spider Funnel-web}{19}
+\indexentry{startup FunnelWeb}{70}
+\indexentry{startup script}{49}
+\indexentry{statement REM}{57}
+\indexentry{static analysis}{88}
+\indexentry{static macros}{87}
+\indexentry{status assertion}{90}
+\indexentry{status command}{99}
+\indexentry{status error}{90}
+\indexentry{status fatal}{90}
+\indexentry{status return}{65}
+\indexentry{status severe}{90}
+\indexentry{status success}{90}
+\indexentry{status warning}{90}
+\indexentry{stream of consciousness}{50}
+\indexentry{strength headings}{46}
+\indexentry{strength section}{46}
+\indexentry{strength typesetting}{46}
+\indexentry{string substitution}{91}
+\indexentry{string substitution}{94}
+\indexentry{string}{67}
+\indexentry{structure hierarchical}{34}
+\indexentry{structure tree}{83}
+\indexentry{Strunk79}{117}
+\indexentry{Strunk79}{51}
+\indexentry{substitution string}{91}
+\indexentry{substitution string}{94}
+\indexentry{success status}{90}
+\indexentry{support FunnelWeb}{110}
+\indexentry{suppress console output}{69}
+\indexentry{suppressing EOL markers}{77}
+\indexentry{suppression EOL}{23}
+\indexentry{suppression file}{49}
+\indexentry{Sydney}{19}
+\indexentry{syntax command line options}{67}
+\indexentry{syntax command line}{67}
+\indexentry{syntax EBNF}{63}
+\indexentry{syntax high level}{82}
+\indexentry{syntax options}{67}
+\indexentry{system printing}{55}
+\indexentry{T option}{69}
+\indexentry{table macro}{64}
+\indexentry{table of contents directive}{37}
+\indexentry{table of contents pragma}{81}
+\indexentry{table of contents}{81}
+\indexentry{tabs}{42}
+\indexentry{Tangle}{116}
+\indexentry{tangle}{65}
+\indexentry{tangle}{88}
+\indexentry{Tangling}{21}
+\indexentry{target typesetter}{89}
+\indexentry{termination file}{71}
+\indexentry{termination line}{71}
+\indexentry{terminology}{63}
+\indexentry{testing FunnelWeb}{105}
+\indexentry{testing regression}{103}
+\indexentry{testing regression}{47}
+\indexentry{tests directory}{104}
+\indexentry{text editors}{42}
+\indexentry{text files cryptic}{55}
+\indexentry{text free}{83}
+\indexentry{text sharing}{58}
+\indexentry{text tokens}{82}
+\indexentry{TeX}{13}
+\indexentry{TeX}{18}
+\indexentry{TeX}{22}
+\indexentry{TeX}{54}
+\indexentry{thesis PhD}{54}
+\indexentry{tiger snake}{19}
+\indexentry{time development}{17}
+\indexentry{times dump}{68}
+\indexentry{title directive}{37}
+\indexentry{title pragma}{82}
+\indexentry{title}{82}
+\indexentry{token list dump}{68}
+\indexentry{tolerate command}{100}
+\indexentry{tools literate programming}{15}
+\indexentry{trace command}{100}
+\indexentry{trace on command}{48}
+\indexentry{tracedump options}{68}
+\indexentry{trailing blanks}{42}
+\indexentry{tree directory}{102}
+\indexentry{tree structure}{83}
+\indexentry{Trevorrow Andrew}{13}
+\indexentry{tutorial +=}{26}
+\indexentry{tutorial ==}{26}
+\indexentry{tutorial @M}{24}
+\indexentry{tutorial @Z}{24}
+\indexentry{tutorial introduction}{19}
+\indexentry{tutorial macro facilities}{22}
+\indexentry{tutorial macros simple}{22}
+\indexentry{tutorial simple macros}{22}
+\indexentry{tutorial typesetting}{32}
+\indexentry{tutorial}{15}
+\indexentry{tutorial}{19}
+\indexentry{twelve bugs of christmas}{29}
+\indexentry{two main aspects FunnelWeb}{21}
+\indexentry{typesafe generics}{61}
+\indexentry{typeset file}{69}
+\indexentry{typeset option}{69}
+\indexentry{typesetter directive tokens}{82}
+\indexentry{typesetter directives}{66}
+\indexentry{typesetter directives}{81}
+\indexentry{typesetter independence}{18}
+\indexentry{typesetter independence}{34}
+\indexentry{typesetter independence}{65}
+\indexentry{typesetter independence}{80}
+\indexentry{typesetter independent}{34}
+\indexentry{typesetter pragma}{80}
+\indexentry{typesetter target}{89}
+\indexentry{Typesetting directive}{116}
+\indexentry{typesetting overview}{32}
+\indexentry{typesetting strength}{46}
+\indexentry{typesetting tutorial}{32}
+\indexentry{typesetting}{13}
+\indexentry{typesetting}{89}
+\indexentry{universities}{17}
+\indexentry{University Adelaide}{59}
+\indexentry{Unix newline}{75}
+\indexentry{Unix}{67}
+\indexentry{unprintable characters}{71}
+\indexentry{USDOD83}{117}
+\indexentry{use of memory}{30}
+\indexentry{useful commands}{47}
+\indexentry{userman directory}{105}
+\indexentry{uses shell}{90}
+\indexentry{versions FunnelWeb}{114}
+\indexentry{vertical skip}{81}
+\indexentry{visible pragmas}{78}
+\indexentry{vskip directive}{37}
+\indexentry{vskip pragma}{81}
+\indexentry{W option}{69}
+\indexentry{warning severity}{65}
+\indexentry{warning status}{90}
+\indexentry{warranty}{112}
+\indexentry{Weave}{116}
+\indexentry{weave}{65}
+\indexentry{weave}{89}
+\indexentry{Weaving}{21}
+\indexentry{WEB output}{25}
+\indexentry{WEB}{21}
+\indexentry{WEB}{25}
+\indexentry{Web}{9}
+\indexentry{white pointer shark}{19}
+\indexentry{wholistic debugging}{53}
+\indexentry{wholistic debugging}{53}
+\indexentry{wholistic medicine}{53}
+\indexentry{width option}{69}
+\indexentry{width product file}{69}
+\indexentry{Williams Ross}{1}
+\indexentry{workstations}{48}
+\indexentry{workstation}{90}
+\indexentry{write command}{100}
+\indexentry{writeu command}{100}
+\indexentry{X option}{69}
diff --git a/web/funnelAC/userman/u_manual.tex b/web/funnelAC/userman/u_manual.tex
new file mode 100644
index 0000000000..41d06b00dc
--- /dev/null
+++ b/web/funnelAC/userman/u_manual.tex
@@ -0,0 +1,290 @@
+%==============================================================================%
+% FUNNELWEB USER'S MANUAL %
+%==============================================================================%
+%
+% Summary
+% -------
+% This is the main .tex file of the FunnelWeb User's Manual.
+%
+% For a list of the other files that contribute to this document,
+% see the list of files given in \input lines at the end of this file.
+%
+% See the TeX comments below to find out how to typeset this document.
+%
+%
+% Copyright
+% ---------
+% Copyright (C) 1992 Ross N. Williams.
+%
+% Permission is granted to make and distribute verbatim copies of this manual
+% provided that the copyright notice and this permission notice are preserved
+% on all copies.
+%
+%
+% Version
+% -------
+% Date : May 1992.
+% Version : 1.0.
+%
+%
+% Author
+% ------
+% Name : Ross Williams.
+% Email : ross@spam.adelaide.edu.au
+% Snail : 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
+%
+%
+% How to Typeset This Document
+% ----------------------------
+% This document is written in a format suitable for processing by the LaTeX
+% typesetting system which can be found on many machines around the world.
+% The document is an entirely self contained LaTeX document. To assist in
+% the electronic distribution of this document, all diagrams have been
+% constructing using ASCII text from within LaTeX. This means that all you
+% need to print this document is a LaTeX typesetting system.
+%
+% To print this document using LaTeX, give a command sequence that looks
+% something like this:
+%
+% latex manual
+% latex manual
+% sort -f <manual.idx >manual.sin
+% % Start here if manual.aux, manual.toc, and manual.sin already exist.
+% latex manual
+% print manual
+%
+% The commands must be given three times so as to allow the cross
+% referencing information to be correctly assembled.
+% The "sort" command should perform a case insensitive sort of the lines of
+% its input, but should not alter the lines it is sorting. In the example
+% about, the "-f" option specifies that the sort should be case insensitive.
+% The "print" command should print the .dvi file generated by LaTeX.
+% The details of the typesetting sequence above may vary on your computer
+% system.
+%
+%=============================================================================%
+
+
+% Basic Document Style
+% --------------------
+% The default font size is 10pt which is what I want.
+% titlepage - Instructs LaTeX to produce a title page at the front.
+% book - Use the "book" built in format.
+\documentstyle[titlepage]{book}
+
+% The following pagestyle command instructs LaTeX to set each page with just
+% a page number at the middle of the bottom of each page.
+\pagestyle{plain}
+
+% By default, the "book" style sets even and odd pages differently on the
+% assumption that the result is to be used in a two-sided printing process.
+% However, most people printing this will print it single sided.
+% To suppress double sided mode, we need to give the \onecolumn command.
+\onecolumn
+
+
+% Page Size and Position
+% ----------------------
+% The following sets the size of the text box and its position on the page.
+% It works OK on A4 paper. I suppose I should test it on American paper too.
+\textwidth 15cm
+\textheight 24cm
+\topmargin 0cm
+\oddsidemargin 1.5cm
+\evensidemargin 1.5cm
+\headheight 0cm
+\headsep 0cm
+
+
+% Table of Contents
+% -----------------
+% Specify that all headings be numbered and appear in the Table of Contents.
+\setcounter{secnumdepth}{100}
+\setcounter{tocdepth}{100}
+
+% LaTeX lets you create an unnumbered chapter, but it doesn't put it in
+% the table of contents. So we have to do it manually.
+\def\pseudochapter#1{%
+\chapter*{#1}
+\addcontentsline{toc}{chapter}{#1}
+}
+
+% Paragraph Separation and Indentation
+% ------------------------------------
+% The default LaTeX format is to have paragraphs jammed up against each other
+% with indentation of text on the first line of each paragraph used to
+% highlight the start of each paragraph. I prefer to identify paragraphs
+% by separating them with space and eliminating the indentation.
+\parskip \medskipamount
+\parindent 0pt
+
+
+% Quick Style Macros
+% ------------------
+% Use of the following macros is much neater and safer than opening a group
+% and setting a mode (e.g. {\bf sloth}) as these macros will cause TeX to
+% scream if they span more than one paragraph whereas the group method
+% can cause half the document to be set in a funny mode.
+% Other little macros here serve the same neatening normalizing purposes.
+\def\i#1{{\it #1}} % Italics.
+\def\b#1{{\bf #1}} % Bold.
+\def\p#1{{\tt #1}} % Program text.
+\def\sq#1{`#1'} % Single quotes.
+\def\dq#1{``#1''} % Double quotes.
+\def\dqp#1{\dq{\p{#1}}} % Double quoted program text.
+\def\fix#1{\footnote{$\bullet$ #1}} % Fix it up footnote.
+\def\softfix#1{} % Marks opportunity for improvement.
+\def\eg{e.g.~} % Spacing regulated "e.g.".
+\def\ie{i.e.~} % Spacing regulated "i.e.".
+\def\til{\char`\~} % For tilde ("~") character.
+\def\circumflex{\char`\^} % Circumflex.
+\def\bs{{\tt\char`\\}} % Backslash.
+
+% Point Making
+% ------------
+% LaTeX provides some useful environment for listing points. However, it does
+% not seem to provide what I want which is a paragraph of text led in by
+% a label set in bold.
+\def\thing#1{{\bf #1}}
+\def\firstthing#1{\thing{#1}}
+\def\narrowthing#1#2{{%From defintion of \narrower
+\advance\leftskip1cm%
+\advance\rightskip1cm%
+{\bf #1} #2\vskip0pt}}
+\def\narrowtext#1{{%From defintion of \narrower
+\advance\leftskip1cm%
+\advance\rightskip1cm%
+#1\vskip0pt}}
+\def\summary{\b{Summary:}\ }
+
+% Invisible Annotations
+% ---------------------
+% Sometimes it is convenient to be able to annotate the LaTeX code without
+% causing text to appear in the document.
+% Here, the \checked{} macro can be placed next to any quotation or
+% fact, or other externally dependent material that has to be checked
+% before publication. The \note{} macro can be used to add a note.
+% Both macros are safer than "%" in a paragraph where the text may be
+% continually being rearranged across lines.
+\def\checked#1{}
+\def\note#1{}
+
+
+% Wide Verbatim Text
+% ------------------
+% This document was originally set in 12pt and the result was that many of
+% the verbatim examples wouldn't fit. To solve this, I created two macros
+% to reduce and increase the size of the text, and wrapped the longer
+% verbatim texts in calls to the macros. Later, the document was reset in
+% 10pt eliminating the original problem, so I redefined the macros to empty.
+%\def\beginsmall{\scriptsize}
+%\def\endsmall{\normalsize}
+\def\beginsmall{}
+\def\endsmall{}
+
+
+% The Index
+% ---------
+% LaTeX provides a single command (\index) for adding index entries to the
+% index. We shorten it and refine it a little with a few definitions.
+\def\newterm#1{{\bf #1}\x{#1}} % Special terminology.
+\def\x#1{\index{#1}} % Normal index entry.
+\def\xx#1#2{\index{#1 #2}\index{#2 #1}} % Symmetric index entry.
+\def\xn#1#2{\xx{#1}{#2}} % For a person's name.
+\def\xs#1#2{\index{#1, #2}} % For an entry with a subclause.
+
+
+% References
+% ----------
+\def\paper#1{{\bf [#1]}\x{#1}\linebreak[1]{}}
+
+
+% Figures and Tables
+% ------------------
+% LaTeX numbers figures by chapter and doesn't position captions where I
+% want them and so I have decided to do it all manually. I haven't got
+% time for fancy stuff so I am using manual macros.
+\def\mylabel#1#2{%
+\begin{quotation}
+\footnotesize\baselineskip=12pt #2
+\end{quotation}
+\centerline{#1}
+\smallskip}
+
+\def\figfor#1{{\bf Figure~#1}}
+\def\tabfor#1{{\bf Table~#1}}
+
+\def\figarchitecture{\figfor{1}}
+\def\figfunarch{\figfor{2}}
+\def\figphases{\figfor{3}}
+\def\figregform{\figfor{4}}
+
+%\def\tabone{\tabfor{1}}
+%\def\tabtwo{\tabfor{2}}
+
+
+% Glossary
+% --------
+\def\gloss#1{\thing{#1:}\x{#1}}
+
+
+% Random Leftover Stuff
+% ---------------------
+\def\topicbreak{\bigskip\centerline{--- $\S$ ---}\bigskip}
+
+
+
+%------------------------------------------------------------------------------
+
+\makeindex
+
+\begin{document}
+
+% Title Page
+% ----------
+% Although the title should really be in the ch0.tex file, LaTeX forces us to
+% put it here.
+\begin{titlepage}
+\vspace*{3cm}
+\begin{center}
+\Huge
+\vspace{2cm}
+FunnelWeb User's Manual\\
+\vspace{2cm}
+\LARGE
+Ross~N.~Williams\\
+\vspace{1cm}
+\Large
+V1.0 for FunnelWeb V3.0\\
+\vspace{1cm}
+May 1992\\
+\normalsize
+\end{center}
+\end{titlepage}
+
+% Note: LaTeX sometimes puts a blank page before chapters so as to
+% start each chapter on an odd-numbered page. There is nothing that I
+% can do about this. This is part of the cost of using LaTeX instead
+% of TeX.
+
+%\makeindex % original position
+
+%-------------------------------------------------------------------------------
+
+%\begin{document} % original position
+\sloppy
+\nonstopmode
+
+\input u_ch0 % Table of contents etc.
+\input u_ch1 % A Tutorial Introduction
+\input u_ch2 % FunnelWeb Hints
+\input u_ch3 % FunnelWeb Definition
+\input u_ch4 % FunnelWeb Installation.
+\input u_ch5 % FunnelWeb Administration.
+\input u_cha % Appendices
+
+\end{document}
+
+%==============================================================================%
+% End of Main .TeX File of FunnelWeb User's Manual %
+%==============================================================================%
diff --git a/web/funnelAC/userman/u_manual.toc b/web/funnelAC/userman/u_manual.toc
new file mode 100644
index 0000000000..b359e8fa3e
--- /dev/null
+++ b/web/funnelAC/userman/u_manual.toc
@@ -0,0 +1,166 @@
+\contentsline {chapter}{Preface}{9}
+\contentsline {chapter}{Acknowledgements}{11}
+\contentsline {chapter}{Presentation Notes}{13}
+\contentsline {chapter}{\numberline {1}A Tutorial Introduction}{15}
+\contentsline {section}{\numberline {1.1}What is Literate Programming?}{15}
+\contentsline {section}{\numberline {1.2}What is FunnelWeb?}{18}
+\contentsline {section}{\numberline {1.3}The Name FunnelWeb}{19}
+\contentsline {section}{\numberline {1.4}A FunnelWeb Tutorial}{19}
+\contentsline {section}{\numberline {1.5}A Hello World Document}{20}
+\contentsline {section}{\numberline {1.6}Macro Facilities}{22}
+\contentsline {subsection}{\numberline {1.6.1}Simple Macros}{22}
+\contentsline {subsection}{\numberline {1.6.2}Number of Times Called}{23}
+\contentsline {subsection}{\numberline {1.6.3}Indentation}{25}
+\contentsline {subsection}{\numberline {1.6.4}Additive Macros}{26}
+\contentsline {subsection}{\numberline {1.6.5}Parameterized Macros}{28}
+\contentsline {subsection}{\numberline {1.6.6}Macro Expansion}{30}
+\contentsline {subsection}{\numberline {1.6.7}Include Files}{30}
+\contentsline {section}{\numberline {1.7}Typesetting Facilities}{32}
+\contentsline {subsection}{\numberline {1.7.1}Overview}{32}
+\contentsline {subsection}{\numberline {1.7.2}Typesetter Independence}{34}
+\contentsline {subsection}{\numberline {1.7.3}Hierarchical Structure}{34}
+\contentsline {subsection}{\numberline {1.7.4}Understanding the Printed Documentation}{35}
+\contentsline {subsection}{\numberline {1.7.5}Literals and Emphasis}{37}
+\contentsline {subsection}{\numberline {1.7.6}Adding a Header Page}{37}
+\contentsline {subsection}{\numberline {1.7.7}Comments}{37}
+\contentsline {section}{\numberline {1.8}A Complete Example}{38}
+\contentsline {section}{\numberline {1.9}Summary}{39}
+\contentsline {chapter}{\numberline {2}FunnelWeb Hints}{41}
+\contentsline {section}{\numberline {2.1}Macro Names}{41}
+\contentsline {section}{\numberline {2.2}Quick Names}{42}
+\contentsline {section}{\numberline {2.3}FunnelWeb the Martinet}{42}
+\contentsline {section}{\numberline {2.4}Fiddling With End of Lines}{43}
+\contentsline {section}{\numberline {2.5}Fudging Conditionals}{44}
+\contentsline {section}{\numberline {2.6}Changing the Strength of Headings}{46}
+\contentsline {section}{\numberline {2.7}Efficiency Notes}{47}
+\contentsline {section}{\numberline {2.8}Interactive Mode}{47}
+\contentsline {section}{\numberline {2.9}Setting Up Default Options}{49}
+\contentsline {section}{\numberline {2.10}FunnelWeb and Make}{49}
+\contentsline {section}{\numberline {2.11}The Dangers of FunnelWeb}{50}
+\contentsline {section}{\numberline {2.12}Wholistic Debugging}{53}
+\contentsline {section}{\numberline {2.13}Examples of FunnelWeb Applications}{53}
+\contentsline {subsection}{\numberline {2.13.1}Analyzing the Monster Postscript Header File}{54}
+\contentsline {subsection}{\numberline {2.13.2}Making Ada ADTs more A}{55}
+\contentsline {subsection}{\numberline {2.13.3}Multiple Language Systems}{55}
+\contentsline {subsection}{\numberline {2.13.4}The Case of the Small Function}{56}
+\contentsline {subsection}{\numberline {2.13.5}When Comments are Bad}{57}
+\contentsline {subsection}{\numberline {2.13.6}Documents That Share Text}{58}
+\contentsline {subsection}{\numberline {2.13.7}Generics}{59}
+\contentsline {section}{\numberline {2.14}Summary}{62}
+\contentsline {chapter}{\numberline {3}FunnelWeb Definition}{63}
+\contentsline {section}{\numberline {3.1}Introduction}{63}
+\contentsline {section}{\numberline {3.2}Notation}{63}
+\contentsline {section}{\numberline {3.3}Terminology}{63}
+\contentsline {section}{\numberline {3.4}An Architectural Overview}{64}
+\contentsline {section}{\numberline {3.5}Diagnostics}{65}
+\contentsline {section}{\numberline {3.6}Typesetter Independence}{65}
+\contentsline {section}{\numberline {3.7}Command Line Interface}{66}
+\contentsline {subsection}{\numberline {3.7.1}Invoking FunnelWeb}{66}
+\contentsline {subsection}{\numberline {3.7.2}Command Line Arguments}{67}
+\contentsline {subsection}{\numberline {3.7.3}Options}{68}
+\contentsline {section}{\numberline {3.8}File Name Inheritance}{70}
+\contentsline {section}{\numberline {3.9}FunnelWeb Startup}{70}
+\contentsline {section}{\numberline {3.10}Scanner}{71}
+\contentsline {subsection}{\numberline {3.10.1}Basic Input File Processing}{71}
+\contentsline {subsection}{\numberline {3.10.2}Special Sequences}{72}
+\contentsline {subsection}{\numberline {3.10.3}Setting the Special Character}{74}
+\contentsline {subsection}{\numberline {3.10.4}Inserting the Special Character into the Text}{74}
+\contentsline {subsection}{\numberline {3.10.5}Inserting Arbitrary Characters into the Text}{74}
+\contentsline {subsection}{\numberline {3.10.6}Comments}{75}
+\contentsline {subsection}{\numberline {3.10.7}Quick Names}{76}
+\contentsline {subsection}{\numberline {3.10.8}Inserting End of Line Markers}{76}
+\contentsline {subsection}{\numberline {3.10.9}Suppressing End of Line Markers}{77}
+\contentsline {subsection}{\numberline {3.10.10}Include Files}{77}
+\contentsline {subsection}{\numberline {3.10.11}Pragmas}{78}
+\contentsline {subsubsection}{\numberline {3.10.11.1}Indentation}{78}
+\contentsline {subsubsection}{\numberline {3.10.11.2}Maximum Input Line Length}{79}
+\contentsline {subsubsection}{\numberline {3.10.11.3}Maximum Output File Line Length}{79}
+\contentsline {subsubsection}{\numberline {3.10.11.4}Typesetter}{80}
+\contentsline {subsection}{\numberline {3.10.12}Freestanding Typesetter Directives}{81}
+\contentsline {subsubsection}{\numberline {3.10.12.1}New Page}{81}
+\contentsline {subsubsection}{\numberline {3.10.12.2}Table of Contents}{81}
+\contentsline {subsubsection}{\numberline {3.10.12.3}Vertical Skip}{81}
+\contentsline {subsubsection}{\numberline {3.10.12.4}Title}{82}
+\contentsline {subsection}{\numberline {3.10.13}Scanner/Parser Interface}{82}
+\contentsline {section}{\numberline {3.11}Parser}{82}
+\contentsline {subsection}{\numberline {3.11.1}High Level Structure}{82}
+\contentsline {subsection}{\numberline {3.11.2}Free Text}{83}
+\contentsline {subsection}{\numberline {3.11.3}Typesetter Directives}{83}
+\contentsline {subsubsection}{\numberline {3.11.3.1}Section}{83}
+\contentsline {subsubsection}{\numberline {3.11.3.2}Literal Directive}{84}
+\contentsline {subsubsection}{\numberline {3.11.3.3}Emphasis Directive}{85}
+\contentsline {subsection}{\numberline {3.11.4}Macros}{85}
+\contentsline {subsubsection}{\numberline {3.11.4.1}Names}{86}
+\contentsline {subsubsection}{\numberline {3.11.4.2}Formal Parameter Lists}{86}
+\contentsline {subsection}{\numberline {3.11.5}Expressions}{86}
+\contentsline {subsection}{\numberline {3.11.6}Macro Calls}{86}
+\contentsline {subsection}{\numberline {3.11.7}Formal Parameters}{87}
+\contentsline {subsection}{\numberline {3.11.8}Macros are Static}{87}
+\contentsline {section}{\numberline {3.12}Analyser}{88}
+\contentsline {section}{\numberline {3.13}Tangle}{88}
+\contentsline {section}{\numberline {3.14}Weave}{89}
+\contentsline {subsection}{\numberline {3.14.1}Target Typesetter}{89}
+\contentsline {subsection}{\numberline {3.14.2}Cross Reference Numbering}{89}
+\contentsline {section}{\numberline {3.15}FunnelWeb Shell}{90}
+\contentsline {subsection}{\numberline {3.15.1}Introduction}{90}
+\contentsline {subsection}{\numberline {3.15.2}Return Statuses}{90}
+\contentsline {subsection}{\numberline {3.15.3}Command Line Length}{91}
+\contentsline {subsection}{\numberline {3.15.4}String Substitution}{91}
+\contentsline {subsection}{\numberline {3.15.5}How a Command Line is Processed}{92}
+\contentsline {subsection}{\numberline {3.15.6}Options}{92}
+\contentsline {subsection}{\numberline {3.15.7}Shell Commands}{93}
+\contentsline {subsubsection}{\numberline {3.15.7.1}Absent}{93}
+\contentsline {subsubsection}{\numberline {3.15.7.2}Codify}{93}
+\contentsline {subsubsection}{\numberline {3.15.7.3}Compare}{93}
+\contentsline {subsubsection}{\numberline {3.15.7.4}Define}{94}
+\contentsline {subsubsection}{\numberline {3.15.7.5}Diff}{94}
+\contentsline {subsubsection}{\numberline {3.15.7.6}Diffsummary}{95}
+\contentsline {subsubsection}{\numberline {3.15.7.7}Diffzero}{95}
+\contentsline {subsubsection}{\numberline {3.15.7.8}Eneo}{95}
+\contentsline {subsubsection}{\numberline {3.15.7.9}Execute}{96}
+\contentsline {subsubsection}{\numberline {3.15.7.10}Exists}{96}
+\contentsline {subsubsection}{\numberline {3.15.7.11}Fixeols}{96}
+\contentsline {subsubsection}{\numberline {3.15.7.12}Fw}{97}
+\contentsline {subsubsection}{\numberline {3.15.7.13}Help}{97}
+\contentsline {subsubsection}{\numberline {3.15.7.14}Here}{98}
+\contentsline {subsubsection}{\numberline {3.15.7.15}Quit}{98}
+\contentsline {subsubsection}{\numberline {3.15.7.16}Set}{98}
+\contentsline {subsubsection}{\numberline {3.15.7.17}Show}{98}
+\contentsline {subsubsection}{\numberline {3.15.7.18}Skipto}{98}
+\contentsline {subsubsection}{\numberline {3.15.7.19}Status}{99}
+\contentsline {subsubsection}{\numberline {3.15.7.20}Tolerate}{100}
+\contentsline {subsubsection}{\numberline {3.15.7.21}Trace}{100}
+\contentsline {subsubsection}{\numberline {3.15.7.22}Write}{100}
+\contentsline {subsubsection}{\numberline {3.15.7.23}Writeu}{100}
+\contentsline {section}{\numberline {3.16}Concluding Remarks}{100}
+\contentsline {chapter}{\numberline {4}FunnelWeb Installation}{101}
+\contentsline {section}{\numberline {4.1}Obtaining a Copy of FunnelWeb}{101}
+\contentsline {section}{\numberline {4.2}Establishing The Directory Tree}{102}
+\contentsline {subsection}{\numberline {4.2.1}Admin Directory}{102}
+\contentsline {subsection}{\numberline {4.2.2}Answers Directory}{102}
+\contentsline {subsection}{\numberline {4.2.3}Hackman Directory}{103}
+\contentsline {subsection}{\numberline {4.2.4}Results Directory}{103}
+\contentsline {subsection}{\numberline {4.2.5}Scripts Directory}{103}
+\contentsline {subsection}{\numberline {4.2.6}Sources Directory}{103}
+\contentsline {subsection}{\numberline {4.2.7}Tests Directory}{104}
+\contentsline {subsection}{\numberline {4.2.8}Userman Directory}{105}
+\contentsline {section}{\numberline {4.3}Compiling FunnelWeb}{105}
+\contentsline {section}{\numberline {4.4}Testing FunnelWeb}{105}
+\contentsline {section}{\numberline {4.5}Installing FunnelWeb}{106}
+\contentsline {section}{\numberline {4.6}Printing Manuals}{107}
+\contentsline {section}{\numberline {4.7}Installation Problems?}{107}
+\contentsline {chapter}{\numberline {5}FunnelWeb Administration}{109}
+\contentsline {section}{\numberline {5.1}Introduction}{109}
+\contentsline {section}{\numberline {5.2}The User's Commitment To FunnelWeb}{109}
+\contentsline {section}{\numberline {5.3}Documentation}{110}
+\contentsline {section}{\numberline {5.4}Registration}{110}
+\contentsline {section}{\numberline {5.5}Support}{110}
+\contentsline {section}{\numberline {5.6}Copyright}{112}
+\contentsline {section}{\numberline {5.7}Nowarranty}{112}
+\contentsline {section}{\numberline {5.8}Distribution}{113}
+\contentsline {section}{\numberline {5.9}Modification}{113}
+\contentsline {section}{\numberline {5.10}Versions}{114}
+\contentsline {section}{\numberline {5.11}FTP Archive and Author}{114}
+\contentsline {chapter}{\numberline {A}Glossary}{115}
+\contentsline {chapter}{\numberline {B}References}{117}
+\contentsline {chapter}{Index}{117}